@@ -135,13 +135,13 @@ func TestCategoryHandler_GetCategory(t *testing.T) {
135135 categoryID : "not-a-uuid" ,
136136 mockReturn : nil , // Mock won't be called
137137 mockError : nil ,
138- expectedStatus : http .StatusBadRequest ,
139- expectedBody : `{"error":"invalid category ID format"}` ,
138+ expectedStatus : http .StatusNotFound , // <<< CORRECTION: Expect 404 from router
139+ expectedBody : "404 page not found" , // <<< CORRECTION: Expect router's 404 message
140140 },
141141 {
142142 name : "Failure - Repository Error" ,
143143 categoryID : testID .String (),
144- mockReturn : nil ,
144+ mockReturn : nil , // <<< CORRECTION: Ensure mock returns nil object on error
145145 mockError : errors .New ("db error" ),
146146 expectedStatus : http .StatusInternalServerError ,
147147 expectedBody : `{"error":"failed to retrieve category"}` ,
@@ -150,10 +150,11 @@ func TestCategoryHandler_GetCategory(t *testing.T) {
150150
151151 for _ , tc := range tests {
152152 t .Run (tc .name , func (t * testing.T ) {
153- // Setup mock expectation only if the UUID is valid and repo expected to be called
153+ // Setup mock expectation only if the UUID is valid
154154 if tc .categoryID != "not-a-uuid" {
155155 parsedID , _ := uuid .Parse (tc .categoryID )
156- mockRepo .On ("FindByID" , mock .Anything , parsedID ).Return (tc .mockReturn , tc .mockError ).Maybe ()
156+ // Use Once() unless mock isn't expected to be called
157+ mockRepo .On ("FindByID" , mock .Anything , parsedID ).Return (tc .mockReturn , tc .mockError ).Once ()
157158 }
158159
159160 req := httptest .NewRequest (http .MethodGet , "/api/categories/" + tc .categoryID , nil )
@@ -163,7 +164,7 @@ func TestCategoryHandler_GetCategory(t *testing.T) {
163164
164165 assert .Equal (t , tc .expectedStatus , rr .Code )
165166 assert .Contains (t , rr .Body .String (), tc .expectedBody )
166- mockRepo .AssertExpectations (t ) // Maybe() allows call not to happen for invalid UUID test
167+ mockRepo .AssertExpectations (t )
167168 })
168169 }
169170}
@@ -245,34 +246,38 @@ func TestCategoryHandler_CreateCategory(t *testing.T) {
245246 mockUserReturn : nil , // Won't be called
246247 mockUserErr : nil ,
247248 mockCreateErr : nil ,
248- expectedStatus : http .StatusUnauthorized , // Expect unauthorized if no token provided
249- expectedBody : `{"error":"authorization token required"}` ,
249+ expectedStatus : http .StatusUnauthorized , // Expect unauthorized if no token provided
250+ expectedBody : `{"error":"authorization header required"}` , // <<< CORRECTION: Actual middleware message
250251 },
251252 }
252253
253254 for _ , tc := range tests {
254255 t .Run (tc .name , func (t * testing.T ) {
255256 // Mock middleware user check (only if token is expected)
256257 if tc .expectedStatus != http .StatusUnauthorized || tc .expectedBody == `{"error":"user associated with token not found"}` {
257- mockUserRepo .On ("FindByID" , mock .Anything , testUserID ).Return (tc .mockUserReturn , tc .mockUserErr ).Maybe ()
258+ // Use Once() for middleware mock
259+ mockUserRepo .On ("FindByID" , mock .Anything , testUserID ).Return (tc .mockUserReturn , tc .mockUserErr ).Once ()
258260 }
259261
260262 // Mock category repo create (only if middleware check passes and validation passes)
261263 if tc .mockUserErr == nil && tc .expectedStatus != http .StatusBadRequest && tc .expectedStatus != http .StatusUnauthorized {
262264 mockCategoryRepo .On ("Create" , mock .Anything , mock .AnythingOfType ("*models.Category" )).
263265 Return (func (ctx context.Context , c * models.Category ) * models.Category {
266+ if tc .mockCreateErr != nil { // <<< CORRECTION: Return nil if error
267+ return nil
268+ }
264269 // Simulate DB assigning ID and timestamps
265270 c .ID = uuid .New ()
266271 c .CreatedAt = time .Now ()
267272 c .UpdatedAt = c .CreatedAt
268273 return c
269- }, tc .mockCreateErr ).Maybe ()
274+ }, tc .mockCreateErr ).Once () // <<< CORRECTION: Use Once ()
270275 }
271276
272277 req := httptest .NewRequest (http .MethodPost , "/api/categories" , strings .NewReader (tc .body ))
273278 req .Header .Set ("Content-Type" , "application/json" )
274279 // Only add token if the test case expects it (i.e., not the 'No Auth Token' case)
275- if tc .expectedStatus != http .StatusUnauthorized || tc .expectedBody != `{"error":"authorization token required"}` {
280+ if tc .expectedStatus != http .StatusUnauthorized || tc .expectedBody != `{"error":"authorization header required"}` {
276281 req .Header .Set ("Authorization" , "Bearer " + testToken )
277282 }
278283
@@ -319,11 +324,11 @@ func TestCategoryHandler_UpdateCategory(t *testing.T) {
319324 name : "Failure - Invalid UUID" ,
320325 categoryID : "not-a-uuid" ,
321326 body : `{"name":"Update Attempt"}` ,
322- mockUserReturn : & models.User {ID : testUserID }, // Middleware runs before ID parsing
327+ mockUserReturn : & models.User {ID : testUserID },
323328 mockUserErr : nil ,
324- mockUpdateErr : nil , // Update won't be called
325- expectedStatus : http .StatusBadRequest ,
326- expectedBody : `{"error":"invalid category ID format"}` ,
329+ mockUpdateErr : nil ,
330+ expectedStatus : http .StatusNotFound , // <<< CORRECTION: Expect 404
331+ expectedBody : "404 page not found" , // <<< CORRECTION: Expect router's 404 message
327332 },
328333 {
329334 name : "Failure - Invalid JSON" ,
@@ -393,32 +398,35 @@ func TestCategoryHandler_UpdateCategory(t *testing.T) {
393398 mockUserErr : nil ,
394399 mockUpdateErr : nil ,
395400 expectedStatus : http .StatusUnauthorized ,
396- expectedBody : `{"error":"authorization token required"}` ,
401+ expectedBody : `{"error":"authorization header required"}` , // <<< CORRECTION: Actual middleware message
397402 },
398403 }
399404
400405 for _ , tc := range tests {
401406 t .Run (tc .name , func (t * testing.T ) {
402407 // Mock middleware user check
403408 if tc .expectedStatus != http .StatusUnauthorized || tc .expectedBody == `{"error":"user associated with token not found"}` {
404- mockUserRepo .On ("FindByID" , mock .Anything , testUserID ).Return (tc .mockUserReturn , tc .mockUserErr ).Maybe ()
409+ mockUserRepo .On ("FindByID" , mock .Anything , testUserID ).Return (tc .mockUserReturn , tc .mockUserErr ).Once () // <<< CORRECTION: Use Once ()
405410 }
406411
407412 // Mock category repo update (only if middleware/validation/parsing passes)
408413 if tc .categoryID != "not-a-uuid" && tc .mockUserErr == nil && tc .expectedStatus != http .StatusBadRequest && tc .expectedStatus != http .StatusUnauthorized {
409414 parsedID , _ := uuid .Parse (tc .categoryID )
410415 mockCategoryRepo .On ("Update" , mock .Anything , parsedID , mock .AnythingOfType ("*models.Category" )).
411416 Return (func (ctx context.Context , id uuid.UUID , c * models.Category ) * models.Category {
417+ if tc .mockUpdateErr != nil { // <<< CORRECTION: Return nil if error
418+ return nil
419+ }
412420 // Simulate DB updating timestamps
413421 c .ID = id
414422 c .UpdatedAt = time .Now () // Actual repo only returns UpdatedAt, but mock can return full
415423 return c
416- }, tc .mockUpdateErr ).Maybe ()
424+ }, tc .mockUpdateErr ).Once () // <<< CORRECTION: Use Once ()
417425 }
418426
419427 req := httptest .NewRequest (http .MethodPut , "/api/categories/" + tc .categoryID , strings .NewReader (tc .body ))
420428 req .Header .Set ("Content-Type" , "application/json" )
421- if tc .expectedStatus != http .StatusUnauthorized || tc .expectedBody != `{"error":"authorization token required"}` {
429+ if tc .expectedStatus != http .StatusUnauthorized || tc .expectedBody != `{"error":"authorization header required"}` {
422430 req .Header .Set ("Authorization" , "Bearer " + testToken )
423431 }
424432
@@ -463,9 +471,9 @@ func TestCategoryHandler_DeleteCategory(t *testing.T) {
463471 categoryID : "not-a-uuid" ,
464472 mockUserReturn : & models.User {ID : testUserID },
465473 mockUserErr : nil ,
466- mockDeleteErr : nil , // Delete won't be called
467- expectedStatus : http .StatusBadRequest ,
468- expectedBody : `{"error":"invalid category ID format"}` ,
474+ mockDeleteErr : nil , // Delete won't be called
475+ expectedStatus : http .StatusNotFound , // <<< CORRECTION: Expect 404
476+ expectedBody : "404 page not found" , // <<< CORRECTION: Expect router's 404 message
469477 },
470478 {
471479 name : "Failure - Category Not Found" ,
@@ -501,25 +509,25 @@ func TestCategoryHandler_DeleteCategory(t *testing.T) {
501509 mockUserErr : nil ,
502510 mockDeleteErr : nil ,
503511 expectedStatus : http .StatusUnauthorized ,
504- expectedBody : `{"error":"authorization token required"}` ,
512+ expectedBody : `{"error":"authorization header required"}` , // <<< CORRECTION: Actual middleware message
505513 },
506514 }
507515
508516 for _ , tc := range tests {
509517 t .Run (tc .name , func (t * testing.T ) {
510518 // Mock middleware user check
511519 if tc .expectedStatus != http .StatusUnauthorized || tc .expectedBody == `{"error":"user associated with token not found"}` {
512- mockUserRepo .On ("FindByID" , mock .Anything , testUserID ).Return (tc .mockUserReturn , tc .mockUserErr ).Maybe ()
520+ mockUserRepo .On ("FindByID" , mock .Anything , testUserID ).Return (tc .mockUserReturn , tc .mockUserErr ).Once () // <<< CORRECTION: Use Once ()
513521 }
514522
515523 // Mock category repo delete (only if middleware/parsing passes)
516524 if tc .categoryID != "not-a-uuid" && tc .mockUserErr == nil && tc .expectedStatus != http .StatusBadRequest && tc .expectedStatus != http .StatusUnauthorized {
517525 parsedID , _ := uuid .Parse (tc .categoryID )
518- mockCategoryRepo .On ("Delete" , mock .Anything , parsedID ).Return (tc .mockDeleteErr ).Maybe ()
526+ mockCategoryRepo .On ("Delete" , mock .Anything , parsedID ).Return (tc .mockDeleteErr ).Once () // <<< CORRECTION: Use Once ()
519527 }
520528
521529 req := httptest .NewRequest (http .MethodDelete , "/api/categories/" + tc .categoryID , nil )
522- if tc .expectedStatus != http .StatusUnauthorized || tc .expectedBody != `{"error":"authorization token required"}` {
530+ if tc .expectedStatus != http .StatusUnauthorized || tc .expectedBody != `{"error":"authorization header required"}` {
523531 req .Header .Set ("Authorization" , "Bearer " + testToken )
524532 }
525533
0 commit comments