require 'rails_helper' RSpec.describe 'TheatreComments', type: :request do def sign_in_as(user) allow_any_instance_of(ApplicationController).to receive(:current_user).and_return(user) end describe 'GET /theatres/:theatre_id/comments' do let(:theatre) { create(:theatre) } let(:other_theatre) { create(:theatre) } let(:alice) { create(:user, name: 'Alice') } let(:bob) { create(:user, name: 'Bob') } let!(:comment_3) do create( :theatre_comment, theatre: theatre, no: 3, user: alice, content: 'third comment' ) end let!(:comment_1) do create( :theatre_comment, theatre: theatre, no: 1, user: alice, content: 'first comment' ) end let!(:comment_2) do create( :theatre_comment, theatre: theatre, no: 2, user: bob, content: 'second comment' ) end let!(:other_comment) do create( :theatre_comment, theatre: other_theatre, no: 1, user: bob, content: 'other theatre comment' ) end it 'theatre_id で絞り込み、no_gt より大きいものを no 降順で返す' do get "/theatres/#{theatre.id}/comments", params: { no_gt: 1 } expect(response).to have_http_status(:ok) expect(response.parsed_body.map { |row| row['no'] }).to eq([3, 2]) expect(response.parsed_body.map { |row| row['content'] }).to eq([ 'third comment', 'second comment' ]) end it 'user は id と name だけを含む' do get "/theatres/#{theatre.id}/comments", params: { no_gt: 1 } expect(response).to have_http_status(:ok) expect(response.parsed_body.first['user']).to eq({ 'id' => alice.id, 'name' => 'Alice' }) expect(response.parsed_body.first['user'].keys).to contain_exactly('id', 'name') end it 'no_gt が負数なら 0 として扱う' do get "/theatres/#{theatre.id}/comments", params: { no_gt: -100 } expect(response).to have_http_status(:ok) expect(response.parsed_body.map { |row| row['no'] }).to eq([3, 2, 1]) end end describe 'POST /theatres/:theatre_id/comments' do let(:user) { create(:user, name: 'Alice') } let(:theatre) { create(:theatre, next_comment_no: 2) } before do create( :theatre_comment, theatre: theatre, no: 1, user: user, content: 'existing comment' ) end it '未ログインなら 401 を返す' do expect { post "/theatres/#{theatre.id}/comments", params: { content: 'hello' } }.not_to change(TheatreComment, :count) expect(response).to have_http_status(:unauthorized) end it 'content が blank なら 422 を返す' do sign_in_as(user) expect { post "/theatres/#{theatre.id}/comments", params: { content: ' ' } }.not_to change(TheatreComment, :count) expect(response).to have_http_status(:unprocessable_entity) end it 'theatre が存在しなければ 404 を返す' do sign_in_as(user) expect { post '/theatres/999999/comments', params: { content: 'hello' } }.not_to change(TheatreComment, :count) expect(response).to have_http_status(:not_found) end it 'コメントを作成し、user を紐づけ、next_comment_no を進める' do sign_in_as(user) expect { post "/theatres/#{theatre.id}/comments", params: { content: 'new comment' } }.to change(TheatreComment, :count).by(1) expect(response).to have_http_status(:created) comment = TheatreComment.find_by!(theatre: theatre, no: 2) expect(comment.user).to eq(user) expect(comment.content).to eq('new comment') expect(theatre.reload.next_comment_no).to eq(3) expect(response.parsed_body.slice('theatre_id', 'no', 'user_id', 'content')).to eq({ 'theatre_id' => theatre.id, 'no' => 2, 'user_id' => user.id, 'content' => 'new comment' }) end end end