require 'rails_helper' RSpec.describe 'Deerjikists API', type: :request do let(:platform) { 'nico' } let(:code) { 'deerjika-bot' } let!(:tag1) { create(:tag, category: :deerjikist) } let!(:tag2) { create(:tag, category: :deerjikist) } let(:member) { create(:user, :member) } let(:guest) { create(:user, role: :guest) } describe 'GET /deerjikists/:platform/:code' do subject(:do_request) do get "/deerjikists/#{ platform }/#{ code }" end context 'when deerjikist exists' do before do Deerjikist.create!(platform:, code:, tag: tag1) end it 'returns 200 and deerjikist json' do do_request expect(response).to have_http_status(:ok) expect(json).to be_a(Hash) expect(json['platform']).to eq(platform) expect(json['code']).to eq(code) expect(json['tag']).to be_a(Hash) expect(json['tag']['id']).to eq(tag1.id) expect(json['tag']['name']).to eq(tag1.name) end end context 'when deerjikist does not exist' do it 'returns 404' do do_request expect(response).to have_http_status(:not_found) end end context 'when platform or code become blank after strip' do it 'returns 400' do get '/deerjikists/%20/%20' expect(response).to have_http_status(:bad_request) end end end describe 'PUT /deerjikists/:platform/:code' do subject(:do_request) do put "/deerjikists/#{ platform }/#{ code }", params: payload end let(:payload) { { tag_id: tag1.id } } context 'when not legged in' do it 'returns 401' do sign_out do_request expect(response).to have_http_status(:unauthorized) end end context 'when logged in but not member' do it 'returns 403' do sign_in_as guest do_request expect(response).to have_http_status(:forbidden) end end context 'when member' do before do sign_in_as member end context 'when params invalid' do it 'returns 400 when tag_id is missing or invalid' do put "/deerjikists/#{ platform }/#{ code }", params: { tag_id: 0 } expect(response).to have_http_status(:bad_request) end it 'returns 400 when platform or code blank after strip' do put '/deerjikists/%20/%20', params: { tag_id: tag1.id } expect(response).to have_http_status(:bad_request) end end context 'when creating new deerjikist' do it 'creates and returns 200 with json' do expect { do_request }.to change { Deerjikist.count }.by(1) expect(response).to have_http_status(:ok) d = Deerjikist.find_by(platform:, code:) expect(d).to be_present expect(d.tag_id).to eq(tag1.id) expect(json['platform']).to eq(platform) expect(json['code']).to eq(code) end end context 'when updating existing deerjikist' do before do Deerjikist.create!(platform:, code:, tag: tag1) end let(:payload) { { tag_id: tag2.id } } it 'updates tag_id and returns 200' do expect { do_request }.not_to change { Deerjikist.count } expect(response).to have_http_status(:ok) d = Deerjikist.find_by(platform:, code:) expect(d.tag_id).to eq(tag2.id) expect(json['platform']).to eq(platform) expect(json['code']).to eq(code) end end end end describe 'DELETE /deerjikists/:platform/:code' do subject(:do_request) do delete "/deerjikists/#{ platform }/#{ code }" end context 'when not logged in' do it 'returns 401' do sign_out do_request expect(response).to have_http_status(:unauthorized) end end context 'when logged in but not member' do it 'returns 403' do sign_in_as guest do_request expect(response).to have_http_status(:forbidden) end end context 'when member' do before do sign_in_as member end it 'returns 400 when platform/code blank after strip' do delete '/deerjikists/%20/%20' expect(response).to have_http_status(:bad_request) end context 'when deerjikist exists' do before do Deerjikist.create!(platform: platform, code: code, tag: tag1) end it 'destroys and returns 204' do expect { do_request }.to change { Deerjikist.exists?(platform: platform, code: code) } .from(true).to(false) expect(response).to have_http_status(:no_content) end end context 'when deerjikist does not exist' do it 'returns 404' do do_request expect(response).to have_http_status(:not_found) end end end end end