generated from VLADIMIR/template
up
This commit is contained in:
+2
-2
@@ -1772,12 +1772,12 @@ message ResetGameLocalModeRsp {}
|
||||
message GameExportRsp { GameExport export = 1; }
|
||||
|
||||
enum ScreenMode {
|
||||
reserved 3, 5;
|
||||
reserved "SCREEN_MODE_INTRO_DONE", "SCREEN_MODE_CONCLUSION_DONE";
|
||||
SCREEN_MODE_UNSPECIFIED = 0;
|
||||
SCREEN_MODE_COVER = 1;
|
||||
SCREEN_MODE_INTRO = 2;
|
||||
SCREEN_MODE_INTRO_DONE = 3;
|
||||
SCREEN_MODE_CONCLUSION = 4;
|
||||
SCREEN_MODE_CONCLUSION_DONE = 5;
|
||||
SCREEN_MODE_RESULTS = 6;
|
||||
SCREEN_MODE_TIMER = 7;
|
||||
SCREEN_MODE_TEXT = 8;
|
||||
|
||||
Binary file not shown.
@@ -6048,9 +6048,7 @@
|
||||
"SCREEN_MODE_UNSPECIFIED",
|
||||
"SCREEN_MODE_COVER",
|
||||
"SCREEN_MODE_INTRO",
|
||||
"SCREEN_MODE_INTRO_DONE",
|
||||
"SCREEN_MODE_CONCLUSION",
|
||||
"SCREEN_MODE_CONCLUSION_DONE",
|
||||
"SCREEN_MODE_RESULTS",
|
||||
"SCREEN_MODE_TIMER",
|
||||
"SCREEN_MODE_TEXT"
|
||||
|
||||
@@ -271,7 +271,7 @@ func (s *server) SetScreenMode(ctx context.Context, req *proto.SetScreenModeReq)
|
||||
if !canManageScreens(ctx) {
|
||||
return nil, status.Error(codes.PermissionDenied, "permission denied")
|
||||
}
|
||||
if req == nil || req.GameID <= 0 || req.Mode == proto.ScreenMode_SCREEN_MODE_UNSPECIFIED {
|
||||
if req == nil || req.GameID <= 0 || !screen_service.ValidMode(int32(req.Mode)) {
|
||||
return nil, status.Error(codes.InvalidArgument, "некорректный режим экрана")
|
||||
}
|
||||
if _, err := s.gameService.GetGame(ctx, int(req.GameID)); err != nil {
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"evening_detective_server/internal/modules/processor_jwt"
|
||||
"evening_detective_server/proto"
|
||||
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
func TestSetScreenModeRejectsRemovedModes(t *testing.T) {
|
||||
ctx := processor_jwt.ContextWithClaims(context.Background(), &processor_jwt.JWTClaims{
|
||||
Roles: []string{"organizer"},
|
||||
})
|
||||
s := &server{}
|
||||
for _, mode := range []int32{3, 5} {
|
||||
_, err := s.SetScreenMode(ctx, &proto.SetScreenModeReq{
|
||||
GameID: 1,
|
||||
Mode: proto.ScreenMode(mode),
|
||||
})
|
||||
if status.Code(err) != codes.InvalidArgument {
|
||||
t.Errorf("SetScreenMode(%d) = %v, want InvalidArgument", mode, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -118,7 +118,7 @@ func normalizePlan(steps []Step, currentStep int) ([]Step, error) {
|
||||
}
|
||||
normalized := make([]Step, 0, len(steps))
|
||||
for _, step := range steps {
|
||||
if step.Mode <= 0 || step.Mode > 8 {
|
||||
if !screen_service.ValidMode(step.Mode) {
|
||||
return nil, ErrInvalidPlan
|
||||
}
|
||||
step.Text = strings.TrimSpace(step.Text)
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package screen_plan_service
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNormalizePlan(t *testing.T) {
|
||||
tests := []struct {
|
||||
@@ -16,6 +19,8 @@ func TestNormalizePlan(t *testing.T) {
|
||||
{Mode: 7, TimerDurationSeconds: 60},
|
||||
},
|
||||
},
|
||||
{name: "rejects removed intro mode", steps: []Step{{Mode: 3}}, wantErr: true},
|
||||
{name: "rejects removed conclusion mode", steps: []Step{{Mode: 5}}, wantErr: true},
|
||||
{
|
||||
name: "rejects empty text",
|
||||
steps: []Step{{Mode: 8}},
|
||||
@@ -36,6 +41,9 @@ func TestNormalizePlan(t *testing.T) {
|
||||
t.Fatalf("normalizePlan() error = %v, want error: %v", err, tt.wantErr)
|
||||
}
|
||||
if tt.wantErr {
|
||||
if !errors.Is(err, ErrInvalidPlan) {
|
||||
t.Fatalf("want ErrInvalidPlan, got %v", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if steps[0].Text != "Внимание" || steps[1].TimerLabel != "Перерыв" {
|
||||
|
||||
@@ -7,6 +7,9 @@ import (
|
||||
"evening_detective_server/internal/repos/screen_sessions_repo"
|
||||
)
|
||||
|
||||
// ErrInvalidMode indicates an unsupported display mode.
|
||||
var ErrInvalidMode = errors.New("некорректный режим экрана")
|
||||
|
||||
// ErrScreenNotFound indicates that a screen session was not found.
|
||||
var ErrScreenNotFound = errors.New("экран не найден")
|
||||
|
||||
@@ -47,8 +50,21 @@ func (s *ScreenService) ListByGame(ctx context.Context, gameID int) ([]*ScreenSe
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// ValidMode reports whether mode is a supported display mode.
|
||||
func ValidMode(mode int32) bool {
|
||||
switch mode {
|
||||
case 1, 2, 4, 6, 7, 8:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// SetMode updates the display mode for a game.
|
||||
func (s *ScreenService) SetMode(ctx context.Context, gameID int, mode int32) error {
|
||||
if !ValidMode(mode) {
|
||||
return ErrInvalidMode
|
||||
}
|
||||
return s.repo.SetMode(ctx, gameID, mode)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package screen_service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSetModeRejectsUnsupportedModes(t *testing.T) {
|
||||
s := NewScreenService(nil)
|
||||
for _, mode := range []int32{-1, 0, 3, 5, 9} {
|
||||
if err := s.SetMode(context.Background(), 1, mode); !errors.Is(err, ErrInvalidMode) {
|
||||
t.Errorf("SetMode(%d) = %v, want ErrInvalidMode", mode, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
-- +goose Up
|
||||
UPDATE game_screen_plans
|
||||
SET steps = (
|
||||
SELECT jsonb_agg(
|
||||
CASE WHEN step->>'mode' IN ('3', '5') THEN
|
||||
step || jsonb_build_object(
|
||||
'mode', 8,
|
||||
'text', CASE step->>'mode'
|
||||
WHEN '3' THEN 'Успехов'
|
||||
ELSE 'Спасибо за игру!'
|
||||
END
|
||||
)
|
||||
ELSE step END
|
||||
ORDER BY position
|
||||
)
|
||||
FROM jsonb_array_elements(steps) WITH ORDINALITY AS items(step, position)
|
||||
), updated_at = NOW()
|
||||
WHERE EXISTS (
|
||||
SELECT 1
|
||||
FROM jsonb_array_elements(steps) AS step
|
||||
WHERE step->>'mode' IN ('3', '5')
|
||||
);
|
||||
|
||||
UPDATE screen_sessions
|
||||
SET text = CASE mode WHEN 3 THEN 'Успехов' ELSE 'Спасибо за игру!' END,
|
||||
mode = 8,
|
||||
command = 0,
|
||||
state_version = state_version + 1,
|
||||
updated_at = NOW()
|
||||
WHERE mode IN (3, 5);
|
||||
|
||||
-- +goose Down
|
||||
-- Text screens remain valid in the previous version; original modes cannot be recovered.
|
||||
+17
-25
@@ -34,15 +34,13 @@ const (
|
||||
type ScreenMode int32
|
||||
|
||||
const (
|
||||
ScreenMode_SCREEN_MODE_UNSPECIFIED ScreenMode = 0
|
||||
ScreenMode_SCREEN_MODE_COVER ScreenMode = 1
|
||||
ScreenMode_SCREEN_MODE_INTRO ScreenMode = 2
|
||||
ScreenMode_SCREEN_MODE_INTRO_DONE ScreenMode = 3
|
||||
ScreenMode_SCREEN_MODE_CONCLUSION ScreenMode = 4
|
||||
ScreenMode_SCREEN_MODE_CONCLUSION_DONE ScreenMode = 5
|
||||
ScreenMode_SCREEN_MODE_RESULTS ScreenMode = 6
|
||||
ScreenMode_SCREEN_MODE_TIMER ScreenMode = 7
|
||||
ScreenMode_SCREEN_MODE_TEXT ScreenMode = 8
|
||||
ScreenMode_SCREEN_MODE_UNSPECIFIED ScreenMode = 0
|
||||
ScreenMode_SCREEN_MODE_COVER ScreenMode = 1
|
||||
ScreenMode_SCREEN_MODE_INTRO ScreenMode = 2
|
||||
ScreenMode_SCREEN_MODE_CONCLUSION ScreenMode = 4
|
||||
ScreenMode_SCREEN_MODE_RESULTS ScreenMode = 6
|
||||
ScreenMode_SCREEN_MODE_TIMER ScreenMode = 7
|
||||
ScreenMode_SCREEN_MODE_TEXT ScreenMode = 8
|
||||
)
|
||||
|
||||
// Enum value maps for ScreenMode.
|
||||
@@ -51,23 +49,19 @@ var (
|
||||
0: "SCREEN_MODE_UNSPECIFIED",
|
||||
1: "SCREEN_MODE_COVER",
|
||||
2: "SCREEN_MODE_INTRO",
|
||||
3: "SCREEN_MODE_INTRO_DONE",
|
||||
4: "SCREEN_MODE_CONCLUSION",
|
||||
5: "SCREEN_MODE_CONCLUSION_DONE",
|
||||
6: "SCREEN_MODE_RESULTS",
|
||||
7: "SCREEN_MODE_TIMER",
|
||||
8: "SCREEN_MODE_TEXT",
|
||||
}
|
||||
ScreenMode_value = map[string]int32{
|
||||
"SCREEN_MODE_UNSPECIFIED": 0,
|
||||
"SCREEN_MODE_COVER": 1,
|
||||
"SCREEN_MODE_INTRO": 2,
|
||||
"SCREEN_MODE_INTRO_DONE": 3,
|
||||
"SCREEN_MODE_CONCLUSION": 4,
|
||||
"SCREEN_MODE_CONCLUSION_DONE": 5,
|
||||
"SCREEN_MODE_RESULTS": 6,
|
||||
"SCREEN_MODE_TIMER": 7,
|
||||
"SCREEN_MODE_TEXT": 8,
|
||||
"SCREEN_MODE_UNSPECIFIED": 0,
|
||||
"SCREEN_MODE_COVER": 1,
|
||||
"SCREEN_MODE_INTRO": 2,
|
||||
"SCREEN_MODE_CONCLUSION": 4,
|
||||
"SCREEN_MODE_RESULTS": 6,
|
||||
"SCREEN_MODE_TIMER": 7,
|
||||
"SCREEN_MODE_TEXT": 8,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -13925,18 +13919,16 @@ const file_main_proto_rawDesc = "" +
|
||||
"\x0eTeamReceiptReq\x12\x16\n" +
|
||||
"\x06gameID\x18\x01 \x01(\x05R\x06gameID\x12\x16\n" +
|
||||
"\x06teamID\x18\x02 \x01(\tR\x06teamID\"\x15\n" +
|
||||
"\x13PrintTeamReceiptRsp*\xf6\x01\n" +
|
||||
"\x13PrintTeamReceiptRsp*\xfa\x01\n" +
|
||||
"\n" +
|
||||
"ScreenMode\x12\x1b\n" +
|
||||
"\x17SCREEN_MODE_UNSPECIFIED\x10\x00\x12\x15\n" +
|
||||
"\x11SCREEN_MODE_COVER\x10\x01\x12\x15\n" +
|
||||
"\x11SCREEN_MODE_INTRO\x10\x02\x12\x1a\n" +
|
||||
"\x16SCREEN_MODE_INTRO_DONE\x10\x03\x12\x1a\n" +
|
||||
"\x16SCREEN_MODE_CONCLUSION\x10\x04\x12\x1f\n" +
|
||||
"\x1bSCREEN_MODE_CONCLUSION_DONE\x10\x05\x12\x17\n" +
|
||||
"\x16SCREEN_MODE_CONCLUSION\x10\x04\x12\x17\n" +
|
||||
"\x13SCREEN_MODE_RESULTS\x10\x06\x12\x15\n" +
|
||||
"\x11SCREEN_MODE_TIMER\x10\a\x12\x14\n" +
|
||||
"\x10SCREEN_MODE_TEXT\x10\b*\xb6\x01\n" +
|
||||
"\x10SCREEN_MODE_TEXT\x10\b\"\x04\b\x03\x10\x03\"\x04\b\x05\x10\x05*\x16SCREEN_MODE_INTRO_DONE*\x1bSCREEN_MODE_CONCLUSION_DONE*\xb6\x01\n" +
|
||||
"\x10ScreenTimerState\x12\"\n" +
|
||||
"\x1eSCREEN_TIMER_STATE_UNSPECIFIED\x10\x00\x12\x1e\n" +
|
||||
"\x1aSCREEN_TIMER_STATE_STOPPED\x10\x01\x12\x1e\n" +
|
||||
|
||||
Reference in New Issue
Block a user