Skip to content

Commit

Permalink
add crud team test & fix error - close #31
Browse files Browse the repository at this point in the history
  • Loading branch information
IgorPolyakov committed Jul 11, 2024
1 parent 3cd0bf2 commit c30ed08
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 50 deletions.
2 changes: 1 addition & 1 deletion internal/app/db/game.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ type Game struct {

type GameDetails struct {
Game
TeamDetails []*TeamDetails
Teams []*Team
}
5 changes: 0 additions & 5 deletions internal/app/db/team.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,3 @@ type Team struct {
SocialLinks string `db:"social_links"`
AvatarUrl string `db:"avatar_url"`
}

type TeamDetails struct {
Team
Members []*User
}
53 changes: 28 additions & 25 deletions internal/app/repository/game.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

models "ctf01d/internal/app/db"

"github.com/google/uuid"
openapi_types "github.com/oapi-codegen/runtime/types"
)

Expand Down Expand Up @@ -35,12 +36,10 @@ func (r *gameRepo) Create(ctx context.Context, game *models.Game) error {

func (r *gameRepo) GetGameDetails(ctx context.Context, id openapi_types.UUID) (*models.GameDetails, error) {
query := `
SELECT g.id, g.start_time, g.end_time, g.description, t.id, t.name, t.description, u.id, u.user_name
SELECT g.id, g.start_time, g.end_time, g.description, t.id, t.name, t.description
FROM games g
JOIN team_games tg ON g.id = tg.game_id
JOIN teams t ON tg.team_id = t.id
JOIN profiles tm ON t.id = tm.current_team_id
JOIN users u ON tm.user_id = u.id
LEFT JOIN team_games tg ON g.id = tg.game_id
LEFT JOIN teams t ON tg.team_id = t.id
WHERE g.id = $1;
`
rows, err := r.db.QueryContext(ctx, query, id)
Expand All @@ -50,39 +49,43 @@ func (r *gameRepo) GetGameDetails(ctx context.Context, id openapi_types.UUID) (*
defer rows.Close()

gameDetails := &models.GameDetails{}
teams := map[openapi_types.UUID]*models.TeamDetails{}
teams := make(map[uuid.UUID]models.Team)

for rows.Next() {
var gameId openapi_types.UUID
var startTime, endTime time.Time
var description string
var teamId openapi_types.UUID
var teamName string
var teamDescription string
var userId openapi_types.UUID
var userName string
var teamId sql.NullString
var teamName sql.NullString
var teamDescription sql.NullString

err := rows.Scan(&gameId, &startTime, &endTime, &description, &teamId, &teamName, &teamDescription, &userId, &userName)
err := rows.Scan(&gameId, &startTime, &endTime, &description, &teamId, &teamName, &teamDescription)
if err != nil {
return nil, err
}

if team, ok := teams[teamId]; ok {
team.Members = append(team.Members, &models.User{Id: userId, Username: userName})
} else {
newTeam := &models.TeamDetails{
Team: models.Team{
Id: teamId,
Name: teamName,
Description: teamDescription,
},
Members: []*models.User{{Id: userId, Username: userName}},
gameDetails.Id = id
gameDetails.StartTime = startTime
gameDetails.EndTime = endTime
gameDetails.Description = description
if teamId.Valid {
teamUUID, err := uuid.Parse(teamId.String)
if err != nil {
return nil, err
}

teams[teamId] = newTeam
gameDetails.TeamDetails = append(gameDetails.TeamDetails, newTeam)
team := models.Team{
Id: teamUUID,
Name: teamName.String,
Description: teamDescription.String,
}
teams[teamUUID] = team
}
}

for _, team := range teams {
gameDetails.Teams = append(gameDetails.Teams, &team)
}

return gameDetails, nil
}

Expand Down
24 changes: 5 additions & 19 deletions internal/app/view/game.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,13 @@ type GameDetails struct {
StartTime time.Time `json:"start_time"`
EndTime time.Time `json:"end_time"`
Description string `json:"description,omitempty"`
Teams []TeamDetails `json:"team_details,omitempty"`
Teams []Teams `json:"team_details,omitempty"`
}

type TeamDetails struct {
type Teams struct {
Id openapi_types.UUID `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Members []Member `json:"members"`
}

type Member struct {
Id openapi_types.UUID `json:"id"`
UserName string `json:"user_name"`
}

func NewGameFromModel(m *db.Game) *Game {
Expand All @@ -45,20 +39,12 @@ func NewGameFromModel(m *db.Game) *Game {
}

func NewGameDetailsFromModel(m *db.GameDetails) *GameDetails {
teams := make([]TeamDetails, 0, len(m.TeamDetails))
for _, t := range m.TeamDetails {
members := make([]Member, 0, len(t.Members))
for _, u := range t.Members {
members = append(members, Member{
Id: u.Id,
UserName: u.Username,
})
}
teams = append(teams, TeamDetails{
teams := make([]Teams, 0, len(m.Teams))
for _, t := range m.Teams {
teams = append(teams, Teams{
Id: t.Id,
Name: t.Name,
Description: t.Description,
Members: members,
})
}

Expand Down
113 changes: 113 additions & 0 deletions test/server_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"net/http/httptest"
"os"
"testing"
"time"

"ctf01d/config"
"ctf01d/internal/app/database"
Expand Down Expand Up @@ -420,6 +421,118 @@ func TestTeamCRUD(t *testing.T) {
})
}

func TestGameCRUD(t *testing.T) {
r, err := NewTestRouter()
if err != nil {
t.Fatalf("failed to initialize router: %v", err)
}

var gameID string
faker := faker.New()

// 1. Создание игры
t.Run("Create Game", func(t *testing.T) {
game := map[string]interface{}{
"start_time": time.Now(),
"end_time": time.Now(),
"description": faker.Lorem().Sentence(10),
}
body, _ := json.Marshal(game)
req, _ := http.NewRequest("POST", "/api/v1/games", bytes.NewBuffer(body))
req.Header.Set("Content-Type", "application/json")
rr := httptest.NewRecorder()
r.ServeHTTP(rr, req)

if rr.Code != http.StatusOK {
t.Fatalf("expected status code 200, got %v", rr.Code)
}
})

// 2. Получение всех игр и использование ID последней
t.Run("Get All Games", func(t *testing.T) {
req, _ := http.NewRequest("GET", "/api/v1/games", nil)
rr := httptest.NewRecorder()
r.ServeHTTP(rr, req)

if rr.Code != http.StatusOK {
t.Fatalf("expected status code 200, got %v", rr.Code)
}

var games []map[string]interface{}
if err := json.Unmarshal(rr.Body.Bytes(), &games); err != nil {
t.Fatalf("could not unmarshal response: %v", err)
}

if len(games) == 0 {
t.Fatalf("expected at least one game")
}

lastGame := games[len(games)-1]
gameID = lastGame["id"].(string)
if gameID == "" {
t.Fatalf("expected game ID in response")
}
})

// 3. Получение игры по ID
t.Run("Get Game by ID", func(t *testing.T) {
req, _ := http.NewRequest("GET", "/api/v1/games/"+gameID, nil)
rr := httptest.NewRecorder()
r.ServeHTTP(rr, req)

if rr.Code != http.StatusOK {
t.Fatalf("expected status code 200, got %v", rr.Code)
}

var response map[string]interface{}
if err := json.Unmarshal(rr.Body.Bytes(), &response); err != nil {
t.Fatalf("could not unmarshal response: %v", err)
}

if response["id"] != gameID {
t.Fatalf("expected game ID %v, got %v", gameID, response["id"])
}
})

// 4. Обновление игры по ID
t.Run("Update Game by ID", func(t *testing.T) {
updatedGame := map[string]interface{}{
"start_time": time.Now(),
"end_time": time.Now(),
"description": faker.Lorem().Sentence(10),
}
body, _ := json.Marshal(updatedGame)
req, _ := http.NewRequest("PUT", "/api/v1/games/"+gameID, bytes.NewBuffer(body))
req.Header.Set("Content-Type", "application/json")
rr := httptest.NewRecorder()
r.ServeHTTP(rr, req)

if rr.Code != http.StatusOK {
t.Fatalf("expected status code 200, got %v", rr.Code)
}

var response map[string]interface{}
if err := json.Unmarshal(rr.Body.Bytes(), &response); err != nil {
t.Fatalf("could not unmarshal response: %v", err)
}

if response["data"] != "Game updated successfully" {
t.Fatalf("expected 'Game updated successfully', got %v", response["data"])
}
})

// 5. Удаление игры по ID
t.Run("Delete Game by ID", func(t *testing.T) {
req, _ := http.NewRequest("DELETE", "/api/v1/games/"+gameID, nil)
rr := httptest.NewRecorder()
r.ServeHTTP(rr, req)

if rr.Code != http.StatusOK {
t.Fatalf("expected status code 200, got %v", rr.Code)
}
})
}

func TestAPIEndpoints(t *testing.T) {
t.Skip()
doc, err := loads.Spec("../api/openapi.yaml")
Expand Down

0 comments on commit c30ed08

Please sign in to comment.