/** * Property-Based Test: Profile API Returns Complete User Data Matching Database * * Feature: user-profile, Property 2: Profile API returns complete user data matching database * * For any active user record, the profile route's mapping logic produces a * response object with all 6 required fields (id, username, email, group, * created_at, last_login) and each value matches the corresponding column * in the users table. The `group` field maps from the `user_group` column. * * Validates: Requirements 4.1 */ const fc = require('fast-check'); /** * Simulates the exact mapping logic from GET /api/auth/profile in routes/auth.js: * * res.json({ * id: user.id, * username: user.username, * email: user.email, * group: user.user_group, * created_at: user.created_at, * last_login: user.last_login * }); */ function mapUserRowToProfileResponse(user) { return { id: user.id, username: user.username, email: user.email, group: user.user_group, created_at: user.created_at, last_login: user.last_login }; } describe('Feature: user-profile, Property 2: Profile API returns complete user data matching database', () => { it('profile response contains all 6 required fields matching the database row', () => { fc.assert( fc.property( // Generate arbitrary user rows matching the users table schema fc.record({ id: fc.integer({ min: 1, max: 1000000 }), username: fc.string({ minLength: 1, maxLength: 50 }), email: fc.string({ minLength: 3, maxLength: 255 }), user_group: fc.constantFrom('Admin', 'Standard_User', 'Read_Only'), created_at: fc.integer({ min: 1577836800000, max: 1924991999000 }) .map(ts => new Date(ts).toISOString().replace('T', ' ').slice(0, 19)), last_login: fc.oneof( fc.integer({ min: 1577836800000, max: 1924991999000 }) .map(ts => new Date(ts).toISOString().replace('T', ' ').slice(0, 19)), fc.constant(null) ), is_active: fc.constant(1) }), (userRow) => { const response = mapUserRowToProfileResponse(userRow); // Assert all 6 required fields are present expect(response).toHaveProperty('id'); expect(response).toHaveProperty('username'); expect(response).toHaveProperty('email'); expect(response).toHaveProperty('group'); expect(response).toHaveProperty('created_at'); expect(response).toHaveProperty('last_login'); // Assert each value matches the corresponding database column expect(response.id).toBe(userRow.id); expect(response.username).toBe(userRow.username); expect(response.email).toBe(userRow.email); expect(response.group).toBe(userRow.user_group); // group maps from user_group expect(response.created_at).toBe(userRow.created_at); expect(response.last_login).toBe(userRow.last_login); // Assert exactly 6 keys — no extra fields leaked expect(Object.keys(response)).toHaveLength(6); } ), { numRuns: 100 } ); }); });