Ctrl K
ComunidadGuías…

src/lib/import-check-in.test.ts

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
import { describe, expect, it } from "vitest";

import {
  checkInAccountSummary,
  checkInProposalValues,
  checkInSubmission,
  checkInWasWritten,
  portraitChoice,
} from "./import-check-in";
import type {
  ImportCheckInDetail,
  LogbookImportNotes,
} from "@/lib/api/logbook-import";
import { formatDateOnly } from "@/lib/date-time";
import { EMPTY_CHECKIN_FORM_VALUES } from "@/lib/validations/checkin-details";

const details: ImportCheckInDetail[] = [
  { detail: "email", account: null, proposed: "[email protected]" },
  { detail: "phone", account: "+44 1", proposed: "+44 2" },
  { detail: "date_of_birth", account: null, proposed: "1988-04-02" },
  {
    detail: "emergency_contacts",
    account: [],
    proposed: [
      { name: "Alex", phone: "0456", relationship: null },
      { name: "Sam", phone: null, relationship: "Parent" },
    ],
  },
  {
    detail: "insurance_policies",
    account: [{ provider: "DAN", number: "P-1", expires_on: "2027-03-01" }],
    proposed: [
      { provider: "DAN", number: "P-1", expires_on: "2027-03-01" },
      { provider: "Aqua", number: null, expires_on: null },
    ],
  },
];

describe("checkInProposalValues", () => {
  it("seeds every member a carried detail holds with the proposal, lists whole", () => {
    expect(checkInProposalValues(details)).toEqual({
      ...EMPTY_CHECKIN_FORM_VALUES,
      email: "[email protected]",
      date_of_birth: "1988-04-02",
      phone: "+44 2",
      emergency_contacts: [
        { name: "Alex", phone: "0456", relationship: "" },
        { name: "Sam", phone: "", relationship: "Parent" },
      ],
      insurance_policies: [
        { provider: "DAN", number: "P-1", expires_on: "2027-03-01" },
        { provider: "Aqua", number: "", expires_on: "" },
      ],
    });
  });
});

describe("checkInAccountSummary", () => {
  it("reads the account's side as one line, dates formatted, rows apart", () => {
    expect(checkInAccountSummary(details[1])).toBe("+44 1");
    expect(checkInAccountSummary(details[4])).toBe(
      `DAN · P-1 · expires ${formatDateOnly("2027-03-01")}`,
    );
    expect(
      checkInAccountSummary({
        ...details[3],
        account: [
          { name: "Alex", phone: "0456", relationship: null },
          { name: "Sam", phone: null, relationship: "Parent" },
        ],
      } as ImportCheckInDetail),
    ).toBe("Alex · 0456; Sam · Parent");
  });

  it("is null where the account holds nothing of the detail", () => {
    expect(checkInAccountSummary(details[0])).toBeNull();
    expect(checkInAccountSummary(details[2])).toBeNull();
    expect(checkInAccountSummary(details[3])).toBeNull();
  });
});

describe("checkInSubmission", () => {
  it("sends every detail not kept, keyed by its member, trimmed, an emptied one cleared", () => {
    const values = {
      ...checkInProposalValues(details),
      phone: "  +44 3 ",
      insurance_policies: [],
    };
    expect(checkInSubmission(details, new Set(), values)).toEqual({
      email: "[email protected]",
      phone: "+44 3",
      date_of_birth: "1988-04-02",
      emergency_contacts: [
        { name: "Alex", phone: "0456", relationship: null },
        { name: "Sam", phone: null, relationship: "Parent" },
      ],
      // `[]`, never `null`: the API refuses a list sent as null.
      insurance_policies: [],
    });
  });

  it("leaves a kept detail out altogether, which is what keeps the account's", () => {
    const submission = checkInSubmission(
      details,
      new Set(["phone", "insurance_policies"] as const),
      checkInProposalValues(details),
    );
    expect(Object.keys(submission)).toEqual([
      "email",
      "date_of_birth",
      "emergency_contacts",
    ]);
  });

  it("sends nothing for a detail the document does not carry", () => {
    expect(
      checkInSubmission(
        [details[1]],
        new Set(),
        checkInProposalValues(details),
      ),
    ).toEqual({ phone: "+44 2" });
  });
});

describe("checkInWasWritten", () => {
  const report = (codes: string[]): LogbookImportNotes => ({
    // One group per written detail, as the API reports them: each detail's
    // sentence names its label, so no two share a group.
    notes: codes.map((code) => ({
      code,
      kind: null,
      collection: null,
      message: "",
      count: 1,
      wheres: [],
    })),
    notes_truncated: 0,
    dives: [],
  });

  it("is true only when the apply says a fact was written", () => {
    expect(checkInWasWritten(report(["check_in_detail_written"]))).toBe(true);
    expect(
      checkInWasWritten(
        report([
          "check_in_detail_dropped",
          "diver_not_applied",
          "portrait_kept",
        ]),
      ),
    ).toBe(false);
  });
});

describe("portraitChoice", () => {
  const sha = "a".repeat(64);

  it("carries the review's digest whichever way the diver chose", () => {
    const offer = { account_sha256: sha, proposed: "data:image/webp;base64," };
    expect(portraitChoice(offer, false)).toEqual({
      choice: "take",
      account_sha256: sha,
    });
    expect(portraitChoice(offer, true)).toEqual({
      choice: "keep",
      account_sha256: sha,
    });
    // No portrait on the account is `null`, sent rather than left out.
    expect(
      portraitChoice({ ...offer, account_sha256: null }, true),
    ).toHaveProperty("account_sha256", null);
  });

  it("sends nothing when nothing was offered", () => {
    expect(portraitChoice(null, false)).toBeUndefined();
  });
});