Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
97 lines
4.2 KiB
Python
97 lines
4.2 KiB
Python
"""/search/logic, /chunks/{id}, /programs/{name}/chunks — 로직 조각 검색·조회 API."""
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
from fastapi.testclient import TestClient
|
|
|
|
from config.settings import settings
|
|
import summarize.runner as runner
|
|
|
|
PAYLOAD = {
|
|
"MAIN_PROGRAM": "ZLOGIC_T1",
|
|
"DESCRIPTION": "로직 검색 테스트",
|
|
"INCLUDE_PROGRAM": [{
|
|
"INCLUDE": "ZLOGIC_T1",
|
|
"SOURCE_CODE": (
|
|
"REPORT zlogic_t1.\n"
|
|
"START-OF-SELECTION.\n"
|
|
" PERFORM get_gr.\n"
|
|
"FORM get_gr.\n"
|
|
" SELECT mblnr FROM mseg INTO TABLE gt_mseg WHERE bwart = '101'.\n"
|
|
" SORT gt_mseg BY mblnr.\n"
|
|
"ENDFORM."
|
|
),
|
|
}],
|
|
}
|
|
|
|
|
|
class StubLLM:
|
|
usage = {"calls": 0, "prompt_tokens": 0, "completion_tokens": 0, "cost_usd": 0.0}
|
|
|
|
def complete_json(self, system: str, user: str) -> dict:
|
|
if "[작업] program_summary" in user:
|
|
return {"program": "x", "business_purpose_ko": "구매오더 입고 자재문서 조회", "confidence": 0.8}
|
|
if "name: GET_GR" in user:
|
|
return {"unit_purpose_ko": "입고 자재문서 조회", "chunks": [{
|
|
"line_start": 5, "line_end": 6, "first_line": "SELECT mblnr FROM mseg INTO TABLE gt_mseg WHERE bwart = '101'.",
|
|
"kind": "sql_select", "purpose_ko": "이동유형 101(입고) 자재문서를 MSEG 에서 조회",
|
|
"purpose_en": "Read goods receipt material documents (movement type 101) from MSEG",
|
|
"keywords_ko": ["입고", "자재문서", "이동유형 101"], "keywords_en": ["goods receipt", "GR"],
|
|
"sap_objects": ["MSEG", "BWART"], "confidence": 0.9}]}
|
|
return {"unit_purpose_ko": "요약", "chunks": []}
|
|
|
|
|
|
@pytest.fixture()
|
|
def client(tmp_path, monkeypatch):
|
|
import query.api as api
|
|
|
|
monkeypatch.setattr(settings, "database_url", f"sqlite:///{tmp_path / 'index.db'}")
|
|
monkeypatch.setattr(settings, "data_normalized", tmp_path / "normalized")
|
|
monkeypatch.setattr(settings, "data_parsed", tmp_path / "parsed")
|
|
monkeypatch.setattr(settings, "llm_base_url", "")
|
|
monkeypatch.setattr(runner, "create_llm", lambda fake=False, **kw: StubLLM())
|
|
c = TestClient(api.app)
|
|
assert c.post("/ingest", json=PAYLOAD).json()["status"] == "loaded"
|
|
runner.summarize_units("ZLOGIC_T1", None, fake=False, dry_run=False, trigger="test")
|
|
return c
|
|
|
|
|
|
def test_search_logic_groups_by_program(client):
|
|
r = client.get("/search/logic", params={"q": "입고 처리하는 로직"}).json()
|
|
assert r["total"] >= 1
|
|
g = r["programs"][0]
|
|
assert g["program"] == "ZLOGIC_T1"
|
|
assert g["purpose"].startswith("구매오더 입고")
|
|
c = g["chunks"][0]
|
|
assert c["unit"] == "GET_GR" and c["kind"] == "sql_select"
|
|
assert (c["line_start"], c["line_end"]) == (5, 6)
|
|
assert c["tables_read"] == ["MSEG"]
|
|
|
|
# 영어 · 객체명으로도 맞는다
|
|
assert client.get("/search/logic", params={"q": "goods receipt"}).json()["total"] >= 1
|
|
assert client.get("/search/logic", params={"q": "MSEG"}).json()["total"] >= 1
|
|
assert client.get("/search/logic", params={"q": "MSEG", "kind": "db_write"}).json()["total"] == 0
|
|
|
|
|
|
def test_chunk_code_and_program_chunks(client):
|
|
from urllib.parse import quote
|
|
|
|
chunk_id = client.get("/search/logic", params={"q": "입고"}).json()["programs"][0]["chunks"][0]["chunk_id"]
|
|
r = client.get(f"/chunks/{quote(chunk_id, safe='')}").json() # chunk_id 의 '#' 은 URL 인코딩 필요
|
|
assert r["code"].startswith(" SELECT mblnr FROM mseg")
|
|
assert r["unit_lines"] == "4-7"
|
|
assert client.get("/chunks/NOPE#C9").status_code == 404
|
|
|
|
lst = client.get("/programs/ZLOGIC_T1/chunks").json()["chunks"]
|
|
assert len(lst) == 1 and lst[0]["chunk_id"] == chunk_id
|
|
|
|
s = client.get("/programs/ZLOGIC_T1/summary").json()
|
|
assert s["structure"]["logic_chunks"][0]["chunk_id"] == chunk_id
|
|
assert s["summary"]["business_purpose_ko"].startswith("구매오더")
|
|
u = client.get("/programs/ZLOGIC_T1/units/GET_GR/code").json()
|
|
assert u["chunks"][0]["chunk_id"] == chunk_id
|
|
|
|
assert client.get("/health").json()["logic_chunks"] == 1
|
|
st = client.get("/summaries/status").json()
|
|
assert st["programs"][0]["chunks"] == 1 and st["programs"][0]["program_summary"] == "done"
|