import React from "react"; import { renderToStaticMarkup } from "react-dom/server"; import { describe, expect, it } from "vitest"; import { ProgressStepper, getAutocallStepState, autocallStepHint } from "./OrderHistoryTimeline"; const orderDelivery = { id: "g-1", deliveryType: "delivery", deliveryStatus: "pending_confirmation", notificationStatus: "first_sms_sent", firstSmsSentAt: "2026-09-27T10:00:00Z", }; const orderPickup = { id: "g-2", deliveryType: "pickup", deliveryStatus: "pending_confirmation", notificationStatus: "first_sms_sent", firstSmsSentAt: "2026-09-27T10:00:00Z", }; const call = (outcome, extra = {}) => ({ id: Math.random().toString(36).slice(2), outcome, attempt_no: 1, created_at: "2026-09-28T10:00:00Z", was_test_mode: false, ...extra, }); describe("шаг «Звонок» в цепочке заказа", () => { it("цепочка доставки содержит шаг звонка сразу после SMS", () => { const markup = renderToStaticMarkup(); const labels = ["Добавлен", "SMS", "Звонок", "Согласовано", "Водитель", "Доставлено"]; let prev = -1; for (const l of labels) { const at = markup.indexOf(`>${l}`); expect(at, `шаг «${l}» есть в цепочке`).toBeGreaterThan(-1); expect(at, `шаг «${l}» идёт по порядку`).toBeGreaterThan(prev); prev = at; } }); it("цепочка самовывоза тоже содержит звонок и заканчивается «Вывезено»", () => { const markup = renderToStaticMarkup(); expect(markup).toContain(">Звонок"); expect(markup).toContain(">Вывезено"); expect(markup).not.toContain(">Водитель"); }); it("без звонков шаг «Звонок» не отмечен пройденным", () => { const markup = renderToStaticMarkup(); expect(getAutocallStepState([])).toBe("empty"); // ни один ✓ не должен стоять на шаге звонка: до звонка и на нём самом пройдены только Добавлен и SMS const callSegment = markup.slice(markup.indexOf(">Звонок") - 400, markup.indexOf(">Звонок")); expect(callSegment.split("✓").length - 1).toBe(0); }); it("согласованный роботом слот отмечает шаг «Звонок» пройденным", () => { const logs = [call("confirmed")]; const markup = renderToStaticMarkup(); expect(getAutocallStepState(logs)).toBe("done"); const callSegment = markup.slice(markup.indexOf(">Звонок") - 400, markup.indexOf(">Звонок")); expect(callSegment).toContain("✓"); }); it("неудачные звонки дают состояние «требует внимания», а не «пройдено»", () => { const logs = [call("no_answer")]; expect(getAutocallStepState(logs)).toBe("warn"); const markup = renderToStaticMarkup(); const callSegment = markup.slice(markup.indexOf(">Звонок") - 400, markup.indexOf(">Звонок")); expect(callSegment).not.toContain("✓"); expect(callSegment).toContain("🤖"); expect(callSegment).toContain("--color-warning"); }); it("подсказка к шагу описывает последний звонок словами логиста", () => { expect(autocallStepHint([])).toBe("Звонков не было"); expect(autocallStepHint([call("no_answer")])).toBe("Звонков: 1 · последний: не взял трубку"); expect(autocallStepHint([call("confirmed", { was_test_mode: true })])) .toBe("Звонков: 1 · последний: клиент согласовал слот · 🧪 тест"); }); });