massive fixes to stores and addresses
All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 18m46s
All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 18m46s
This commit is contained in:
@@ -102,7 +102,11 @@ export class AddressRepository {
|
||||
* @param limit Maximum number of results (default: 10)
|
||||
* @returns Array of matching Address objects
|
||||
*/
|
||||
async searchAddressesByText(query: string, logger: Logger, limit: number = 10): Promise<Address[]> {
|
||||
async searchAddressesByText(
|
||||
query: string,
|
||||
logger: Logger,
|
||||
limit: number = 10,
|
||||
): Promise<Address[]> {
|
||||
try {
|
||||
const sql = `
|
||||
SELECT * FROM public.addresses
|
||||
|
||||
@@ -21,13 +21,13 @@ describe('Deals DB Service', () => {
|
||||
// Import the Pool type to use for casting the mock instance.
|
||||
let dealsRepo: DealsRepository;
|
||||
const mockDb = {
|
||||
query: vi.fn()
|
||||
query: vi.fn(),
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
|
||||
mockDb.query.mockReset()
|
||||
mockDb.query.mockReset();
|
||||
|
||||
// Instantiate the repository with the minimal mock db for each test
|
||||
dealsRepo = new DealsRepository(mockDb);
|
||||
@@ -71,10 +71,9 @@ describe('Deals DB Service', () => {
|
||||
|
||||
// Assert
|
||||
expect(result).toEqual(mockDeals);
|
||||
expect(mockDb.query).toHaveBeenCalledWith(
|
||||
expect.stringContaining('FROM flyer_items fi'),
|
||||
['user-123'],
|
||||
);
|
||||
expect(mockDb.query).toHaveBeenCalledWith(expect.stringContaining('FROM flyer_items fi'), [
|
||||
'user-123',
|
||||
]);
|
||||
expect(mockLogger.debug).toHaveBeenCalledWith(
|
||||
{ userId: 'user-123' },
|
||||
'Finding best prices for watched items.',
|
||||
|
||||
@@ -45,9 +45,7 @@ describe('StoreRepository', () => {
|
||||
expect(storeId).toBeGreaterThan(0);
|
||||
|
||||
// Verify it was created
|
||||
const result = await pool.query('SELECT * FROM public.stores WHERE store_id = $1', [
|
||||
storeId,
|
||||
]);
|
||||
const result = await pool.query('SELECT * FROM public.stores WHERE store_id = $1', [storeId]);
|
||||
expect(result.rows).toHaveLength(1);
|
||||
expect(result.rows[0].name).toBe('Test Store');
|
||||
});
|
||||
@@ -60,9 +58,7 @@ describe('StoreRepository', () => {
|
||||
);
|
||||
createdStoreIds.push(storeId);
|
||||
|
||||
const result = await pool.query('SELECT * FROM public.stores WHERE store_id = $1', [
|
||||
storeId,
|
||||
]);
|
||||
const result = await pool.query('SELECT * FROM public.stores WHERE store_id = $1', [storeId]);
|
||||
expect(result.rows[0].logo_url).toBe('https://example.com/logo.png');
|
||||
});
|
||||
|
||||
@@ -79,9 +75,7 @@ describe('StoreRepository', () => {
|
||||
const storeId = await repo.createStore('User Store', logger, null, userId);
|
||||
createdStoreIds.push(storeId);
|
||||
|
||||
const result = await pool.query('SELECT * FROM public.stores WHERE store_id = $1', [
|
||||
storeId,
|
||||
]);
|
||||
const result = await pool.query('SELECT * FROM public.stores WHERE store_id = $1', [storeId]);
|
||||
expect(result.rows[0].created_by).toBe(userId);
|
||||
|
||||
// Cleanup user
|
||||
@@ -150,11 +144,7 @@ describe('StoreRepository', () => {
|
||||
const storeId = await repo.createStore('Logo Update Test', logger);
|
||||
createdStoreIds.push(storeId);
|
||||
|
||||
await repo.updateStore(
|
||||
storeId,
|
||||
{ logo_url: 'https://example.com/new-logo.png' },
|
||||
logger,
|
||||
);
|
||||
await repo.updateStore(storeId, { logo_url: 'https://example.com/new-logo.png' }, logger);
|
||||
|
||||
const store = await repo.getStoreById(storeId, logger);
|
||||
expect(store.logo_url).toBe('https://example.com/new-logo.png');
|
||||
|
||||
@@ -90,9 +90,15 @@ export class StoreRepository {
|
||||
const result = await this.db.query<Store>(query);
|
||||
return result.rows;
|
||||
} catch (error) {
|
||||
handleDbError(error, logger, 'Database error in getAllStores', {}, {
|
||||
defaultMessage: 'Failed to retrieve stores.',
|
||||
});
|
||||
handleDbError(
|
||||
error,
|
||||
logger,
|
||||
'Database error in getAllStores',
|
||||
{},
|
||||
{
|
||||
defaultMessage: 'Failed to retrieve stores.',
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,11 +27,7 @@ export class StoreLocationRepository {
|
||||
* @param logger Logger instance
|
||||
* @returns The store_location_id of the created link
|
||||
*/
|
||||
async createStoreLocation(
|
||||
storeId: number,
|
||||
addressId: number,
|
||||
logger: Logger,
|
||||
): Promise<number> {
|
||||
async createStoreLocation(storeId: number, addressId: number, logger: Logger): Promise<number> {
|
||||
try {
|
||||
const query = `
|
||||
INSERT INTO public.store_locations (store_id, address_id)
|
||||
@@ -210,9 +206,15 @@ export class StoreLocationRepository {
|
||||
const result = await this.db.query<StoreWithLocations>(query);
|
||||
return result.rows;
|
||||
} catch (error) {
|
||||
handleDbError(error, logger, 'Database error in getAllStoresWithLocations', {}, {
|
||||
defaultMessage: 'Failed to retrieve stores with locations.',
|
||||
});
|
||||
handleDbError(
|
||||
error,
|
||||
logger,
|
||||
'Database error in getAllStoresWithLocations',
|
||||
{},
|
||||
{
|
||||
defaultMessage: 'Failed to retrieve stores with locations.',
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -253,7 +253,7 @@ describe('Email Service (Server)', () => {
|
||||
name: 'email-job',
|
||||
data,
|
||||
attemptsMade: 1,
|
||||
} as unknown as Job<EmailJobData>);
|
||||
}) as unknown as Job<EmailJobData>;
|
||||
|
||||
it('should call sendMail with job data and log success', async () => {
|
||||
const job = createMockJob(mockJobData);
|
||||
|
||||
@@ -5,7 +5,11 @@ import { getPool } from '../../services/db/connection.db';
|
||||
import type { UserProfile } from '../../types';
|
||||
import { createAndLoginUser, TEST_EXAMPLE_DOMAIN } from '../utils/testHelpers';
|
||||
import { cleanupDb } from '../utils/cleanup';
|
||||
import { createStoreWithLocation, cleanupStoreLocations, type CreatedStoreLocation } from '../utils/storeHelpers';
|
||||
import {
|
||||
createStoreWithLocation,
|
||||
cleanupStoreLocations,
|
||||
type CreatedStoreLocation,
|
||||
} from '../utils/storeHelpers';
|
||||
|
||||
/**
|
||||
* @vitest-environment node
|
||||
|
||||
@@ -1325,9 +1325,7 @@ export const createMockAddress = (overrides: Partial<Address> = {}): Address =>
|
||||
* @param overrides - An object containing properties to override the default mock values.
|
||||
* @returns A complete and type-safe StoreLocation object.
|
||||
*/
|
||||
export const createMockStoreLocation = (
|
||||
overrides: Partial<StoreLocation> = {},
|
||||
): StoreLocation => {
|
||||
export const createMockStoreLocation = (overrides: Partial<StoreLocation> = {}): StoreLocation => {
|
||||
const defaultStoreLocation: StoreLocation = {
|
||||
store_location_id: getNextId(),
|
||||
store_id: overrides.store_id ?? getNextId(),
|
||||
@@ -1349,7 +1347,9 @@ export const createMockStoreLocation = (
|
||||
* @returns A complete and type-safe StoreLocationWithAddress object.
|
||||
*/
|
||||
export const createMockStoreLocationWithAddress = (
|
||||
overrides: Omit<Partial<StoreLocationWithAddress>, 'address'> & { address?: Partial<Address> } = {},
|
||||
overrides: Omit<Partial<StoreLocationWithAddress>, 'address'> & {
|
||||
address?: Partial<Address>;
|
||||
} = {},
|
||||
): StoreLocationWithAddress => {
|
||||
// Create the address first, using the address_id from overrides if provided
|
||||
const address = createMockAddress({
|
||||
@@ -1380,23 +1380,24 @@ export const createMockStoreLocationWithAddress = (
|
||||
*/
|
||||
export const createMockStoreWithLocations = (
|
||||
overrides: Omit<Partial<StoreWithLocations>, 'locations'> & {
|
||||
locations?: Array<Omit<Partial<StoreLocationWithAddress>, 'address'> & { address?: Partial<Address> }>;
|
||||
locations?: Array<
|
||||
Omit<Partial<StoreLocationWithAddress>, 'address'> & { address?: Partial<Address> }
|
||||
>;
|
||||
} = {},
|
||||
): StoreWithLocations => {
|
||||
const store = createMockStore(overrides);
|
||||
|
||||
// If locations are provided, create them; otherwise create one default location
|
||||
const locations =
|
||||
overrides.locations?.map((locOverride) =>
|
||||
createMockStoreLocationWithAddress({
|
||||
...locOverride,
|
||||
store_id: store.store_id,
|
||||
}),
|
||||
) ?? [
|
||||
createMockStoreLocationWithAddress({
|
||||
store_id: store.store_id,
|
||||
}),
|
||||
];
|
||||
const locations = overrides.locations?.map((locOverride) =>
|
||||
createMockStoreLocationWithAddress({
|
||||
...locOverride,
|
||||
store_id: store.store_id,
|
||||
}),
|
||||
) ?? [
|
||||
createMockStoreLocationWithAddress({
|
||||
store_id: store.store_id,
|
||||
}),
|
||||
];
|
||||
|
||||
return {
|
||||
...store,
|
||||
|
||||
@@ -119,9 +119,10 @@ export async function cleanupStoreLocations(
|
||||
const addressIds = locations.map((l) => l.addressId);
|
||||
|
||||
// Delete in reverse order of creation
|
||||
await pool.query('DELETE FROM public.store_locations WHERE store_location_id = ANY($1::bigint[])', [
|
||||
storeLocationIds,
|
||||
]);
|
||||
await pool.query(
|
||||
'DELETE FROM public.store_locations WHERE store_location_id = ANY($1::bigint[])',
|
||||
[storeLocationIds],
|
||||
);
|
||||
await pool.query('DELETE FROM public.stores WHERE store_id = ANY($1::bigint[])', [storeIds]);
|
||||
await pool.query('DELETE FROM public.addresses WHERE address_id = ANY($1::bigint[])', [
|
||||
addressIds,
|
||||
|
||||
Reference in New Issue
Block a user