0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-08 14:34:02 +08:00
discourse/plugins/discourse-rewind/spec/services/fetch_reports_spec.rb
Martin Brennan 9ae904b3ee
FIX: Only actually fetch initial report count in Rewind (#36940)
We changed rewind to fetch reports in batches, fetching only 3 to start
with, and then fetching more as needed. However, we were actually
fetching all reports server side then cutting down the results to only
3, which meant we were incurring unnecessary load on the server in the
case where reports were not cached, leading to 502 errors in some cases.

This fix also necessitates changing the caching strategy. Previously, we
would cache all of the reports at
once then when fetching an individual report we would pull from there.
However now that we aren't fetching
all reports at once, we need to cache individual reports and fetch them
if they are not cached.
2026-01-05 09:34:26 +10:00

155 lines
5 KiB
Ruby
Vendored

# frozen_string_literal: true
RSpec.describe(DiscourseRewind::FetchReports) do
describe ".call" do
subject(:result) { described_class.call(**dependencies) }
fab!(:current_user, :user)
let(:guardian) { Guardian.new(current_user) }
let(:dependencies) { { guardian: } }
before { SiteSetting.discourse_rewind_enabled = true }
context "when in january" do
before { freeze_time DateTime.parse("2021-01-22") }
it "computes the correct previous year" do
expect(result.year).to eq(2020)
end
end
context "when in december" do
before { freeze_time DateTime.parse("2021-12-22") }
it "computes the correct previous year" do
expect(result.year).to eq(2021)
end
end
context "when out of valid months december" do
before { freeze_time DateTime.parse("2021-02-22") }
it { is_expected.to fail_to_find_a_model(:year) }
end
context "in development mode" do
before do
Rails.env.stubs(:development?).returns(true)
freeze_time DateTime.parse("2021-06-22")
end
it "finds the year no matter what month" do
expect(result.year).to eq(2021)
end
end
context "when reports are cached" do
before { freeze_time DateTime.parse("2021-12-22") }
it "returns the cached reports" do
initial_count = result.reports.length
expect(initial_count).to eq(DiscourseRewind::FetchReports::INITIAL_REPORT_COUNT)
allow(DiscourseRewind::Action::TopWords).to receive(:call)
expect(result.reports.length).to eq(initial_count)
expect(DiscourseRewind::Action::TopWords).to_not have_received(:call)
end
end
context "when reports are not cached" do
before { freeze_time DateTime.parse("2021-01-22") }
it "returns the reports" do
expect(result.reports.length).to eq(DiscourseRewind::FetchReports::INITIAL_REPORT_COUNT)
end
it "only actually calls the first INITIAL_REPORT_COUNT reports" do
DiscourseRewind::Action::TopWords.expects(:call).once
DiscourseRewind::Action::ReadingTime.expects(:call).once
DiscourseRewind::Action::WritingAnalysis.expects(:call).once
DiscourseRewind::Action::Reactions.expects(:call).never
result
end
end
context "when checking total_available" do
before { freeze_time DateTime.parse("2021-12-22") }
it "returns the total number of available reports" do
expect(result.total_available).to eq(DiscourseRewind::FetchReports::REPORTS.size)
expect(result.total_available).to be > result.reports.length
end
end
context "with for_user_username parameter" do
fab!(:other_user, :user)
fab!(:admin, :admin)
before { freeze_time DateTime.parse("2021-12-22") }
context "when for_user_username is blank" do
let(:dependencies) { { guardian:, params: { for_user_username: "" } } }
it "uses the guardian user" do
expect(result).to be_success
expect(result.for_user).to eq(current_user)
end
end
context "when for_user_username is provided but user does not exist" do
let(:dependencies) { { guardian:, params: { for_user_username: "nonexistent" } } }
it { is_expected.to fail_to_find_a_model(:for_user) }
end
context "when viewing own rewind" do
let(:dependencies) { { guardian:, params: { for_user_username: current_user.username } } }
it "returns the user's reports" do
expect(result).to be_success
expect(result.for_user).to eq(current_user)
end
end
context "when viewing another user's rewind" do
context "when the other user has sharing enabled" do
before { other_user.user_option.update!(discourse_rewind_share_publicly: true) }
let(:dependencies) { { guardian:, params: { for_user_username: other_user.username } } }
it "allows access to the reports" do
expect(result).to be_success
expect(result.for_user).to eq(other_user)
end
context "when the other user has hide_profile enabled" do
before { other_user.user_option.update!(hide_profile: true) }
it { is_expected.to fail_to_find_a_model(:for_user) }
end
end
context "when the other user has sharing disabled" do
before { other_user.user_option.update!(discourse_rewind_share_publicly: false) }
context "when guardian is an admin" do
let(:guardian) { Guardian.new(admin) }
let(:dependencies) { { guardian:, params: { for_user_username: other_user.username } } }
it "allows access to the reports" do
expect(result).to be_success
expect(result.for_user).to eq(other_user)
end
end
context "when guardian is not an admin" do
let(:dependencies) { { guardian:, params: { for_user_username: other_user.username } } }
it { is_expected.to fail_to_find_a_model(:for_user) }
end
end
end
end
end
end