ぼざクリタグ広場 https://hub.nizika.monster
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

192 lines
5.6 KiB

  1. require 'digest'
  2. require 'rails_helper'
  3. require 'stringio'
  4. RSpec.describe 'WikiAssets API', type: :request do
  5. def dummy_upload(content = 'dummy-image', filename: 'dummy.png', content_type: 'image/png')
  6. Rack::Test::UploadedFile.new(StringIO.new(content),
  7. content_type,
  8. original_filename: filename)
  9. end
  10. let(:member) { create(:user, :member, name: 'member user') }
  11. let(:guest) { create(:user, name: 'guest user') }
  12. let!(:tag_name) { TagName.create!(name: 'spec_wiki_asset_page') }
  13. let!(:page) do
  14. WikiPage.create!(tag_name: tag_name, created_user: member, updated_user: member).tap do |p|
  15. Wiki::Commit.content!(page: p, body: 'init', created_user: member, message: 'init')
  16. end
  17. end
  18. describe 'GET /wiki/:wiki_page_id/assets' do
  19. subject(:do_request) do
  20. get "/wiki/#{wiki_page_id}/assets"
  21. end
  22. let(:wiki_page_id) { page.id }
  23. let!(:asset) do
  24. WikiAsset.new(wiki_page: page,
  25. no: 1,
  26. alt_text: 'spec alt',
  27. sha256: Digest::SHA256.digest('asset-1'),
  28. created_by_user: member).tap do |record|
  29. record.file.attach(dummy_upload('asset-1'))
  30. record.save!
  31. end
  32. end
  33. context 'when wiki page exists' do
  34. it 'returns assets for the page' do
  35. do_request
  36. expect(response).to have_http_status(:ok)
  37. expect(json).to be_an(Array)
  38. expect(json.size).to eq(1)
  39. expect(json.first).to include(
  40. 'wiki_page_id' => page.id,
  41. 'no' => 1)
  42. end
  43. it 'does not include assets from other pages' do
  44. other_tag_name = TagName.create!(name: 'spec_other_wiki_asset_page')
  45. other_page = WikiPage.create!(tag_name: other_tag_name,
  46. created_user: member,
  47. updated_user: member)
  48. Wiki::Commit.content!(page: other_page, body: 'other', created_user: member, message: 'other')
  49. WikiAsset.new(wiki_page: other_page,
  50. no: 1,
  51. alt_text: 'other alt',
  52. sha256: Digest::SHA256.digest('asset-2'),
  53. created_by_user: member).tap do |record|
  54. record.file.attach(dummy_upload('asset-2', filename: 'other.png'))
  55. record.save!
  56. end
  57. do_request
  58. expect(response).to have_http_status(:ok)
  59. expect(json.size).to eq(1)
  60. expect(json.first['wiki_page_id']).to eq(page.id)
  61. end
  62. end
  63. context 'when wiki page does not exist' do
  64. let(:wiki_page_id) { 999_999_999 }
  65. it 'returns 404' do
  66. do_request
  67. expect(response).to have_http_status(:not_found)
  68. end
  69. end
  70. end
  71. describe 'POST /wiki/:wiki_page_id/assets' do
  72. subject(:do_request) do
  73. post "/wiki/#{wiki_page_id}/assets", params: params
  74. end
  75. let(:wiki_page_id) { page.id }
  76. let(:params) do
  77. { file: dummy_upload(upload_content),
  78. alt_text: 'uploaded alt' }
  79. end
  80. let(:upload_content) { 'uploaded-image-binary' }
  81. context 'when not logged in' do
  82. it 'returns 401' do
  83. sign_out
  84. do_request
  85. expect(response).to have_http_status(:unauthorized)
  86. end
  87. end
  88. context 'when logged in but not member' do
  89. it 'returns 403' do
  90. sign_in_as(guest)
  91. do_request
  92. expect(response).to have_http_status(:forbidden)
  93. end
  94. end
  95. context 'when wiki page does not exist' do
  96. let(:wiki_page_id) { 999_999_999 }
  97. it 'returns 404' do
  98. sign_in_as(member)
  99. do_request
  100. expect(response).to have_http_status(:not_found)
  101. end
  102. end
  103. context 'when file is blank' do
  104. let(:params) { { alt_text: 'uploaded alt' } }
  105. it 'returns 400' do
  106. sign_in_as(member)
  107. do_request
  108. expect(response).to have_http_status(:bad_request)
  109. end
  110. end
  111. context 'when success' do
  112. before do
  113. sign_in_as(member)
  114. end
  115. it 'creates asset, attaches file, increments next_asset_no, and returns json' do
  116. expect { do_request }
  117. .to change(WikiAsset, :count).by(1)
  118. expect(response).to have_http_status(:ok)
  119. asset = WikiAsset.order(:id).last
  120. expect(asset.wiki_page_id).to eq(page.id)
  121. expect(asset.no).to eq(1)
  122. expect(asset.alt_text).to eq('uploaded alt')
  123. expect(asset.sha256).to eq(Digest::SHA256.digest(upload_content))
  124. expect(asset.created_by_user_id).to eq(member.id)
  125. expect(asset.file).to be_attached
  126. expect(asset.file.download).to eq(upload_content)
  127. expect(page.reload.next_asset_no).to eq(2)
  128. expect(json).to include(
  129. 'wiki_page_id' => page.id,
  130. 'no' => 1,
  131. 'url' => asset.url
  132. )
  133. end
  134. it 'uses the next page-local number when assets already exist' do
  135. existing = WikiAsset.new(wiki_page: page,
  136. no: 1,
  137. alt_text: 'existing alt',
  138. sha256: Digest::SHA256.digest('existing'),
  139. created_by_user: member)
  140. existing.file.attach(dummy_upload('existing', filename: 'existing.png'))
  141. existing.save!
  142. page.update!(next_asset_no: 2)
  143. do_request
  144. expect(response).to have_http_status(:ok)
  145. asset = WikiAsset.order(:id).last
  146. expect(asset.no).to eq(2)
  147. expect(page.reload.next_asset_no).to eq(3)
  148. expect(json).to include(
  149. 'wiki_page_id' => page.id,
  150. 'no' => 2,
  151. 'url' => asset.url
  152. )
  153. end
  154. end
  155. end
  156. end