304 lines
7.8 KiB
JavaScript
304 lines
7.8 KiB
JavaScript
import { getClientWithToken } from '../apollo/client';
|
||
import * as GQL from '../types';
|
||
import { ERRORS, SlotsService } from './slots';
|
||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||
|
||
vi.mock('../apollo/client');
|
||
vi.mock('./services');
|
||
vi.mock('../config/env', () => {
|
||
return {
|
||
env: {
|
||
BOT_TOKEN: 'test',
|
||
LOGIN_GRAPHQL: 'test',
|
||
PASSWORD_GRAPHQL: 'test',
|
||
URL_GRAPHQL: 'test',
|
||
},
|
||
};
|
||
});
|
||
|
||
const mockGetClientWithToken = vi.mocked(getClientWithToken);
|
||
|
||
describe('SlotsService', () => {
|
||
let slotsService;
|
||
const mockUser = { telegramId: 123_456_789 };
|
||
|
||
const mockCustomer = {
|
||
documentId: 'customer-123',
|
||
firstName: 'John',
|
||
lastName: 'Doe',
|
||
telegramId: 123_456_789,
|
||
};
|
||
|
||
const mockSlot = {
|
||
datetime_end: '2024-01-01T11:00:00Z',
|
||
datetime_start: '2024-01-01T10:00:00Z',
|
||
documentId: 'slot-123',
|
||
master: mockCustomer,
|
||
orders: [],
|
||
state: GQL.Enum_Slot_State.Open,
|
||
};
|
||
|
||
const mockGetCustomerResult = {
|
||
data: {
|
||
customers: [mockCustomer],
|
||
},
|
||
};
|
||
|
||
const mockGetSlotResult = {
|
||
data: {
|
||
slot: mockSlot,
|
||
},
|
||
};
|
||
|
||
beforeEach(() => {
|
||
slotsService = new SlotsService(mockUser);
|
||
vi.clearAllMocks();
|
||
});
|
||
|
||
afterEach(() => {
|
||
vi.restoreAllMocks();
|
||
});
|
||
|
||
describe('updateSlot', () => {
|
||
const mockVariables = {
|
||
data: {
|
||
datetime_end: '2024-01-01T11:00:00Z',
|
||
datetime_start: '2024-01-01T10:00:00Z',
|
||
state: GQL.Enum_Slot_State.Open,
|
||
},
|
||
documentId: 'slot-123',
|
||
};
|
||
|
||
const mockMutationResult = {
|
||
data: {
|
||
updateSlot: mockSlot,
|
||
},
|
||
errors: undefined,
|
||
};
|
||
|
||
it('should successfully update slot when user has permission', async () => {
|
||
const mockMutate = vi.fn().mockResolvedValue(mockMutationResult);
|
||
const mockQuery = vi
|
||
.fn()
|
||
.mockResolvedValueOnce(mockGetCustomerResult)
|
||
.mockResolvedValueOnce(mockGetSlotResult);
|
||
|
||
mockGetClientWithToken.mockResolvedValue({
|
||
mutate: mockMutate,
|
||
query: mockQuery,
|
||
});
|
||
|
||
const result = slotsService.updateSlot(mockVariables);
|
||
|
||
await expect(result).resolves.toBe(mockMutationResult.data);
|
||
});
|
||
|
||
it('should throw error when user does not have permission', async () => {
|
||
const unrelatedCustomer = {
|
||
...mockCustomer,
|
||
documentId: 'different-customer-123',
|
||
};
|
||
|
||
const mockQuery = vi
|
||
.fn()
|
||
.mockResolvedValueOnce({
|
||
data: { customers: [unrelatedCustomer] },
|
||
})
|
||
.mockResolvedValueOnce({
|
||
data: { slot: mockSlot }, // slot принадлежит другому пользователю
|
||
});
|
||
|
||
mockGetClientWithToken.mockResolvedValue({
|
||
mutate: vi.fn(),
|
||
query: mockQuery,
|
||
});
|
||
|
||
const result = slotsService.updateSlot(mockVariables);
|
||
|
||
await expect(result).rejects.toThrow(ERRORS.NO_PERMISSION);
|
||
});
|
||
|
||
it('should throw error when slot does not exist', async () => {
|
||
const mockQuery = vi
|
||
.fn()
|
||
.mockResolvedValueOnce(mockGetCustomerResult)
|
||
.mockResolvedValueOnce({
|
||
data: { slot: null }, // slot не найден
|
||
});
|
||
|
||
mockGetClientWithToken.mockResolvedValue({
|
||
mutate: vi.fn(),
|
||
query: mockQuery,
|
||
});
|
||
|
||
const result = slotsService.updateSlot(mockVariables);
|
||
|
||
await expect(result).rejects.toThrow();
|
||
});
|
||
|
||
it('should throw error when customer is not found', async () => {
|
||
const mockQuery = vi.fn().mockResolvedValue({
|
||
data: { customers: [] }, // пользователь не найден
|
||
});
|
||
|
||
mockGetClientWithToken.mockResolvedValue({
|
||
mutate: vi.fn(),
|
||
query: mockQuery,
|
||
});
|
||
|
||
const result = slotsService.updateSlot(mockVariables);
|
||
|
||
await expect(result).rejects.toThrow('Customer not found');
|
||
});
|
||
});
|
||
|
||
describe('checkPermission', () => {
|
||
const mockVariables = {
|
||
documentId: 'slot-123',
|
||
};
|
||
|
||
it('should not throw error when user has permission', async () => {
|
||
const mockQuery = vi
|
||
.fn()
|
||
.mockResolvedValueOnce(mockGetCustomerResult)
|
||
.mockResolvedValueOnce(mockGetSlotResult);
|
||
|
||
mockGetClientWithToken.mockResolvedValue({
|
||
query: mockQuery,
|
||
});
|
||
|
||
const result = slotsService.checkPermission(mockVariables);
|
||
|
||
await expect(result).resolves.toBeUndefined();
|
||
});
|
||
|
||
it('should throw error when user does not have permission', async () => {
|
||
const unrelatedCustomer = {
|
||
...mockCustomer,
|
||
documentId: 'different-customer-123',
|
||
};
|
||
|
||
const mockQuery = vi
|
||
.fn()
|
||
.mockResolvedValueOnce({
|
||
data: { customers: [unrelatedCustomer] },
|
||
})
|
||
.mockResolvedValueOnce({
|
||
data: { slot: mockSlot }, // slot принадлежит другому пользователю
|
||
});
|
||
|
||
mockGetClientWithToken.mockResolvedValue({
|
||
query: mockQuery,
|
||
});
|
||
|
||
const result = slotsService.checkPermission(mockVariables);
|
||
|
||
await expect(result).rejects.toThrow(ERRORS.NO_PERMISSION);
|
||
});
|
||
|
||
it('should throw error when slot does not exist', async () => {
|
||
const mockQuery = vi
|
||
.fn()
|
||
.mockResolvedValueOnce(mockGetCustomerResult)
|
||
.mockResolvedValueOnce({
|
||
data: { slot: null }, // slot не найден
|
||
});
|
||
|
||
mockGetClientWithToken.mockResolvedValue({
|
||
query: mockQuery,
|
||
});
|
||
|
||
const result = slotsService.checkPermission(mockVariables);
|
||
|
||
await expect(result).rejects.toThrow();
|
||
});
|
||
});
|
||
|
||
describe('deleteSlot', () => {
|
||
const mockVariables = {
|
||
documentId: 'slot-123',
|
||
};
|
||
|
||
const mockMutationResult = {
|
||
data: {
|
||
deleteSlot: {
|
||
documentId: 'slot-123',
|
||
},
|
||
},
|
||
errors: undefined,
|
||
};
|
||
|
||
it('should successfully delete slot when no orders', async () => {
|
||
const mockMutate = vi.fn().mockResolvedValue(mockMutationResult);
|
||
const mockQuery = vi
|
||
.fn()
|
||
.mockResolvedValueOnce(mockGetCustomerResult)
|
||
.mockResolvedValue(mockGetSlotResult);
|
||
|
||
mockGetClientWithToken.mockResolvedValue({
|
||
mutate: mockMutate,
|
||
query: mockQuery,
|
||
});
|
||
|
||
const result = slotsService.deleteSlot(mockVariables);
|
||
|
||
await expect(result).resolves.toBe(mockMutationResult.data);
|
||
});
|
||
|
||
it('should throw error when slot has orders', async () => {
|
||
const slotWithOrders = {
|
||
...mockSlot,
|
||
orders: [
|
||
{
|
||
datetime_end: '2024-01-01T11:00:00Z',
|
||
datetime_start: '2024-01-01T10:00:00Z',
|
||
documentId: 'order-123',
|
||
state: GQL.Enum_Order_State.Scheduled,
|
||
},
|
||
],
|
||
};
|
||
|
||
const mockQuery = vi
|
||
.fn()
|
||
.mockResolvedValueOnce(mockGetCustomerResult)
|
||
.mockResolvedValue({
|
||
data: { slot: slotWithOrders }, // slot с заказами
|
||
});
|
||
|
||
mockGetClientWithToken.mockResolvedValue({
|
||
mutate: vi.fn(),
|
||
query: mockQuery,
|
||
});
|
||
|
||
const result = slotsService.deleteSlot(mockVariables);
|
||
|
||
await expect(result).rejects.toThrow(ERRORS.HAS_ORDERS);
|
||
});
|
||
|
||
it('should throw error when user does not have permission', async () => {
|
||
const unrelatedCustomer = {
|
||
...mockCustomer,
|
||
documentId: 'different-customer-123',
|
||
};
|
||
|
||
const mockQuery = vi
|
||
.fn()
|
||
.mockResolvedValueOnce({
|
||
data: { customers: [unrelatedCustomer] },
|
||
})
|
||
.mockResolvedValueOnce({
|
||
data: { slot: mockSlot }, // slot принадлежит другому пользователю
|
||
});
|
||
|
||
mockGetClientWithToken.mockResolvedValue({
|
||
mutate: vi.fn(),
|
||
query: mockQuery,
|
||
});
|
||
|
||
const result = slotsService.deleteSlot(mockVariables);
|
||
|
||
await expect(result).rejects.toThrow(ERRORS.NO_PERMISSION);
|
||
});
|
||
});
|
||
});
|