Skip to content

Commit

Permalink
Add UpdateCardGroupUserState
Browse files Browse the repository at this point in the history
  • Loading branch information
yasuflatland-lf committed Aug 14, 2024
1 parent b3e6f09 commit 4d055df
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 10 deletions.
7 changes: 7 additions & 0 deletions backend/graph/db/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ type Cardgroup struct {
Users []User `gorm:"many2many:cardgroup_users" validate:"-"`
}

type CardgroupUser struct {
CardGroupID int64 `gorm:"column:cardgroup_id;primaryKey" validate:"-"`
UserID int64 `gorm:"column:user_id;primaryKey" validate:"number"`
State int `gorm:"column:state" validate:"number"`
Updated time.Time `gorm:"column:updated;autoUpdateTime"`
}

type Role struct {
ID int64 `gorm:"column:id;primaryKey" validate:"number"`
Name string `gorm:"column:name;not null" validate:"required,fl_name,min=1"`
Expand Down
2 changes: 1 addition & 1 deletion backend/graph/db/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func (u *User) validateAtCreate(user *User) error {
return nil
}

// Updating data in same transaction
// AfterUpdate Updating data in same transaction
func (u *User) AfterUpdate(tx *gorm.DB) (err error) {
tx.Model(&User{}).Where("id = ?", u.ID).Update("updated", time.Now().UTC())
return nil
Expand Down
4 changes: 2 additions & 2 deletions backend/graph/services/card_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func (suite *CardTestSuite) TestCardService() {

suite.Run("Normal_CreateCard", func() {
// Arrange
createdGroup, _ := testutils.CreateUserAndCardGroup(ctx, userService, cardGroupService, roleService)
createdGroup, _, _ := testutils.CreateUserAndCardGroup(ctx, userService, cardGroupService, roleService)
input := model.NewCard{
Front: "Test Front",
Back: "Test Back",
Expand Down Expand Up @@ -206,7 +206,7 @@ func (suite *CardTestSuite) TestCardService() {

suite.Run("Normal_FetchAllCardsByCardGroup", func() {
// Arrange
createdGroup, _ := testutils.CreateUserAndCardGroup(ctx, userService, cardGroupService, roleService)
createdGroup, _, _ := testutils.CreateUserAndCardGroup(ctx, userService, cardGroupService, roleService)

// Create 200 dummy cards
for i := 0; i < 200; i++ {
Expand Down
48 changes: 46 additions & 2 deletions backend/graph/services/cardgroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ import (
"fmt"
"time"

"github.com/pkg/errors"

"github.com/m-mizutani/goerr"
"github.com/pkg/errors"
"gorm.io/gorm"
)

// cardGroupService provides methods to manage card groups in the database.
type cardGroupService struct {
db *gorm.DB
defaultLimit int
Expand All @@ -29,8 +29,15 @@ type CardGroupService interface {
GetCardGroupsByUser(ctx context.Context, userID int64) ([]*model.CardGroup, error)
PaginatedCardGroupsByUser(ctx context.Context, userID int64, first *int, after *int64, last *int, before *int64) (*model.CardGroupConnection, error)
GetCardGroupsByIDs(ctx context.Context, ids []int64) ([]*model.CardGroup, error)
UpdateCardGroupUserState(ctx context.Context, cardGroupID int64, userID int64, newState int) error
}

// NewCardGroupService creates a new CardGroupService instance.
func NewCardGroupService(db *gorm.DB, defaultLimit int) CardGroupService {
return &cardGroupService{db: db, defaultLimit: defaultLimit}
}

// convertToGormCardGroup converts a NewCardGroup input to a GORM-compatible Cardgroup model.
func convertToGormCardGroup(input model.NewCardGroup) *repository.Cardgroup {
return &repository.Cardgroup{
Name: input.Name,
Expand All @@ -39,6 +46,7 @@ func convertToGormCardGroup(input model.NewCardGroup) *repository.Cardgroup {
}
}

// convertToCardGroup converts a Cardgroup repository model to a GraphQL-compatible CardGroup model.
func convertToCardGroup(cardGroup repository.Cardgroup) *model.CardGroup {
return &model.CardGroup{
ID: cardGroup.ID,
Expand All @@ -48,6 +56,7 @@ func convertToCardGroup(cardGroup repository.Cardgroup) *model.CardGroup {
}
}

// GetCardGroupByID retrieves a card group by its ID from the database.
func (s *cardGroupService) GetCardGroupByID(ctx context.Context, id int64) (*model.CardGroup, error) {
var cardGroup repository.Cardgroup
if err := s.db.First(&cardGroup, id).Error; err != nil {
Expand All @@ -59,6 +68,7 @@ func (s *cardGroupService) GetCardGroupByID(ctx context.Context, id int64) (*mod
return convertToCardGroup(cardGroup), nil
}

// CreateCardGroup creates a new card group in the database.
func (s *cardGroupService) CreateCardGroup(ctx context.Context, input model.NewCardGroup) (*model.CardGroup, error) {
gormCardGroup := convertToGormCardGroup(input)
result := s.db.WithContext(ctx).Create(&gormCardGroup)
Expand All @@ -68,6 +78,7 @@ func (s *cardGroupService) CreateCardGroup(ctx context.Context, input model.NewC
return convertToCardGroup(*gormCardGroup), nil
}

// CardGroups retrieves all card groups from the database.
func (s *cardGroupService) CardGroups(ctx context.Context) ([]*model.CardGroup, error) {
var cardGroups []repository.Cardgroup
if err := s.db.WithContext(ctx).Find(&cardGroups).Error; err != nil {
Expand All @@ -80,6 +91,7 @@ func (s *cardGroupService) CardGroups(ctx context.Context) ([]*model.CardGroup,
return gqlCardGroups, nil
}

// UpdateCardGroup updates a card group in the database by its ID.
func (s *cardGroupService) UpdateCardGroup(ctx context.Context, id int64, input model.NewCardGroup) (*model.CardGroup, error) {
var cardGroup repository.Cardgroup
if err := s.db.WithContext(ctx).First(&cardGroup, id).Error; err != nil {
Expand All @@ -93,6 +105,7 @@ func (s *cardGroupService) UpdateCardGroup(ctx context.Context, id int64, input
return convertToCardGroup(cardGroup), nil
}

// DeleteCardGroup deletes a card group from the database by its ID.
func (s *cardGroupService) DeleteCardGroup(ctx context.Context, id int64) (*bool, error) {
success := false
result := s.db.WithContext(ctx).Delete(&repository.Cardgroup{}, id)
Expand All @@ -106,6 +119,7 @@ func (s *cardGroupService) DeleteCardGroup(ctx context.Context, id int64) (*bool
return &success, nil
}

// AddUserToCardGroup adds a user to a card group in the database.
func (s *cardGroupService) AddUserToCardGroup(ctx context.Context, userID int64, cardGroupID int64) (*model.CardGroup, error) {
var user repository.User
var cardGroup repository.Cardgroup
Expand All @@ -121,6 +135,7 @@ func (s *cardGroupService) AddUserToCardGroup(ctx context.Context, userID int64,
return convertToCardGroup(cardGroup), nil
}

// RemoveUserFromCardGroup removes a user from a card group in the database.
func (s *cardGroupService) RemoveUserFromCardGroup(ctx context.Context, userID int64, cardGroupID int64) (*model.CardGroup, error) {
var user repository.User
var cardGroup repository.Cardgroup
Expand All @@ -136,6 +151,7 @@ func (s *cardGroupService) RemoveUserFromCardGroup(ctx context.Context, userID i
return convertToCardGroup(cardGroup), nil
}

// GetCardGroupsByUser retrieves all card groups associated with a specific user from the database.
func (s *cardGroupService) GetCardGroupsByUser(ctx context.Context, userID int64) ([]*model.CardGroup, error) {
var user repository.User
if err := s.db.WithContext(ctx).Preload("CardGroups").First(&user, userID).Error; err != nil {
Expand All @@ -148,6 +164,7 @@ func (s *cardGroupService) GetCardGroupsByUser(ctx context.Context, userID int64
return gqlCardGroups, nil
}

// PaginatedCardGroupsByUser retrieves a paginated list of card groups associated with a specific user.
func (s *cardGroupService) PaginatedCardGroupsByUser(ctx context.Context, userID int64, first *int, after *int64, last *int, before *int64) (*model.CardGroupConnection, error) {
var user repository.User
var cardGroups []repository.Cardgroup
Expand Down Expand Up @@ -204,6 +221,7 @@ func (s *cardGroupService) PaginatedCardGroupsByUser(ctx context.Context, userID
}, nil
}

// GetCardGroupsByIDs retrieves card groups by their IDs from the database.
func (s *cardGroupService) GetCardGroupsByIDs(ctx context.Context, ids []int64) ([]*model.CardGroup, error) {
var cardGroups []*repository.Cardgroup
if err := s.db.WithContext(ctx).Where("id IN ?", ids).Find(&cardGroups).Error; err != nil {
Expand All @@ -217,3 +235,29 @@ func (s *cardGroupService) GetCardGroupsByIDs(ctx context.Context, ids []int64)

return gqlCardGroups, nil
}

// UpdateCardGroupUserState updates the state of a user in a specific card group in the database.
func (s *cardGroupService) UpdateCardGroupUserState(ctx context.Context, cardGroupID int64, userID int64, newState int) error {
// Initialize the structure with the IDs and the new state
cardGroupUser := repository.CardgroupUser{
CardGroupID: cardGroupID,
UserID: userID,
State: newState,
Updated: time.Now().UTC(),
}

// Perform the update using Gorm
result := s.db.WithContext(ctx).
Model(&repository.CardgroupUser{}).
Where("cardgroup_id = ? AND user_id = ?", cardGroupID, userID).
Updates(map[string]interface{}{
"state": cardGroupUser.State,
"updated": cardGroupUser.Updated,
})

if result.Error != nil {
return goerr.Wrap(result.Error)
}

return nil
}
28 changes: 28 additions & 0 deletions backend/graph/services/cardgroup_test.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package services_test

import (
"backend/graph/db"
"backend/graph/model"
"backend/graph/services"
"backend/testutils"
"context"
"github.com/labstack/gommon/log"
"github.com/m-mizutani/goerr"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
"gorm.io/gorm"
Expand Down Expand Up @@ -272,6 +274,32 @@ func (suite *CardGroupTestSuite) TestCardGroupService() {
assert.Error(t, err)
assert.Nil(t, group)
})

suite.Run("Normal_CardGroupUserState", func() {
userService := services.NewUserService(suite.db, 20)
cardGroupService := services.NewCardGroupService(suite.db, 20)
roleService := services.NewRoleService(suite.db, 20)

ctx := context.Background()
cardGroup, user, _ := testutils.CreateUserAndCardGroup(ctx, userService, cardGroupService, roleService)

// Perform the UpdateCardGroupUserState operation
newState := 3
err := cardGroupService.UpdateCardGroupUserState(context.Background(), cardGroup.ID, user.ID, newState)
if err != nil {
t.Errorf("UpdateCardGroupUserState() error = %+v", goerr.Wrap(err))
}

// Verify the update
var cardGroupUser db.CardgroupUser
if err := suite.db.Where("cardgroup_id = ? AND user_id = ?", cardGroup.ID, user.ID).First(&cardGroupUser).Error; err != nil {
t.Fatalf("failed to retrieve updated record: %+v", goerr.Wrap(err))
}

if cardGroupUser.State != newState {
t.Errorf("expected state to be %d, got %d", newState, cardGroupUser.State)
}
})
}

func TestCardGroupTestSuite(t *testing.T) {
Expand Down
20 changes: 15 additions & 5 deletions backend/testutils/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func SetupTestDB(ctx context.Context, user, password, dbName string) (repository
pg := repository.NewPostgres(config)
if err = pg.Open(); err != nil {
pgContainer.Terminate(ctx)
return nil, nil, goerr.Wrap(err, "failed to open database")
return nil, nil, goerr.Wrap(err, "failed to open database: %w", err)
}

cleanup := func(migrationFilePath string) {
Expand Down Expand Up @@ -117,15 +117,15 @@ func CreateUserAndCardGroup(
ctx context.Context,
userService services.UserService,
cardGroupService services.CardGroupService,
roleService services.RoleService) (*model.CardGroup, error) {
roleService services.RoleService) (*model.CardGroup, *model.User, error) {

// Create a role
newRole := model.NewRole{
Name: "Test Role",
}
createdRole, err := roleService.CreateRole(ctx, newRole)
if err != nil {
return nil, err
return nil, nil, err
}

// Create a user
Expand All @@ -137,7 +137,7 @@ func CreateUserAndCardGroup(
}
createdUser, err := userService.CreateUser(ctx, newUser)
if err != nil {
return nil, err
return nil, nil, err
}

// Create a card group
Expand All @@ -148,5 +148,15 @@ func CreateUserAndCardGroup(
UserIds: []int64{createdUser.ID},
}

return cardGroupService.CreateCardGroup(ctx, input)
createdCardGroup, err := cardGroupService.CreateCardGroup(ctx, input)
if err != nil {
return nil, nil, err
}

_, err = cardGroupService.AddUserToCardGroup(ctx, createdCardGroup.ID, createdUser.ID)
if err != nil {
return nil, nil, err
}

return createdCardGroup, createdUser, nil
}

0 comments on commit 4d055df

Please sign in to comment.