Files
discourse-data-explorer/spec/report_generator_spec.rb
T
David Battersby 08a01b23fe FEATURE: add option to send individual report PM to group members (#369)
This change adds an option to the Schedule a PM with Data Explorer results script, which when selected will send individual PMs to each group member selected in the Send to User, Group or Email field.

When this field is not checked, the functionality for groups will work as it did before (ie. send a single PM to the group).
2025-04-18 15:50:57 +04:00

288 lines
9.2 KiB
Ruby

# frozen_string_literal: true
require "rails_helper"
describe DiscourseDataExplorer::ReportGenerator do
fab!(:user)
fab!(:unauthorised_user) { Fabricate(:user) }
fab!(:unauthorised_group) { Fabricate(:group) }
fab!(:group) { Fabricate(:group, users: [user]) }
fab!(:query) { DiscourseDataExplorer::Query.find(-1) }
let(:query_params) { [%w[from_days_ago 0], %w[duration_days 15]] }
before do
SiteSetting.data_explorer_enabled = true
SiteSetting.authorized_extensions = "csv"
end
describe ".generate" do
it "returns [] if the recipient is not in query group" do
Fabricate(:query_group, query: query, group: group)
result =
described_class.generate(
query.id,
query_params,
[unauthorised_user.username, unauthorised_group.name],
)
expect(result).to eq []
end
it "returns a list of pms for authorised users" do
SiteSetting.personal_message_enabled_groups = group.id
DiscourseDataExplorer::ResultToMarkdown.expects(:convert).returns("le table")
freeze_time
result = described_class.generate(query.id, query_params, [user.username])
expect(result).to eq(
[
{
"title" =>
I18n.t(
"data_explorer.report_generator.private_message.title",
query_name: query.name,
),
"target_usernames" => [user.username],
"raw" =>
I18n.t(
"data_explorer.report_generator.private_message.body",
recipient_name: user.username,
query_name: query.name,
table: "le table",
base_url: Discourse.base_url,
query_id: query.id,
created_at: Time.zone.now.strftime("%Y-%m-%d at %H:%M:%S"),
timezone: Time.zone.name,
),
},
],
)
end
it "still returns a list of pms if a group or user does not exist" do
Fabricate(:query_group, query: query, group: group)
SiteSetting.personal_message_enabled_groups = group.id
DiscourseDataExplorer::ResultToMarkdown.expects(:convert).returns("le table")
freeze_time
result = described_class.generate(query.id, query_params, [group.name, "non-existent-group"])
expect(result).to eq(
[
{
"title" =>
I18n.t(
"data_explorer.report_generator.private_message.title",
query_name: query.name,
),
"target_group_names" => [group.name],
"raw" =>
I18n.t(
"data_explorer.report_generator.private_message.body",
recipient_name: group.name,
query_name: query.name,
table: "le table",
base_url: Discourse.base_url,
query_id: query.id,
created_at: Time.zone.now.strftime("%Y-%m-%d at %H:%M:%S"),
timezone: Time.zone.name,
),
},
],
)
end
it "works with email recipients" do
DiscourseDataExplorer::ResultToMarkdown.expects(:convert).returns("le table")
freeze_time
email = "[email protected]"
result = described_class.generate(query.id, query_params, [email])
expect(result).to eq(
[
{
"title" =>
I18n.t(
"data_explorer.report_generator.private_message.title",
query_name: query.name,
),
"target_emails" => [email],
"raw" =>
I18n.t(
"data_explorer.report_generator.private_message.body",
recipient_name: email,
query_name: query.name,
table: "le table",
base_url: Discourse.base_url,
query_id: query.id,
created_at: Time.zone.now.strftime("%Y-%m-%d at %H:%M:%S"),
timezone: Time.zone.name,
),
},
],
)
end
it "works with duplicate recipients" do
DiscourseDataExplorer::ResultToMarkdown.expects(:convert).returns("le table")
freeze_time
result = described_class.generate(query.id, query_params, [user.username, user.username])
expect(result).to eq(
[
{
"title" =>
I18n.t(
"data_explorer.report_generator.private_message.title",
query_name: query.name,
),
"target_usernames" => [user.username],
"raw" =>
I18n.t(
"data_explorer.report_generator.private_message.body",
recipient_name: user.username,
query_name: query.name,
table: "le table",
base_url: Discourse.base_url,
query_id: query.id,
created_at: Time.zone.now.strftime("%Y-%m-%d at %H:%M:%S"),
timezone: Time.zone.name,
),
},
],
)
end
it "works with multiple recipient types" do
Fabricate(:query_group, query: query, group: group)
DiscourseDataExplorer::ResultToMarkdown.expects(:convert).returns("le table")
result =
described_class.generate(
query.id,
query_params,
[group.name, user.username, "[email protected]"],
)
expect(result.length).to eq(3)
expect(result[0]["target_usernames"]).to eq([user.username])
expect(result[1]["target_group_names"]).to eq([group.name])
expect(result[2]["target_emails"]).to eq(["[email protected]"])
end
it "extracts users from group when option is selected" do
Fabricate(:query_group, query: query, group: group)
DiscourseDataExplorer::ResultToMarkdown.expects(:convert).returns("le table")
freeze_time
result =
described_class.generate(query.id, query_params, [group.name], { users_from_group: true })
expect(result.length).to eq(1)
expect(result[0]["target_usernames"]).to eq([user.username])
end
it "works with attached csv file" do
SiteSetting.personal_message_enabled_groups = group.id
DiscourseDataExplorer::ResultToMarkdown.expects(:convert).returns("le table")
freeze_time
result =
described_class.generate(query.id, query_params, [user.username], { attach_csv: true })
filename =
"#{query.slug}@#{Slug.for(Discourse.current_hostname, "discourse")}-#{Date.today}.dcqresult.csv"
expect(result[0]["raw"]).to eq(
I18n.t(
"data_explorer.report_generator.private_message.body",
recipient_name: user.username,
query_name: query.name,
table: "le table",
base_url: Discourse.base_url,
query_id: query.id,
created_at: Time.zone.now.strftime("%Y-%m-%d at %H:%M:%S"),
timezone: Time.zone.name,
) + "\n\n" +
I18n.t(
"data_explorer.report_generator.upload_appendix",
filename: filename,
short_url: Upload.find_by(original_filename: filename).short_url,
),
)
end
end
describe ".generate_post" do
it "works without attached csv file" do
DiscourseDataExplorer::ResultToMarkdown.expects(:convert).returns("le table")
freeze_time
result = described_class.generate_post(query.id, query_params)
expect(result["raw"]).to eq(
I18n.t(
"data_explorer.report_generator.post.body",
query_name: query.name,
table: "le table",
base_url: Discourse.base_url,
query_id: query.id,
created_at: Time.zone.now.strftime("%Y-%m-%d at %H:%M:%S"),
timezone: Time.zone.name,
),
)
end
it "works with attached csv file" do
DiscourseDataExplorer::ResultToMarkdown.expects(:convert).returns("le table")
freeze_time
result = described_class.generate_post(query.id, query_params, { attach_csv: true })
filename =
"#{query.slug}@#{Slug.for(Discourse.current_hostname, "discourse")}-#{Date.today}.dcqresult.csv"
expect(result["raw"]).to eq(
I18n.t(
"data_explorer.report_generator.post.body",
query_name: query.name,
table: "le table",
base_url: Discourse.base_url,
query_id: query.id,
created_at: Time.zone.now.strftime("%Y-%m-%d at %H:%M:%S"),
timezone: Time.zone.name,
) + "\n\n" +
I18n.t(
"data_explorer.report_generator.upload_appendix",
filename: filename,
short_url: Upload.find_by(original_filename: filename).short_url,
),
)
end
end
describe ".params_to_hash" do
context "when passing nothing" do
let(:query_params) { "[]" }
it { expect(described_class.params_to_hash(query_params)).to eq({}) }
end
context "when passing an array of arrays" do
let(:query_params) { '[["foo", 1], ["bar", 2]]' }
it { expect(described_class.params_to_hash(query_params)).to eq({ "foo" => 1, "bar" => 2 }) }
end
context "when passing an array of hashes" do
let(:query_params) { '[{ "key": "foo", "value": 1 }, { "key": "bar", "value": 2 }]' }
it { expect(described_class.params_to_hash(query_params)).to eq({ "foo" => 1, "bar" => 2 }) }
end
end
end