From c775a24b136498f1541e28df38e9f53454ec7c6b Mon Sep 17 00:00:00 2001 From: garrettladley Date: Fri, 2 Feb 2024 23:44:15 -0500 Subject: [PATCH] student user tests --- backend/src/auth/tokens.go | 2 - backend/tests/api/club_test.go | 22 +++--- backend/tests/api/helpers.go | 91 ++++++++++++++++++++++-- backend/tests/api/user_tag_test.go | 10 +-- backend/tests/api/user_test.go | 110 ++++++++++++++++------------- 5 files changed, 165 insertions(+), 70 deletions(-) diff --git a/backend/src/auth/tokens.go b/backend/src/auth/tokens.go index fb08ff8cb..c065f7340 100644 --- a/backend/src/auth/tokens.go +++ b/backend/src/auth/tokens.go @@ -1,7 +1,6 @@ package auth import ( - "fmt" "time" "github.com/GenerateNU/sac/backend/src/config" @@ -71,7 +70,6 @@ func CreateRefreshToken(id string, refreshExpiresAfter uint, refreshTokenSecret func SignToken(token *jwt.Token, secret string) (*string, *errors.Error) { if token == nil || secret == "" { - fmt.Println(token) return nil, &errors.FailedToSignToken } diff --git a/backend/tests/api/club_test.go b/backend/tests/api/club_test.go index b24f1ac7d..0ab174a97 100644 --- a/backend/tests/api/club_test.go +++ b/backend/tests/api/club_test.go @@ -132,8 +132,8 @@ func AssertSampleClubBodyRespDB(app TestApp, assert *assert.A, resp *http.Respon return AssertClubBodyRespDB(app, assert, resp, SampleClubFactory(userID)) } -func CreateSampleClub(t *testing.T, existingAppAssert *ExistingAppAssert) (eaa ExistingAppAssert, userUUID uuid.UUID, clubUUID uuid.UUID) { - appAssert, userID := CreateSampleUser(t, existingAppAssert) +func CreateSampleClub(t *testing.T, existingAppAssert *ExistingAppAssert) (eaa ExistingAppAssert, studentUUID uuid.UUID, clubUUID uuid.UUID) { + appAssert, userID, _ := CreateSampleStudent(t, existingAppAssert) var sampleClubUUID uuid.UUID @@ -230,7 +230,7 @@ var TestNumClubsRemainsAt1 = func(app TestApp, assert *assert.A, resp *http.Resp } func AssertCreateBadClubDataFails(t *testing.T, jsonKey string, badValues []interface{}) { - appAssert, uuid := CreateSampleUser(t, nil) + appAssert, uuid, _ := CreateSampleStudent(t, nil) for _, badValue := range badValues { sampleClubPermutation := *SampleClubFactory(uuid) @@ -307,9 +307,9 @@ func TestCreateClubFailsOnInvalidLogo(t *testing.T) { } func TestUpdateClubWorks(t *testing.T) { - appAssert, userUUID, clubUUID := CreateSampleClub(t, nil) + appAssert, studentUUID, clubUUID := CreateSampleClub(t, nil) - updatedClub := SampleClubFactory(userUUID) + updatedClub := SampleClubFactory(studentUUID) (*updatedClub)["name"] = "Updated Name" (*updatedClub)["preview"] = "Updated Preview" @@ -328,9 +328,9 @@ func TestUpdateClubWorks(t *testing.T) { } func TestUpdateClubFailsOnInvalidBody(t *testing.T) { - appAssert, userUUID, clubUUID := CreateSampleClub(t, nil) + appAssert, studentUUID, clubUUID := CreateSampleClub(t, nil) - body := SampleClubFactory(userUUID) + body := SampleClubFactory(studentUUID) for _, invalidData := range []map[string]interface{}{ {"description": "Not a URL"}, @@ -391,24 +391,26 @@ func TestUpdateClubFailsBadRequest(t *testing.T) { "null", } + sampleStudent, rawPassword := SampleStudentFactory() + for _, badRequest := range badRequests { TestRequest{ Method: fiber.MethodPatch, Path: fmt.Sprintf("/api/v1/clubs/%s", badRequest), - Body: SampleUserFactory(), + Body: SampleStudentJSONFactory(sampleStudent, rawPassword), }.TestOnError(t, nil, errors.FailedToValidateID).Close() } } func TestUpdateClubFailsOnClubIdNotExist(t *testing.T) { - appAssert, userUUID := CreateSampleUser(t, nil) + appAssert, studentUUID, _ := CreateSampleStudent(t, nil) uuid := uuid.New() TestRequest{ Method: fiber.MethodPatch, Path: fmt.Sprintf("/api/v1/clubs/%s", uuid), - Body: SampleClubFactory(userUUID), + Body: SampleClubFactory(studentUUID), }.TestOnErrorAndDB(t, &appAssert, ErrorWithDBTester{ Error: errors.ClubNotFound, diff --git a/backend/tests/api/helpers.go b/backend/tests/api/helpers.go index c2ce1f823..89026cfcf 100644 --- a/backend/tests/api/helpers.go +++ b/backend/tests/api/helpers.go @@ -12,9 +12,11 @@ import ( "strings" "testing" + "github.com/GenerateNU/sac/backend/src/auth" "github.com/GenerateNU/sac/backend/src/config" "github.com/GenerateNU/sac/backend/src/database" "github.com/GenerateNU/sac/backend/src/errors" + "github.com/GenerateNU/sac/backend/src/models" "github.com/GenerateNU/sac/backend/src/server" "github.com/goccy/go-json" @@ -28,8 +30,9 @@ import ( type AuthLevel string var ( - SuperUser AuthLevel = "super_user" - LoggedOut AuthLevel = "logged_out" + SuperUser AuthLevel = "super_user" + StudentUser AuthLevel = "sample_user" + LoggedOut AuthLevel = "logged_out" ) type TestUser struct { @@ -39,6 +42,40 @@ type TestUser struct { RefreshToken string } +func SampleStudentFactory() (models.User, string) { + password := "1234567890&" + hashedPassword, err := auth.ComputePasswordHash(password) + if err != nil { + panic(err) + } + + return models.User{ + Role: models.Student, + FirstName: "Jane", + LastName: "Doe", + Email: "doe.jane@northeastern.edu", + PasswordHash: *hashedPassword, + NUID: "001234567", + College: models.KCCS, + Year: models.Third, + }, password +} + +func SampleStudentJSONFactory(sampleStudent models.User, rawPassword string) *map[string]interface{} { + if sampleStudent.Role != models.Student { + panic("User is not a student") + } + return &map[string]interface{}{ + "first_name": sampleStudent.FirstName, + "last_name": sampleStudent.LastName, + "email": sampleStudent.Email, + "password": rawPassword, + "nuid": sampleStudent.NUID, + "college": string(sampleStudent.College), + "year": int(sampleStudent.Year), + } +} + func (app *TestApp) Auth(level AuthLevel) { if level == SuperUser { superUser, superUserErr := database.SuperUser(app.Settings.SuperUser) @@ -82,6 +119,51 @@ func (app *TestApp) Auth(level AuthLevel) { AccessToken: accessToken, RefreshToken: refreshToken, } + } else if level == StudentUser { + studentUser, rawPassword := SampleStudentFactory() + + _, err := app.Send(TestRequest{ + Method: fiber.MethodPost, + Path: "/api/v1/users/", + Body: SampleStudentJSONFactory(studentUser, rawPassword), + }) + if err != nil { + panic(err) + } + + resp, err := app.Send(TestRequest{ + Method: fiber.MethodPost, + Path: "/api/v1/auth/login", + Body: &map[string]interface{}{ + "email": studentUser.Email, + "password": rawPassword, + }, + }) + if err != nil { + panic(err) + } + + var accessToken string + var refreshToken string + + for _, cookie := range resp.Cookies() { + if cookie.Name == "access_token" { + accessToken = cookie.Value + } else if cookie.Name == "refresh_token" { + refreshToken = cookie.Value + } + } + + if accessToken == "" || refreshToken == "" { + panic("Failed to authenticate sample student user") + } + + app.TestUser = &TestUser{ + Email: studentUser.Email, + Password: rawPassword, + AccessToken: accessToken, + RefreshToken: refreshToken, + } } } @@ -287,13 +369,12 @@ func (request *TestRequest) testOn(t *testing.T, existingAppAssert *ExistingAppA assert.Equal(value, respBody[key].(string)) assert.Equal(status, resp.StatusCode) - return appAssert, resp } func (request TestRequest) TestOnError(t *testing.T, existingAppAssert *ExistingAppAssert, expectedError errors.Error) ExistingAppAssert { - request.testOn(t, existingAppAssert, expectedError.StatusCode, "error", expectedError.Message) - return *existingAppAssert + appAssert, _ := request.testOn(t, existingAppAssert, expectedError.StatusCode, "error", expectedError.Message) + return appAssert } type ErrorWithDBTester struct { diff --git a/backend/tests/api/user_tag_test.go b/backend/tests/api/user_tag_test.go index a67022a56..4a85e215f 100644 --- a/backend/tests/api/user_tag_test.go +++ b/backend/tests/api/user_tag_test.go @@ -183,7 +183,7 @@ type UUIDSlice []uuid.UUID var testUUID = uuid.New() func TestCreateUserTagsFailsOnInvalidKey(t *testing.T) { - appAssert, uuid := CreateSampleUser(t, nil) + appAssert, uuid, _ := CreateSampleStudent(t, nil) invalidBody := []map[string]interface{}{ { @@ -214,7 +214,7 @@ func TestCreateUserTagsFailsOnNonExistentUser(t *testing.T) { } func TestCreateUserTagsWorks(t *testing.T) { - appAssert, uuid := CreateSampleUser(t, nil) + appAssert, uuid, _ := CreateSampleStudent(t, nil) // Create a set of tags: tagUUIDs := CreateSetOfTags(t, appAssert) @@ -237,7 +237,7 @@ func TestCreateUserTagsWorks(t *testing.T) { } func TestCreateUserTagsNoneAddedIfInvalid(t *testing.T) { - appAssert, uuid := CreateSampleUser(t, nil) + appAssert, uuid, _ := CreateSampleStudent(t, nil) TestRequest{ Method: fiber.MethodPost, @@ -269,7 +269,7 @@ func TestGetUserTagsFailsOnNonExistentUser(t *testing.T) { } func TestGetUserTagsReturnsEmptyListWhenNoneAdded(t *testing.T) { - appAssert, uuid := CreateSampleUser(t, nil) + appAssert, uuid, _ := CreateSampleStudent(t, nil) TestRequest{ Method: fiber.MethodGet, @@ -293,7 +293,7 @@ func TestGetUserTagsReturnsEmptyListWhenNoneAdded(t *testing.T) { } func TestGetUserTagsReturnsCorrectList(t *testing.T) { - appAssert, uuid := CreateSampleUser(t, nil) + appAssert, uuid, _ := CreateSampleStudent(t, nil) // Create a set of tags: tagUUIDs := CreateSetOfTags(t, appAssert) diff --git a/backend/tests/api/user_test.go b/backend/tests/api/user_test.go index 020f4c320..7e6bdf5bc 100644 --- a/backend/tests/api/user_test.go +++ b/backend/tests/api/user_test.go @@ -19,7 +19,7 @@ import ( "github.com/huandu/go-assert" ) -func TestGetUsersWorks(t *testing.T) { +func TestGetUsersWorksForSuper(t *testing.T) { TestRequest{ Method: fiber.MethodGet, Path: "/api/v1/users/", @@ -59,8 +59,16 @@ func TestGetUsersWorks(t *testing.T) { ).Close() } +func TestGetUsersFailsForStudent(t *testing.T) { + TestRequest{ + Method: fiber.MethodGet, + Path: "/api/v1/users/", + AuthLevel: &StudentUser, + }.TestOnError(t, nil, errors.Unauthorized).Close() +} + func TestGetUserWorks(t *testing.T) { - appAssert, uuid := CreateSampleUser(t, nil) + appAssert, uuid, _ := CreateSampleStudent(t, nil) TestRequest{ Method: fiber.MethodGet, @@ -75,7 +83,9 @@ func TestGetUserWorks(t *testing.T) { assert.NilError(err) - sampleUser := *SampleUserFactory() + sampleStudent, rawPassword := SampleStudentFactory() + + sampleUser := *SampleStudentJSONFactory(sampleStudent, rawPassword) assert.Equal(sampleUser["first_name"].(string), respUser.FirstName) assert.Equal(sampleUser["last_name"].(string), respUser.LastName) @@ -132,7 +142,7 @@ func TestGetUserFailsNotExist(t *testing.T) { } func TestUpdateUserWorks(t *testing.T) { - appAssert, uuid := CreateSampleUser(t, nil) + appAssert, uuid, _ := CreateSampleStudent(t, nil) newFirstName := "Michael" newLastName := "Brennan" @@ -154,12 +164,16 @@ func TestUpdateUserWorks(t *testing.T) { assert.NilError(err) + sampleStudent, rawPassword := SampleStudentFactory() + + sampleStudentJSON := *SampleStudentJSONFactory(sampleStudent, rawPassword) + assert.Equal(newFirstName, respUser.FirstName) assert.Equal(newLastName, respUser.LastName) - assert.Equal((*SampleUserFactory())["email"].(string), respUser.Email) - assert.Equal((*SampleUserFactory())["nuid"].(string), respUser.NUID) - assert.Equal(models.College((*SampleUserFactory())["college"].(string)), respUser.College) - assert.Equal(models.Year((*SampleUserFactory())["year"].(int)), respUser.Year) + assert.Equal((sampleStudentJSON)["email"].(string), respUser.Email) + assert.Equal((sampleStudentJSON)["nuid"].(string), respUser.NUID) + assert.Equal(models.College((sampleStudentJSON)["college"].(string)), respUser.College) + assert.Equal(models.Year((sampleStudentJSON)["year"].(int)), respUser.Year) var dbUser models.User @@ -179,7 +193,7 @@ func TestUpdateUserWorks(t *testing.T) { } func TestUpdateUserFailsOnInvalidBody(t *testing.T) { - appAssert, uuid := CreateSampleUser(t, nil) + appAssert, uuid, _ := CreateSampleStudent(t, nil) for _, invalidData := range []map[string]interface{}{ {"email": "not.northeastern@gmail.com"}, @@ -211,11 +225,13 @@ func TestUpdateUserFailsBadRequest(t *testing.T) { "null", } + sampleStudent, rawPassword := SampleStudentFactory() + for _, badRequest := range badRequests { TestRequest{ Method: fiber.MethodPatch, Path: fmt.Sprintf("/api/v1/users/%s", badRequest), - Body: SampleUserFactory(), + Body: SampleStudentJSONFactory(sampleStudent, rawPassword), }.TestOnError(t, nil, errors.FailedToValidateID).Close() } } @@ -223,10 +239,12 @@ func TestUpdateUserFailsBadRequest(t *testing.T) { func TestUpdateUserFailsOnIdNotExist(t *testing.T) { uuid := uuid.New() + sampleStudent, rawPassword := SampleStudentFactory() + TestRequest{ Method: fiber.MethodPatch, Path: fmt.Sprintf("/api/v1/users/%s", uuid), - Body: SampleUserFactory(), + Body: SampleStudentJSONFactory(sampleStudent, rawPassword), }.TestOnErrorAndDB(t, nil, ErrorWithDBTester{ Error: errors.UserNotFound, @@ -242,7 +260,7 @@ func TestUpdateUserFailsOnIdNotExist(t *testing.T) { } func TestDeleteUserWorks(t *testing.T) { - appAssert, uuid := CreateSampleUser(t, nil) + appAssert, uuid, _ := CreateSampleStudent(t, nil) TestRequest{ Method: fiber.MethodDelete, @@ -298,18 +316,6 @@ func TestDeleteUserBadRequest(t *testing.T) { } } -func SampleUserFactory() *map[string]interface{} { - return &map[string]interface{}{ - "first_name": "Jane", - "last_name": "Doe", - "email": "doe.jane@northeastern.edu", - "password": "1234567890&", - "nuid": "001234567", - "college": "KCCS", - "year": 3, - } -} - func AssertUserWithIDBodyRespDB(app TestApp, assert *assert.A, resp *http.Response, body *map[string]interface{}) uuid.UUID { var respUser models.User @@ -351,16 +357,20 @@ func AssertUserWithIDBodyRespDB(app TestApp, assert *assert.A, resp *http.Respon } func AssertSampleUserBodyRespDB(app TestApp, assert *assert.A, resp *http.Response) uuid.UUID { - return AssertUserWithIDBodyRespDB(app, assert, resp, SampleUserFactory()) + sampleStudent, rawPassword := SampleStudentFactory() + + return AssertUserWithIDBodyRespDB(app, assert, resp, SampleStudentJSONFactory(sampleStudent, rawPassword)) } -func CreateSampleUser(t *testing.T, existingAppAssert *ExistingAppAssert) (ExistingAppAssert, uuid.UUID) { +func CreateSampleStudent(t *testing.T, existingAppAssert *ExistingAppAssert) (ExistingAppAssert, uuid.UUID, *map[string]interface{}) { var uuid uuid.UUID + sampleStudent, rawPassword := SampleStudentFactory() + newAppAssert := TestRequest{ Method: fiber.MethodPost, Path: "/api/v1/users/", - Body: SampleUserFactory(), + Body: SampleStudentJSONFactory(sampleStudent, rawPassword), }.TestOnStatusAndDB(t, existingAppAssert, DBTesterWithStatus{ Status: fiber.StatusCreated, @@ -371,9 +381,9 @@ func CreateSampleUser(t *testing.T, existingAppAssert *ExistingAppAssert) (Exist ) if existingAppAssert == nil { - return newAppAssert, uuid + return newAppAssert, uuid, SampleStudentJSONFactory(sampleStudent, rawPassword) } else { - return *existingAppAssert, uuid + return *existingAppAssert, uuid, SampleStudentJSONFactory(sampleStudent, rawPassword) } } @@ -396,17 +406,19 @@ var TestNumUsersRemainsAt2 = func(app TestApp, assert *assert.A, resp *http.Resp } func TestCreateUserWorks(t *testing.T) { - appAssert, _ := CreateSampleUser(t, nil) + appAssert, _, _ := CreateSampleStudent(t, nil) appAssert.Close() } func TestCreateUserFailsIfUserWithEmailAlreadyExists(t *testing.T) { - appAssert, _ := CreateSampleUser(t, nil) + appAssert, studentUUID, body := CreateSampleStudent(t, nil) + + (*body)["id"] = studentUUID TestRequest{ Method: fiber.MethodPost, Path: "/api/v1/users/", - Body: SampleUserFactory(), + Body: body, }.TestOnErrorAndDB(t, &appAssert, ErrorWithDBTester{ Error: errors.UserAlreadyExists, @@ -418,22 +430,20 @@ func TestCreateUserFailsIfUserWithEmailAlreadyExists(t *testing.T) { } func TestCreateUserFailsIfUserWithNUIDAlreadyExists(t *testing.T) { - appAssert, _ := CreateSampleUser(t, nil) - - slightlyDifferentSampleUser := &map[string]interface{}{ - "first_name": "John", - "last_name": "Doe", - "email": "doe.john@northeastern.edu", - "password": "1234567890&", - "nuid": "001234567", - "college": "KCCS", - "year": 3, - } + appAssert, _, _ := CreateSampleStudent(t, nil) + + sampleStudent, rawPassword := SampleStudentFactory() + + slightlyDifferentSampleStudentJSON := SampleStudentJSONFactory(sampleStudent, rawPassword) + + (*slightlyDifferentSampleStudentJSON)["first_name"] = "John" + (*slightlyDifferentSampleStudentJSON)["last_name"] = "Doe" + (*slightlyDifferentSampleStudentJSON)["email"] = "doe.john@northeastern.edu" TestRequest{ Method: fiber.MethodPost, Path: "/api/v1/users/", - Body: slightlyDifferentSampleUser, + Body: slightlyDifferentSampleStudentJSON, }.TestOnErrorAndDB(t, &appAssert, ErrorWithDBTester{ Error: errors.UserAlreadyExists, @@ -443,10 +453,12 @@ func TestCreateUserFailsIfUserWithNUIDAlreadyExists(t *testing.T) { } func AssertCreateBadDataFails(t *testing.T, jsonKey string, badValues []interface{}) { - appAssert, _ := CreateSampleUser(t, nil) + appAssert, _, _ := CreateSampleStudent(t, nil) + + sampleStudent, rawPassword := SampleStudentFactory() for _, badValue := range badValues { - sampleUserPermutation := *SampleUserFactory() + sampleUserPermutation := *SampleStudentJSONFactory(sampleStudent, rawPassword) sampleUserPermutation[jsonKey] = badValue TestRequest{ @@ -524,7 +536,9 @@ func TestCreateUserFailsOnInvalidCollege(t *testing.T) { } func TestCreateUserFailsOnMissingFields(t *testing.T) { - appAssert, _ := CreateSampleUser(t, nil) + appAssert, _, _ := CreateSampleStudent(t, nil) + + sampleStudent, rawPassword := SampleStudentFactory() for _, missingField := range []string{ "first_name", @@ -535,7 +549,7 @@ func TestCreateUserFailsOnMissingFields(t *testing.T) { "college", "year", } { - sampleUserPermutation := *SampleUserFactory() + sampleUserPermutation := *SampleStudentJSONFactory(sampleStudent, rawPassword) delete(sampleUserPermutation, missingField) TestRequest{