From da9e49ceccc7f8a069768f3bb86a596f1379cf67 Mon Sep 17 00:00:00 2001 From: Naoki Kishi Date: Wed, 29 Jul 2020 19:23:55 +0900 Subject: [PATCH] =?UTF-8?q?ARCHIVE=E3=81=A8STOP=E3=81=AE=E3=81=A8=E3=81=8D?= =?UTF-8?q?=E3=81=AF=E3=82=BB=E3=83=83=E3=82=B7=E3=83=A7=E3=83=B3=E4=BD=9C?= =?UTF-8?q?=E6=88=90=E8=80=85=E3=81=97=E3=81=8B=E6=93=8D=E4=BD=9C=E3=81=A7?= =?UTF-8?q?=E3=81=8D=E3=81=AA=E3=81=84=E3=82=88=E3=81=86=E3=81=AB=E3=81=99?= =?UTF-8?q?=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- usecase/session_state.go | 10 ++++++ web/handler/session_state_test.go | 52 +++++++++++++++++++++++++++++-- 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/usecase/session_state.go b/usecase/session_state.go index 15741fa5..3ae54a9a 100644 --- a/usecase/session_state.go +++ b/usecase/session_state.go @@ -150,6 +150,11 @@ func (s *SessionStateUseCase) pause(ctx context.Context, sess *entity.Session) e // archive はセッションのstateをARCHIVEDに変更します。 func (s *SessionStateUseCase) archive(ctx context.Context, session *entity.Session) error { + userID, _ := service.GetUserIDFromContext(ctx) + if !session.IsCreator(userID) { + return fmt.Errorf("user is not creator: %w", entity.ErrSessionNotAllowToControlOthers) + } + switch session.StateType { case entity.Play: if err := s.playerCli.Pause(ctx, session.DeviceID); err != nil && !errors.Is(err, entity.ErrActiveDeviceNotFound) { @@ -177,6 +182,11 @@ func (s *SessionStateUseCase) archive(ctx context.Context, session *entity.Sessi // stop はセッションのstateをSTOPに変更します。 func (s *SessionStateUseCase) stop(ctx context.Context, session *entity.Session) error { + userID, _ := service.GetUserIDFromContext(ctx) + if !session.IsCreator(userID) { + return fmt.Errorf("user is not creator: %w", entity.ErrSessionNotAllowToControlOthers) + } + switch session.StateType { case entity.Stop: return nil diff --git a/web/handler/session_state_test.go b/web/handler/session_state_test.go index f3d14f37..5ffd2ba9 100644 --- a/web/handler/session_state_test.go +++ b/web/handler/session_state_test.go @@ -609,6 +609,7 @@ func TestSessionHandler_State_STOP(t *testing.T) { { name: "StateType=ARCHIVED: 手動でアーカイブを解除して202", sessionID: "sessionID", + userID: "creator_id", prepareMockPlayerFn: func(m *mock_spotify.MockPlayer) {}, prepareMockPusherFn: func(m *mock_event.MockPusher) { m.EXPECT().Push(&event.PushMessage{SessionID: "sessionID", Msg: entity.EventUnarchive}) @@ -645,14 +646,28 @@ func TestSessionHandler_State_STOP(t *testing.T) { wantErr: false, wantCode: http.StatusAccepted, }, + { + name: "セッション作成者以外の操作のときは400", + sessionID: "sessionID", + userID: "non_creator_id", + prepareMockPlayerFn: func(m *mock_spotify.MockPlayer) {}, + prepareMockPusherFn: func(m *mock_event.MockPusher) {}, + prepareMockUserRepoFn: func(m *mock_repository.MockUser) {}, + prepareMockSessionRepoFn: func(m *mock_repository.MockSession) { + m.EXPECT().FindByID(gomock.Any(), "sessionID").Return(&entity.Session{StateType: entity.Pause, CreatorID: "creator_id"}, nil) + }, + wantErr: true, + wantCode: http.StatusBadRequest, + }, { name: "StateType=PLAY: 不正なstateの変更なので400", sessionID: "sessionID", + userID: "creator_id", prepareMockPlayerFn: func(m *mock_spotify.MockPlayer) {}, prepareMockPusherFn: func(m *mock_event.MockPusher) {}, prepareMockUserRepoFn: func(m *mock_repository.MockUser) {}, prepareMockSessionRepoFn: func(m *mock_repository.MockSession) { - m.EXPECT().FindByID(gomock.Any(), "sessionID").Return(&entity.Session{StateType: entity.Play}, nil) + m.EXPECT().FindByID(gomock.Any(), "sessionID").Return(&entity.Session{StateType: entity.Play, CreatorID: "creator_id"}, nil) }, wantErr: true, wantCode: http.StatusBadRequest, @@ -660,11 +675,12 @@ func TestSessionHandler_State_STOP(t *testing.T) { { name: "StateType=PAUSE: 不正なstateの変更なので400", sessionID: "sessionID", + userID: "creator_id", prepareMockPlayerFn: func(m *mock_spotify.MockPlayer) {}, prepareMockPusherFn: func(m *mock_event.MockPusher) {}, prepareMockUserRepoFn: func(m *mock_repository.MockUser) {}, prepareMockSessionRepoFn: func(m *mock_repository.MockSession) { - m.EXPECT().FindByID(gomock.Any(), "sessionID").Return(&entity.Session{StateType: entity.Pause}, nil) + m.EXPECT().FindByID(gomock.Any(), "sessionID").Return(&entity.Session{StateType: entity.Pause, CreatorID: "creator_id"}, nil) }, wantErr: true, wantCode: http.StatusBadRequest, @@ -672,11 +688,12 @@ func TestSessionHandler_State_STOP(t *testing.T) { { name: "StateType=STOP: なにもせずに202", sessionID: "sessionID", + userID: "creator_id", prepareMockPlayerFn: func(m *mock_spotify.MockPlayer) {}, prepareMockPusherFn: func(m *mock_event.MockPusher) {}, prepareMockUserRepoFn: func(m *mock_repository.MockUser) {}, prepareMockSessionRepoFn: func(m *mock_repository.MockSession) { - m.EXPECT().FindByID(gomock.Any(), "sessionID").Return(&entity.Session{StateType: entity.Stop}, nil) + m.EXPECT().FindByID(gomock.Any(), "sessionID").Return(&entity.Session{StateType: entity.Stop, CreatorID: "creator_id"}, nil) }, wantErr: false, wantCode: http.StatusAccepted, @@ -727,6 +744,7 @@ func TestSessionHandler_State_ARCHIVED(t *testing.T) { { name: "StateType=PLAY: Spotifyでの再生を一時停止した後、正しくアーカイブされて202", sessionID: "sessionID", + userID: "creator_id", prepareMockPlayerFn: func(m *mock_spotify.MockPlayer) { m.EXPECT().Pause(gomock.Any(), "device_id").Return(nil) }, @@ -768,6 +786,7 @@ func TestSessionHandler_State_ARCHIVED(t *testing.T) { { name: "StateType=PAUSE: 正しくアーカイブされて202", sessionID: "sessionID", + userID: "creator_id", prepareMockPlayerFn: func(m *mock_spotify.MockPlayer) {}, prepareMockPusherFn: func(m *mock_event.MockPusher) { m.EXPECT().Push(&event.PushMessage{SessionID: "sessionID", Msg: entity.EventArchived}) @@ -807,6 +826,7 @@ func TestSessionHandler_State_ARCHIVED(t *testing.T) { { name: "StateType=STOP: 正しくアーカイブされて202", sessionID: "sessionID", + userID: "creator_id", prepareMockPlayerFn: func(m *mock_spotify.MockPlayer) {}, prepareMockPusherFn: func(m *mock_event.MockPusher) { m.EXPECT().Push(&event.PushMessage{SessionID: "sessionID", Msg: entity.EventArchived}) @@ -846,6 +866,7 @@ func TestSessionHandler_State_ARCHIVED(t *testing.T) { { name: "StateType=ARCHIVED: 既にアーカイブされているので何もせずに202", sessionID: "sessionID", + userID: "creator_id", prepareMockPlayerFn: func(m *mock_spotify.MockPlayer) {}, prepareMockPusherFn: func(m *mock_event.MockPusher) {}, prepareMockUserRepoFn: func(m *mock_repository.MockUser) {}, @@ -867,6 +888,31 @@ func TestSessionHandler_State_ARCHIVED(t *testing.T) { wantErr: false, wantCode: http.StatusAccepted, }, + { + name: "セッション作成者以外のときは400", + sessionID: "sessionID", + userID: "non_creator_id", + prepareMockPlayerFn: func(m *mock_spotify.MockPlayer) {}, + prepareMockPusherFn: func(m *mock_event.MockPusher) {}, + prepareMockUserRepoFn: func(m *mock_repository.MockUser) {}, + prepareMockSessionRepoFn: func(m *mock_repository.MockSession) { + m.EXPECT().FindByID(gomock.Any(), "sessionID").Return(&entity.Session{ + ID: "sessionID", + Name: "session_name", + CreatorID: "creator_id", + QueueHead: 0, + DeviceID: "device_id", + StateType: entity.Archived, + QueueTracks: []*entity.QueueTrack{ + {Index: 0, URI: "spotify:track:5uQ0vKy2973Y9IUCd1wMEF"}, + {Index: 1, URI: "spotify:track:49BRCNV7E94s7Q2FUhhT3w"}, + }, + AllowToControlByOthers: true, + }, nil) + }, + wantErr: true, + wantCode: http.StatusBadRequest, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) {