report_service_spec.rb 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. # frozen_string_literal: true
  2. require 'rails_helper'
  3. RSpec.describe ReportService do
  4. subject { described_class.new }
  5. let(:source_account) { Fabricate(:account) }
  6. let(:target_account) { Fabricate(:account) }
  7. context 'with a local account' do
  8. it 'has a uri' do
  9. report = subject.call(source_account, target_account)
  10. expect(report.uri).to_not be_nil
  11. end
  12. end
  13. context 'with a remote account' do
  14. let(:remote_account) { Fabricate(:account, domain: 'example.com', protocol: :activitypub, inbox_url: 'http://example.com/inbox') }
  15. let(:forward) { false }
  16. before do
  17. stub_request(:post, 'http://example.com/inbox').to_return(status: 200)
  18. end
  19. it 'does not have an application' do
  20. report = subject.call(source_account, remote_account)
  21. expect(report.application).to be_nil
  22. end
  23. context 'when forward is true', :inline_jobs do
  24. let(:forward) { true }
  25. it 'has a URI and sends ActivityPub payload' do
  26. report = subject.call(source_account, remote_account, forward: forward)
  27. expect(report.uri)
  28. .to_not be_nil
  29. expect(a_request(:post, 'http://example.com/inbox'))
  30. .to have_been_made
  31. end
  32. context 'when reporting a reply on a different remote server' do
  33. let(:remote_thread_account) { Fabricate(:account, domain: 'foo.com', protocol: :activitypub, inbox_url: 'http://foo.com/inbox') }
  34. let(:reported_status) { Fabricate(:status, account: remote_account, thread: Fabricate(:status, account: remote_thread_account)) }
  35. before do
  36. stub_request(:post, 'http://foo.com/inbox').to_return(status: 200)
  37. end
  38. context 'when forward_to_domains includes both the replied-to domain and the origin domain' do
  39. it 'sends ActivityPub payload to both the author of the replied-to post and the reported user' do
  40. subject.call(source_account, remote_account, status_ids: [reported_status.id], forward: forward, forward_to_domains: [remote_account.domain, remote_thread_account.domain])
  41. expect(a_request(:post, 'http://foo.com/inbox')).to have_been_made
  42. expect(a_request(:post, 'http://example.com/inbox')).to have_been_made
  43. end
  44. end
  45. context 'when forward_to_domains includes only the replied-to domain' do
  46. it 'sends ActivityPub payload only to the author of the replied-to post' do
  47. subject.call(source_account, remote_account, status_ids: [reported_status.id], forward: forward, forward_to_domains: [remote_thread_account.domain])
  48. expect(a_request(:post, 'http://foo.com/inbox')).to have_been_made
  49. expect(a_request(:post, 'http://example.com/inbox')).to_not have_been_made
  50. end
  51. end
  52. context 'when forward_to_domains does not include the replied-to domain' do
  53. it 'does not send ActivityPub payload to the author of the replied-to post' do
  54. subject.call(source_account, remote_account, status_ids: [reported_status.id], forward: forward)
  55. expect(a_request(:post, 'http://foo.com/inbox')).to_not have_been_made
  56. end
  57. end
  58. end
  59. context 'when reporting a reply on the same remote server as the person being replied-to' do
  60. let(:remote_thread_account) { Fabricate(:account, domain: 'example.com', protocol: :activitypub, inbox_url: 'http://example.com/inbox') }
  61. let(:reported_status) { Fabricate(:status, account: remote_account, thread: Fabricate(:status, account: remote_thread_account)) }
  62. context 'when forward_to_domains includes both the replied-to domain and the origin domain' do
  63. it 'sends ActivityPub payload only once' do
  64. subject.call(source_account, remote_account, status_ids: [reported_status.id], forward: forward, forward_to_domains: [remote_account.domain])
  65. expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.once
  66. end
  67. end
  68. context 'when forward_to_domains does not include the replied-to domain' do
  69. it 'sends ActivityPub payload only once' do
  70. subject.call(source_account, remote_account, status_ids: [reported_status.id], forward: forward)
  71. expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.once
  72. end
  73. end
  74. end
  75. end
  76. context 'when forward is false' do
  77. it 'does not send anything' do
  78. subject.call(source_account, remote_account, forward: forward)
  79. expect(a_request(:post, 'http://example.com/inbox')).to_not have_been_made
  80. end
  81. end
  82. end
  83. context 'when passed an application' do
  84. let(:application) { Fabricate(:application) }
  85. it 'has an application' do
  86. report = subject.call(source_account, target_account, application: application)
  87. expect(report.application).to eq application
  88. end
  89. end
  90. context 'when the reported status is a DM' do
  91. subject do
  92. -> { described_class.new.call(source_account, target_account, status_ids: [status.id]) }
  93. end
  94. let(:status) { Fabricate(:status, account: target_account, visibility: :direct) }
  95. context 'when it is addressed to the reporter' do
  96. before do
  97. status.mentions.create(account: source_account)
  98. end
  99. it 'creates a report and attaches the DM to the report' do
  100. expect { subject.call }
  101. .to change { target_account.targeted_reports.count }.from(0).to(1)
  102. expect(target_account.targeted_reports.pluck(:status_ids))
  103. .to eq [[status.id]]
  104. end
  105. end
  106. context 'when it is not addressed to the reporter' do
  107. it 'errors out' do
  108. expect { subject.call }.to raise_error(ActiveRecord::RecordNotFound)
  109. end
  110. end
  111. context 'when the reporter is remote' do
  112. let(:source_account) { Fabricate(:account, domain: 'example.com', uri: 'https://example.com/users/1') }
  113. context 'when it is addressed to the reporter' do
  114. before do
  115. status.mentions.create(account: source_account)
  116. end
  117. it 'creates a report and attaches DM to report' do
  118. expect { subject.call }
  119. .to change { target_account.targeted_reports.count }.from(0).to(1)
  120. expect(target_account.targeted_reports.pluck(:status_ids))
  121. .to eq [[status.id]]
  122. end
  123. end
  124. context 'when it is not addressed to the reporter' do
  125. it 'does not add the DM to the report' do
  126. subject.call
  127. expect(target_account.targeted_reports.pluck(:status_ids)).to eq [[]]
  128. end
  129. end
  130. end
  131. end
  132. context 'when other reports already exist for the same target' do
  133. subject do
  134. -> { described_class.new.call(source_account, target_account) }
  135. end
  136. before do
  137. Fabricate(:report, target_account: target_account)
  138. source_account.user.settings['notification_emails.report'] = true
  139. source_account.user.save
  140. end
  141. it 'does not send an e-mail' do
  142. emails = capture_emails { subject.call }
  143. expect(emails).to be_empty
  144. end
  145. end
  146. end