812 lines
22 KiB
JavaScript
812 lines
22 KiB
JavaScript
import { getClientWithToken } from '../apollo/client';
|
||
import * as GQL from '../types';
|
||
import { CustomersService } from './customers';
|
||
import { ERRORS, OrdersService } from './orders';
|
||
import { ServicesService } from './services';
|
||
import { SlotsService } from './slots';
|
||
import dayjs from 'dayjs';
|
||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||
|
||
vi.mock('../apollo/client');
|
||
vi.mock('./customers');
|
||
vi.mock('./services');
|
||
vi.mock('./slots');
|
||
vi.mock('../config/env', () => {
|
||
return {
|
||
env: {
|
||
BOT_TOKEN: 'test',
|
||
LOGIN_GRAPHQL: 'test',
|
||
PASSWORD_GRAPHQL: 'test',
|
||
URL_GRAPHQL: 'test',
|
||
},
|
||
};
|
||
});
|
||
|
||
const mockGetClientWithToken = vi.mocked(getClientWithToken);
|
||
const mockCustomersService = vi.mocked(CustomersService);
|
||
const mockServicesService = vi.mocked(ServicesService);
|
||
const mockSlotsService = vi.mocked(SlotsService);
|
||
|
||
describe('OrdersService', () => {
|
||
/**
|
||
* @type {OrdersService}
|
||
*/
|
||
let ordersService;
|
||
const mockUser = { telegramId: 123_456_789 };
|
||
|
||
const mockCustomer = {
|
||
active: true,
|
||
documentId: 'customer-123',
|
||
firstName: 'John',
|
||
lastName: 'Doe',
|
||
role: GQL.Enum_Customer_Role.Customer,
|
||
telegramId: 123_456_789,
|
||
};
|
||
|
||
const mockMaster = {
|
||
active: true,
|
||
documentId: 'master-123',
|
||
firstName: 'Jane',
|
||
lastName: 'Master',
|
||
role: GQL.Enum_Customer_Role.Master,
|
||
telegramId: 987_654_321,
|
||
};
|
||
|
||
const now = dayjs().minute(0).second(0).millisecond(0);
|
||
vi.setSystemTime(now.toDate());
|
||
|
||
const mockSlot = {
|
||
datetime_end: now.add(6, 'hour').toISOString(),
|
||
datetime_start: now.toISOString(),
|
||
documentId: 'slot-123',
|
||
master: mockMaster,
|
||
orders: [],
|
||
state: GQL.Enum_Slot_State.Open,
|
||
};
|
||
|
||
const mockService = {
|
||
active: true,
|
||
documentId: 'service-123',
|
||
duration: '01:00:00', // 1 час
|
||
master: mockMaster,
|
||
name: 'Test Service',
|
||
};
|
||
|
||
const mockOrder = {
|
||
client: mockCustomer,
|
||
datetime_end: now.add(1, 'hour').toISOString(),
|
||
datetime_start: now.toISOString(),
|
||
documentId: 'order-123',
|
||
services: [mockService],
|
||
slot: mockSlot,
|
||
state: GQL.Enum_Order_State.Created,
|
||
};
|
||
|
||
const mockGetCustomerResult = {
|
||
data: {
|
||
customers: [mockCustomer],
|
||
},
|
||
};
|
||
|
||
beforeEach(() => {
|
||
ordersService = new OrdersService(mockUser);
|
||
vi.clearAllMocks();
|
||
});
|
||
|
||
afterEach(() => {
|
||
vi.restoreAllMocks();
|
||
});
|
||
|
||
describe('createOrder', () => {
|
||
const mockVariables = {
|
||
input: {
|
||
client: 'customer-123',
|
||
datetime_end: now.add(1, 'hour').toISOString(),
|
||
datetime_start: now.toISOString(),
|
||
services: ['service-123'],
|
||
slot: 'slot-123',
|
||
},
|
||
};
|
||
|
||
const mockMutationResult = {
|
||
data: {
|
||
createOrder: mockOrder,
|
||
},
|
||
errors: undefined,
|
||
};
|
||
|
||
it('should successfully create order for customer', async () => {
|
||
const mockMutate = vi.fn().mockResolvedValue(mockMutationResult);
|
||
const mockQuery = vi.fn().mockImplementation(({ query }) => {
|
||
if (query === GQL.GetCustomerDocument) {
|
||
return Promise.resolve(mockGetCustomerResult);
|
||
}
|
||
|
||
if (query === GQL.GetOrdersDocument) {
|
||
return Promise.resolve({ data: { orders: [] } }); // нет пересекающихся заказов
|
||
}
|
||
|
||
return Promise.resolve({ data: {} });
|
||
});
|
||
|
||
mockGetClientWithToken.mockResolvedValue({
|
||
mutate: mockMutate,
|
||
query: mockQuery,
|
||
});
|
||
|
||
// Мокаем ServicesService.getService
|
||
const mockGetService = vi.fn().mockResolvedValue({
|
||
service: mockService,
|
||
});
|
||
mockServicesService.mockImplementation(() => ({
|
||
getService: mockGetService,
|
||
}));
|
||
|
||
// Мокаем SlotsService.getSlot
|
||
const mockGetSlot = vi.fn().mockResolvedValue({
|
||
slot: mockSlot,
|
||
});
|
||
mockSlotsService.mockImplementation(() => ({
|
||
getSlot: mockGetSlot,
|
||
}));
|
||
|
||
// Мокаем CustomersService.getCustomer
|
||
const mockGetCustomer = vi.fn().mockResolvedValue({
|
||
customer: mockCustomer,
|
||
});
|
||
mockCustomersService.mockImplementation(() => ({
|
||
getCustomer: mockGetCustomer,
|
||
getMasters: vi.fn().mockResolvedValue({
|
||
masters: [mockMaster],
|
||
}),
|
||
}));
|
||
|
||
const result = ordersService.createOrder(mockVariables);
|
||
|
||
await expect(result).resolves.toBe(mockMutationResult.data);
|
||
});
|
||
|
||
it('should successfully create approved order for master', async () => {
|
||
const masterCustomer = {
|
||
...mockCustomer,
|
||
role: GQL.Enum_Customer_Role.Master,
|
||
};
|
||
|
||
const masterSlot = {
|
||
...mockSlot,
|
||
master: masterCustomer,
|
||
};
|
||
|
||
const mockMutate = vi.fn().mockResolvedValue(mockMutationResult);
|
||
const mockQuery = vi.fn().mockImplementation(({ query }) => {
|
||
if (query === GQL.GetCustomerDocument) {
|
||
return Promise.resolve({
|
||
data: { customers: [masterCustomer] },
|
||
});
|
||
}
|
||
|
||
if (query === GQL.GetOrdersDocument) {
|
||
return Promise.resolve({ data: { orders: [] } });
|
||
}
|
||
|
||
return Promise.resolve({ data: {} });
|
||
});
|
||
|
||
mockGetClientWithToken.mockResolvedValue({
|
||
mutate: mockMutate,
|
||
query: mockQuery,
|
||
});
|
||
|
||
const mockGetService = vi.fn().mockResolvedValue({
|
||
service: mockService,
|
||
});
|
||
mockServicesService.mockImplementation(() => ({
|
||
getService: mockGetService,
|
||
}));
|
||
|
||
const mockGetSlot = vi.fn().mockResolvedValue({
|
||
slot: masterSlot,
|
||
});
|
||
mockSlotsService.mockImplementation(() => ({
|
||
getSlot: mockGetSlot,
|
||
}));
|
||
|
||
const mockGetCustomer = vi.fn().mockResolvedValue({
|
||
customer: masterCustomer,
|
||
});
|
||
mockCustomersService.mockImplementation(() => ({
|
||
getCustomer: mockGetCustomer,
|
||
getMasters: vi.fn().mockResolvedValue({
|
||
masters: [masterCustomer],
|
||
}),
|
||
}));
|
||
|
||
const result = ordersService.createOrder({
|
||
...mockVariables,
|
||
input: {
|
||
...mockVariables.input,
|
||
client: masterCustomer.documentId,
|
||
},
|
||
});
|
||
|
||
await expect(result).resolves.toBe(mockMutationResult.data);
|
||
});
|
||
|
||
it('should throw error when slot is missing', async () => {
|
||
const variablesWithoutSlot = {
|
||
input: {
|
||
client: 'customer-123',
|
||
datetime_start: now.toISOString(),
|
||
services: ['service-123'],
|
||
},
|
||
};
|
||
|
||
const result = ordersService.createOrder(variablesWithoutSlot);
|
||
|
||
await expect(result).rejects.toThrow(ERRORS.MISSING_SLOT);
|
||
});
|
||
|
||
it('should throw error when services are missing', async () => {
|
||
const variablesWithoutServices = {
|
||
input: {
|
||
client: 'customer-123',
|
||
datetime_start: now.toISOString(),
|
||
slot: 'slot-123',
|
||
},
|
||
};
|
||
|
||
const result = ordersService.createOrder(variablesWithoutServices);
|
||
|
||
await expect(result).rejects.toThrow(ERRORS.MISSING_SERVICES);
|
||
});
|
||
|
||
it('should throw error when datetime_start is missing', async () => {
|
||
const variablesWithoutStart = {
|
||
input: {
|
||
client: 'customer-123',
|
||
services: ['service-123'],
|
||
slot: 'slot-123',
|
||
},
|
||
};
|
||
|
||
const result = ordersService.createOrder(variablesWithoutStart);
|
||
|
||
await expect(result).rejects.toThrow(ERRORS.MISSING_START_TIME);
|
||
});
|
||
|
||
it('should throw error when datetime_end is missing', async () => {
|
||
const variablesWithoutEnd = {
|
||
input: {
|
||
client: 'customer-123',
|
||
datetime_start: now.toISOString(),
|
||
services: ['service-123'],
|
||
slot: 'slot-123',
|
||
},
|
||
};
|
||
|
||
const result = ordersService.createOrder(variablesWithoutEnd);
|
||
|
||
await expect(result).rejects.toThrow(ERRORS.MISSING_END_TIME);
|
||
});
|
||
|
||
it('should throw error when client is missing', async () => {
|
||
const variablesWithoutClient = {
|
||
input: {
|
||
datetime_start: now.toISOString(),
|
||
services: ['service-123'],
|
||
slot: 'slot-123',
|
||
},
|
||
};
|
||
|
||
const result = ordersService.createOrder(variablesWithoutClient);
|
||
|
||
await expect(result).rejects.toThrow(ERRORS.MISSING_CLIENT);
|
||
});
|
||
|
||
it('should throw error when order time is in the past', async () => {
|
||
const pastTime = now.subtract(1, 'hour');
|
||
const variablesWithPastTime = {
|
||
input: {
|
||
client: 'customer-123',
|
||
datetime_end: pastTime.add(1, 'hour').toISOString(),
|
||
datetime_start: pastTime.toISOString(),
|
||
services: ['service-123'],
|
||
slot: 'slot-123',
|
||
},
|
||
};
|
||
|
||
const result = ordersService.createOrder(variablesWithPastTime);
|
||
|
||
await expect(result).rejects.toThrow(ERRORS.NO_ORDER_IN_PAST);
|
||
});
|
||
|
||
it('should throw error when order time is invalid', async () => {
|
||
const variablesWithInvalidTime = {
|
||
input: {
|
||
client: 'customer-123',
|
||
datetime_end: now.toISOString(), // равно datetime_start
|
||
datetime_start: now.toISOString(),
|
||
services: ['service-123'],
|
||
slot: 'slot-123',
|
||
},
|
||
};
|
||
|
||
const result = ordersService.createOrder(variablesWithInvalidTime);
|
||
|
||
await expect(result).rejects.toThrow(ERRORS.INVALID_TIME);
|
||
});
|
||
|
||
it('should throw error when slot is not found', async () => {
|
||
const mockQuery = vi.fn().mockImplementation(({ query }) => {
|
||
if (query === GQL.GetCustomerDocument) {
|
||
return Promise.resolve(mockGetCustomerResult);
|
||
}
|
||
|
||
return Promise.resolve({ data: {} });
|
||
});
|
||
|
||
mockGetClientWithToken.mockResolvedValue({
|
||
mutate: vi.fn(),
|
||
query: mockQuery,
|
||
});
|
||
|
||
const mockGetSlot = vi.fn().mockResolvedValue({
|
||
slot: null, // слот не найден
|
||
});
|
||
mockSlotsService.mockImplementation(() => ({
|
||
getSlot: mockGetSlot,
|
||
}));
|
||
|
||
const result = ordersService.createOrder(mockVariables);
|
||
|
||
await expect(result).rejects.toThrow(ERRORS.MISSING_SLOT);
|
||
});
|
||
|
||
it('should throw error when order is out of slot time', async () => {
|
||
const mockQuery = vi.fn().mockImplementation(({ query }) => {
|
||
if (query === GQL.GetCustomerDocument) {
|
||
return Promise.resolve(mockGetCustomerResult);
|
||
}
|
||
|
||
return Promise.resolve({ data: {} });
|
||
});
|
||
|
||
mockGetClientWithToken.mockResolvedValue({
|
||
mutate: vi.fn(),
|
||
query: mockQuery,
|
||
});
|
||
|
||
const mockGetSlot = vi.fn().mockResolvedValue({
|
||
slot: mockSlot,
|
||
});
|
||
mockSlotsService.mockImplementation(() => ({
|
||
getSlot: mockGetSlot,
|
||
}));
|
||
|
||
const mockGetCustomer = vi.fn().mockResolvedValue({
|
||
customer: mockCustomer,
|
||
});
|
||
mockCustomersService.mockImplementation(() => ({
|
||
getCustomer: mockGetCustomer,
|
||
getMasters: vi.fn().mockResolvedValue({
|
||
masters: [mockMaster],
|
||
}),
|
||
}));
|
||
|
||
const variablesWithOutOfSlotTime = {
|
||
input: {
|
||
client: 'customer-123',
|
||
datetime_end: now.add(8, 'hour').toISOString(),
|
||
datetime_start: now.add(7, 'hour').toISOString(), // после окончания слота
|
||
services: ['service-123'],
|
||
slot: 'slot-123',
|
||
},
|
||
};
|
||
|
||
const result = ordersService.createOrder(variablesWithOutOfSlotTime);
|
||
|
||
await expect(result).rejects.toThrow(ERRORS.NO_ORDER_OUT_OF_SLOT);
|
||
});
|
||
|
||
it('should throw error when slot is closed', async () => {
|
||
const closedSlot = {
|
||
...mockSlot,
|
||
state: GQL.Enum_Slot_State.Closed,
|
||
};
|
||
|
||
const mockQuery = vi.fn().mockImplementation(({ query }) => {
|
||
if (query === GQL.GetCustomerDocument) {
|
||
return Promise.resolve(mockGetCustomerResult);
|
||
}
|
||
|
||
return Promise.resolve({ data: {} });
|
||
});
|
||
|
||
mockGetClientWithToken.mockResolvedValue({
|
||
mutate: vi.fn(),
|
||
query: mockQuery,
|
||
});
|
||
|
||
const mockGetSlot = vi.fn().mockResolvedValue({
|
||
slot: closedSlot,
|
||
});
|
||
mockSlotsService.mockImplementation(() => ({
|
||
getSlot: mockGetSlot,
|
||
}));
|
||
|
||
const mockGetCustomer = vi.fn().mockResolvedValue({
|
||
customer: mockCustomer,
|
||
});
|
||
mockCustomersService.mockImplementation(() => ({
|
||
getCustomer: mockGetCustomer,
|
||
getMasters: vi.fn().mockResolvedValue({
|
||
masters: [mockMaster],
|
||
}),
|
||
}));
|
||
|
||
const result = ordersService.createOrder(mockVariables);
|
||
|
||
await expect(result).rejects.toThrow(ERRORS.SLOT_CLOSED);
|
||
});
|
||
|
||
it('should throw error when client is not found', async () => {
|
||
const mockQuery = vi.fn().mockImplementation(({ query }) => {
|
||
if (query === GQL.GetCustomerDocument) {
|
||
return Promise.resolve(mockGetCustomerResult);
|
||
}
|
||
|
||
return Promise.resolve({ data: {} });
|
||
});
|
||
|
||
mockGetClientWithToken.mockResolvedValue({
|
||
mutate: vi.fn(),
|
||
query: mockQuery,
|
||
});
|
||
|
||
const mockGetSlot = vi.fn().mockResolvedValue({
|
||
slot: mockSlot,
|
||
});
|
||
mockSlotsService.mockImplementation(() => ({
|
||
getSlot: mockGetSlot,
|
||
}));
|
||
|
||
const mockGetCustomer = vi.fn().mockResolvedValue({
|
||
customer: null, // клиент не найден
|
||
});
|
||
mockCustomersService.mockImplementation(() => ({
|
||
getCustomer: mockGetCustomer,
|
||
getMasters: vi.fn().mockResolvedValue({
|
||
masters: [mockMaster],
|
||
}),
|
||
}));
|
||
|
||
const result = ordersService.createOrder(mockVariables);
|
||
|
||
await expect(result).rejects.toThrow(ERRORS.NOT_FOUND_CLIENT);
|
||
});
|
||
|
||
it('should throw error when client is inactive', async () => {
|
||
const inactiveCustomer = {
|
||
...mockCustomer,
|
||
active: false,
|
||
};
|
||
|
||
const mockQuery = vi.fn().mockImplementation(({ query }) => {
|
||
if (query === GQL.GetCustomerDocument) {
|
||
return Promise.resolve(mockGetCustomerResult);
|
||
}
|
||
|
||
return Promise.resolve({ data: {} });
|
||
});
|
||
|
||
mockGetClientWithToken.mockResolvedValue({
|
||
mutate: vi.fn(),
|
||
query: mockQuery,
|
||
});
|
||
|
||
const mockGetSlot = vi.fn().mockResolvedValue({
|
||
slot: mockSlot,
|
||
});
|
||
mockSlotsService.mockImplementation(() => ({
|
||
getSlot: mockGetSlot,
|
||
}));
|
||
|
||
const mockGetCustomer = vi.fn().mockResolvedValue({
|
||
customer: inactiveCustomer,
|
||
});
|
||
mockCustomersService.mockImplementation(() => ({
|
||
getCustomer: mockGetCustomer,
|
||
getMasters: vi.fn().mockResolvedValue({
|
||
masters: [mockMaster],
|
||
}),
|
||
}));
|
||
|
||
const result = ordersService.createOrder(mockVariables);
|
||
|
||
await expect(result).rejects.toThrow(ERRORS.INACTIVE_CLIENT);
|
||
});
|
||
|
||
it('should throw error when master is inactive', async () => {
|
||
const inactiveMaster = {
|
||
...mockMaster,
|
||
active: false,
|
||
};
|
||
|
||
const slotWithInactiveMaster = {
|
||
...mockSlot,
|
||
master: inactiveMaster,
|
||
};
|
||
|
||
const mockQuery = vi.fn().mockImplementation(({ query }) => {
|
||
if (query === GQL.GetCustomerDocument) {
|
||
return Promise.resolve(mockGetCustomerResult);
|
||
}
|
||
|
||
return Promise.resolve({ data: {} });
|
||
});
|
||
|
||
mockGetClientWithToken.mockResolvedValue({
|
||
mutate: vi.fn(),
|
||
query: mockQuery,
|
||
});
|
||
|
||
const mockGetSlot = vi.fn().mockResolvedValue({
|
||
slot: slotWithInactiveMaster,
|
||
});
|
||
mockSlotsService.mockImplementation(() => ({
|
||
getSlot: mockGetSlot,
|
||
}));
|
||
|
||
const mockGetCustomer = vi.fn().mockResolvedValue({
|
||
customer: mockCustomer,
|
||
});
|
||
mockCustomersService.mockImplementation(() => ({
|
||
getCustomer: mockGetCustomer,
|
||
getMasters: vi.fn().mockResolvedValue({
|
||
masters: [inactiveMaster],
|
||
}),
|
||
}));
|
||
|
||
const result = ordersService.createOrder(mockVariables);
|
||
|
||
await expect(result).rejects.toThrow(ERRORS.INACTIVE_MASTER);
|
||
});
|
||
|
||
it('should throw error when customer tries to book themselves as master', async () => {
|
||
const activeCustomerAsMaster = {
|
||
...mockCustomer,
|
||
active: true,
|
||
role: GQL.Enum_Customer_Role.Master,
|
||
};
|
||
|
||
const slotWithCustomerAsMaster = {
|
||
...mockSlot,
|
||
master: activeCustomerAsMaster,
|
||
};
|
||
|
||
const mockQuery = vi.fn().mockImplementation(({ query }) => {
|
||
if (query === GQL.GetCustomerDocument) {
|
||
return Promise.resolve(mockGetCustomerResult);
|
||
}
|
||
|
||
return Promise.resolve({ data: {} });
|
||
});
|
||
|
||
mockGetClientWithToken.mockResolvedValue({
|
||
mutate: vi.fn(),
|
||
query: mockQuery,
|
||
});
|
||
|
||
const mockGetSlot = vi.fn().mockResolvedValue({
|
||
slot: slotWithCustomerAsMaster,
|
||
});
|
||
mockSlotsService.mockImplementation(() => ({
|
||
getSlot: mockGetSlot,
|
||
}));
|
||
|
||
const mockGetCustomer = vi.fn().mockResolvedValue({
|
||
customer: mockCustomer,
|
||
});
|
||
mockCustomersService.mockImplementation(() => ({
|
||
getCustomer: mockGetCustomer,
|
||
getMasters: vi.fn().mockResolvedValue({
|
||
masters: [activeCustomerAsMaster],
|
||
}),
|
||
}));
|
||
|
||
const result = ordersService.createOrder(mockVariables);
|
||
|
||
await expect(result).rejects.toThrow(ERRORS.NO_MASTER_SELF_BOOK);
|
||
});
|
||
|
||
it('should throw error when customer is not linked to master', async () => {
|
||
const mockQuery = vi.fn().mockImplementation(({ query }) => {
|
||
if (query === GQL.GetCustomerDocument) {
|
||
return Promise.resolve(mockGetCustomerResult);
|
||
}
|
||
|
||
return Promise.resolve({ data: {} });
|
||
});
|
||
|
||
mockGetClientWithToken.mockResolvedValue({
|
||
mutate: vi.fn(),
|
||
query: mockQuery,
|
||
});
|
||
|
||
const mockGetSlot = vi.fn().mockResolvedValue({
|
||
slot: mockSlot,
|
||
});
|
||
mockSlotsService.mockImplementation(() => ({
|
||
getSlot: mockGetSlot,
|
||
}));
|
||
|
||
const mockGetCustomer = vi.fn().mockResolvedValue({
|
||
customer: mockCustomer,
|
||
});
|
||
mockCustomersService.mockImplementation(() => ({
|
||
getCustomer: mockGetCustomer,
|
||
getMasters: vi.fn().mockResolvedValue({
|
||
masters: [], // клиент не связан с мастером
|
||
}),
|
||
}));
|
||
|
||
const result = ordersService.createOrder(mockVariables);
|
||
|
||
await expect(result).rejects.toThrow(ERRORS.INVALID_MASTER);
|
||
});
|
||
|
||
it('should throw error when time overlaps with other orders', async () => {
|
||
const overlappingOrder = {
|
||
...mockOrder,
|
||
documentId: 'order-456',
|
||
};
|
||
|
||
const mockQuery = vi.fn().mockImplementation(({ query }) => {
|
||
if (query === GQL.GetCustomerDocument) {
|
||
return Promise.resolve(mockGetCustomerResult);
|
||
}
|
||
|
||
if (query === GQL.GetOrdersDocument) {
|
||
return Promise.resolve({
|
||
data: { orders: [overlappingOrder] },
|
||
}); // есть пересекающиеся заказы
|
||
}
|
||
|
||
return Promise.resolve({ data: {} });
|
||
});
|
||
|
||
mockGetClientWithToken.mockResolvedValue({
|
||
mutate: vi.fn(),
|
||
query: mockQuery,
|
||
});
|
||
|
||
const mockGetSlot = vi.fn().mockResolvedValue({
|
||
slot: mockSlot,
|
||
});
|
||
mockSlotsService.mockImplementation(() => ({
|
||
getSlot: mockGetSlot,
|
||
}));
|
||
|
||
const mockGetCustomer = vi.fn().mockResolvedValue({
|
||
customer: mockCustomer,
|
||
});
|
||
mockCustomersService.mockImplementation(() => ({
|
||
getCustomer: mockGetCustomer,
|
||
getMasters: vi.fn().mockResolvedValue({
|
||
masters: [mockMaster],
|
||
}),
|
||
}));
|
||
|
||
const result = ordersService.createOrder(mockVariables);
|
||
|
||
await expect(result).rejects.toThrow(ERRORS.OVERLAPPING_TIME);
|
||
});
|
||
|
||
it('should throw error when service duration is invalid', async () => {
|
||
const serviceWithoutDuration = {
|
||
...mockService,
|
||
duration: null,
|
||
};
|
||
|
||
const mockQuery = vi.fn().mockImplementation(({ query }) => {
|
||
if (query === GQL.GetCustomerDocument) {
|
||
return Promise.resolve(mockGetCustomerResult);
|
||
}
|
||
|
||
return Promise.resolve({ data: {} });
|
||
});
|
||
|
||
mockGetClientWithToken.mockResolvedValue({
|
||
mutate: vi.fn(),
|
||
query: mockQuery,
|
||
});
|
||
|
||
const mockGetSlot = vi.fn().mockResolvedValue({
|
||
slot: mockSlot,
|
||
});
|
||
mockSlotsService.mockImplementation(() => ({
|
||
getSlot: mockGetSlot,
|
||
}));
|
||
|
||
const mockGetCustomer = vi.fn().mockResolvedValue({
|
||
customer: mockCustomer,
|
||
});
|
||
mockCustomersService.mockImplementation(() => ({
|
||
getCustomer: mockGetCustomer,
|
||
getMasters: vi.fn().mockResolvedValue({
|
||
masters: [mockMaster],
|
||
}),
|
||
}));
|
||
|
||
const mockGetService = vi.fn().mockResolvedValue({
|
||
service: serviceWithoutDuration,
|
||
});
|
||
mockServicesService.mockImplementation(() => ({
|
||
getService: mockGetService,
|
||
}));
|
||
|
||
const result = ordersService.createOrder(mockVariables);
|
||
|
||
await expect(result).rejects.toThrow(ERRORS.INVALID_SERVICE_DURATION);
|
||
});
|
||
|
||
it('should calculate datetime_end based on service duration', async () => {
|
||
const mockMutate = vi.fn().mockResolvedValue(mockMutationResult);
|
||
const mockQuery = vi.fn().mockImplementation(({ query }) => {
|
||
if (query === GQL.GetCustomerDocument) {
|
||
return Promise.resolve(mockGetCustomerResult);
|
||
}
|
||
|
||
if (query === GQL.GetOrdersDocument) {
|
||
return Promise.resolve({ data: { orders: [] } });
|
||
}
|
||
|
||
return Promise.resolve({ data: {} });
|
||
});
|
||
|
||
mockGetClientWithToken.mockResolvedValue({
|
||
mutate: mockMutate,
|
||
query: mockQuery,
|
||
});
|
||
|
||
const mockGetService = vi.fn().mockResolvedValue({
|
||
service: mockService,
|
||
});
|
||
mockServicesService.mockImplementation(() => ({
|
||
getService: mockGetService,
|
||
}));
|
||
|
||
const mockGetSlot = vi.fn().mockResolvedValue({
|
||
slot: mockSlot,
|
||
});
|
||
mockSlotsService.mockImplementation(() => ({
|
||
getSlot: mockGetSlot,
|
||
}));
|
||
|
||
const mockGetCustomer = vi.fn().mockResolvedValue({
|
||
customer: mockCustomer,
|
||
});
|
||
mockCustomersService.mockImplementation(() => ({
|
||
getCustomer: mockGetCustomer,
|
||
getMasters: vi.fn().mockResolvedValue({
|
||
masters: [mockMaster],
|
||
}),
|
||
}));
|
||
|
||
await ordersService.createOrder(mockVariables);
|
||
|
||
expect(mockMutate).toHaveBeenCalledWith({
|
||
mutation: GQL.CreateOrderDocument,
|
||
variables: {
|
||
...mockVariables,
|
||
input: {
|
||
...mockVariables.input,
|
||
datetime_end: now.add(1, 'hour').toISOString(), // 1 час от начала
|
||
state: GQL.Enum_Order_State.Created,
|
||
},
|
||
},
|
||
});
|
||
});
|
||
});
|
||
});
|