lootsa tests fixes
All checks were successful
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Successful in 4m30s
All checks were successful
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Successful in 4m30s
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
// src/services/db/user.db.test.ts
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
|
||||
// Un-mock the module we are testing to ensure we use the real implementation.
|
||||
vi.unmock('./user.db');
|
||||
|
||||
import {
|
||||
findUserByEmail,
|
||||
createUser,
|
||||
@@ -21,11 +25,7 @@ import {
|
||||
getUserFeed,
|
||||
logSearchQuery,
|
||||
} from './user.db';
|
||||
import { Pool } from 'pg';
|
||||
|
||||
const mockQuery = vi.fn();
|
||||
const mockRelease = vi.fn();
|
||||
const mockConnect = vi.fn().mockResolvedValue({ query: mockQuery, release: mockRelease });
|
||||
import { mockPoolInstance } from '../../tests/setup/tests-setup-unit';
|
||||
import type { Profile } from '../../types';
|
||||
|
||||
// Mock other db services that are used by functions in user.db.ts
|
||||
@@ -38,33 +38,17 @@ vi.mock('./personalization', () => ({
|
||||
|
||||
describe('User DB Service', () => {
|
||||
beforeEach(() => {
|
||||
// FIX: Reset mockQuery
|
||||
mockQuery.mockReset();
|
||||
|
||||
vi.mocked(Pool).mockImplementation(function() {
|
||||
return {
|
||||
query: mockQuery,
|
||||
connect: mockConnect,
|
||||
release: mockRelease,
|
||||
on: vi.fn(),
|
||||
end: vi.fn(),
|
||||
totalCount: 0,
|
||||
idleCount: 0,
|
||||
waitingCount: 0,
|
||||
} as unknown as Pool;
|
||||
});
|
||||
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
describe('findUserByEmail', () => {
|
||||
it('should execute the correct query and return a user', async () => {
|
||||
const mockUser = { user_id: '123', email: 'test@example.com' };
|
||||
mockQuery.mockResolvedValue({ rows: [mockUser] });
|
||||
mockPoolInstance.query.mockResolvedValue({ rows: [mockUser] });
|
||||
|
||||
const result = await findUserByEmail('test@example.com');
|
||||
|
||||
expect(mockQuery).toHaveBeenCalledWith(expect.stringContaining('FROM public.users WHERE email = $1'), ['test@example.com']);
|
||||
expect(mockPoolInstance.query).toHaveBeenCalledWith(expect.stringContaining('FROM public.users WHERE email = $1'), ['test@example.com']);
|
||||
expect(result).toEqual(mockUser);
|
||||
});
|
||||
});
|
||||
@@ -74,7 +58,7 @@ describe('User DB Service', () => {
|
||||
const mockUser = { user_id: 'new-user-id', email: 'new@example.com' };
|
||||
const mockProfile = { ...mockUser, role: 'user' };
|
||||
|
||||
mockQuery
|
||||
mockPoolInstance.query
|
||||
.mockResolvedValueOnce({ rows: [] }) // BEGIN
|
||||
.mockResolvedValueOnce({ rows: [] }) // set_config
|
||||
.mockResolvedValueOnce({ rows: [mockUser] }) // INSERT user RETURNING
|
||||
@@ -83,8 +67,8 @@ describe('User DB Service', () => {
|
||||
|
||||
const result = await createUser('new@example.com', 'hashedpass', { full_name: 'New User' });
|
||||
|
||||
expect(mockConnect).toHaveBeenCalled();
|
||||
expect(mockQuery).toHaveBeenCalledWith('BEGIN');
|
||||
expect(mockPoolInstance.connect).toHaveBeenCalled();
|
||||
expect(mockPoolInstance.query).toHaveBeenCalledWith('BEGIN');
|
||||
// The implementation returns the profile, not just the user row
|
||||
expect(result).toEqual(mockProfile);
|
||||
});
|
||||
@@ -92,102 +76,102 @@ describe('User DB Service', () => {
|
||||
|
||||
describe('findUserById', () => {
|
||||
it('should query for a user by their ID', async () => {
|
||||
mockQuery.mockResolvedValue({ rows: [{ user_id: '123' }] });
|
||||
mockPoolInstance.query.mockResolvedValue({ rows: [{ user_id: '123' }] });
|
||||
await findUserById('123');
|
||||
expect(mockQuery).toHaveBeenCalledWith(expect.stringContaining('FROM public.users WHERE user_id = $1'), ['123']);
|
||||
expect(mockPoolInstance.query).toHaveBeenCalledWith(expect.stringContaining('FROM public.users WHERE user_id = $1'), ['123']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('findUserWithPasswordHashById', () => {
|
||||
it('should query for a user and their password hash by ID', async () => {
|
||||
mockQuery.mockResolvedValue({ rows: [{ user_id: '123', password_hash: 'hash' }] });
|
||||
mockPoolInstance.query.mockResolvedValue({ rows: [{ user_id: '123', password_hash: 'hash' }] });
|
||||
await findUserWithPasswordHashById('123');
|
||||
expect(mockQuery).toHaveBeenCalledWith(expect.stringContaining('SELECT user_id, email, password_hash'), ['123']);
|
||||
expect(mockPoolInstance.query).toHaveBeenCalledWith(expect.stringContaining('SELECT user_id, email, password_hash'), ['123']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('findUserProfileById', () => {
|
||||
it('should query for a user profile by user ID', async () => {
|
||||
mockQuery.mockResolvedValue({ rows: [{ user_id: '123' }] });
|
||||
mockPoolInstance.query.mockResolvedValue({ rows: [{ user_id: '123' }] });
|
||||
await findUserProfileById('123');
|
||||
expect(mockQuery).toHaveBeenCalledWith(expect.stringContaining('FROM public.profiles WHERE user_id = $1'), ['123']);
|
||||
expect(mockPoolInstance.query).toHaveBeenCalledWith(expect.stringContaining('FROM public.profiles WHERE user_id = $1'), ['123']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('updateUserProfile', () => {
|
||||
it('should execute an UPDATE query for the user profile', async () => {
|
||||
const mockProfile: Profile = { user_id: '123', full_name: 'Updated Name', role: 'user', points: 0 };
|
||||
mockQuery.mockResolvedValue({ rows: [mockProfile] });
|
||||
mockPoolInstance.query.mockResolvedValue({ rows: [mockProfile] });
|
||||
|
||||
await updateUserProfile('123', { full_name: 'Updated Name' });
|
||||
|
||||
expect(mockQuery).toHaveBeenCalledWith(expect.stringContaining('UPDATE public.profiles'), expect.any(Array));
|
||||
expect(mockPoolInstance.query).toHaveBeenCalledWith(expect.stringContaining('UPDATE public.profiles'), expect.any(Array));
|
||||
});
|
||||
});
|
||||
|
||||
describe('updateUserPreferences', () => {
|
||||
it('should execute an UPDATE query for user preferences', async () => {
|
||||
mockQuery.mockResolvedValue({ rows: [{}] });
|
||||
mockPoolInstance.query.mockResolvedValue({ rows: [{}] });
|
||||
await updateUserPreferences('123', { darkMode: true });
|
||||
expect(mockQuery).toHaveBeenCalledWith(expect.stringContaining("SET preferences = COALESCE(preferences, '{}'::jsonb) || $1"), [{ darkMode: true }, '123']);
|
||||
expect(mockPoolInstance.query).toHaveBeenCalledWith(expect.stringContaining("SET preferences = COALESCE(preferences, '{}'::jsonb) || $1"), [{ darkMode: true }, '123']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('updateUserPassword', () => {
|
||||
it('should execute an UPDATE query for the user password', async () => {
|
||||
mockQuery.mockResolvedValue({ rows: [] });
|
||||
mockPoolInstance.query.mockResolvedValue({ rows: [] });
|
||||
await updateUserPassword('123', 'newhash');
|
||||
expect(mockQuery).toHaveBeenCalledWith('UPDATE public.users SET password_hash = $1 WHERE user_id = $2', ['newhash', '123']);
|
||||
expect(mockPoolInstance.query).toHaveBeenCalledWith('UPDATE public.users SET password_hash = $1 WHERE user_id = $2', ['newhash', '123']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('deleteUserById', () => {
|
||||
it('should execute a DELETE query for the user', async () => {
|
||||
mockQuery.mockResolvedValue({ rows: [] });
|
||||
mockPoolInstance.query.mockResolvedValue({ rows: [] });
|
||||
await deleteUserById('123');
|
||||
expect(mockQuery).toHaveBeenCalledWith('DELETE FROM public.users WHERE user_id = $1', ['123']);
|
||||
expect(mockPoolInstance.query).toHaveBeenCalledWith('DELETE FROM public.users WHERE user_id = $1', ['123']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('saveRefreshToken', () => {
|
||||
it('should execute an UPDATE query to save the refresh token', async () => {
|
||||
mockQuery.mockResolvedValue({ rows: [] });
|
||||
mockPoolInstance.query.mockResolvedValue({ rows: [] });
|
||||
await saveRefreshToken('123', 'new-token');
|
||||
expect(mockQuery).toHaveBeenCalledWith('UPDATE public.users SET refresh_token = $1 WHERE user_id = $2', ['new-token', '123']);
|
||||
expect(mockPoolInstance.query).toHaveBeenCalledWith('UPDATE public.users SET refresh_token = $1 WHERE user_id = $2', ['new-token', '123']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('findUserByRefreshToken', () => {
|
||||
it('should query for a user by their refresh token', async () => {
|
||||
mockQuery.mockResolvedValue({ rows: [{ user_id: '123' }] });
|
||||
mockPoolInstance.query.mockResolvedValue({ rows: [{ user_id: '123' }] });
|
||||
await findUserByRefreshToken('a-token');
|
||||
expect(mockQuery).toHaveBeenCalledWith(expect.stringContaining('WHERE refresh_token = $1'), ['a-token']);
|
||||
expect(mockPoolInstance.query).toHaveBeenCalledWith(expect.stringContaining('WHERE refresh_token = $1'), ['a-token']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('createPasswordResetToken', () => {
|
||||
it('should execute DELETE and INSERT queries', async () => {
|
||||
mockQuery.mockResolvedValue({ rows: [] });
|
||||
mockPoolInstance.query.mockResolvedValue({ rows: [] });
|
||||
const expires = new Date();
|
||||
await createPasswordResetToken('123', 'token-hash', expires);
|
||||
expect(mockQuery).toHaveBeenCalledWith('DELETE FROM public.password_reset_tokens WHERE user_id = $1', ['123']);
|
||||
expect(mockQuery).toHaveBeenCalledWith(expect.stringContaining('INSERT INTO public.password_reset_tokens'), ['123', 'token-hash', expires]);
|
||||
expect(mockPoolInstance.query).toHaveBeenCalledWith('DELETE FROM public.password_reset_tokens WHERE user_id = $1', ['123']);
|
||||
expect(mockPoolInstance.query).toHaveBeenCalledWith(expect.stringContaining('INSERT INTO public.password_reset_tokens'), ['123', 'token-hash', expires]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getValidResetTokens', () => {
|
||||
it('should query for tokens where expires_at > NOW()', async () => {
|
||||
mockQuery.mockResolvedValue({ rows: [] });
|
||||
mockPoolInstance.query.mockResolvedValue({ rows: [] });
|
||||
await getValidResetTokens();
|
||||
expect(mockQuery).toHaveBeenCalledWith(expect.stringContaining('WHERE expires_at > NOW()'));
|
||||
expect(mockPoolInstance.query).toHaveBeenCalledWith(expect.stringContaining('WHERE expires_at > NOW()'));
|
||||
});
|
||||
});
|
||||
|
||||
describe('deleteResetToken', () => {
|
||||
it('should execute a DELETE query for the token hash', async () => {
|
||||
mockQuery.mockResolvedValue({ rows: [] });
|
||||
mockPoolInstance.query.mockResolvedValue({ rows: [] });
|
||||
await deleteResetToken('token-hash');
|
||||
expect(mockQuery).toHaveBeenCalledWith('DELETE FROM public.password_reset_tokens WHERE token_hash = $1', ['token-hash']);
|
||||
expect(mockPoolInstance.query).toHaveBeenCalledWith('DELETE FROM public.password_reset_tokens WHERE token_hash = $1', ['token-hash']);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -197,13 +181,13 @@ describe('User DB Service', () => {
|
||||
const { getShoppingLists } = await import('./shopping.db');
|
||||
const { getWatchedItems } = await import('./personalization.db');
|
||||
|
||||
mockQuery.mockResolvedValue({ rows: [{ user_id: '123' }] }); // For findUserProfileById
|
||||
mockPoolInstance.query.mockResolvedValue({ rows: [{ user_id: '123' }] }); // For findUserProfileById
|
||||
vi.mocked(getWatchedItems).mockResolvedValue([]);
|
||||
vi.mocked(getShoppingLists).mockResolvedValue([]);
|
||||
|
||||
await exportUserData('123');
|
||||
|
||||
expect(mockQuery).toHaveBeenCalledWith(expect.stringContaining('FROM public.profiles'), ['123']);
|
||||
expect(mockPoolInstance.query).toHaveBeenCalledWith(expect.stringContaining('FROM public.profiles'), ['123']);
|
||||
expect(getWatchedItems).toHaveBeenCalledWith('123');
|
||||
expect(getShoppingLists).toHaveBeenCalledWith('123');
|
||||
});
|
||||
@@ -211,9 +195,9 @@ describe('User DB Service', () => {
|
||||
|
||||
describe('followUser', () => {
|
||||
it('should execute an INSERT query to create a follow relationship', async () => {
|
||||
mockQuery.mockResolvedValue({ rows: [] });
|
||||
mockPoolInstance.query.mockResolvedValue({ rows: [] });
|
||||
await followUser('user-1', 'user-2');
|
||||
expect(mockQuery).toHaveBeenCalledWith(expect.stringContaining('INSERT INTO public.user_follows'), ['user-1', 'user-2']);
|
||||
expect(mockPoolInstance.query).toHaveBeenCalledWith(expect.stringContaining('INSERT INTO public.user_follows'), ['user-1', 'user-2']);
|
||||
});
|
||||
|
||||
it('should throw an error if a user tries to follow themselves', async () => {
|
||||
@@ -223,26 +207,26 @@ describe('User DB Service', () => {
|
||||
|
||||
describe('unfollowUser', () => {
|
||||
it('should execute a DELETE query to remove a follow relationship', async () => {
|
||||
mockQuery.mockResolvedValue({ rows: [] });
|
||||
mockPoolInstance.query.mockResolvedValue({ rows: [] });
|
||||
await unfollowUser('user-1', 'user-2');
|
||||
expect(mockQuery).toHaveBeenCalledWith('DELETE FROM public.user_follows WHERE follower_id = $1 AND following_id = $2', ['user-1', 'user-2']);
|
||||
expect(mockPoolInstance.query).toHaveBeenCalledWith('DELETE FROM public.user_follows WHERE follower_id = $1 AND following_id = $2', ['user-1', 'user-2']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getUserFeed', () => {
|
||||
it('should call the get_user_feed database function', async () => {
|
||||
mockQuery.mockResolvedValue({ rows: [] });
|
||||
mockPoolInstance.query.mockResolvedValue({ rows: [] });
|
||||
await getUserFeed('user-123', 10, 20);
|
||||
expect(mockQuery).toHaveBeenCalledWith('SELECT * FROM public.get_user_feed($1, $2, $3)', ['user-123', 10, 20]);
|
||||
expect(mockPoolInstance.query).toHaveBeenCalledWith('SELECT * FROM public.get_user_feed($1, $2, $3)', ['user-123', 10, 20]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('logSearchQuery', () => {
|
||||
it('should insert a search query into the log', async () => {
|
||||
mockQuery.mockResolvedValue({ rows: [] });
|
||||
mockPoolInstance.query.mockResolvedValue({ rows: [] });
|
||||
const queryData = { userId: 'user-123', queryText: 'apples', resultCount: 5, wasSuccessful: true };
|
||||
await logSearchQuery(queryData);
|
||||
expect(mockQuery).toHaveBeenCalledWith(expect.stringContaining('INSERT INTO public.search_queries'), [queryData.userId, queryData.queryText, queryData.resultCount, queryData.wasSuccessful]);
|
||||
expect(mockPoolInstance.query).toHaveBeenCalledWith(expect.stringContaining('INSERT INTO public.search_queries'), [queryData.userId, queryData.queryText, queryData.resultCount, queryData.wasSuccessful]);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user