filters_spec.rb 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. # frozen_string_literal: true
  2. require 'rails_helper'
  3. RSpec.describe 'Filters' do
  4. let(:user) { Fabricate(:user) }
  5. let(:scopes) { 'read:filters write:filters' }
  6. let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
  7. let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
  8. shared_examples 'unauthorized for invalid token' do
  9. let(:headers) { { 'Authorization' => '' } }
  10. it 'returns http unauthorized' do
  11. subject
  12. expect(response).to have_http_status(401)
  13. end
  14. end
  15. describe 'GET /api/v2/filters' do
  16. subject do
  17. get '/api/v2/filters', headers: headers
  18. end
  19. let!(:filters) { Fabricate.times(3, :custom_filter, account: user.account) }
  20. it_behaves_like 'forbidden for wrong scope', 'write write:filters'
  21. it_behaves_like 'unauthorized for invalid token'
  22. it 'returns the existing filters successfully', :aggregate_failures do
  23. subject
  24. expect(response).to have_http_status(200)
  25. expect(body_as_json.pluck(:id)).to match_array(filters.map { |filter| filter.id.to_s })
  26. end
  27. end
  28. describe 'POST /api/v2/filters' do
  29. subject do
  30. post '/api/v2/filters', params: params, headers: headers
  31. end
  32. let(:params) { {} }
  33. it_behaves_like 'forbidden for wrong scope', 'read read:filters'
  34. it_behaves_like 'unauthorized for invalid token'
  35. context 'with valid params' do
  36. let(:params) { { title: 'magic', context: %w(home), filter_action: 'hide', keywords_attributes: [keyword: 'magic'] } }
  37. it 'returns http success' do
  38. subject
  39. expect(response).to have_http_status(200)
  40. end
  41. it 'returns a filter with keywords', :aggregate_failures do
  42. subject
  43. json = body_as_json
  44. expect(json[:title]).to eq 'magic'
  45. expect(json[:filter_action]).to eq 'hide'
  46. expect(json[:context]).to eq ['home']
  47. expect(json[:keywords].map { |keyword| keyword.slice(:keyword, :whole_word) }).to eq [{ keyword: 'magic', whole_word: true }]
  48. end
  49. it 'creates a filter', :aggregate_failures do
  50. subject
  51. filter = user.account.custom_filters.first
  52. expect(filter).to be_present
  53. expect(filter.keywords.pluck(:keyword)).to eq ['magic']
  54. expect(filter.context).to eq %w(home)
  55. expect(filter.irreversible?).to be true
  56. expect(filter.expires_at).to be_nil
  57. end
  58. end
  59. context 'when the required title param is missing' do
  60. let(:params) { { context: %w(home), filter_action: 'hide', keywords_attributes: [keyword: 'magic'] } }
  61. it 'returns http unprocessable entity' do
  62. subject
  63. expect(response).to have_http_status(422)
  64. end
  65. end
  66. context 'when the required context param is missing' do
  67. let(:params) { { title: 'magic', filter_action: 'hide', keywords_attributes: [keyword: 'magic'] } }
  68. it 'returns http unprocessable entity' do
  69. subject
  70. expect(response).to have_http_status(422)
  71. end
  72. end
  73. context 'when the given context value is invalid' do
  74. let(:params) { { title: 'magic', context: %w(shaolin), filter_action: 'hide', keywords_attributes: [keyword: 'magic'] } }
  75. it 'returns http unprocessable entity' do
  76. subject
  77. expect(response).to have_http_status(422)
  78. end
  79. end
  80. end
  81. describe 'GET /api/v2/filters/:id' do
  82. subject do
  83. get "/api/v2/filters/#{filter.id}", headers: headers
  84. end
  85. let(:filter) { Fabricate(:custom_filter, account: user.account) }
  86. it_behaves_like 'forbidden for wrong scope', 'write write:filters'
  87. it_behaves_like 'unauthorized for invalid token'
  88. it 'returns the filter successfully', :aggregate_failures do
  89. subject
  90. expect(response).to have_http_status(200)
  91. expect(body_as_json[:id]).to eq(filter.id.to_s)
  92. end
  93. context 'when the filter belongs to someone else' do
  94. let(:filter) { Fabricate(:custom_filter) }
  95. it 'returns http not found' do
  96. subject
  97. expect(response).to have_http_status(404)
  98. end
  99. end
  100. end
  101. describe 'PUT /api/v2/filters/:id' do
  102. subject do
  103. put "/api/v2/filters/#{filter.id}", params: params, headers: headers
  104. end
  105. let!(:filter) { Fabricate(:custom_filter, account: user.account) }
  106. let!(:keyword) { Fabricate(:custom_filter_keyword, custom_filter: filter) }
  107. let(:params) { {} }
  108. it_behaves_like 'forbidden for wrong scope', 'read read:filters'
  109. it_behaves_like 'unauthorized for invalid token'
  110. context 'when updating filter parameters' do
  111. context 'with valid params' do
  112. let(:params) { { title: 'updated', context: %w(home public) } }
  113. it 'updates the filter successfully', :aggregate_failures do
  114. subject
  115. filter.reload
  116. expect(response).to have_http_status(200)
  117. expect(filter.title).to eq 'updated'
  118. expect(filter.reload.context).to eq %w(home public)
  119. end
  120. end
  121. context 'with invalid params' do
  122. let(:params) { { title: 'updated', context: %w(word) } }
  123. it 'returns http unprocessable entity' do
  124. subject
  125. expect(response).to have_http_status(422)
  126. end
  127. end
  128. end
  129. context 'when updating keywords in bulk' do
  130. let(:params) { { keywords_attributes: [{ id: keyword.id, keyword: 'updated' }] } }
  131. before do
  132. allow(redis).to receive_messages(publish: nil)
  133. end
  134. it 'returns http success' do
  135. subject
  136. expect(response).to have_http_status(200)
  137. end
  138. it 'updates the keyword' do
  139. subject
  140. expect(keyword.reload.keyword).to eq 'updated'
  141. end
  142. it 'sends exactly one filters_changed event' do
  143. subject
  144. expect(redis).to have_received(:publish).with("timeline:#{user.account.id}", Oj.dump(event: :filters_changed)).once
  145. end
  146. end
  147. context 'when the filter belongs to someone else' do
  148. let(:filter) { Fabricate(:custom_filter) }
  149. it 'returns http not found' do
  150. subject
  151. expect(response).to have_http_status(404)
  152. end
  153. end
  154. end
  155. describe 'DELETE /api/v2/filters/:id' do
  156. subject do
  157. delete "/api/v2/filters/#{filter.id}", headers: headers
  158. end
  159. let(:filter) { Fabricate(:custom_filter, account: user.account) }
  160. it_behaves_like 'forbidden for wrong scope', 'read read:filters'
  161. it_behaves_like 'unauthorized for invalid token'
  162. it 'returns http success' do
  163. subject
  164. expect(response).to have_http_status(200)
  165. end
  166. it 'removes the filter' do
  167. subject
  168. expect { filter.reload }.to raise_error ActiveRecord::RecordNotFound
  169. end
  170. context 'when the filter belongs to someone else' do
  171. let(:filter) { Fabricate(:custom_filter) }
  172. it 'returns http not found' do
  173. subject
  174. expect(response).to have_http_status(404)
  175. end
  176. end
  177. end
  178. end