account_interactions_spec.rb 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724
  1. require 'rails_helper'
  2. describe AccountInteractions do
  3. let(:account) { Fabricate(:account, username: 'account') }
  4. let(:account_id) { account.id }
  5. let(:account_ids) { [account_id] }
  6. let(:target_account) { Fabricate(:account, username: 'target') }
  7. let(:target_account_id) { target_account.id }
  8. let(:target_account_ids) { [target_account_id] }
  9. describe '.following_map' do
  10. subject { Account.following_map(target_account_ids, account_id) }
  11. context 'account with Follow' do
  12. it 'returns { target_account_id => true }' do
  13. Fabricate(:follow, account: account, target_account: target_account)
  14. is_expected.to eq(target_account_id => { reblogs: true, notify: false, languages: nil })
  15. end
  16. end
  17. context 'account without Follow' do
  18. it 'returns {}' do
  19. is_expected.to eq({})
  20. end
  21. end
  22. end
  23. describe '.followed_by_map' do
  24. subject { Account.followed_by_map(target_account_ids, account_id) }
  25. context 'account with Follow' do
  26. it 'returns { target_account_id => true }' do
  27. Fabricate(:follow, account: target_account, target_account: account)
  28. is_expected.to eq(target_account_id => true)
  29. end
  30. end
  31. context 'account without Follow' do
  32. it 'returns {}' do
  33. is_expected.to eq({})
  34. end
  35. end
  36. end
  37. describe '.blocking_map' do
  38. subject { Account.blocking_map(target_account_ids, account_id) }
  39. context 'account with Block' do
  40. it 'returns { target_account_id => true }' do
  41. Fabricate(:block, account: account, target_account: target_account)
  42. is_expected.to eq(target_account_id => true)
  43. end
  44. end
  45. context 'account without Block' do
  46. it 'returns {}' do
  47. is_expected.to eq({})
  48. end
  49. end
  50. end
  51. describe '.muting_map' do
  52. subject { Account.muting_map(target_account_ids, account_id) }
  53. context 'account with Mute' do
  54. before do
  55. Fabricate(:mute, target_account: target_account, account: account, hide_notifications: hide)
  56. end
  57. context 'if Mute#hide_notifications?' do
  58. let(:hide) { true }
  59. it 'returns { target_account_id => { notifications: true } }' do
  60. is_expected.to eq(target_account_id => { notifications: true })
  61. end
  62. end
  63. context 'unless Mute#hide_notifications?' do
  64. let(:hide) { false }
  65. it 'returns { target_account_id => { notifications: false } }' do
  66. is_expected.to eq(target_account_id => { notifications: false })
  67. end
  68. end
  69. end
  70. context 'account without Mute' do
  71. it 'returns {}' do
  72. is_expected.to eq({})
  73. end
  74. end
  75. end
  76. describe '#follow!' do
  77. it 'creates and returns Follow' do
  78. expect do
  79. expect(account.follow!(target_account)).to be_kind_of Follow
  80. end.to change { account.following.count }.by 1
  81. end
  82. end
  83. describe '#block' do
  84. it 'creates and returns Block' do
  85. expect do
  86. expect(account.block!(target_account)).to be_kind_of Block
  87. end.to change { account.block_relationships.count }.by 1
  88. end
  89. end
  90. describe '#mute!' do
  91. subject { account.mute!(target_account, notifications: arg_notifications) }
  92. context 'Mute does not exist yet' do
  93. context 'arg :notifications is nil' do
  94. let(:arg_notifications) { nil }
  95. it 'creates Mute, and returns Mute' do
  96. expect do
  97. expect(subject).to be_kind_of Mute
  98. end.to change { account.mute_relationships.count }.by 1
  99. end
  100. end
  101. context 'arg :notifications is false' do
  102. let(:arg_notifications) { false }
  103. it 'creates Mute, and returns Mute' do
  104. expect do
  105. expect(subject).to be_kind_of Mute
  106. end.to change { account.mute_relationships.count }.by 1
  107. end
  108. end
  109. context 'arg :notifications is true' do
  110. let(:arg_notifications) { true }
  111. it 'creates Mute, and returns Mute' do
  112. expect do
  113. expect(subject).to be_kind_of Mute
  114. end.to change { account.mute_relationships.count }.by 1
  115. end
  116. end
  117. end
  118. context 'Mute already exists' do
  119. before do
  120. account.mute_relationships << mute
  121. end
  122. let(:mute) do
  123. Fabricate(:mute,
  124. account: account,
  125. target_account: target_account,
  126. hide_notifications: hide_notifications)
  127. end
  128. context 'mute.hide_notifications is true' do
  129. let(:hide_notifications) { true }
  130. context 'arg :notifications is nil' do
  131. let(:arg_notifications) { nil }
  132. it 'returns Mute without updating mute.hide_notifications' do
  133. expect do
  134. expect(subject).to be_kind_of Mute
  135. end.not_to change { mute.reload.hide_notifications? }.from(true)
  136. end
  137. end
  138. context 'arg :notifications is false' do
  139. let(:arg_notifications) { false }
  140. it 'returns Mute, and updates mute.hide_notifications false' do
  141. expect do
  142. expect(subject).to be_kind_of Mute
  143. end.to change { mute.reload.hide_notifications? }.from(true).to(false)
  144. end
  145. end
  146. context 'arg :notifications is true' do
  147. let(:arg_notifications) { true }
  148. it 'returns Mute without updating mute.hide_notifications' do
  149. expect do
  150. expect(subject).to be_kind_of Mute
  151. end.not_to change { mute.reload.hide_notifications? }.from(true)
  152. end
  153. end
  154. end
  155. context 'mute.hide_notifications is false' do
  156. let(:hide_notifications) { false }
  157. context 'arg :notifications is nil' do
  158. let(:arg_notifications) { nil }
  159. it 'returns Mute, and updates mute.hide_notifications true' do
  160. expect do
  161. expect(subject).to be_kind_of Mute
  162. end.to change { mute.reload.hide_notifications? }.from(false).to(true)
  163. end
  164. end
  165. context 'arg :notifications is false' do
  166. let(:arg_notifications) { false }
  167. it 'returns Mute without updating mute.hide_notifications' do
  168. expect do
  169. expect(subject).to be_kind_of Mute
  170. end.not_to change { mute.reload.hide_notifications? }.from(false)
  171. end
  172. end
  173. context 'arg :notifications is true' do
  174. let(:arg_notifications) { true }
  175. it 'returns Mute, and updates mute.hide_notifications true' do
  176. expect do
  177. expect(subject).to be_kind_of Mute
  178. end.to change { mute.reload.hide_notifications? }.from(false).to(true)
  179. end
  180. end
  181. end
  182. end
  183. end
  184. describe '#mute_conversation!' do
  185. let(:conversation) { Fabricate(:conversation) }
  186. subject { account.mute_conversation!(conversation) }
  187. it 'creates and returns ConversationMute' do
  188. expect do
  189. is_expected.to be_kind_of ConversationMute
  190. end.to change { account.conversation_mutes.count }.by 1
  191. end
  192. end
  193. describe '#block_domain!' do
  194. let(:domain) { 'example.com' }
  195. subject { account.block_domain!(domain) }
  196. it 'creates and returns AccountDomainBlock' do
  197. expect do
  198. is_expected.to be_kind_of AccountDomainBlock
  199. end.to change { account.domain_blocks.count }.by 1
  200. end
  201. end
  202. describe '#block_idna_domain!' do
  203. subject do
  204. [
  205. account.block_domain!(idna_domain),
  206. account.block_domain!(punycode_domain),
  207. ]
  208. end
  209. let(:idna_domain) { '대한민국.한국' }
  210. let(:punycode_domain) { 'xn--3e0bs9hfvinn1a.xn--3e0b707e' }
  211. it 'creates single AccountDomainBlock' do
  212. expect do
  213. expect(subject).to all(be_a AccountDomainBlock)
  214. end.to change { account.domain_blocks.count }.by 1
  215. end
  216. end
  217. describe '#unfollow!' do
  218. subject { account.unfollow!(target_account) }
  219. context 'following target_account' do
  220. it 'returns destroyed Follow' do
  221. account.active_relationships.create(target_account: target_account)
  222. is_expected.to be_kind_of Follow
  223. expect(subject).to be_destroyed
  224. end
  225. end
  226. context 'not following target_account' do
  227. it 'returns nil' do
  228. is_expected.to be_nil
  229. end
  230. end
  231. end
  232. describe '#unblock!' do
  233. subject { account.unblock!(target_account) }
  234. context 'blocking target_account' do
  235. it 'returns destroyed Block' do
  236. account.block_relationships.create(target_account: target_account)
  237. is_expected.to be_kind_of Block
  238. expect(subject).to be_destroyed
  239. end
  240. end
  241. context 'not blocking target_account' do
  242. it 'returns nil' do
  243. is_expected.to be_nil
  244. end
  245. end
  246. end
  247. describe '#unmute!' do
  248. subject { account.unmute!(target_account) }
  249. context 'muting target_account' do
  250. it 'returns destroyed Mute' do
  251. account.mute_relationships.create(target_account: target_account)
  252. is_expected.to be_kind_of Mute
  253. expect(subject).to be_destroyed
  254. end
  255. end
  256. context 'not muting target_account' do
  257. it 'returns nil' do
  258. is_expected.to be_nil
  259. end
  260. end
  261. end
  262. describe '#unmute_conversation!' do
  263. let(:conversation) { Fabricate(:conversation) }
  264. subject { account.unmute_conversation!(conversation) }
  265. context 'muting the conversation' do
  266. it 'returns destroyed ConversationMute' do
  267. account.conversation_mutes.create(conversation: conversation)
  268. is_expected.to be_kind_of ConversationMute
  269. expect(subject).to be_destroyed
  270. end
  271. end
  272. context 'not muting the conversation' do
  273. it 'returns nil' do
  274. is_expected.to be nil
  275. end
  276. end
  277. end
  278. describe '#unblock_domain!' do
  279. let(:domain) { 'example.com' }
  280. subject { account.unblock_domain!(domain) }
  281. context 'blocking the domain' do
  282. it 'returns destroyed AccountDomainBlock' do
  283. account_domain_block = Fabricate(:account_domain_block, domain: domain)
  284. account.domain_blocks << account_domain_block
  285. is_expected.to be_kind_of AccountDomainBlock
  286. expect(subject).to be_destroyed
  287. end
  288. end
  289. context 'unblocking the domain' do
  290. it 'returns nil' do
  291. is_expected.to be_nil
  292. end
  293. end
  294. end
  295. describe '#unblock_idna_domain!' do
  296. subject { account.unblock_domain!(punycode_domain) }
  297. let(:idna_domain) { '대한민국.한국' }
  298. let(:punycode_domain) { 'xn--3e0bs9hfvinn1a.xn--3e0b707e' }
  299. context 'when blocking the domain' do
  300. it 'returns destroyed AccountDomainBlock' do
  301. account_domain_block = Fabricate(:account_domain_block, domain: idna_domain)
  302. account.domain_blocks << account_domain_block
  303. expect(subject).to be_a AccountDomainBlock
  304. expect(subject).to be_destroyed
  305. end
  306. end
  307. context 'when unblocking idna domain' do
  308. it 'returns nil' do
  309. expect(subject).to be_nil
  310. end
  311. end
  312. end
  313. describe '#following?' do
  314. subject { account.following?(target_account) }
  315. context 'following target_account' do
  316. it 'returns true' do
  317. account.active_relationships.create(target_account: target_account)
  318. is_expected.to be true
  319. end
  320. end
  321. context 'not following target_account' do
  322. it 'returns false' do
  323. is_expected.to be false
  324. end
  325. end
  326. end
  327. describe '#followed_by?' do
  328. subject { account.followed_by?(target_account) }
  329. context 'followed by target_account' do
  330. it 'returns true' do
  331. account.passive_relationships.create(account: target_account)
  332. is_expected.to be true
  333. end
  334. end
  335. context 'not followed by target_account' do
  336. it 'returns false' do
  337. is_expected.to be false
  338. end
  339. end
  340. end
  341. describe '#blocking?' do
  342. subject { account.blocking?(target_account) }
  343. context 'blocking target_account' do
  344. it 'returns true' do
  345. account.block_relationships.create(target_account: target_account)
  346. is_expected.to be true
  347. end
  348. end
  349. context 'not blocking target_account' do
  350. it 'returns false' do
  351. is_expected.to be false
  352. end
  353. end
  354. end
  355. describe '#domain_blocking?' do
  356. let(:domain) { 'example.com' }
  357. subject { account.domain_blocking?(domain) }
  358. context 'blocking the domain' do
  359. it' returns true' do
  360. account_domain_block = Fabricate(:account_domain_block, domain: domain)
  361. account.domain_blocks << account_domain_block
  362. is_expected.to be true
  363. end
  364. end
  365. context 'not blocking the domain' do
  366. it 'returns false' do
  367. is_expected.to be false
  368. end
  369. end
  370. end
  371. describe '#muting?' do
  372. subject { account.muting?(target_account) }
  373. context 'muting target_account' do
  374. it 'returns true' do
  375. mute = Fabricate(:mute, account: account, target_account: target_account)
  376. account.mute_relationships << mute
  377. is_expected.to be true
  378. end
  379. end
  380. context 'not muting target_account' do
  381. it 'returns false' do
  382. is_expected.to be false
  383. end
  384. end
  385. end
  386. describe '#muting_conversation?' do
  387. let(:conversation) { Fabricate(:conversation) }
  388. subject { account.muting_conversation?(conversation) }
  389. context 'muting the conversation' do
  390. it 'returns true' do
  391. account.conversation_mutes.create(conversation: conversation)
  392. is_expected.to be true
  393. end
  394. end
  395. context 'not muting the conversation' do
  396. it 'returns false' do
  397. is_expected.to be false
  398. end
  399. end
  400. end
  401. describe '#muting_notifications?' do
  402. before do
  403. mute = Fabricate(:mute, target_account: target_account, account: account, hide_notifications: hide)
  404. account.mute_relationships << mute
  405. end
  406. subject { account.muting_notifications?(target_account) }
  407. context 'muting notifications of target_account' do
  408. let(:hide) { true }
  409. it 'returns true' do
  410. is_expected.to be true
  411. end
  412. end
  413. context 'not muting notifications of target_account' do
  414. let(:hide) { false }
  415. it 'returns false' do
  416. is_expected.to be false
  417. end
  418. end
  419. end
  420. describe '#requested?' do
  421. subject { account.requested?(target_account) }
  422. context 'requested by target_account' do
  423. it 'returns true' do
  424. Fabricate(:follow_request, account: account, target_account: target_account)
  425. is_expected.to be true
  426. end
  427. end
  428. context 'not requested by target_account' do
  429. it 'returns false' do
  430. is_expected.to be false
  431. end
  432. end
  433. end
  434. describe '#favourited?' do
  435. let(:status) { Fabricate(:status, account: account, favourites: favourites) }
  436. subject { account.favourited?(status) }
  437. context 'favorited' do
  438. let(:favourites) { [Fabricate(:favourite, account: account)] }
  439. it 'returns true' do
  440. is_expected.to be true
  441. end
  442. end
  443. context 'not favorited' do
  444. let(:favourites) { [] }
  445. it 'returns false' do
  446. is_expected.to be false
  447. end
  448. end
  449. end
  450. describe '#reblogged?' do
  451. let(:status) { Fabricate(:status, account: account, reblogs: reblogs) }
  452. subject { account.reblogged?(status) }
  453. context 'reblogged' do
  454. let(:reblogs) { [Fabricate(:status, account: account)] }
  455. it 'returns true' do
  456. is_expected.to be true
  457. end
  458. end
  459. context 'not reblogged' do
  460. let(:reblogs) { [] }
  461. it 'returns false' do
  462. is_expected.to be false
  463. end
  464. end
  465. end
  466. describe '#pinned?' do
  467. let(:status) { Fabricate(:status, account: account) }
  468. subject { account.pinned?(status) }
  469. context 'pinned' do
  470. it 'returns true' do
  471. Fabricate(:status_pin, account: account, status: status)
  472. is_expected.to be true
  473. end
  474. end
  475. context 'not pinned' do
  476. it 'returns false' do
  477. is_expected.to be false
  478. end
  479. end
  480. end
  481. describe '#remote_followers_hash' do
  482. let(:me) { Fabricate(:account, username: 'Me') }
  483. let(:remote_1) { Fabricate(:account, username: 'alice', domain: 'example.org', uri: 'https://example.org/users/alice') }
  484. let(:remote_2) { Fabricate(:account, username: 'bob', domain: 'example.org', uri: 'https://example.org/users/bob') }
  485. let(:remote_3) { Fabricate(:account, username: 'instance-actor', domain: 'example.org', uri: 'https://example.org') }
  486. let(:remote_4) { Fabricate(:account, username: 'eve', domain: 'foo.org', uri: 'https://foo.org/users/eve') }
  487. before do
  488. remote_1.follow!(me)
  489. remote_2.follow!(me)
  490. remote_3.follow!(me)
  491. remote_4.follow!(me)
  492. me.follow!(remote_1)
  493. end
  494. it 'returns correct hash for remote domains' do
  495. expect(me.remote_followers_hash('https://example.org/')).to eq '20aecbe774b3d61c25094370baf370012b9271c5b172ecedb05caff8d79ef0c7'
  496. expect(me.remote_followers_hash('https://foo.org/')).to eq 'ccb9c18a67134cfff9d62c7f7e7eb88e6b803446c244b84265565f4eba29df0e'
  497. expect(me.remote_followers_hash('https://foo.org.evil.com/')).to eq '0000000000000000000000000000000000000000000000000000000000000000'
  498. expect(me.remote_followers_hash('https://foo')).to eq '0000000000000000000000000000000000000000000000000000000000000000'
  499. end
  500. it 'invalidates cache as needed when removing or adding followers' do
  501. expect(me.remote_followers_hash('https://example.org/')).to eq '20aecbe774b3d61c25094370baf370012b9271c5b172ecedb05caff8d79ef0c7'
  502. remote_3.unfollow!(me)
  503. expect(me.remote_followers_hash('https://example.org/')).to eq '707962e297b7bd94468a21bc8e506a1bcea607a9142cd64e27c9b106b2a5f6ec'
  504. remote_1.unfollow!(me)
  505. expect(me.remote_followers_hash('https://example.org/')).to eq '241b00794ce9b46aa864f3220afadef128318da2659782985bac5ed5bd436bff'
  506. remote_1.follow!(me)
  507. expect(me.remote_followers_hash('https://example.org/')).to eq '707962e297b7bd94468a21bc8e506a1bcea607a9142cd64e27c9b106b2a5f6ec'
  508. end
  509. end
  510. describe '#local_followers_hash' do
  511. let(:me) { Fabricate(:account, username: 'Me') }
  512. let(:remote_1) { Fabricate(:account, username: 'alice', domain: 'example.org', uri: 'https://example.org/users/alice') }
  513. before do
  514. me.follow!(remote_1)
  515. end
  516. it 'returns correct hash for local users' do
  517. expect(remote_1.local_followers_hash).to eq Digest::SHA256.hexdigest(ActivityPub::TagManager.instance.uri_for(me))
  518. end
  519. it 'invalidates cache as needed when removing or adding followers' do
  520. expect(remote_1.local_followers_hash).to eq Digest::SHA256.hexdigest(ActivityPub::TagManager.instance.uri_for(me))
  521. me.unfollow!(remote_1)
  522. expect(remote_1.local_followers_hash).to eq '0000000000000000000000000000000000000000000000000000000000000000'
  523. me.follow!(remote_1)
  524. expect(remote_1.local_followers_hash).to eq Digest::SHA256.hexdigest(ActivityPub::TagManager.instance.uri_for(me))
  525. end
  526. end
  527. describe 'muting an account' do
  528. let(:me) { Fabricate(:account, username: 'Me') }
  529. let(:you) { Fabricate(:account, username: 'You') }
  530. context 'with the notifications option unspecified' do
  531. before do
  532. me.mute!(you)
  533. end
  534. it 'defaults to muting notifications' do
  535. expect(me.muting_notifications?(you)).to be true
  536. end
  537. end
  538. context 'with the notifications option set to false' do
  539. before do
  540. me.mute!(you, notifications: false)
  541. end
  542. it 'does not mute notifications' do
  543. expect(me.muting_notifications?(you)).to be false
  544. end
  545. end
  546. context 'with the notifications option set to true' do
  547. before do
  548. me.mute!(you, notifications: true)
  549. end
  550. it 'does mute notifications' do
  551. expect(me.muting_notifications?(you)).to be true
  552. end
  553. end
  554. end
  555. describe 'ignoring reblogs from an account' do
  556. before do
  557. @me = Fabricate(:account, username: 'Me')
  558. @you = Fabricate(:account, username: 'You')
  559. end
  560. context 'with the reblogs option unspecified' do
  561. before do
  562. @me.follow!(@you)
  563. end
  564. it 'defaults to showing reblogs' do
  565. expect(@me.muting_reblogs?(@you)).to be(false)
  566. end
  567. end
  568. context 'with the reblogs option set to false' do
  569. before do
  570. @me.follow!(@you, reblogs: false)
  571. end
  572. it 'does mute reblogs' do
  573. expect(@me.muting_reblogs?(@you)).to be(true)
  574. end
  575. end
  576. context 'with the reblogs option set to true' do
  577. before do
  578. @me.follow!(@you, reblogs: true)
  579. end
  580. it 'does not mute reblogs' do
  581. expect(@me.muting_reblogs?(@you)).to be(false)
  582. end
  583. end
  584. end
  585. end