@@ -54,6 +54,19 @@ func TestLoginUser(t *testing.T) {
5454 // Call the handler
5555 handler .LoginUser (c )
5656 assert .Equal (t , http .StatusOK , w .Code )
57+
58+ // Verify response structure
59+ var response LoginResponse
60+ err := json .Unmarshal (w .Body .Bytes (), & response )
61+ assert .NoError (t , err )
62+ assert .True (t , response .Success )
63+ assert .Equal (t , "Login successful" , response .Message )
64+ assert .NotEmpty (t , response .Token )
65+
66+ // Verify security headers
67+ assert .Equal (t , "nosniff" , w .Header ().Get ("X-Content-Type-Options" ))
68+ assert .Equal (t , "DENY" , w .Header ().Get ("X-Frame-Options" ))
69+ assert .Equal (t , "1; mode=block" , w .Header ().Get ("X-XSS-Protection" ))
5770 })
5871
5972 t .Run ("bad request with invalid JSON" , func (t * testing.T ) {
@@ -63,18 +76,6 @@ func TestLoginUser(t *testing.T) {
6376 mockLoginService := services .NewUserLoginService (mockDBService )
6477 handler := & UserHandler {userRegistrationService : * mockRegService , userLoginService : * mockLoginService }
6578
66- user := & models.User {
67- Email : mocks .TestUserEmail ,
68- Password : mocks .TestUserPasswordHash ,
69- }
70- userDetails := & models.UserDetail {
71- FirstName : mocks .TestUserFirstName ,
72- LastName : mocks .TestUserLastName ,
73- }
74-
75- mockDBService .On ("FindUserByEmail" , user .Email ).Return (user , nil )
76- mockDBService .On ("FindUserDetailsByUserID" , user .ID ).Return (userDetails , nil )
77-
7879 // Create a request with invalid JSON
7980 req , _ := http .NewRequest (http .MethodPost , "/auth/login" , bytes .NewBuffer ([]byte ("{invalid-json" )))
8081 req .Header .Set ("Content-Type" , "application/json" )
@@ -89,10 +90,12 @@ func TestLoginUser(t *testing.T) {
8990
9091 // Assert the results
9192 assert .Equal (t , http .StatusBadRequest , w .Code )
92- var response map [ string ] string
93+ var response ErrorResponse
9394 err := json .Unmarshal (w .Body .Bytes (), & response )
9495 assert .NoError (t , err )
95- assert .Contains (t , response ["error" ], "invalid character" )
96+ assert .False (t , response .Success )
97+ assert .Equal (t , "Invalid input data" , response .Message )
98+ assert .Equal (t , "validation_failed" , response .Error )
9699 })
97100
98101 t .Run ("Invalid Email format Error Test" , func (t * testing.T ) {
@@ -124,10 +127,12 @@ func TestLoginUser(t *testing.T) {
124127
125128 // Assert the results
126129 assert .Equal (t , http .StatusBadRequest , w .Code )
127- var response map [ string ] string
130+ var response ErrorResponse
128131 err := json .Unmarshal (w .Body .Bytes (), & response )
129132 assert .NoError (t , err )
130- assert .Contains (t , response ["error" ], "Error:Field validation for 'Email' failed on the 'email' tag" )
133+ assert .False (t , response .Success )
134+ assert .Equal (t , "Please provide a valid email address" , response .Message )
135+ assert .Equal (t , "validation_failed" , response .Error )
131136 })
132137
133138 t .Run ("Unauthorized Login Test" , func (t * testing.T ) {
@@ -169,9 +174,110 @@ func TestLoginUser(t *testing.T) {
169174
170175 // Assert the results
171176 assert .Equal (t , http .StatusUnauthorized , w .Code )
172- var response map [string ]string
177+ var response ErrorResponse
178+ err := json .Unmarshal (w .Body .Bytes (), & response )
179+ assert .NoError (t , err )
180+ assert .False (t , response .Success )
181+ assert .Equal (t , "Invalid email or password" , response .Message )
182+ assert .Equal (t , "authentication_failed" , response .Error )
183+ })
184+
185+ t .Run ("Empty email validation" , func (t * testing.T ) {
186+ mockDBService := new (mocks.MockDatabaseOperationService )
187+ mockPasswordDeliveryService := & mocks.MockPasswordDeliveryService {ShouldFail : false }
188+ mockRegService := services .NewUserRegistrationService (mockPasswordDeliveryService , mockDBService )
189+ mockLoginService := services .NewUserLoginService (mockDBService )
190+ handler := & UserHandler {userRegistrationService : * mockRegService , userLoginService : * mockLoginService }
191+
192+ // Sample request data with empty email (spaces are treated as invalid email format by binding validation)
193+ loginRequest := models.LoginRequest {
194+ Email : " " ,
195+ Password : "password123" ,
196+ }
197+
198+ // Create a request
199+ requestBody , _ := json .Marshal (loginRequest )
200+ req , _ := http .NewRequest (http .MethodPost , "/login" , bytes .NewBuffer (requestBody ))
201+ req .Header .Set ("Content-Type" , "application/json" )
202+
203+ // Create a ResponseRecorder to capture the response
204+ w := httptest .NewRecorder ()
205+ c , _ := gin .CreateTestContext (w )
206+ c .Request = req
207+
208+ handler .LoginUser (c )
209+
210+ // Assert the results - binding validation catches this first as invalid email format
211+ assert .Equal (t , http .StatusBadRequest , w .Code )
212+ var response ErrorResponse
213+ err := json .Unmarshal (w .Body .Bytes (), & response )
214+ assert .NoError (t , err )
215+ assert .False (t , response .Success )
216+ assert .Equal (t , "Please provide a valid email address" , response .Message )
217+ assert .Equal (t , "validation_failed" , response .Error )
218+ })
219+
220+ t .Run ("Missing email field validation" , func (t * testing.T ) {
221+ mockDBService := new (mocks.MockDatabaseOperationService )
222+ mockPasswordDeliveryService := & mocks.MockPasswordDeliveryService {ShouldFail : false }
223+ mockRegService := services .NewUserRegistrationService (mockPasswordDeliveryService , mockDBService )
224+ mockLoginService := services .NewUserLoginService (mockDBService )
225+ handler := & UserHandler {userRegistrationService : * mockRegService , userLoginService : * mockLoginService }
226+
227+ // Create request with missing email field entirely
228+ requestBody := []byte (`{"password": "password123"}` )
229+ req , _ := http .NewRequest (http .MethodPost , "/login" , bytes .NewBuffer (requestBody ))
230+ req .Header .Set ("Content-Type" , "application/json" )
231+
232+ // Create a ResponseRecorder to capture the response
233+ w := httptest .NewRecorder ()
234+ c , _ := gin .CreateTestContext (w )
235+ c .Request = req
236+
237+ handler .LoginUser (c )
238+
239+ // Assert the results - missing required field triggers general validation error
240+ assert .Equal (t , http .StatusBadRequest , w .Code )
241+ var response ErrorResponse
242+ err := json .Unmarshal (w .Body .Bytes (), & response )
243+ assert .NoError (t , err )
244+ assert .False (t , response .Success )
245+ assert .Equal (t , "Invalid input data" , response .Message )
246+ assert .Equal (t , "validation_failed" , response .Error )
247+ })
248+
249+ t .Run ("Empty password validation" , func (t * testing.T ) {
250+ mockDBService := new (mocks.MockDatabaseOperationService )
251+ mockPasswordDeliveryService := & mocks.MockPasswordDeliveryService {ShouldFail : false }
252+ mockRegService := services .NewUserRegistrationService (mockPasswordDeliveryService , mockDBService )
253+ mockLoginService := services .NewUserLoginService (mockDBService )
254+ handler := & UserHandler {userRegistrationService : * mockRegService , userLoginService : * mockLoginService }
255+
256+ // Sample request data with empty password
257+ loginRequest := models.LoginRequest {
258+ Email : mocks .TestUserEmail ,
259+ Password : " " ,
260+ }
261+
262+ // Create a request
263+ requestBody , _ := json .Marshal (loginRequest )
264+ req , _ := http .NewRequest (http .MethodPost , "/login" , bytes .NewBuffer (requestBody ))
265+ req .Header .Set ("Content-Type" , "application/json" )
266+
267+ // Create a ResponseRecorder to capture the response
268+ w := httptest .NewRecorder ()
269+ c , _ := gin .CreateTestContext (w )
270+ c .Request = req
271+
272+ handler .LoginUser (c )
273+
274+ // Assert the results
275+ assert .Equal (t , http .StatusBadRequest , w .Code )
276+ var response ErrorResponse
173277 err := json .Unmarshal (w .Body .Bytes (), & response )
174278 assert .NoError (t , err )
175- assert .Contains (t , response ["error" ], "Invalid credentials" )
279+ assert .False (t , response .Success )
280+ assert .Equal (t , "Password is required" , response .Message )
281+ assert .Equal (t , "missing_password" , response .Error )
176282 })
177283}
0 commit comments