notify_service_spec.rb 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. # frozen_string_literal: true
  2. require 'rails_helper'
  3. RSpec.describe NotifyService do
  4. subject { described_class.new.call(recipient, type, activity) }
  5. let(:user) { Fabricate(:user) }
  6. let(:recipient) { user.account }
  7. let(:sender) { Fabricate(:account, domain: 'example.com') }
  8. let(:activity) { Fabricate(:follow, account: sender, target_account: recipient) }
  9. let(:type) { :follow }
  10. it { expect { subject }.to change(Notification, :count).by(1) }
  11. it 'does not notify when sender is blocked' do
  12. recipient.block!(sender)
  13. expect { subject }.to_not change(Notification, :count)
  14. end
  15. it 'does not notify when sender is muted with hide_notifications' do
  16. recipient.mute!(sender, notifications: true)
  17. expect { subject }.to_not change(Notification, :count)
  18. end
  19. it 'does notify when sender is muted without hide_notifications' do
  20. recipient.mute!(sender, notifications: false)
  21. expect { subject }.to change(Notification, :count)
  22. end
  23. it 'does not notify when sender\'s domain is blocked' do
  24. recipient.block_domain!(sender.domain)
  25. expect { subject }.to_not change(Notification, :count)
  26. end
  27. it 'does still notify when sender\'s domain is blocked but sender is followed' do
  28. recipient.block_domain!(sender.domain)
  29. recipient.follow!(sender)
  30. expect { subject }.to change(Notification, :count)
  31. end
  32. it 'does not notify when sender is silenced and not followed' do
  33. sender.silence!
  34. subject
  35. expect(Notification.find_by(activity: activity).filtered?).to be true
  36. end
  37. it 'does not notify when recipient is suspended' do
  38. recipient.suspend!
  39. expect { subject }.to_not change(Notification, :count)
  40. end
  41. describe 'reblogs' do
  42. let(:status) { Fabricate(:status, account: Fabricate(:account)) }
  43. let(:activity) { Fabricate(:status, account: sender, reblog: status) }
  44. let(:type) { :reblog }
  45. it 'shows reblogs by default' do
  46. recipient.follow!(sender)
  47. expect { subject }.to change(Notification, :count)
  48. end
  49. it 'shows reblogs when explicitly enabled' do
  50. recipient.follow!(sender, reblogs: true)
  51. expect { subject }.to change(Notification, :count)
  52. end
  53. it 'shows reblogs when disabled' do
  54. recipient.follow!(sender, reblogs: false)
  55. expect { subject }.to change(Notification, :count)
  56. end
  57. end
  58. context 'with muted and blocked users' do
  59. let(:asshole) { Fabricate(:account, username: 'asshole') }
  60. let(:reply_to) { Fabricate(:status, account: asshole) }
  61. let(:activity) { Fabricate(:mention, account: recipient, status: Fabricate(:status, account: sender, thread: reply_to)) }
  62. let(:type) { :mention }
  63. it 'does not notify when conversation is muted' do
  64. recipient.mute_conversation!(activity.status.conversation)
  65. expect { subject }.to_not change(Notification, :count)
  66. end
  67. it 'does not notify when it is a reply to a blocked user' do
  68. recipient.block!(asshole)
  69. expect { subject }.to_not change(Notification, :count)
  70. end
  71. end
  72. context 'with sender as recipient' do
  73. let(:sender) { recipient }
  74. it 'does not notify when recipient is the sender' do
  75. expect { subject }.to_not change(Notification, :count)
  76. end
  77. end
  78. describe 'email' do
  79. before do
  80. user.settings.update('notification_emails.follow': enabled)
  81. user.save
  82. end
  83. context 'when email notification is enabled' do
  84. let(:enabled) { true }
  85. it 'sends email', :inline_jobs do
  86. emails = capture_emails { subject }
  87. expect(emails.size)
  88. .to eq(1)
  89. expect(emails.first)
  90. .to have_attributes(
  91. to: contain_exactly(user.email),
  92. subject: eq(I18n.t('notification_mailer.follow.subject', name: sender.acct))
  93. )
  94. end
  95. end
  96. context 'when email notification is disabled' do
  97. let(:enabled) { false }
  98. it "doesn't send email" do
  99. emails = capture_emails { subject }
  100. expect(emails).to be_empty
  101. end
  102. end
  103. end
  104. context 'when the blocked sender has a role' do
  105. let(:sender) { Fabricate(:user, role: sender_role).account }
  106. let(:activity) { Fabricate(:mention, status: Fabricate(:status, account: sender)) }
  107. let(:type) { :mention }
  108. before do
  109. recipient.block!(sender)
  110. end
  111. context 'when the role is a visible moderator' do
  112. let(:sender_role) { Fabricate(:user_role, highlighted: true, permissions: UserRole::FLAGS[:manage_users]) }
  113. it 'does notify' do
  114. expect { subject }.to change(Notification, :count)
  115. end
  116. end
  117. context 'when the role is a non-visible moderator' do
  118. let(:sender_role) { Fabricate(:user_role, highlighted: false, permissions: UserRole::FLAGS[:manage_users]) }
  119. it 'does not notify' do
  120. expect { subject }.to_not change(Notification, :count)
  121. end
  122. end
  123. context 'when the role is a visible non-moderator' do
  124. let(:sender_role) { Fabricate(:user_role, highlighted: true) }
  125. it 'does not notify' do
  126. expect { subject }.to_not change(Notification, :count)
  127. end
  128. end
  129. end
  130. context 'with filtered notifications' do
  131. let(:unknown) { Fabricate(:account, username: 'unknown') }
  132. let(:status) { Fabricate(:status, account: unknown) }
  133. let(:activity) { Fabricate(:mention, account: recipient, status: status) }
  134. let(:type) { :mention }
  135. before do
  136. Fabricate(:notification_policy, account: recipient, filter_not_following: true)
  137. end
  138. it 'creates a filtered notification' do
  139. expect { subject }.to change(Notification, :count)
  140. expect(Notification.last).to be_filtered
  141. end
  142. context 'when no notification request exists' do
  143. it 'creates a notification request' do
  144. expect { subject }.to change(NotificationRequest, :count)
  145. end
  146. end
  147. context 'when a notification request exists' do
  148. let!(:notification_request) do
  149. Fabricate(:notification_request, account: recipient, from_account: unknown, last_status: Fabricate(:status, account: unknown))
  150. end
  151. it 'updates the existing notification request' do
  152. expect { subject }.to_not change(NotificationRequest, :count)
  153. expect(notification_request.reload.last_status).to eq status
  154. end
  155. end
  156. end
  157. describe NotifyService::DropCondition do
  158. subject { described_class.new(notification) }
  159. let(:activity) { Fabricate(:mention, status: Fabricate(:status)) }
  160. let(:notification) { Fabricate(:notification, type: :mention, activity: activity, from_account: activity.status.account, account: activity.account) }
  161. describe '#drop' do
  162. context 'when sender is silenced and recipient has a default policy' do
  163. before do
  164. notification.from_account.silence!
  165. end
  166. it 'returns false' do
  167. expect(subject.drop?).to be false
  168. end
  169. end
  170. context 'when sender is silenced and recipient has a policy to ignore silenced accounts' do
  171. before do
  172. notification.from_account.silence!
  173. notification.account.create_notification_policy!(for_limited_accounts: :drop)
  174. end
  175. it 'returns true' do
  176. expect(subject.drop?).to be true
  177. end
  178. end
  179. context 'when sender is new and recipient has a default policy' do
  180. it 'returns false' do
  181. expect(subject.drop?).to be false
  182. end
  183. end
  184. context 'when sender is new and recipient has a policy to ignore silenced accounts' do
  185. before do
  186. notification.account.create_notification_policy!(for_new_accounts: :drop)
  187. end
  188. it 'returns true' do
  189. expect(subject.drop?).to be true
  190. end
  191. end
  192. context 'when sender is new and followed and recipient has a policy to ignore silenced accounts' do
  193. before do
  194. notification.account.create_notification_policy!(for_new_accounts: :drop)
  195. notification.account.follow!(notification.from_account)
  196. end
  197. it 'returns false' do
  198. expect(subject.drop?).to be false
  199. end
  200. end
  201. context 'when recipient has blocked sender' do
  202. before do
  203. notification.account.block!(notification.from_account)
  204. end
  205. it 'returns true' do
  206. expect(subject.drop?).to be true
  207. end
  208. end
  209. end
  210. end
  211. describe NotifyService::FilterCondition do
  212. subject { described_class.new(notification) }
  213. let(:activity) { Fabricate(:mention, status: Fabricate(:status)) }
  214. let(:notification) { Fabricate(:notification, type: :mention, activity: activity, from_account: activity.status.account, account: activity.account) }
  215. describe '#filter?' do
  216. context 'when sender is silenced' do
  217. before do
  218. notification.from_account.silence!
  219. end
  220. it 'returns true' do
  221. expect(subject.filter?).to be true
  222. end
  223. context 'when recipient follows sender' do
  224. before do
  225. notification.account.follow!(notification.from_account)
  226. end
  227. it 'returns false' do
  228. expect(subject.filter?).to be false
  229. end
  230. end
  231. context 'when recipient is allowing limited accounts' do
  232. before do
  233. notification.account.create_notification_policy!(for_limited_accounts: :accept)
  234. end
  235. it 'returns false' do
  236. expect(subject.filter?).to be false
  237. end
  238. end
  239. end
  240. context 'when recipient is filtering not-followed senders' do
  241. before do
  242. Fabricate(:notification_policy, account: notification.account, filter_not_following: true)
  243. end
  244. it 'returns true' do
  245. expect(subject.filter?).to be true
  246. end
  247. context 'when sender has permission' do
  248. before do
  249. Fabricate(:notification_permission, account: notification.account, from_account: notification.from_account)
  250. end
  251. it 'returns false' do
  252. expect(subject.filter?).to be false
  253. end
  254. end
  255. context 'when sender is followed by recipient' do
  256. before do
  257. notification.account.follow!(notification.from_account)
  258. end
  259. it 'returns false' do
  260. expect(subject.filter?).to be false
  261. end
  262. end
  263. end
  264. context 'when recipient is filtering not-followers' do
  265. before do
  266. Fabricate(:notification_policy, account: notification.account, filter_not_followers: true)
  267. end
  268. it 'returns true' do
  269. expect(subject.filter?).to be true
  270. end
  271. context 'when sender has permission' do
  272. before do
  273. Fabricate(:notification_permission, account: notification.account, from_account: notification.from_account)
  274. end
  275. it 'returns false' do
  276. expect(subject.filter?).to be false
  277. end
  278. end
  279. context 'when sender follows recipient' do
  280. before do
  281. notification.from_account.follow!(notification.account)
  282. end
  283. it 'returns true' do
  284. expect(subject.filter?).to be true
  285. end
  286. end
  287. context 'when sender follows recipient for longer than 3 days' do
  288. before do
  289. follow = notification.from_account.follow!(notification.account)
  290. follow.update(created_at: 4.days.ago)
  291. end
  292. it 'returns false' do
  293. expect(subject.filter?).to be false
  294. end
  295. end
  296. end
  297. context 'when recipient is filtering new accounts' do
  298. before do
  299. Fabricate(:notification_policy, account: notification.account, filter_new_accounts: true)
  300. end
  301. it 'returns true' do
  302. expect(subject.filter?).to be true
  303. end
  304. context 'when sender has permission' do
  305. before do
  306. Fabricate(:notification_permission, account: notification.account, from_account: notification.from_account)
  307. end
  308. it 'returns false' do
  309. expect(subject.filter?).to be false
  310. end
  311. end
  312. context 'when sender is older than 30 days' do
  313. before do
  314. notification.from_account.update(created_at: 31.days.ago)
  315. end
  316. it 'returns false' do
  317. expect(subject.filter?).to be false
  318. end
  319. end
  320. end
  321. context 'when recipient is not filtering anyone' do
  322. before do
  323. Fabricate(:notification_policy, account: notification.account)
  324. end
  325. it 'returns false' do
  326. expect(subject.filter?).to be false
  327. end
  328. end
  329. context 'when recipient is filtering unsolicited private mentions' do
  330. before do
  331. Fabricate(:notification_policy, account: notification.account, filter_private_mentions: true)
  332. end
  333. context 'when notification is not a private mention' do
  334. it 'returns false' do
  335. expect(subject.filter?).to be false
  336. end
  337. end
  338. context 'when notification is a private mention' do
  339. before do
  340. notification.target_status.update(visibility: :direct)
  341. end
  342. it 'returns true' do
  343. expect(subject.filter?).to be true
  344. end
  345. context 'when the message chain is initiated by recipient, but sender is not mentioned' do
  346. before do
  347. original_status = Fabricate(:status, account: notification.account, visibility: :direct)
  348. notification.target_status.update(thread: original_status)
  349. end
  350. it 'returns true' do
  351. expect(subject.filter?).to be true
  352. end
  353. end
  354. context 'when the message chain is initiated by recipient, and sender is mentioned' do
  355. before do
  356. original_status = Fabricate(:status, account: notification.account, visibility: :direct)
  357. notification.target_status.update(thread: original_status)
  358. Fabricate(:mention, status: original_status, account: notification.from_account)
  359. end
  360. it 'returns false' do
  361. expect(subject.filter?).to be false
  362. end
  363. end
  364. context 'when the sender is mentioned in an unrelated message chain' do
  365. before do
  366. original_status = Fabricate(:status, visibility: :direct)
  367. intermediary_status = Fabricate(:status, visibility: :direct, thread: original_status)
  368. notification.target_status.update(thread: intermediary_status)
  369. Fabricate(:mention, status: original_status, account: notification.from_account)
  370. end
  371. it 'returns true' do
  372. expect(subject.filter?).to be true
  373. end
  374. end
  375. end
  376. end
  377. end
  378. end
  379. end