Skip to content

Commit

Permalink
api test for recover and reset password
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasmenendez committed Sep 16, 2024
1 parent 345d687 commit 76846dc
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 1 deletion.
5 changes: 5 additions & 0 deletions api/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,11 @@ func (a *API) recoverUserPasswordHandler(w http.ResponseWriter, r *http.Request)
ErrGenericInternalServerError.Write(w)
return
}
// check the user is verified
if !user.Verified {
ErrUnauthorized.With("user not verified").Write(w)
return
}
// generate a new verification code
if err := a.sendUserCode(r.Context(), user, db.CodeTypePasswordReset); err != nil {
log.Warnw("could not send verification code", "error", err)
Expand Down
93 changes: 93 additions & 0 deletions api/users_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,3 +206,96 @@ func TestVerifyAccountHandler(t *testing.T) {
c.Assert(resp.StatusCode, qt.Equals, http.StatusOK)
c.Assert(resp.Body.Close(), qt.IsNil)
}

func TestRecoverAndResetPassword(t *testing.T) {
c := qt.New(t)
defer func() {
if err := testDB.Reset(); err != nil {
c.Logf("error resetting test database: %v", err)
}
}()
// register a user
jsonUser := mustMarshal(&UserInfo{
Email: testEmail,
Password: testPass,
FirstName: testFirstName,
LastName: testLastName,
})
req, err := http.NewRequest(http.MethodPost, testURL(usersEndpoint), bytes.NewBuffer(jsonUser))
c.Assert(err, qt.IsNil)
resp, err := http.DefaultClient.Do(req)
c.Assert(err, qt.IsNil)
c.Assert(resp.StatusCode, qt.Equals, http.StatusOK)
c.Assert(resp.Body.Close(), qt.IsNil)
// try to recover the password before verifying the user (should fail)
jsonRecover := mustMarshal(&UserInfo{
Email: testEmail,
})
req, err = http.NewRequest(http.MethodPost, testURL(usersRecoveryPasswordEndpoint), bytes.NewBuffer(jsonRecover))
c.Assert(err, qt.IsNil)
resp, err = http.DefaultClient.Do(req)
c.Assert(err, qt.IsNil)
c.Assert(resp.StatusCode, qt.Equals, http.StatusUnauthorized)
c.Assert(resp.Body.Close(), qt.IsNil)
// get the verification code from the email
mailBody, err := testMailService.FindEmail(context.Background(), testEmail)
c.Assert(err, qt.IsNil)
verifyMailCode := strings.TrimPrefix(mailBody, VerificationCodeEmailBody)
// verify the user
verification := mustMarshal(&UserVerification{
Email: testEmail,
Code: verifyMailCode,
})
req, err = http.NewRequest(http.MethodPost, testURL(verifyUserEndpoint), bytes.NewBuffer(verification))
c.Assert(err, qt.IsNil)
resp, err = http.DefaultClient.Do(req)
c.Assert(err, qt.IsNil)
c.Assert(resp.StatusCode, qt.Equals, http.StatusOK)
c.Assert(resp.Body.Close(), qt.IsNil)
// try to recover the password after verifying the user
req, err = http.NewRequest(http.MethodPost, testURL(usersRecoveryPasswordEndpoint), bytes.NewBuffer(jsonRecover))
c.Assert(err, qt.IsNil)
resp, err = http.DefaultClient.Do(req)
c.Assert(err, qt.IsNil)
c.Assert(resp.StatusCode, qt.Equals, http.StatusOK)
c.Assert(resp.Body.Close(), qt.IsNil)
// get the recovery code from the email
mailBody, err = testMailService.FindEmail(context.Background(), testEmail)
c.Assert(err, qt.IsNil)
passResetMailCode := strings.TrimPrefix(mailBody, VerificationCodeEmailBody)
// reset the password
newPassword := "password2"
resetPass := mustMarshal(&UserPasswordReset{
Email: testEmail,
Code: passResetMailCode,
NewPassword: newPassword,
})
req, err = http.NewRequest(http.MethodPost, testURL(usersResetPasswordEndpoint), bytes.NewBuffer(resetPass))
c.Assert(err, qt.IsNil)
resp, err = http.DefaultClient.Do(req)
c.Assert(err, qt.IsNil)
c.Assert(resp.StatusCode, qt.Equals, http.StatusOK)
c.Assert(resp.Body.Close(), qt.IsNil)
// try to login with the old password (should fail)
jsonLogin := mustMarshal(&UserInfo{
Email: testEmail,
Password: testPass,
})
req, err = http.NewRequest(http.MethodPost, testURL(authLoginEndpoint), bytes.NewBuffer(jsonLogin))
c.Assert(err, qt.IsNil)
resp, err = http.DefaultClient.Do(req)
c.Assert(err, qt.IsNil)
c.Assert(resp.StatusCode, qt.Equals, http.StatusUnauthorized)
c.Assert(resp.Body.Close(), qt.IsNil)
// try to login with the new password
jsonLogin = mustMarshal(&UserInfo{
Email: testEmail,
Password: newPassword,
})
req, err = http.NewRequest(http.MethodPost, testURL(authLoginEndpoint), bytes.NewBuffer(jsonLogin))
c.Assert(err, qt.IsNil)
resp, err = http.DefaultClient.Do(req)
c.Assert(err, qt.IsNil)
c.Assert(resp.StatusCode, qt.Equals, http.StatusOK)
c.Assert(resp.Body.Close(), qt.IsNil)
}
21 changes: 20 additions & 1 deletion notifications/testmail/mail.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,25 @@ func (tm *TestMail) SendNotification(_ context.Context, notification *notificati
return smtp.SendMail(smtpAddr, auth, tm.config.FromAddress, []string{notification.ToAddress}, msg)
}

func (tm *TestMail) clear() error {
clearEndpoint := fmt.Sprintf("http://%s:%d/api/v1/messages", tm.config.Host, tm.config.APIPort)
req, err := http.NewRequest("DELETE", clearEndpoint, nil)
if err != nil {
return fmt.Errorf("could not create request: %v", err)
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return fmt.Errorf("could not send request: %v", err)
}
defer func() {
_ = resp.Body.Close()
}()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("unexpected status code: %d", resp.StatusCode)
}
return nil
}

func (tm *TestMail) FindEmail(ctx context.Context, to string) (string, error) {
searchEndpoint := fmt.Sprintf("http://%s:%d/api/v2/search?kind=to&query=%s", tm.config.Host, tm.config.APIPort, to)
req, err := http.NewRequestWithContext(ctx, "GET", searchEndpoint, nil)
Expand Down Expand Up @@ -74,5 +93,5 @@ func (tm *TestMail) FindEmail(ctx context.Context, to string) (string, error) {
if len(mailResults.Items) == 0 {
return "", io.EOF
}
return mailResults.Items[0].Content.Body, nil
return mailResults.Items[0].Content.Body, tm.clear()
}

0 comments on commit 76846dc

Please sign in to comment.