1
0
mirror of https://github.com/raseels-repos/golang-saas-starter-kit.git synced 2025-06-06 23:46:29 +02:00

1511 lines
42 KiB
Go
Raw Normal View History

package tests
import (
2019-06-26 20:21:00 -08:00
"context"
"encoding/json"
2019-06-26 20:21:00 -08:00
"fmt"
"net/http"
"net/http/httptest"
"testing"
2019-06-26 20:21:00 -08:00
"time"
"geeks-accelerator/oss/saas-starter-kit/internal/mid"
"geeks-accelerator/oss/saas-starter-kit/internal/platform/auth"
"geeks-accelerator/oss/saas-starter-kit/internal/platform/tests"
"geeks-accelerator/oss/saas-starter-kit/internal/platform/web"
2019-08-01 16:17:47 -08:00
"geeks-accelerator/oss/saas-starter-kit/internal/platform/web/weberror"
"geeks-accelerator/oss/saas-starter-kit/internal/user"
"geeks-accelerator/oss/saas-starter-kit/internal/user_account"
2019-06-26 20:21:00 -08:00
"github.com/pborman/uuid"
)
type mockUser struct {
*user.User
password string
}
func mockUserCreateRequest() user.UserCreateRequest {
return user.UserCreateRequest{
2019-08-01 16:17:47 -08:00
FirstName: "Lee",
LastName: "Brown",
2019-06-26 20:21:00 -08:00
Email: uuid.NewRandom().String() + "@geeksinthewoods.com",
Password: "akTechFr0n!ier",
PasswordConfirm: "akTechFr0n!ier",
}
}
// mockUser creates a new user for testing and associates it with the supplied account ID.
func newMockUser(accountID string, role user_account.UserAccountRole) mockUser {
req := mockUserCreateRequest()
u, err := user.Create(tests.Context(), auth.Claims{}, test.MasterDB, req, time.Now().UTC().AddDate(-1, -1, -1))
if err != nil {
panic(err)
}
_, err = user_account.Create(tests.Context(), auth.Claims{}, test.MasterDB, user_account.UserAccountCreateRequest{
UserID: u.ID,
AccountID: accountID,
Roles: []user_account.UserAccountRole{role},
}, time.Now().UTC().AddDate(-1, -1, -1))
2019-06-26 20:21:00 -08:00
if err != nil {
panic(err)
}
return mockUser{
User: u,
password: req.Password,
}
}
// TestUserCRUDAdmin tests all the user CRUD endpoints using an user with role admin.
func TestUserCRUDAdmin(t *testing.T) {
2019-06-26 20:21:00 -08:00
defer tests.Recover(t)
tr := roleTests[auth.RoleAdmin]
// Add claims to the context for the user.
ctx := context.WithValue(tests.Context(), auth.Key, tr.Claims)
// Test create.
var created user.UserResponse
{
expectedStatus := http.StatusCreated
req := mockUserCreateRequest()
rt := requestTest{
fmt.Sprintf("Create %d w/role %s", expectedStatus, tr.Role),
http.MethodPost,
"/v1/users",
req,
tr.Token,
tr.Claims,
expectedStatus,
nil,
}
t.Logf("\tTest: %s - %s %s", rt.name, rt.method, rt.url)
w, ok := executeRequestTest(t, rt, ctx)
if !ok {
t.Fatalf("\t%s\tExecute request failed.", tests.Failed)
}
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
var actual user.UserResponse
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
t.Logf("\t\tGot error : %+v", err)
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
}
created = actual
expectedMap := map[string]interface{}{
"updated_at": web.NewTimeResponse(ctx, actual.UpdatedAt.Value),
"id": actual.ID,
"email": req.Email,
"timezone": actual.Timezone,
"created_at": web.NewTimeResponse(ctx, actual.CreatedAt.Value),
2019-08-01 16:17:47 -08:00
"first_name": req.FirstName,
"last_name": req.LastName,
}
2019-06-26 20:21:00 -08:00
var expected user.UserResponse
if err := decodeMapToStruct(expectedMap, &expected); err != nil {
t.Logf("\t\tGot error : %+v\nActual results to format expected : \n", err)
printResultMap(ctx, w.Body.Bytes()) // used to help format expectedMap
t.Fatalf("\t%s\tDecode expected failed.", tests.Failed)
}
2019-06-26 20:21:00 -08:00
if diff := cmpDiff(t, actual, expected); diff {
if len(expectedMap) == 0 {
printResultMap(ctx, w.Body.Bytes()) // used to help format expectedMap
}
t.Fatalf("\t%s\tReceived expected result.", tests.Failed)
}
t.Logf("\t%s\tReceived expected result.", tests.Success)
// Only for user creation do we need to do this.
_, err := user_account.Create(tests.Context(), auth.Claims{}, test.MasterDB, user_account.UserAccountCreateRequest{
UserID: actual.ID,
AccountID: tr.Account.ID,
Roles: []user_account.UserAccountRole{user_account.UserAccountRole_User},
}, time.Now().UTC().AddDate(-1, -1, -1))
if err != nil {
t.Fatalf("\t%s\tLink user to account.", tests.Failed)
}
}
2019-06-26 20:21:00 -08:00
// Test read.
{
expectedStatus := http.StatusOK
2019-06-26 20:21:00 -08:00
rt := requestTest{
fmt.Sprintf("Read %d w/role %s", expectedStatus, tr.Role),
2019-06-26 20:21:00 -08:00
http.MethodGet,
fmt.Sprintf("/v1/users/%s", created.ID),
2019-06-26 20:21:00 -08:00
nil,
tr.Token,
tr.Claims,
expectedStatus,
nil,
}
t.Logf("\tTest: %s - %s %s", rt.name, rt.method, rt.url)
w, ok := executeRequestTest(t, rt, ctx)
if !ok {
t.Fatalf("\t%s\tExecute request failed.", tests.Failed)
}
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
var actual user.UserResponse
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
t.Logf("\t\tGot error : %+v", err)
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
}
if diff := cmpDiff(t, actual, created); diff {
t.Fatalf("\t%s\tReceived expected result.", tests.Failed)
}
t.Logf("\t%s\tReceived expected result.", tests.Success)
}
2019-06-26 20:21:00 -08:00
// Test Read with random ID.
{
expectedStatus := http.StatusNotFound
randID := uuid.NewRandom().String()
rt := requestTest{
fmt.Sprintf("Read %d w/role %s using random ID", expectedStatus, tr.Role),
2019-06-26 20:21:00 -08:00
http.MethodGet,
fmt.Sprintf("/v1/users/%s", randID),
2019-06-26 20:21:00 -08:00
nil,
tr.Token,
tr.Claims,
expectedStatus,
nil,
}
t.Logf("\tTest: %s - %s %s", rt.name, rt.method, rt.url)
w, ok := executeRequestTest(t, rt, ctx)
if !ok {
t.Fatalf("\t%s\tExecute request failed.", tests.Failed)
}
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
2019-08-01 16:17:47 -08:00
var actual weberror.ErrorResponse
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
t.Logf("\t\tGot error : %+v", err)
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
}
2019-08-01 16:17:47 -08:00
expected := weberror.ErrorResponse{
Error: fmt.Sprintf("user %s not found: Entity not found", randID),
}
2019-06-26 20:21:00 -08:00
if diff := cmpDiff(t, actual, expected); diff {
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
}
t.Logf("\t%s\tReceived expected error.", tests.Success)
}
// Test Read with forbidden ID.
{
expectedStatus := http.StatusNotFound
rt := requestTest{
fmt.Sprintf("Read %d w/role %s using forbidden ID", expectedStatus, tr.Role),
2019-06-26 20:21:00 -08:00
http.MethodGet,
fmt.Sprintf("/v1/users/%s", tr.ForbiddenUser.ID),
2019-06-26 20:21:00 -08:00
nil,
tr.Token,
tr.Claims,
expectedStatus,
nil,
}
t.Logf("\tTest: %s - %s %s", rt.name, rt.method, rt.url)
w, ok := executeRequestTest(t, rt, ctx)
if !ok {
t.Fatalf("\t%s\tExecute request failed.", tests.Failed)
}
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
2019-08-01 16:17:47 -08:00
var actual weberror.ErrorResponse
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
t.Logf("\t\tGot error : %+v", err)
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
}
2019-08-01 16:17:47 -08:00
expected := weberror.ErrorResponse{
Error: fmt.Sprintf("user %s not found: Entity not found", tr.ForbiddenUser.ID),
}
if diff := cmpDiff(t, actual, expected); diff {
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
}
t.Logf("\t%s\tReceived expected error.", tests.Success)
}
// Test update.
{
expectedStatus := http.StatusNoContent
newName := uuid.NewRandom().String()
rt := requestTest{
fmt.Sprintf("Update %d w/role %s", expectedStatus, tr.Role),
http.MethodPatch,
2019-06-26 20:21:00 -08:00
"/v1/users",
user.UserUpdateRequest{
2019-08-01 16:17:47 -08:00
ID: created.ID,
FirstName: &newName,
2019-06-26 20:21:00 -08:00
},
tr.Token,
tr.Claims,
expectedStatus,
nil,
}
t.Logf("\tTest: %s - %s %s", rt.name, rt.method, rt.url)
w, ok := executeRequestTest(t, rt, ctx)
if !ok {
t.Fatalf("\t%s\tExecute request failed.", tests.Failed)
}
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
if len(w.Body.String()) != 0 {
if diff := cmpDiff(t, w.Body.Bytes(), nil); diff {
t.Fatalf("\t%s\tReceived expected empty.", tests.Failed)
}
}
t.Logf("\t%s\tReceived expected empty.", tests.Success)
}
// Test update password.
{
expectedStatus := http.StatusNoContent
newPass := uuid.NewRandom().String()
rt := requestTest{
fmt.Sprintf("Update password %d w/role %s", expectedStatus, tr.Role),
http.MethodPatch,
"/v1/users/password",
user.UserUpdatePasswordRequest{
ID: created.ID,
Password: newPass,
PasswordConfirm: newPass,
2019-06-26 20:21:00 -08:00
},
tr.Token,
tr.Claims,
expectedStatus,
nil,
}
t.Logf("\tTest: %s - %s %s", rt.name, rt.method, rt.url)
w, ok := executeRequestTest(t, rt, ctx)
if !ok {
t.Fatalf("\t%s\tExecute request failed.", tests.Failed)
}
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
2019-06-26 20:21:00 -08:00
if len(w.Body.String()) != 0 {
if diff := cmpDiff(t, w.Body.Bytes(), nil); diff {
t.Fatalf("\t%s\tReceived expected empty.", tests.Failed)
}
}
t.Logf("\t%s\tReceived expected empty.", tests.Success)
}
2019-06-26 20:21:00 -08:00
// Test archive.
{
2019-06-26 20:21:00 -08:00
expectedStatus := http.StatusNoContent
rt := requestTest{
fmt.Sprintf("Archive %d w/role %s", expectedStatus, tr.Role),
2019-06-26 20:21:00 -08:00
http.MethodPatch,
"/v1/users/archive",
user.UserArchiveRequest{
ID: created.ID,
2019-06-26 20:21:00 -08:00
},
tr.Token,
tr.Claims,
expectedStatus,
nil,
}
t.Logf("\tTest: %s - %s %s", rt.name, rt.method, rt.url)
w, ok := executeRequestTest(t, rt, ctx)
if !ok {
t.Fatalf("\t%s\tExecute request failed.", tests.Failed)
}
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
if len(w.Body.String()) != 0 {
if diff := cmpDiff(t, w.Body.Bytes(), nil); diff {
t.Fatalf("\t%s\tReceived expected empty.", tests.Failed)
}
}
t.Logf("\t%s\tReceived expected empty.", tests.Success)
}
// Test delete.
{
expectedStatus := http.StatusNoContent
rt := requestTest{
fmt.Sprintf("Delete %d w/role %s", expectedStatus, tr.Role),
http.MethodDelete,
fmt.Sprintf("/v1/users/%s", created.ID),
nil,
2019-06-26 20:21:00 -08:00
tr.Token,
tr.Claims,
expectedStatus,
nil,
}
t.Logf("\tTest: %s - %s %s", rt.name, rt.method, rt.url)
w, ok := executeRequestTest(t, rt, ctx)
if !ok {
t.Fatalf("\t%s\tExecute request failed.", tests.Failed)
}
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
if len(w.Body.String()) != 0 {
if diff := cmpDiff(t, w.Body.Bytes(), nil); diff {
t.Fatalf("\t%s\tReceived expected empty.", tests.Failed)
}
}
t.Logf("\t%s\tReceived expected empty.", tests.Success)
}
// Test switch account.
{
expectedStatus := http.StatusOK
newAccount := newMockSignup().account
rt := requestTest{
fmt.Sprintf("Switch account %d w/role %s", expectedStatus, tr.Role),
2019-06-26 20:21:00 -08:00
http.MethodPatch,
fmt.Sprintf("/v1/users/switch-account/%s", newAccount.ID),
nil,
2019-06-26 20:21:00 -08:00
tr.Token,
tr.Claims,
expectedStatus,
nil,
}
t.Logf("\tTest: %s - %s %s", rt.name, rt.method, rt.url)
_, err := user_account.Create(tests.Context(), auth.Claims{}, test.MasterDB, user_account.UserAccountCreateRequest{
UserID: tr.User.ID,
AccountID: newAccount.ID,
Roles: []user_account.UserAccountRole{user_account.UserAccountRole_User},
}, time.Now().UTC().AddDate(-1, -1, -1))
if err != nil {
t.Fatalf("\t%s\tAdd user to account failed.", tests.Failed)
}
w, ok := executeRequestTest(t, rt, ctx)
if !ok {
t.Fatalf("\t%s\tExecute request failed.", tests.Failed)
}
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
var actual map[string]interface{}
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
t.Logf("\t\tGot error : %+v", err)
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
}
// This is just for response format validation, will verify account from claims.
expected := map[string]interface{}{
"access_token": actual["access_token"],
"token_type": actual["token_type"],
"expiry": actual["expiry"],
2019-08-01 16:17:47 -08:00
"ttl": actual["ttl"],
}
if diff := cmpDiff(t, actual, expected); diff {
t.Fatalf("\t%s\tReceived expected result.", tests.Failed)
}
t.Logf("\t%s\tReceived expected result.", tests.Success)
newClaims, err := authenticator.ParseClaims(actual["access_token"].(string))
if err != nil {
t.Logf("\t\tGot error : %+v", err)
t.Fatalf("\t%s\tParse claims failed.", tests.Failed)
} else if newClaims.Audience != newAccount.ID {
t.Logf("\t\tGot : %+v", newClaims.Audience)
t.Logf("\t\tExpected : %+v", newAccount.ID)
t.Fatalf("\t%s\tParse claims expected audience to match new account.", tests.Failed)
} else if newClaims.Subject != tr.User.ID {
t.Logf("\t\tGot : %+v", newClaims.Subject)
t.Logf("\t\tExpected : %+v", tr.User.ID)
t.Fatalf("\t%s\tParse claims expected Subject to match user.", tests.Failed)
}
t.Logf("\t%s\tParse claims valid.", tests.Success)
}
}
// TestUserCRUDUser tests all the user CRUD endpoints using an user with role user.
func TestUserCRUDUser(t *testing.T) {
defer tests.Recover(t)
tr := roleTests[auth.RoleUser]
// Add claims to the context for the user.
ctx := context.WithValue(tests.Context(), auth.Key, tr.Claims)
// Test create.
{
2019-06-26 20:21:00 -08:00
expectedStatus := http.StatusForbidden
req := mockUserCreateRequest()
rt := requestTest{
fmt.Sprintf("Create %d w/role %s", expectedStatus, tr.Role),
http.MethodPost,
2019-06-26 20:21:00 -08:00
"/v1/users",
req,
2019-06-26 20:21:00 -08:00
tr.Token,
tr.Claims,
expectedStatus,
nil,
}
t.Logf("\tTest: %s - %s %s", rt.name, rt.method, rt.url)
w, ok := executeRequestTest(t, rt, ctx)
if !ok {
t.Fatalf("\t%s\tExecute request failed.", tests.Failed)
}
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
2019-08-01 16:17:47 -08:00
var actual weberror.ErrorResponse
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
t.Logf("\t\tGot error : %+v", err)
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
}
2019-08-01 16:17:47 -08:00
expected := mid.ErrorForbidden(ctx).(*weberror.Error).Display(ctx)
2019-06-26 20:21:00 -08:00
if diff := cmpDiff(t, actual, expected); diff {
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
}
t.Logf("\t%s\tReceived expected error.", tests.Success)
}
2019-06-26 20:21:00 -08:00
// Since role doesn't support create, bypass auth to test other endpoints.
created := newMockUser(tr.Account.ID, user_account.UserAccountRole_User).Response(ctx)
// Test read.
{
expectedStatus := http.StatusOK
rt := requestTest{
fmt.Sprintf("Read %d w/role %s", expectedStatus, tr.Role),
http.MethodGet,
fmt.Sprintf("/v1/users/%s", created.ID),
nil,
2019-06-26 20:21:00 -08:00
tr.Token,
tr.Claims,
expectedStatus,
nil,
}
t.Logf("\tTest: %s - %s %s", rt.name, rt.method, rt.url)
w, ok := executeRequestTest(t, rt, ctx)
if !ok {
t.Fatalf("\t%s\tExecute request failed.", tests.Failed)
}
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
var actual *user.UserResponse
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
t.Logf("\t\tGot error : %+v", err)
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
}
if diff := cmpDiff(t, actual, created); diff {
t.Fatalf("\t%s\tReceived expected result.", tests.Failed)
}
t.Logf("\t%s\tReceived expected result.", tests.Success)
}
// Test Read with random ID.
{
expectedStatus := http.StatusNotFound
randID := uuid.NewRandom().String()
rt := requestTest{
fmt.Sprintf("Read %d w/role %s using random ID", expectedStatus, tr.Role),
http.MethodGet,
fmt.Sprintf("/v1/users/%s", randID),
nil,
2019-06-26 20:21:00 -08:00
tr.Token,
tr.Claims,
expectedStatus,
nil,
}
t.Logf("\tTest: %s - %s %s", rt.name, rt.method, rt.url)
w, ok := executeRequestTest(t, rt, ctx)
if !ok {
t.Fatalf("\t%s\tExecute request failed.", tests.Failed)
}
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
2019-08-01 16:17:47 -08:00
var actual weberror.ErrorResponse
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
t.Logf("\t\tGot error : %+v", err)
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
}
2019-08-01 16:17:47 -08:00
expected := weberror.ErrorResponse{
Error: fmt.Sprintf("user %s not found: Entity not found", randID),
}
if diff := cmpDiff(t, actual, expected); diff {
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
}
t.Logf("\t%s\tReceived expected error.", tests.Success)
}
// Test Read with forbidden ID.
{
expectedStatus := http.StatusNotFound
rt := requestTest{
fmt.Sprintf("Read %d w/role %s using forbidden ID", expectedStatus, tr.Role),
http.MethodGet,
fmt.Sprintf("/v1/users/%s", tr.ForbiddenUser.ID),
nil,
2019-06-26 20:21:00 -08:00
tr.Token,
tr.Claims,
expectedStatus,
nil,
}
t.Logf("\tTest: %s - %s %s", rt.name, rt.method, rt.url)
w, ok := executeRequestTest(t, rt, ctx)
if !ok {
t.Fatalf("\t%s\tExecute request failed.", tests.Failed)
}
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
2019-08-01 16:17:47 -08:00
var actual weberror.ErrorResponse
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
t.Logf("\t\tGot error : %+v", err)
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
}
2019-08-01 16:17:47 -08:00
expected := weberror.ErrorResponse{
Error: fmt.Sprintf("user %s not found: Entity not found", tr.ForbiddenUser.ID),
}
if diff := cmpDiff(t, actual, expected); diff {
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
}
t.Logf("\t%s\tReceived expected error.", tests.Success)
}
// Test update.
{
expectedStatus := http.StatusForbidden
newName := uuid.NewRandom().String()
rt := requestTest{
fmt.Sprintf("Update %d w/role %s", expectedStatus, tr.Role),
2019-06-26 20:21:00 -08:00
http.MethodPatch,
"/v1/users",
user.UserUpdateRequest{
2019-08-01 16:17:47 -08:00
ID: created.ID,
FirstName: &newName,
2019-06-26 20:21:00 -08:00
},
tr.Token,
tr.Claims,
expectedStatus,
nil,
}
t.Logf("\tTest: %s - %s %s", rt.name, rt.method, rt.url)
w, ok := executeRequestTest(t, rt, ctx)
if !ok {
t.Fatalf("\t%s\tExecute request failed.", tests.Failed)
}
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
2019-08-01 16:17:47 -08:00
var actual weberror.ErrorResponse
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
t.Logf("\t\tGot error : %+v", err)
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
}
2019-08-01 16:17:47 -08:00
expected := weberror.ErrorResponse{
Error: user.ErrForbidden.Error(),
}
if diff := cmpDiff(t, actual, expected); diff {
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
}
t.Logf("\t%s\tReceived expected error.", tests.Success)
}
// Test update password.
{
expectedStatus := http.StatusForbidden
newPass := uuid.NewRandom().String()
rt := requestTest{
fmt.Sprintf("Update password %d w/role %s", expectedStatus, tr.Role),
http.MethodPatch,
"/v1/users/password",
user.UserUpdatePasswordRequest{
ID: created.ID,
Password: newPass,
PasswordConfirm: newPass,
},
tr.Token,
tr.Claims,
expectedStatus,
nil,
}
t.Logf("\tTest: %s - %s %s", rt.name, rt.method, rt.url)
w, ok := executeRequestTest(t, rt, ctx)
if !ok {
t.Fatalf("\t%s\tExecute request failed.", tests.Failed)
}
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
2019-08-01 16:17:47 -08:00
var actual weberror.ErrorResponse
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
t.Logf("\t\tGot error : %+v", err)
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
}
2019-08-01 16:17:47 -08:00
expected := weberror.ErrorResponse{
Error: user.ErrForbidden.Error(),
}
if diff := cmpDiff(t, actual, expected); diff {
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
}
t.Logf("\t%s\tReceived expected error.", tests.Success)
}
// Test archive.
{
expectedStatus := http.StatusForbidden
rt := requestTest{
fmt.Sprintf("Archive %d w/role %s", expectedStatus, tr.Role),
http.MethodPatch,
"/v1/users/archive",
user.UserArchiveRequest{
ID: created.ID,
},
tr.Token,
tr.Claims,
expectedStatus,
nil,
}
t.Logf("\tTest: %s - %s %s", rt.name, rt.method, rt.url)
w, ok := executeRequestTest(t, rt, ctx)
if !ok {
t.Fatalf("\t%s\tExecute request failed.", tests.Failed)
}
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
2019-08-01 16:17:47 -08:00
var actual weberror.ErrorResponse
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
t.Logf("\t\tGot error : %+v", err)
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
}
2019-08-01 16:17:47 -08:00
expected := mid.ErrorForbidden(ctx).(*weberror.Error).Display(ctx)
if diff := cmpDiff(t, actual, expected); diff {
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
}
t.Logf("\t%s\tReceived expected error.", tests.Success)
}
// Test delete.
{
expectedStatus := http.StatusForbidden
rt := requestTest{
fmt.Sprintf("Delete %d w/role %s", expectedStatus, tr.Role),
http.MethodDelete,
fmt.Sprintf("/v1/users/%s", created.ID),
nil,
tr.Token,
tr.Claims,
expectedStatus,
nil,
}
t.Logf("\tTest: %s - %s %s", rt.name, rt.method, rt.url)
w, ok := executeRequestTest(t, rt, ctx)
if !ok {
t.Fatalf("\t%s\tExecute request failed.", tests.Failed)
}
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
2019-08-01 16:17:47 -08:00
var actual weberror.ErrorResponse
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
t.Logf("\t\tGot error : %+v", err)
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
}
2019-08-01 16:17:47 -08:00
expected := mid.ErrorForbidden(ctx).(*weberror.Error).Display(ctx)
if diff := cmpDiff(t, actual, expected); diff {
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
}
t.Logf("\t%s\tReceived expected error.", tests.Success)
}
// Test switch account.
{
expectedStatus := http.StatusOK
newAccount := newMockSignup().account
rt := requestTest{
fmt.Sprintf("Switch account %d w/role %s", expectedStatus, tr.Role),
http.MethodPatch,
fmt.Sprintf("/v1/users/switch-account/%s", newAccount.ID),
nil,
tr.Token,
tr.Claims,
expectedStatus,
nil,
}
t.Logf("\tTest: %s - %s %s", rt.name, rt.method, rt.url)
_, err := user_account.Create(tests.Context(), auth.Claims{}, test.MasterDB, user_account.UserAccountCreateRequest{
UserID: tr.User.ID,
AccountID: newAccount.ID,
Roles: []user_account.UserAccountRole{user_account.UserAccountRole_User},
}, time.Now().UTC().AddDate(-1, -1, -1))
if err != nil {
t.Fatalf("\t%s\tAdd user to account failed.", tests.Failed)
}
w, ok := executeRequestTest(t, rt, ctx)
if !ok {
t.Fatalf("\t%s\tExecute request failed.", tests.Failed)
}
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
var actual map[string]interface{}
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
t.Logf("\t\tGot error : %+v", err)
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
}
// This is just for response format validation, will verify account from claims.
expected := map[string]interface{}{
"access_token": actual["access_token"],
"token_type": actual["token_type"],
"expiry": actual["expiry"],
2019-08-01 16:17:47 -08:00
"ttl": actual["ttl"],
}
if diff := cmpDiff(t, actual, expected); diff {
t.Fatalf("\t%s\tReceived expected result.", tests.Failed)
}
t.Logf("\t%s\tReceived expected result.", tests.Success)
newClaims, err := authenticator.ParseClaims(actual["access_token"].(string))
if err != nil {
t.Logf("\t\tGot error : %+v", err)
t.Fatalf("\t%s\tParse claims failed.", tests.Failed)
} else if newClaims.Audience != newAccount.ID {
t.Logf("\t\tGot : %+v", newClaims.Audience)
t.Logf("\t\tExpected : %+v", newAccount.ID)
t.Fatalf("\t%s\tParse claims expected audience to match new account.", tests.Failed)
} else if newClaims.Subject != tr.User.ID {
t.Logf("\t\tGot : %+v", newClaims.Subject)
t.Logf("\t\tExpected : %+v", tr.User.ID)
t.Fatalf("\t%s\tParse claims expected Subject to match user.", tests.Failed)
}
t.Logf("\t%s\tParse claims valid.", tests.Success)
}
}
2019-06-26 20:21:00 -08:00
// TestUserCreate validates create user endpoint.
func TestUserCreate(t *testing.T) {
defer tests.Recover(t)
tr := roleTests[auth.RoleAdmin]
// Add claims to the context for the user.
ctx := context.WithValue(tests.Context(), auth.Key, tr.Claims)
// Test create with invalid data.
{
expectedStatus := http.StatusBadRequest
req := mockUserCreateRequest()
req.Email = "invalid email address.com"
rt := requestTest{
fmt.Sprintf("Create %d w/role %s using invalid data", expectedStatus, tr.Role),
http.MethodPost,
"/v1/users",
req,
tr.Token,
tr.Claims,
expectedStatus,
nil,
}
t.Logf("\tTest: %s - %s %s", rt.name, rt.method, rt.url)
w, ok := executeRequestTest(t, rt, ctx)
if !ok {
t.Fatalf("\t%s\tExecute request failed.", tests.Failed)
}
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
2019-08-01 16:17:47 -08:00
var actual weberror.ErrorResponse
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
t.Logf("\t\tGot error : %+v", err)
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
}
2019-08-01 16:17:47 -08:00
expected := weberror.ErrorResponse{
Error: "Field validation error",
Fields: []weberror.FieldError{
//{Field: "email", Error: "Key: 'UserCreateRequest.email' Error:Field validation for 'email' failed on the 'email' tag"},
{
Field: "email",
Value: req.Email,
Tag: "email",
Error: "email must be a valid email address",
Display: "email must be a valid email address",
},
},
}
if diff := cmpDiff(t, actual, expected); diff {
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
}
t.Logf("\t%s\tReceived expected error.", tests.Success)
}
}
// TestUserUpdate validates update user endpoint.
func TestUserUpdate(t *testing.T) {
defer tests.Recover(t)
tr := roleTests[auth.RoleAdmin]
// Add claims to the context for the user.
ctx := context.WithValue(tests.Context(), auth.Key, tr.Claims)
// Test update with invalid data.
{
expectedStatus := http.StatusBadRequest
invalidEmail := "invalid email address"
rt := requestTest{
fmt.Sprintf("Update %d w/role %s using invalid data", expectedStatus, tr.Role),
http.MethodPatch,
"/v1/users",
user.UserUpdateRequest{
ID: tr.User.ID,
Email: &invalidEmail,
},
tr.Token,
tr.Claims,
expectedStatus,
nil,
}
t.Logf("\tTest: %s - %s %s", rt.name, rt.method, rt.url)
w, ok := executeRequestTest(t, rt, ctx)
if !ok {
t.Fatalf("\t%s\tExecute request failed.", tests.Failed)
}
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
2019-08-01 16:17:47 -08:00
var actual weberror.ErrorResponse
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
t.Logf("\t\tGot error : %+v", err)
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
}
2019-08-01 16:17:47 -08:00
expected := weberror.ErrorResponse{
Error: "Field validation error",
Fields: []weberror.FieldError{
//{Field: "email", Error: "Key: 'UserUpdateRequest.email' Error:Field validation for 'email' failed on the 'email' tag"},
{
Field: "email",
Value: invalidEmail,
Tag: "email",
Error: "email must be a valid email address",
Display: "email must be a valid email address",
},
},
}
if diff := cmpDiff(t, actual, expected); diff {
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
}
t.Logf("\t%s\tReceived expected error.", tests.Success)
}
}
// TestUserUpdatePassword validates update user password endpoint.
func TestUserUpdatePassword(t *testing.T) {
defer tests.Recover(t)
tr := roleTests[auth.RoleAdmin]
// Add claims to the context for the user.
ctx := context.WithValue(tests.Context(), auth.Key, tr.Claims)
// Since role doesn't support create, bypass auth to test other endpoints.
created := newMockUser(tr.Account.ID, user_account.UserAccountRole_User).Response(ctx)
// Test update user password with invalid data.
{
expectedStatus := http.StatusBadRequest
newPass := uuid.NewRandom().String()
2019-08-01 16:17:47 -08:00
diffPass := "different"
rt := requestTest{
fmt.Sprintf("Update password %d w/role %s using invalid data", expectedStatus, tr.Role),
http.MethodPatch,
"/v1/users/password",
user.UserUpdatePasswordRequest{
ID: created.ID,
Password: newPass,
2019-08-01 16:17:47 -08:00
PasswordConfirm: diffPass,
},
tr.Token,
tr.Claims,
expectedStatus,
nil,
}
t.Logf("\tTest: %s - %s %s", rt.name, rt.method, rt.url)
w, ok := executeRequestTest(t, rt, ctx)
if !ok {
t.Fatalf("\t%s\tExecute request failed.", tests.Failed)
}
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
2019-08-01 16:17:47 -08:00
var actual weberror.ErrorResponse
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
t.Logf("\t\tGot error : %+v", err)
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
}
2019-08-01 16:17:47 -08:00
expected := weberror.ErrorResponse{
Error: "Field validation error",
Fields: []weberror.FieldError{
//{Field: "password_confirm", Error: "Key: 'UserUpdatePasswordRequest.password_confirm' Error:Field validation for 'password_confirm' failed on the 'eqfield' tag"},
{
Field: "password_confirm",
Value: diffPass,
Tag: "eqfield",
Error: "password_confirm must be equal to Password",
Display: "password_confirm must be equal to Password",
},
},
}
if diff := cmpDiff(t, actual, expected); diff {
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
}
t.Logf("\t%s\tReceived expected error.", tests.Success)
}
}
// TestUserArchive validates archive user endpoint.
func TestUserArchive(t *testing.T) {
defer tests.Recover(t)
tr := roleTests[auth.RoleAdmin]
// Add claims to the context for the user.
ctx := context.WithValue(tests.Context(), auth.Key, tr.Claims)
// Test archive user with invalid data.
{
expectedStatus := http.StatusBadRequest
2019-08-01 16:17:47 -08:00
invalidId := "a"
rt := requestTest{
fmt.Sprintf("Archive %d w/role %s using invalid data", expectedStatus, tr.Role),
http.MethodPatch,
"/v1/users/archive",
user.UserArchiveRequest{
2019-08-01 16:17:47 -08:00
ID: invalidId,
},
tr.Token,
tr.Claims,
expectedStatus,
nil,
}
t.Logf("\tTest: %s - %s %s", rt.name, rt.method, rt.url)
w, ok := executeRequestTest(t, rt, ctx)
if !ok {
t.Fatalf("\t%s\tExecute request failed.", tests.Failed)
}
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
2019-08-01 16:17:47 -08:00
var actual weberror.ErrorResponse
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
t.Logf("\t\tGot error : %+v", err)
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
}
2019-08-01 16:17:47 -08:00
expected := weberror.ErrorResponse{
Error: "Field validation error",
Fields: []weberror.FieldError{
//{Field: "id", Error: "Key: 'UserArchiveRequest.id' Error:Field validation for 'id' failed on the 'uuid' tag"},
{
Field: "id",
Value: invalidId,
Tag: "uuid",
Error: "id must be a valid UUID",
Display: "id must be a valid UUID",
},
},
}
if diff := cmpDiff(t, actual, expected); diff {
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
}
t.Logf("\t%s\tReceived expected error.", tests.Success)
}
// Test archive user with forbidden ID.
{
expectedStatus := http.StatusForbidden
rt := requestTest{
fmt.Sprintf("Archive %d w/role %s using forbidden ID", expectedStatus, tr.Role),
http.MethodPatch,
"/v1/users/archive",
user.UserArchiveRequest{
ID: tr.ForbiddenUser.ID,
},
tr.Token,
tr.Claims,
expectedStatus,
nil,
}
t.Logf("\tTest: %s - %s %s", rt.name, rt.method, rt.url)
w, ok := executeRequestTest(t, rt, ctx)
if !ok {
t.Fatalf("\t%s\tExecute request failed.", tests.Failed)
}
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
2019-08-01 16:17:47 -08:00
var actual weberror.ErrorResponse
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
t.Logf("\t\tGot error : %+v", err)
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
}
2019-08-01 16:17:47 -08:00
expected := weberror.ErrorResponse{
Error: user.ErrForbidden.Error(),
}
if diff := cmpDiff(t, actual, expected); diff {
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
}
t.Logf("\t%s\tReceived expected error.", tests.Success)
}
}
// TestUserDelete validates delete user endpoint.
func TestUserDelete(t *testing.T) {
defer tests.Recover(t)
tr := roleTests[auth.RoleAdmin]
// Add claims to the context for the user.
ctx := context.WithValue(tests.Context(), auth.Key, tr.Claims)
// Test delete user with invalid data.
{
expectedStatus := http.StatusBadRequest
2019-08-01 16:17:47 -08:00
invalidId := "345345"
rt := requestTest{
fmt.Sprintf("Delete %d w/role %s using invalid data", expectedStatus, tr.Role),
http.MethodDelete,
2019-08-01 16:17:47 -08:00
fmt.Sprintf("/v1/users/%s", invalidId),
nil,
tr.Token,
tr.Claims,
expectedStatus,
nil,
}
t.Logf("\tTest: %s - %s %s", rt.name, rt.method, rt.url)
w, ok := executeRequestTest(t, rt, ctx)
if !ok {
t.Fatalf("\t%s\tExecute request failed.", tests.Failed)
}
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
2019-08-01 16:17:47 -08:00
var actual weberror.ErrorResponse
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
t.Logf("\t\tGot error : %+v", err)
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
}
2019-08-01 16:17:47 -08:00
expected := weberror.ErrorResponse{
Error: "Field validation error",
Fields: []weberror.FieldError{
//{Field: "id", Error: "Key: 'id' Error:Field validation for 'id' failed on the 'uuid' tag"},
{
Field: "id",
Value: invalidId,
Tag: "uuid",
Error: "id must be a valid UUID",
Display: "id must be a valid UUID",
},
},
}
if diff := cmpDiff(t, actual, expected); diff {
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
}
t.Logf("\t%s\tReceived expected error.", tests.Success)
}
// Test delete user with forbidden ID.
{
expectedStatus := http.StatusForbidden
rt := requestTest{
fmt.Sprintf("Delete %d w/role %s using forbidden ID", expectedStatus, tr.Role),
http.MethodDelete,
fmt.Sprintf("/v1/users/%s", tr.ForbiddenUser.ID),
nil,
tr.Token,
tr.Claims,
expectedStatus,
nil,
}
t.Logf("\tTest: %s - %s %s", rt.name, rt.method, rt.url)
w, ok := executeRequestTest(t, rt, ctx)
if !ok {
t.Fatalf("\t%s\tExecute request failed.", tests.Failed)
}
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
2019-08-01 16:17:47 -08:00
var actual weberror.ErrorResponse
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
t.Logf("\t\tGot error : %+v", err)
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
}
2019-08-01 16:17:47 -08:00
expected := weberror.ErrorResponse{
Error: user.ErrForbidden.Error(),
}
if diff := cmpDiff(t, actual, expected); diff {
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
}
t.Logf("\t%s\tReceived expected error.", tests.Success)
}
}
// TestUserSwitchAccount validates user switch account endpoint.
func TestUserSwitchAccount(t *testing.T) {
defer tests.Recover(t)
tr := roleTests[auth.RoleAdmin]
// Add claims to the context for the user.
ctx := context.WithValue(tests.Context(), auth.Key, tr.Claims)
// Test user switch account with invalid data.
{
expectedStatus := http.StatusBadRequest
2019-08-01 16:17:47 -08:00
invalidAccountId := "sf"
rt := requestTest{
fmt.Sprintf("Switch account %d w/role %s using invalid data", expectedStatus, tr.Role),
http.MethodPatch,
2019-08-01 16:17:47 -08:00
"/v1/users/switch-account/" + invalidAccountId,
nil,
tr.Token,
tr.Claims,
expectedStatus,
nil,
}
t.Logf("\tTest: %s - %s %s", rt.name, rt.method, rt.url)
w, ok := executeRequestTest(t, rt, ctx)
if !ok {
t.Fatalf("\t%s\tExecute request failed.", tests.Failed)
}
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
2019-08-01 16:17:47 -08:00
var actual weberror.ErrorResponse
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
t.Logf("\t\tGot error : %+v", err)
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
}
2019-08-01 16:17:47 -08:00
expected := weberror.ErrorResponse{
Error: "Field validation error",
Fields: []weberror.FieldError{
{
Field: "account_id",
Value: invalidAccountId,
Tag: "uuid",
Error: "account_id must be a valid UUID",
Display: "account_id must be a valid UUID",
},
},
}
2019-08-01 16:17:47 -08:00
if diff := cmpDiff(t, expected, actual); diff {
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
}
t.Logf("\t%s\tReceived expected error.", tests.Success)
}
// Test user switch account with forbidden ID.
{
expectedStatus := http.StatusUnauthorized
rt := requestTest{
fmt.Sprintf("Switch account %d w/role %s using forbidden ID", expectedStatus, tr.Role),
http.MethodPatch,
fmt.Sprintf("/v1/users/switch-account/%s", tr.ForbiddenAccount.ID),
nil,
tr.Token,
tr.Claims,
expectedStatus,
nil,
}
t.Logf("\tTest: %s - %s %s", rt.name, rt.method, rt.url)
w, ok := executeRequestTest(t, rt, ctx)
if !ok {
t.Fatalf("\t%s\tExecute request failed.", tests.Failed)
}
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
2019-08-01 16:17:47 -08:00
var actual weberror.ErrorResponse
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
t.Logf("\t\tGot error : %+v", err)
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
}
2019-08-01 16:17:47 -08:00
expected := weberror.ErrorResponse{
Error: user.ErrAuthenticationFailure.Error(),
}
if diff := cmpDiff(t, actual, expected); diff {
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
}
t.Logf("\t%s\tReceived expected error.", tests.Success)
}
}
// TestUserToken validates user token endpoint.
func TestUserToken(t *testing.T) {
defer tests.Recover(t)
// Test user token with empty credentials.
{
expectedStatus := http.StatusUnauthorized
rt := requestTest{
fmt.Sprintf("Token %d using empty request", expectedStatus),
http.MethodPost,
"/v1/oauth/token",
nil,
user.Token{},
auth.Claims{},
expectedStatus,
nil,
}
t.Logf("\tTest: %s - %s %s", rt.name, rt.method, rt.url)
w, ok := executeRequestTest(t, rt, tests.Context())
if !ok {
t.Fatalf("\t%s\tExecute request failed.", tests.Failed)
}
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
2019-08-01 16:17:47 -08:00
var actual weberror.ErrorResponse
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
t.Logf("\t\tGot error : %+v", err)
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
}
2019-08-01 16:17:47 -08:00
expected := weberror.ErrorResponse{
Error: "must provide email and password in Basic auth",
}
if diff := cmpDiff(t, actual, expected); diff {
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
}
t.Logf("\t%s\tReceived expected error.", tests.Success)
}
// Test user token with invalid email.
{
expectedStatus := http.StatusUnauthorized
rt := requestTest{
fmt.Sprintf("Token %d using invalid email", expectedStatus),
http.MethodPost,
"/v1/oauth/token",
nil,
user.Token{},
auth.Claims{},
expectedStatus,
nil,
}
t.Logf("\tTest: %s - %s %s", rt.name, rt.method, rt.url)
r := httptest.NewRequest(rt.method, rt.url, nil)
r.SetBasicAuth("invalid email.com", "some random password")
w := httptest.NewRecorder()
r.Header.Set("Content-Type", web.MIMEApplicationJSONCharsetUTF8)
a.ServeHTTP(w, r)
if w.Code != expectedStatus {
t.Logf("\t\tBody : %s\n", w.Body.String())
t.Logf("\t\tShould receive a status code of %d for the response : %v", rt.statusCode, w.Code)
t.Fatalf("\t%s\tExecute request failed.", tests.Failed)
}
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
2019-08-01 16:17:47 -08:00
var actual weberror.ErrorResponse
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
t.Logf("\t\tGot error : %+v", err)
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
}
2019-08-01 16:17:47 -08:00
expected := weberror.ErrorResponse{
Error: user.ErrAuthenticationFailure.Error(),
}
if diff := cmpDiff(t, actual, expected); diff {
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
}
t.Logf("\t%s\tReceived expected error.", tests.Success)
}
// Test user token with invalid password.
{
for _, tr := range roleTests {
expectedStatus := http.StatusUnauthorized
rt := requestTest{
fmt.Sprintf("Token %d w/role %s using invalid password", expectedStatus, tr.Role),
http.MethodPost,
"/v1/oauth/token",
nil,
user.Token{},
auth.Claims{},
expectedStatus,
nil,
}
t.Logf("\tTest: %s - %s %s", rt.name, rt.method, rt.url)
r := httptest.NewRequest(rt.method, rt.url, nil)
r.SetBasicAuth(tr.User.Email, "invalid password")
w := httptest.NewRecorder()
r.Header.Set("Content-Type", web.MIMEApplicationJSONCharsetUTF8)
a.ServeHTTP(w, r)
if w.Code != expectedStatus {
t.Logf("\t\tBody : %s\n", w.Body.String())
t.Logf("\t\tShould receive a status code of %d for the response : %v", rt.statusCode, w.Code)
t.Fatalf("\t%s\tExecute request failed.", tests.Failed)
}
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
2019-08-01 16:17:47 -08:00
var actual weberror.ErrorResponse
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
t.Logf("\t\tGot error : %+v", err)
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
}
2019-08-01 16:17:47 -08:00
expected := weberror.ErrorResponse{
Error: user.ErrAuthenticationFailure.Error(),
}
if diff := cmpDiff(t, actual, expected); diff {
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
}
t.Logf("\t%s\tReceived expected error.", tests.Success)
}
}
// Test user token with valid email and password.
{
for _, tr := range roleTests {
expectedStatus := http.StatusOK
rt := requestTest{
fmt.Sprintf("Token %d w/role %s using valid credentials", expectedStatus, tr.Role),
http.MethodPost,
"/v1/oauth/token",
nil,
user.Token{},
auth.Claims{},
expectedStatus,
nil,
}
t.Logf("\tTest: %s - %s %s", rt.name, rt.method, rt.url)
r := httptest.NewRequest(rt.method, rt.url, nil)
r.SetBasicAuth(tr.User.Email, tr.User.password)
w := httptest.NewRecorder()
r.Header.Set("Content-Type", web.MIMEApplicationJSONCharsetUTF8)
a.ServeHTTP(w, r)
if w.Code != expectedStatus {
t.Logf("\t\tBody : %s\n", w.Body.String())
t.Logf("\t\tShould receive a status code of %d for the response : %v", rt.statusCode, w.Code)
t.Fatalf("\t%s\tExecute request failed.", tests.Failed)
}
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
var actual map[string]interface{}
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
t.Logf("\t\tGot error : %+v", err)
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
}
// This is just for response format validation, will verify account from claims.
expected := map[string]interface{}{
"access_token": actual["access_token"],
"token_type": actual["token_type"],
"expiry": actual["expiry"],
2019-08-01 16:17:47 -08:00
"ttl": actual["ttl"],
}
if diff := cmpDiff(t, actual, expected); diff {
t.Fatalf("\t%s\tReceived expected result.", tests.Failed)
}
t.Logf("\t%s\tReceived expected result.", tests.Success)
}
}
}