Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 1 commit into from
Feb 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@
<QueryResultsWrapper
@results={{this.results}}
@showResults={{this.showResults}}
@query={{this.selectedItem}}
@query={{this.model}}
@content={{this.results}}
/>
{{/if}}
83 changes: 83 additions & 0 deletions test/javascripts/acceptance/run-query-test.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
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";

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([
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally I would have written this as a system spec to avoid needing to do all these mocks and stubs, but it's cool you got it to work this way 👍

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");

Expand Down
Loading