Stage 17 round 6 (#10 backend): enforce chat only on your turn
CI / changes (pull_request) Successful in 1s
CI / unit (pull_request) Successful in 8s
CI / integration (pull_request) Successful in 11s
CI / ui (pull_request) Successful in 30s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m3s

PostMessage now rejects a chat sent on a finished game or when it is not the sender's
turn (ErrChatNotYourTurn -> 409 chat_not_your_turn), matching the UI where the message
field is hidden off-turn and only the nudge shows. Existing chat tests post on the
to-move seat and are unaffected; adds an off-turn-rejection integration test + the dto
mapping case + the UI error message.
This commit is contained in:
Ilia Denisov
2026-06-07 11:23:43 +02:00
parent 512ad4dfb9
commit 2cb2b57cdb
7 changed files with 34 additions and 2 deletions
+1
View File
@@ -48,6 +48,7 @@ func TestStatusForError(t *testing.T) {
"not your turn": {game.ErrNotYourTurn, http.StatusConflict, "not_your_turn"},
"nudge own turn": {social.ErrNudgeOnOwnTurn, http.StatusConflict, "nudge_own_turn"},
"nudge too soon": {social.ErrNudgeTooSoon, http.StatusConflict, "nudge_too_soon"},
"chat off turn": {social.ErrChatNotYourTurn, http.StatusConflict, "chat_not_your_turn"},
"illegal play": {engine.ErrIllegalPlay, http.StatusUnprocessableEntity, "illegal_play"},
"email taken": {account.ErrEmailTaken, http.StatusConflict, "email_taken"},
"code mismatch": {account.ErrCodeMismatch, http.StatusUnauthorized, "code_invalid"},
+2
View File
@@ -207,6 +207,8 @@ func statusForError(err error) (int, string) {
// A too-frequent nudge is a distinct, non-content rejection — the UI must say
// "don't rush the player so often", not the chat content-rejection message.
return http.StatusConflict, "nudge_too_soon"
case errors.Is(err, social.ErrChatNotYourTurn):
return http.StatusConflict, "chat_not_your_turn"
case errors.Is(err, social.ErrSelfRelation):
return http.StatusBadRequest, "self_relation"
case errors.Is(err, social.ErrRequestExists):