This commit is contained in:
2026-10-03 13:33:18 +07:00
parent 2caa2c1a88
commit 5d8c296ecd
30 changed files with 94 additions and 94 deletions
+5 -5
View File
@@ -17,8 +17,8 @@ func TestGameErrorStatus(t *testing.T) {
err error err error
code codes.Code code codes.Code
}{ }{
{"not found", "Игра не найдена", game_service.ErrGameNotFound, codes.NotFound}, {"not found", "игра не найдена", game_service.ErrGameNotFound, codes.NotFound},
{"invalid format", "Формат игры должен быть online или offline", game_service.ErrInvalidGameFormat, codes.InvalidArgument}, {"invalid format", "формат игры должен быть online или offline", game_service.ErrInvalidGameFormat, codes.InvalidArgument},
{"internal", "не удалось получить игру", errors.New("private database detail"), codes.Internal}, {"internal", "не удалось получить игру", errors.New("private database detail"), codes.Internal},
} { } {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
@@ -36,9 +36,9 @@ func TestAnswerErrorStatus(t *testing.T) {
err error err error
code codes.Code code codes.Code
}{ }{
{"team not found", "Команда не найдена", answer_service.ErrTeamNotFound, codes.NotFound}, {"team not found", "команда не найдена", answer_service.ErrTeamNotFound, codes.NotFound},
{"question not found", "Вопрос не найден", answer_service.ErrQuestionNotFound, codes.InvalidArgument}, {"question not found", "вопрос не найден", answer_service.ErrQuestionNotFound, codes.InvalidArgument},
{"game not started", "Игра не начата, отвечать на вопросы нельзя", answer_service.ErrGameNotStarted, codes.FailedPrecondition}, {"game not started", "игра не начата, отвечать на вопросы нельзя", answer_service.ErrGameNotStarted, codes.FailedPrecondition},
{"internal", "не удалось получить ответы игры", errors.New("private database detail"), codes.Internal}, {"internal", "не удалось получить ответы игры", errors.New("private database detail"), codes.Internal},
} { } {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
+4 -4
View File
@@ -17,10 +17,10 @@ func TestParticipationErrorStatus(t *testing.T) {
code codes.Code code codes.Code
want string want string
}{ }{
{"invalid link", participation_service.ErrParticipationLink, codes.NotFound, "Ссылка недействительна"}, {"invalid link", participation_service.ErrParticipationLink, codes.NotFound, "ссылка недействительна"},
{"invalid answer", participation_service.ErrInvalidAnswer, codes.InvalidArgument, "Выберите подтверждение или отмену участия"}, {"invalid answer", participation_service.ErrInvalidAnswer, codes.InvalidArgument, "выберите подтверждение или отмену участия"},
{"closed", participation_service.ErrParticipationClosed, codes.FailedPrecondition, "Приём ответов закрыт"}, {"closed", participation_service.ErrParticipationClosed, codes.FailedPrecondition, "приём ответов закрыт"},
{"final", participation_service.ErrParticipationFinal, codes.FailedPrecondition, "Решение уже принято и не может быть изменено"}, {"final", participation_service.ErrParticipationFinal, codes.FailedPrecondition, "решение уже принято и не может быть изменено"},
{"internal", errors.New("private database detail"), codes.Internal, "participation failed"}, {"internal", errors.New("private database detail"), codes.Internal, "participation failed"},
} { } {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
+2 -2
View File
@@ -17,8 +17,8 @@ func TestScenarioErrorStatus(t *testing.T) {
code codes.Code code codes.Code
message string message string
}{ }{
{"not found", "scenario failed", scenarios_service.ErrScenarioNotFound, codes.NotFound, "Сценарий не найден"}, {"not found", "scenario failed", scenarios_service.ErrScenarioNotFound, codes.NotFound, "сценарий не найден"},
{"not owner", "scenario failed", scenarios_service.ErrScenarioNotOwner, codes.PermissionDenied, "Сценарий принадлежит другому пользователю"}, {"not owner", "scenario failed", scenarios_service.ErrScenarioNotOwner, codes.PermissionDenied, "сценарий принадлежит другому пользователю"},
{"published", "scenario failed", scenarios_service.ErrScenarioPublished, codes.FailedPrecondition, scenarios_service.ErrScenarioPublished.Error()}, {"published", "scenario failed", scenarios_service.ErrScenarioPublished, codes.FailedPrecondition, scenarios_service.ErrScenarioPublished.Error()},
{"internal", "scenario failed", errors.New("private database detail"), codes.Internal, "scenario failed"}, {"internal", "scenario failed", errors.New("private database detail"), codes.Internal, "scenario failed"},
} { } {
+3 -3
View File
@@ -17,9 +17,9 @@ func TestTeamErrorStatus(t *testing.T) {
code codes.Code code codes.Code
message string message string
}{ }{
{"game not found", "add failed", team_service.ErrGameNotFound, codes.NotFound, "Игра не найдена"}, {"game not found", "add failed", team_service.ErrGameNotFound, codes.NotFound, "игра не найдена"},
{"team not found", "delete failed", team_service.ErrTeamNotFound, codes.NotFound, "Команда не найдена"}, {"team not found", "delete failed", team_service.ErrTeamNotFound, codes.NotFound, "команда не найдена"},
{"invalid captain email", "add failed", team_service.ErrInvalidCaptainEmail, codes.InvalidArgument, "Укажите корректную почту капитана"}, {"invalid captain email", "add failed", team_service.ErrInvalidCaptainEmail, codes.InvalidArgument, "укажите корректную почту капитана"},
{"internal", "add failed", errors.New("private database detail"), codes.Internal, "add failed"}, {"internal", "add failed", errors.New("private database detail"), codes.Internal, "add failed"},
} { } {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
+1 -1
View File
@@ -43,7 +43,7 @@ func Generate(cards []Card) ([]byte, error) {
} }
qr, err := qrcode.New(card.URL, qrcode.Medium) qr, err := qrcode.New(card.URL, qrcode.Medium)
if err != nil { if err != nil {
return nil, fmt.Errorf("QR команды %d: %w", i+1, err) return nil, fmt.Errorf("qr команды %d: %w", i+1, err)
} }
if i%12 == 0 { if i%12 == 0 {
pdf.AddPage() pdf.AddPage()
+1 -1
View File
@@ -10,7 +10,7 @@ import (
var ( var (
// ErrActionsNotFound indicates that no actions were found. // ErrActionsNotFound indicates that no actions were found.
ErrActionsNotFound = errors.New("Ход не найден") ErrActionsNotFound = errors.New("ход не найден")
) )
// ActionsRepo persists team actions. // ActionsRepo persists team actions.
+1 -1
View File
@@ -11,7 +11,7 @@ import (
var ( var (
// ErrApplicationNotFound indicates that an application was not found. // ErrApplicationNotFound indicates that an application was not found.
ErrApplicationNotFound = errors.New("Улика не найдена") ErrApplicationNotFound = errors.New("улика не найдена")
) )
// ApplicationsRepo persists team applications. // ApplicationsRepo persists team applications.
+4 -4
View File
@@ -12,13 +12,13 @@ import (
var ( var (
// ErrReviewNotFound indicates that a review was not found. // ErrReviewNotFound indicates that a review was not found.
ErrReviewNotFound = errors.New("Отзыв не найден") ErrReviewNotFound = errors.New("отзыв не найден")
// ErrReviewExists indicates that a team already submitted a review. // ErrReviewExists indicates that a team already submitted a review.
ErrReviewExists = errors.New("Отзыв от команды уже оставлен") ErrReviewExists = errors.New("отзыв от команды уже оставлен")
// ErrTeamNotFound indicates that a team was not found. // ErrTeamNotFound indicates that a team was not found.
ErrTeamNotFound = errors.New("Команда не найдена") ErrTeamNotFound = errors.New("команда не найдена")
// ErrInvalidStatus indicates that a moderation status is invalid. // ErrInvalidStatus indicates that a moderation status is invalid.
ErrInvalidStatus = errors.New("Недопустимый статус модерации") ErrInvalidStatus = errors.New("недопустимый статус модерации")
) )
// Review describes a game review. // Review describes a game review.
+1 -1
View File
@@ -13,7 +13,7 @@ import (
var ( var (
// ErrGameNotFound indicates that a game was not found. // ErrGameNotFound indicates that a game was not found.
ErrGameNotFound = errors.New("Игра не найдена") ErrGameNotFound = errors.New("игра не найдена")
) )
// GamesRepo persists games. // GamesRepo persists games.
+1 -1
View File
@@ -12,7 +12,7 @@ import (
var ( var (
// ErrScenarioNotFound indicates that a scenario was not found. // ErrScenarioNotFound indicates that a scenario was not found.
ErrScenarioNotFound = errors.New("Сценарий не найден") ErrScenarioNotFound = errors.New("сценарий не найден")
) )
// ScenariosRepo persists scenarios. // ScenariosRepo persists scenarios.
+1 -1
View File
@@ -11,7 +11,7 @@ import (
) )
// ErrScreenNotFound indicates that a screen session was not found. // ErrScreenNotFound indicates that a screen session was not found.
var ErrScreenNotFound = errors.New("Экран не найден") var ErrScreenNotFound = errors.New("экран не найден")
// ScreenSession describes a screen session. // ScreenSession describes a screen session.
type ScreenSession struct { type ScreenSession struct {
+4 -4
View File
@@ -12,13 +12,13 @@ import (
) )
// ErrParticipationLink indicates that a participation link is invalid. // ErrParticipationLink indicates that a participation link is invalid.
var ErrParticipationLink = errors.New("Ссылка недействительна") var ErrParticipationLink = errors.New("ссылка недействительна")
// ErrParticipationClosed indicates that participation answers are closed. // ErrParticipationClosed indicates that participation answers are closed.
var ErrParticipationClosed = errors.New("Приём ответов закрыт") var ErrParticipationClosed = errors.New("приём ответов закрыт")
// ErrParticipationFinal indicates that a final answer cannot be changed. // ErrParticipationFinal indicates that a final answer cannot be changed.
var ErrParticipationFinal = errors.New("Решение уже принято и не может быть изменено") var ErrParticipationFinal = errors.New("решение уже принято и не может быть изменено")
const maxParticipationEmailAttempts = 8 const maxParticipationEmailAttempts = 8
@@ -80,7 +80,7 @@ func (r *TeamsRepo) GetParticipation(ctx context.Context, token string) (*Partic
// AnswerParticipation stores a team's final answer. // AnswerParticipation stores a team's final answer.
func (r *TeamsRepo) AnswerParticipation(ctx context.Context, token, answer string) (*Participation, error) { func (r *TeamsRepo) AnswerParticipation(ctx context.Context, token, answer string) (*Participation, error) {
if answer != "confirmed" && answer != "cancelled" { if answer != "confirmed" && answer != "cancelled" {
return nil, errors.New("Выберите подтверждение или отмену участия") return nil, errors.New("выберите подтверждение или отмену участия")
} }
hash, err := tokenHash(token) hash, err := tokenHash(token)
if err != nil { if err != nil {
+2 -2
View File
@@ -11,7 +11,7 @@ import (
var ( var (
// ErrTeamNotFound indicates that a team was not found. // ErrTeamNotFound indicates that a team was not found.
ErrTeamNotFound = errors.New("Команда не найдена") ErrTeamNotFound = errors.New("команда не найдена")
) )
// TeamsRepo persists teams and their game membership. // TeamsRepo persists teams and their game membership.
@@ -189,7 +189,7 @@ func (r *TeamsRepo) DeleteTeam(ctx context.Context, teamID int) error {
} }
// ErrRegistrationClosed indicates that team registration is unavailable. // ErrRegistrationClosed indicates that team registration is unavailable.
var ErrRegistrationClosed = errors.New("Игра не найдена или регистрация уже закрыта") var ErrRegistrationClosed = errors.New("игра не найдена или регистрация уже закрыта")
func (r *TeamsRepo) RegisterTeam(ctx context.Context, gameID int, deliveryID, name, email string, participantsCount int32, password string) (int, error) { func (r *TeamsRepo) RegisterTeam(ctx context.Context, gameID int, deliveryID, name, email string, participantsCount int32, password string) (int, error) {
return r.RegisterTeamWithParticipation(ctx, gameID, deliveryID, name, email, participantsCount, password, false) return r.RegisterTeamWithParticipation(ctx, gameID, deliveryID, name, email, participantsCount, password, false)
+3 -3
View File
@@ -11,11 +11,11 @@ import (
var ( var (
// ErrTicketNotFound indicates that a ticket was not found. // ErrTicketNotFound indicates that a ticket was not found.
ErrTicketNotFound = errors.New("Билет не найден") ErrTicketNotFound = errors.New("билет не найден")
// ErrTicketUsed indicates that a ticket was already used. // ErrTicketUsed indicates that a ticket was already used.
ErrTicketUsed = errors.New("Билет уже использован") ErrTicketUsed = errors.New("билет уже использован")
// ErrGameFinished indicates that the game has finished. // ErrGameFinished indicates that the game has finished.
ErrGameFinished = errors.New("Игра уже завершена") ErrGameFinished = errors.New("игра уже завершена")
) )
// Info describes a support ticket. // Info describes a support ticket.
+4 -4
View File
@@ -15,7 +15,7 @@ import (
var ( var (
// ErrUserNotFound indicates that a user was not found. // ErrUserNotFound indicates that a user was not found.
ErrUserNotFound = errors.New("Пользователь не найден") ErrUserNotFound = errors.New("пользователь не найден")
) )
// UsersRepo persists users and their roles. // UsersRepo persists users and their roles.
@@ -39,7 +39,7 @@ func (s *UsersRepo) AddUserWithAgreements(
agreements []user_agreements_repo.Agreement, agreements []user_agreements_repo.Agreement,
) (int, error) { ) (int, error) {
if len(agreements) == 0 { if len(agreements) == 0 {
return 0, errors.New("Не переданы записи об акцепте соглашений") return 0, errors.New("не переданы записи об акцепте соглашений")
} }
tx, err := s.pool.Begin(ctx) tx, err := s.pool.Begin(ctx)
@@ -68,11 +68,11 @@ func (s *UsersRepo) AddUserWithAgreements(
).Scan(&id) ).Scan(&id)
if err != nil { if err != nil {
if errors.Is(err, pgx.ErrNoRows) { if errors.Is(err, pgx.ErrNoRows) {
return 0, errors.New("Username или email уже используется") return 0, errors.New("username или email уже используется")
} }
var pgErr *pgconn.PgError var pgErr *pgconn.PgError
if errors.As(err, &pgErr) && pgErr.Code == "23505" { if errors.As(err, &pgErr) && pgErr.Code == "23505" {
return 0, errors.New("Username или email уже используется") return 0, errors.New("username или email уже используется")
} }
return 0, err return 0, err
} }
+7 -7
View File
@@ -40,13 +40,13 @@ func NewAnswerService(
} }
var ( var (
ErrTeamNotFound = errors.New("Команда не найдена") ErrTeamNotFound = errors.New("команда не найдена")
ErrGameNotFound = errors.New("Игра не найдена") ErrGameNotFound = errors.New("игра не найдена")
ErrGameFinished = errors.New("Игра завершена, ответы больше нельзя изменять") ErrGameFinished = errors.New("игра завершена, ответы больше нельзя изменять")
ErrGameNotStarted = errors.New("Игра не начата, отвечать на вопросы нельзя") ErrGameNotStarted = errors.New("игра не начата, отвечать на вопросы нельзя")
ErrQuestionNotFound = errors.New("Вопрос не найден") ErrQuestionNotFound = errors.New("вопрос не найден")
ErrGameNotFinished = errors.New("Итоги доступны после завершения игры") ErrGameNotFinished = errors.New("итоги доступны после завершения игры")
ErrOfflineAnswers = errors.New("В offline-игре ответы через сайт недоступны") ErrOfflineAnswers = errors.New("в offline-игре ответы через сайт недоступны")
) )
func (s *AnswerService) getTeamAndGame(ctx context.Context, teamID int, password string) (*repos.Team, *repos.Game, error) { func (s *AnswerService) getTeamAndGame(ctx context.Context, teamID int, password string) (*repos.Team, *repos.Game, error) {
@@ -19,19 +19,19 @@ import (
var ( var (
// ErrTeamNotFound indicates that a team was not found. // ErrTeamNotFound indicates that a team was not found.
ErrTeamNotFound = errors.New("Команда не найдена") ErrTeamNotFound = errors.New("команда не найдена")
// ErrGameNotFound indicates that a game was not found. // ErrGameNotFound indicates that a game was not found.
ErrGameNotFound = errors.New("Игра не найдена") ErrGameNotFound = errors.New("игра не найдена")
// ErrReviewNotFound indicates that a review was not found. // ErrReviewNotFound indicates that a review was not found.
ErrReviewNotFound = errors.New("Отзыв не найден") ErrReviewNotFound = errors.New("отзыв не найден")
// ErrReviewExists indicates that a team already submitted a review. // ErrReviewExists indicates that a team already submitted a review.
ErrReviewExists = errors.New("Отзыв от команды уже оставлен") ErrReviewExists = errors.New("отзыв от команды уже оставлен")
// ErrInvalidStatus indicates that a moderation status is invalid. // ErrInvalidStatus indicates that a moderation status is invalid.
ErrInvalidStatus = errors.New("Недопустимый статус модерации") ErrInvalidStatus = errors.New("недопустимый статус модерации")
// ErrGameNotFinished indicates that the game is not finished. // ErrGameNotFinished indicates that the game is not finished.
ErrGameNotFinished = errors.New("Оценить можно только завершённую игру") ErrGameNotFinished = errors.New("оценить можно только завершённую игру")
// ErrInvalidReview indicates that review data is invalid. // ErrInvalidReview indicates that review data is invalid.
ErrInvalidReview = errors.New("Оценка должна быть от 1 до 5, текст обязателен") ErrInvalidReview = errors.New("оценка должна быть от 1 до 5, текст обязателен")
) )
// GameReviewService handles game reviews. // GameReviewService handles game reviews.
+2 -2
View File
@@ -25,8 +25,8 @@ type GameService struct {
} }
var ( var (
ErrGameNotFound = errors.New("Игра не найдена") ErrGameNotFound = errors.New("игра не найдена")
ErrInvalidGameFormat = errors.New("Формат игры должен быть online или offline") ErrInvalidGameFormat = errors.New("формат игры должен быть online или offline")
) )
// NewGameService creates a game service. // NewGameService creates a game service.
@@ -16,9 +16,9 @@ import (
var ( var (
// ErrTeamNotFound indicates that a team was not found. // ErrTeamNotFound indicates that a team was not found.
ErrTeamNotFound = errors.New("Команда не найдена") ErrTeamNotFound = errors.New("команда не найдена")
// ErrGameNotFound indicates that a game was not found. // ErrGameNotFound indicates that a game was not found.
ErrGameNotFound = errors.New("Игра не найдена") ErrGameNotFound = errors.New("игра не найдена")
) )
// GameplayService handles team gameplay operations. // GameplayService handles team gameplay operations.
@@ -462,14 +462,14 @@ func TestSubmitAnswersValidation(t *testing.T) {
} }
func TestSubmitAnswersBusinessError(t *testing.T) { func TestSubmitAnswersBusinessError(t *testing.T) {
f := newMCPFixture(t, &fakeGamePlayer{err: errors.New("Игра завершена, ответы больше нельзя изменять")}) f := newMCPFixture(t, &fakeGamePlayer{err: errors.New("игра завершена, ответы больше нельзя изменять")})
got := f.call(t, "submit_answers", map[string]any{ got := f.call(t, "submit_answers", map[string]any{
"team_id": float64(10), "team_id": float64(10),
"password": "wrong", "password": "wrong",
"answers": []any{map[string]any{"questionCode": "q1", "answer": "x"}}, "answers": []any{map[string]any{"questionCode": "q1", "answer": "x"}},
}) })
if !strings.Contains(got, "Игра завершена") { if !strings.Contains(got, "игра завершена") {
t.Fatalf("submit_answers с ошибкой сервиса: %q; want error text", got) t.Fatalf("submit_answers с ошибкой сервиса: %q; want error text", got)
} }
} }
@@ -19,11 +19,11 @@ type Participation struct {
var ( var (
// ErrParticipationLink indicates that a participation link is invalid. // ErrParticipationLink indicates that a participation link is invalid.
ErrParticipationLink = errors.New("Ссылка недействительна") ErrParticipationLink = errors.New("ссылка недействительна")
// ErrParticipationClosed indicates that participation answers are closed. // ErrParticipationClosed indicates that participation answers are closed.
ErrParticipationClosed = errors.New("Приём ответов закрыт") ErrParticipationClosed = errors.New("приём ответов закрыт")
// ErrParticipationFinal indicates that a final answer cannot be changed. // ErrParticipationFinal indicates that a final answer cannot be changed.
ErrParticipationFinal = errors.New("Решение уже принято и не может быть изменено") ErrParticipationFinal = errors.New("решение уже принято и не может быть изменено")
// ErrInvalidAnswer indicates that the participation answer is invalid. // ErrInvalidAnswer indicates that the participation answer is invalid.
ErrInvalidAnswer = errors.New("Выберите подтверждение или отмену участия") ErrInvalidAnswer = errors.New("выберите подтверждение или отмену участия")
) )
@@ -145,7 +145,7 @@ func TestParticipationPostgres(t *testing.T) {
t.Fatalf("wrong eligible teams: %v", seen) t.Fatalf("wrong eligible teams: %v", seen)
} }
exec(`UPDATE teams SET participation_next_attempt_at=NULL`) exec(`UPDATE teams SET participation_next_attempt_at=NULL`)
sender := &participationSender{err: errors.New("SMTP unavailable")} sender := &participationSender{err: errors.New("smtp unavailable")}
if err := service.sendParticipationEmails(ctx, sender, "secret", time.UTC); err != nil { if err := service.sendParticipationEmails(ctx, sender, "secret", time.UTC); err != nil {
t.Fatal(err) t.Fatal(err)
} }
@@ -128,15 +128,15 @@ func (s *ScenarioService) UpdateScenarioByID(
return s.scenariosRepo.UpdateScenarioByID(ctx, id, name, description, image) return s.scenariosRepo.UpdateScenarioByID(ctx, id, name, description, image)
} }
var ErrScenarioPublished = errors.New("Опубликованный сценарий нельзя снять с публикации или удалить: исключительное право отчуждено Оператору") var ErrScenarioPublished = errors.New("опубликованный сценарий нельзя снять с публикации или удалить: исключительное право отчуждено оператору")
var ErrScenarioNotOwner = errors.New("Сценарий принадлежит другому пользователю") var ErrScenarioNotOwner = errors.New("сценарий принадлежит другому пользователю")
var ErrScenarioNotFound = errors.New("Сценарий не найден") var ErrScenarioNotFound = errors.New("сценарий не найден")
var ErrInvalidArchive = errors.New("Некорректный архив сценария") var ErrInvalidArchive = errors.New("некорректный архив сценария")
var ErrInvalidScenarioData = errors.New("Некорректные данные сценария") var ErrInvalidScenarioData = errors.New("некорректные данные сценария")
func MaxArchiveSize() int { func MaxArchiveSize() int {
return scenario_archive.MaxArchiveSize() return scenario_archive.MaxArchiveSize()
@@ -295,7 +295,7 @@ func (s *ScenarioService) UpdateScenarioBackground(ctx context.Context, id int,
return err return err
} }
if background != "" && file_storage.FileType(background) != "image" { if background != "" && file_storage.FileType(background) != "image" {
return errors.New("Фон дела должен быть изображением") return errors.New("фон дела должен быть изображением")
} }
story, err := s.getStory(ctx, id) story, err := s.getStory(ctx, id)
if err != nil { if err != nil {
+1 -1
View File
@@ -8,7 +8,7 @@ import (
) )
// ErrScreenNotFound indicates that a screen session was not found. // ErrScreenNotFound indicates that a screen session was not found.
var ErrScreenNotFound = errors.New("Экран не найден") var ErrScreenNotFound = errors.New("экран не найден")
// ScreenService handles screen sessions. // ScreenService handles screen sessions.
type ScreenService struct { type ScreenService struct {
@@ -11,10 +11,10 @@ import (
) )
var ( var (
ErrInvalidCaptainEmail = errors.New("Укажите корректную почту капитана") ErrInvalidCaptainEmail = errors.New("укажите корректную почту капитана")
ErrTeamNotFound = errors.New("Команда не найдена") ErrTeamNotFound = errors.New("команда не найдена")
ErrInvalidRegistration = errors.New("Укажите название команды (до 255 символов), почту капитана и положительное количество участников") ErrInvalidRegistration = errors.New("укажите название команды (до 255 символов), почту капитана и положительное количество участников")
ErrRegistrationClosed = errors.New("Игра не найдена или регистрация уже закрыта") ErrRegistrationClosed = errors.New("игра не найдена или регистрация уже закрыта")
) )
// Registration contains data required to register a team. // Registration contains data required to register a team.
+1 -1
View File
@@ -12,7 +12,7 @@ import (
) )
var ( var (
ErrGameNotFound = errors.New("Игра не найдена") ErrGameNotFound = errors.New("игра не найдена")
ErrNoCards = errors.New("нет карточек") ErrNoCards = errors.New("нет карточек")
) )
+3 -3
View File
@@ -23,11 +23,11 @@ var (
// ErrInvalidBaseURL indicates that the public application URL is missing. // ErrInvalidBaseURL indicates that the public application URL is missing.
ErrInvalidBaseURL = errors.New("необходимо настроить APP_BASE_URL — публичный адрес приложения") ErrInvalidBaseURL = errors.New("необходимо настроить APP_BASE_URL — публичный адрес приложения")
// ErrTicketNotFound indicates that a ticket was not found. // ErrTicketNotFound indicates that a ticket was not found.
ErrTicketNotFound = errors.New("Билет не найден") ErrTicketNotFound = errors.New("билет не найден")
// ErrTicketUsed indicates that a ticket was already used. // ErrTicketUsed indicates that a ticket was already used.
ErrTicketUsed = errors.New("Билет уже использован") ErrTicketUsed = errors.New("билет уже использован")
// ErrGameFinished indicates that the game has finished. // ErrGameFinished indicates that the game has finished.
ErrGameFinished = errors.New("Игра уже завершена") ErrGameFinished = errors.New("игра уже завершена")
) )
// Ticket describes an issued support ticket. // Ticket describes an issued support ticket.
@@ -90,7 +90,7 @@ func TestLoginAfterPasswordChangePreservesEmailCase(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
_, _, err := svc.Login(ctx, " User@Example.COM ", "new password 123") _, _, err := svc.Login(ctx, " User@Example.COM ", "new password 123")
if err == nil || err.Error() != "Не получилось получить доступ" { if err == nil || err.Error() != "не получилось получить доступ" {
t.Fatalf("lookup/password verification failed: %v", err) t.Fatalf("lookup/password verification failed: %v", err)
} }
_, _, err = svc.Login(ctx, "user@example.com", "new password 123") _, _, err = svc.Login(ctx, "user@example.com", "new password 123")
+15 -15
View File
@@ -76,17 +76,17 @@ func NewUsersService(
} }
var ( var (
ErrTermsNotAccepted = errors.New("Необходимо принять Пользовательское соглашение и Политику конфиденциальности") ErrTermsNotAccepted = errors.New("необходимо принять пользовательское соглашение и политику конфиденциальности")
// ErrInvalidEmail indicates that an email address is invalid. // ErrInvalidEmail indicates that an email address is invalid.
ErrInvalidEmail = errors.New("Некорректный email") ErrInvalidEmail = errors.New("некорректный email")
// ErrInvalidCredentials indicates that the supplied credentials are invalid. // ErrInvalidCredentials indicates that the supplied credentials are invalid.
ErrInvalidCredentials = errors.New("Не верен email или пароль") ErrInvalidCredentials = errors.New("не верен email или пароль")
// ErrInvalidAccountPassword indicates that the account password is invalid. // ErrInvalidAccountPassword indicates that the account password is invalid.
ErrInvalidAccountPassword = errors.New("Неверный пароль") ErrInvalidAccountPassword = errors.New("неверный пароль")
// ErrInvalidRefreshToken indicates that a refresh token is invalid. // ErrInvalidRefreshToken indicates that a refresh token is invalid.
ErrInvalidRefreshToken = errors.New("Пользователь не найден") ErrInvalidRefreshToken = errors.New("пользователь не найден")
// ErrInvalidRole indicates that a role is invalid. // ErrInvalidRole indicates that a role is invalid.
ErrInvalidRole = errors.New("Недопустимая роль") ErrInvalidRole = errors.New("недопустимая роль")
) )
// AddUser creates a user account. // AddUser creates a user account.
@@ -256,16 +256,16 @@ func (s *UsersService) Login(
accessToken, err := s.processorJWT.GenerateAccessToken(user.ID, user.Email, user.Roles) accessToken, err := s.processorJWT.GenerateAccessToken(user.ID, user.Email, user.Roles)
if err != nil { if err != nil {
return "", "", errors.New("Не получилось получить доступ") return "", "", errors.New("не получилось получить доступ")
} }
refreshToken, err := s.processorJWT.GenerateRefreshToken(user.ID) refreshToken, err := s.processorJWT.GenerateRefreshToken(user.ID)
if err != nil { if err != nil {
return "", "", errors.New("Не получилось получить доступ") return "", "", errors.New("не получилось получить доступ")
} }
refreshTokenClaims, err := s.processorJWT.GetClaims(refreshToken) refreshTokenClaims, err := s.processorJWT.GetClaims(refreshToken)
if err != nil { if err != nil {
return "", "", errors.New("Не получилось получить доступ") return "", "", errors.New("не получилось получить доступ")
} }
if err := s.refreshTokensRepo.AddRefreshToken(ctx, user.ID, refreshTokenClaims.ExpiresAt.Time, refreshTokenClaims.ID); err != nil { if err := s.refreshTokensRepo.AddRefreshToken(ctx, user.ID, refreshTokenClaims.ExpiresAt.Time, refreshTokenClaims.ID); err != nil {
@@ -307,16 +307,16 @@ func (s *UsersService) Refresh(
accessToken, err := s.processorJWT.GenerateAccessToken(user.ID, user.Email, user.Roles) accessToken, err := s.processorJWT.GenerateAccessToken(user.ID, user.Email, user.Roles)
if err != nil { if err != nil {
return "", "", errors.New("Не получилось получить доступ") return "", "", errors.New("не получилось получить доступ")
} }
refreshToken, err := s.processorJWT.GenerateRefreshToken(user.ID) refreshToken, err := s.processorJWT.GenerateRefreshToken(user.ID)
if err != nil { if err != nil {
return "", "", errors.New("Не получилось получить доступ") return "", "", errors.New("не получилось получить доступ")
} }
refreshTokenClaims, err := s.processorJWT.GetClaims(refreshToken) refreshTokenClaims, err := s.processorJWT.GetClaims(refreshToken)
if err != nil { if err != nil {
return "", "", errors.New("Не получилось получить доступ") return "", "", errors.New("не получилось получить доступ")
} }
if err := s.refreshTokensRepo.AddRefreshToken(ctx, user.ID, refreshTokenClaims.ExpiresAt.Time, refreshTokenClaims.ID); err != nil { if err := s.refreshTokensRepo.AddRefreshToken(ctx, user.ID, refreshTokenClaims.ExpiresAt.Time, refreshTokenClaims.ID); err != nil {
@@ -386,10 +386,10 @@ func (s *UsersService) DeleteUserRole(
var ( var (
// ErrPasswordChangeForbidden indicates that the password cannot be changed. // ErrPasswordChangeForbidden indicates that the password cannot be changed.
ErrPasswordChangeForbidden = errors.New("Изменять чужой пароль может только администратор") ErrPasswordChangeForbidden = errors.New("изменять чужой пароль может только администратор")
// ErrInvalidPasswordChange indicates that the password change request is invalid. // ErrInvalidPasswordChange indicates that the password change request is invalid.
ErrInvalidPasswordChange = errors.New("Укажите чужой положительный ID и пароль от 8 до 16 символов") ErrInvalidPasswordChange = errors.New("укажите чужой положительный ID и пароль от 8 до 16 символов")
ErrUserNotFound = errors.New("Пользователь не найден") ErrUserNotFound = errors.New("пользователь не найден")
) )
// ChangeUserPassword changes a user's password subject to authorization checks. // ChangeUserPassword changes a user's password subject to authorization checks.
@@ -60,7 +60,7 @@ func (r *fakeRepo) AddUserWithAgreements(
r.mu.Lock() r.mu.Lock()
defer r.mu.Unlock() defer r.mu.Unlock()
if _, ok := r.users[email]; ok { if _, ok := r.users[email]; ok {
return 0, errors.New("Username или email уже используется") return 0, errors.New("username или email уже используется")
} }
id := r.nextID id := r.nextID
r.nextID++ r.nextID++