outboxes_controller_spec.rb 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. # frozen_string_literal: true
  2. require 'rails_helper'
  3. RSpec.describe ActivityPub::OutboxesController do
  4. let!(:account) { Fabricate(:account) }
  5. before do
  6. Fabricate(:status, account: account, visibility: :public)
  7. Fabricate(:status, account: account, visibility: :unlisted)
  8. Fabricate(:status, account: account, visibility: :private)
  9. Fabricate(:status, account: account, visibility: :direct)
  10. Fabricate(:status, account: account, visibility: :limited)
  11. allow(controller).to receive(:signed_request_actor).and_return(remote_account)
  12. end
  13. describe 'GET #show' do
  14. context 'without signature' do
  15. subject(:response) { get :show, params: { account_username: account.username, page: page } }
  16. let(:body) { body_as_json }
  17. let(:remote_account) { nil }
  18. context 'with page not requested' do
  19. let(:page) { nil }
  20. it 'returns http success' do
  21. expect(response).to have_http_status(200)
  22. end
  23. it 'returns application/activity+json' do
  24. expect(response.media_type).to eq 'application/activity+json'
  25. end
  26. it 'returns totalItems' do
  27. expect(body[:totalItems]).to eq 4
  28. end
  29. it_behaves_like 'cacheable response'
  30. it 'does not have a Vary header' do
  31. expect(response.headers['Vary']).to be_nil
  32. end
  33. context 'when account is permanently suspended' do
  34. before do
  35. account.suspend!
  36. account.deletion_request.destroy
  37. end
  38. it 'returns http gone' do
  39. expect(response).to have_http_status(410)
  40. end
  41. end
  42. context 'when account is temporarily suspended' do
  43. before do
  44. account.suspend!
  45. end
  46. it 'returns http forbidden' do
  47. expect(response).to have_http_status(403)
  48. end
  49. end
  50. end
  51. context 'with page requested' do
  52. let(:page) { 'true' }
  53. it 'returns http success' do
  54. expect(response).to have_http_status(200)
  55. end
  56. it 'returns application/activity+json' do
  57. expect(response.media_type).to eq 'application/activity+json'
  58. end
  59. it 'returns orderedItems with public or unlisted statuses' do
  60. expect(body[:orderedItems]).to be_an Array
  61. expect(body[:orderedItems].size).to eq 2
  62. expect(body[:orderedItems].all? { |item| targets_public_collection?(item) }).to be true
  63. end
  64. it_behaves_like 'cacheable response'
  65. it 'returns Vary header with Signature' do
  66. expect(response.headers['Vary']).to include 'Signature'
  67. end
  68. context 'when account is permanently suspended' do
  69. before do
  70. account.suspend!
  71. account.deletion_request.destroy
  72. end
  73. it 'returns http gone' do
  74. expect(response).to have_http_status(410)
  75. end
  76. end
  77. context 'when account is temporarily suspended' do
  78. before do
  79. account.suspend!
  80. end
  81. it 'returns http forbidden' do
  82. expect(response).to have_http_status(403)
  83. end
  84. end
  85. end
  86. end
  87. context 'with signature' do
  88. let(:remote_account) { Fabricate(:account, domain: 'example.com') }
  89. let(:page) { 'true' }
  90. context 'when signed request account does not follow account' do
  91. before do
  92. get :show, params: { account_username: account.username, page: page }
  93. end
  94. it 'returns http success' do
  95. expect(response).to have_http_status(200)
  96. end
  97. it 'returns application/activity+json' do
  98. expect(response.media_type).to eq 'application/activity+json'
  99. end
  100. it 'returns orderedItems with public or unlisted statuses' do
  101. json = body_as_json
  102. expect(json[:orderedItems]).to be_an Array
  103. expect(json[:orderedItems].size).to eq 2
  104. expect(json[:orderedItems].all? { |item| targets_public_collection?(item) }).to be true
  105. end
  106. it 'returns private Cache-Control header' do
  107. expect(response.headers['Cache-Control']).to eq 'max-age=60, private'
  108. end
  109. end
  110. context 'when signed request account follows account' do
  111. before do
  112. remote_account.follow!(account)
  113. get :show, params: { account_username: account.username, page: page }
  114. end
  115. it 'returns http success' do
  116. expect(response).to have_http_status(200)
  117. end
  118. it 'returns application/activity+json' do
  119. expect(response.media_type).to eq 'application/activity+json'
  120. end
  121. it 'returns orderedItems with private statuses' do
  122. json = body_as_json
  123. expect(json[:orderedItems]).to be_an Array
  124. expect(json[:orderedItems].size).to eq 3
  125. expect(json[:orderedItems].all? { |item| targets_public_collection?(item) || targets_followers_collection?(item, account) }).to be true
  126. end
  127. it 'returns private Cache-Control header' do
  128. expect(response.headers['Cache-Control']).to eq 'max-age=60, private'
  129. end
  130. end
  131. context 'when signed request account is blocked' do
  132. before do
  133. account.block!(remote_account)
  134. get :show, params: { account_username: account.username, page: page }
  135. end
  136. it 'returns http success' do
  137. expect(response).to have_http_status(200)
  138. end
  139. it 'returns application/activity+json' do
  140. expect(response.media_type).to eq 'application/activity+json'
  141. end
  142. it 'returns empty orderedItems' do
  143. json = body_as_json
  144. expect(json[:orderedItems]).to be_an Array
  145. expect(json[:orderedItems].size).to eq 0
  146. end
  147. it 'returns private Cache-Control header' do
  148. expect(response.headers['Cache-Control']).to eq 'max-age=60, private'
  149. end
  150. end
  151. context 'when signed request account is domain blocked' do
  152. before do
  153. account.block_domain!(remote_account.domain)
  154. get :show, params: { account_username: account.username, page: page }
  155. end
  156. it 'returns http success' do
  157. expect(response).to have_http_status(200)
  158. end
  159. it 'returns application/activity+json' do
  160. expect(response.media_type).to eq 'application/activity+json'
  161. end
  162. it 'returns empty orderedItems' do
  163. json = body_as_json
  164. expect(json[:orderedItems]).to be_an Array
  165. expect(json[:orderedItems].size).to eq 0
  166. end
  167. it 'returns private Cache-Control header' do
  168. expect(response.headers['Cache-Control']).to eq 'max-age=60, private'
  169. end
  170. end
  171. end
  172. end
  173. private
  174. def ap_public_collection
  175. ActivityPub::TagManager::COLLECTIONS[:public]
  176. end
  177. def targets_public_collection?(item)
  178. item[:to].include?(ap_public_collection) || item[:cc].include?(ap_public_collection)
  179. end
  180. def targets_followers_collection?(item, account)
  181. item[:to].include?(
  182. account_followers_url(account, ActionMailer::Base.default_url_options)
  183. )
  184. end
  185. end