Newer
Older
client_dwatch / lib / ds-logs / __tests__ / presets.test.ts
/**
 * 指示書AY §3 表2(`lib/ds-logs/presets.ts`。now = 2026-10-19T12:00:00+09:00)。
 * ブリーフ §5 と監督判断 第2ラウンドから本書で具体化。★P1・P2 の行は §11 Q14・Q15 の採用で確定★。
 *
 * | #   | 入力                               | from                      | to                        |
 * | T1  | 1h(直近1時間)                    | 2026-10-19T11:00:00+09:00 | なし(D23)               |
 * | T2  | 3h(直近3時間)                    | 2026-10-19T09:00:00+09:00 | なし                      |
 * | T3  | 24h(直近24時間)                  | 2026-10-18T12:00:00+09:00 | なし                      |
 * | T4  | all(全て)                        | なし                      | なし                      |
 * | T5  | 2026-10-18〜2026-10-19             | 2026-10-18T00:00:00+09:00 | 2026-10-20T00:00:00+09:00(終了日を含む) |
 * | T6  | 2026-10-31〜2026-10-31             | 2026-10-31T00:00:00+09:00 | 2026-11-01T00:00:00+09:00(月またぎ) |
 * | T7  | 開始だけ 2026-10-19                | 2026-10-19T00:00:00+09:00 | なし                      |
 * | T8  | 終了だけ 2026-10-18                | なし                      | 2026-10-19T00:00:00+09:00 |
 * | T9  | 2026-10-19〜2026-10-18(逆)       | null(不正)              | —                         |
 * | T10 | now を UTC で渡す(03:00Z)・1h    | 2026-10-19T11:00:00+09:00 | なし(実行環境のタイムゾーンに依存しない) |
 */
import { describe, expect, it } from "vitest";
import { dateRangeError, periodFromDates, periodFromPreset } from "@/lib/ds-logs/presets";

const NOW = new Date("2026-10-19T12:00:00+09:00");

describe("periodFromPreset() — 表2 T1〜T4・T10", () => {
  it.each<[string, "1h" | "3h" | "24h" | "all", Date, string | null]>([
    ["T1 直近1時間", "1h", NOW, "2026-10-19T11:00:00+09:00"],
    ["T2 直近3時間", "3h", NOW, "2026-10-19T09:00:00+09:00"],
    ["T3 直近24時間", "24h", NOW, "2026-10-18T12:00:00+09:00"],
    ["T4 全て", "all", NOW, null],
    ["T10 now を UTC で渡しても JST で返す", "1h", new Date("2026-10-19T03:00:00Z"), "2026-10-19T11:00:00+09:00"],
  ])("%s", (_label, preset, now, expectedFrom) => {
    expect(periodFromPreset(preset, now)).toEqual({ from: expectedFrom, to: null });
  });
});

describe("periodFromDates() — 表2 T5〜T9", () => {
  it.each<[string, string | null, string | null, { from: string | null; to: string | null } | null]>([
    ["T5 終了日を含む", "2026-10-18", "2026-10-19", { from: "2026-10-18T00:00:00+09:00", to: "2026-10-20T00:00:00+09:00" }],
    ["T6 月またぎ", "2026-10-31", "2026-10-31", { from: "2026-10-31T00:00:00+09:00", to: "2026-11-01T00:00:00+09:00" }],
    ["T7 開始だけ", "2026-10-19", null, { from: "2026-10-19T00:00:00+09:00", to: null }],
    ["T8 終了だけ", null, "2026-10-18", { from: null, to: "2026-10-19T00:00:00+09:00" }],
    ["T9 逆(開始 > 終了)は不正", "2026-10-19", "2026-10-18", null],
  ])("%s", (_label, start, end, expected) => {
    expect(periodFromDates(start, end)).toEqual(expected);
  });
});

describe("dateRangeError() — 指示書BJ 表D", () => {
  it.each<[string, string | null, string | null, "reversed" | "invalid" | null]>([
    ["D1 逆順", "2026-10-19", "2026-10-18", "reversed"],
    ["D2 正常", "2026-10-18", "2026-10-19", null],
    ["D3 同じ日", "2026-10-18", "2026-10-18", null],
    ["D4 存在しない日付", "2026-02-30", "2026-03-01", "invalid"],
    ["D5 開始 null", null, "2026-10-18", null],
    ["D6 終了 null", "2026-10-19", null, null],
  ])("%s", (_label, start, end, expected) => {
    expect(dateRangeError(start, end)).toBe(expected);
  });
});