All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 30m53s
142 lines
4.3 KiB
TypeScript
142 lines
4.3 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
import { FlyerPersistenceService } from './flyerPersistenceService.server';
|
|
import { withTransaction } from './db/connection.db';
|
|
import { createFlyerAndItems } from './db/flyer.db';
|
|
import { AdminRepository } from './db/admin.db';
|
|
import type { FlyerInsert, FlyerItemInsert, Flyer } from '../types';
|
|
import type { Logger } from 'pino';
|
|
import type { PoolClient } from 'pg';
|
|
|
|
// Mock dependencies
|
|
vi.mock('./db/connection.db', () => ({
|
|
withTransaction: vi.fn(),
|
|
}));
|
|
|
|
vi.mock('./db/flyer.db', () => ({
|
|
createFlyerAndItems: vi.fn(),
|
|
}));
|
|
|
|
vi.mock('./db/admin.db', () => ({
|
|
AdminRepository: vi.fn(),
|
|
}));
|
|
|
|
describe('FlyerPersistenceService', () => {
|
|
let service: FlyerPersistenceService;
|
|
let mockLogger: Logger;
|
|
let mockClient: PoolClient;
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
service = new FlyerPersistenceService();
|
|
|
|
mockLogger = {
|
|
info: vi.fn(),
|
|
error: vi.fn(),
|
|
warn: vi.fn(),
|
|
debug: vi.fn(),
|
|
child: vi.fn().mockReturnThis(),
|
|
} as unknown as Logger;
|
|
|
|
mockClient = { query: vi.fn() } as unknown as PoolClient;
|
|
|
|
// Mock withTransaction to execute the callback immediately with a mock client
|
|
vi.mocked(withTransaction).mockImplementation(async (callback) => {
|
|
return callback(mockClient);
|
|
});
|
|
});
|
|
|
|
describe('saveFlyer', () => {
|
|
const mockFlyerData = {
|
|
file_name: 'test.jpg',
|
|
store_name: 'Test Store',
|
|
image_url: 'http://example.com/image.jpg',
|
|
icon_url: 'http://example.com/icon.jpg',
|
|
checksum: 'abc',
|
|
status: 'processed',
|
|
item_count: 0,
|
|
} as FlyerInsert;
|
|
|
|
const mockItemsForDb: FlyerItemInsert[] = [];
|
|
|
|
const mockCreatedFlyer = {
|
|
flyer_id: 1,
|
|
file_name: 'test.jpg',
|
|
store_id: 10,
|
|
// ... other fields
|
|
} as Flyer;
|
|
|
|
const mockCreatedItems: any[] = [];
|
|
|
|
it('should save flyer and items, and log activity if userId is provided', async () => {
|
|
const userId = 'user-123';
|
|
|
|
vi.mocked(createFlyerAndItems).mockResolvedValue({
|
|
flyer: mockCreatedFlyer,
|
|
items: mockCreatedItems,
|
|
});
|
|
|
|
const mockLogActivity = vi.fn();
|
|
// Mock the AdminRepository constructor to return an object with logActivity
|
|
vi.mocked(AdminRepository).mockImplementation(() => ({
|
|
logActivity: mockLogActivity,
|
|
} as any));
|
|
|
|
const result = await service.saveFlyer(mockFlyerData, mockItemsForDb, userId, mockLogger);
|
|
|
|
expect(withTransaction).toHaveBeenCalled();
|
|
expect(createFlyerAndItems).toHaveBeenCalledWith(
|
|
mockFlyerData,
|
|
mockItemsForDb,
|
|
mockLogger,
|
|
mockClient
|
|
);
|
|
expect(mockLogger.info).toHaveBeenCalledWith(
|
|
expect.stringContaining('Successfully processed flyer')
|
|
);
|
|
|
|
// Verify AdminRepository usage
|
|
expect(AdminRepository).toHaveBeenCalledWith(mockClient);
|
|
expect(mockLogActivity).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
userId,
|
|
action: 'flyer_processed',
|
|
displayText: `Processed a new flyer for ${mockFlyerData.store_name}.`,
|
|
details: { flyerId: mockCreatedFlyer.flyer_id, storeName: mockFlyerData.store_name },
|
|
}),
|
|
mockLogger
|
|
);
|
|
|
|
expect(result).toEqual(mockCreatedFlyer);
|
|
});
|
|
|
|
it('should save flyer and items, but NOT log activity if userId is undefined', async () => {
|
|
const userId = undefined;
|
|
|
|
vi.mocked(createFlyerAndItems).mockResolvedValue({
|
|
flyer: mockCreatedFlyer,
|
|
items: mockCreatedItems,
|
|
});
|
|
|
|
const mockLogActivity = vi.fn();
|
|
vi.mocked(AdminRepository).mockImplementation(() => ({
|
|
logActivity: mockLogActivity,
|
|
} as any));
|
|
|
|
const result = await service.saveFlyer(mockFlyerData, mockItemsForDb, userId, mockLogger);
|
|
|
|
expect(createFlyerAndItems).toHaveBeenCalled();
|
|
expect(AdminRepository).not.toHaveBeenCalled();
|
|
expect(mockLogActivity).not.toHaveBeenCalled();
|
|
expect(result).toEqual(mockCreatedFlyer);
|
|
});
|
|
|
|
it('should propagate errors from createFlyerAndItems', async () => {
|
|
const error = new Error('DB Error');
|
|
vi.mocked(createFlyerAndItems).mockRejectedValue(error);
|
|
|
|
await expect(
|
|
service.saveFlyer(mockFlyerData, mockItemsForDb, 'user-1', mockLogger)
|
|
).rejects.toThrow(error);
|
|
});
|
|
});
|
|
}); |