diff --git a/packages/api/src/routes/meal-plans.routes.test.ts b/packages/api/src/routes/meal-plans.routes.test.ts index b8fc051..12d36c5 100644 --- a/packages/api/src/routes/meal-plans.routes.test.ts +++ b/packages/api/src/routes/meal-plans.routes.test.ts @@ -203,7 +203,7 @@ describe('Meal Plans Routes - Unit Tests', () => { }; const prisma = await import('../config/database'); - vi.mocked(prisma.default.mealPlan.findFirst).mockResolvedValue(mockMealPlan as any); + vi.mocked(prisma.default.mealPlan.findUnique).mockResolvedValue(mockMealPlan as any); const response = await request(app) .get('/meal-plans/mp1') @@ -214,7 +214,7 @@ describe('Meal Plans Routes - Unit Tests', () => { it('should return 404 if meal plan not found', async () => { const prisma = await import('../config/database'); - vi.mocked(prisma.default.mealPlan.findFirst).mockResolvedValue(null); + vi.mocked(prisma.default.mealPlan.findUnique).mockResolvedValue(null); const response = await request(app) .get('/meal-plans/nonexistent') @@ -223,26 +223,33 @@ describe('Meal Plans Routes - Unit Tests', () => { expect(response.body.error).toBe('Meal plan not found'); }); - it('should filter by userId automatically', async () => { + it('should return 403 if meal plan belongs to different user', async () => { + const mockMealPlan = { + id: 'mp1', + userId: 'different-user-id', + date: new Date('2025-01-15'), + notes: 'Test plan', + meals: [], + createdAt: new Date(), + updatedAt: new Date(), + }; + const prisma = await import('../config/database'); - vi.mocked(prisma.default.mealPlan.findFirst).mockResolvedValue(null); + vi.mocked(prisma.default.mealPlan.findUnique).mockResolvedValue(mockMealPlan as any); await request(app) .get('/meal-plans/mp1') - .expect(404); + .expect(403); - expect(prisma.default.mealPlan.findFirst).toHaveBeenCalledWith({ - where: { - id: 'mp1', - userId: 'test-user-id', - }, + expect(prisma.default.mealPlan.findUnique).toHaveBeenCalledWith({ + where: { id: 'mp1' }, include: expect.any(Object), }); }); it('should handle database errors', async () => { const prisma = await import('../config/database'); - vi.mocked(prisma.default.mealPlan.findFirst).mockRejectedValue( + vi.mocked(prisma.default.mealPlan.findUnique).mockRejectedValue( new Error('Database error') ); @@ -388,7 +395,7 @@ describe('Meal Plans Routes - Unit Tests', () => { }; const prisma = await import('../config/database'); - vi.mocked(prisma.default.mealPlan.findFirst).mockResolvedValue(mockExistingPlan as any); + vi.mocked(prisma.default.mealPlan.findUnique).mockResolvedValue(mockExistingPlan as any); vi.mocked(prisma.default.mealPlan.update).mockResolvedValue(mockUpdatedPlan as any); const response = await request(app) @@ -403,7 +410,7 @@ describe('Meal Plans Routes - Unit Tests', () => { it('should return 404 if meal plan not found', async () => { const prisma = await import('../config/database'); - vi.mocked(prisma.default.mealPlan.findFirst).mockResolvedValue(null); + vi.mocked(prisma.default.mealPlan.findUnique).mockResolvedValue(null); const response = await request(app) .put('/meal-plans/nonexistent') @@ -416,18 +423,28 @@ describe('Meal Plans Routes - Unit Tests', () => { }); it('should verify user ownership', async () => { + const mockMealPlan = { + id: 'mp1', + userId: 'different-user-id', + date: new Date('2025-01-15'), + notes: 'Old notes', + meals: [], + createdAt: new Date(), + updatedAt: new Date(), + }; + const prisma = await import('../config/database'); - vi.mocked(prisma.default.mealPlan.findFirst).mockResolvedValue(null); + vi.mocked(prisma.default.mealPlan.findUnique).mockResolvedValue(mockMealPlan as any); await request(app) .put('/meal-plans/mp1') .send({ notes: 'Updated notes', }) - .expect(404); + .expect(403); - expect(prisma.default.mealPlan.findFirst).toHaveBeenCalledWith({ - where: { id: 'mp1', userId: 'test-user-id' }, + expect(prisma.default.mealPlan.findUnique).toHaveBeenCalledWith({ + where: { id: 'mp1' }, }); }); @@ -443,7 +460,7 @@ describe('Meal Plans Routes - Unit Tests', () => { }; const prisma = await import('../config/database'); - vi.mocked(prisma.default.mealPlan.findFirst).mockResolvedValue(mockExistingPlan as any); + vi.mocked(prisma.default.mealPlan.findUnique).mockResolvedValue(mockExistingPlan as any); vi.mocked(prisma.default.mealPlan.update).mockRejectedValue( new Error('Database error') ); @@ -472,7 +489,7 @@ describe('Meal Plans Routes - Unit Tests', () => { }; const prisma = await import('../config/database'); - vi.mocked(prisma.default.mealPlan.findFirst).mockResolvedValue(mockMealPlan as any); + vi.mocked(prisma.default.mealPlan.findUnique).mockResolvedValue(mockMealPlan as any); vi.mocked(prisma.default.mealPlan.delete).mockResolvedValue(mockMealPlan as any); const response = await request(app) @@ -484,7 +501,7 @@ describe('Meal Plans Routes - Unit Tests', () => { it('should return 404 if meal plan not found', async () => { const prisma = await import('../config/database'); - vi.mocked(prisma.default.mealPlan.findFirst).mockResolvedValue(null); + vi.mocked(prisma.default.mealPlan.findUnique).mockResolvedValue(null); const response = await request(app) .delete('/meal-plans/nonexistent') @@ -494,15 +511,25 @@ describe('Meal Plans Routes - Unit Tests', () => { }); it('should verify user ownership', async () => { + const mockMealPlan = { + id: 'mp1', + userId: 'different-user-id', + date: new Date('2025-01-15'), + notes: 'Test plan', + meals: [], + createdAt: new Date(), + updatedAt: new Date(), + }; + const prisma = await import('../config/database'); - vi.mocked(prisma.default.mealPlan.findFirst).mockResolvedValue(null); + vi.mocked(prisma.default.mealPlan.findUnique).mockResolvedValue(mockMealPlan as any); await request(app) .delete('/meal-plans/mp1') - .expect(404); + .expect(403); - expect(prisma.default.mealPlan.findFirst).toHaveBeenCalledWith({ - where: { id: 'mp1', userId: 'test-user-id' }, + expect(prisma.default.mealPlan.findUnique).toHaveBeenCalledWith({ + where: { id: 'mp1' }, }); }); @@ -518,7 +545,7 @@ describe('Meal Plans Routes - Unit Tests', () => { }; const prisma = await import('../config/database'); - vi.mocked(prisma.default.mealPlan.findFirst).mockResolvedValue(mockMealPlan as any); + vi.mocked(prisma.default.mealPlan.findUnique).mockResolvedValue(mockMealPlan as any); vi.mocked(prisma.default.mealPlan.delete).mockRejectedValue( new Error('Database error') ); @@ -563,7 +590,7 @@ describe('Meal Plans Routes - Unit Tests', () => { }; const prisma = await import('../config/database'); - vi.mocked(prisma.default.mealPlan.findFirst).mockResolvedValue(mockMealPlan as any); + vi.mocked(prisma.default.mealPlan.findUnique).mockResolvedValue(mockMealPlan as any); vi.mocked(prisma.default.meal.create).mockResolvedValue(mockCreatedMeal as any); vi.mocked(prisma.default.mealRecipe.create).mockResolvedValue({ mealId: 'm1', recipeId: 'r1' } as any); vi.mocked(prisma.default.meal.findUnique).mockResolvedValue(mockCompleteMeal as any); @@ -582,7 +609,7 @@ describe('Meal Plans Routes - Unit Tests', () => { it('should return 404 if meal plan not found', async () => { const prisma = await import('../config/database'); - vi.mocked(prisma.default.mealPlan.findFirst).mockResolvedValue(null); + vi.mocked(prisma.default.mealPlan.findUnique).mockResolvedValue(null); const response = await request(app) .post('/meal-plans/nonexistent/meals') @@ -597,8 +624,18 @@ describe('Meal Plans Routes - Unit Tests', () => { }); it('should verify user ownership', async () => { + const mockMealPlan = { + id: 'mp1', + userId: 'different-user-id', + date: new Date('2025-01-15'), + notes: 'Test plan', + meals: [], + createdAt: new Date(), + updatedAt: new Date(), + }; + const prisma = await import('../config/database'); - vi.mocked(prisma.default.mealPlan.findFirst).mockResolvedValue(null); + vi.mocked(prisma.default.mealPlan.findUnique).mockResolvedValue(mockMealPlan as any); await request(app) .post('/meal-plans/mp1/meals') @@ -606,10 +643,10 @@ describe('Meal Plans Routes - Unit Tests', () => { mealType: 'BREAKFAST', recipeId: 'r1', }) - .expect(404); + .expect(403); - expect(prisma.default.mealPlan.findFirst).toHaveBeenCalledWith({ - where: { id: 'mp1', userId: 'test-user-id' }, + expect(prisma.default.mealPlan.findUnique).toHaveBeenCalledWith({ + where: { id: 'mp1' }, include: { meals: true }, }); }); @@ -654,7 +691,7 @@ describe('Meal Plans Routes - Unit Tests', () => { }; const prisma = await import('../config/database'); - vi.mocked(prisma.default.mealPlan.findFirst).mockResolvedValue(mockMealPlan as any); + vi.mocked(prisma.default.mealPlan.findUnique).mockResolvedValue(mockMealPlan as any); vi.mocked(prisma.default.meal.create).mockResolvedValue(mockCreatedMeal as any); vi.mocked(prisma.default.mealRecipe.create).mockResolvedValue({ mealId: 'm1', recipeId: 'r1' } as any); vi.mocked(prisma.default.meal.findUnique).mockResolvedValue(mockCreatedMeal as any); @@ -687,7 +724,7 @@ describe('Meal Plans Routes - Unit Tests', () => { }; const prisma = await import('../config/database'); - vi.mocked(prisma.default.mealPlan.findFirst).mockResolvedValue(mockMealPlan as any); + vi.mocked(prisma.default.mealPlan.findUnique).mockResolvedValue(mockMealPlan as any); vi.mocked(prisma.default.meal.create).mockRejectedValue( new Error('Database error') ); @@ -924,7 +961,7 @@ describe('Meal Plans Routes - Unit Tests', () => { .expect(200); expect(response.body.data.items).toHaveLength(2); - expect(response.body.data.items[0].ingredientName).toBe('flour'); + expect(response.body.data.items[0].ingredientName).toBe('Flour'); expect(response.body.data.items[0].totalAmount).toBe(2); expect(response.body.data.items[0].unit).toBe('cups'); expect(response.body.data.items[0].recipes).toContain('Pancakes');