test(tester): fix tests #3
6 changed files with 1500 additions and 181 deletions
5
go.mod
5
go.mod
|
@ -4,11 +4,13 @@ go 1.23.6
|
|||
|
||||
require (
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.2
|
||||
github.com/Masterminds/squirrel v1.5.4
|
||||
github.com/gofiber/fiber/v2 v2.52.6
|
||||
github.com/golang-jwt/jwt/v4 v4.5.1
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/ilyakaznacheev/cleanenv v1.5.0
|
||||
github.com/jackc/pgerrcode v0.0.0-20240316143900-6e2875d9b438
|
||||
github.com/microcosm-cc/bluemonday v1.0.27
|
||||
github.com/oapi-codegen/runtime v1.1.1
|
||||
github.com/open-policy-agent/opa v1.2.0
|
||||
github.com/rabbitmq/amqp091-go v1.10.0
|
||||
|
@ -35,10 +37,11 @@ require (
|
|||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
|
||||
github.com/jackc/puddle/v2 v2.2.1 // indirect
|
||||
github.com/klauspost/compress v1.17.11 // indirect
|
||||
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
|
||||
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||
github.com/microcosm-cc/bluemonday v1.0.27 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/prometheus/client_golang v1.21.0 // indirect
|
||||
|
|
7
go.sum
7
go.sum
|
@ -5,6 +5,8 @@ github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8
|
|||
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU=
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU=
|
||||
github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8afzqM=
|
||||
github.com/Masterminds/squirrel v1.5.4/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
|
||||
github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk=
|
||||
github.com/agnivade/levenshtein v1.2.1 h1:EHBY3UOn1gwdy/VbFwgo4cxecRznFk7fKWN1KOX7eoM=
|
||||
github.com/agnivade/levenshtein v1.2.1/go.mod h1:QVVI16kDrtSuwcpd0p1+xMC6Z/VfhtCyDIjcwga4/DU=
|
||||
|
@ -97,6 +99,10 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
|||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq6+3iTQz8KNCLtVX6idSoTLdUw=
|
||||
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o=
|
||||
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhRWSsG5rVo6hYhAB/ADZrk=
|
||||
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw=
|
||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
|
@ -146,6 +152,7 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ
|
|||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
|
|
|
@ -2,10 +2,9 @@ package repository
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"git.sch9.ru/new_gate/ms-tester/internal/models"
|
||||
sq "github.com/Masterminds/squirrel"
|
||||
"github.com/jmoiron/sqlx"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type ContestRepository struct {
|
||||
|
@ -172,7 +171,7 @@ const (
|
|||
func (r *ContestRepository) ListContests(ctx context.Context, filter models.ContestsFilter) (*models.ContestsList, error) {
|
||||
const op = "ContestRepository.ReadTasks"
|
||||
|
||||
var contests []*models.ContestsListItem
|
||||
contests := make([]*models.ContestsListItem, 0)
|
||||
query := r.db.Rebind(readContestsListQuery)
|
||||
err := r.db.SelectContext(ctx, &contests, query, filter.PageSize, filter.Offset())
|
||||
if err != nil {
|
||||
|
@ -207,7 +206,7 @@ func (r *ContestRepository) ListParticipants(ctx context.Context, filter models.
|
|||
filter.PageSize = 1
|
||||
}
|
||||
|
||||
var participants []*models.ParticipantsListItem
|
||||
participants := make([]*models.ParticipantsListItem, 0)
|
||||
query := r.db.Rebind(readParticipantsListQuery)
|
||||
err := r.db.SelectContext(ctx, &participants, query, filter.ContestId, filter.PageSize, filter.Offset())
|
||||
if err != nil {
|
||||
|
@ -313,93 +312,94 @@ func (r *ContestRepository) CreateSolution(ctx context.Context, creation *models
|
|||
return id, nil
|
||||
}
|
||||
|
||||
// buildListSolutionsQueries builds two SQL queries: one for selecting solutions
|
||||
// and another for counting them. The first query selects all columns that are
|
||||
// needed for the solutions list, including the task and contest titles, and
|
||||
// the participant name. The second query counts the number of solutions that
|
||||
// match the filter.
|
||||
//
|
||||
// The caller is responsible for executing the queries and processing the
|
||||
// results.
|
||||
func buildListSolutionsQueries(filter models.SolutionsFilter) (sq.SelectBuilder, sq.SelectBuilder) {
|
||||
columns := []string{
|
||||
"s.id",
|
||||
"s.participant_id",
|
||||
"p2.name AS participant_name",
|
||||
"s.state",
|
||||
"s.score",
|
||||
"s.penalty",
|
||||
"s.time_stat",
|
||||
"s.memory_stat",
|
||||
"s.language",
|
||||
"s.task_id",
|
||||
"t.position AS task_position",
|
||||
"p.title AS task_title",
|
||||
"t.contest_id",
|
||||
"c.title",
|
||||
"s.updated_at",
|
||||
"s.created_at",
|
||||
}
|
||||
|
||||
qb := sq.Select(columns...).
|
||||
From("solutions s").
|
||||
LeftJoin("tasks t ON s.task_id = t.id").
|
||||
LeftJoin("problems p ON t.problem_id = p.id").
|
||||
LeftJoin("contests c ON t.contest_id = c.id").
|
||||
LeftJoin("participants p2 ON s.participant_id = p2.id")
|
||||
|
||||
if filter.ContestId != nil {
|
||||
qb = qb.Where("s.contest_id = ?", *filter.ContestId)
|
||||
}
|
||||
if filter.ParticipantId != nil {
|
||||
qb = qb.Where("s.participant_id = ?", *filter.ParticipantId)
|
||||
}
|
||||
if filter.TaskId != nil {
|
||||
qb = qb.Where("s.task_id = ?", *filter.TaskId)
|
||||
}
|
||||
if filter.Language != nil {
|
||||
qb = qb.Where("s.language = ?", *filter.Language)
|
||||
}
|
||||
if filter.State != nil {
|
||||
qb = qb.Where("s.state = ?", *filter.State)
|
||||
}
|
||||
|
||||
countQb := sq.Select("COUNT(*)").FromSelect(qb, "sub")
|
||||
|
||||
if filter.Order != nil && *filter.Order < 0 {
|
||||
qb = qb.OrderBy("s.id DESC")
|
||||
}
|
||||
|
||||
qb = qb.Limit(uint64(filter.PageSize)).Offset(uint64(filter.Offset()))
|
||||
|
||||
return qb, countQb
|
||||
}
|
||||
|
||||
func (r *ContestRepository) ListSolutions(ctx context.Context, filter models.SolutionsFilter) (*models.SolutionsList, error) {
|
||||
const op = "ContestRepository.ListSolutions"
|
||||
|
||||
baseQuery := `
|
||||
SELECT s.id,
|
||||
baseQb, countQb := buildListSolutionsQueries(filter)
|
||||
|
||||
s.participant_id,
|
||||
p2.name as participant_name,
|
||||
|
||||
s.state,
|
||||
s.score,
|
||||
s.penalty,
|
||||
s.time_stat,
|
||||
s.memory_stat,
|
||||
s.language,
|
||||
|
||||
s.task_id,
|
||||
t.position as task_position,
|
||||
p.title as task_title,
|
||||
|
||||
t.contest_id,
|
||||
c.title,
|
||||
|
||||
s.updated_at,
|
||||
s.created_at
|
||||
FROM solutions s
|
||||
LEFT JOIN tasks t ON s.task_id = t.id
|
||||
LEFT JOIN problems p ON t.problem_id = p.id
|
||||
LEFT JOIN contests c ON t.contest_id = c.id
|
||||
LEFT JOIN participants p2 on s.participant_id = p2.id
|
||||
WHERE 1=1
|
||||
`
|
||||
|
||||
var conditions []string
|
||||
var args []interface{}
|
||||
|
||||
if filter.ContestId != nil {
|
||||
conditions = append(conditions, "s.contest_id = ?")
|
||||
args = append(args, *filter.ContestId)
|
||||
query, args, err := countQb.ToSql()
|
||||
if err != nil {
|
||||
return nil, handlePgErr(err, op)
|
||||
}
|
||||
if filter.ParticipantId != nil {
|
||||
conditions = append(conditions, "s.participant_id = ?")
|
||||
args = append(args, *filter.ParticipantId)
|
||||
}
|
||||
if filter.TaskId != nil {
|
||||
conditions = append(conditions, "s.task_id = ?")
|
||||
args = append(args, *filter.TaskId)
|
||||
}
|
||||
if filter.Language != nil {
|
||||
conditions = append(conditions, "s.language = ?")
|
||||
args = append(args, *filter.Language)
|
||||
}
|
||||
if filter.State != nil {
|
||||
conditions = append(conditions, "s.state = ?")
|
||||
args = append(args, *filter.State)
|
||||
}
|
||||
|
||||
if len(conditions) > 0 {
|
||||
baseQuery += " AND " + strings.Join(conditions, " AND ")
|
||||
}
|
||||
|
||||
if filter.Order != nil {
|
||||
orderDirection := "ASC"
|
||||
if *filter.Order < 0 {
|
||||
orderDirection = "DESC"
|
||||
}
|
||||
baseQuery += fmt.Sprintf(" ORDER BY s.id %s", orderDirection)
|
||||
}
|
||||
|
||||
countQuery := "SELECT COUNT(*) FROM (" + baseQuery + ") as count_table"
|
||||
var totalCount int32
|
||||
err := r.db.QueryRowxContext(ctx, r.db.Rebind(countQuery), args...).Scan(&totalCount)
|
||||
err = r.db.QueryRowxContext(ctx, r.db.Rebind(query), args...).Scan(&totalCount)
|
||||
if err != nil {
|
||||
return nil, handlePgErr(err, op)
|
||||
}
|
||||
|
||||
offset := (filter.Page - 1) * filter.PageSize
|
||||
baseQuery += " LIMIT ? OFFSET ?"
|
||||
args = append(args, filter.PageSize, offset)
|
||||
|
||||
rows, err := r.db.QueryxContext(ctx, r.db.Rebind(baseQuery), args...)
|
||||
query, args, err = baseQb.ToSql()
|
||||
if err != nil {
|
||||
return nil, handlePgErr(err, op)
|
||||
}
|
||||
rows, err := r.db.QueryxContext(ctx, r.db.Rebind(query), args...)
|
||||
if err != nil {
|
||||
return nil, handlePgErr(err, op)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var solutions []*models.SolutionsListItem
|
||||
solutions := make([]*models.SolutionsListItem, 0)
|
||||
for rows.Next() {
|
||||
var solution models.SolutionsListItem
|
||||
err = rows.StructScan(&solution)
|
||||
|
@ -551,7 +551,7 @@ WITH Attempts AS (
|
|||
MIN(CASE WHEN s.state = 5 THEN s.penalty END) as success_penalty
|
||||
FROM solutions s
|
||||
JOIN tasks t ON t.id = s.task_id
|
||||
WHERE t.contest_id = :contest_id
|
||||
WHERE t.contest_id = ?
|
||||
GROUP BY s.participant_id, s.task_id
|
||||
)
|
||||
SELECT
|
||||
|
@ -559,11 +559,11 @@ SELECT
|
|||
p.name,
|
||||
COUNT(DISTINCT CASE WHEN a.success_penalty IS NOT NULL THEN a.task_id END) as solved_in_total,
|
||||
COALESCE(SUM(CASE WHEN a.success_penalty IS NOT NULL
|
||||
THEN a.failed_attempts * :penalty + a.success_penalty
|
||||
THEN a.failed_attempts * ? + a.success_penalty
|
||||
ELSE 0 END), 0) as penalty_in_total
|
||||
FROM participants p
|
||||
LEFT JOIN Attempts a ON a.participant_id = p.id
|
||||
WHERE p.contest_id = :contest_id
|
||||
WHERE p.contest_id = ?
|
||||
GROUP BY p.id, p.name
|
||||
`
|
||||
)
|
||||
|
@ -596,10 +596,7 @@ func (r *ContestRepository) ReadMonitor(ctx context.Context, contestId int32) (*
|
|||
|
||||
penalty := int32(20) // FIXME
|
||||
namedQuery := r.db.Rebind(participantsQuery)
|
||||
rows3, err := r.db.NamedQueryContext(ctx, namedQuery, map[string]interface{}{
|
||||
"contest_id": contestId,
|
||||
"penalty": penalty,
|
||||
})
|
||||
rows3, err := r.db.QueryxContext(ctx, namedQuery, contestId, penalty, contestId)
|
||||
if err != nil {
|
||||
return nil, handlePgErr(err, op)
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -2,57 +2,153 @@ package repository
|
|||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"git.sch9.ru/new_gate/ms-tester/internal/models"
|
||||
"github.com/DATA-DOG/go-sqlmock"
|
||||
"github.com/jmoiron/sqlx"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/zap"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestProblemRepository_CreateProblem(t *testing.T) {
|
||||
t.Parallel()
|
||||
type problemTestFixture struct {
|
||||
db *sql.DB
|
||||
sqlxDB *sqlx.DB
|
||||
mock sqlmock.Sqlmock
|
||||
problemRepo *ProblemRepository
|
||||
}
|
||||
|
||||
func newProblemTestFixture(t *testing.T) *problemTestFixture {
|
||||
db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
|
||||
require.NoError(t, err)
|
||||
defer db.Close()
|
||||
|
||||
sqlxDB := sqlx.NewDb(db, "sqlmock")
|
||||
defer sqlxDB.Close()
|
||||
repo := NewProblemRepository(sqlxDB)
|
||||
|
||||
problemRepo := NewProblemRepository(sqlxDB, zap.NewNop())
|
||||
return &problemTestFixture{
|
||||
db: db,
|
||||
sqlxDB: sqlxDB,
|
||||
mock: mock,
|
||||
problemRepo: repo,
|
||||
}
|
||||
}
|
||||
|
||||
// cleanup closes database connections
|
||||
func (tf *problemTestFixture) cleanup() {
|
||||
tf.db.Close()
|
||||
tf.sqlxDB.Close()
|
||||
}
|
||||
|
||||
func TestProblemRepository_CreateProblem(t *testing.T) {
|
||||
tf := newProblemTestFixture(t)
|
||||
defer tf.cleanup()
|
||||
|
||||
t.Run("valid problem creation", func(t *testing.T) {
|
||||
title := "Problem title"
|
||||
|
||||
title := "Test Problem"
|
||||
rows := sqlmock.NewRows([]string{"id"}).AddRow(1)
|
||||
|
||||
mock.ExpectQuery(sqlxDB.Rebind(createProblemQuery)).WithArgs(title).WillReturnRows(rows)
|
||||
tf.mock.ExpectQuery(tf.sqlxDB.Rebind(createProblemQuery)).
|
||||
WithArgs(title).
|
||||
WillReturnRows(rows)
|
||||
|
||||
id, err := problemRepo.CreateProblem(context.Background(), title)
|
||||
id, err := tf.problemRepo.CreateProblem(context.Background(), tf.problemRepo.DB(), title)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, int32(1), id)
|
||||
})
|
||||
}
|
||||
|
||||
func TestProblemRepository_ReadProblemById(t *testing.T) {
|
||||
tf := newProblemTestFixture(t)
|
||||
defer tf.cleanup()
|
||||
|
||||
t.Run("valid problem read", func(t *testing.T) {
|
||||
id := int32(1)
|
||||
rows := sqlmock.NewRows([]string{"id", "title"}).
|
||||
AddRow(1, "Test Problem")
|
||||
|
||||
tf.mock.ExpectQuery(tf.sqlxDB.Rebind(readProblemQuery)).
|
||||
WithArgs(id).
|
||||
WillReturnRows(rows)
|
||||
|
||||
problem, err := tf.problemRepo.ReadProblemById(context.Background(), tf.problemRepo.DB(), id)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, problem)
|
||||
require.Equal(t, int32(1), problem.Id)
|
||||
require.Equal(t, "Test Problem", problem.Title)
|
||||
})
|
||||
}
|
||||
|
||||
func TestProblemRepository_DeleteProblem(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()
|
||||
|
||||
problemRepo := NewProblemRepository(sqlxDB, zap.NewNop())
|
||||
tf := newProblemTestFixture(t)
|
||||
defer tf.cleanup()
|
||||
|
||||
t.Run("valid problem deletion", func(t *testing.T) {
|
||||
id := int32(1)
|
||||
rows := sqlmock.NewResult(1, 1)
|
||||
|
||||
mock.ExpectExec(sqlxDB.Rebind(deleteProblemQuery)).WithArgs(id).WillReturnResult(rows)
|
||||
tf.mock.ExpectExec(tf.sqlxDB.Rebind(deleteProblemQuery)).
|
||||
WithArgs(id).
|
||||
WillReturnResult(rows)
|
||||
|
||||
err = problemRepo.DeleteProblem(context.Background(), id)
|
||||
err := tf.problemRepo.DeleteProblem(context.Background(), tf.problemRepo.DB(), id)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestProblemRepository_ListProblems(t *testing.T) {
|
||||
tf := newProblemTestFixture(t)
|
||||
defer tf.cleanup()
|
||||
|
||||
t.Run("valid problems list", func(t *testing.T) {
|
||||
filter := models.ProblemsFilter{
|
||||
Page: 1,
|
||||
PageSize: 10,
|
||||
}
|
||||
listRows := sqlmock.NewRows([]string{"id", "title", "solved_count"}).
|
||||
AddRow(1, "Problem 1", 5).
|
||||
AddRow(2, "Problem 2", 3)
|
||||
countRows := sqlmock.NewRows([]string{"count"}).AddRow(2)
|
||||
|
||||
tf.mock.ExpectQuery(tf.sqlxDB.Rebind(ListProblemsQuery)).
|
||||
WithArgs(filter.PageSize, filter.Offset()).
|
||||
WillReturnRows(listRows)
|
||||
|
||||
tf.mock.ExpectQuery(tf.sqlxDB.Rebind(CountProblemsQuery)).
|
||||
WillReturnRows(countRows)
|
||||
|
||||
result, err := tf.problemRepo.ListProblems(context.Background(), tf.problemRepo.DB(), filter)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, result)
|
||||
require.Len(t, result.Problems, 2)
|
||||
require.Equal(t, int32(1), result.Pagination.Page)
|
||||
require.Equal(t, int32(1), result.Pagination.Total)
|
||||
})
|
||||
}
|
||||
|
||||
func TestProblemRepository_UpdateProblem(t *testing.T) {
|
||||
tf := newProblemTestFixture(t)
|
||||
defer tf.cleanup()
|
||||
|
||||
t.Run("valid problem update", func(t *testing.T) {
|
||||
id := int32(1)
|
||||
problemUpdate := models.ProblemUpdate{
|
||||
Title: sp("Updated Title"),
|
||||
TimeLimit: i32p(1000),
|
||||
MemoryLimit: i32p(256),
|
||||
}
|
||||
rows := sqlmock.NewResult(1, 1)
|
||||
|
||||
tf.mock.ExpectExec(tf.sqlxDB.Rebind(UpdateProblemQuery)).
|
||||
WithArgs(
|
||||
problemUpdate.Title,
|
||||
problemUpdate.TimeLimit,
|
||||
problemUpdate.MemoryLimit,
|
||||
nil, nil, nil, nil, nil,
|
||||
nil, nil, nil, nil, nil,
|
||||
id,
|
||||
).
|
||||
WillReturnResult(rows)
|
||||
|
||||
err := tf.problemRepo.UpdateProblem(context.Background(), tf.problemRepo.DB(), id, problemUpdate)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
|
2
proto
2
proto
|
@ -1 +1 @@
|
|||
Subproject commit 1fbee7ba29c358c76d1c835ac6999ce9e1b59ee9
|
||||
Subproject commit f00483d24a53a243734c793fc24e02d52d39fdab
|
Loading…
Add table
Reference in a new issue