file re-org
Some checks failed
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Failing after 53s
Some checks failed
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Failing after 53s
This commit is contained in:
@@ -1,160 +0,0 @@
|
||||
// src/routes/user.integration.test.ts
|
||||
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
|
||||
import * as apiClient from '../services/apiClient';
|
||||
import { logger } from '../services/logger.server';
|
||||
import { getPool } from '../services/db/connection';
|
||||
import type { User } from '../types';
|
||||
|
||||
/**
|
||||
* @vitest-environment node
|
||||
*/
|
||||
|
||||
const TEST_PASSWORD = 'a-much-stronger-password-for-testing-!@#$';
|
||||
|
||||
/**
|
||||
* A helper function to create a new user and log them in, returning the user object and auth token.
|
||||
* This provides an authenticated context for testing protected API endpoints.
|
||||
*/
|
||||
const createAndLoginUser = async (email: string) => {
|
||||
const password = TEST_PASSWORD;
|
||||
// Register the new user.
|
||||
await apiClient.registerUser(email, password, 'Test User');
|
||||
|
||||
// Log in to get the auth token.
|
||||
const { user, token } = await apiClient.loginUser(email, password, false);
|
||||
return { user, token };
|
||||
};
|
||||
|
||||
describe('User API Routes Integration Tests', () => {
|
||||
let testUser: User;
|
||||
let authToken: string;
|
||||
|
||||
// --- START DEBUG LOGGING ---
|
||||
// Query the DB from within the test file to see its state.
|
||||
beforeAll(async () => {
|
||||
const res = await getPool().query('SELECT u.user_id, u.email, p.role FROM public.users u JOIN public.profiles p ON u.user_id = p.user_id');
|
||||
console.log('\n--- [user.integration.test.ts] Users found in DB from TEST perspective (beforeAll): ---');
|
||||
console.table(res.rows);
|
||||
console.log('-------------------------------------------------------------------------------------\n');
|
||||
});
|
||||
// --- END DEBUG LOGGING ---
|
||||
// Before any tests run, create a new user and log them in.
|
||||
// The token will be used for all subsequent API calls in this test suite.
|
||||
beforeAll(async () => {
|
||||
const email = `user-test-${Date.now()}@example.com`;
|
||||
const { user, token } = await createAndLoginUser(email);
|
||||
testUser = user;
|
||||
authToken = token;
|
||||
});
|
||||
|
||||
// After all tests, clean up by deleting the created user.
|
||||
afterAll(async () => {
|
||||
if (testUser) {
|
||||
logger.debug(`[user.integration.test.ts afterAll] Cleaning up user ID: ${testUser.user_id}`);
|
||||
// This requires an authenticated call to delete the account.
|
||||
await apiClient.deleteUserAccount(TEST_PASSWORD, authToken);
|
||||
}
|
||||
});
|
||||
|
||||
it('should fetch the authenticated user profile via GET /api/users/profile', async () => {
|
||||
// Act: Call the API endpoint using the authenticated token.
|
||||
const profile = await apiClient.getAuthenticatedUserProfile(authToken);
|
||||
|
||||
// Assert: Verify the profile data matches the created user.
|
||||
expect(profile).toBeDefined();
|
||||
expect(profile.user_id).toBe(testUser.user_id);
|
||||
expect(profile.user.email).toBe(testUser.email);
|
||||
expect(profile.full_name).toBe('Test User');
|
||||
expect(profile.role).toBe('user');
|
||||
});
|
||||
|
||||
it('should update the user profile via PUT /api/users/profile', async () => {
|
||||
// Arrange: Define the profile updates.
|
||||
const profileUpdates = {
|
||||
full_name: 'Updated Test User',
|
||||
};
|
||||
|
||||
// Act: Call the update endpoint with the new data and the auth token.
|
||||
const updatedProfile = await apiClient.updateUserProfile(profileUpdates, authToken);
|
||||
|
||||
// Assert: Check that the returned profile reflects the changes.
|
||||
expect(updatedProfile).toBeDefined();
|
||||
expect(updatedProfile.full_name).toBe('Updated Test User');
|
||||
|
||||
// Also, fetch the profile again to ensure the change was persisted.
|
||||
const refetchedProfile = await apiClient.getAuthenticatedUserProfile(authToken);
|
||||
expect(refetchedProfile.full_name).toBe('Updated Test User');
|
||||
});
|
||||
|
||||
it('should update user preferences via PUT /api/users/profile/preferences', async () => {
|
||||
// Arrange: Define the preference updates.
|
||||
const preferenceUpdates = {
|
||||
darkMode: true,
|
||||
};
|
||||
|
||||
// Act: Call the update endpoint.
|
||||
const updatedProfile = await apiClient.updateUserPreferences(preferenceUpdates, authToken);
|
||||
|
||||
// Assert: Check that the preferences object in the returned profile is updated.
|
||||
expect(updatedProfile).toBeDefined();
|
||||
expect(updatedProfile.preferences).toBeDefined();
|
||||
expect(updatedProfile.preferences?.darkMode).toBe(true);
|
||||
});
|
||||
|
||||
it('should reject registration with a weak password', async () => {
|
||||
// Arrange: Define a new user with a known weak password.
|
||||
const email = `weak-password-user-${Date.now()}@example.com`;
|
||||
const weakPassword = 'password';
|
||||
|
||||
// Act & Assert: Attempt to register and expect the promise to reject
|
||||
// with an error message indicating the password is too weak.
|
||||
await expect(
|
||||
apiClient.registerUser(email, weakPassword, 'Weak Password User')
|
||||
).rejects.toThrow(/Password is too weak/);
|
||||
});
|
||||
|
||||
it('should allow a user to delete their own account and then fail to log in', async () => {
|
||||
// Arrange: Create a new, separate user just for this deletion test.
|
||||
const deletionEmail = `delete-me-${Date.now()}@example.com`;
|
||||
const { token: deletionToken } = await createAndLoginUser(deletionEmail);
|
||||
|
||||
// Act: Call the delete endpoint with the correct password and token.
|
||||
const deleteResponse = await apiClient.deleteUserAccount(TEST_PASSWORD, deletionToken);
|
||||
|
||||
// Assert: Check for a successful deletion message.
|
||||
expect(deleteResponse.message).toBe('Account deleted successfully.');
|
||||
|
||||
// Assert (Verification): Attempting to log in again with the same credentials should now fail.
|
||||
// We expect the promise to reject with an error indicating incorrect credentials,
|
||||
// because the user no longer exists.
|
||||
await expect(
|
||||
apiClient.loginUser(deletionEmail, TEST_PASSWORD, false)
|
||||
).rejects.toThrow('Incorrect email or password.');
|
||||
});
|
||||
|
||||
it('should allow a user to reset their password and log in with the new one', async () => {
|
||||
// Arrange: Create a new user for the password reset flow.
|
||||
const resetEmail = `reset-me-${Date.now()}@example.com`;
|
||||
const { user: resetUser } = await createAndLoginUser(resetEmail);
|
||||
|
||||
// Act 1: Request a password reset. In our test environment, the token is returned in the response.
|
||||
const resetRequestResponse = await apiClient.requestPasswordReset(resetEmail);
|
||||
const resetToken = resetRequestResponse.token;
|
||||
|
||||
// Assert 1: Check that we received a token.
|
||||
expect(resetToken).toBeDefined();
|
||||
expect(resetToken).toBeTypeOf('string');
|
||||
|
||||
// Act 2: Use the token to set a new password.
|
||||
const newPassword = 'my-new-secure-password-!@#$';
|
||||
const resetResponse = await apiClient.resetPassword(resetToken!, newPassword);
|
||||
|
||||
// Assert 2: Check for a successful password reset message.
|
||||
expect(resetResponse.message).toBe('Password has been reset successfully.');
|
||||
|
||||
// Act 3 & Assert 3 (Verification): Log in with the NEW password to confirm the change.
|
||||
const loginResponse = await apiClient.loginUser(resetEmail, newPassword, false);
|
||||
expect(loginResponse.user).toBeDefined();
|
||||
expect(loginResponse.user.user_id).toBe(resetUser.user_id);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user