You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

224 lines
7.3 KiB

  1. # frozen_string_literal: true
  2. require 'rails_helper'
  3. RSpec.describe ActivityPub::RepliesController, type: :controller do
  4. let(:status) { Fabricate(:status, visibility: parent_visibility) }
  5. let(:remote_reply_id) { nil }
  6. let(:remote_account) { nil }
  7. shared_examples 'cachable response' do
  8. it 'does not set cookies' do
  9. expect(response.cookies).to be_empty
  10. expect(response.headers['Set-Cookies']).to be nil
  11. end
  12. it 'does not set sessions' do
  13. expect(session).to be_empty
  14. end
  15. it 'returns public Cache-Control header' do
  16. expect(response.headers['Cache-Control']).to include 'public'
  17. end
  18. end
  19. before do
  20. allow(controller).to receive(:signed_request_account).and_return(remote_account)
  21. Fabricate(:status, thread: status, visibility: :public)
  22. Fabricate(:status, thread: status, visibility: :public)
  23. Fabricate(:status, thread: status, visibility: :private)
  24. Fabricate(:status, account: status.account, thread: status, visibility: :public)
  25. Fabricate(:status, account: status.account, thread: status, visibility: :private)
  26. Fabricate(:status, account: remote_account, thread: status, visibility: :public, uri: remote_reply_id) if remote_reply_id
  27. end
  28. describe 'GET #index' do
  29. context 'with no signature' do
  30. before do
  31. get :index, params: { account_username: status.account.username, status_id: status.id }
  32. end
  33. context 'when status is public' do
  34. let(:parent_visibility) { :public }
  35. it 'returns http success' do
  36. expect(response).to have_http_status(200)
  37. end
  38. it 'returns application/activity+json' do
  39. expect(response.content_type).to eq 'application/activity+json'
  40. end
  41. it_behaves_like 'cachable response'
  42. it 'returns items with account\'s own replies' do
  43. json = body_as_json
  44. expect(json[:first]).to be_a Hash
  45. expect(json[:first][:items]).to be_an Array
  46. expect(json[:first][:items].size).to eq 1
  47. expect(json[:first][:items].all? { |item| item[:to].include?(ActivityPub::TagManager::COLLECTIONS[:public]) || item[:cc].include?(ActivityPub::TagManager::COLLECTIONS[:public]) }).to be true
  48. end
  49. end
  50. context 'when status is private' do
  51. let(:parent_visibility) { :private }
  52. it 'returns http not found' do
  53. expect(response).to have_http_status(404)
  54. end
  55. end
  56. context 'when status is direct' do
  57. let(:parent_visibility) { :direct }
  58. it 'returns http not found' do
  59. expect(response).to have_http_status(404)
  60. end
  61. end
  62. end
  63. context 'with signature' do
  64. let(:remote_account) { Fabricate(:account, domain: 'example.com') }
  65. let(:only_other_accounts) { nil }
  66. context do
  67. before do
  68. get :index, params: { account_username: status.account.username, status_id: status.id, only_other_accounts: only_other_accounts }
  69. end
  70. context 'when status is public' do
  71. let(:parent_visibility) { :public }
  72. it 'returns http success' do
  73. expect(response).to have_http_status(200)
  74. end
  75. it 'returns application/activity+json' do
  76. expect(response.content_type).to eq 'application/activity+json'
  77. end
  78. it_behaves_like 'cachable response'
  79. context 'without only_other_accounts' do
  80. it 'returns items with account\'s own replies' do
  81. json = body_as_json
  82. expect(json[:first]).to be_a Hash
  83. expect(json[:first][:items]).to be_an Array
  84. expect(json[:first][:items].size).to eq 1
  85. expect(json[:first][:items].all? { |item| item[:to].include?(ActivityPub::TagManager::COLLECTIONS[:public]) || item[:cc].include?(ActivityPub::TagManager::COLLECTIONS[:public]) }).to be true
  86. end
  87. end
  88. context 'with only_other_accounts' do
  89. let(:only_other_accounts) { 'true' }
  90. it 'returns items with other public or unlisted replies' do
  91. json = body_as_json
  92. expect(json[:first]).to be_a Hash
  93. expect(json[:first][:items]).to be_an Array
  94. expect(json[:first][:items].size).to eq 2
  95. expect(json[:first][:items].all? { |item| item[:to].include?(ActivityPub::TagManager::COLLECTIONS[:public]) || item[:cc].include?(ActivityPub::TagManager::COLLECTIONS[:public]) }).to be true
  96. end
  97. context 'with remote responses' do
  98. let(:remote_reply_id) { 'foo' }
  99. it 'returned items are all inlined local toots or are ids' do
  100. json = body_as_json
  101. expect(json[:first]).to be_a Hash
  102. expect(json[:first][:items]).to be_an Array
  103. expect(json[:first][:items].size).to eq 3
  104. expect(json[:first][:items].all? { |item| item.is_a?(Hash) ? ActivityPub::TagManager.instance.local_uri?(item[:id]) : item.is_a?(String) }).to be true
  105. expect(json[:first][:items]).to include remote_reply_id
  106. end
  107. end
  108. end
  109. end
  110. context 'when status is private' do
  111. let(:parent_visibility) { :private }
  112. it 'returns http not found' do
  113. expect(response).to have_http_status(404)
  114. end
  115. end
  116. context 'when status is direct' do
  117. let(:parent_visibility) { :direct }
  118. it 'returns http not found' do
  119. expect(response).to have_http_status(404)
  120. end
  121. end
  122. end
  123. context 'when signed request account is blocked' do
  124. before do
  125. status.account.block!(remote_account)
  126. get :index, params: { account_username: status.account.username, status_id: status.id }
  127. end
  128. context 'when status is public' do
  129. let(:parent_visibility) { :public }
  130. it 'returns http not found' do
  131. expect(response).to have_http_status(404)
  132. end
  133. end
  134. context 'when status is private' do
  135. let(:parent_visibility) { :private }
  136. it 'returns http not found' do
  137. expect(response).to have_http_status(404)
  138. end
  139. end
  140. context 'when status is direct' do
  141. let(:parent_visibility) { :direct }
  142. it 'returns http not found' do
  143. expect(response).to have_http_status(404)
  144. end
  145. end
  146. end
  147. context 'when signed request account is domain blocked' do
  148. before do
  149. status.account.block_domain!(remote_account.domain)
  150. get :index, params: { account_username: status.account.username, status_id: status.id }
  151. end
  152. context 'when status is public' do
  153. let(:parent_visibility) { :public }
  154. it 'returns http not found' do
  155. expect(response).to have_http_status(404)
  156. end
  157. end
  158. context 'when status is private' do
  159. let(:parent_visibility) { :private }
  160. it 'returns http not found' do
  161. expect(response).to have_http_status(404)
  162. end
  163. end
  164. context 'when status is direct' do
  165. let(:parent_visibility) { :direct }
  166. it 'returns http not found' do
  167. expect(response).to have_http_status(404)
  168. end
  169. end
  170. end
  171. end
  172. end
  173. end