|
- require 'digest'
- require 'rails_helper'
- require 'stringio'
-
-
- RSpec.describe 'WikiAssets API', type: :request do
- def dummy_upload(content = 'dummy-image', filename: 'dummy.png', content_type: 'image/png')
- Rack::Test::UploadedFile.new(StringIO.new(content),
- content_type,
- original_filename: filename)
- end
-
- let(:member) { create(:user, :member, name: 'member user') }
- let(:guest) { create(:user, name: 'guest user') }
-
- let!(:tag_name) { TagName.create!(name: 'spec_wiki_asset_page') }
- let!(:page) do
- WikiPage.create!(tag_name: tag_name, created_user: member, updated_user: member).tap do |p|
- Wiki::Commit.content!(page: p, body: 'init', created_user: member, message: 'init')
- end
- end
-
- describe 'GET /wiki/:wiki_page_id/assets' do
- subject(:do_request) do
- get "/wiki/#{wiki_page_id}/assets"
- end
-
- let(:wiki_page_id) { page.id }
-
- let!(:asset) do
- WikiAsset.new(wiki_page: page,
- no: 1,
- alt_text: 'spec alt',
- sha256: Digest::SHA256.digest('asset-1'),
- created_by_user: member).tap do |record|
- record.file.attach(dummy_upload('asset-1'))
- record.save!
- end
- end
-
- context 'when wiki page exists' do
- it 'returns assets for the page' do
- do_request
-
- expect(response).to have_http_status(:ok)
- expect(json).to be_an(Array)
- expect(json.size).to eq(1)
-
- expect(json.first).to include(
- 'wiki_page_id' => page.id,
- 'no' => 1)
- end
-
- it 'does not include assets from other pages' do
- other_tag_name = TagName.create!(name: 'spec_other_wiki_asset_page')
- other_page = WikiPage.create!(tag_name: other_tag_name,
- created_user: member,
- updated_user: member)
- Wiki::Commit.content!(page: other_page, body: 'other', created_user: member, message: 'other')
-
- WikiAsset.new(wiki_page: other_page,
- no: 1,
- alt_text: 'other alt',
- sha256: Digest::SHA256.digest('asset-2'),
- created_by_user: member).tap do |record|
- record.file.attach(dummy_upload('asset-2', filename: 'other.png'))
- record.save!
- end
-
- do_request
-
- expect(response).to have_http_status(:ok)
- expect(json.size).to eq(1)
- expect(json.first['wiki_page_id']).to eq(page.id)
- end
- end
-
- context 'when wiki page does not exist' do
- let(:wiki_page_id) { 999_999_999 }
-
- it 'returns 404' do
- do_request
- expect(response).to have_http_status(:not_found)
- end
- end
- end
-
- describe 'POST /wiki/:wiki_page_id/assets' do
- subject(:do_request) do
- post "/wiki/#{wiki_page_id}/assets", params: params
- end
-
- let(:wiki_page_id) { page.id }
- let(:params) do
- { file: dummy_upload(upload_content),
- alt_text: 'uploaded alt' }
- end
- let(:upload_content) { 'uploaded-image-binary' }
-
- 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 wiki page does not exist' do
- let(:wiki_page_id) { 999_999_999 }
-
- it 'returns 404' do
- sign_in_as(member)
- do_request
- expect(response).to have_http_status(:not_found)
- end
- end
-
- context 'when file is blank' do
- let(:params) { { alt_text: 'uploaded alt' } }
-
- it 'returns 400' do
- sign_in_as(member)
- do_request
- expect(response).to have_http_status(:bad_request)
- end
- end
-
- context 'when success' do
- before do
- sign_in_as(member)
- end
-
- it 'creates asset, attaches file, increments next_asset_no, and returns json' do
- expect { do_request }
- .to change(WikiAsset, :count).by(1)
-
- expect(response).to have_http_status(:ok)
-
- asset = WikiAsset.order(:id).last
- expect(asset.wiki_page_id).to eq(page.id)
- expect(asset.no).to eq(1)
- expect(asset.alt_text).to eq('uploaded alt')
- expect(asset.sha256).to eq(Digest::SHA256.digest(upload_content))
- expect(asset.created_by_user_id).to eq(member.id)
- expect(asset.file).to be_attached
- expect(asset.file.download).to eq(upload_content)
-
- expect(page.reload.next_asset_no).to eq(2)
-
- expect(json).to include(
- 'wiki_page_id' => page.id,
- 'no' => 1,
- 'url' => asset.url
- )
- end
-
- it 'uses the next page-local number when assets already exist' do
- existing = WikiAsset.new(wiki_page: page,
- no: 1,
- alt_text: 'existing alt',
- sha256: Digest::SHA256.digest('existing'),
- created_by_user: member)
- existing.file.attach(dummy_upload('existing', filename: 'existing.png'))
- existing.save!
- page.update!(next_asset_no: 2)
-
- do_request
-
- expect(response).to have_http_status(:ok)
-
- asset = WikiAsset.order(:id).last
- expect(asset.no).to eq(2)
- expect(page.reload.next_asset_no).to eq(3)
-
- expect(json).to include(
- 'wiki_page_id' => page.id,
- 'no' => 2,
- 'url' => asset.url
- )
- end
- end
- end
- end
|