massive fixes to stores and addresses
All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 18m46s

This commit is contained in:
2026-01-19 00:34:11 -08:00
parent d2efca8339
commit 795b3d0b28
9 changed files with 60 additions and 53 deletions

View File

@@ -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

View File

@@ -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.',

View File

@@ -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');

View File

@@ -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.',
},
);
}
}

View File

@@ -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.',
},
);
}
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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,

View File

@@ -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,