Skip to content

Commit

Permalink
run added password reset and verification sent hooks tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ganigeorgiev committed Jul 19, 2022
1 parent 383b2a1 commit f295ce9
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 36 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ jobs:
# - name: Run linter
# uses: golangci/golangci-lint-action@v3

- name: Run tests
run: go test ./...

- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v3
with:
Expand Down
28 changes: 20 additions & 8 deletions apis/admin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ import (

"github.com/labstack/echo/v5"
"github.com/pocketbase/dbx"
"github.com/pocketbase/pocketbase/daos"
"github.com/pocketbase/pocketbase/models"
"github.com/pocketbase/pocketbase/tests"
"github.com/pocketbase/pocketbase/tools/types"
)

func TestAdminAuth(t *testing.T) {
Expand Down Expand Up @@ -100,21 +102,31 @@ func TestAdminRequestPasswordReset(t *testing.T) {
Url: "/api/admins/request-password-reset",
Body: strings.NewReader(`{"email":"[email protected]"}`),
ExpectedStatus: 204,
// usually this events are fired but since the submit is
// executed in a separate go routine they are fired async
// ExpectedEvents: map[string]int{
// "OnModelBeforeUpdate": 1,
// "OnModelAfterUpdate": 1,
// "OnMailerBeforeUserResetPasswordSend:1": 1,
// "OnMailerAfterUserResetPasswordSend:1": 1,
// },
ExpectedEvents: map[string]int{
"OnModelBeforeUpdate": 1,
"OnModelAfterUpdate": 1,
"OnMailerBeforeAdminResetPasswordSend": 1,
"OnMailerAfterAdminResetPasswordSend": 1,
},
},
{
Name: "existing admin (after already sent)",
Method: http.MethodPost,
Url: "/api/admins/request-password-reset",
Body: strings.NewReader(`{"email":"[email protected]"}`),
ExpectedStatus: 204,
BeforeFunc: func(t *testing.T, app *tests.TestApp, e *echo.Echo) {
// simulate recent password request
admin, err := app.Dao().FindAdminByEmail("[email protected]")
if err != nil {
t.Fatal(err)
}
admin.LastResetSentAt = types.NowDateTime()
dao := daos.New(app.Dao().DB()) // new dao to ignore hooks
if err := dao.Save(admin); err != nil {
t.Fatal(err)
}
},
},
}

Expand Down
71 changes: 50 additions & 21 deletions apis/user_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import (
"testing"

"github.com/labstack/echo/v5"
"github.com/pocketbase/pocketbase/daos"
"github.com/pocketbase/pocketbase/tests"
"github.com/pocketbase/pocketbase/tools/types"
)

func TestUsersAuthMethods(t *testing.T) {
Expand Down Expand Up @@ -140,21 +142,31 @@ func TestUserRequestPasswordReset(t *testing.T) {
Url: "/api/users/request-password-reset",
Body: strings.NewReader(`{"email":"[email protected]"}`),
ExpectedStatus: 204,
// usually this events are fired but since the submit is
// executed in a separate go routine they are fired async
// ExpectedEvents: map[string]int{
// "OnModelBeforeUpdate": 1,
// "OnModelAfterUpdate": 1,
// "OnMailerBeforeUserResetPasswordSend": 1,
// "OnMailerAfterUserResetPasswordSend": 1,
// },
ExpectedEvents: map[string]int{
"OnModelBeforeUpdate": 1,
"OnModelAfterUpdate": 1,
"OnMailerBeforeUserResetPasswordSend": 1,
"OnMailerAfterUserResetPasswordSend": 1,
},
},
{
Name: "existing user (after already sent)",
Method: http.MethodPost,
Url: "/api/users/request-password-reset",
Body: strings.NewReader(`{"email":"[email protected]"}`),
ExpectedStatus: 204,
BeforeFunc: func(t *testing.T, app *tests.TestApp, e *echo.Echo) {
// simulate recent password request
user, err := app.Dao().FindUserByEmail("[email protected]")
if err != nil {
t.Fatal(err)
}
user.LastResetSentAt = types.NowDateTime()
dao := daos.New(app.Dao().DB()) // new dao to ignore hooks
if err := dao.Save(user); err != nil {
t.Fatal(err)
}
},
},
}

Expand Down Expand Up @@ -216,50 +228,67 @@ func TestUserConfirmPasswordReset(t *testing.T) {

func TestUserRequestVerification(t *testing.T) {
scenarios := []tests.ApiScenario{
// empty data
{
Name: "empty data",
Method: http.MethodPost,
Url: "/api/users/request-verification",
Body: strings.NewReader(``),
ExpectedStatus: 400,
ExpectedContent: []string{`"data":{"email":{"code":"validation_required","message":"Cannot be blank."}}`},
},
// invalid data
{
Name: "invalid data",
Method: http.MethodPost,
Url: "/api/users/request-verification",
Body: strings.NewReader(`{"email`),
ExpectedStatus: 400,
ExpectedContent: []string{`"data":{}`},
},
// missing user
{
Name: "missing user",
Method: http.MethodPost,
Url: "/api/users/request-verification",
Body: strings.NewReader(`{"email":"[email protected]"}`),
ExpectedStatus: 204,
},
// existing already verified user
{
Name: "existing already verified user",
Method: http.MethodPost,
Url: "/api/users/request-verification",
Body: strings.NewReader(`{"email":"[email protected]"}`),
ExpectedStatus: 204,
},
// existing unverified user
{
Name: "existing unverified user",
Method: http.MethodPost,
Url: "/api/users/request-verification",
Body: strings.NewReader(`{"email":"[email protected]"}`),
ExpectedStatus: 204,
// usually this events are fired but since the submit is
// executed in a separate go routine they are fired async
// ExpectedEvents: map[string]int{
// "OnModelBeforeUpdate": 1,
// "OnModelAfterUpdate": 1,
// "OnMailerBeforeUserVerificationSend": 1,
// "OnMailerAfterUserVerificationSend": 1,
// },
ExpectedEvents: map[string]int{
"OnModelBeforeUpdate": 1,
"OnModelAfterUpdate": 1,
"OnMailerBeforeUserVerificationSend": 1,
"OnMailerAfterUserVerificationSend": 1,
},
},
{
Name: "existing unverified user (after already sent)",
Method: http.MethodPost,
Url: "/api/users/request-verification",
Body: strings.NewReader(`{"email":"[email protected]"}`),
ExpectedStatus: 204,
BeforeFunc: func(t *testing.T, app *tests.TestApp, e *echo.Echo) {
// simulate recent verification sent
user, err := app.Dao().FindUserByEmail("[email protected]")
if err != nil {
t.Fatal(err)
}
user.LastVerificationSentAt = types.NowDateTime()
dao := daos.New(app.Dao().DB()) // new dao to ignore hooks
if err := dao.Save(user); err != nil {
t.Fatal(err)
}
},
},
}

Expand Down
12 changes: 6 additions & 6 deletions daos/record_expand_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func TestExpandRecords(t *testing.T) {
expands []string
fetchFunc daos.ExpandFetchFunc
expectExpandProps int
expectExpandFailires int
expectExpandFailures int
}{
// empty records
{
Expand Down Expand Up @@ -130,8 +130,8 @@ func TestExpandRecords(t *testing.T) {
records, _ := app.Dao().FindRecordsByIds(col, ids, nil)
failed := app.Dao().ExpandRecords(records, s.expands, s.fetchFunc)

if len(failed) != s.expectExpandFailires {
t.Errorf("(%d) Expected %d failures, got %d: \n%v", i, s.expectExpandFailires, len(failed), failed)
if len(failed) != s.expectExpandFailures {
t.Errorf("(%d) Expected %d failures, got %d: \n%v", i, s.expectExpandFailures, len(failed), failed)
}

encoded, _ := json.Marshal(records)
Expand All @@ -155,7 +155,7 @@ func TestExpandRecord(t *testing.T) {
expands []string
fetchFunc daos.ExpandFetchFunc
expectExpandProps int
expectExpandFailires int
expectExpandFailures int
}{
// empty expand
{
Expand Down Expand Up @@ -241,8 +241,8 @@ func TestExpandRecord(t *testing.T) {
record, _ := app.Dao().FindFirstRecordByData(col, "id", s.recordId)
failed := app.Dao().ExpandRecord(record, s.expands, s.fetchFunc)

if len(failed) != s.expectExpandFailires {
t.Errorf("(%d) Expected %d failures, got %d: \n%v", i, s.expectExpandFailires, len(failed), failed)
if len(failed) != s.expectExpandFailures {
t.Errorf("(%d) Expected %d failures, got %d: \n%v", i, s.expectExpandFailures, len(failed), failed)
}

encoded, _ := json.Marshal(record)
Expand Down
8 changes: 7 additions & 1 deletion tests/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ type ApiScenario struct {
ExpectedContent []string
NotExpectedContent []string
ExpectedEvents map[string]int
// test events
// test hooks
BeforeFunc func(t *testing.T, app *TestApp, e *echo.Echo)
AfterFunc func(t *testing.T, app *TestApp, e *echo.Echo)
}
Expand Down Expand Up @@ -81,6 +81,12 @@ func (scenario *ApiScenario) Test(t *testing.T) {
t.Errorf("[%s] Expected status code %d, got %d", prefix, scenario.ExpectedStatus, res.StatusCode)
}

// @todo consider replacing with sync.WaitGroup
//
// apply a small delay before checking the expectations to ensure
// that all fired go routines have complicated before cleaning up the app instance
time.Sleep(5 * time.Millisecond)

if len(scenario.ExpectedContent) == 0 && len(scenario.NotExpectedContent) == 0 {
if len(recorder.Body.Bytes()) != 0 {
t.Errorf("[%s] Expected empty body, got \n%v", prefix, recorder.Body.String())
Expand Down

0 comments on commit f295ce9

Please sign in to comment.