domain_blocks_spec.rb 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. # frozen_string_literal: true
  2. require 'rails_helper'
  3. RSpec.describe 'Domain Blocks' do
  4. let(:role) { UserRole.find_by(name: 'Admin') }
  5. let(:user) { Fabricate(:user, role: role) }
  6. let(:scopes) { 'admin:read:domain_blocks admin:write:domain_blocks' }
  7. let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
  8. let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
  9. describe 'GET /api/v1/admin/domain_blocks' do
  10. subject do
  11. get '/api/v1/admin/domain_blocks', headers: headers, params: params
  12. end
  13. let(:params) { {} }
  14. it_behaves_like 'forbidden for wrong scope', 'write:statuses'
  15. it_behaves_like 'forbidden for wrong role', ''
  16. it_behaves_like 'forbidden for wrong role', 'Moderator'
  17. context 'when there are no domain blocks' do
  18. it 'returns an empty list' do
  19. subject
  20. expect(response)
  21. .to have_http_status(200)
  22. expect(response.content_type)
  23. .to start_with('application/json')
  24. expect(response.parsed_body)
  25. .to be_empty
  26. end
  27. end
  28. context 'when there are domain blocks' do
  29. let!(:domain_blocks) do
  30. [
  31. Fabricate(:domain_block, severity: :silence, reject_media: true),
  32. Fabricate(:domain_block, severity: :suspend, obfuscate: true),
  33. Fabricate(:domain_block, severity: :noop, reject_reports: true),
  34. Fabricate(:domain_block, public_comment: 'Spam'),
  35. Fabricate(:domain_block, private_comment: 'Spam'),
  36. ]
  37. end
  38. let(:expected_responde) do
  39. domain_blocks.map do |domain_block|
  40. {
  41. id: domain_block.id.to_s,
  42. domain: domain_block.domain,
  43. digest: domain_block.domain_digest,
  44. created_at: domain_block.created_at.strftime('%Y-%m-%dT%H:%M:%S.%LZ'),
  45. severity: domain_block.severity.to_s,
  46. reject_media: domain_block.reject_media,
  47. reject_reports: domain_block.reject_reports,
  48. private_comment: domain_block.private_comment,
  49. public_comment: domain_block.public_comment,
  50. obfuscate: domain_block.obfuscate,
  51. }
  52. end
  53. end
  54. it 'returns the expected domain blocks' do
  55. subject
  56. expect(response)
  57. .to have_http_status(200)
  58. expect(response.content_type)
  59. .to start_with('application/json')
  60. expect(response.parsed_body)
  61. .to match_array(expected_responde)
  62. end
  63. context 'with limit param' do
  64. let(:params) { { limit: 2 } }
  65. it 'returns only the requested number of domain blocks' do
  66. subject
  67. expect(response.parsed_body.size).to eq(params[:limit])
  68. end
  69. end
  70. end
  71. end
  72. describe 'GET /api/v1/admin/domain_blocks/:id' do
  73. subject do
  74. get "/api/v1/admin/domain_blocks/#{domain_block.id}", headers: headers
  75. end
  76. let!(:domain_block) { Fabricate(:domain_block) }
  77. it_behaves_like 'forbidden for wrong scope', 'write:statuses'
  78. it_behaves_like 'forbidden for wrong role', ''
  79. it_behaves_like 'forbidden for wrong role', 'Moderator'
  80. it 'returns the expected domain block content', :aggregate_failures do
  81. subject
  82. expect(response).to have_http_status(200)
  83. expect(response.content_type)
  84. .to start_with('application/json')
  85. expect(response.parsed_body).to match(
  86. id: domain_block.id.to_s,
  87. domain: domain_block.domain,
  88. digest: domain_block.domain_digest,
  89. created_at: domain_block.created_at.strftime('%Y-%m-%dT%H:%M:%S.%LZ'),
  90. severity: domain_block.severity.to_s,
  91. reject_media: domain_block.reject_media,
  92. reject_reports: domain_block.reject_reports,
  93. private_comment: domain_block.private_comment,
  94. public_comment: domain_block.public_comment,
  95. obfuscate: domain_block.obfuscate
  96. )
  97. end
  98. context 'when the requested domain block does not exist' do
  99. it 'returns http not found' do
  100. get '/api/v1/admin/domain_blocks/-1', headers: headers
  101. expect(response).to have_http_status(404)
  102. expect(response.content_type)
  103. .to start_with('application/json')
  104. end
  105. end
  106. end
  107. describe 'POST /api/v1/admin/domain_blocks' do
  108. subject do
  109. post '/api/v1/admin/domain_blocks', headers: headers, params: params
  110. end
  111. let(:params) { { domain: 'foo.bar.com', severity: :silence } }
  112. it_behaves_like 'forbidden for wrong scope', 'write:statuses'
  113. it_behaves_like 'forbidden for wrong role', ''
  114. it_behaves_like 'forbidden for wrong role', 'Moderator'
  115. it 'creates a domain block with the expected domain name and severity', :aggregate_failures do
  116. subject
  117. expect(response).to have_http_status(200)
  118. expect(response.content_type)
  119. .to start_with('application/json')
  120. expect(response.parsed_body).to match a_hash_including(
  121. {
  122. domain: 'foo.bar.com',
  123. severity: 'silence',
  124. }
  125. )
  126. expect(DomainBlock.find_by(domain: 'foo.bar.com')).to be_present
  127. end
  128. context 'when a looser domain block already exists on a higher level domain' do
  129. let(:params) { { domain: 'foo.bar.com', severity: :suspend } }
  130. before do
  131. Fabricate(:domain_block, domain: 'bar.com', severity: :silence)
  132. end
  133. it 'creates a domain block with the expected domain name and severity', :aggregate_failures do
  134. subject
  135. expect(response).to have_http_status(200)
  136. expect(response.content_type)
  137. .to start_with('application/json')
  138. expect(response.parsed_body).to match a_hash_including(
  139. {
  140. domain: 'foo.bar.com',
  141. severity: 'suspend',
  142. }
  143. )
  144. expect(DomainBlock.find_by(domain: 'foo.bar.com')).to be_present
  145. end
  146. end
  147. context 'when a domain block already exists on the same domain' do
  148. before do
  149. Fabricate(:domain_block, domain: 'foo.bar.com', severity: :silence)
  150. end
  151. it 'returns existing domain block in error', :aggregate_failures do
  152. subject
  153. expect(response).to have_http_status(422)
  154. expect(response.content_type)
  155. .to start_with('application/json')
  156. expect(response.parsed_body[:existing_domain_block][:domain]).to eq('foo.bar.com')
  157. end
  158. end
  159. context 'when a stricter domain block already exists on a higher level domain' do
  160. before do
  161. Fabricate(:domain_block, domain: 'bar.com', severity: :suspend)
  162. end
  163. it 'returns existing domain block in error', :aggregate_failures do
  164. subject
  165. expect(response).to have_http_status(422)
  166. expect(response.content_type)
  167. .to start_with('application/json')
  168. expect(response.parsed_body[:existing_domain_block][:domain]).to eq('bar.com')
  169. end
  170. end
  171. context 'when given domain name is invalid' do
  172. let(:params) { { domain: 'foo bar', severity: :silence } }
  173. it 'returns http unprocessable entity' do
  174. subject
  175. expect(response).to have_http_status(422)
  176. expect(response.content_type)
  177. .to start_with('application/json')
  178. end
  179. end
  180. end
  181. describe 'PUT /api/v1/admin/domain_blocks/:id' do
  182. subject do
  183. put "/api/v1/admin/domain_blocks/#{domain_block.id}", headers: headers, params: params
  184. end
  185. let!(:domain_block) { Fabricate(:domain_block, domain: 'example.com', severity: :silence) }
  186. let(:params) { { domain: 'example.com', severity: 'suspend' } }
  187. it_behaves_like 'forbidden for wrong scope', 'write:statuses'
  188. it_behaves_like 'forbidden for wrong role', ''
  189. it_behaves_like 'forbidden for wrong role', 'Moderator'
  190. it 'returns the updated domain block', :aggregate_failures do
  191. subject
  192. expect(response).to have_http_status(200)
  193. expect(response.content_type)
  194. .to start_with('application/json')
  195. expect(response.parsed_body).to match a_hash_including(
  196. {
  197. id: domain_block.id.to_s,
  198. domain: domain_block.domain,
  199. digest: domain_block.domain_digest,
  200. severity: 'suspend',
  201. }
  202. )
  203. end
  204. it 'updates the block severity' do
  205. expect { subject }.to change { domain_block.reload.severity }.from('silence').to('suspend')
  206. end
  207. context 'when domain block does not exist' do
  208. it 'returns http not found' do
  209. put '/api/v1/admin/domain_blocks/-1', headers: headers
  210. expect(response).to have_http_status(404)
  211. expect(response.content_type)
  212. .to start_with('application/json')
  213. end
  214. end
  215. end
  216. describe 'DELETE /api/v1/admin/domain_blocks/:id' do
  217. subject do
  218. delete "/api/v1/admin/domain_blocks/#{domain_block.id}", headers: headers
  219. end
  220. let!(:domain_block) { Fabricate(:domain_block) }
  221. it_behaves_like 'forbidden for wrong scope', 'write:statuses'
  222. it_behaves_like 'forbidden for wrong role', ''
  223. it_behaves_like 'forbidden for wrong role', 'Moderator'
  224. it 'deletes the domain block', :aggregate_failures do
  225. subject
  226. expect(response).to have_http_status(200)
  227. expect(response.content_type)
  228. .to start_with('application/json')
  229. expect(DomainBlock.find_by(id: domain_block.id)).to be_nil
  230. end
  231. context 'when domain block does not exist' do
  232. it 'returns http not found' do
  233. delete '/api/v1/admin/domain_blocks/-1', headers: headers
  234. expect(response).to have_http_status(404)
  235. expect(response.content_type)
  236. .to start_with('application/json')
  237. end
  238. end
  239. end
  240. end