diff --git a/__tests__/users.test.ts b/__tests__/users.test.ts index 38bd93e..30a9031 100644 --- a/__tests__/users.test.ts +++ b/__tests__/users.test.ts @@ -1,7 +1,6 @@ /** * Test suite for Users API - * This test file will fail due to the TypeError bug in api/users.ts - * Used for Workflow #1 - Bug Fixing + * Comprehensive unit tests with edge cases and error handling */ import { getUserById, getUserEmail, isAdmin, formatUserName } from '../api/users'; @@ -11,14 +10,36 @@ describe('Users API', () => { it('should return a user when given a valid ID', () => { const user = getUserById(1); expect(user).toBeDefined(); - expect(user.name).toBe('Alice Johnson'); + expect(user?.name).toBe('Alice Johnson'); + expect(user?.id).toBe(1); + expect(user?.email).toBe('alice@example.com'); + expect(user?.role).toBe('admin'); }); - // This test will FAIL due to the bug! it('should handle non-existent user ID gracefully', () => { const user = getUserById(999); expect(user).toBeUndefined(); }); + + it('should return correct user for each valid ID', () => { + const user2 = getUserById(2); + expect(user2?.name).toBe('Bob Smith'); + expect(user2?.role).toBe('user'); + + const user3 = getUserById(3); + expect(user3?.name).toBe('Charlie Brown'); + expect(user3?.role).toBe('guest'); + }); + + it('should handle negative ID values', () => { + const user = getUserById(-1); + expect(user).toBeUndefined(); + }); + + it('should handle zero as ID', () => { + const user = getUserById(0); + expect(user).toBeUndefined(); + }); }); describe('getUserEmail', () => { @@ -27,10 +48,24 @@ describe('Users API', () => { expect(email).toBe('bob@example.com'); }); - // This test will FAIL - TypeError! - it('should handle non-existent user', () => { + it('should return email for admin user', () => { + const email = getUserEmail(1); + expect(email).toBe('alice@example.com'); + }); + + it('should return undefined for non-existent user', () => { + const email = getUserEmail(999); + expect(email).toBeUndefined(); + }); + + it('should not throw error for invalid user ID', () => { expect(() => getUserEmail(999)).not.toThrow(); }); + + it('should handle negative user IDs', () => { + const email = getUserEmail(-5); + expect(email).toBeUndefined(); + }); }); describe('isAdmin', () => { @@ -42,10 +77,21 @@ describe('Users API', () => { expect(isAdmin(2)).toBe(false); }); - // This test will FAIL - TypeError! - it('should handle non-existent user', () => { + it('should return false for guest user', () => { + expect(isAdmin(3)).toBe(false); + }); + + it('should return false for non-existent user', () => { + expect(isAdmin(999)).toBe(false); + }); + + it('should not throw error when checking non-existent user', () => { expect(() => isAdmin(999)).not.toThrow(); }); + + it('should return false for negative user IDs', () => { + expect(isAdmin(-1)).toBe(false); + }); }); describe('formatUserName', () => { @@ -53,5 +99,22 @@ describe('Users API', () => { const user = { id: 1, name: 'john doe', email: 'john@test.com', role: 'user' as const }; expect(formatUserName(user)).toBe('JOHN DOE'); }); + + it('should format existing user names correctly', () => { + const user1 = getUserById(1); + if (user1) { + expect(formatUserName(user1)).toBe('ALICE JOHNSON'); + } + }); + + it('should handle single-word names', () => { + const user = { id: 5, name: 'Alice', email: 'alice@test.com', role: 'admin' as const }; + expect(formatUserName(user)).toBe('ALICE'); + }); + + it('should handle names with special characters', () => { + const user = { id: 6, name: "O'Brien", email: 'obrien@test.com', role: 'user' as const }; + expect(formatUserName(user)).toBe("O'BRIEN"); + }); }); }); \ No newline at end of file diff --git a/api/users.ts b/api/users.ts index 45a29e0..1512a52 100644 --- a/api/users.ts +++ b/api/users.ts @@ -20,47 +20,42 @@ const users: User[] = [ /** * Get user by ID - * BUG: This function doesn't handle the case when user is not found + * @param id - The user ID to search for + * @returns The user object if found, undefined otherwise */ -export function getUserById(id: number): User { +export function getUserById(id: number): User | undefined { const user = users.find(u => u.id === id); - // TypeError will occur here when user is undefined return user; } /** * Get user's email - * BUG: Accessing property on potentially undefined result + * @param userId - The user ID + * @returns The user's email if found, undefined otherwise */ -export function getUserEmail(userId: number): string { +export function getUserEmail(userId: number): string | undefined { const user = getUserById(userId); - // This will throw TypeError if user doesn't exist - return user.email; + return user?.email; } /** * Check if user is admin - * BUG: No null check before accessing role property + * @param userId - The user ID to check + * @returns True if user exists and is admin, false otherwise */ export function isAdmin(userId: number): boolean { const user = getUserById(userId); - // Another potential TypeError here - return user.role === 'admin'; + return user?.role === 'admin'; } -// Unused import that should be cleaned up (for Workflow #2) -import * as fs from 'fs'; -// Console.log that should be removed (for Workflow #2) -console.log('Users API loaded'); /** * Format user display name - * Missing proper formatting and has inconsistent spacing + * @param user - The user object + * @returns The formatted display name in uppercase */ export function formatUserName(user: User): string { - // Inconsistent indentation (for ESLint to catch) - const displayName=user.name.toUpperCase(); // Missing spaces around = - return displayName - // Missing semicolon above (for Prettier to fix) + const displayName = user.name.toUpperCase(); + return displayName; } \ No newline at end of file