diff --git a/internal/services/repository.go b/internal/services/repository.go index 1c3d0af..8f075fd 100644 --- a/internal/services/repository.go +++ b/internal/services/repository.go @@ -24,11 +24,11 @@ func NewRepository(filepath string) (*Repository, error) { if err != nil { return nil, err } - _, err = db.Exec("CREATE TABLE IF NOT EXISTS actions (id INTEGER PRIMARY KEY AUTOINCREMENT, place TEXT, teamId INTEGER);") + _, err = db.Exec("CREATE TABLE IF NOT EXISTS actions (id INTEGER PRIMARY KEY AUTOINCREMENT, place TEXT, teamId INTEGER, FOREIGN KEY (teamId) REFERENCES teams(id) ON DELETE CASCADE);") if err != nil { return nil, err } - _, err = db.Exec("CREATE TABLE IF NOT EXISTS applications (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, teamId INTEGER, state TEXT);") + _, err = db.Exec("CREATE TABLE IF NOT EXISTS applications (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, teamId INTEGER, state TEXT, FOREIGN KEY (teamId) REFERENCES teams(id) ON DELETE CASCADE);") if err != nil { return nil, err } @@ -127,19 +127,36 @@ func (r *Repository) GetTeam(ctx context.Context, teamId any, password any) (*mo return teams[0], nil } -func (r *Repository) AddApplications(ctx context.Context, actions []*models.Action) error { - for _, action := range actions { - for _, application := range action.Applications { - _, err := r.db.Exec("insert into applications (name, teamId, state) values ($1, $2, $3)", application.Name, action.TeamID, application.State) - if err != nil { - return err - } +func (r *Repository) AddApplications(ctx context.Context, teamId int64, applications []*models.Application) error { + for _, application := range applications { + _, err := r.db.Exec("insert into applications (name, teamId, state) values ($1, $2, $3)", application.Name, teamId, application.State) + if err != nil { + return err } } return nil } -func (r *Repository) GetApplications(ctx context.Context, teamId int64, state string) ([]*models.Application, error) { +func (r *Repository) GetApplications(ctx context.Context, teamId int64) ([]*models.Application, error) { + rows, err := r.db.Query("select id, name from applications where teamId = $1", teamId) + if err != nil { + return nil, err + } + defer rows.Close() + applications := []*models.Application{} + + for rows.Next() { + item := &models.Application{} + err := rows.Scan(&item.ID, &item.Name) + if err != nil { + return nil, err + } + applications = append(applications, item) + } + return applications, nil +} + +func (r *Repository) GetApplicationsByState(ctx context.Context, teamId int64, state string) ([]*models.Application, error) { rows, err := r.db.Query("select id, name from applications where teamId = $1 and state = $2", teamId, state) if err != nil { return nil, err diff --git a/internal/services/services.go b/internal/services/services.go index 2c8df4c..dc4b7e6 100644 --- a/internal/services/services.go +++ b/internal/services/services.go @@ -78,7 +78,27 @@ func (s *Services) AddAction(ctx context.Context, req *proto.AddActionReq) (*pro if err := s.repository.AddActions(ctx, team.ID, actions); err != nil { return nil, status.Errorf(codes.Internal, err.Error()) } - if err := s.repository.AddApplications(ctx, actions); err != nil { + currentApplications, err := s.repository.GetApplications(ctx, team.ID) + if err != nil { + return nil, err + } + + newApplications := make([]*models.Application, 0, len(actions)) + for _, action := range actions { + for _, actionApplication := range action.Applications { + f := false + for _, currentApplication := range currentApplications { + if currentApplication.Name == actionApplication.Name { + f = true + } + } + if !f { + newApplications = append(newApplications, actionApplication) + } + } + } + + if err := s.repository.AddApplications(ctx, team.ID, newApplications); err != nil { return nil, status.Errorf(codes.Internal, err.Error()) } addLog(team, "add action", actions) @@ -134,11 +154,11 @@ func (s *Services) GetTeams(ctx context.Context, _ *proto.GetTeamsReq) (*proto.G return nil, err } newTeam.SpendTime = int64(len(actions)) - applications, err := s.repository.GetApplications(ctx, team.ID, "NEW") + currentApplications, err := s.repository.GetApplicationsByState(ctx, team.ID, "NEW") if err != nil { return nil, err } - newTeam.Applications = mapApplicationsToProtoApplications(applications) + newTeam.Applications = mapApplicationsToProtoApplications(currentApplications) res = append(res, newTeam) } return &proto.GetTeamsRsp{Teams: res}, err diff --git a/internal/tests/action_test.go b/internal/tests/action_test.go new file mode 100644 index 0000000..7d408ec --- /dev/null +++ b/internal/tests/action_test.go @@ -0,0 +1,33 @@ +package tests + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestGetApplication(t *testing.T) { + defer deleteTeams(t) + + client, close := getClient() + defer close() + + createTeamResp, err := createTeam(client, "Тестовая команда") + assert.Nil(t, err, "запрос отправлену спешно") + + team := createTeamResp.Teams[0] + + addAction(t, client, team.Name, team.Password, "Т-1") + + getTeamsResp, err := getTeams(client) + assert.Nil(t, err, "запрос отправлен успешно") + applications := getTeamsResp.Teams[0].Applications + assert.Equal(t, 1, len(applications), "выдать 1 приложение") + + addAction(t, client, team.Name, team.Password, "Т-1") + + getTeamsResp, err = getTeams(client) + assert.Nil(t, err, "запрос отправлен успешно") + applications = getTeamsResp.Teams[0].Applications + assert.Equal(t, 1, len(applications), "выдать 1 приложение") +} diff --git a/internal/tests/client.go b/internal/tests/client.go index 90f29d9..b3f8c21 100644 --- a/internal/tests/client.go +++ b/internal/tests/client.go @@ -2,6 +2,7 @@ package tests import ( "context" + "encoding/base64" "log" "testing" "time" @@ -12,6 +13,7 @@ import ( "github.com/stretchr/testify/assert" "google.golang.org/grpc" + "google.golang.org/grpc/metadata" ) func getClient() (pb.EveningDetectiveClient, func() error) { @@ -55,3 +57,25 @@ func getTeams(client pb.EveningDetectiveClient) (*pb.GetTeamsRsp, error) { req := &pb.GetTeamsReq{} return client.GetTeams(ctx, req) } + +func addAction( + t *testing.T, + client pb.EveningDetectiveClient, + name string, + password string, + place string, +) { + ctx, cancel := getContext() + defer cancel() + md := metadata.Pairs( + "team-id", base64.StdEncoding.EncodeToString([]byte(name)), + "password", password, + ) + ctx = metadata.NewOutgoingContext(ctx, md) + + req := &pb.AddActionReq{ + Place: place, + } + _, err := client.AddAction(ctx, req) + assert.Nil(t, err, "запрос отправлен успешно") +} diff --git a/internal/tests/teams_test.go b/internal/tests/teams_test.go index ab7cb5f..a057e2b 100644 --- a/internal/tests/teams_test.go +++ b/internal/tests/teams_test.go @@ -7,6 +7,8 @@ import ( ) func TestCreateTeam(t *testing.T) { + defer deleteTeams(t) + client, close := getClient() defer close() @@ -19,21 +21,21 @@ func TestCreateTeam(t *testing.T) { assert.Nil(t, err, "запрос отправлен успешно") assert.Equal(t, len(getTeamsResp.Teams), 1, "количество команд равно 1") assert.Equal(t, getTeamsResp.Teams[0].Name, "Тестовая команда") - - deleteTeams(t) } func TestCreateTeamWithEmptyName(t *testing.T) { + defer deleteTeams(t) + client, close := getClient() defer close() _, err := createTeam(client, "") assert.NotNil(t, err, "запрос не удался") - - deleteTeams(t) } func TestCreateTwoTeam(t *testing.T) { + defer deleteTeams(t) + client, close := getClient() defer close() @@ -48,11 +50,11 @@ func TestCreateTwoTeam(t *testing.T) { assert.Equal(t, len(getTeamsResp.Teams), 2, "количество команд равно 2") assert.Equal(t, getTeamsResp.Teams[0].Name, "Тестовая команда 1") assert.Equal(t, getTeamsResp.Teams[1].Name, "Тестовая команда 2") - - deleteTeams(t) } func TestCreateTwoEqTeam(t *testing.T) { + defer deleteTeams(t) + client, close := getClient() defer close() @@ -61,11 +63,11 @@ func TestCreateTwoEqTeam(t *testing.T) { _, err = createTeam(client, "Тестовая команда") assert.NotNil(t, err, "запрос не удался") - - deleteTeams(t) } func TestCreateTwoBadTeam(t *testing.T) { + defer deleteTeams(t) + client, close := getClient() defer close() @@ -74,6 +76,4 @@ func TestCreateTwoBadTeam(t *testing.T) { _, err = createTeam(client, "Тестовая команда ") assert.NotNil(t, err, "запрос не удался") - - deleteTeams(t) }