-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Loading status checks…
Handle Auth in Tests (#143)
Co-authored-by: David Oduneye <[email protected]>
1 parent
6e25748
commit 60e360b
Showing
49 changed files
with
1,801 additions
and
1,193 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
.DS_Store | ||
.env | ||
sac-cli | ||
.vscode | ||
.trunk |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,6 @@ | ||
package database | ||
|
||
import ( | ||
"github.com/GenerateNU/sac/backend/src/auth" | ||
"github.com/GenerateNU/sac/backend/src/config" | ||
"github.com/GenerateNU/sac/backend/src/models" | ||
|
||
|
@@ -11,21 +10,44 @@ import ( | |
) | ||
|
||
func ConfigureDB(settings config.Settings) (*gorm.DB, error) { | ||
db, err := gorm.Open(postgres.Open(settings.Database.WithDb()), &gorm.Config{ | ||
Logger: logger.Default.LogMode(logger.Info), | ||
SkipDefaultTransaction: true, | ||
TranslateError: true, | ||
}) | ||
db, err := EstablishConn(settings.Database.WithDb(), WithLoggerInfo()) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
err = db.Exec("CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\"").Error | ||
if err := MigrateDB(settings, db); err != nil { | ||
return nil, err | ||
} | ||
|
||
return db, nil | ||
} | ||
|
||
type OptionalFunc func(gorm.Config) gorm.Config | ||
|
||
func WithLoggerInfo() OptionalFunc { | ||
return func(gormConfig gorm.Config) gorm.Config { | ||
gormConfig.Logger = logger.Default.LogMode(logger.Info) | ||
return gormConfig | ||
} | ||
} | ||
|
||
func EstablishConn(dsn string, opts ...OptionalFunc) (*gorm.DB, error) { | ||
rootConfig := gorm.Config{ | ||
SkipDefaultTransaction: true, | ||
TranslateError: true, | ||
} | ||
|
||
for _, opt := range opts { | ||
rootConfig = opt(rootConfig) | ||
} | ||
|
||
db, err := gorm.Open(postgres.Open(dsn), &rootConfig) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if err := MigrateDB(settings, db); err != nil { | ||
err = db.Exec("CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\"").Error | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
|
@@ -78,22 +100,12 @@ func createSuperUser(settings config.Settings, db *gorm.DB) error { | |
return err | ||
} | ||
|
||
passwordHash, err := auth.ComputePasswordHash(settings.SuperUser.Password) | ||
superUser, err := SuperUser(settings.SuperUser) | ||
if err != nil { | ||
tx.Rollback() | ||
return err | ||
} | ||
|
||
superUser := models.User{ | ||
Role: models.Super, | ||
NUID: "000000000", | ||
Email: "[email protected]", | ||
PasswordHash: *passwordHash, | ||
FirstName: "SAC", | ||
LastName: "Super", | ||
College: models.KCCS, | ||
Year: models.First, | ||
} | ||
|
||
var user models.User | ||
|
||
if err := db.Where("nuid = ?", superUser.NUID).First(&user).Error; err != nil { | ||
|
@@ -108,17 +120,9 @@ func createSuperUser(settings config.Settings, db *gorm.DB) error { | |
return err | ||
} | ||
|
||
superClub := models.Club{ | ||
Name: "SAC", | ||
Preview: "SAC", | ||
Description: "SAC", | ||
NumMembers: 0, | ||
IsRecruiting: true, | ||
RecruitmentCycle: models.RecruitmentCycle(models.Always), | ||
RecruitmentType: models.Application, | ||
ApplicationLink: "https://generatenu.com/apply", | ||
Logo: "https://aws.amazon.com/s3", | ||
} | ||
SuperUserUUID = superUser.ID | ||
|
||
superClub := SuperClub() | ||
|
||
if err := tx.Create(&superClub).Error; err != nil { | ||
tx.Rollback() | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package database | ||
|
||
import ( | ||
"github.com/GenerateNU/sac/backend/src/auth" | ||
"github.com/GenerateNU/sac/backend/src/config" | ||
"github.com/GenerateNU/sac/backend/src/errors" | ||
"github.com/GenerateNU/sac/backend/src/models" | ||
"github.com/google/uuid" | ||
) | ||
|
||
var SuperUserUUID uuid.UUID | ||
|
||
func SuperUser(superUserSettings config.SuperUserSettings) (*models.User, *errors.Error) { | ||
passwordHash, err := auth.ComputePasswordHash(superUserSettings.Password) | ||
if err != nil { | ||
return nil, &errors.FailedToComputePasswordHash | ||
} | ||
|
||
return &models.User{ | ||
Role: models.Super, | ||
NUID: "000000000", | ||
Email: "generatesac@gmail.com", | ||
PasswordHash: *passwordHash, | ||
FirstName: "SAC", | ||
LastName: "Super", | ||
College: models.KCCS, | ||
Year: models.First, | ||
}, nil | ||
} | ||
|
||
func SuperClub() models.Club { | ||
return models.Club{ | ||
Name: "SAC", | ||
Preview: "SAC", | ||
Description: "SAC", | ||
NumMembers: 0, | ||
IsRecruiting: true, | ||
RecruitmentCycle: models.RecruitmentCycle(models.Always), | ||
RecruitmentType: models.Application, | ||
ApplicationLink: "https://generatenu.com/apply", | ||
Logo: "https://aws.amazon.com/s3", | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package errors | ||
|
||
import "github.com/gofiber/fiber/v2" | ||
|
||
var ( | ||
PassedAuthenticateMiddlewareButNilClaims = Error{ | ||
StatusCode: fiber.StatusInternalServerError, | ||
Message: "passed authenticate middleware but claims is nil", | ||
} | ||
FailedToCastToCustomClaims = Error{ | ||
StatusCode: fiber.StatusInternalServerError, | ||
Message: "failed to cast to custom claims", | ||
} | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package routes | ||
|
||
import ( | ||
"github.com/GenerateNU/sac/backend/src/config" | ||
"github.com/GenerateNU/sac/backend/src/controllers" | ||
"github.com/GenerateNU/sac/backend/src/services" | ||
"github.com/gofiber/fiber/v2" | ||
) | ||
|
||
func Auth(router fiber.Router, authService services.AuthServiceInterface, authSettings config.AuthSettings) { | ||
authController := controllers.NewAuthController(authService, authSettings) | ||
|
||
// api/v1/auth/* | ||
auth := router.Group("/auth") | ||
|
||
auth.Post("/login", authController.Login) | ||
auth.Get("/logout", authController.Logout) | ||
auth.Get("/refresh", authController.Refresh) | ||
auth.Get("/me", authController.Me) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package routes | ||
|
||
import ( | ||
"github.com/GenerateNU/sac/backend/src/controllers" | ||
"github.com/GenerateNU/sac/backend/src/services" | ||
"github.com/gofiber/fiber/v2" | ||
) | ||
|
||
func Category(router fiber.Router, categoryService services.CategoryServiceInterface) fiber.Router { | ||
categoryController := controllers.NewCategoryController(categoryService) | ||
|
||
categories := router.Group("/categories") | ||
|
||
categories.Post("/", categoryController.CreateCategory) | ||
categories.Get("/", categoryController.GetCategories) | ||
categories.Get("/:categoryID", categoryController.GetCategory) | ||
categories.Delete("/:categoryID", categoryController.DeleteCategory) | ||
categories.Patch("/:categoryID", categoryController.UpdateCategory) | ||
|
||
return categories | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package routes | ||
|
||
import ( | ||
"github.com/GenerateNU/sac/backend/src/controllers" | ||
"github.com/GenerateNU/sac/backend/src/services" | ||
"github.com/gofiber/fiber/v2" | ||
) | ||
|
||
func CategoryTag(router fiber.Router, categoryTagService services.CategoryTagServiceInterface) { | ||
categoryTagController := controllers.NewCategoryTagController(categoryTagService) | ||
|
||
categoryTags := router.Group("/:categoryID/tags") | ||
|
||
categoryTags.Get("/", categoryTagController.GetTagsByCategory) | ||
categoryTags.Get("/:tagID", categoryTagController.GetTagByCategory) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package routes | ||
|
||
import ( | ||
"github.com/GenerateNU/sac/backend/src/controllers" | ||
"github.com/GenerateNU/sac/backend/src/middleware" | ||
"github.com/GenerateNU/sac/backend/src/services" | ||
"github.com/GenerateNU/sac/backend/src/types" | ||
"github.com/gofiber/fiber/v2" | ||
) | ||
|
||
func Club(router fiber.Router, clubService services.ClubServiceInterface, middlewareService middleware.MiddlewareInterface) { | ||
clubController := controllers.NewClubController(clubService) | ||
|
||
clubs := router.Group("/clubs") | ||
|
||
clubs.Get("/", middlewareService.Authorize(types.ClubReadAll), clubController.GetAllClubs) | ||
clubs.Post("/", clubController.CreateClub) | ||
|
||
// api/v1/clubs/:clubID/* | ||
clubsID := clubs.Group("/:clubID") | ||
clubsID.Use(middleware.SuperSkipper(middlewareService.UserAuthorizeById)) | ||
|
||
clubsID.Get("/", clubController.GetClub) | ||
clubsID.Patch("/", middlewareService.Authorize(types.ClubWrite), clubController.UpdateClub) | ||
clubsID.Delete("/", middleware.SuperSkipper(middlewareService.Authorize(types.ClubDelete)), clubController.DeleteClub) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package routes | ||
|
||
import ( | ||
"github.com/GenerateNU/sac/backend/src/controllers" | ||
"github.com/GenerateNU/sac/backend/src/services" | ||
"github.com/gofiber/fiber/v2" | ||
) | ||
|
||
func Tag(router fiber.Router, tagService services.TagServiceInterface) { | ||
tagController := controllers.NewTagController(tagService) | ||
|
||
tags := router.Group("/tags") | ||
|
||
tags.Get("/:tagID", tagController.GetTag) | ||
tags.Post("/", tagController.CreateTag) | ||
tags.Patch("/:tagID", tagController.UpdateTag) | ||
tags.Delete("/:tagID", tagController.DeleteTag) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package routes | ||
|
||
import ( | ||
"github.com/GenerateNU/sac/backend/src/controllers" | ||
"github.com/GenerateNU/sac/backend/src/middleware" | ||
"github.com/GenerateNU/sac/backend/src/services" | ||
"github.com/GenerateNU/sac/backend/src/types" | ||
"github.com/gofiber/fiber/v2" | ||
) | ||
|
||
func User(router fiber.Router, userService services.UserServiceInterface, middlewareService middleware.MiddlewareInterface) fiber.Router { | ||
userController := controllers.NewUserController(userService) | ||
|
||
// api/v1/users/* | ||
users := router.Group("/users") | ||
users.Post("/", userController.CreateUser) | ||
users.Get("/", middleware.SuperSkipper(middlewareService.Authorize(types.UserReadAll)), userController.GetUsers) | ||
|
||
// api/v1/users/:userID/* | ||
usersID := users.Group("/:userID") | ||
usersID.Use(middleware.SuperSkipper(middlewareService.UserAuthorizeById)) | ||
|
||
usersID.Get("/", userController.GetUser) | ||
usersID.Patch("/", userController.UpdateUser) | ||
usersID.Delete("/", userController.DeleteUser) | ||
|
||
return users | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package routes | ||
|
||
import ( | ||
"github.com/GenerateNU/sac/backend/src/controllers" | ||
"github.com/GenerateNU/sac/backend/src/services" | ||
"github.com/gofiber/fiber/v2" | ||
) | ||
|
||
func UserTag(router fiber.Router, userTagService services.UserTagServiceInterface) { | ||
userTagController := controllers.NewUserTagController(userTagService) | ||
|
||
userTags := router.Group("/:userID/tags") | ||
|
||
userTags.Post("/", userTagController.CreateUserTags) | ||
userTags.Get("/", userTagController.GetUserTags) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package routes | ||
|
||
import ( | ||
"github.com/gofiber/fiber/v2" | ||
"github.com/gofiber/swagger" | ||
) | ||
|
||
func Utility(router fiber.Router) { | ||
router.Get("/swagger/*", swagger.HandlerDefault) | ||
router.Get("/health", func(c *fiber.Ctx) error { | ||
return c.SendStatus(200) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,26 @@ | ||
package types | ||
|
||
import "github.com/golang-jwt/jwt" | ||
import ( | ||
"github.com/GenerateNU/sac/backend/src/errors" | ||
"github.com/gofiber/fiber/v2" | ||
"github.com/golang-jwt/jwt" | ||
) | ||
|
||
type CustomClaims struct { | ||
jwt.StandardClaims | ||
Role string `json:"role"` | ||
} | ||
|
||
func From(c *fiber.Ctx) (*CustomClaims, *errors.Error) { | ||
rawClaims := c.Locals("claims") | ||
if rawClaims == nil { | ||
return nil, nil | ||
} | ||
|
||
claims, ok := rawClaims.(*CustomClaims) | ||
if !ok { | ||
return nil, &errors.FailedToCastToCustomClaims | ||
} | ||
|
||
return claims, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package helpers | ||
|
||
import ( | ||
"fmt" | ||
"net" | ||
"path/filepath" | ||
|
||
"github.com/GenerateNU/sac/backend/src/config" | ||
"github.com/GenerateNU/sac/backend/src/server" | ||
"github.com/gofiber/fiber/v2" | ||
"github.com/huandu/go-assert" | ||
"gorm.io/gorm" | ||
) | ||
|
||
type TestApp struct { | ||
App *fiber.App | ||
Address string | ||
Conn *gorm.DB | ||
Settings config.Settings | ||
TestUser *TestUser | ||
} | ||
|
||
func spawnApp() (*TestApp, error) { | ||
listener, err := net.Listen("tcp", "127.0.0.1:0") | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
configuration, err := config.GetConfiguration(filepath.Join("..", "..", "..", "config")) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
configuration.Database.DatabaseName = generateRandomDBName() | ||
|
||
connectionWithDB, err := configureDatabase(configuration) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &TestApp{ | ||
App: server.Init(connectionWithDB, configuration), | ||
Address: fmt.Sprintf("http://%s", listener.Addr().String()), | ||
Conn: connectionWithDB, | ||
Settings: configuration, | ||
}, nil | ||
} | ||
|
||
type ExistingAppAssert struct { | ||
App TestApp | ||
Assert *assert.A | ||
} | ||
|
||
func (eaa ExistingAppAssert) Close() { | ||
db, err := eaa.App.Conn.DB() | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
err = db.Close() | ||
if err != nil { | ||
panic(err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
package helpers | ||
|
||
import ( | ||
"github.com/GenerateNU/sac/backend/src/auth" | ||
"github.com/GenerateNU/sac/backend/src/database" | ||
"github.com/GenerateNU/sac/backend/src/models" | ||
"github.com/goccy/go-json" | ||
"github.com/gofiber/fiber/v2" | ||
"github.com/google/uuid" | ||
) | ||
|
||
type TestUser struct { | ||
UUID uuid.UUID | ||
Email string | ||
Password string | ||
AccessToken string | ||
RefreshToken string | ||
} | ||
|
||
func (app *TestApp) Auth(role models.UserRole) { | ||
if role == models.Super { | ||
app.authSuper() | ||
} else if role == models.Student { | ||
app.authStudent() | ||
} | ||
// unauthed -> do nothing | ||
} | ||
|
||
func (app *TestApp) authSuper() { | ||
superUser, superUserErr := database.SuperUser(app.Settings.SuperUser) | ||
if superUserErr != nil { | ||
panic(superUserErr) | ||
} | ||
|
||
email := superUser.Email | ||
password := app.Settings.SuperUser.Password | ||
|
||
resp, err := app.Send(TestRequest{ | ||
Method: fiber.MethodPost, | ||
Path: "/api/v1/auth/login", | ||
Body: &map[string]interface{}{ | ||
"email": email, | ||
"password": password, | ||
}, | ||
}) | ||
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 super user") | ||
} | ||
|
||
app.TestUser = &TestUser{ | ||
UUID: database.SuperUserUUID, | ||
Email: email, | ||
Password: password, | ||
AccessToken: accessToken, | ||
RefreshToken: refreshToken, | ||
} | ||
} | ||
|
||
func (app *TestApp) authStudent() { | ||
studentUser, rawPassword := SampleStudentFactory() | ||
|
||
resp, err := app.Send(TestRequest{ | ||
Method: fiber.MethodPost, | ||
Path: "/api/v1/users/", | ||
Body: SampleStudentJSONFactory(studentUser, rawPassword), | ||
}) | ||
if err != nil { | ||
panic(err) | ||
} | ||
var respBody map[string]interface{} | ||
|
||
err = json.NewDecoder(resp.Body).Decode(&respBody) | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
rawStudentUserUUID := respBody["id"].(string) | ||
studentUserUUID, err := uuid.Parse(rawStudentUserUUID) | ||
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{ | ||
UUID: studentUserUUID, | ||
Email: studentUser.Email, | ||
Password: rawPassword, | ||
AccessToken: accessToken, | ||
RefreshToken: refreshToken, | ||
} | ||
} | ||
|
||
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), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package helpers | ||
|
||
import ( | ||
"fmt" | ||
"sync" | ||
|
||
"github.com/GenerateNU/sac/backend/src/config" | ||
"github.com/GenerateNU/sac/backend/src/database" | ||
"gorm.io/gorm" | ||
) | ||
|
||
var ( | ||
rootConn *gorm.DB | ||
once sync.Once | ||
) | ||
|
||
func RootConn(dbSettings config.DatabaseSettings) { | ||
once.Do(func() { | ||
var err error | ||
rootConn, err = database.EstablishConn(dbSettings.WithoutDb()) | ||
if err != nil { | ||
panic(err) | ||
} | ||
}) | ||
} | ||
|
||
func configureDatabase(settings config.Settings) (*gorm.DB, error) { | ||
RootConn(settings.Database) | ||
|
||
err := rootConn.Exec(fmt.Sprintf("CREATE DATABASE %s", settings.Database.DatabaseName)).Error | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
dbWithDB, err := database.EstablishConn(settings.Database.WithDb()) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
err = database.MigrateDB(settings, dbWithDB) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return dbWithDB, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
package helpers | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"net/http" | ||
"net/http/httptest" | ||
"strings" | ||
|
||
"github.com/GenerateNU/sac/backend/src/errors" | ||
"github.com/GenerateNU/sac/backend/src/models" | ||
|
||
"github.com/goccy/go-json" | ||
|
||
"github.com/huandu/go-assert" | ||
) | ||
|
||
type TestRequest struct { | ||
Method string | ||
Path string | ||
Body *map[string]interface{} | ||
Headers *map[string]string | ||
Role *models.UserRole | ||
TestUserIDReplaces *string | ||
} | ||
|
||
func (app TestApp) Send(request TestRequest) (*http.Response, error) { | ||
address := fmt.Sprintf("%s%s", app.Address, request.Path) | ||
|
||
var req *http.Request | ||
|
||
if request.TestUserIDReplaces != nil { | ||
if strings.Contains(request.Path, *request.TestUserIDReplaces) { | ||
request.Path = strings.Replace(request.Path, *request.TestUserIDReplaces, app.TestUser.UUID.String(), 1) | ||
address = fmt.Sprintf("%s%s", app.Address, request.Path) | ||
} | ||
if request.Body != nil { | ||
if _, ok := (*request.Body)[*request.TestUserIDReplaces]; ok { | ||
(*request.Body)[*request.TestUserIDReplaces] = app.TestUser.UUID.String() | ||
} | ||
} | ||
} | ||
|
||
if request.Body == nil { | ||
req = httptest.NewRequest(request.Method, address, nil) | ||
} else { | ||
bodyBytes, err := json.Marshal(request.Body) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
req = httptest.NewRequest(request.Method, address, bytes.NewBuffer(bodyBytes)) | ||
|
||
if request.Headers == nil { | ||
request.Headers = &map[string]string{} | ||
} | ||
|
||
if _, ok := (*request.Headers)["Content-Type"]; !ok { | ||
(*request.Headers)["Content-Type"] = "application/json" | ||
} | ||
} | ||
|
||
if request.Headers != nil { | ||
for key, value := range *request.Headers { | ||
req.Header.Add(key, value) | ||
} | ||
} | ||
|
||
if app.TestUser != nil { | ||
req.AddCookie(&http.Cookie{ | ||
Name: "access_token", | ||
Value: app.TestUser.AccessToken, | ||
}) | ||
} | ||
|
||
resp, err := app.App.Test(req) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return resp, nil | ||
} | ||
|
||
func (request TestRequest) test(existingAppAssert ExistingAppAssert) (ExistingAppAssert, *http.Response) { | ||
if existingAppAssert.App.TestUser == nil && request.Role != nil { | ||
existingAppAssert.App.Auth(*request.Role) | ||
} | ||
|
||
resp, err := existingAppAssert.App.Send(request) | ||
|
||
existingAppAssert.Assert.NilError(err) | ||
|
||
return existingAppAssert, resp | ||
} | ||
|
||
func (existingAppAssert ExistingAppAssert) TestOnStatus(request TestRequest, status int) ExistingAppAssert { | ||
appAssert, resp := request.test(existingAppAssert) | ||
|
||
_, assert := appAssert.App, appAssert.Assert | ||
|
||
assert.Equal(status, resp.StatusCode) | ||
|
||
return appAssert | ||
} | ||
|
||
func (request *TestRequest) testOn(existingAppAssert ExistingAppAssert, status int, key string, value string) (ExistingAppAssert, *http.Response) { | ||
appAssert, resp := request.test(existingAppAssert) | ||
assert := appAssert.Assert | ||
|
||
var respBody map[string]interface{} | ||
|
||
err := json.NewDecoder(resp.Body).Decode(&respBody) | ||
|
||
assert.NilError(err) | ||
assert.Equal(value, respBody[key].(string)) | ||
|
||
assert.Equal(status, resp.StatusCode) | ||
return appAssert, resp | ||
} | ||
|
||
func (existingAppAssert ExistingAppAssert) TestOnError(request TestRequest, expectedError errors.Error) ExistingAppAssert { | ||
appAssert, _ := request.testOn(existingAppAssert, expectedError.StatusCode, "error", expectedError.Message) | ||
return appAssert | ||
} | ||
|
||
type ErrorWithTester struct { | ||
Error errors.Error | ||
Tester Tester | ||
} | ||
|
||
func (existingAppAssert ExistingAppAssert) TestOnErrorAndDB(request TestRequest, errorWithDBTester ErrorWithTester) ExistingAppAssert { | ||
appAssert, resp := request.testOn(existingAppAssert, errorWithDBTester.Error.StatusCode, "error", errorWithDBTester.Error.Message) | ||
errorWithDBTester.Tester(appAssert.App, appAssert.Assert, resp) | ||
return appAssert | ||
} | ||
|
||
func (existingAppAssert ExistingAppAssert) TestOnMessage(request TestRequest, status int, message string) ExistingAppAssert { | ||
request.testOn(existingAppAssert, status, "message", message) | ||
return existingAppAssert | ||
} | ||
|
||
func (existingAppAssert ExistingAppAssert) TestOnMessageAndDB(request TestRequest, status int, message string, dbTester Tester) ExistingAppAssert { | ||
appAssert, resp := request.testOn(existingAppAssert, status, "message", message) | ||
dbTester(appAssert.App, appAssert.Assert, resp) | ||
return appAssert | ||
} | ||
|
||
type Tester func(app TestApp, assert *assert.A, resp *http.Response) | ||
|
||
type TesterWithStatus struct { | ||
Status int | ||
Tester | ||
} | ||
|
||
func (existingAppAssert ExistingAppAssert) TestOnStatusAndDB(request TestRequest, testerStatus TesterWithStatus) ExistingAppAssert { | ||
appAssert, resp := request.test(existingAppAssert) | ||
app, assert := appAssert.App, appAssert.Assert | ||
|
||
assert.Equal(testerStatus.Status, resp.StatusCode) | ||
|
||
testerStatus.Tester(app, assert, resp) | ||
|
||
return appAssert | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package helpers | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/huandu/go-assert" | ||
) | ||
|
||
func InitTest(t *testing.T) ExistingAppAssert { | ||
assert := assert.New(t) | ||
app, err := spawnApp() | ||
|
||
assert.NilError(err) | ||
|
||
return ExistingAppAssert{ | ||
App: *app, | ||
Assert: assert, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package helpers | ||
|
||
import ( | ||
crand "crypto/rand" | ||
"fmt" | ||
"math/big" | ||
"strings" | ||
) | ||
|
||
func generateRandomInt(max int64) int64 { | ||
randInt, _ := crand.Int(crand.Reader, big.NewInt(max)) | ||
return randInt.Int64() | ||
} | ||
|
||
func generateRandomDBName() string { | ||
prefix := "sac_test_" | ||
letterBytes := "abcdefghijklmnopqrstuvwxyz" | ||
length := len(prefix) + 36 | ||
result := make([]byte, length) | ||
for i := 0; i < length; i++ { | ||
result[i] = letterBytes[generateRandomInt(int64(len(letterBytes)))] | ||
} | ||
|
||
return fmt.Sprintf("%s%s", prefix, string(result)) | ||
} | ||
|
||
func generateCasingPermutations(word string, currentPermutation string, index int, results *[]string) { | ||
if index == len(word) { | ||
*results = append(*results, currentPermutation) | ||
return | ||
} | ||
|
||
generateCasingPermutations(word, fmt.Sprintf("%s%s", currentPermutation, strings.ToLower(string(word[index]))), index+1, results) | ||
generateCasingPermutations(word, fmt.Sprintf("%s%s", currentPermutation, strings.ToUpper(string(word[index]))), index+1, results) | ||
} | ||
|
||
func AllCasingPermutations(word string) []string { | ||
results := make([]string, 0) | ||
generateCasingPermutations(word, "", 0, &results) | ||
return results | ||
} | ||
|
||
func StringToPointer(s string) *string { | ||
return &s | ||
} |
2 changes: 1 addition & 1 deletion
2
backend/tests/api/helpers_test.go → backend/tests/api/helpers/utilities_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
package tests | ||
package helpers | ||
|
||
import ( | ||
"slices" | ||
|
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.