diff --git a/app/controllers/api/v1/rooms_controller.rb b/app/controllers/api/v1/rooms_controller.rb index 3514a90..cec28e1 100644 --- a/app/controllers/api/v1/rooms_controller.rb +++ b/app/controllers/api/v1/rooms_controller.rb @@ -49,22 +49,16 @@ def create # => save gaas_token in redis: type: list, key 'room:#{room.id}:gaas_tokens', value: [gaas_token1, gaas_token2, ...] # when close room, call gaas end game if possible def destroy - return render json: { error: 'Room not found' }, status: :not_found unless @room - return render json: { error: 'Room is already closed' }, status: :unprocessable_entity if @room.closed? - - user = Visitor.find(@jwt_request['sub']) - - unless user.owner_of?(@room) - return render json: { error: 'You are not the owner of this room' }, - status: :forbidden + case result = Domain::SplitRoom::Command::Close.new(room: @room, user_request: @jwt_request).call.error + in nil then head :ok + in Domain::SplitRoom::Command::RoomIsRequired + render json: { error: 'Room not found' }, status: :not_found + in Domain::SplitRoom::Command::UserIsRequired + render json: { error: 'User not found' }, status: :unauthorized + in Domain::SplitRoom::Command::UserIsNotOwner + render json: { error: 'You are not the owner of this room' }, status: :forbidden + else render json: { error: result.message }, status: :unprocessable_entity end - - @room.call_gaas_end_game(@jwt_request[:gaas_auth0_token]) - @room.close - - Domain::CloseRoomEvent.new(room_id: @room.id).dispatch - - head :ok end # POST /api/v1/rooms/:id/ai_players diff --git a/app/lib/domain/split_room/command/close.rb b/app/lib/domain/split_room/command/close.rb new file mode 100644 index 0000000..ebd9fa4 --- /dev/null +++ b/app/lib/domain/split_room/command/close.rb @@ -0,0 +1,46 @@ +module Domain + module SplitRoom + module Command + class Close + def initialize(params = {}) + @room = params[:room] + @user = Visitor.find_by(id: params.dig(:user_request, :sub)) + @gaas_auth0_token = params.dig(:user_request, :gaas_auth0_token) + @error = nil + end + + attr_reader :room, :user, :gaas_auth0_token + attr_accessor :error + + def call + validate! + return self unless error.nil? + + # TODO: Refactor the integration with GAAS + room.call_gaas_end_game(gaas_auth0_token) + room.close + + Domain::CloseRoomEvent.new(room_id: room.id).dispatch + + self + end + + private + + def validate! + self.error = RoomIsRequired.new and return if room.nil? + self.error = UserIsRequired.new and return if user.nil? + self.error = UserIsNotOwner.new and return unless can_close_the_room? + end + + def can_close_the_room? + room.owner_id == user.id || user.role_admin? + end + end + + class RoomIsRequired < StandardError; end + class UserIsRequired < StandardError; end + class UserIsNotOwner < StandardError; end + end + end +end diff --git a/spec/requests/api/v1/rooms_spec.rb b/spec/requests/api/v1/rooms_spec.rb index b51572a..3764a1a 100644 --- a/spec/requests/api/v1/rooms_spec.rb +++ b/spec/requests/api/v1/rooms_spec.rb @@ -109,6 +109,8 @@ end path "/api/#{version}/rooms/{id}/close" do + let(:id) { room.id } + post '關閉房間' do tags 'Rooms' # description "" @@ -117,12 +119,40 @@ parameter name: :id, in: :path, type: :string response 200, 'ok.' do - xit + before { room.update(owner_id: user.id) } + + run_test! + end + + response 404, 'not found.' do + let(:id) { 'invalid' } + + run_test! + end + + response 401, 'unauthorized.' do + let(:Authorization) { nil } + + run_test! + end + + response 403, 'forbidden.' do + run_test! + end + + context 'when the user is admin' do + before { user.role_admin! } + + response 200, 'ok.' do + run_test! + end end end end path "/api/#{version}/rooms/{id}/knock-knock" do + let(:id) { room.id } + get '取得加入房間 token' do tags 'Rooms' # description "" @@ -130,8 +160,6 @@ produces 'application/json' parameter name: :id, in: :path, type: :string - let(:id) { room.id } - response 200, 'ok.' do run_test! do |response| expect(JSON.parse(response.body)).to have_key('token')