| @@ -8,23 +8,35 @@ RSpec.describe 'Tags deerjikists API', type: :request do | |||
| let!(:tag) { create(:tag, category: :deerjikist) } | |||
| let(:member) { create(:user, :member) } | |||
| let(:guest) { create(:user, role: :guest) } | |||
| before do | |||
| # show_by_name / deerjikists_by_name 用に名前を固定 | |||
| tag.tag_name.update!(name: 'deerjika') | |||
| end | |||
| describe 'GET /tags/:id/deerjikists' do | |||
| subject(:do_request) do | |||
| get "/tags/#{ tag_id }/deerjikists" | |||
| get "/tags/#{tag_id}/deerjikists" | |||
| end | |||
| let(:tag_id) { tag.id } | |||
| context 'when tag exists and has no deerjikists' do | |||
| it 'returns 200 and empty array' do | |||
| it 'returns 200 with tag and empty deerjikists array' do | |||
| do_request | |||
| expect(response).to have_http_status(:ok) | |||
| expect(json).to eq([]) | |||
| expect(json).to be_a(Hash) | |||
| expect(json['tag']).to be_a(Hash) | |||
| expect(json['tag']['id']).to eq(tag.id) | |||
| expect(json['tag']['name']).to eq('deerjika') | |||
| expect(json['tag']['category']).to eq('deerjikist') | |||
| expect(json['tag']['has_deerjikists']).to eq(false) | |||
| expect(json['deerjikists']).to eq([]) | |||
| end | |||
| end | |||
| @@ -34,17 +46,27 @@ RSpec.describe 'Tags deerjikists API', type: :request do | |||
| Deerjikist.create!(platform: platform2, code: code2, tag: tag) | |||
| end | |||
| it 'returns 200 and deerjikists array' do | |||
| it 'returns 200 with tag and deerjikists array' do | |||
| do_request | |||
| expect(response).to have_http_status(:ok) | |||
| expect(json).to be_a(Array) | |||
| expect(json.size).to eq(2) | |||
| expect(json).to be_a(Hash) | |||
| expect(json.map { |h| [h['platform'], h['code']] }).to contain_exactly( | |||
| [platform1, code1], | |||
| [platform2, code2], | |||
| ) | |||
| expect(json['tag']).to be_a(Hash) | |||
| expect(json['tag']['id']).to eq(tag.id) | |||
| expect(json['tag']['name']).to eq('deerjika') | |||
| expect(json['tag']['category']).to eq('deerjikist') | |||
| expect(json['tag']['has_deerjikists']).to eq(true) | |||
| expect(json['deerjikists']).to be_a(Array) | |||
| expect(json['deerjikists'].size).to eq(2) | |||
| expect(json['deerjikists'].map { |h| [h['platform'], h['code']] }) | |||
| .to contain_exactly( | |||
| [platform1, code1], | |||
| [platform2, code2], | |||
| ) | |||
| end | |||
| end | |||
| @@ -53,6 +75,7 @@ RSpec.describe 'Tags deerjikists API', type: :request do | |||
| it 'returns 404' do | |||
| do_request | |||
| expect(response).to have_http_status(:not_found) | |||
| end | |||
| end | |||
| @@ -60,7 +83,7 @@ RSpec.describe 'Tags deerjikists API', type: :request do | |||
| describe 'GET /tags/name/:name/deerjikists' do | |||
| subject(:do_request) do | |||
| get "/tags/name/#{ name }/deerjikists" | |||
| get "/tags/name/#{name}/deerjikists" | |||
| end | |||
| let(:name) { 'deerjika' } | |||
| @@ -70,6 +93,7 @@ RSpec.describe 'Tags deerjikists API', type: :request do | |||
| it 'returns 400' do | |||
| do_request | |||
| expect(response).to have_http_status(:bad_request) | |||
| end | |||
| end | |||
| @@ -79,23 +103,209 @@ RSpec.describe 'Tags deerjikists API', type: :request do | |||
| it 'returns 404' do | |||
| do_request | |||
| expect(response).to have_http_status(:not_found) | |||
| end | |||
| end | |||
| context 'when tag exists and has no deerjikists' do | |||
| it 'returns 200 with tag and empty deerjikists array' do | |||
| do_request | |||
| expect(response).to have_http_status(:ok) | |||
| expect(json).to be_a(Hash) | |||
| expect(json['tag']).to be_a(Hash) | |||
| expect(json['tag']['id']).to eq(tag.id) | |||
| expect(json['tag']['name']).to eq('deerjika') | |||
| expect(json['tag']['category']).to eq('deerjikist') | |||
| expect(json['tag']['has_deerjikists']).to eq(false) | |||
| expect(json['deerjikists']).to eq([]) | |||
| end | |||
| end | |||
| context 'when tag exists and has deerjikists' do | |||
| before do | |||
| Deerjikist.create!(platform: platform1, code: code1, tag: tag) | |||
| end | |||
| it 'returns 200 and deerjikists array' do | |||
| it 'returns 200 with tag and deerjikists array' do | |||
| do_request | |||
| expect(response).to have_http_status(:ok) | |||
| expect(json).to be_a(Array) | |||
| expect(json.size).to eq(1) | |||
| expect(json[0]['platform']).to eq(platform1) | |||
| expect(json[0]['code']).to eq(code1) | |||
| expect(json).to be_a(Hash) | |||
| expect(json['tag']).to be_a(Hash) | |||
| expect(json['tag']['id']).to eq(tag.id) | |||
| expect(json['tag']['name']).to eq('deerjika') | |||
| expect(json['tag']['category']).to eq('deerjikist') | |||
| expect(json['tag']['has_deerjikists']).to eq(true) | |||
| expect(json['deerjikists']).to be_a(Array) | |||
| expect(json['deerjikists'].size).to eq(1) | |||
| expect(json['deerjikists'][0]['platform']).to eq(platform1) | |||
| expect(json['deerjikists'][0]['code']).to eq(code1) | |||
| end | |||
| end | |||
| end | |||
| describe 'PUT /tags/:id/deerjikists' do | |||
| subject(:do_request) do | |||
| put "/tags/#{tag_id}/deerjikists", params: payload, as: :json | |||
| end | |||
| let(:tag_id) { tag.id } | |||
| let(:payload) do | |||
| [ | |||
| { platform: platform1, code: code1 }, | |||
| { platform: platform2, code: code2 }, | |||
| ] | |||
| end | |||
| context 'when not logged in' do | |||
| it 'returns 401' do | |||
| do_request | |||
| expect(response).to have_http_status(:unauthorized) | |||
| end | |||
| end | |||
| context 'when logged in but not member' do | |||
| before do | |||
| sign_in_as guest | |||
| end | |||
| it 'returns 403' do | |||
| do_request | |||
| expect(response).to have_http_status(:forbidden) | |||
| end | |||
| end | |||
| context 'when tag does not exist' do | |||
| let(:tag_id) { 9_999_999 } | |||
| before do | |||
| sign_in_as member | |||
| end | |||
| it 'returns 404' do | |||
| do_request | |||
| expect(response).to have_http_status(:not_found) | |||
| end | |||
| end | |||
| context 'when logged in as member' do | |||
| before do | |||
| sign_in_as member | |||
| end | |||
| context 'when tag has no deerjikists' do | |||
| it 'creates deerjikists and returns deerjikists array' do | |||
| expect { | |||
| do_request | |||
| }.to change { Deerjikist.where(tag: tag).count }.from(0).to(2) | |||
| expect(response).to have_http_status(:ok) | |||
| expect(json).to be_a(Array) | |||
| expect(json.map { |h| [h['platform'], h['code']] }) | |||
| .to contain_exactly( | |||
| [platform1, code1], | |||
| [platform2, code2], | |||
| ) | |||
| expect(Deerjikist.where(tag: tag).map { |d| [d.platform, d.code] }) | |||
| .to contain_exactly( | |||
| [platform1, code1], | |||
| [platform2, code2], | |||
| ) | |||
| end | |||
| end | |||
| context 'when tag already has deerjikists' do | |||
| before do | |||
| Deerjikist.create!(platform: platform1, code: 'old-code-1', tag: tag) | |||
| Deerjikist.create!(platform: platform2, code: 'old-code-2', tag: tag) | |||
| end | |||
| it 'replaces deerjikists and returns deerjikists array' do | |||
| do_request | |||
| expect(response).to have_http_status(:ok) | |||
| expect(Deerjikist.where(tag: tag).map { |d| [d.platform, d.code] }) | |||
| .to contain_exactly( | |||
| [platform1, code1], | |||
| [platform2, code2], | |||
| ) | |||
| expect(Deerjikist.exists?(platform: platform1, code: 'old-code-1')).to eq(false) | |||
| expect(Deerjikist.exists?(platform: platform2, code: 'old-code-2')).to eq(false) | |||
| expect(json).to be_a(Array) | |||
| expect(json.map { |h| [h['platform'], h['code']] }) | |||
| .to contain_exactly( | |||
| [platform1, code1], | |||
| [platform2, code2], | |||
| ) | |||
| end | |||
| end | |||
| context 'when payload is empty array' do | |||
| let(:payload) { [] } | |||
| before do | |||
| Deerjikist.create!(platform: platform1, code: code1, tag: tag) | |||
| Deerjikist.create!(platform: platform2, code: code2, tag: tag) | |||
| end | |||
| it 'clears deerjikists and returns empty array' do | |||
| expect { | |||
| do_request | |||
| }.to change { Deerjikist.where(tag: tag).count }.from(2).to(0) | |||
| expect(response).to have_http_status(:ok) | |||
| expect(json).to eq([]) | |||
| end | |||
| end | |||
| context 'when youtube code is handle' do | |||
| let(:channel_id) { 'UCabcdefghijklmnopqrstuv' } | |||
| let(:payload) do | |||
| [ | |||
| { platform: 'youtube', code: '@deerjika' }, | |||
| ] | |||
| end | |||
| before do | |||
| allow(Net::HTTP).to receive(:get).and_return( | |||
| %(<link rel="canonical" href="https://www.youtube.com/channel/#{channel_id}">), | |||
| ) | |||
| end | |||
| it 'normalises youtube handle to channel id' do | |||
| expect { | |||
| do_request | |||
| }.to change { Deerjikist.where(tag: tag).count }.from(0).to(1) | |||
| expect(response).to have_http_status(:ok) | |||
| expect(Net::HTTP).to have_received(:get) | |||
| expect(Deerjikist.exists?(platform: 'youtube', code: channel_id, tag: tag)) | |||
| .to eq(true) | |||
| expect(json).to be_a(Array) | |||
| expect(json.size).to eq(1) | |||
| expect(json[0]['platform']).to eq('youtube') | |||
| expect(json[0]['code']).to eq(channel_id) | |||
| end | |||
| end | |||
| end | |||
| end | |||