phase: 102_extensionless_filenames
All verification complete — every gate green, no defects found in previously completed work. **Phase 102 final verification pass — report** Verified (all three task files present in `complete/`; working-tree implementation matches D1–D5 design): - `match_extension` choke point in `app/rag/importer.py` (walk + `formats` counter), `doc_format` name-token badge in `app/api/docs.py`, config/`.env.example` docs, fixture `tests/fixtures/extensionless_kb/`, integration + E2E suites — all present and correct - Completion criteria: end-to-end sync (✓ integration + E2E), case matrix incl. `mydockerfile`/`Dockerfile.dev`/`.dockerfile` exclusions (✓ unit), `formats=dockerfile:1` not `unknown` (✓ log-line assertion), badge `dockerfile`/`containerfile` + `text` fallback + suffixed unchanged (✓ unit/integration/E2E), prune-on-token-removal (✓ `pruned==2`), suffixed-path rule byte-identical (✓ single-line swap, existing cases untouched) Test / lint results (exact commands): - `uv run pytest --cov=app --cov-report=term-missing` → 2084 passed, **99%** coverage (>90% gate) - `uv run pytest tests/e2e/test_extensionless_import.py -v --no-cov` → 2 passed, isolated, DB up - Regressions isolated: `test_import_documents` 3✓, `test_import_extensions_env` 2✓, `test_quadlet_jinja_import` 4✓, `test_document_viewer` 7✓, `test_kb_tree` 8✓ - `uv run ruff check .` → clean; `uv run pyright` → 0 errors, 0 warnings Notable: commit intentionally not made (harness commits the phase); 102's task files already sit in `complete/`, overview stays in `todo/` for the harness. Next pending phases: 98, 99, 103, 104, 105 (numeric next after 102: `103_suggestions_session_openers`).
This commit is contained in:
@@ -35,6 +35,7 @@ from sqlalchemy import select, text
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
import app.api.docs as docs_api
|
||||
from app.config import get_settings
|
||||
from app.main import app as fastapi_app
|
||||
from app.models import Chunk, Document
|
||||
from app.rag.llm import EmbeddingError
|
||||
@@ -555,3 +556,71 @@ def test_content_format_from_suffix(client, db) -> None:
|
||||
finally:
|
||||
db.execute(text("TRUNCATE chunks, documents"))
|
||||
db.commit()
|
||||
|
||||
|
||||
def test_content_format_name_token_extensionless(
|
||||
client, db, monkeypatch
|
||||
) -> None:
|
||||
"""Phase 102: the endpoint's ``format`` carries the name token for an
|
||||
extensionless document whose lowercased full filename is a
|
||||
``BOR_IMPORT_EXTENSIONS`` token (``Dockerfile`` → ``dockerfile``),
|
||||
``text`` for an extensionless name that is NOT configured, and every
|
||||
suffixed value is unchanged (display never depends on the import
|
||||
list — ``notes/README.dev`` badges ``dev`` even though ``dev`` is not
|
||||
a configured token). The endpoint reads the real ``get_settings()``,
|
||||
so the token lands via the house env-override pattern (the default
|
||||
list does not contain ``dockerfile``)."""
|
||||
get_settings.cache_clear()
|
||||
try:
|
||||
monkeypatch.setenv("BOR_IMPORT_EXTENSIONS", "md,dockerfile")
|
||||
|
||||
_seed_doc(
|
||||
db,
|
||||
path="services/api/Dockerfile",
|
||||
title="Dockerfile",
|
||||
content="FROM alpine\nCMD [\"/bin/sh\"]",
|
||||
chunks=0,
|
||||
)
|
||||
r = client.get(
|
||||
"/api/documents/content",
|
||||
params={"source": "Homelab", "path": "services/api/Dockerfile"},
|
||||
)
|
||||
assert r.status_code == 200
|
||||
assert r.json()["format"] == "dockerfile"
|
||||
|
||||
# Suffix precedence under the same override — the import list is
|
||||
# ignored for suffixed paths.
|
||||
_seed_doc(
|
||||
db,
|
||||
path="notes/README.dev",
|
||||
title="README.dev",
|
||||
content="dev note",
|
||||
chunks=0,
|
||||
)
|
||||
r = client.get(
|
||||
"/api/documents/content",
|
||||
params={"source": "Homelab", "path": "notes/README.dev"},
|
||||
)
|
||||
assert r.status_code == 200
|
||||
assert r.json()["format"] == "dev"
|
||||
|
||||
# Extensionless name NOT in the configured set → the ``text``
|
||||
# fallback (the existing README pin above covers the same case
|
||||
# under the default settings).
|
||||
_seed_doc(
|
||||
db,
|
||||
path="Containerfile",
|
||||
title="Containerfile",
|
||||
content="FROM alpine",
|
||||
chunks=0,
|
||||
)
|
||||
r = client.get(
|
||||
"/api/documents/content",
|
||||
params={"source": "Homelab", "path": "Containerfile"},
|
||||
)
|
||||
assert r.status_code == 200
|
||||
assert r.json()["format"] == "text"
|
||||
finally:
|
||||
get_settings.cache_clear()
|
||||
db.execute(text("TRUNCATE chunks, documents"))
|
||||
db.commit()
|
||||
|
||||
Reference in New Issue
Block a user