FIX: Query downloads were being passed an incorrect query object. (#359)

This is a follow-up to d726c4889e5c5d7726ed1035c37d0cd60a3bb3d6.

The previous change missed changing the name of the query object when passing it to QueryResultsWrapper, which resulted in the download links not working properly after a query was run.

This change fixes that bug, and includes an acceptance test to ensure it stays fixed during future work on this plugin.
This commit is contained in:
Gary Pendergast 2025-02-14 10:11:32 +11:00 committed by GitHub
parent 6dc695cced
commit c13e79d21b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 84 additions and 6 deletions

View File

@ -150,11 +150,6 @@ export default class PluginsExplorerController extends Controller {
this.showCreate = true;
}
@action
resetParams() {
this.selectedItem.resetParams();
}
@action
updateSortProperty(property) {
if (this.sortByProperty === property) {

View File

@ -217,7 +217,7 @@
<QueryResultsWrapper
@results={{this.results}}
@showResults={{this.showResults}}
@query={{this.selectedItem}}
@query={{this.model}}
@content={{this.results}}
/>
{{/if}}

View File

@ -1,5 +1,6 @@
import { click, visit } from "@ember/test-helpers";
import { test } from "qunit";
import sinon from "sinon";
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
import { i18n } from "discourse-i18n";
@ -7,6 +8,14 @@ acceptance("Data Explorer Plugin | Run Query", function (needs) {
needs.user();
needs.settings({ data_explorer_enabled: true });
needs.hooks.beforeEach(() => {
sinon.stub(window, "open");
});
needs.hooks.afterEach(() => {
window.open.restore();
});
needs.pretender((server, helper) => {
server.get("/admin/plugins/explorer/groups.json", () => {
return helper.response([
@ -203,6 +212,12 @@ acceptance("Data Explorer Plugin | Run Query", function (needs) {
rows: [[0, null, false]],
});
});
server.get("/session/csrf.json", function () {
return helper.response({
csrf: "mgk906YLagHo2gOgM1ddYjAN4hQolBdJCqlY6jYzAYs= ",
});
});
});
test("runs query and renders data and a chart", async function (assert) {
@ -233,6 +248,74 @@ acceptance("Data Explorer Plugin | Run Query", function (needs) {
assert.dom("canvas").exists("the chart was rendered");
});
test("runs query and is able to download the results", async function (assert) {
await visit("/admin/plugins/explorer/queries/-6");
await click("form.query-run button");
const createElement = document.createElement.bind(document);
const appendChild = document.body.appendChild.bind(document.body);
const removeChild = document.body.removeChild.bind(document.body);
const finishedForm = sinon.promise();
let formElement;
const formStub = sinon
.stub(document, "createElement")
.callsFake((tagName) => {
if (tagName === "form") {
formElement = {
fakeForm: true,
setAttribute: sinon.stub(),
appendChild: sinon.stub(),
submit: sinon.stub().callsFake(finishedForm.resolve),
};
return formElement;
}
return createElement(tagName);
});
const appendChildStub = sinon
.stub(document.body, "appendChild")
.callsFake((el) => {
if (!el.fakeForm) {
return appendChild(el);
}
});
const removeChildStub = sinon
.stub(document.body, "removeChild")
.callsFake((el) => {
if (!el.fakeForm) {
return removeChild(el);
}
});
await click("div.result-info button:nth-child(1)");
await finishedForm;
formStub.restore();
appendChildStub.restore();
removeChildStub.restore();
assert.ok(window.open.called, "window.open was called for downloading");
assert.ok(formStub.called, "form was created for downloading");
assert.ok(formElement.submit.called, "form was submitted for downloading");
assert.ok(
formElement.setAttribute.calledWith("action"),
"form action attribute was set"
);
assert.ok(
formElement.setAttribute.calledWith("method", "post"),
"form method attribute was set to POST"
);
});
test("runs query and renders 0, false, and NULL values correctly", async function (assert) {
await visit("/admin/plugins/explorer/queries/2");