diff --git a/docs/swagger/traPortfolio.v1.yaml b/docs/swagger/traPortfolio.v1.yaml index e035e318..a66cebdc 100644 --- a/docs/swagger/traPortfolio.v1.yaml +++ b/docs/swagger/traPortfolio.v1.yaml @@ -1121,7 +1121,7 @@ components: type: array description: コンテストチーム items: - $ref: "#/components/schemas/ContestTeam" + $ref: "#/components/schemas/ContestTeamWithoutMembers" required: - teams ContestDetail: @@ -1148,10 +1148,10 @@ components: - link - description - teams - ContestTeam: - title: ContestTeam + ContestTeamWithoutMembers: + title: ContestTeamWithoutMembers type: object - description: コンテストチーム情報 + description: コンテストチーム情報(チームメンバーなし) properties: id: type: string @@ -1168,6 +1168,21 @@ components: - id - name - result + ContestTeam: + title: ContestTeam + type: object + description: コンテストチーム情報 + allOf: + - $ref: "#/components/schemas/ContestTeamWithoutMembers" + - type: object + properties: + members: + type: array + description: チームメンバーのユーザー情報 + items: + $ref: '#/components/schemas/User' + required: + - members ContestTeamDetail: title: ContestTeamDetail type: object @@ -1191,7 +1206,6 @@ components: required: - link - description - - members PrPermitted: title: PrPermitted type: boolean diff --git a/domain/contest.go b/domain/contest.go index 8d84c79f..00d017ca 100644 --- a/domain/contest.go +++ b/domain/contest.go @@ -20,16 +20,20 @@ type ContestDetail struct { ContestTeams []*ContestTeam } -type ContestTeam struct { +type ContestTeamWithoutMembers struct { ID uuid.UUID ContestID uuid.UUID Name string Result string } +type ContestTeam struct { + ContestTeamWithoutMembers + Members []*User +} + type ContestTeamDetail struct { ContestTeam Link string Description string - Members []*User } diff --git a/domain/user.go b/domain/user.go index d4e5f229..a3c6361a 100644 --- a/domain/user.go +++ b/domain/user.go @@ -66,7 +66,7 @@ type UserContest struct { Name string // コンテスト名 TimeStart time.Time TimeEnd time.Time - Teams []*ContestTeam // ユーザーが所属するチームのリスト + Teams []*ContestTeamWithoutMembers // ユーザーが所属するチームのリスト } type UserGroup struct { diff --git a/integration_tests/repository/user_test.go b/integration_tests/repository/user_test.go index 7f43bb61..744a5f2b 100644 --- a/integration_tests/repository/user_test.go +++ b/integration_tests/repository/user_test.go @@ -545,14 +545,16 @@ func TestUserRepository_GetContests(t *testing.T) { mustAddContestTeamMembers(t, contestRepo, team2.ID, []uuid.UUID{user1.ID}) expected1 := []*domain.UserContest{ - newUserContest(t, &contest1.Contest, []*domain.ContestTeam{&team1.ContestTeam}), - newUserContest(t, &contest2.Contest, []*domain.ContestTeam{&team2.ContestTeam}), + newUserContest(t, &contest1.Contest, []*domain.ContestTeamWithoutMembers{&team1.ContestTeam.ContestTeamWithoutMembers}), + newUserContest(t, &contest2.Contest, []*domain.ContestTeamWithoutMembers{&team2.ContestTeam.ContestTeamWithoutMembers}), } contests1, err := userRepo.GetContests(context.Background(), user1.ID) assert.NoError(t, err) assert.ElementsMatch(t, expected1, contests1) - expected2 := []*domain.UserContest{newUserContest(t, &contest1.Contest, []*domain.ContestTeam{&team1.ContestTeam})} + expected2 := []*domain.UserContest{ + newUserContest(t, &contest1.Contest, []*domain.ContestTeamWithoutMembers{&team1.ContestTeam.ContestTeamWithoutMembers}), + } contests2, err := userRepo.GetContests(context.Background(), user2.ID) assert.NoError(t, err) assert.ElementsMatch(t, expected2, contests2) @@ -580,8 +582,7 @@ func newUserProject(t *testing.T, args *urepository.CreateProjectMemberArgs, pro } } -func newUserContest(t *testing.T, contest *domain.Contest, teams []*domain.ContestTeam) *domain.UserContest { - t.Helper() +func newUserContest(t *testing.T, contest *domain.Contest, teams []*domain.ContestTeamWithoutMembers) *domain.UserContest { return &domain.UserContest{ ID: contest.ID, Name: contest.Name, diff --git a/interfaces/handler/contest.go b/interfaces/handler/contest.go index c2c8fb07..73f400a1 100644 --- a/interfaces/handler/contest.go +++ b/interfaces/handler/contest.go @@ -55,7 +55,11 @@ func (h *ContestHandler) GetContest(c echo.Context) error { teams := make([]schema.ContestTeam, len(contest.ContestTeams)) for i, v := range contest.ContestTeams { - teams[i] = newContestTeam(v.ID, v.Name, v.Result) + members := make([]schema.User, len(v.Members)) + for j, ct := range v.Members { + members[j] = newUser(ct.ID, ct.Name, ct.RealName()) + } + teams[i] = newContestTeam(v.ID, v.Name, v.Result, members) } res := newContestDetail( @@ -89,11 +93,7 @@ func (h *ContestHandler) CreateContest(c echo.Context) error { return err } - contestTeams := make([]schema.ContestTeam, 0, len(contest.ContestTeams)) - for _, team := range contest.ContestTeams { - contestTeams = append(contestTeams, newContestTeam(team.ID, team.Name, team.Result)) - } - res := newContestDetail(newContest(contest.ID, contest.Name, contest.TimeStart, contest.TimeEnd), contest.Link, contest.Description, contestTeams) + res := newContestDetail(newContest(contest.ID, contest.Name, contest.TimeStart, contest.TimeEnd), contest.Link, contest.Description, []schema.ContestTeam{}) return c.JSON(http.StatusCreated, res) } @@ -159,7 +159,11 @@ func (h *ContestHandler) GetContestTeams(c echo.Context) error { res := make([]schema.ContestTeam, len(contestTeams)) for i, v := range contestTeams { - res[i] = newContestTeam(v.ID, v.Name, v.Result) + members := make([]schema.User, len(v.Members)) + for j, ct := range v.Members { + members[j] = newUser(ct.ID, ct.Name, ct.RealName()) + } + res[i] = newContestTeam(v.ID, v.Name, v.Result, members) } return c.JSON(http.StatusOK, res) @@ -189,10 +193,9 @@ func (h *ContestHandler) GetContestTeam(c echo.Context) error { } res := newContestTeamDetail( - newContestTeam(contestTeam.ID, contestTeam.Name, contestTeam.Result), + newContestTeam(contestTeam.ID, contestTeam.Name, contestTeam.Result, members), contestTeam.Link, contestTeam.Description, - members, ) return c.JSON(http.StatusOK, res) @@ -223,7 +226,7 @@ func (h *ContestHandler) AddContestTeam(c echo.Context) error { return err } - res := newContestTeam(contestTeam.ID, contestTeam.Name, contestTeam.Result) + res := newContestTeam(contestTeam.ID, contestTeam.Name, contestTeam.Result, []schema.User{}) return c.JSON(http.StatusCreated, res) } @@ -384,20 +387,29 @@ func newContestDetail(contest schema.Contest, link string, description string, t } } -func newContestTeam(id uuid.UUID, name string, result string) schema.ContestTeam { +func newContestTeam(id uuid.UUID, name string, result string, members []schema.User) schema.ContestTeam { return schema.ContestTeam{ + Id: id, + Name: name, + Result: result, + Members: members, + } +} + +func newContestTeamWithoutMembers(id uuid.UUID, name string, result string) schema.ContestTeamWithoutMembers { + return schema.ContestTeamWithoutMembers{ Id: id, Name: name, Result: result, } } -func newContestTeamDetail(team schema.ContestTeam, link string, description string, members []schema.User) schema.ContestTeamDetail { +func newContestTeamDetail(team schema.ContestTeam, link string, description string) schema.ContestTeamDetail { return schema.ContestTeamDetail{ Description: description, Id: team.Id, Link: link, - Members: members, + Members: team.Members, Name: team.Name, Result: team.Result, } diff --git a/interfaces/handler/contest_test.go b/interfaces/handler/contest_test.go index 3f778dc6..f7016368 100644 --- a/interfaces/handler/contest_test.go +++ b/interfaces/handler/contest_test.go @@ -124,26 +124,47 @@ func makeContest(t *testing.T) (*domain.ContestDetail, *schema.ContestDetail) { Description: random.AlphaNumeric(), ContestTeams: []*domain.ContestTeam{ { - ID: getContestID[1], - ContestID: getContestID[0], - Name: random.AlphaNumeric(), - Result: random.AlphaNumeric(), + ContestTeamWithoutMembers: domain.ContestTeamWithoutMembers{ + ID: getContestID[1], + ContestID: getContestID[0], + Name: random.AlphaNumeric(), + Result: random.AlphaNumeric(), + }, + Members: []*domain.User{ + domain.NewUser(random.UUID(), random.AlphaNumeric(), random.AlphaNumeric(), random.Bool()), + domain.NewUser(random.UUID(), random.AlphaNumeric(), random.AlphaNumeric(), random.Bool()), + }, }, { - ID: getContestID[2], - ContestID: getContestID[0], - Name: random.AlphaNumeric(), - Result: random.AlphaNumeric(), + ContestTeamWithoutMembers: domain.ContestTeamWithoutMembers{ + ID: getContestID[2], + ContestID: getContestID[0], + Name: random.AlphaNumeric(), + Result: random.AlphaNumeric(), + }, + Members: []*domain.User{ + domain.NewUser(random.UUID(), random.AlphaNumeric(), random.AlphaNumeric(), random.Bool()), + domain.NewUser(random.UUID(), random.AlphaNumeric(), random.AlphaNumeric(), random.Bool()), + }, }, }, } teams := make([]schema.ContestTeam, len(d.ContestTeams)) for i, v := range d.ContestTeams { + member := make([]schema.User, len(v.Members)) + for j, w := range v.Members { + member[j] = schema.User{ + Id: w.ID, + Name: w.Name, + RealName: w.RealName(), + } + } teams[i] = schema.ContestTeam{ - Id: v.ID, - Name: v.Name, - Result: v.Result, + Id: v.ID, + Members: member, + Name: v.Name, + Result: v.Result, } } @@ -511,26 +532,46 @@ func TestContestHandler_GetContestTeams(t *testing.T) { contestID := random.UUID() repoContestTeams := []*domain.ContestTeam{ { - ID: random.UUID(), - ContestID: contestID, - Name: random.AlphaNumeric(), - Result: random.AlphaNumeric(), + ContestTeamWithoutMembers: domain.ContestTeamWithoutMembers{ + ID: random.UUID(), + ContestID: contestID, + Name: random.AlphaNumeric(), + Result: random.AlphaNumeric(), + }, + Members: []*domain.User{ + domain.NewUser(random.UUID(), random.AlphaNumeric(), random.AlphaNumeric(), random.Bool()), + domain.NewUser(random.UUID(), random.AlphaNumeric(), random.AlphaNumeric(), random.Bool()), + }, }, { - ID: random.UUID(), - ContestID: contestID, - Name: random.AlphaNumeric(), - Result: random.AlphaNumeric(), + ContestTeamWithoutMembers: domain.ContestTeamWithoutMembers{ + ID: random.UUID(), + ContestID: contestID, + Name: random.AlphaNumeric(), + Result: random.AlphaNumeric(), + }, + Members: []*domain.User{ + domain.NewUser(random.UUID(), random.AlphaNumeric(), random.AlphaNumeric(), random.Bool()), + domain.NewUser(random.UUID(), random.AlphaNumeric(), random.AlphaNumeric(), random.Bool()), + }, }, } hres = []*schema.ContestTeam{ { - Id: repoContestTeams[0].ID, + Id: repoContestTeams[0].ID, + Members: []schema.User{ + {Id: repoContestTeams[0].Members[0].ID, Name: repoContestTeams[0].Members[0].Name, RealName: repoContestTeams[0].Members[0].RealName()}, + {Id: repoContestTeams[0].Members[1].ID, Name: repoContestTeams[0].Members[1].Name, RealName: repoContestTeams[0].Members[1].RealName()}, + }, Name: repoContestTeams[0].Name, Result: repoContestTeams[0].Result, }, { - Id: repoContestTeams[1].ID, + Id: repoContestTeams[1].ID, + Members: []schema.User{ + {Id: repoContestTeams[1].Members[0].ID, Name: repoContestTeams[1].Members[0].Name, RealName: repoContestTeams[1].Members[0].RealName()}, + {Id: repoContestTeams[1].Members[1].ID, Name: repoContestTeams[1].Members[1].Name, RealName: repoContestTeams[1].Members[1].RealName()}, + }, Name: repoContestTeams[1].Name, Result: repoContestTeams[1].Result, }, @@ -580,17 +621,19 @@ func TestContestHandler_GetContestTeam(t *testing.T) { contestID := random.UUID() repoContestTeamDetail := domain.ContestTeamDetail{ ContestTeam: domain.ContestTeam{ - ID: teamID, - ContestID: contestID, - Name: random.AlphaNumeric(), - Result: random.AlphaNumeric(), + ContestTeamWithoutMembers: domain.ContestTeamWithoutMembers{ + ID: teamID, + ContestID: contestID, + Name: random.AlphaNumeric(), + Result: random.AlphaNumeric(), + }, + Members: []*domain.User{ + domain.NewUser(random.UUID(), random.AlphaNumeric(), random.AlphaNumeric(), random.Bool()), + domain.NewUser(random.UUID(), random.AlphaNumeric(), random.AlphaNumeric(), random.Bool()), + }, }, Link: random.AlphaNumeric(), Description: random.AlphaNumeric(), - Members: []*domain.User{ - domain.NewUser(random.UUID(), random.AlphaNumeric(), random.AlphaNumeric(), random.Bool()), - domain.NewUser(random.UUID(), random.AlphaNumeric(), random.AlphaNumeric(), random.Bool()), - }, } members := make([]schema.User, 0, len(repoContestTeamDetail.Members)) for _, member := range repoContestTeamDetail.Members { @@ -684,19 +727,22 @@ func TestContestHandler_AddContestTeam(t *testing.T) { } want := domain.ContestTeamDetail{ ContestTeam: domain.ContestTeam{ - ID: teamID, - ContestID: contestID, - Name: args.Name, - Result: args.Result.ValueOrZero(), + ContestTeamWithoutMembers: domain.ContestTeamWithoutMembers{ + ID: teamID, + ContestID: contestID, + Name: args.Name, + Result: args.Result.ValueOrZero(), + }, + Members: make([]*domain.User, 0), }, Link: args.Link.ValueOrZero(), Description: args.Description, - Members: nil, } expectedResBody := schema.ContestTeam{ - Id: teamID, - Name: want.Name, - Result: want.Result, + Id: teamID, + Members: make([]schema.User, 0), + Name: want.Name, + Result: want.Result, } s.EXPECT().CreateContestTeam(anyCtx{}, contestID, &args).Return(&want, nil) return reqBody, expectedResBody, fmt.Sprintf("/api/v1/contests/%s/teams", contestID) diff --git a/interfaces/handler/schema/schema_gen.go b/interfaces/handler/schema/schema_gen.go index 7c233350..df0ab85b 100644 --- a/interfaces/handler/schema/schema_gen.go +++ b/interfaces/handler/schema/schema_gen.go @@ -111,11 +111,14 @@ type ContestDetail struct { Teams []ContestTeam `json:"teams"` } -// ContestTeam コンテストチーム情報 +// ContestTeam defines model for ContestTeam. type ContestTeam struct { // Id コンテストチームuuid Id uuid.UUID `json:"id"` + // Members チームメンバーのユーザー情報 + Members []User `json:"members"` + // Name チーム名 Name string `json:"name"` @@ -144,6 +147,18 @@ type ContestTeamDetail struct { Result string `json:"result"` } +// ContestTeamWithoutMembers コンテストチーム情報(チームメンバーなし) +type ContestTeamWithoutMembers struct { + // Id コンテストチームuuid + Id uuid.UUID `json:"id"` + + // Name チーム名 + Name string `json:"name"` + + // Result 順位などの結果 + Result string `json:"result"` +} + // CreateContestRequest 新規コンテストリクエスト type CreateContestRequest struct { // Description コンテスト説明 @@ -466,7 +481,7 @@ type UserContest struct { Name string `json:"name"` // Teams コンテストチーム - Teams []ContestTeam `json:"teams"` + Teams []ContestTeamWithoutMembers `json:"teams"` } // UserDetail defines model for UserDetail. diff --git a/interfaces/handler/user.go b/interfaces/handler/user.go index 6c544453..2d560349 100644 --- a/interfaces/handler/user.go +++ b/interfaces/handler/user.go @@ -262,9 +262,9 @@ func (h *UserHandler) GetUserContests(c echo.Context) error { res := make([]schema.UserContest, len(contests)) for i, c := range contests { - teams := make([]schema.ContestTeam, len(c.Teams)) + teams := make([]schema.ContestTeamWithoutMembers, len(c.Teams)) for j, ct := range c.Teams { - teams[j] = newContestTeam(ct.ID, ct.Name, ct.Result) + teams[j] = newContestTeamWithoutMembers(ct.ID, ct.Name, ct.Result) } res[i] = newUserContest( newContest(c.ID, c.Name, c.TimeStart, c.TimeEnd), @@ -357,7 +357,7 @@ func newUserProject(id uuid.UUID, name string, duration schema.YearWithSemesterD } } -func newUserContest(contest schema.Contest, teams []schema.ContestTeam) schema.UserContest { +func newUserContest(contest schema.Contest, teams []schema.ContestTeamWithoutMembers) schema.UserContest { return schema.UserContest{ Id: contest.Id, Name: contest.Name, diff --git a/interfaces/handler/user_test.go b/interfaces/handler/user_test.go index 9770ab43..20004095 100644 --- a/interfaces/handler/user_test.go +++ b/interfaces/handler/user_test.go @@ -1189,7 +1189,7 @@ func TestUserHandler_GetUserContests(t *testing.T) { Name: random.AlphaNumeric(), TimeStart: random.Time(), TimeEnd: random.Time(), - Teams: []*domain.ContestTeam{ + Teams: []*domain.ContestTeamWithoutMembers{ { ID: random.UUID(), ContestID: random.UUID(), @@ -1201,8 +1201,8 @@ func TestUserHandler_GetUserContests(t *testing.T) { hcontest := newUserContest( newContest(rcontest.ID, rcontest.Name, rcontest.TimeStart, rcontest.TimeEnd), - []schema.ContestTeam{ - newContestTeam(rcontest.Teams[0].ID, rcontest.Teams[0].Name, rcontest.Teams[0].Result), + []schema.ContestTeamWithoutMembers{ + newContestTeamWithoutMembers(rcontest.Teams[0].ID, rcontest.Teams[0].Name, rcontest.Teams[0].Result), }, ) diff --git a/interfaces/repository/contest_impl.go b/interfaces/repository/contest_impl.go index c5b10c1e..a9f0162a 100644 --- a/interfaces/repository/contest_impl.go +++ b/interfaces/repository/contest_impl.go @@ -178,6 +178,7 @@ func (r *ContestRepository) DeleteContest(ctx context.Context, contestID uuid.UU } func (r *ContestRepository) GetContestTeams(ctx context.Context, contestID uuid.UUID) ([]*domain.ContestTeam, error) { + //IDがcontestIDであるようなcontestが存在するかチェック if err := r.h. WithContext(ctx). Where(&model.Contest{ID: contestID}). @@ -186,6 +187,7 @@ func (r *ContestRepository) GetContestTeams(ctx context.Context, contestID uuid. return nil, err } + //ContestIDがcontestIDであるようなcontestTeamを10件まで列挙する teams := make([]*model.ContestTeam, 10) err := r.h. WithContext(ctx). @@ -195,15 +197,58 @@ func (r *ContestRepository) GetContestTeams(ctx context.Context, contestID uuid. if err != nil { return nil, err } + + //teamsの要素vについてTeamIDがv.IDである(TeamIDがteamsIDListに入っているID)ようなContestTeamUserBelongingを列挙する + var teamsIDList = make([]uuid.UUID, len(teams)) + for i, v := range teams { + teamsIDList[i] = v.ID + } + + var belongings = []*model.ContestTeamUserBelonging{} + err = r.h. + WithContext(ctx). + Preload("User"). + Where("team_id IN (?)", teamsIDList). + Find(&belongings). + Error() + + if err != nil { + return nil, err + } + + belongingMap := make(map[uuid.UUID]([]*model.ContestTeamUserBelonging)) + for _, v := range belongings { + belongingMap[v.TeamID] = append(belongingMap[v.TeamID], v) + } + + nameMap, err := r.makeUserNameMap() + if err != nil { + return nil, err + } + result := make([]*domain.ContestTeam, 0, len(teams)) for _, v := range teams { + members := make([]*domain.User, len(belongingMap[v.ID])) + for i, w := range belongingMap[v.ID] { + u := w.User + members[i] = domain.NewUser(u.ID, u.Name, nameMap[u.Name], u.Check) + } + result = append(result, &domain.ContestTeam{ - ID: v.ID, - ContestID: v.ContestID, - Name: v.Name, - Result: v.Result, + ContestTeamWithoutMembers: domain.ContestTeamWithoutMembers{ + ID: v.ID, + ContestID: v.ContestID, + Name: v.Name, + Result: v.Result, + }, + Members: members, }) } + + // if len(result) == 0 { + // result = []*domain.ContestTeam{} + // } + return result, nil } @@ -218,16 +263,40 @@ func (r *ContestRepository) GetContestTeam(ctx context.Context, contestID uuid.U return nil, err } + var belongings []*model.ContestTeamUserBelonging + err := r.h. + WithContext(ctx). + Preload("User"). + Where(&model.ContestTeamUserBelonging{TeamID: teamID}). + Find(&belongings). + Error() + if err != nil { + return nil, err + } + + nameMap, err := r.makeUserNameMap() + if err != nil { + return nil, err + } + + members := make([]*domain.User, len(belongings)) + for i, w := range belongings { + u := w.User + members[i] = domain.NewUser(u.ID, u.Name, nameMap[u.Name], u.Check) + } + res := &domain.ContestTeamDetail{ ContestTeam: domain.ContestTeam{ - ID: team.ID, - ContestID: team.ContestID, - Name: team.Name, - Result: team.Result, + ContestTeamWithoutMembers: domain.ContestTeamWithoutMembers{ + ID: team.ID, + ContestID: team.ContestID, + Name: team.Name, + Result: team.Result, + }, + Members: members, }, Link: team.Link, Description: team.Description, - // Members: } return res, nil } @@ -257,14 +326,16 @@ func (r *ContestRepository) CreateContestTeam(ctx context.Context, contestID uui result := &domain.ContestTeamDetail{ ContestTeam: domain.ContestTeam{ - ID: contestTeam.ID, - ContestID: contestTeam.ContestID, - Name: contestTeam.Name, - Result: contestTeam.Result, + ContestTeamWithoutMembers: domain.ContestTeamWithoutMembers{ + ID: contestTeam.ID, + ContestID: contestTeam.ContestID, + Name: contestTeam.Name, + Result: contestTeam.Result, + }, + Members: make([]*domain.User, 0), }, Link: contestTeam.Link, Description: contestTeam.Description, - Members: nil, } return result, nil } diff --git a/interfaces/repository/contest_impl_test.go b/interfaces/repository/contest_impl_test.go index 2d1d4667..b9b339e4 100644 --- a/interfaces/repository/contest_impl_test.go +++ b/interfaces/repository/contest_impl_test.go @@ -540,10 +540,16 @@ func TestContestRepository_GetContestTeams(t *testing.T) { }, want: []*domain.ContestTeam{ { - ID: random.UUID(), - ContestID: cid, - Name: random.AlphaNumeric(), - Result: random.AlphaNumeric(), + ContestTeamWithoutMembers: domain.ContestTeamWithoutMembers{ + ID: random.UUID(), + ContestID: cid, + Name: random.AlphaNumeric(), + Result: random.AlphaNumeric(), + }, + Members: []*domain.User{ + domain.NewUser(random.UUID(), random.AlphaNumeric(), random.AlphaNumeric(), true), + domain.NewUser(random.UUID(), random.AlphaNumeric(), random.AlphaNumeric(), true), + }, }, }, setup: func(f mockContestRepositoryFields, args args, want []*domain.ContestTeam) { @@ -559,6 +565,33 @@ func TestContestRepository_GetContestTeams(t *testing.T) { ExpectQuery(makeSQLQueryRegexp("SELECT * FROM `contest_teams` WHERE `contest_teams`.`contest_id` = ?")). WithArgs(args.contestID). WillReturnRows(rows) + + teamsIDList := make([]driver.Value, len(want)) + teamRows := sqlmock.NewRows([]string{"team_id", "user_id"}) + for i, u := range want { + teamsIDList[i] = u.ID + for _, w := range u.Members { + teamRows.AddRow(u.ID, w.ID) + } + } + + f.h.Mock. + ExpectQuery(makeSQLQueryRegexp("SELECT * FROM `contest_team_user_belongings` WHERE team_id IN (?)")). + WithArgs(teamsIDList...). + WillReturnRows(teamRows) + + userIDs := make([]driver.Value, len(want[0].Members)) + userRows := sqlmock.NewRows([]string{"id", "name", "check"}) + for i, u := range want[0].Members { + userIDs[i] = u.ID + userRows.AddRow(u.ID, u.Name, u.Check) + } + f.h.Mock. + ExpectQuery(makeSQLQueryRegexp("SELECT * FROM `users` WHERE `users`.`id` IN (?,?)")). + WithArgs(userIDs...). + WillReturnRows(userRows) + + f.portal.EXPECT().GetUsers().Return(makePortalUsers(t, want[0].Members), nil) }, assertion: assert.NoError, }, @@ -636,16 +669,22 @@ func TestContestRepository_GetContestTeam(t *testing.T) { }, want: &domain.ContestTeamDetail{ ContestTeam: domain.ContestTeam{ - ID: tid, - ContestID: cid, - Name: random.AlphaNumeric(), - Result: random.AlphaNumeric(), + ContestTeamWithoutMembers: domain.ContestTeamWithoutMembers{ + ID: tid, + ContestID: cid, + Name: random.AlphaNumeric(), + Result: random.AlphaNumeric(), + }, + Members: []*domain.User{ + domain.NewUser(random.UUID(), random.AlphaNumeric(), random.AlphaNumeric(), true), + domain.NewUser(random.UUID(), random.AlphaNumeric(), random.AlphaNumeric(), true), + }, }, Link: random.RandURLString(), Description: random.AlphaNumeric(), - // Members }, setup: func(f mockContestRepositoryFields, args args, want *domain.ContestTeamDetail) { + u := want.Members[0] f.h.Mock. ExpectQuery(makeSQLQueryRegexp("SELECT * FROM `contest_teams` WHERE `contest_teams`.`id` = ? AND `contest_teams`.`contest_id` = ? ORDER BY `contest_teams`.`id` LIMIT 1")). WithArgs(args.teamID, args.contestID). @@ -653,6 +692,36 @@ func TestContestRepository_GetContestTeam(t *testing.T) { sqlmock.NewRows([]string{"id", "contest_id", "name", "result", "link", "description"}). AddRow(want.ContestTeam.ID, want.ContestTeam.ContestID, want.ContestTeam.Name, want.ContestTeam.Result, want.Link, want.Description), ) + + belongingRows := sqlmock.NewRows([]string{"team_id", "user_id"}) + for _, u := range want.Members { + belongingRows.AddRow(args.teamID, u.ID) + } + f.h.Mock. + ExpectQuery(makeSQLQueryRegexp("SELECT * FROM `contest_team_user_belongings` WHERE `contest_team_user_belongings`.`team_id` = ?")). + WithArgs(args.teamID). + WillReturnRows(belongingRows) + + userIDs := make([]driver.Value, len(want.Members)) + userRows := sqlmock.NewRows([]string{"id", "name", "check"}) + for i, u := range want.Members { + userIDs[i] = u.ID + userRows.AddRow(u.ID, u.Name, u.Check) + } + f.h.Mock. + ExpectQuery(makeSQLQueryRegexp("SELECT * FROM `users` WHERE `users`.`id` IN (?,?)")). + WithArgs(userIDs...). + WillReturnRows(userRows) + + f.h.Mock. + ExpectQuery(makeSQLQueryRegexp("SELECT * FROM `users` WHERE `users`.`id` = ?")). + WithArgs(u.ID). + WillReturnRows( + sqlmock.NewRows([]string{"id", "name", "check"}). + AddRow(u.ID, u.Name, u.Check), + ) + + f.portal.EXPECT().GetUsers().Return(makePortalUsers(t, want.Members), nil) }, assertion: assert.NoError, }, @@ -718,14 +787,16 @@ func TestContestRepository_CreateContestTeam(t *testing.T) { }, want: &domain.ContestTeamDetail{ ContestTeam: domain.ContestTeam{ - // ID: Assertion時にgot.IDと合わせる - ContestID: cid, - Name: successArgs.Name, - Result: successArgs.Result.ValueOrZero(), + ContestTeamWithoutMembers: domain.ContestTeamWithoutMembers{ + // ID: Assertion時にgot.IDと合わせる + ContestID: cid, + Name: successArgs.Name, + Result: successArgs.Result.ValueOrZero(), + }, + Members: make([]*domain.User, 0), }, Link: successArgs.Link.ValueOrZero(), Description: successArgs.Description, - Members: nil, }, setup: func(f mockContestRepositoryFields, args args, want *domain.ContestTeamDetail) { f.h.Mock. diff --git a/interfaces/repository/user_impl.go b/interfaces/repository/user_impl.go index 68e23545..b700c9b9 100644 --- a/interfaces/repository/user_impl.go +++ b/interfaces/repository/user_impl.go @@ -529,7 +529,7 @@ func (r *UserRepository) GetContests(ctx context.Context, userID uuid.UUID) ([]* Name: ct.Contest.Name, TimeStart: ct.Contest.Since, TimeEnd: ct.Contest.Until, - Teams: []*domain.ContestTeam{}, + Teams: []*domain.ContestTeamWithoutMembers{}, } } } @@ -537,7 +537,7 @@ func (r *UserRepository) GetContests(ctx context.Context, userID uuid.UUID) ([]* for _, v := range contestTeamUserBelongings { if userID == v.UserID { ct := v.ContestTeam - contestsMap[ct.ContestID].Teams = append(contestsMap[ct.ContestID].Teams, &domain.ContestTeam{ + contestsMap[ct.ContestID].Teams = append(contestsMap[ct.ContestID].Teams, &domain.ContestTeamWithoutMembers{ ID: ct.ID, ContestID: ct.ContestID, Name: ct.Name, diff --git a/interfaces/repository/user_impl_test.go b/interfaces/repository/user_impl_test.go index 9f95a466..0accb8bd 100644 --- a/interfaces/repository/user_impl_test.go +++ b/interfaces/repository/user_impl_test.go @@ -1466,7 +1466,7 @@ func TestUserRepository_GetContests(t *testing.T) { Name: random.AlphaNumeric(), TimeStart: random.Time(), TimeEnd: random.Time(), - Teams: []*domain.ContestTeam{ + Teams: []*domain.ContestTeamWithoutMembers{ { ID: random.UUID(), ContestID: cid, @@ -1518,7 +1518,7 @@ func TestUserRepository_GetContests(t *testing.T) { Name: random.AlphaNumeric(), TimeStart: random.Time(), TimeEnd: random.Time(), - Teams: []*domain.ContestTeam{ + Teams: []*domain.ContestTeamWithoutMembers{ { ID: random.UUID(), ContestID: cid, diff --git a/usecases/service/contest_test.go b/usecases/service/contest_test.go index 8f1bb750..40039b59 100644 --- a/usecases/service/contest_test.go +++ b/usecases/service/contest_test.go @@ -118,10 +118,12 @@ func TestContestService_GetContest(t *testing.T) { Description: random.AlphaNumeric(), ContestTeams: []*domain.ContestTeam{ { - ID: random.UUID(), - ContestID: cid, - Name: random.AlphaNumeric(), - Result: random.AlphaNumeric(), + ContestTeamWithoutMembers: domain.ContestTeamWithoutMembers{ + ID: random.UUID(), + ContestID: cid, + Name: random.AlphaNumeric(), + Result: random.AlphaNumeric(), + }, }, }, }, @@ -449,10 +451,12 @@ func TestContestService_GetContestTeams(t *testing.T) { }, want: []*domain.ContestTeam{ { - ID: random.UUID(), - ContestID: cid, - Name: random.AlphaNumeric(), - Result: random.AlphaNumeric(), + ContestTeamWithoutMembers: domain.ContestTeamWithoutMembers{ + ID: random.UUID(), + ContestID: cid, + Name: random.AlphaNumeric(), + Result: random.AlphaNumeric(), + }, }, }, setup: func(f fields, args args, want []*domain.ContestTeam) { @@ -524,25 +528,29 @@ func Test_contestService_GetContestTeam(t *testing.T) { }, want: &domain.ContestTeamDetail{ ContestTeam: domain.ContestTeam{ - ID: tid, - ContestID: cid, - Name: random.AlphaNumeric(), - Result: random.AlphaNumeric(), + ContestTeamWithoutMembers: domain.ContestTeamWithoutMembers{ + ID: tid, + ContestID: cid, + Name: random.AlphaNumeric(), + Result: random.AlphaNumeric(), + }, + Members: []*domain.User{ + domain.NewUser(random.UUID(), random.AlphaNumeric(), random.AlphaNumeric(), random.Bool()), + }, }, Link: random.RandURLString(), Description: random.AlphaNumeric(), - Members: []*domain.User{ - domain.NewUser(random.UUID(), random.AlphaNumeric(), random.AlphaNumeric(), random.Bool()), - }, }, setup: func(f fields, args args, want *domain.ContestTeamDetail) { repo := f.repo.(*mock_repository.MockContestRepository) repo.EXPECT().GetContestTeam(args.ctx, args.contestID, args.teamID).Return(&domain.ContestTeamDetail{ ContestTeam: domain.ContestTeam{ - ID: args.teamID, - ContestID: args.contestID, - Name: want.Name, - Result: want.Result, + ContestTeamWithoutMembers: domain.ContestTeamWithoutMembers{ + ID: args.teamID, + ContestID: args.contestID, + Name: want.Name, + Result: want.Result, + }, }, Link: want.Link, Description: want.Description, @@ -577,10 +585,12 @@ func Test_contestService_GetContestTeam(t *testing.T) { repo := f.repo.(*mock_repository.MockContestRepository) repo.EXPECT().GetContestTeam(args.ctx, args.contestID, args.teamID).Return(&domain.ContestTeamDetail{ ContestTeam: domain.ContestTeam{ - ID: args.teamID, - ContestID: args.contestID, - Name: random.AlphaNumeric(), - Result: random.AlphaNumeric(), + ContestTeamWithoutMembers: domain.ContestTeamWithoutMembers{ + ID: args.teamID, + ContestID: args.contestID, + Name: random.AlphaNumeric(), + Result: random.AlphaNumeric(), + }, }, Link: random.RandURLString(), Description: random.AlphaNumeric(), @@ -650,27 +660,31 @@ func TestContestService_CreateContestTeam(t *testing.T) { }, want: &domain.ContestTeamDetail{ ContestTeam: domain.ContestTeam{ - ID: tid, - ContestID: cid, - Name: name, - Result: result, + ContestTeamWithoutMembers: domain.ContestTeamWithoutMembers{ + ID: tid, + ContestID: cid, + Name: name, + Result: result, + }, + Members: nil, }, Link: link, Description: description, - Members: nil, }, setup: func(f fields, args args, want *domain.ContestTeamDetail) { repo := f.repo.(*mock_repository.MockContestRepository) repo.EXPECT().CreateContestTeam(args.ctx, args.contestID, args.args).Return(&domain.ContestTeamDetail{ ContestTeam: domain.ContestTeam{ - ID: tid, - ContestID: args.contestID, - Name: args.args.Name, - Result: args.args.Result.ValueOrZero(), + ContestTeamWithoutMembers: domain.ContestTeamWithoutMembers{ + ID: tid, + ContestID: args.contestID, + Name: args.args.Name, + Result: args.args.Result.ValueOrZero(), + }, + Members: nil, }, Link: args.args.Link.ValueOrZero(), Description: args.args.Description, - Members: nil, }, nil) }, assertion: assert.NoError, diff --git a/usecases/service/user_test.go b/usecases/service/user_test.go index cbef07d2..54959297 100644 --- a/usecases/service/user_test.go +++ b/usecases/service/user_test.go @@ -573,7 +573,7 @@ func TestUserService_GetUserContests(t *testing.T) { Name: random.AlphaNumeric(), TimeStart: random.Time(), TimeEnd: random.Time(), - Teams: []*domain.ContestTeam{ + Teams: []*domain.ContestTeamWithoutMembers{ { ID: random.UUID(), Name: random.AlphaNumeric(), diff --git a/util/mockdata/handler.go b/util/mockdata/handler.go index de56d8fe..2a962885 100644 --- a/util/mockdata/handler.go +++ b/util/mockdata/handler.go @@ -7,38 +7,45 @@ import ( ) var ( - HMockContestDetails = CloneHandlerMockContestDetails() - HMockContests = CloneHandlerMockContests() - HMockContestTeamsByID = CloneHandlerMockContestTeamsByID() - HMockEvents = CloneHandlerMockEvents() - HMockEventDetails = CloneHandlerMockEventDetails() - HMockGroups = CloneHandlerMockGroups() - HMockGroupMembersByID = CloneHandlerMockGroupMembersByID() - HMockProjects = CloneHandlerMockProjects() - HMockProjectDetails = CloneHandlerMockProjectDetails() - HMockProjectMembers = CloneHandlerMockProjectMembers() - HMockUsers = CloneHandlerMockUsers() - HMockUserDetails = CloneHandlerMockUserDetails() - HMockUserAccountsByID = CloneHandlerMockUserAccountsByID() - HMockUserEvents = CloneHandlerMockUserEvents() - HMockUserContestsByID = CloneHandlerMockUserContestsByID() - HMockUserGroupsByID = CloneHandlerMockUserGroupsByID() - HMockUserProjects = CloneHandlerMockUserProjects() + HMockContestDetails = CloneHandlerMockContestDetails() + HMockContests = CloneHandlerMockContests() + HMockContestTeamsByID = CloneHandlerMockContestTeamsByID() + HMockContestTeamMembersByID = CloneHandlerMockContestTeamMembersByID() + HMockEvents = CloneHandlerMockEvents() + HMockEventDetails = CloneHandlerMockEventDetails() + HMockGroups = CloneHandlerMockGroups() + HMockGroupMembersByID = CloneHandlerMockGroupMembersByID() + HMockProjects = CloneHandlerMockProjects() + HMockProjectDetails = CloneHandlerMockProjectDetails() + HMockProjectMembers = CloneHandlerMockProjectMembers() + HMockUsers = CloneHandlerMockUsers() + HMockUserDetails = CloneHandlerMockUserDetails() + HMockUserAccountsByID = CloneHandlerMockUserAccountsByID() + HMockUserEvents = CloneHandlerMockUserEvents() + HMockUserContestsByID = CloneHandlerMockUserContestsByID() + HMockUserGroupsByID = CloneHandlerMockUserGroupsByID() + HMockUserProjects = CloneHandlerMockUserProjects() ) func CloneHandlerMockContestDetails() []schema.ContestDetail { var ( - mContests = CloneMockContests() - hContestTeams = CloneMockContestTeams() - mContestTeams = make([]schema.ContestTeam, len(hContestTeams)) - hContestDetails = make([]schema.ContestDetail, len(mContests)) + mContests = CloneMockContests() + hContestTeams = CloneMockContestTeams() + hTeamMembersByID = CloneHandlerMockContestTeamMembersByID() + mContestTeams = make([]schema.ContestTeam, len(hContestTeams)) + hContestDetails = make([]schema.ContestDetail, len(mContests)) ) for i, c := range hContestTeams { + members, ok := hTeamMembersByID[c.ID] + if !ok { + members = make([]schema.User, 0) + } mContestTeams[i] = schema.ContestTeam{ - Id: c.ID, - Name: c.Name, - Result: c.Result, + Id: c.ID, + Members: members, + Name: c.Name, + Result: c.Result, } } @@ -80,19 +87,53 @@ func CloneHandlerMockContests() []schema.Contest { func CloneHandlerMockContestTeamsByID() map[uuid.UUID][]schema.ContestTeam { var ( mContestTeams = CloneMockContestTeams() + hTeamMembersByID = CloneHandlerMockContestTeamMembersByID() hContestTeamsByID = make(map[uuid.UUID][]schema.ContestTeam) ) for _, ct := range mContestTeams { + members, ok := hTeamMembersByID[ct.ID] + if !ok { + members = make([]schema.User, 0) + } hContestTeamsByID[ct.ContestID] = append(hContestTeamsByID[ct.ContestID], schema.ContestTeam{ - Id: ct.ID, - Name: ct.Name, - Result: ct.Result, + Id: ct.ID, + Members: members, + Name: ct.Name, + Result: ct.Result, }) } return hContestTeamsByID } +func CloneHandlerMockContestTeamMembersByID() map[uuid.UUID][]schema.User { + var ( + hContestTeams = CloneMockContestTeams() + mockMembersBelongings = CloneMockContestTeamUserBelongings() + mockMembers = CloneMockUsers() + portalUsers = CloneMockPortalUsers() + hContestMembers = make(map[uuid.UUID][]schema.User, len(hContestTeams)) + ) + + for _, c := range hContestTeams { + for _, ct := range mockMembersBelongings { + if c.ID == ct.TeamID { + for i, cm := range mockMembers { + if ct.UserID == cm.ID { + hContestMembers[ct.TeamID] = append(hContestMembers[c.ID], schema.User{ + Id: cm.ID, + Name: cm.Name, + RealName: portalUsers[i].RealName, + }) + } + } + } + } + } + + return hContestMembers +} + func CloneHandlerMockEvents() []schema.Event { var ( eventDetails = CloneHandlerMockEventDetails() @@ -401,11 +442,11 @@ func CloneHandlerMockUserContestsByID() map[uuid.UUID][]schema.UserContest { ) // userContestTeams[userID][contestID] = []ContestTeam - userContestTeams := make(map[uuid.UUID]map[uuid.UUID][]schema.ContestTeam, len(mUsers)) + userContestTeams := make(map[uuid.UUID]map[uuid.UUID][]schema.ContestTeamWithoutMembers, len(mUsers)) for _, u := range mUsers { - userContestTeams[u.ID] = make(map[uuid.UUID][]schema.ContestTeam, len(hContests)) + userContestTeams[u.ID] = make(map[uuid.UUID][]schema.ContestTeamWithoutMembers, len(hContests)) for _, c := range hContests { - userContestTeams[u.ID][c.Id] = []schema.ContestTeam{} + userContestTeams[u.ID][c.Id] = []schema.ContestTeamWithoutMembers{} for _, ct := range mContestTeams { if ct.ContestID != c.Id { continue @@ -416,7 +457,7 @@ func CloneHandlerMockUserContestsByID() map[uuid.UUID][]schema.UserContest { continue } - userContestTeams[u.ID][c.Id] = append(userContestTeams[u.ID][c.Id], schema.ContestTeam{ + userContestTeams[u.ID][c.Id] = append(userContestTeams[u.ID][c.Id], schema.ContestTeamWithoutMembers{ Id: ct.ID, Name: ct.Name, Result: ct.Result,