discourse-ai/spec/lib/modules/summarization/entry_point_spec.rb

166 lines
5.5 KiB
Ruby

# frozen_string_literal: true
RSpec.describe DiscourseAi::Summarization::EntryPoint do
before do
assign_fake_provider_to(:ai_summarization_model)
SiteSetting.ai_summarization_enabled = true
SiteSetting.ai_summarize_max_hot_topics_gists_per_batch = 100
end
fab!(:user)
describe "#inject_into" do
describe "hot topics gist summarization" do
fab!(:topic_ai_gist)
before { TopicHotScore.create!(topic_id: topic_ai_gist.target_id, score: 1.0) }
let(:topic_query) { TopicQuery.new(user) }
describe "topic_query_create_list_topics modifier" do
context "when hot topic summarization is enabled" do
it "doesn't duplicate records when there more than one summary type" do
Fabricate(:ai_summary, target: topic_ai_gist.target)
expect(topic_query.list_hot.topics.map(&:id)).to contain_exactly(
topic_ai_gist.target_id,
)
end
it "doesn't exclude records when the topic has a single different summary" do
regular_summary_2 = Fabricate(:ai_summary)
TopicHotScore.create!(topic_id: regular_summary_2.target_id, score: 1.0)
expect(topic_query.list_hot.topics.map(&:id)).to contain_exactly(
regular_summary_2.target_id,
topic_ai_gist.target_id,
)
end
it "doesn't filter out hot topics without summaries" do
TopicHotScore.create!(topic_id: Fabricate(:topic).id, score: 1.0)
expect(topic_query.list_hot.topics.size).to eq(2)
end
end
end
describe "topic_list_item serializer's ai_summary" do
context "when hot topic summarization is disabled" do
it "doesn't include summaries" do
gist_topic = topic_query.list_hot.topics.find { |t| t.id == topic_ai_gist.target_id }
serialized =
TopicListItemSerializer.new(gist_topic, scope: Guardian.new, root: false).as_json
expect(serialized.has_key?(:ai_topic_gist)).to eq(false)
end
end
context "when hot topics summarization is enabled" do
fab!(:group)
before do
group.add(user)
SiteSetting.ai_hot_topic_gists_allowed_groups = group.id
SiteSetting.ai_summarize_max_hot_topics_gists_per_batch = 100
end
it "includes the summary" do
gist_topic = topic_query.list_hot.topics.find { |t| t.id == topic_ai_gist.target_id }
serialized =
TopicListItemSerializer.new(
gist_topic,
scope: Guardian.new(user),
root: false,
filter: :hot,
).as_json
expect(serialized[:ai_topic_gist]).to be_present
end
it "doesn't include the summary when the user is not a member of the opt-in group" do
SiteSetting.ai_hot_topic_gists_allowed_groups = ""
gist_topic = topic_query.list_hot.topics.find { |t| t.id == topic_ai_gist.target_id }
serialized =
TopicListItemSerializer.new(
gist_topic,
scope: Guardian.new(user),
root: false,
filter: :hot,
).as_json
expect(serialized[:ai_topic_gist]).to be_nil
end
it "works when the topic has whispers" do
SiteSetting.whispers_allowed_groups = "#{Group::AUTO_GROUPS[:staff]}"
admin = Fabricate(:admin)
group.add(admin)
# We are testing a scenario where AR could get confused if we don't use `references`.
first = create_post(raw: "this is the first post", title: "super amazing title")
_whisper =
create_post(
topic_id: first.topic.id,
post_type: Post.types[:whisper],
raw: "this is a whispered reply",
)
Fabricate(:topic_ai_gist, target: first.topic)
topic_id = first.topic.id
TopicUser.update_last_read(admin, topic_id, first.post_number, 1, 1)
TopicUser.change(
admin.id,
topic_id,
notification_level: TopicUser.notification_levels[:tracking],
)
gist_topic = TopicQuery.new(admin).list_unread.topics.find { |t| t.id == topic_id }
serialized =
TopicListItemSerializer.new(
gist_topic,
scope: Guardian.new(admin),
root: false,
filter: :unread,
).as_json
expect(serialized[:ai_topic_gist]).to be_present
end
it "doesn't include the summary if it's not a gist" do
regular_summary_2 = Fabricate(:ai_summary)
TopicHotScore.create!(topic_id: regular_summary_2.target_id, score: 1.0)
hot_topic = topic_query.list_hot.topics.find { |t| t.id == regular_summary_2.target_id }
serialized =
TopicListItemSerializer.new(
hot_topic,
scope: Guardian.new(user),
root: false,
filter: :hot,
).as_json
expect(serialized[:ai_topic_gist]).to be_nil
end
end
end
end
end
describe "#on topic_hot_scores_updated" do
it "queues a job to generate gists" do
expect { DiscourseEvent.trigger(:topic_hot_scores_updated) }.to change(
Jobs::HotTopicsGistBatch.jobs,
:size,
).by(1)
end
end
end