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
code codes.Code
}{
{"not found", "Игра не найдена", game_service.ErrGameNotFound, codes.NotFound},
{"invalid format", "Формат игры должен быть online или offline", game_service.ErrInvalidGameFormat, codes.InvalidArgument},
{"not found", "игра не найдена", game_service.ErrGameNotFound, codes.NotFound},
{"invalid format", "формат игры должен быть online или offline", game_service.ErrInvalidGameFormat, codes.InvalidArgument},
{"internal", "не удалось получить игру", errors.New("private database detail"), codes.Internal},
} {
t.Run(tc.name, func(t *testing.T) {
@@ -36,9 +36,9 @@ func TestAnswerErrorStatus(t *testing.T) {
err error
code codes.Code
}{
{"team not found", "Команда не найдена", answer_service.ErrTeamNotFound, codes.NotFound},
{"question not found", "Вопрос не найден", answer_service.ErrQuestionNotFound, codes.InvalidArgument},
{"game not started", "Игра не начата, отвечать на вопросы нельзя", answer_service.ErrGameNotStarted, codes.FailedPrecondition},
{"team not found", "команда не найдена", answer_service.ErrTeamNotFound, codes.NotFound},
{"question not found", "вопрос не найден", answer_service.ErrQuestionNotFound, codes.InvalidArgument},
{"game not started", "игра не начата, отвечать на вопросы нельзя", answer_service.ErrGameNotStarted, codes.FailedPrecondition},
{"internal", "не удалось получить ответы игры", errors.New("private database detail"), codes.Internal},
} {
t.Run(tc.name, func(t *testing.T) {
+4 -4
View File
@@ -17,10 +17,10 @@ func TestParticipationErrorStatus(t *testing.T) {
code codes.Code
want string
}{
{"invalid link", participation_service.ErrParticipationLink, codes.NotFound, "Ссылка недействительна"},
{"invalid answer", participation_service.ErrInvalidAnswer, codes.InvalidArgument, "Выберите подтверждение или отмену участия"},
{"closed", participation_service.ErrParticipationClosed, codes.FailedPrecondition, "Приём ответов закрыт"},
{"final", participation_service.ErrParticipationFinal, codes.FailedPrecondition, "Решение уже принято и не может быть изменено"},
{"invalid link", participation_service.ErrParticipationLink, codes.NotFound, "ссылка недействительна"},
{"invalid answer", participation_service.ErrInvalidAnswer, codes.InvalidArgument, "выберите подтверждение или отмену участия"},
{"closed", participation_service.ErrParticipationClosed, codes.FailedPrecondition, "приём ответов закрыт"},
{"final", participation_service.ErrParticipationFinal, codes.FailedPrecondition, "решение уже принято и не может быть изменено"},
{"internal", errors.New("private database detail"), codes.Internal, "participation failed"},
} {
t.Run(tc.name, func(t *testing.T) {
+2 -2
View File
@@ -17,8 +17,8 @@ func TestScenarioErrorStatus(t *testing.T) {
code codes.Code
message string
}{
{"not found", "scenario failed", scenarios_service.ErrScenarioNotFound, codes.NotFound, "Сценарий не найден"},
{"not owner", "scenario failed", scenarios_service.ErrScenarioNotOwner, codes.PermissionDenied, "Сценарий принадлежит другому пользователю"},
{"not found", "scenario failed", scenarios_service.ErrScenarioNotFound, codes.NotFound, "сценарий не найден"},
{"not owner", "scenario failed", scenarios_service.ErrScenarioNotOwner, codes.PermissionDenied, "сценарий принадлежит другому пользователю"},
{"published", "scenario failed", scenarios_service.ErrScenarioPublished, codes.FailedPrecondition, scenarios_service.ErrScenarioPublished.Error()},
{"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
message string
}{
{"game not found", "add failed", team_service.ErrGameNotFound, codes.NotFound, "Игра не найдена"},
{"team not found", "delete failed", team_service.ErrTeamNotFound, codes.NotFound, "Команда не найдена"},
{"invalid captain email", "add failed", team_service.ErrInvalidCaptainEmail, codes.InvalidArgument, "Укажите корректную почту капитана"},
{"game not found", "add failed", team_service.ErrGameNotFound, codes.NotFound, "игра не найдена"},
{"team not found", "delete failed", team_service.ErrTeamNotFound, codes.NotFound, "команда не найдена"},
{"invalid captain email", "add failed", team_service.ErrInvalidCaptainEmail, codes.InvalidArgument, "укажите корректную почту капитана"},
{"internal", "add failed", errors.New("private database detail"), codes.Internal, "add failed"},
} {
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)
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 {
pdf.AddPage()
+1 -1
View File
@@ -10,7 +10,7 @@ import (
var (
// ErrActionsNotFound indicates that no actions were found.
ErrActionsNotFound = errors.New("Ход не найден")
ErrActionsNotFound = errors.New("ход не найден")
)
// ActionsRepo persists team actions.
+1 -1
View File
@@ -11,7 +11,7 @@ import (
var (
// ErrApplicationNotFound indicates that an application was not found.
ErrApplicationNotFound = errors.New("Улика не найдена")
ErrApplicationNotFound = errors.New("улика не найдена")
)
// ApplicationsRepo persists team applications.
+4 -4
View File
@@ -12,13 +12,13 @@ import (
var (
// ErrReviewNotFound indicates that a review was not found.
ErrReviewNotFound = errors.New("Отзыв не найден")
ErrReviewNotFound = errors.New("отзыв не найден")
// ErrReviewExists indicates that a team already submitted a review.
ErrReviewExists = errors.New("Отзыв от команды уже оставлен")
ErrReviewExists = errors.New("отзыв от команды уже оставлен")
// ErrTeamNotFound indicates that a team was not found.
ErrTeamNotFound = errors.New("Команда не найдена")
ErrTeamNotFound = errors.New("команда не найдена")
// ErrInvalidStatus indicates that a moderation status is invalid.
ErrInvalidStatus = errors.New("Недопустимый статус модерации")
ErrInvalidStatus = errors.New("недопустимый статус модерации")
)
// Review describes a game review.
+1 -1
View File
@@ -13,7 +13,7 @@ import (
var (
// ErrGameNotFound indicates that a game was not found.
ErrGameNotFound = errors.New("Игра не найдена")
ErrGameNotFound = errors.New("игра не найдена")
)
// GamesRepo persists games.
+1 -1
View File
@@ -12,7 +12,7 @@ import (
var (
// ErrScenarioNotFound indicates that a scenario was not found.
ErrScenarioNotFound = errors.New("Сценарий не найден")
ErrScenarioNotFound = errors.New("сценарий не найден")
)
// ScenariosRepo persists scenarios.
+1 -1
View File
@@ -11,7 +11,7 @@ import (
)
// ErrScreenNotFound indicates that a screen session was not found.
var ErrScreenNotFound = errors.New("Экран не найден")
var ErrScreenNotFound = errors.New("экран не найден")
// ScreenSession describes a screen session.
type ScreenSession struct {
+4 -4
View File
@@ -12,13 +12,13 @@ import (
)
// ErrParticipationLink indicates that a participation link is invalid.
var ErrParticipationLink = errors.New("Ссылка недействительна")
var ErrParticipationLink = errors.New("ссылка недействительна")
// ErrParticipationClosed indicates that participation answers are closed.
var ErrParticipationClosed = errors.New("Приём ответов закрыт")
var ErrParticipationClosed = errors.New("приём ответов закрыт")
// ErrParticipationFinal indicates that a final answer cannot be changed.
var ErrParticipationFinal = errors.New("Решение уже принято и не может быть изменено")
var ErrParticipationFinal = errors.New("решение уже принято и не может быть изменено")
const maxParticipationEmailAttempts = 8
@@ -80,7 +80,7 @@ func (r *TeamsRepo) GetParticipation(ctx context.Context, token string) (*Partic
// AnswerParticipation stores a team's final answer.
func (r *TeamsRepo) AnswerParticipation(ctx context.Context, token, answer string) (*Participation, error) {
if answer != "confirmed" && answer != "cancelled" {
return nil, errors.New("Выберите подтверждение или отмену участия")
return nil, errors.New("выберите подтверждение или отмену участия")
}
hash, err := tokenHash(token)
if err != nil {
+2 -2
View File
@@ -11,7 +11,7 @@ import (
var (
// ErrTeamNotFound indicates that a team was not found.
ErrTeamNotFound = errors.New("Команда не найдена")
ErrTeamNotFound = errors.New("команда не найдена")
)
// 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.
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) {
return r.RegisterTeamWithParticipation(ctx, gameID, deliveryID, name, email, participantsCount, password, false)
+3 -3
View File
@@ -11,11 +11,11 @@ import (
var (
// ErrTicketNotFound indicates that a ticket was not found.
ErrTicketNotFound = errors.New("Билет не найден")
ErrTicketNotFound = errors.New("билет не найден")
// ErrTicketUsed indicates that a ticket was already used.
ErrTicketUsed = errors.New("Билет уже использован")
ErrTicketUsed = errors.New("билет уже использован")
// ErrGameFinished indicates that the game has finished.
ErrGameFinished = errors.New("Игра уже завершена")
ErrGameFinished = errors.New("игра уже завершена")
)
// Info describes a support ticket.
+4 -4
View File
@@ -15,7 +15,7 @@ import (
var (
// ErrUserNotFound indicates that a user was not found.
ErrUserNotFound = errors.New("Пользователь не найден")
ErrUserNotFound = errors.New("пользователь не найден")
)
// UsersRepo persists users and their roles.
@@ -39,7 +39,7 @@ func (s *UsersRepo) AddUserWithAgreements(
agreements []user_agreements_repo.Agreement,
) (int, error) {
if len(agreements) == 0 {
return 0, errors.New("Не переданы записи об акцепте соглашений")
return 0, errors.New("не переданы записи об акцепте соглашений")
}
tx, err := s.pool.Begin(ctx)
@@ -68,11 +68,11 @@ func (s *UsersRepo) AddUserWithAgreements(
).Scan(&id)
if err != nil {
if errors.Is(err, pgx.ErrNoRows) {
return 0, errors.New("Username или email уже используется")
return 0, errors.New("username или email уже используется")
}
var pgErr *pgconn.PgError
if errors.As(err, &pgErr) && pgErr.Code == "23505" {
return 0, errors.New("Username или email уже используется")
return 0, errors.New("username или email уже используется")
}
return 0, err
}
+7 -7
View File
@@ -40,13 +40,13 @@ func NewAnswerService(
}
var (
ErrTeamNotFound = errors.New("Команда не найдена")
ErrGameNotFound = errors.New("Игра не найдена")
ErrGameFinished = errors.New("Игра завершена, ответы больше нельзя изменять")
ErrGameNotStarted = errors.New("Игра не начата, отвечать на вопросы нельзя")
ErrQuestionNotFound = errors.New("Вопрос не найден")
ErrGameNotFinished = errors.New("Итоги доступны после завершения игры")
ErrOfflineAnswers = errors.New("В offline-игре ответы через сайт недоступны")
ErrTeamNotFound = errors.New("команда не найдена")
ErrGameNotFound = errors.New("игра не найдена")
ErrGameFinished = errors.New("игра завершена, ответы больше нельзя изменять")
ErrGameNotStarted = errors.New("игра не начата, отвечать на вопросы нельзя")
ErrQuestionNotFound = errors.New("вопрос не найден")
ErrGameNotFinished = errors.New("итоги доступны после завершения игры")
ErrOfflineAnswers = errors.New("в offline-игре ответы через сайт недоступны")
)
func (s *AnswerService) getTeamAndGame(ctx context.Context, teamID int, password string) (*repos.Team, *repos.Game, error) {
@@ -19,19 +19,19 @@ import (
var (
// ErrTeamNotFound indicates that a team was not found.
ErrTeamNotFound = errors.New("Команда не найдена")
ErrTeamNotFound = errors.New("команда не найдена")
// ErrGameNotFound indicates that a game was not found.
ErrGameNotFound = errors.New("Игра не найдена")
ErrGameNotFound = errors.New("игра не найдена")
// ErrReviewNotFound indicates that a review was not found.
ErrReviewNotFound = errors.New("Отзыв не найден")
ErrReviewNotFound = errors.New("отзыв не найден")
// ErrReviewExists indicates that a team already submitted a review.
ErrReviewExists = errors.New("Отзыв от команды уже оставлен")
ErrReviewExists = errors.New("отзыв от команды уже оставлен")
// ErrInvalidStatus indicates that a moderation status is invalid.
ErrInvalidStatus = errors.New("Недопустимый статус модерации")
ErrInvalidStatus = errors.New("недопустимый статус модерации")
// ErrGameNotFinished indicates that the game is not finished.
ErrGameNotFinished = errors.New("Оценить можно только завершённую игру")
ErrGameNotFinished = errors.New("оценить можно только завершённую игру")
// ErrInvalidReview indicates that review data is invalid.
ErrInvalidReview = errors.New("Оценка должна быть от 1 до 5, текст обязателен")
ErrInvalidReview = errors.New("оценка должна быть от 1 до 5, текст обязателен")
)
// GameReviewService handles game reviews.
+2 -2
View File
@@ -25,8 +25,8 @@ type GameService struct {
}
var (
ErrGameNotFound = errors.New("Игра не найдена")
ErrInvalidGameFormat = errors.New("Формат игры должен быть online или offline")
ErrGameNotFound = errors.New("игра не найдена")
ErrInvalidGameFormat = errors.New("формат игры должен быть online или offline")
)
// NewGameService creates a game service.
@@ -16,9 +16,9 @@ import (
var (
// ErrTeamNotFound indicates that a team was not found.
ErrTeamNotFound = errors.New("Команда не найдена")
ErrTeamNotFound = errors.New("команда не найдена")
// ErrGameNotFound indicates that a game was not found.
ErrGameNotFound = errors.New("Игра не найдена")
ErrGameNotFound = errors.New("игра не найдена")
)
// GameplayService handles team gameplay operations.
@@ -462,14 +462,14 @@ func TestSubmitAnswersValidation(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{
"team_id": float64(10),
"password": "wrong",
"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)
}
}
@@ -19,11 +19,11 @@ type Participation struct {
var (
// ErrParticipationLink indicates that a participation link is invalid.
ErrParticipationLink = errors.New("Ссылка недействительна")
ErrParticipationLink = errors.New("ссылка недействительна")
// ErrParticipationClosed indicates that participation answers are closed.
ErrParticipationClosed = errors.New("Приём ответов закрыт")
ErrParticipationClosed = errors.New("приём ответов закрыт")
// ErrParticipationFinal indicates that a final answer cannot be changed.
ErrParticipationFinal = errors.New("Решение уже принято и не может быть изменено")
ErrParticipationFinal = errors.New("решение уже принято и не может быть изменено")
// 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)
}
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 {
t.Fatal(err)
}
@@ -128,15 +128,15 @@ func (s *ScenarioService) UpdateScenarioByID(
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 {
return scenario_archive.MaxArchiveSize()
@@ -295,7 +295,7 @@ func (s *ScenarioService) UpdateScenarioBackground(ctx context.Context, id int,
return err
}
if background != "" && file_storage.FileType(background) != "image" {
return errors.New("Фон дела должен быть изображением")
return errors.New("фон дела должен быть изображением")
}
story, err := s.getStory(ctx, id)
if err != nil {
+1 -1
View File
@@ -8,7 +8,7 @@ import (
)
// ErrScreenNotFound indicates that a screen session was not found.
var ErrScreenNotFound = errors.New("Экран не найден")
var ErrScreenNotFound = errors.New("экран не найден")
// ScreenService handles screen sessions.
type ScreenService struct {
@@ -11,10 +11,10 @@ import (
)
var (
ErrInvalidCaptainEmail = errors.New("Укажите корректную почту капитана")
ErrTeamNotFound = errors.New("Команда не найдена")
ErrInvalidRegistration = errors.New("Укажите название команды (до 255 символов), почту капитана и положительное количество участников")
ErrRegistrationClosed = errors.New("Игра не найдена или регистрация уже закрыта")
ErrInvalidCaptainEmail = errors.New("укажите корректную почту капитана")
ErrTeamNotFound = errors.New("команда не найдена")
ErrInvalidRegistration = errors.New("укажите название команды (до 255 символов), почту капитана и положительное количество участников")
ErrRegistrationClosed = errors.New("игра не найдена или регистрация уже закрыта")
)
// Registration contains data required to register a team.
+1 -1
View File
@@ -12,7 +12,7 @@ import (
)
var (
ErrGameNotFound = errors.New("Игра не найдена")
ErrGameNotFound = errors.New("игра не найдена")
ErrNoCards = errors.New("нет карточек")
)
+3 -3
View File
@@ -23,11 +23,11 @@ var (
// ErrInvalidBaseURL indicates that the public application URL is missing.
ErrInvalidBaseURL = errors.New("необходимо настроить APP_BASE_URL — публичный адрес приложения")
// ErrTicketNotFound indicates that a ticket was not found.
ErrTicketNotFound = errors.New("Билет не найден")
ErrTicketNotFound = errors.New("билет не найден")
// ErrTicketUsed indicates that a ticket was already used.
ErrTicketUsed = errors.New("Билет уже использован")
ErrTicketUsed = errors.New("билет уже использован")
// ErrGameFinished indicates that the game has finished.
ErrGameFinished = errors.New("Игра уже завершена")
ErrGameFinished = errors.New("игра уже завершена")
)
// Ticket describes an issued support ticket.
@@ -90,7 +90,7 @@ func TestLoginAfterPasswordChangePreservesEmailCase(t *testing.T) {
t.Fatal(err)
}
_, _, 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)
}
_, _, err = svc.Login(ctx, "user@example.com", "new password 123")
+15 -15
View File
@@ -76,17 +76,17 @@ func NewUsersService(
}
var (
ErrTermsNotAccepted = errors.New("Необходимо принять Пользовательское соглашение и Политику конфиденциальности")
ErrTermsNotAccepted = errors.New("необходимо принять пользовательское соглашение и политику конфиденциальности")
// 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 = errors.New("Не верен email или пароль")
ErrInvalidCredentials = errors.New("не верен email или пароль")
// ErrInvalidAccountPassword indicates that the account password is invalid.
ErrInvalidAccountPassword = errors.New("Неверный пароль")
ErrInvalidAccountPassword = errors.New("неверный пароль")
// ErrInvalidRefreshToken indicates that a refresh token is invalid.
ErrInvalidRefreshToken = errors.New("Пользователь не найден")
ErrInvalidRefreshToken = errors.New("пользователь не найден")
// ErrInvalidRole indicates that a role is invalid.
ErrInvalidRole = errors.New("Недопустимая роль")
ErrInvalidRole = errors.New("недопустимая роль")
)
// AddUser creates a user account.
@@ -256,16 +256,16 @@ func (s *UsersService) Login(
accessToken, err := s.processorJWT.GenerateAccessToken(user.ID, user.Email, user.Roles)
if err != nil {
return "", "", errors.New("Не получилось получить доступ")
return "", "", errors.New("не получилось получить доступ")
}
refreshToken, err := s.processorJWT.GenerateRefreshToken(user.ID)
if err != nil {
return "", "", errors.New("Не получилось получить доступ")
return "", "", errors.New("не получилось получить доступ")
}
refreshTokenClaims, err := s.processorJWT.GetClaims(refreshToken)
if err != nil {
return "", "", errors.New("Не получилось получить доступ")
return "", "", errors.New("не получилось получить доступ")
}
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)
if err != nil {
return "", "", errors.New("Не получилось получить доступ")
return "", "", errors.New("не получилось получить доступ")
}
refreshToken, err := s.processorJWT.GenerateRefreshToken(user.ID)
if err != nil {
return "", "", errors.New("Не получилось получить доступ")
return "", "", errors.New("не получилось получить доступ")
}
refreshTokenClaims, err := s.processorJWT.GetClaims(refreshToken)
if err != nil {
return "", "", errors.New("Не получилось получить доступ")
return "", "", errors.New("не получилось получить доступ")
}
if err := s.refreshTokensRepo.AddRefreshToken(ctx, user.ID, refreshTokenClaims.ExpiresAt.Time, refreshTokenClaims.ID); err != nil {
@@ -386,10 +386,10 @@ func (s *UsersService) DeleteUserRole(
var (
// ErrPasswordChangeForbidden indicates that the password cannot be changed.
ErrPasswordChangeForbidden = errors.New("Изменять чужой пароль может только администратор")
ErrPasswordChangeForbidden = errors.New("изменять чужой пароль может только администратор")
// ErrInvalidPasswordChange indicates that the password change request is invalid.
ErrInvalidPasswordChange = errors.New("Укажите чужой положительный ID и пароль от 8 до 16 символов")
ErrUserNotFound = errors.New("Пользователь не найден")
ErrInvalidPasswordChange = errors.New("укажите чужой положительный ID и пароль от 8 до 16 символов")
ErrUserNotFound = errors.New("пользователь не найден")
)
// ChangeUserPassword changes a user's password subject to authorization checks.
@@ -60,7 +60,7 @@ func (r *fakeRepo) AddUserWithAgreements(
r.mu.Lock()
defer r.mu.Unlock()
if _, ok := r.users[email]; ok {
return 0, errors.New("Username или email уже используется")
return 0, errors.New("username или email уже используется")
}
id := r.nextID
r.nextID++