outboxes_controller_spec.rb 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  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(:remote_account) { nil }
  17. context 'with page not requested' do
  18. let(:page) { nil }
  19. it 'returns http success and correct media type and headers and items count' do
  20. expect(response)
  21. .to have_http_status(200)
  22. .and have_cacheable_headers
  23. expect(response.media_type).to eq 'application/activity+json'
  24. expect(response.headers['Vary']).to be_nil
  25. expect(response.parsed_body[:totalItems]).to eq 4
  26. end
  27. context 'when account is permanently suspended' do
  28. before do
  29. account.suspend!
  30. account.deletion_request.destroy
  31. end
  32. it 'returns http gone' do
  33. expect(response).to have_http_status(410)
  34. end
  35. end
  36. context 'when account is temporarily suspended' do
  37. before do
  38. account.suspend!
  39. end
  40. it 'returns http forbidden' do
  41. expect(response).to have_http_status(403)
  42. end
  43. end
  44. end
  45. context 'with page requested' do
  46. let(:page) { 'true' }
  47. it 'returns http success and correct media type and vary header and items' do
  48. expect(response)
  49. .to have_http_status(200)
  50. .and have_cacheable_headers
  51. expect(response.media_type).to eq 'application/activity+json'
  52. expect(response.headers['Vary']).to include 'Signature'
  53. expect(response.parsed_body)
  54. .to include(
  55. orderedItems: be_an(Array)
  56. .and(have_attributes(size: 2))
  57. .and(all(satisfy { |item| targets_public_collection?(item) }))
  58. )
  59. end
  60. context 'when account is permanently suspended' do
  61. before do
  62. account.suspend!
  63. account.deletion_request.destroy
  64. end
  65. it 'returns http gone' do
  66. expect(response).to have_http_status(410)
  67. end
  68. end
  69. context 'when account is temporarily suspended' do
  70. before do
  71. account.suspend!
  72. end
  73. it 'returns http forbidden' do
  74. expect(response).to have_http_status(403)
  75. end
  76. end
  77. end
  78. end
  79. context 'with signature' do
  80. let(:remote_account) { Fabricate(:account, domain: 'example.com') }
  81. let(:page) { 'true' }
  82. context 'when signed request account does not follow account' do
  83. before do
  84. get :show, params: { account_username: account.username, page: page }
  85. end
  86. it 'returns http success and correct media type and headers and items' do
  87. expect(response).to have_http_status(200)
  88. expect(response.media_type).to eq 'application/activity+json'
  89. expect(response.headers['Cache-Control']).to eq 'max-age=60, private'
  90. expect(response.parsed_body)
  91. .to include(
  92. orderedItems: be_an(Array)
  93. .and(have_attributes(size: 2))
  94. .and(all(satisfy { |item| targets_public_collection?(item) }))
  95. )
  96. end
  97. end
  98. context 'when signed request account follows account' do
  99. before do
  100. remote_account.follow!(account)
  101. get :show, params: { account_username: account.username, page: page }
  102. end
  103. it 'returns http success and correct media type and headers and items' do
  104. expect(response).to have_http_status(200)
  105. expect(response.media_type).to eq 'application/activity+json'
  106. expect(response.headers['Cache-Control']).to eq 'max-age=60, private'
  107. expect(response.parsed_body)
  108. .to include(
  109. orderedItems: be_an(Array)
  110. .and(have_attributes(size: 3))
  111. .and(all(satisfy { |item| targets_public_collection?(item) || targets_followers_collection?(item, account) }))
  112. )
  113. end
  114. end
  115. context 'when signed request account is blocked' do
  116. before do
  117. account.block!(remote_account)
  118. get :show, params: { account_username: account.username, page: page }
  119. end
  120. it 'returns http success and correct media type and headers and items' do
  121. expect(response).to have_http_status(200)
  122. expect(response.media_type).to eq 'application/activity+json'
  123. expect(response.headers['Cache-Control']).to eq 'max-age=60, private'
  124. expect(response.parsed_body)
  125. .to include(
  126. orderedItems: be_an(Array).and(be_empty)
  127. )
  128. end
  129. end
  130. context 'when signed request account is domain blocked' do
  131. before do
  132. account.block_domain!(remote_account.domain)
  133. get :show, params: { account_username: account.username, page: page }
  134. end
  135. it 'returns http success and correct media type and headers and items' do
  136. expect(response).to have_http_status(200)
  137. expect(response.media_type).to eq 'application/activity+json'
  138. expect(response.headers['Cache-Control']).to eq 'max-age=60, private'
  139. expect(response.parsed_body)
  140. .to include(
  141. orderedItems: be_an(Array).and(be_empty)
  142. )
  143. end
  144. end
  145. end
  146. end
  147. private
  148. def ap_public_collection
  149. ActivityPub::TagManager::COLLECTIONS[:public]
  150. end
  151. def targets_public_collection?(item)
  152. item[:to].include?(ap_public_collection) || item[:cc].include?(ap_public_collection)
  153. end
  154. def targets_followers_collection?(item, account)
  155. item[:to].include?(
  156. account_followers_url(account, ActionMailer::Base.default_url_options)
  157. )
  158. end
  159. end