import { describe, expect, it } from "vitest"; import { getStatusOwnerRole } from "../constants/deliveryWorkflow"; import { demoOrders, demoUsers } from "../data/mockAppData"; import { assignDriverToOrder, applyStatusUpdate, autoAssignOrders, buildMetrics, cloneOrders, createOrderRecord, filterOrdersByView, getKanbanDropResolution, getAvailableTransitions, } from "./orderService"; describe("orderService", () => { it("lets manager see the whole pipeline", () => { const result = filterOrdersByView({ orders: cloneOrders(demoOrders), currentUser: demoUsers[0], filters: { query: "", status: "all", stage: "all", ownerRole: "all", agingState: "all", managerId: "all", logisticianId: "all", messenger: "all", }, }); expect(result.visibleOrders).toHaveLength(demoOrders.length); expect(result.filteredOrders).toHaveLength(demoOrders.length); }); it("shows employees all orders in their responsibility zone", () => { const driver = demoUsers.find((user) => user.role === "driver"); const result = filterOrdersByView({ orders: cloneOrders(demoOrders), currentUser: driver, filters: { query: "", status: "all", stage: "all", ownerRole: "all", agingState: "all", managerId: "all", logisticianId: "all", messenger: "all", }, }); const expectedDriverOrders = demoOrders.filter((order) => getStatusOwnerRole(order.status) === "driver"); expect(result.visibleOrders).toHaveLength(expectedDriverOrders.length); expect(result.visibleOrders.every((order) => getStatusOwnerRole(order.status) === "driver")).toBe(true); }); it("finds orders by customer phone, stage, owner role and aging state", () => { const result = filterOrdersByView({ orders: cloneOrders(demoOrders), currentUser: demoUsers[0], filters: { query: "+7 978 000-12-31", status: "all", stage: "logistics", ownerRole: "logistician", agingState: "warning", managerId: "all", logisticianId: "all", messenger: "all", }, now: "2026-03-15T12:00:00Z", }); expect(result.filteredOrders).toHaveLength(1); expect(result.filteredOrders[0].orderNumber).toBe("CD-240031"); }); it("updates status and prepends history record", () => { const nextOrder = applyStatusUpdate(demoOrders[0], "Доставка согласована", "Ольга Синицына"); expect(nextOrder.status).toBe("Доставка согласована"); expect(nextOrder.history[0].action).toBe("Изменение статуса"); expect(nextOrder.history[0].newStatus).toBe("Доставка согласована"); }); it("assigns a driver and records the action in history", () => { const nextOrder = assignDriverToOrder(demoOrders[0], "u-driver", "Ольга Синицына"); expect(nextOrder.assignedDriverId).toBe("u-driver"); expect(nextOrder.history[0].action).toBe("Назначение водителя"); expect(nextOrder.history[0].userName).toBe("Ольга Синицына"); }); it("returns role-scoped transitions for logistics stage", () => { const transitions = getAvailableTransitions({ status: "Ожидает согласования доставки", role: "logistician", }); expect(transitions).toEqual(["Доставка согласована", "Проблема доставки", "Отменён"]); }); it("lets manager move orders across the full workflow from the shared board", () => { const transitions = getAvailableTransitions({ status: "Ожидает согласования доставки", role: "manager", }); expect(transitions).toEqual(["Доставка согласована", "Проблема доставки", "Отменён"]); }); it("lets logisticians hand orders off into delivery only when a driver is assigned", () => { const assignedOrder = { ...demoOrders.find((order) => order.status === "Доставка согласована"), assignedDriverId: "u-driver", }; const blockedOrder = { ...assignedOrder, assignedDriverId: null, }; const deliveryColumn = { key: "delivery", title: "Доставка", statuses: ["Назначен водитель", "Загружен", "В пути"], }; expect( getKanbanDropResolution({ order: assignedOrder, column: deliveryColumn, role: "logistician", }), ).toMatchObject({ nextStatus: "Назначен водитель" }); expect( getKanbanDropResolution({ order: blockedOrder, column: deliveryColumn, role: "logistician", }), ).toMatchObject({ nextStatus: null, reason: "Сначала назначьте водителя, потом заказ можно передать в доставку.", }); }); it("creates a new order draft with assigned logistician", () => { const logisticians = demoUsers.filter((user) => user.role === "logistician"); const order = createOrderRecord({ actorName: "Анна Мельник", availableLogisticians: logisticians, payload: { orderNumber: "CD-900000", customerName: "Тест Клиент", customerPhone: "+7 978 777-00-00", customerAddress: "Симферополь", messenger: "СМС", managerId: "u-manager", deliveryDate: "2026-03-15", items: "Тестовая позиция", comments: "важно", tags: "новый", }, }); expect(order.status).toBe("Новый"); expect(order.deliveryAgreementStatus).toBe("Не начато"); expect(order.logisticianIds).toHaveLength(1); expect(order.history[0].action).toBe("Создание заказа"); }); it("auto distributes orders across logisticians", () => { const logisticians = demoUsers.filter((user) => user.role === "logistician"); const assigned = autoAssignOrders(cloneOrders(demoOrders), logisticians); expect(assigned[0].logisticianIds[0]).toBe(logisticians[0].id); expect(assigned[1].logisticianIds[0]).toBe(logisticians[1].id); }); it("builds dashboard metrics", () => { const metrics = buildMetrics(demoOrders); expect(metrics.total).toBe(demoOrders.length); expect(metrics.readyToShip).toBe(demoOrders.filter((order) => order.status === "Готов к отгрузке").length); expect(metrics.awaitingDeliveryCoordination).toBe( demoOrders.filter((order) => order.status === "Ожидает согласования доставки").length, ); expect(metrics.exceptions).toBe(demoOrders.filter((order) => order.status === "Проблема доставки").length); }); it("ships with an expanded demo dataset across the workflow", () => { expect(demoOrders.length).toBeGreaterThanOrEqual(32); expect(new Set(demoOrders.map((order) => order.status)).size).toBeGreaterThanOrEqual(10); expect( demoOrders.some((order) => order.status === "Доставка согласована" && order.assignedDriverId), ).toBe(true); expect( demoOrders.every((order) => Number.isFinite(new Date(order.createdAt).getTime())), ).toBe(true); expect( demoOrders.every((order) => Number.isFinite(new Date(order.scheduledDelivery).getTime())), ).toBe(true); }); });