generated from VLADIMIR/template
up
This commit is contained in:
@@ -14,6 +14,8 @@ func mapScreenPlanSteps(steps []*proto.ScreenPlanStep) []screen_plan_service.Ste
|
||||
}
|
||||
mapped = append(mapped, screen_plan_service.Step{
|
||||
Mode: int32(step.Mode),
|
||||
QRURL: step.QrUrl,
|
||||
TimerType: int32(step.TimerType),
|
||||
Text: step.Text,
|
||||
TimerLabel: step.TimerLabel,
|
||||
TimerDurationSeconds: step.TimerDurationSeconds,
|
||||
@@ -30,6 +32,8 @@ func mapScreenPlan(plan *screen_plan_service.Plan) *proto.ScreenPlan {
|
||||
for _, step := range plan.Steps {
|
||||
steps = append(steps, &proto.ScreenPlanStep{
|
||||
Mode: proto.ScreenMode(step.Mode),
|
||||
QrUrl: step.QRURL,
|
||||
TimerType: proto.ScreenTimerType(step.TimerType),
|
||||
Text: step.Text,
|
||||
TimerLabel: step.TimerLabel,
|
||||
TimerDurationSeconds: step.TimerDurationSeconds,
|
||||
|
||||
+40
-3
@@ -222,6 +222,8 @@ func screenState(session *screen_service.ScreenSession) *proto.ScreenState {
|
||||
TimerRemainingSeconds: timerRemaining,
|
||||
TimerState: timerState,
|
||||
Text: session.Text,
|
||||
QrUrl: session.QRURL,
|
||||
TimerType: proto.ScreenTimerType(session.TimerType),
|
||||
}
|
||||
if time.Since(session.LastSeen) <= 5*time.Second {
|
||||
state.Status = "connected"
|
||||
@@ -277,6 +279,15 @@ func (s *server) SetScreenMode(ctx context.Context, req *proto.SetScreenModeReq)
|
||||
if _, err := s.gameService.GetGame(ctx, int(req.GameID)); err != nil {
|
||||
return nil, status.Error(codes.NotFound, "игра не найдена")
|
||||
}
|
||||
if req.Mode == proto.ScreenMode_SCREEN_MODE_QR {
|
||||
if !screen_service.ValidQR(req.QrUrl, req.Text) {
|
||||
return nil, status.Error(codes.InvalidArgument, "Укажите ссылку HTTP/HTTPS до 2048 байт и текст до 10000 байт")
|
||||
}
|
||||
if err := s.screenService.SetQR(ctx, int(req.GameID), req.QrUrl, req.Text); err != nil {
|
||||
return nil, status.Error(codes.Internal, "не удалось изменить QR-код")
|
||||
}
|
||||
return &proto.SetScreenModeRsp{}, nil
|
||||
}
|
||||
if err := s.screenService.SetMode(ctx, int(req.GameID), int32(req.Mode)); err != nil {
|
||||
return nil, status.Error(codes.Internal, "не удалось изменить режим экранов")
|
||||
}
|
||||
@@ -287,12 +298,12 @@ func (s *server) SetScreenTimer(ctx context.Context, req *proto.SetScreenTimerRe
|
||||
if !canManageScreens(ctx) {
|
||||
return nil, status.Error(codes.PermissionDenied, "permission denied")
|
||||
}
|
||||
if req == nil || req.GameID <= 0 || req.DurationSeconds <= 0 || req.DurationSeconds > 24*60*60 {
|
||||
if req == nil || req.GameID <= 0 || req.DurationSeconds <= 0 || req.DurationSeconds > 24*60*60 || !screen_service.ValidTimerType(int32(req.TimerType)) {
|
||||
return nil, status.Error(codes.InvalidArgument, "некорректные параметры таймера")
|
||||
}
|
||||
label := strings.TrimSpace(req.Label)
|
||||
if label == "" {
|
||||
label = "Перерыв"
|
||||
label = screen_service.TimerLabel(int32(req.TimerType))
|
||||
}
|
||||
if len(label) > 200 {
|
||||
return nil, status.Error(codes.InvalidArgument, "слишком длинная надпись таймера")
|
||||
@@ -300,7 +311,7 @@ func (s *server) SetScreenTimer(ctx context.Context, req *proto.SetScreenTimerRe
|
||||
if _, err := s.gameService.GetGame(ctx, int(req.GameID)); err != nil {
|
||||
return nil, status.Error(codes.NotFound, "игра не найдена")
|
||||
}
|
||||
if err := s.screenService.SetTimer(ctx, int(req.GameID), req.DurationSeconds, label); err != nil {
|
||||
if err := s.screenService.SetTimer(ctx, int(req.GameID), req.DurationSeconds, label, int32(req.TimerType)); err != nil {
|
||||
return nil, status.Error(codes.Internal, "не удалось настроить таймер экранов")
|
||||
}
|
||||
return &proto.SetScreenTimerRsp{}, nil
|
||||
@@ -366,3 +377,29 @@ func (s *server) GetScreenResults(ctx context.Context, req *proto.GetScreenResul
|
||||
}
|
||||
return &proto.GetScreenResultsRsp{Questions: mapResultsQuestions(results.Questions), Teams: mapTeamResults(results.Teams)}, nil
|
||||
}
|
||||
|
||||
func (s *server) GetScreenTeams(ctx context.Context, req *proto.GetScreenTeamsReq) (*proto.GetScreenTeamsRsp, error) {
|
||||
if req == nil || req.ScreenID == "" || req.AccessToken == "" {
|
||||
return nil, status.Error(codes.InvalidArgument, "некорректные данные экрана")
|
||||
}
|
||||
id, err := strconv.Atoi(req.ScreenID)
|
||||
if err != nil || id <= 0 {
|
||||
return nil, status.Error(codes.InvalidArgument, "некорректный идентификатор экрана")
|
||||
}
|
||||
session, err := s.screenService.Get(ctx, id, hashScreenToken(req.AccessToken))
|
||||
if errors.Is(err, screen_service.ErrScreenNotFound) {
|
||||
return nil, status.Error(codes.Unauthenticated, "недействительная сессия экрана")
|
||||
}
|
||||
if err != nil || session.GameID == nil {
|
||||
return nil, status.Error(codes.FailedPrecondition, "экран не привязан к игре")
|
||||
}
|
||||
teams, err := s.teamService.GetScreenTeams(ctx, *session.GameID)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, "не удалось получить команды")
|
||||
}
|
||||
result := make([]*proto.ScreenTeam, 0, len(teams))
|
||||
for _, team := range teams {
|
||||
result = append(result, &proto.ScreenTeam{ID: team.ID, Name: team.Name})
|
||||
}
|
||||
return &proto.GetScreenTeamsRsp{Teams: result}, nil
|
||||
}
|
||||
|
||||
@@ -26,3 +26,22 @@ func TestSetScreenModeRejectsRemovedModes(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestScreenTeamsRejectsInvalidAccess(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
req *proto.GetScreenTeamsReq
|
||||
}{
|
||||
{"missing", nil},
|
||||
{"missing token", &proto.GetScreenTeamsReq{ScreenID: "1"}},
|
||||
{"bad ID", &proto.GetScreenTeamsReq{ScreenID: "bad", AccessToken: "token"}},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
_, err := (&server{}).GetScreenTeams(context.Background(), tt.req)
|
||||
if status.Code(err) != codes.InvalidArgument {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user