From 774cdb920d6090d50dcd7555bdbb6997159bccb7 Mon Sep 17 00:00:00 2001 From: Cristian Magherusan-Stanciu Date: Sat, 30 May 2026 19:02:57 +0200 Subject: [PATCH 1/2] test(api/auth): fix brittle mock string in resetPassword test (closes #513) The mock returned "invalid or expired token" but the real service emits "invalid or expired reset token" (with "reset"). Because isResetPasswordClientError matches the real string, the mismatched mock caused the error to fall through as a 500, but the test never checked the status code, so it passed vacuously. Fix: align the mock to the real service string and assert the error is classified as a 400 client error via IsClientError, which is the invariant the test was meant to guard. --- internal/api/handler_auth_test.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/internal/api/handler_auth_test.go b/internal/api/handler_auth_test.go index 26041abe3..3d9fd2880 100644 --- a/internal/api/handler_auth_test.go +++ b/internal/api/handler_auth_test.go @@ -708,7 +708,9 @@ func TestHandler_resetPassword_Error(t *testing.T) { ctx := context.Background() mockAuth := new(MockAuthService) - mockAuth.On("ConfirmPasswordReset", ctx, mock.Anything).Return(errors.New("invalid or expired token")) + // Use the exact string the real service emits so isResetPasswordClientError + // classifies it as a 400 client error, not a 500 internal error. + mockAuth.On("ConfirmPasswordReset", ctx, mock.Anything).Return(errors.New("invalid or expired reset token")) handler := &Handler{auth: mockAuth} @@ -718,9 +720,12 @@ func TestHandler_resetPassword_Error(t *testing.T) { encoded := base64.StdEncoding.EncodeToString([]byte("newpassword123")) req := &events.LambdaFunctionURLRequest{Body: `{"token": "bad-token", "new_password": "` + encoded + `"}`} result, err := handler.resetPassword(ctx, req) - assert.Error(t, err) + require.Error(t, err) assert.Nil(t, result) - assert.Contains(t, err.Error(), "invalid or expired token") + ce, ok := IsClientError(err) + require.True(t, ok, "expired-token error must be wrapped as a client error (400)") + assert.Equal(t, 400, ce.code) + assert.Contains(t, ce.Error(), "invalid or expired reset token") } // Issue #459: ConfirmPasswordReset errors must surface as a 4xx client From 087373f2e62524ac506c0977cf2d0aaddf895053 Mon Sep 17 00:00:00 2001 From: Cristian Magherusan-Stanciu Date: Fri, 19 Jun 2026 23:31:17 +0200 Subject: [PATCH 2/2] test(api/auth): register mock.AssertExpectations in resetPassword tests Add t.Cleanup(func(){ mockAuth.AssertExpectations(t) }) to TestHandler_resetPassword_Error and TestHandler_resetPassword_ErrorIsClientError so that a future On() call without a corresponding invocation is caught rather than silently passing. --- internal/api/handler_auth_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/api/handler_auth_test.go b/internal/api/handler_auth_test.go index 3d9fd2880..eccaf9b60 100644 --- a/internal/api/handler_auth_test.go +++ b/internal/api/handler_auth_test.go @@ -707,6 +707,7 @@ func TestHandler_resetPasswordStatus_NoAuthService(t *testing.T) { func TestHandler_resetPassword_Error(t *testing.T) { ctx := context.Background() mockAuth := new(MockAuthService) + t.Cleanup(func() { mockAuth.AssertExpectations(t) }) // Use the exact string the real service emits so isResetPasswordClientError // classifies it as a 400 client error, not a 500 internal error. @@ -737,6 +738,7 @@ func TestHandler_resetPassword_Error(t *testing.T) { func TestHandler_resetPassword_ErrorIsClientError(t *testing.T) { ctx := context.Background() mockAuth := new(MockAuthService) + t.Cleanup(func() { mockAuth.AssertExpectations(t) }) mockAuth.On("ConfirmPasswordReset", ctx, mock.Anything). Return(errors.New("this is your current password, choose a different one"))