Some checks failed
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Failing after 5m16s
App.ts refactor into hooks unit tests
112 lines
5.0 KiB
TypeScript
112 lines
5.0 KiB
TypeScript
// src/services/db/address.db.test.ts
|
|
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
import { mockPoolInstance } from '../../tests/setup/tests-setup-unit';
|
|
import { AddressRepository } from './address.db';
|
|
import type { Address } from '../../types';
|
|
import { UniqueConstraintError } from './errors.db';
|
|
|
|
// Un-mock the module we are testing
|
|
vi.unmock('./address.db');
|
|
|
|
// Mock dependencies
|
|
vi.mock('../logger.server', () => ({
|
|
logger: { info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() },
|
|
}));
|
|
|
|
describe('Address DB Service', () => {
|
|
let addressRepo: AddressRepository;
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
addressRepo = new AddressRepository(mockPoolInstance as any);
|
|
});
|
|
|
|
describe('getAddressById', () => {
|
|
it('should return an address if found', async () => {
|
|
const mockAddress: Address = { address_id: 1, address_line_1: '123 Main St', city: 'Anytown', province_state: 'CA', postal_code: '12345', country: 'USA' };
|
|
mockPoolInstance.query.mockResolvedValue({ rows: [mockAddress] });
|
|
|
|
const result = await addressRepo.getAddressById(1);
|
|
|
|
expect(result).toEqual(mockAddress);
|
|
expect(mockPoolInstance.query).toHaveBeenCalledWith('SELECT * FROM public.addresses WHERE address_id = $1', [1]);
|
|
});
|
|
|
|
it('should return undefined if no address is found', async () => {
|
|
mockPoolInstance.query.mockResolvedValue({ rows: [] });
|
|
const result = await addressRepo.getAddressById(999);
|
|
expect(result).toBeUndefined();
|
|
});
|
|
|
|
it('should throw an error if the database query fails', async () => {
|
|
const dbError = new Error('DB Error');
|
|
mockPoolInstance.query.mockRejectedValue(dbError);
|
|
|
|
await expect(addressRepo.getAddressById(1)).rejects.toThrow('Failed to retrieve address.');
|
|
});
|
|
});
|
|
|
|
describe('upsertAddress', () => {
|
|
it('should perform an INSERT when no address_id is provided', async () => {
|
|
const newAddressData = { address_line_1: '456 New Ave', city: 'Newville' };
|
|
mockPoolInstance.query.mockResolvedValue({ rows: [{ address_id: 2 }] });
|
|
|
|
const result = await addressRepo.upsertAddress(newAddressData);
|
|
|
|
expect(result).toBe(2);
|
|
expect(mockPoolInstance.query).toHaveBeenCalledWith(expect.stringContaining('INSERT INTO public.addresses'), expect.any(Array));
|
|
expect(mockPoolInstance.query).not.toHaveBeenCalledWith(expect.stringContaining('UPDATE public.addresses'), expect.any(Array));
|
|
});
|
|
|
|
it('should perform an INSERT with location when lat/lng are provided', async () => {
|
|
const newAddressData = { address_line_1: '789 Geo St', latitude: 45.0, longitude: -75.0 };
|
|
mockPoolInstance.query.mockResolvedValue({ rows: [{ address_id: 3 }] });
|
|
|
|
await addressRepo.upsertAddress(newAddressData);
|
|
|
|
// Check that the query string includes the ST_MakePoint function call
|
|
const [query, values] = mockPoolInstance.query.mock.calls[0];
|
|
expect(query).toContain('ST_SetSRID(ST_MakePoint(');
|
|
// Verify that longitude and latitude are the last two parameters
|
|
expect(values).toContain(-75.0);
|
|
expect(values).toContain(45.0);
|
|
});
|
|
|
|
it('should perform an UPDATE when an address_id is provided', async () => {
|
|
const existingAddressData = { address_id: 1, address_line_1: '789 Old Rd', city: 'Oldtown' };
|
|
mockPoolInstance.query.mockResolvedValue({ rows: [{ address_id: 1 }] });
|
|
|
|
const result = await addressRepo.upsertAddress(existingAddressData);
|
|
|
|
expect(result).toBe(1);
|
|
expect(mockPoolInstance.query).toHaveBeenCalledWith(expect.stringContaining('UPDATE public.addresses'), expect.any(Array));
|
|
expect(mockPoolInstance.query).not.toHaveBeenCalledWith(expect.stringContaining('INSERT INTO public.addresses'), expect.any(Array));
|
|
});
|
|
|
|
it('should throw a generic error on INSERT failure', async () => {
|
|
const newAddressData = { address_line_1: '456 New Ave', city: 'Newville' };
|
|
const dbError = new Error('DB Error');
|
|
mockPoolInstance.query.mockRejectedValue(dbError);
|
|
|
|
await expect(addressRepo.upsertAddress(newAddressData)).rejects.toThrow('Failed to upsert address.');
|
|
});
|
|
|
|
it('should throw a generic error on UPDATE failure', async () => {
|
|
const existingAddressData = { address_id: 1, address_line_1: '789 Old Rd', city: 'Oldtown' };
|
|
const dbError = new Error('DB Error');
|
|
mockPoolInstance.query.mockRejectedValue(dbError);
|
|
|
|
await expect(addressRepo.upsertAddress(existingAddressData)).rejects.toThrow('Failed to upsert address.');
|
|
});
|
|
|
|
it('should throw UniqueConstraintError on duplicate address insert', async () => {
|
|
const newAddressData = { address_line_1: '123 Main St', city: 'Anytown' };
|
|
const dbError = new Error('duplicate key value violates unique constraint');
|
|
(dbError as any).code = '23505';
|
|
mockPoolInstance.query.mockRejectedValue(dbError);
|
|
|
|
await expect(addressRepo.upsertAddress(newAddressData)).rejects.toThrow(UniqueConstraintError);
|
|
await expect(addressRepo.upsertAddress(newAddressData)).rejects.toThrow('An identical address already exists.');
|
|
});
|
|
});
|
|
}); |