statuses_controller_spec.rb 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. require 'rails_helper'
  2. RSpec.describe Api::V1::StatusesController, type: :controller do
  3. render_views
  4. let(:user) { Fabricate(:user) }
  5. let(:app) { Fabricate(:application, name: 'Test app', website: 'http://testapp.com') }
  6. let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, application: app, scopes: scopes) }
  7. context 'with an oauth token' do
  8. before do
  9. allow(controller).to receive(:doorkeeper_token) { token }
  10. end
  11. describe 'GET #show' do
  12. let(:scopes) { 'read:statuses' }
  13. let(:status) { Fabricate(:status, account: user.account) }
  14. it 'returns http success' do
  15. get :show, params: { id: status.id }
  16. expect(response).to have_http_status(200)
  17. end
  18. context 'when post includes filtered terms' do
  19. let(:status) { Fabricate(:status, text: 'this toot is about that banned word') }
  20. before do
  21. user.account.custom_filters.create!(phrase: 'filter1', context: %w(home), action: :hide, keywords_attributes: [{ keyword: 'banned' }, { keyword: 'irrelevant' }])
  22. end
  23. it 'returns http success' do
  24. get :show, params: { id: status.id }
  25. expect(response).to have_http_status(200)
  26. end
  27. it 'returns filter information' do
  28. get :show, params: { id: status.id }
  29. json = body_as_json
  30. expect(json[:filtered][0]).to include({
  31. filter: a_hash_including({
  32. id: user.account.custom_filters.first.id.to_s,
  33. title: 'filter1',
  34. filter_action: 'hide',
  35. }),
  36. keyword_matches: ['banned'],
  37. })
  38. end
  39. end
  40. context 'when post is explicitly filtered' do
  41. let(:status) { Fabricate(:status, text: 'hello world') }
  42. before do
  43. filter = user.account.custom_filters.create!(phrase: 'filter1', context: %w(home), action: :hide)
  44. filter.statuses.create!(status_id: status.id)
  45. end
  46. it 'returns http success' do
  47. get :show, params: { id: status.id }
  48. expect(response).to have_http_status(200)
  49. end
  50. it 'returns filter information' do
  51. get :show, params: { id: status.id }
  52. json = body_as_json
  53. expect(json[:filtered][0]).to include({
  54. filter: a_hash_including({
  55. id: user.account.custom_filters.first.id.to_s,
  56. title: 'filter1',
  57. filter_action: 'hide',
  58. }),
  59. status_matches: [status.id.to_s],
  60. })
  61. end
  62. end
  63. context 'when reblog includes filtered terms' do
  64. let(:status) { Fabricate(:status, reblog: Fabricate(:status, text: 'this toot is about that banned word')) }
  65. before do
  66. user.account.custom_filters.create!(phrase: 'filter1', context: %w(home), action: :hide, keywords_attributes: [{ keyword: 'banned' }, { keyword: 'irrelevant' }])
  67. end
  68. it 'returns http success' do
  69. get :show, params: { id: status.id }
  70. expect(response).to have_http_status(200)
  71. end
  72. it 'returns filter information' do
  73. get :show, params: { id: status.id }
  74. json = body_as_json
  75. expect(json[:reblog][:filtered][0]).to include({
  76. filter: a_hash_including({
  77. id: user.account.custom_filters.first.id.to_s,
  78. title: 'filter1',
  79. filter_action: 'hide',
  80. }),
  81. keyword_matches: ['banned'],
  82. })
  83. end
  84. end
  85. end
  86. describe 'GET #context' do
  87. let(:scopes) { 'read:statuses' }
  88. let(:status) { Fabricate(:status, account: user.account) }
  89. before do
  90. Fabricate(:status, account: user.account, thread: status)
  91. end
  92. it 'returns http success' do
  93. get :context, params: { id: status.id }
  94. expect(response).to have_http_status(200)
  95. end
  96. end
  97. describe 'POST #create' do
  98. let(:scopes) { 'write:statuses' }
  99. context do
  100. before do
  101. post :create, params: { status: 'Hello world' }
  102. end
  103. it 'returns http success' do
  104. expect(response).to have_http_status(200)
  105. end
  106. it 'returns rate limit headers' do
  107. expect(response.headers['X-RateLimit-Limit']).to eq RateLimiter::FAMILIES[:statuses][:limit].to_s
  108. expect(response.headers['X-RateLimit-Remaining']).to eq (RateLimiter::FAMILIES[:statuses][:limit] - 1).to_s
  109. end
  110. end
  111. context 'with missing parameters' do
  112. before do
  113. post :create, params: {}
  114. end
  115. it 'returns http unprocessable entity' do
  116. expect(response).to have_http_status(422)
  117. end
  118. it 'returns rate limit headers' do
  119. expect(response.headers['X-RateLimit-Limit']).to eq RateLimiter::FAMILIES[:statuses][:limit].to_s
  120. end
  121. end
  122. context 'when exceeding rate limit' do
  123. before do
  124. rate_limiter = RateLimiter.new(user.account, family: :statuses)
  125. 300.times { rate_limiter.record! }
  126. post :create, params: { status: 'Hello world' }
  127. end
  128. it 'returns http too many requests' do
  129. expect(response).to have_http_status(429)
  130. end
  131. it 'returns rate limit headers' do
  132. expect(response.headers['X-RateLimit-Limit']).to eq RateLimiter::FAMILIES[:statuses][:limit].to_s
  133. expect(response.headers['X-RateLimit-Remaining']).to eq '0'
  134. end
  135. end
  136. end
  137. describe 'DELETE #destroy' do
  138. let(:scopes) { 'write:statuses' }
  139. let(:status) { Fabricate(:status, account: user.account) }
  140. before do
  141. post :destroy, params: { id: status.id }
  142. end
  143. it 'returns http success' do
  144. expect(response).to have_http_status(200)
  145. end
  146. it 'removes the status' do
  147. expect(Status.find_by(id: status.id)).to be nil
  148. end
  149. end
  150. describe 'PUT #update' do
  151. let(:scopes) { 'write:statuses' }
  152. let(:status) { Fabricate(:status, account: user.account) }
  153. before do
  154. put :update, params: { id: status.id, status: 'I am updated' }
  155. end
  156. it 'returns http success' do
  157. expect(response).to have_http_status(200)
  158. end
  159. it 'updates the status' do
  160. expect(status.reload.text).to eq 'I am updated'
  161. end
  162. end
  163. end
  164. context 'without an oauth token' do
  165. before do
  166. allow(controller).to receive(:doorkeeper_token) { nil }
  167. end
  168. context 'with a private status' do
  169. let(:status) { Fabricate(:status, account: user.account, visibility: :private) }
  170. describe 'GET #show' do
  171. it 'returns http unauthorized' do
  172. get :show, params: { id: status.id }
  173. expect(response).to have_http_status(404)
  174. end
  175. end
  176. describe 'GET #context' do
  177. before do
  178. Fabricate(:status, account: user.account, thread: status)
  179. end
  180. it 'returns http unauthorized' do
  181. get :context, params: { id: status.id }
  182. expect(response).to have_http_status(404)
  183. end
  184. end
  185. end
  186. context 'with a public status' do
  187. let(:status) { Fabricate(:status, account: user.account, visibility: :public) }
  188. describe 'GET #show' do
  189. it 'returns http success' do
  190. get :show, params: { id: status.id }
  191. expect(response).to have_http_status(200)
  192. end
  193. end
  194. describe 'GET #context' do
  195. before do
  196. Fabricate(:status, account: user.account, thread: status)
  197. end
  198. it 'returns http success' do
  199. get :context, params: { id: status.id }
  200. expect(response).to have_http_status(200)
  201. end
  202. end
  203. end
  204. end
  205. end