When setting up an automation to create a DM or a post with a report on a recurring basis, and using a Data Explorer query that has parameters, we encounter an error. The `.params_to_hash` method currently expects an array of arrays for the parameters, but in reality they seem to be arrays of hashes. This change makes `.params_to_hash` work with arrays of hashes. It also preserves the ability to work with nested arrays in case this is used somewhere else.
277 lines
8.8 KiB
Ruby
277 lines
8.8 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 "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
|