Newer
Older
client_dwatch / lib / db / __tests__ / robot-error-select.test.ts
/**
 * `robot_error_reports` の読み取りの `select` が `robot_id` / `robot` を含まないこと(指示書AU 段階0-4。§11 Q6)。
 *
 * ★先方の DDL では `robot_id` が NULL 可(TeamWorks 第11回 P-8 b)、Prisma のスキーマは NOT NULL のまま★。
 *   読まなければ NULL の行が入っても落ちない。経路ごとの「NULL の行を混ぜても落ちない」は
 *   各ルートのテスト(`app/api/{clean-logs,prechecks,prechecks/[id]/status,reports}/__tests__/route.test.ts`)。
 */
import { describe, expect, it } from "vitest";
import {
  ROBOT_ERROR_COUNT_SELECT,
  ROBOT_ERROR_LIST_KEY_SELECT,
  ROBOT_ERROR_LIST_ROW_SELECT,
  ROBOT_ERROR_PRECHECK_ROW_SELECT,
  ROBOT_ERROR_STATUS_SELECT,
  ROBOT_ERROR_TYPE_SELECT,
} from "@/lib/db/robot-error-select";
import { guardNullRobotId } from "./robot-error-null-guard";

const SELECTS: [string, Record<string, unknown>][] = [
  ["ROBOT_ERROR_COUNT_SELECT", ROBOT_ERROR_COUNT_SELECT],
  ["ROBOT_ERROR_STATUS_SELECT", ROBOT_ERROR_STATUS_SELECT],
  ["ROBOT_ERROR_TYPE_SELECT", ROBOT_ERROR_TYPE_SELECT],
  ["ROBOT_ERROR_PRECHECK_ROW_SELECT", ROBOT_ERROR_PRECHECK_ROW_SELECT],
  // エラー一覧(指示書AW D6): 1段目(キーだけ)と2段目・PATCH の前後の読み取り
  ["ROBOT_ERROR_LIST_KEY_SELECT", ROBOT_ERROR_LIST_KEY_SELECT],
  ["ROBOT_ERROR_LIST_ROW_SELECT", ROBOT_ERROR_LIST_ROW_SELECT],
];

describe("robot_error_reports の select(指示書AU 段階0-4)", () => {
  it.each(SELECTS)("%s は robot_id も robot も含まない", (_name, select) => {
    expect(select).not.toHaveProperty("robot_id");
    expect(select).not.toHaveProperty("robot");
  });

  it.each(SELECTS)("%s は紐づけのキー clean_timetable_id を含む", (_name, select) => {
    expect(select.clean_timetable_id).toBe(true);
  });
});

describe("guardNullRobotId(スタブで Prisma の失敗を再現する)", () => {
  const nullRow = [{ error_id: "E1", robot_id: null }];

  it("select なし(全列)で NULL の行を読むと落ちる", () => {
    expect(() => guardNullRobotId(nullRow, { where: {} })).toThrow(/robot_id/);
    expect(() => guardNullRobotId(nullRow, { include: { facility: true } })).toThrow(/robot_id/);
  });

  it("select / include に robot_id・robot があると落ちる", () => {
    expect(() => guardNullRobotId(nullRow, { select: { robot_id: true } })).toThrow();
    expect(() => guardNullRobotId(nullRow, { select: { robot: true } })).toThrow();
    expect(() => guardNullRobotId(nullRow, { include: { robot: true } })).toThrow();
  });

  it("select で絞っていれば落ちない", () => {
    expect(() => guardNullRobotId(nullRow, { select: ROBOT_ERROR_PRECHECK_ROW_SELECT })).not.toThrow();
  });

  it("NULL の行が無ければ select なしでも落ちない(既存のテストを巻き込まない)", () => {
    expect(() => guardNullRobotId([{ robot_id: BigInt(1) }], undefined)).not.toThrow();
  });
});