mock mock mock !
All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 57m50s

This commit is contained in:
2025-12-19 20:31:04 -08:00
parent e62739810e
commit a3d3ddd772
48 changed files with 1062 additions and 507 deletions

View File

@@ -2,8 +2,8 @@
import { describe, it, expect, vi, beforeEach } from 'vitest';
import supertest from 'supertest';
import { Request, Response, NextFunction } from 'express';
import adminRouter from './admin.routes'; // This was a duplicate, fixed.
import { createMockUserProfile, createMockAdminUserView } from '../tests/utils/mockFactories';
import adminRouter from './admin.routes';
import { createMockUserProfile, createMockAdminUserView, createMockProfile } from '../tests/utils/mockFactories';
import { UserProfile, Profile } from '../types';
import { NotFoundError } from '../services/db/errors.db';
import { createTestApp } from '../tests/utils/createTestApp';
@@ -118,12 +118,10 @@ describe('Admin User Management Routes (/api/admin/users)', () => {
describe('PUT /users/:id', () => {
it('should update a user role successfully', async () => {
// The `updateUserRole` function returns a `Profile` object, not a `User` object.
const updatedUser: Profile = {
const updatedUser = createMockProfile({
user_id: userId,
role: 'admin',
points: 0,
};
});
vi.mocked(adminRepo.updateUserRole).mockResolvedValue(updatedUser);
const response = await supertest(app)
.put(`/api/admin/users/${userId}`)

View File

@@ -44,7 +44,7 @@ vi.mock('passport-local', () => ({
import * as db from '../services/db/index.db';
import { UserProfile } from '../types';
import { createMockUserProfile } from '../tests/utils/mockFactories';
import { createMockUserProfile, createMockUserWithPasswordHash } from '../tests/utils/mockFactories';
import { mockLogger } from '../tests/utils/mockLogger';
// Mock dependencies before importing the passport configuration
@@ -105,15 +105,14 @@ describe('Passport Configuration', () => {
it('should call done(null, user) on successful authentication', async () => {
// Arrange
const mockUser = {
user_id: 'user-123',
email: 'test@test.com',
password_hash: 'hashed_password',
failed_login_attempts: 0,
last_failed_login: null,
points: 0,
role: 'user' as const
};
const mockUser = {
...createMockUserWithPasswordHash({
user_id: 'user-123',
email: 'test@test.com',
}),
points: 0,
role: 'user' as const,
};
vi.mocked(mockedDb.userRepo.findUserWithProfileByEmail).mockResolvedValue(mockUser);
vi.mocked(bcrypt.compare).mockResolvedValue(true as never);
@@ -140,15 +139,15 @@ describe('Passport Configuration', () => {
});
it('should call done(null, false) and increment failed attempts on password mismatch', async () => {
const mockUser = {
user_id: 'user-123',
email: 'test@test.com',
password_hash: 'hashed_password',
failed_login_attempts: 1,
last_failed_login: null,
points: 0,
role: 'user' as const
};
const mockUser = {
...createMockUserWithPasswordHash({
user_id: 'user-123',
email: 'test@test.com',
failed_login_attempts: 1,
}),
points: 0,
role: 'user' as const,
};
vi.mocked(mockedDb.userRepo.findUserWithProfileByEmail).mockResolvedValue(mockUser);
vi.mocked(bcrypt.compare).mockResolvedValue(false as never);
@@ -162,15 +161,15 @@ describe('Passport Configuration', () => {
});
it('should call done(null, false) for an OAuth user (no password hash)', async () => {
const mockUser = {
user_id: 'oauth-user',
email: 'oauth@test.com',
password_hash: null,
failed_login_attempts: 0,
last_failed_login: null,
points: 0,
role: 'user' as const
};
const mockUser = {
...createMockUserWithPasswordHash({
user_id: 'oauth-user',
email: 'oauth@test.com',
password_hash: null,
}),
points: 0,
role: 'user' as const,
};
vi.mocked(mockedDb.userRepo.findUserWithProfileByEmail).mockResolvedValue(mockUser);
if (localStrategyCallbackWrapper.callback) {
@@ -182,13 +181,14 @@ describe('Passport Configuration', () => {
it('should call done(null, false) if account is locked', async () => {
const mockUser = {
user_id: 'locked-user',
email: 'locked@test.com',
password_hash: 'hashed_password',
failed_login_attempts: 5,
last_failed_login: new Date().toISOString(),
points: 0,
role: 'user' as const
...createMockUserWithPasswordHash({
user_id: 'locked-user',
email: 'locked@test.com',
failed_login_attempts: 5,
last_failed_login: new Date().toISOString(),
}),
points: 0,
role: 'user' as const,
};
vi.mocked(mockedDb.userRepo.findUserWithProfileByEmail).mockResolvedValue(mockUser);
@@ -201,13 +201,14 @@ describe('Passport Configuration', () => {
it('should allow login if lockout period has expired', async () => {
const mockUser = {
user_id: 'expired-lock-user',
email: 'expired@test.com',
password_hash: 'hashed_password',
failed_login_attempts: 5,
last_failed_login: new Date(Date.now() - 20 * 60 * 1000).toISOString(),
points: 0,
role: 'user' as const
...createMockUserWithPasswordHash({
user_id: 'expired-lock-user',
email: 'expired@test.com',
failed_login_attempts: 5,
last_failed_login: new Date(Date.now() - 20 * 60 * 1000).toISOString(),
}),
points: 0,
role: 'user' as const,
};
vi.mocked(mockedDb.userRepo.findUserWithProfileByEmail).mockResolvedValue(mockUser);
vi.mocked(bcrypt.compare).mockResolvedValue(true as never); // Correct password
@@ -303,13 +304,7 @@ describe('Passport Configuration', () => {
it('should call next() if user has "admin" role', () => {
// Arrange
const mockReq: Partial<Request> = {
// Create a complete, type-safe mock UserProfile object.
user: {
user_id: 'admin-id',
role: 'admin',
points: 100,
user: { user_id: 'admin-id', email: 'admin@test.com' }
},
user: createMockUserProfile({ user_id: 'admin-id', role: 'admin', user: { user_id: 'admin-id', email: 'admin@test.com' } }),
};
// Act
@@ -323,12 +318,7 @@ describe('Passport Configuration', () => {
it('should return 403 Forbidden if user does not have "admin" role', () => {
// Arrange
const mockReq: Partial<Request> = {
user: {
user_id: 'user-id',
role: 'user',
points: 50,
user: { user_id: 'user-id', email: 'user@test.com' }
},
user: createMockUserProfile({ user_id: 'user-id', role: 'user', user: { user_id: 'user-id', email: 'user@test.com' } }),
};
// Act

View File

@@ -4,7 +4,7 @@ import supertest from 'supertest';
import express from 'express';
// Use * as bcrypt to match the implementation's import style and ensure mocks align.
import * as bcrypt from 'bcrypt';
import userRouter from './user.routes';
import userRouter from './user.routes'; // This was a duplicate, fixed.
import { createMockUserProfile, createMockMasterGroceryItem, createMockShoppingList, createMockShoppingListItem, createMockRecipe, createMockNotification, createMockDietaryRestriction, createMockAppliance, createMockUserWithPasswordHash, createMockAddress } from '../tests/utils/mockFactories';
import { Appliance, Notification, DietaryRestriction, Address } from '../types';
import { ForeignKeyConstraintError, NotFoundError } from '../services/db/errors.db';
@@ -460,7 +460,7 @@ describe('User Routes (/api/users)', () => {
describe('PUT /profile', () => {
it('should update the user profile successfully', async () => {
const profileUpdates = { full_name: 'New Name' };
const updatedProfile = { ...mockUserProfile, ...profileUpdates };
const updatedProfile = createMockUserProfile({ ...mockUserProfile, ...profileUpdates });
vi.mocked(db.userRepo.updateUserProfile).mockResolvedValue(updatedProfile);
const response = await supertest(app)
.put('/api/users/profile')
@@ -588,10 +588,10 @@ describe('User Routes (/api/users)', () => {
describe('PUT /profile/preferences', () => {
it('should update user preferences successfully', async () => {
const preferencesUpdate = { darkMode: true, unitSystem: 'metric' as const };
const updatedProfile = {
...mockUserProfile,
preferences: { ...mockUserProfile.preferences, ...preferencesUpdate }
};
const updatedProfile = createMockUserProfile({
...mockUserProfile,
preferences: { ...mockUserProfile.preferences, ...preferencesUpdate },
});
vi.mocked(db.userRepo.updateUserPreferences).mockResolvedValue(updatedProfile);
const response = await supertest(app)
.put('/api/users/profile/preferences')
@@ -928,7 +928,7 @@ describe('User Routes (/api/users)', () => {
it('PUT /recipes/:recipeId should update a user\'s own recipe', async () => {
const updates = { description: 'A new delicious description.' };
const mockUpdatedRecipe = { ...createMockRecipe({ recipe_id: 1 }), ...updates };
const mockUpdatedRecipe = createMockRecipe({ recipe_id: 1, ...updates });
vi.mocked(db.recipeRepo.updateRecipe).mockResolvedValue(mockUpdatedRecipe);
const response = await supertest(app)