Compare commits
4 commits
develop
...
feature/co
Author | SHA1 | Date | |
---|---|---|---|
a1ebd51404 | |||
e201b12db5 | |||
f7dd1bc806 | |||
4d40159772 |
7 changed files with 215 additions and 0 deletions
|
@ -10,4 +10,8 @@ type ContestHandlers interface {
|
||||||
CreateContest(ctx context.Context, req *contestv1.CreateContestRequest) (*contestv1.CreateContestResponse, error)
|
CreateContest(ctx context.Context, req *contestv1.CreateContestRequest) (*contestv1.CreateContestResponse, error)
|
||||||
ReadContest(ctx context.Context, req *contestv1.ReadContestRequest) (*contestv1.ReadContestResponse, error)
|
ReadContest(ctx context.Context, req *contestv1.ReadContestRequest) (*contestv1.ReadContestResponse, error)
|
||||||
DeleteContest(ctx context.Context, req *contestv1.DeleteContestRequest) (*emptypb.Empty, error)
|
DeleteContest(ctx context.Context, req *contestv1.DeleteContestRequest) (*emptypb.Empty, error)
|
||||||
|
AddTask(ctx context.Context, req *contestv1.AddTaskRequest) (*contestv1.AddTaskResponse, error)
|
||||||
|
DeleteTask(ctx context.Context, req *contestv1.DeleteTaskRequest) (*emptypb.Empty, error)
|
||||||
|
AddParticipant(ctx context.Context, req *contestv1.AddParticipantRequest) (*contestv1.AddParticipantResponse, error)
|
||||||
|
DeleteParticipant(ctx context.Context, req *contestv1.DeleteParticipantRequest) (*emptypb.Empty, error)
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,3 +49,35 @@ func (h *ContestHandlers) DeleteContest(ctx context.Context, req *contestv1.Dele
|
||||||
}
|
}
|
||||||
return &emptypb.Empty{}, nil
|
return &emptypb.Empty{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *ContestHandlers) AddTask(ctx context.Context, req *contestv1.AddTaskRequest) (*contestv1.AddTaskResponse, error) {
|
||||||
|
id, err := h.contestUC.AddTask(ctx, req.GetContestId(), req.GetProblemId())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &contestv1.AddTaskResponse{Id: id}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *ContestHandlers) DeleteTask(ctx context.Context, req *contestv1.DeleteTaskRequest) (*emptypb.Empty, error) {
|
||||||
|
err := h.contestUC.DeleteTask(ctx, req.GetTaskId())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &emptypb.Empty{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *ContestHandlers) AddParticipant(ctx context.Context, req *contestv1.AddParticipantRequest) (*contestv1.AddParticipantResponse, error) {
|
||||||
|
id, err := h.contestUC.AddParticipant(ctx, req.GetContestId(), req.GetUserId())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &contestv1.AddParticipantResponse{Id: id}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *ContestHandlers) DeleteParticipant(ctx context.Context, req *contestv1.DeleteParticipantRequest) (*emptypb.Empty, error) {
|
||||||
|
err := h.contestUC.DeleteParticipant(ctx, req.GetParticipantId())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &emptypb.Empty{}, nil
|
||||||
|
}
|
||||||
|
|
|
@ -9,4 +9,8 @@ type ContestRepository interface {
|
||||||
CreateContest(ctx context.Context, title string) (int32, error)
|
CreateContest(ctx context.Context, title string) (int32, error)
|
||||||
ReadContestById(ctx context.Context, id int32) (*models.Contest, error)
|
ReadContestById(ctx context.Context, id int32) (*models.Contest, error)
|
||||||
DeleteContest(ctx context.Context, id int32) error
|
DeleteContest(ctx context.Context, id int32) error
|
||||||
|
AddTask(ctx context.Context, contestId int32, taskId int32) (int32, error)
|
||||||
|
DeleteTask(ctx context.Context, taskId int32) error
|
||||||
|
AddParticipant(ctx context.Context, contestId int32, userId int32) (int32, error)
|
||||||
|
DeleteParticipant(ctx context.Context, participantId int32) error
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,65 @@ func (r *ContestRepository) DeleteContest(ctx context.Context, id int32) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const addTaskQuery = "INSERT INTO task (problem_id, contest_id, position) VALUES (?, ?,COALESCE(SELECT MAX(position) FROM task WHERE contest_id = ? ,0) + 1) RETURNING id"
|
||||||
|
|
||||||
|
func (r *ContestRepository) AddTask(ctx context.Context, contestId int32, problem_id int32) (int32, error) {
|
||||||
|
query := r.db.Rebind(addTaskQuery)
|
||||||
|
rows, err := r.db.QueryxContext(ctx, query, problem_id, contestId, contestId)
|
||||||
|
if err != nil {
|
||||||
|
return 0, handlePgErr(err)
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
var id int32
|
||||||
|
rows.Next()
|
||||||
|
err = rows.Scan(&id)
|
||||||
|
if err != nil {
|
||||||
|
return 0, handlePgErr(err)
|
||||||
|
}
|
||||||
|
return id, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const deleteTaskQuery = "DELETE FROM task WHERE id=?"
|
||||||
|
|
||||||
|
func (r *ContestRepository) DeleteTask(ctx context.Context, taskId int32) error {
|
||||||
|
query := r.db.Rebind(deleteTaskQuery)
|
||||||
|
_, err := r.db.ExecContext(ctx, query, taskId)
|
||||||
|
if err != nil {
|
||||||
|
return handlePgErr(err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const addParticipantQuery = "INSERT INTO participant (user_id ,contest_id, name) VALUES (?, ?, ?) RETURNING id"
|
||||||
|
|
||||||
|
func (r *ContestRepository) AddParticipant(ctx context.Context, contestId int32, userId int32) (int32, error) {
|
||||||
|
query := r.db.Rebind(addParticipantQuery)
|
||||||
|
name := ""
|
||||||
|
rows, err := r.db.QueryxContext(ctx, query, contestId, userId, name)
|
||||||
|
if err != nil {
|
||||||
|
return 0, handlePgErr(err)
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
var id int32
|
||||||
|
rows.Next()
|
||||||
|
err = rows.Scan(&id)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return id, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const deleteParticipantQuery = "DELETE FROM participant WHERE id=?"
|
||||||
|
|
||||||
|
func (r *ContestRepository) DeleteParticipant(ctx context.Context, participantId int32) error {
|
||||||
|
query := r.db.Rebind(deleteParticipantQuery)
|
||||||
|
_, err := r.db.ExecContext(ctx, query, participantId)
|
||||||
|
if err != nil {
|
||||||
|
return handlePgErr(err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func handlePgErr(err error) error {
|
func handlePgErr(err error) error {
|
||||||
var pgErr *pgconn.PgError
|
var pgErr *pgconn.PgError
|
||||||
if !errors.As(err, &pgErr) {
|
if !errors.As(err, &pgErr) {
|
||||||
|
|
|
@ -56,3 +56,99 @@ func TestContestRepository_DeleteContest(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestContestRepository_AddTask(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
sqlxDB := sqlx.NewDb(db, "sqlmock")
|
||||||
|
defer sqlxDB.Close()
|
||||||
|
|
||||||
|
contestRepo := NewContestRepository(sqlxDB, zap.NewNop())
|
||||||
|
|
||||||
|
t.Run("valid task additional", func(t *testing.T) {
|
||||||
|
taskId := int32(1)
|
||||||
|
contestId := int32(1)
|
||||||
|
|
||||||
|
rows := sqlmock.NewRows([]string{"id"}).AddRow(1)
|
||||||
|
|
||||||
|
mock.ExpectQuery(sqlxDB.Rebind(addTaskQuery)).WithArgs(taskId, contestId, contestId).WillReturnRows(rows)
|
||||||
|
|
||||||
|
id, err := contestRepo.AddTask(context.Background(), contestId, taskId)
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, int32(1), id)
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestContestRepository_DeleteTask(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
sqlxDB := sqlx.NewDb(db, "sqlmock")
|
||||||
|
defer sqlxDB.Close()
|
||||||
|
contestRepo := NewContestRepository(sqlxDB, zap.NewNop())
|
||||||
|
t.Run("valid task deletion", func(t *testing.T) {
|
||||||
|
id := int32(1)
|
||||||
|
rows := sqlmock.NewResult(1, 1)
|
||||||
|
|
||||||
|
mock.ExpectExec(sqlxDB.Rebind(deleteTaskQuery)).WithArgs(id).WillReturnResult(rows)
|
||||||
|
|
||||||
|
err = contestRepo.DeleteTask(context.Background(), id)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestContestRepository_AddParticipant(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
sqlxDB := sqlx.NewDb(db, "sqlmock")
|
||||||
|
defer sqlxDB.Close()
|
||||||
|
contestRepo := NewContestRepository(sqlxDB, zap.NewNop())
|
||||||
|
|
||||||
|
t.Run("valid participant addition", func(t *testing.T) {
|
||||||
|
contestId := int32(1)
|
||||||
|
userId := int32(1)
|
||||||
|
name := ""
|
||||||
|
|
||||||
|
rows := sqlmock.NewRows([]string{"id"}).AddRow(1)
|
||||||
|
|
||||||
|
mock.ExpectQuery(sqlxDB.Rebind(addParticipantQuery)).WithArgs(contestId, userId, name).WillReturnRows(rows)
|
||||||
|
|
||||||
|
id, err := contestRepo.AddParticipant(context.Background(), contestId, userId)
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, int32(1), id)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestContestRepository_DeleteParticipant(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
sqlxDB := sqlx.NewDb(db, "sqlmock")
|
||||||
|
defer sqlxDB.Close()
|
||||||
|
|
||||||
|
contestRepo := NewContestRepository(sqlxDB, zap.NewNop())
|
||||||
|
|
||||||
|
t.Run("valid participant deletion", func(t *testing.T) {
|
||||||
|
id := int32(1)
|
||||||
|
rows := sqlmock.NewResult(1, 1)
|
||||||
|
|
||||||
|
mock.ExpectExec(sqlxDB.Rebind(deleteParticipantQuery)).WithArgs(id).WillReturnResult(rows)
|
||||||
|
|
||||||
|
err = contestRepo.DeleteParticipant(context.Background(), id)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -9,4 +9,8 @@ type ContestUseCase interface {
|
||||||
CreateContest(ctx context.Context, title string) (int32, error)
|
CreateContest(ctx context.Context, title string) (int32, error)
|
||||||
ReadContestById(ctx context.Context, id int32) (*models.Contest, error)
|
ReadContestById(ctx context.Context, id int32) (*models.Contest, error)
|
||||||
DeleteContest(ctx context.Context, id int32) error
|
DeleteContest(ctx context.Context, id int32) error
|
||||||
|
AddTask(ctx context.Context, contestId int32, taskId int32) (int32, error)
|
||||||
|
DeleteTask(ctx context.Context, taskId int32) error
|
||||||
|
AddParticipant(ctx context.Context, contestId int32, userId int32) (int32, error)
|
||||||
|
DeleteParticipant(ctx context.Context, participantId int32) error
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,3 +29,19 @@ func (uc *ContestUseCase) ReadContestById(ctx context.Context, id int32) (*model
|
||||||
func (uc *ContestUseCase) DeleteContest(ctx context.Context, id int32) error {
|
func (uc *ContestUseCase) DeleteContest(ctx context.Context, id int32) error {
|
||||||
return uc.contestRepo.DeleteContest(ctx, id)
|
return uc.contestRepo.DeleteContest(ctx, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (uc *ContestUseCase) AddTask(ctx context.Context, contestId int32, taskId int32) (id int32, err error) {
|
||||||
|
return uc.contestRepo.AddTask(ctx, contestId, taskId)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (uc *ContestUseCase) DeleteTask(ctx context.Context, taskId int32) error {
|
||||||
|
return uc.contestRepo.DeleteTask(ctx, taskId)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (uc *ContestUseCase) AddParticipant(ctx context.Context, contestId int32, userId int32) (id int32, err error) {
|
||||||
|
return uc.contestRepo.AddParticipant(ctx, contestId, userId)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (uc *ContestUseCase) DeleteParticipant(ctx context.Context, participantId int32) error {
|
||||||
|
return uc.contestRepo.DeleteParticipant(ctx, participantId)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue