1
0
mirror of https://github.com/pocketbase/pocketbase.git synced 2024-11-24 17:07:00 +02:00

run added password reset and verification sent hooks tests

This commit is contained in:
Gani Georgiev 2022-07-19 14:20:28 +03:00
parent 383b2a1279
commit f295ce9403
5 changed files with 86 additions and 36 deletions

View File

@ -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:

View File

@ -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) {
@ -100,14 +102,12 @@ func TestAdminRequestPasswordReset(t *testing.T) {
Url: "/api/admins/request-password-reset",
Body: strings.NewReader(`{"email":"test@example.com"}`),
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)",
@ -115,6 +115,18 @@ func TestAdminRequestPasswordReset(t *testing.T) {
Url: "/api/admins/request-password-reset",
Body: strings.NewReader(`{"email":"test@example.com"}`),
ExpectedStatus: 204,
BeforeFunc: func(t *testing.T, app *tests.TestApp, e *echo.Echo) {
// simulate recent password request
admin, err := app.Dao().FindAdminByEmail("test@example.com")
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)
}
},
},
}

View File

@ -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) {
@ -140,14 +142,12 @@ func TestUserRequestPasswordReset(t *testing.T) {
Url: "/api/users/request-password-reset",
Body: strings.NewReader(`{"email":"test@example.com"}`),
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)",
@ -155,6 +155,18 @@ func TestUserRequestPasswordReset(t *testing.T) {
Url: "/api/users/request-password-reset",
Body: strings.NewReader(`{"email":"test@example.com"}`),
ExpectedStatus: 204,
BeforeFunc: func(t *testing.T, app *tests.TestApp, e *echo.Echo) {
// simulate recent password request
user, err := app.Dao().FindUserByEmail("test@example.com")
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)
}
},
},
}
@ -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":"missing@example.com"}`),
ExpectedStatus: 204,
},
// existing already verified user
{
Name: "existing already verified user",
Method: http.MethodPost,
Url: "/api/users/request-verification",
Body: strings.NewReader(`{"email":"test@example.com"}`),
ExpectedStatus: 204,
},
// existing unverified user
{
Name: "existing unverified user",
Method: http.MethodPost,
Url: "/api/users/request-verification",
Body: strings.NewReader(`{"email":"test2@example.com"}`),
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":"test2@example.com"}`),
ExpectedStatus: 204,
BeforeFunc: func(t *testing.T, app *tests.TestApp, e *echo.Echo) {
// simulate recent verification sent
user, err := app.Dao().FindUserByEmail("test2@example.com")
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)
}
},
},
}

View File

@ -23,7 +23,7 @@ func TestExpandRecords(t *testing.T) {
expands []string
fetchFunc daos.ExpandFetchFunc
expectExpandProps int
expectExpandFailires int
expectExpandFailures int
}{
// empty records
{
@ -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)
@ -155,7 +155,7 @@ func TestExpandRecord(t *testing.T) {
expands []string
fetchFunc daos.ExpandFetchFunc
expectExpandProps int
expectExpandFailires int
expectExpandFailures int
}{
// empty expand
{
@ -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)

View File

@ -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)
}
@ -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())