statuses_spec.rb 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. # frozen_string_literal: true
  2. require 'rails_helper'
  3. RSpec.describe Trends::Statuses do
  4. subject! { described_class.new(threshold: 5, review_threshold: 10, score_halflife: 8.hours) }
  5. let!(:at_time) { DateTime.new(2021, 11, 14, 10, 15, 0) }
  6. describe 'Trends::Statuses::Query' do
  7. let!(:query) { subject.query }
  8. let!(:today) { at_time }
  9. let!(:status_foo) { Fabricate(:status, text: 'Foo', language: 'en', trendable: true, created_at: today) }
  10. let!(:status_bar) { Fabricate(:status, text: 'Bar', language: 'en', trendable: true, created_at: today) }
  11. before do
  12. default_threshold_value.times { reblog(status_foo, today) }
  13. default_threshold_value.times { reblog(status_bar, today) }
  14. subject.refresh(today)
  15. end
  16. describe '#filtered_for' do
  17. let(:account) { Fabricate(:account) }
  18. it 'returns a composable query scope' do
  19. expect(query.filtered_for(account)).to be_a Trends::Query
  20. end
  21. it 'filters out blocked accounts' do
  22. account.block!(status_foo.account)
  23. expect(query.filtered_for(account).to_a).to eq [status_bar]
  24. end
  25. it 'filters out muted accounts' do
  26. account.mute!(status_bar.account)
  27. expect(query.filtered_for(account).to_a).to eq [status_foo]
  28. end
  29. it 'filters out blocked-by accounts' do
  30. status_foo.account.block!(account)
  31. expect(query.filtered_for(account).to_a).to eq [status_bar]
  32. end
  33. end
  34. end
  35. describe '#add' do
  36. let(:status) { Fabricate(:status) }
  37. before do
  38. subject.add(status, 1, at_time)
  39. end
  40. it 'records use' do
  41. expect(subject.send(:recently_used_ids, at_time)).to eq [status.id]
  42. end
  43. end
  44. describe '#query' do
  45. it 'returns a composable query scope' do
  46. expect(subject.query).to be_a Trends::Query
  47. end
  48. it 'responds to filtered_for' do
  49. expect(subject.query).to respond_to(:filtered_for)
  50. end
  51. end
  52. describe '#refresh' do
  53. let!(:today) { at_time }
  54. let!(:yesterday) { today - 1.day }
  55. let!(:status_foo) { Fabricate(:status, text: 'Foo', language: 'en', trendable: true, created_at: yesterday) }
  56. let!(:status_bar) { Fabricate(:status, text: 'Bar', language: 'en', trendable: true, created_at: today) }
  57. let!(:status_baz) { Fabricate(:status, text: 'Baz', language: 'en', trendable: true, created_at: today) }
  58. before do
  59. default_threshold_value.times { reblog(status_foo, today) }
  60. default_threshold_value.times { reblog(status_bar, today) }
  61. (default_threshold_value - 1).times { reblog(status_baz, today) }
  62. end
  63. context 'when status trends are refreshed' do
  64. before do
  65. subject.refresh(today)
  66. end
  67. it 'returns correct statuses from query' do
  68. results = subject.query.limit(10).to_a
  69. expect(results).to eq [status_bar, status_foo]
  70. expect(results).to_not include(status_baz)
  71. end
  72. end
  73. it 'decays scores' do
  74. subject.refresh(today)
  75. original_score = status_bar.trend.score
  76. expect(original_score).to be_a Float
  77. subject.refresh(today + subject.options[:score_halflife])
  78. decayed_score = status_bar.trend.reload.score
  79. expect(decayed_score).to be <= original_score / 2
  80. end
  81. end
  82. def reblog(status, at_time)
  83. reblog = Fabricate(:status, reblog: status, created_at: at_time)
  84. subject.add(status, reblog.account_id, at_time)
  85. end
  86. def default_threshold_value
  87. described_class.default_options[:threshold]
  88. end
  89. end