Skip to content

Commit

Permalink
SAC-6 Get User GET (#14)
Browse files Browse the repository at this point in the history
Co-authored-by: edwinliiiii <[email protected]>
Co-authored-by: edwinliiiii <[email protected]>
Co-authored-by: Garrett Ladley <[email protected]>
Co-authored-by: garrettladley <[email protected]>
  • Loading branch information
5 people authored Jan 21, 2024
1 parent 4ca58e6 commit 5c57959
Show file tree
Hide file tree
Showing 13 changed files with 164 additions and 33 deletions.
5 changes: 2 additions & 3 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,8 @@ jobs:
- name: Install Dependencies
run: cd backend && go get ./...
- name: Migrate DB
run: |
cd backend/src && go run main.go --only-migrate
run: cd backend/src && go run main.go --only-migrate
- name: Run Tests with Coverage
run: cd backend && go test -race -coverprofile=coverage.txt -covermode=atomic ./...
run: cd backend && go test -failfast -benchmem -race -coverprofile=coverage.txt ./...
- name: Print Coverage
run: cd backend && go tool cover -func=coverage.txt
21 changes: 21 additions & 0 deletions backend/src/controllers/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,24 @@ func (u *UserController) GetAllUsers(c *fiber.Ctx) error {

return c.Status(fiber.StatusOK).JSON(users)
}

// GetUser godoc
//
// @Summary Gets specific user
// @Description Returns specific user
// @ID get-user
// @Tags user
// @Produce json
// @Success 200 {object} models.User
// @Failure 400 {string} string "failed to validate id"
// @Failure 404 {string} string "failed to find user"
// @Failure 500 {string} string
// @Router /api/v1/users/ [get]
func (u *UserController) GetUser(c *fiber.Ctx) error {
user, err := u.userService.GetUser(c.Params("id"))
if err != nil {
return err
}

return c.Status(fiber.StatusOK).JSON(user)
}
2 changes: 1 addition & 1 deletion backend/src/models/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const (
type User struct {
types.Model

Role UserRole `gorm:"type:varchar(255);" json:"user_role" validate:"required,max=255"`
Role UserRole `gorm:"type:varchar(255);" json:"user_role,omitempty" validate:"required,max=255"`
NUID string `gorm:"column:nuid;type:varchar(9);unique" json:"nuid" validate:"required,numeric,len=9"`
FirstName string `gorm:"type:varchar(255)" json:"first_name" validate:"required,max=255"`
LastName string `gorm:"type:varchar(255)" json:"last_name" validate:"required,max=255"`
Expand Down
1 change: 1 addition & 0 deletions backend/src/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ func userRoutes(router fiber.Router, userService services.UserServiceInterface)
users := router.Group("/users")

users.Get("/", userController.GetAllUsers)
users.Get("/:id", userController.GetUser)
}

func categoryRoutes(router fiber.Router, categoryService services.CategoryServiceInterface) {
Expand Down
13 changes: 12 additions & 1 deletion backend/src/services/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,30 @@ package services
import (
"github.com/GenerateNU/sac/backend/src/models"
"github.com/GenerateNU/sac/backend/src/transactions"
"github.com/GenerateNU/sac/backend/src/utilities"

"gorm.io/gorm"
)

type UserServiceInterface interface {
GetAllUsers() ([]models.User, error)
GetUser(string) (*models.User, error)
}

type UserService struct {
DB *gorm.DB
}

// Gets all users (including soft deleted users) for testing
func (u *UserService) GetAllUsers() ([]models.User, error) {
return transactions.GetAllUsers(u.DB)
}

func (u *UserService) GetUser(userID string) (*models.User, error) {
idAsUint, err := utilities.ValidateID(userID)

if err != nil {
return nil, err
}

return transactions.GetUser(u.DB, *idAsUint)
}
17 changes: 16 additions & 1 deletion backend/src/transactions/user.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package transactions

import (
"errors"

"github.com/GenerateNU/sac/backend/src/models"

"github.com/gofiber/fiber/v2"
Expand All @@ -10,9 +12,22 @@ import (
func GetAllUsers(db *gorm.DB) ([]models.User, error) {
var users []models.User

if err := db.Unscoped().Omit("password_hash").Find(&users).Error; err != nil {
if err := db.Omit("password_hash").Find(&users).Error; err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, "failed to get all users")
}

return users, nil
}

func GetUser(db *gorm.DB, id uint) (*models.User, error) {
var user models.User

if err := db.Omit("password_hash").First(&user, id).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, fiber.NewError(fiber.StatusNotFound, "failed to find tag")
}
return nil, fiber.NewError(fiber.StatusInternalServerError, "failed to get user")
}

return &user, nil
}
12 changes: 8 additions & 4 deletions backend/tests/api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Say you want to test hitting the `[APP_ADDRESS]/health` endpoint with a GET requ
TestRequest{
Method: "GET",
Path: "/health",
}.TestOnStatus(t, nil, 200)
}.TestOnStatus(t, nil, 200).Close()
```

## Testing that a Request Returns a XXX Status Code and Assert Something About the Database
Expand All @@ -59,7 +59,7 @@ TestRequest{
Status: 201,
DBTester: AssertRespCategorySameAsDBCategory,
},
)
).Close()
```

### DBTesters
Expand Down Expand Up @@ -114,9 +114,13 @@ TestRequest{
Status: 201,
DBTester: AssertRespTagSameAsDBTag,
},
)
).Close()
```

### Why Close?

This closes the connection to the database. This is important because if you don't close the connection, we will run out of available connections and the tests will fail. **Call this on the last test request of a test**

## Testing that a Request Returns a XXX Status Code, Assert Something About the Message, and Assert Something About the Database

Say you want to test a bad request to POST `[APP_ADDRESS]/api/v1/categories/` endpoint returns a `400` status code, the message is `failed to process the request`, and that a category was not created.
Expand All @@ -136,5 +140,5 @@ TestRequest{
},
DBTester: AssertNoCategories,
},
)
).Close()
```
10 changes: 6 additions & 4 deletions backend/tests/api/category_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func CreateSampleCategory(t *testing.T, categoryName string, existingAppAssert *
}

func TestCreateCategoryWorks(t *testing.T) {
CreateSampleCategory(t, "Science", nil)
CreateSampleCategory(t, "Science", nil).Close()
}

func TestCreateCategoryIgnoresid(t *testing.T) {
Expand All @@ -57,7 +57,7 @@ func TestCreateCategoryIgnoresid(t *testing.T) {
Status: 201,
DBTester: AssertRespCategorySameAsDBCategory,
},
)
).Close()
}

func AssertNoCategories(app TestApp, assert *assert.A, resp *http.Response) {
Expand Down Expand Up @@ -89,7 +89,7 @@ func TestCreateCategoryFailsIfNameIsNotString(t *testing.T) {
},
DBTester: AssertNoCategories,
},
)
).Close()
}

func TestCreateCategoryFailsIfNameIsMissing(t *testing.T) {
Expand All @@ -105,7 +105,7 @@ func TestCreateCategoryFailsIfNameIsMissing(t *testing.T) {
},
DBTester: AssertNoCategories,
},
)
).Close()
}

func TestCreateCategoryFailsIfCategoryWithThatNameAlreadyExists(t *testing.T) {
Expand Down Expand Up @@ -134,4 +134,6 @@ func TestCreateCategoryFailsIfCategoryWithThatNameAlreadyExists(t *testing.T) {
},
)
}

existingAppAssert.Close()
}
2 changes: 1 addition & 1 deletion backend/tests/api/health_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ func TestHealthWorks(t *testing.T) {
Path: "/health",
}.TestOnStatus(t, nil,
200,
)
).Close()
}
14 changes: 14 additions & 0 deletions backend/tests/api/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,20 @@ type ExistingAppAssert struct {
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)
}
}

type TestRequest struct {
Method string
Path string
Expand Down
26 changes: 13 additions & 13 deletions backend/tests/api/tag_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func CreateSampleTag(t *testing.T, tagName string, categoryName string, existing
}

func TestCreateTagWorks(t *testing.T) {
CreateSampleTag(t, "Generate", "Science", nil)
CreateSampleTag(t, "Generate", "Science", nil).Close()
}

var AssertNoTags = func(app TestApp, assert *assert.A, resp *http.Response) {
Expand Down Expand Up @@ -83,7 +83,7 @@ func TestCreateTagFailsBadRequest(t *testing.T) {
},
DBTester: AssertNoTags,
},
)
).Close()
}
}

Expand Down Expand Up @@ -111,7 +111,7 @@ func TestCreateTagFailsValidation(t *testing.T) {
},
DBTester: AssertNoTags,
},
)
).Close()
}
}

Expand All @@ -126,7 +126,7 @@ func TestGetTagWorks(t *testing.T) {
Status: 200,
DBTester: AssertRespTagSameAsDBTag,
},
)
).Close()
}

func TestGetTagFailsBadRequest(t *testing.T) {
Expand All @@ -147,7 +147,7 @@ func TestGetTagFailsBadRequest(t *testing.T) {
Status: 400,
Message: "failed to validate id",
},
)
).Close()
}
}

Expand All @@ -160,7 +160,7 @@ func TestGetTagFailsNotFound(t *testing.T) {
Status: 404,
Message: "failed to find tag",
},
)
).Close()
}

func TestUpdateTagWorksUpdateName(t *testing.T) {
Expand All @@ -178,7 +178,7 @@ func TestUpdateTagWorksUpdateName(t *testing.T) {
Status: 200,
DBTester: AssertRespTagSameAsDBTag,
},
)
).Close()
}

func TestUpdateTagWorksUpdateCategory(t *testing.T) {
Expand All @@ -197,7 +197,7 @@ func TestUpdateTagWorksUpdateCategory(t *testing.T) {
Status: 200,
DBTester: AssertRespTagSameAsDBTag,
},
)
).Close()
}

func TestUpdateTagWorksWithSameDetails(t *testing.T) {
Expand All @@ -215,7 +215,7 @@ func TestUpdateTagWorksWithSameDetails(t *testing.T) {
Status: 200,
DBTester: AssertRespTagSameAsDBTag,
},
)
).Close()
}

func TestUpdateTagFailsBadRequest(t *testing.T) {
Expand Down Expand Up @@ -243,7 +243,7 @@ func TestUpdateTagFailsBadRequest(t *testing.T) {
},
DBTester: AssertNoTags,
},
)
).Close()
}
}

Expand All @@ -258,7 +258,7 @@ func TestDeleteTagWorks(t *testing.T) {
Status: 204,
DBTester: AssertNoTags,
},
)
).Close()
}

func TestDeleteTagFailsBadRequest(t *testing.T) {
Expand All @@ -279,7 +279,7 @@ func TestDeleteTagFailsBadRequest(t *testing.T) {
Status: 400,
Message: "failed to validate id",
},
)
).Close()
}
}

Expand All @@ -292,5 +292,5 @@ func TestDeleteTagFailsNotFound(t *testing.T) {
Status: 404,
Message: "failed to find tag",
},
)
).Close()
}
Loading

0 comments on commit 5c57959

Please sign in to comment.