import { describe, it, expect } from "vitest"; import { extractNavActions, APP_ROUTES } from "../../src/services/chatNavService"; describe("chatNavService.extractNavActions", () => { it("마커가 없으면 actions 빈 배열·원문 유지(trim만)", () => { const r = extractNavActions("오늘 우리 경기 대전에서 6시 30분에 해"); expect(r.actions).toEqual([]); expect(r.clean).toBe("오늘 우리 경기 대전에서 6시 30분에 해"); }); it("유효 마커를 actions로 분리하고 본문에서 제거한다", () => { const r = extractNavActions("예측은 예측 탭에서 하면 돼 [[NAV:prediction]]"); expect(r.actions).toEqual([ { type: "navigate", route: "prediction", label: APP_ROUTES.prediction }, ]); expect(r.clean).toBe("예측은 예측 탭에서 하면 돼"); expect(r.clean).not.toContain("[[NAV:"); }); it("여러 마커를 등장 순서대로, 라벨까지 채워 반환한다", () => { const r = extractNavActions("출석하고 [[NAV:attendance]] 예측도 해 [[NAV:prediction]]"); expect(r.actions.map((a) => a.route)).toEqual(["attendance", "prediction"]); expect(r.actions[0].label).toBe(APP_ROUTES.attendance); expect(r.clean).toBe("출석하고 예측도 해"); // 마커 제거(중간 공백은 남되 양끝 trim) }); it("알 수 없는 route는 무시한다(모델 환각 방어)", () => { const r = extractNavActions("어딘가 가봐 [[NAV:settings_unknown]] [[NAV:schedule]]"); expect(r.actions.map((a) => a.route)).toEqual(["schedule"]); }); it("프로토타입 키(toString 등)를 route로 받지 않는다", () => { const r = extractNavActions("ㅋㅋ [[NAV:toString]] [[NAV:hasOwnProperty]]"); expect(r.actions).toEqual([]); }); it("중복 route는 하나로 접는다", () => { const r = extractNavActions("[[NAV:shop]] 포인트는 상점에서 [[NAV:shop]]"); expect(r.actions.map((a) => a.route)).toEqual(["shop"]); }); it("마커만 있고 본문이 비면 clean이 빈 문자열(상위에서 필터 처리)", () => { const r = extractNavActions("[[NAV:home]]"); expect(r.clean).toBe(""); expect(r.actions.map((a) => a.route)).toEqual(["home"]); }); it("APP_ROUTES는 12개 무파라미터 라우트를 가진다(클라 확정본)", () => { expect(Object.keys(APP_ROUTES).sort()).toEqual([ "attendance", "home", "inquiry", "mypage", "notices", "notification_settings", "notifications", "photo_decorator", "prediction", "prediction_history", "schedule", "shop", ]); }); });