This commit is contained in:
2026-10-23 03:02:22 +07:00
parent 980ca18b60
commit 0879a8946a
20 changed files with 1827 additions and 960 deletions
@@ -7,6 +7,8 @@ func mapPlan(plan *game_screen_plans_repo.Plan) *Plan {
for _, step := range plan.Steps {
steps = append(steps, Step{
Mode: step.Mode,
QRURL: step.QRURL,
TimerType: step.TimerType,
Text: step.Text,
TimerLabel: step.TimerLabel,
TimerDurationSeconds: step.TimerDurationSeconds,
@@ -20,6 +22,8 @@ func mapSteps(steps []Step) []game_screen_plans_repo.Step {
for _, step := range steps {
mapped = append(mapped, game_screen_plans_repo.Step{
Mode: step.Mode,
QRURL: step.QRURL,
TimerType: step.TimerType,
Text: step.Text,
TimerLabel: step.TimerLabel,
TimerDurationSeconds: step.TimerDurationSeconds,
@@ -21,6 +21,8 @@ var (
// Step is a screen plan step used by the application layer.
type Step struct {
QRURL string
TimerType int32
Mode int32
Text string
TimerLabel string
@@ -103,13 +105,13 @@ func (s *ScreenPlanService) SetStep(ctx context.Context, gameID, currentStep int
func (s *ScreenPlanService) ApplyCurrent(ctx context.Context, gameID, screenID int) error {
plan, err := s.Get(ctx, gameID)
if errors.Is(err, ErrPlanNotFound) {
return s.screenService.InitializeScreen(ctx, screenID, gameID, 1, "", "Перерыв", 600)
return s.screenService.InitializeScreen(ctx, screenID, gameID, 1, "", "Перерыв", 600, "", 0)
}
if err != nil {
return err
}
step := plan.Steps[plan.CurrentStep]
return s.screenService.InitializeScreen(ctx, screenID, gameID, step.Mode, step.Text, step.TimerLabel, step.TimerDurationSeconds)
return s.screenService.InitializeScreen(ctx, screenID, gameID, step.Mode, step.Text, step.TimerLabel, step.TimerDurationSeconds, step.QRURL, step.TimerType)
}
func normalizePlan(steps []Step, currentStep int) ([]Step, error) {
@@ -126,12 +128,18 @@ func normalizePlan(steps []Step, currentStep int) ([]Step, error) {
if step.Mode == 8 && (step.Text == "" || len(step.Text) > 10000) {
return nil, ErrInvalidPlan
}
if step.Mode == 9 && !screen_service.ValidQR(step.QRURL, step.Text) {
return nil, ErrInvalidPlan
}
if !screen_service.ValidTimerType(step.TimerType) {
return nil, ErrInvalidPlan
}
if step.Mode == 7 {
if step.TimerDurationSeconds <= 0 || step.TimerDurationSeconds > 24*60*60 {
return nil, ErrInvalidPlan
}
if step.TimerLabel == "" {
step.TimerLabel = "Перерыв"
step.TimerLabel = screen_service.TimerLabel(step.TimerType)
}
if len(step.TimerLabel) > 200 {
return nil, ErrInvalidPlan
@@ -144,11 +152,14 @@ func normalizePlan(steps []Step, currentStep int) ([]Step, error) {
func (s *ScreenPlanService) applyStep(ctx context.Context, gameID int, plan *Plan) error {
step := plan.Steps[plan.CurrentStep]
if step.Mode == 9 {
return s.screenService.SetQR(ctx, gameID, step.QRURL, step.Text)
}
if step.Mode == 8 {
return s.screenService.SetText(ctx, gameID, step.Text)
}
if step.Mode == 7 {
return s.screenService.SetTimer(ctx, gameID, step.TimerDurationSeconds, step.TimerLabel)
return s.screenService.SetTimer(ctx, gameID, step.TimerDurationSeconds, step.TimerLabel, step.TimerType)
}
return s.screenService.SetMode(ctx, gameID, step.Mode)
}
@@ -3,6 +3,8 @@ package screen_plan_service
import (
"errors"
"testing"
"evening_detective_server/internal/repos/game_screen_plans_repo"
)
func TestNormalizePlan(t *testing.T) {
@@ -52,3 +54,38 @@ func TestNormalizePlan(t *testing.T) {
})
}
}
func TestNormalizeNewScreens(t *testing.T) {
tests := []struct {
name string
step Step
wantLabel string
wantErr bool
}{
{name: "QR", step: Step{Mode: 9, QRURL: "https://example.org", Text: ""}},
{name: "teams", step: Step{Mode: 10}},
{name: "invalid QR", step: Step{Mode: 9, QRURL: "javascript:alert(1)"}, wantErr: true},
{name: "before game", step: Step{Mode: 7, TimerType: 1, TimerDurationSeconds: 60}, wantLabel: "До начала игры"},
{name: "until end", step: Step{Mode: 7, TimerType: 2, TimerDurationSeconds: 60}, wantLabel: "До конца игры"},
{name: "custom legacy", step: Step{Mode: 7, TimerLabel: "Обсуждение", TimerDurationSeconds: 60}, wantLabel: "Обсуждение"},
{name: "invalid type", step: Step{Mode: 7, TimerType: 3, TimerDurationSeconds: 60}, wantErr: true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := normalizePlan([]Step{tt.step}, 0)
if (err != nil) != tt.wantErr {
t.Fatalf("normalizePlan() error: %v", err)
}
if tt.wantErr {
return
}
if result[0].TimerLabel != tt.wantLabel {
t.Fatalf("label = %q", result[0].TimerLabel)
}
roundTrip := mapPlan(&game_screen_plans_repo.Plan{Steps: mapSteps(result)})
if roundTrip.Steps[0] != result[0] {
t.Fatal("lost step fields")
}
})
}
}