import { describe, expect, it } from "vitest";
// ★ルート本体は**静的 import** すること★(`app/api/__tests__/master-filter.test.ts` 冒頭と同じ理由)
import { GET } from "@/app/api/facilities/route";
import { facilities } from "@/lib/fixtures";
import type { Facility, ListResponse } from "@/lib/types";
/**
* `GET /facilities` のレスポンスに ★所属(屋号・ホールディングス)が載っていること★
* (指示書AK ★段階5★)。
*
* ------------------------------------------------------------------------
* ★★なぜルートまで通すのか★★
* ------------------------------------------------------------------------
* `Facility` に列を足しても、★ルートが別の形に詰め替えていれば画面には出ません★。
* ★「列が1つ静かに欠ける」は例外もテスト失敗も出ない壊れ方★(一覧は200で返り続ける)なので、
* ★ルート → データソース → JSON★ まで通して固定します
* (`app/api/__tests__/master-filter.test.ts` と同じ考え方)。
*
* ★絞り込み・並べ替え・ページングはここでは見ない★ —
* それぞれ `lib/facilities/__tests__/query.test.ts` と
* `app/api/__tests__/master-filter.test.ts` の担当。
*/
describe("GET /facilities: 所属(指示書AK 段階5)", () => {
async function items(): Promise<Facility[]> {
// ★`per_page` は上限(200)まで寄せる★(fixtures の12件を1ページに収める)
const res = await GET(new Request("http://localhost/api/facilities?per_page=200"));
expect(res.status).toBe(200);
const body = (await res.json()) as ListResponse<Facility>;
return body.items;
}
it("全件に `customer_id` / `customer_name` / `group_id` / `group_name` が載る", async () => {
const rows = await items();
expect(rows).toHaveLength(facilities.length);
for (const row of rows) {
expect(typeof row.customer_id).toBe("number");
expect(typeof row.customer_name).toBe("string");
// ★`group_id` は API の形★ — ★`0` を漏らさないこと★(D-011 / ★落とし穴3★)
expect(row.group_id).not.toBe(0);
}
});
it("★ホールディングスありの施設★は名前まで返る", async () => {
const row = (await items()).find((f) => f.id === 1);
expect(row).toMatchObject({
customer_id: 1,
customer_name: "メガバリューマート",
group_id: 1,
group_name: "バリューホールディングス",
});
});
it("★ホールディングスなしの施設★は `group_id` / `group_name` が両方 `null`", async () => {
const row = (await items()).find((f) => f.id === 12);
expect(row).toMatchObject({
customer_id: 4,
customer_name: "フレッシュタウン湖畔",
group_id: null,
group_name: null,
});
});
});