| @@ -8,23 +8,35 @@ RSpec.describe 'Tags deerjikists API', type: :request do | |||||
| let!(:tag) { create(:tag, category: :deerjikist) } | let!(:tag) { create(:tag, category: :deerjikist) } | ||||
| let(:member) { create(:user, :member) } | |||||
| let(:guest) { create(:user, role: :guest) } | |||||
| before do | before do | ||||
| # show_by_name / deerjikists_by_name 用に名前を固定 | |||||
| tag.tag_name.update!(name: 'deerjika') | tag.tag_name.update!(name: 'deerjika') | ||||
| end | end | ||||
| describe 'GET /tags/:id/deerjikists' do | describe 'GET /tags/:id/deerjikists' do | ||||
| subject(:do_request) do | subject(:do_request) do | ||||
| get "/tags/#{ tag_id }/deerjikists" | |||||
| get "/tags/#{tag_id}/deerjikists" | |||||
| end | end | ||||
| let(:tag_id) { tag.id } | let(:tag_id) { tag.id } | ||||
| context 'when tag exists and has no deerjikists' do | 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 | do_request | ||||
| expect(response).to have_http_status(:ok) | 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 | ||||
| end | end | ||||
| @@ -34,17 +46,27 @@ RSpec.describe 'Tags deerjikists API', type: :request do | |||||
| Deerjikist.create!(platform: platform2, code: code2, tag: tag) | Deerjikist.create!(platform: platform2, code: code2, tag: tag) | ||||
| end | end | ||||
| it 'returns 200 and deerjikists array' do | |||||
| it 'returns 200 with tag and deerjikists array' do | |||||
| do_request | do_request | ||||
| expect(response).to have_http_status(:ok) | 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 | ||||
| end | end | ||||
| @@ -53,6 +75,7 @@ RSpec.describe 'Tags deerjikists API', type: :request do | |||||
| it 'returns 404' do | it 'returns 404' do | ||||
| do_request | do_request | ||||
| expect(response).to have_http_status(:not_found) | expect(response).to have_http_status(:not_found) | ||||
| end | end | ||||
| end | end | ||||
| @@ -60,7 +83,7 @@ RSpec.describe 'Tags deerjikists API', type: :request do | |||||
| describe 'GET /tags/name/:name/deerjikists' do | describe 'GET /tags/name/:name/deerjikists' do | ||||
| subject(:do_request) do | subject(:do_request) do | ||||
| get "/tags/name/#{ name }/deerjikists" | |||||
| get "/tags/name/#{name}/deerjikists" | |||||
| end | end | ||||
| let(:name) { 'deerjika' } | let(:name) { 'deerjika' } | ||||
| @@ -70,6 +93,7 @@ RSpec.describe 'Tags deerjikists API', type: :request do | |||||
| it 'returns 400' do | it 'returns 400' do | ||||
| do_request | do_request | ||||
| expect(response).to have_http_status(:bad_request) | expect(response).to have_http_status(:bad_request) | ||||
| end | end | ||||
| end | end | ||||
| @@ -79,23 +103,209 @@ RSpec.describe 'Tags deerjikists API', type: :request do | |||||
| it 'returns 404' do | it 'returns 404' do | ||||
| do_request | do_request | ||||
| expect(response).to have_http_status(:not_found) | expect(response).to have_http_status(:not_found) | ||||
| end | end | ||||
| 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 | context 'when tag exists and has deerjikists' do | ||||
| before do | before do | ||||
| Deerjikist.create!(platform: platform1, code: code1, tag: tag) | Deerjikist.create!(platform: platform1, code: code1, tag: tag) | ||||
| end | end | ||||
| it 'returns 200 and deerjikists array' do | |||||
| it 'returns 200 with tag and deerjikists array' do | |||||
| do_request | do_request | ||||
| expect(response).to have_http_status(:ok) | 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 | end | ||||
| end | end | ||||