mirror of
https://github.com/raseels-repos/golang-saas-starter-kit.git
synced 2025-06-06 23:46:29 +02:00
889 lines
24 KiB
Go
889 lines
24 KiB
Go
package tests
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"testing"
|
|
"time"
|
|
|
|
"geeks-accelerator/oss/saas-starter-kit/example-project/internal/mid"
|
|
"geeks-accelerator/oss/saas-starter-kit/example-project/internal/platform/auth"
|
|
"geeks-accelerator/oss/saas-starter-kit/example-project/internal/platform/tests"
|
|
"geeks-accelerator/oss/saas-starter-kit/example-project/internal/platform/web"
|
|
"geeks-accelerator/oss/saas-starter-kit/example-project/internal/project"
|
|
"github.com/pborman/uuid"
|
|
)
|
|
|
|
func mockProjectCreateRequest(accountID string) project.ProjectCreateRequest {
|
|
return project.ProjectCreateRequest{
|
|
Name: fmt.Sprintf("Moon Launch %s", uuid.NewRandom().String()),
|
|
AccountID: accountID,
|
|
}
|
|
}
|
|
|
|
// mockProject creates a new project for testing and associates it with the supplied account ID.
|
|
func newMockProject(accountID string) *project.Project {
|
|
req := mockProjectCreateRequest(accountID)
|
|
p, err := project.Create(tests.Context(), auth.Claims{}, test.MasterDB, req, time.Now().UTC().AddDate(-1, -1, -1))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return p
|
|
}
|
|
|
|
// TestProjectCRUDAdmin tests all the project CRUD endpoints using an user with role admin.
|
|
func TestProjectCRUDAdmin(t *testing.T) {
|
|
defer tests.Recover(t)
|
|
|
|
tr := roleTests[auth.RoleAdmin]
|
|
|
|
// Add claims to the context for the project.
|
|
ctx := context.WithValue(tests.Context(), auth.Key, tr.Claims)
|
|
|
|
// Test create.
|
|
var created project.ProjectResponse
|
|
{
|
|
expectedStatus := http.StatusCreated
|
|
|
|
req := mockProjectCreateRequest(tr.Account.ID)
|
|
rt := requestTest{
|
|
fmt.Sprintf("Create %d w/role %s", expectedStatus, tr.Role),
|
|
http.MethodPost,
|
|
"/v1/projects",
|
|
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 project.ProjectResponse
|
|
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,
|
|
"account_id": req.AccountID,
|
|
"status": web.NewEnumResponse(ctx, "active", project.ProjectStatus_Values),
|
|
"created_at": web.NewTimeResponse(ctx, actual.CreatedAt.Value),
|
|
"name": req.Name,
|
|
}
|
|
|
|
var expected project.ProjectResponse
|
|
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)
|
|
}
|
|
|
|
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)
|
|
}
|
|
|
|
// Test read.
|
|
{
|
|
expectedStatus := http.StatusOK
|
|
|
|
rt := requestTest{
|
|
fmt.Sprintf("Read %d w/role %s", expectedStatus, tr.Role),
|
|
http.MethodGet,
|
|
fmt.Sprintf("/v1/projects/%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)
|
|
|
|
var actual project.ProjectResponse
|
|
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/projects/%s", randID),
|
|
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 web.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)
|
|
}
|
|
|
|
expected := web.ErrorResponse{
|
|
Error: fmt.Sprintf("project %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.
|
|
forbiddenProject := newMockProject(newMockSignup().account.ID)
|
|
{
|
|
expectedStatus := http.StatusNotFound
|
|
|
|
rt := requestTest{
|
|
fmt.Sprintf("Read %d w/role %s using forbidden ID", expectedStatus, tr.Role),
|
|
http.MethodGet,
|
|
fmt.Sprintf("/v1/projects/%s", forbiddenProject.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)
|
|
|
|
var actual web.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)
|
|
}
|
|
|
|
expected := web.ErrorResponse{
|
|
Error: fmt.Sprintf("project %s not found: Entity not found", forbiddenProject.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,
|
|
"/v1/projects",
|
|
project.ProjectUpdateRequest{
|
|
ID: created.ID,
|
|
Name: &newName,
|
|
},
|
|
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 archive.
|
|
{
|
|
expectedStatus := http.StatusNoContent
|
|
|
|
rt := requestTest{
|
|
fmt.Sprintf("Archive %d w/role %s", expectedStatus, tr.Role),
|
|
http.MethodPatch,
|
|
"/v1/projects/archive",
|
|
project.ProjectArchiveRequest{
|
|
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)
|
|
|
|
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/projects/%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)
|
|
|
|
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)
|
|
}
|
|
}
|
|
|
|
// TestProjectCRUDUser tests all the project CRUD endpoints using an user with role project.
|
|
func TestProjectCRUDUser(t *testing.T) {
|
|
defer tests.Recover(t)
|
|
|
|
tr := roleTests[auth.RoleUser]
|
|
|
|
// Add claims to the context for the project.
|
|
ctx := context.WithValue(tests.Context(), auth.Key, tr.Claims)
|
|
|
|
// Test create.
|
|
{
|
|
expectedStatus := http.StatusForbidden
|
|
|
|
req := mockProjectCreateRequest(tr.Account.ID)
|
|
rt := requestTest{
|
|
fmt.Sprintf("Create %d w/role %s", expectedStatus, tr.Role),
|
|
http.MethodPost,
|
|
"/v1/projects",
|
|
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 web.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)
|
|
}
|
|
|
|
expected := web.ErrorResponse{
|
|
Error: mid.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)
|
|
}
|
|
|
|
// Since role doesn't support create, bypass auth to test other endpoints.
|
|
created := newMockProject(tr.Account.ID).Response(ctx)
|
|
|
|
// Test read.
|
|
{
|
|
expectedStatus := http.StatusOK
|
|
|
|
rt := requestTest{
|
|
fmt.Sprintf("Read %d w/role %s", expectedStatus, tr.Role),
|
|
http.MethodGet,
|
|
fmt.Sprintf("/v1/projects/%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)
|
|
|
|
var actual *project.ProjectResponse
|
|
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/projects/%s", randID),
|
|
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 web.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)
|
|
}
|
|
|
|
expected := web.ErrorResponse{
|
|
Error: fmt.Sprintf("project %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.
|
|
forbiddenProject := newMockProject(newMockSignup().account.ID)
|
|
{
|
|
expectedStatus := http.StatusNotFound
|
|
|
|
rt := requestTest{
|
|
fmt.Sprintf("Read %d w/role %s using forbidden ID", expectedStatus, tr.Role),
|
|
http.MethodGet,
|
|
fmt.Sprintf("/v1/projects/%s", forbiddenProject.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)
|
|
|
|
var actual web.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)
|
|
}
|
|
|
|
expected := web.ErrorResponse{
|
|
Error: fmt.Sprintf("project %s not found: Entity not found", forbiddenProject.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),
|
|
http.MethodPatch,
|
|
"/v1/projects",
|
|
project.ProjectUpdateRequest{
|
|
ID: created.ID,
|
|
Name: &newName,
|
|
},
|
|
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 web.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)
|
|
}
|
|
|
|
expected := web.ErrorResponse{
|
|
Error: mid.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/projects/archive",
|
|
project.ProjectArchiveRequest{
|
|
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)
|
|
|
|
var actual web.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)
|
|
}
|
|
|
|
expected := web.ErrorResponse{
|
|
Error: mid.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 delete.
|
|
{
|
|
expectedStatus := http.StatusForbidden
|
|
|
|
rt := requestTest{
|
|
fmt.Sprintf("Delete %d w/role %s", expectedStatus, tr.Role),
|
|
http.MethodDelete,
|
|
fmt.Sprintf("/v1/projects/%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)
|
|
|
|
var actual web.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)
|
|
}
|
|
|
|
expected := web.ErrorResponse{
|
|
Error: mid.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)
|
|
}
|
|
}
|
|
|
|
// TestProjectCreate validates create project endpoint.
|
|
func TestProjectCreate(t *testing.T) {
|
|
defer tests.Recover(t)
|
|
|
|
tr := roleTests[auth.RoleAdmin]
|
|
|
|
// Add claims to the context for the project.
|
|
ctx := context.WithValue(tests.Context(), auth.Key, tr.Claims)
|
|
|
|
// Test create with invalid data.
|
|
{
|
|
expectedStatus := http.StatusBadRequest
|
|
|
|
req := mockProjectCreateRequest(tr.Account.ID)
|
|
invalidStatus := project.ProjectStatus("invalid status")
|
|
req.Status = &invalidStatus
|
|
rt := requestTest{
|
|
fmt.Sprintf("Create %d w/role %s using invalid data", expectedStatus, tr.Role),
|
|
http.MethodPost,
|
|
"/v1/projects",
|
|
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 web.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)
|
|
}
|
|
|
|
expected := web.ErrorResponse{
|
|
Error: "field validation error",
|
|
Fields: []web.FieldError{
|
|
{Field: "status", Error: "Key: 'ProjectCreateRequest.status' Error:Field validation for 'status' failed on the 'oneof' tag"},
|
|
},
|
|
}
|
|
|
|
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)
|
|
}
|
|
}
|
|
|
|
// TestProjectUpdate validates update project endpoint.
|
|
func TestProjectUpdate(t *testing.T) {
|
|
defer tests.Recover(t)
|
|
|
|
tr := roleTests[auth.RoleAdmin]
|
|
|
|
// Add claims to the context for the project.
|
|
ctx := context.WithValue(tests.Context(), auth.Key, tr.Claims)
|
|
|
|
// Test update with invalid data.
|
|
{
|
|
expectedStatus := http.StatusBadRequest
|
|
|
|
invalidStatus := project.ProjectStatus("invalid status")
|
|
rt := requestTest{
|
|
fmt.Sprintf("Update %d w/role %s using invalid data", expectedStatus, tr.Role),
|
|
http.MethodPatch,
|
|
"/v1/projects",
|
|
project.ProjectUpdateRequest{
|
|
ID: uuid.NewRandom().String(),
|
|
Status: &invalidStatus,
|
|
},
|
|
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 web.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)
|
|
}
|
|
|
|
expected := web.ErrorResponse{
|
|
Error: "field validation error",
|
|
Fields: []web.FieldError{
|
|
{Field: "status", Error: "Key: 'ProjectUpdateRequest.status' Error:Field validation for 'status' failed on the 'oneof' tag"},
|
|
},
|
|
}
|
|
|
|
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)
|
|
}
|
|
}
|
|
|
|
// TestProjectArchive validates archive project endpoint.
|
|
func TestProjectArchive(t *testing.T) {
|
|
defer tests.Recover(t)
|
|
|
|
tr := roleTests[auth.RoleAdmin]
|
|
|
|
// Add claims to the context for the project.
|
|
ctx := context.WithValue(tests.Context(), auth.Key, tr.Claims)
|
|
|
|
forbiddenProject := newMockProject(newMockSignup().account.ID)
|
|
|
|
// Test archive with invalid data.
|
|
{
|
|
expectedStatus := http.StatusBadRequest
|
|
|
|
rt := requestTest{
|
|
fmt.Sprintf("Archive %d w/role %s using invalid data", expectedStatus, tr.Role),
|
|
http.MethodPatch,
|
|
"/v1/projects/archive",
|
|
project.ProjectArchiveRequest{
|
|
ID: "a",
|
|
},
|
|
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 web.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)
|
|
}
|
|
|
|
expected := web.ErrorResponse{
|
|
Error: "field validation error",
|
|
Fields: []web.FieldError{
|
|
{Field: "id", Error: "Key: 'ProjectArchiveRequest.id' Error:Field validation for 'id' failed on the 'uuid' tag"},
|
|
},
|
|
}
|
|
|
|
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 with forbidden ID.
|
|
{
|
|
expectedStatus := http.StatusForbidden
|
|
|
|
rt := requestTest{
|
|
fmt.Sprintf("Archive %d w/role %s using forbidden ID", expectedStatus, tr.Role),
|
|
http.MethodPatch,
|
|
"/v1/projects/archive",
|
|
project.ProjectArchiveRequest{
|
|
ID: forbiddenProject.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)
|
|
|
|
var actual web.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)
|
|
}
|
|
|
|
expected := web.ErrorResponse{
|
|
Error: project.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)
|
|
}
|
|
}
|
|
|
|
// TestProjectDelete validates delete project endpoint.
|
|
func TestProjectDelete(t *testing.T) {
|
|
defer tests.Recover(t)
|
|
|
|
tr := roleTests[auth.RoleAdmin]
|
|
|
|
// Add claims to the context for the project.
|
|
ctx := context.WithValue(tests.Context(), auth.Key, tr.Claims)
|
|
|
|
forbiddenProject := newMockProject(newMockSignup().account.ID)
|
|
|
|
// Test delete with invalid data.
|
|
{
|
|
expectedStatus := http.StatusBadRequest
|
|
|
|
rt := requestTest{
|
|
fmt.Sprintf("Delete %d w/role %s using invalid data", expectedStatus, tr.Role),
|
|
http.MethodDelete,
|
|
"/v1/projects/a",
|
|
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 web.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)
|
|
}
|
|
|
|
expected := web.ErrorResponse{
|
|
Error: "field validation error",
|
|
Fields: []web.FieldError{
|
|
{Field: "id", Error: "Key: 'id' Error:Field validation for 'id' failed on the 'uuid' tag"},
|
|
},
|
|
}
|
|
|
|
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 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/projects/%s", forbiddenProject.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)
|
|
|
|
var actual web.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)
|
|
}
|
|
|
|
expected := web.ErrorResponse{
|
|
Error: project.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)
|
|
}
|
|
}
|