feat(payments): report direct-rail income to «Мой налог» #295

Merged
developer merged 4 commits from feature/mynalog-export into development 2026-07-28 14:50:14 +00:00
Showing only changes of commit f8efa21158 - Show all commits
+18 -2
View File
@@ -4,6 +4,7 @@ package inttest
import (
"context"
"errors"
"testing"
"github.com/google/uuid"
@@ -64,8 +65,15 @@ func TestNoRepeatWordsPinnedFromTheVariant(t *testing.T) {
func TestNoRepeatWordsHonoursThePinNotTheVariant(t *testing.T) {
ctx := context.Background()
svc := newGameService()
g := createTwoSeatGame(t, svc, engine.VariantErudit)
// Each game draws from a bag seeded with crypto/rand, so an opening rack occasionally has no
// playable word at all. That is a legitimate engine answer which says nothing about the pin
// under test, and taking it for a failure made this test flake (~1 run in 300 on the committed
// dictionary, and more often on another one). Retry with fresh games instead: one unlucky draw
// no longer decides the result, while a genuinely broken path still fails every attempt.
const draws = 5
for attempt := 1; ; attempt++ {
g := createTwoSeatGame(t, svc, engine.VariantErudit)
if _, err := testDB.ExecContext(ctx,
`UPDATE backend.games SET no_repeat_words = false WHERE game_id = $1`, g.ID); err != nil {
t.Fatalf("clear the pin: %v", err)
@@ -80,7 +88,15 @@ func TestNoRepeatWordsHonoursThePinNotTheVariant(t *testing.T) {
}
// The rule reaches the engine from the row, so the reconstructed game plays unrestricted:
// its generated moves are the solver's full list, none filtered away.
if _, err := svc.Hint(ctx, reloaded.ID, reloaded.Seats[reloaded.ToMove].AccountID); err != nil {
_, err = svc.Hint(ctx, reloaded.ID, reloaded.Seats[reloaded.ToMove].AccountID)
if err == nil {
return
}
if !errors.Is(err, game.ErrNoHintAvailable) {
t.Fatalf("hint on an unrestricted Erudit game: %v", err)
}
if attempt == draws {
t.Fatalf("no opening rack in %d games had a playable move", draws)
}
}
}