discourse/plugins/discourse-workflows/test/javascripts/acceptance/workflows-user-modal-test.js
Joffrey JAFFEUX 90c5ba36fa
FEATURE: adds a modal node to discourse workflows (#40978)
This node allows to display a modal to a specific user and react to the
answer of the user. It requires the user to be actually on the discourse
site.

<img width="2089" height="876" alt="Screenshot 2026-06-17 at 11 31 28"
src="https://github.com/user-attachments/assets/abc40762-eb8e-445e-80b6-1a24bc3c54ea"
/>
<img width="281" height="237" alt="Screenshot 2026-06-17 at 11 31 21"
src="https://github.com/user-attachments/assets/481a9cfa-9d6b-40a9-a593-458a99d9f50a"
/>
2026-06-17 12:12:51 +02:00

112 lines
3.4 KiB
JavaScript
Vendored

import { click, settled, visit } from "@ember/test-helpers";
import { test } from "qunit";
import {
acceptance,
loggedInUser,
publishToMessageBus,
} from "discourse/tests/helpers/qunit-helpers";
acceptance("Discourse Workflows | User modal", function (needs) {
// Present only when a published workflow uses a modal node; gates the
// subscription and provides the channel's starting message-bus id.
needs.user({ discourse_workflows_user_modal_last_id: 0 });
let lastRequestBody = null;
needs.pretender((server, helper) => {
server.post("/discourse-workflows/modal-responses", (request) => {
lastRequestBody = request.requestBody;
return helper.response({});
});
});
needs.hooks.beforeEach(() => (lastRequestBody = null));
function channel() {
return `/discourse-workflows/user-modal/${loggedInUser().id}`;
}
const payload = {
type: "show_modal",
title: "Approve topic?",
body: "Please choose an option",
buttons: [
{
label: "Approve",
value: "approve",
style: "primary",
action_id: "1:approve:sig-approve",
},
{
label: "Reject",
value: "reject",
style: "danger",
action_id: "1:reject:sig-reject",
},
],
};
test("opens a modal with the configured title, body, and buttons", async function (assert) {
await visit("/");
await publishToMessageBus(channel(), payload);
await settled();
assert.dom(".workflows-user-modal").exists("the modal opens");
assert.dom(".d-modal__title-text").hasText("Approve topic?");
assert
.dom(".workflows-user-modal__body")
.hasText("Please choose an option");
assert
.dom(".d-modal__footer .btn")
.exists({ count: 2 }, "renders one button per configured option");
assert.dom(".d-modal__footer .btn-primary").hasText("Approve");
assert.dom(".d-modal__footer .btn-danger").hasText("Reject");
});
test("posts the chosen button's action id and closes the modal", async function (assert) {
await visit("/");
await publishToMessageBus(channel(), payload);
await settled();
await click(".d-modal__footer .btn-primary");
assert.strictEqual(
new URLSearchParams(lastRequestBody).get("action_id"),
"1:approve:sig-approve",
"submits the action id of the clicked button"
);
assert.dom(".workflows-user-modal").doesNotExist("the modal closes");
});
test("ignores message bus payloads of other types", async function (assert) {
await visit("/");
await publishToMessageBus(channel(), { type: "something_else" });
await settled();
assert.dom(".workflows-user-modal").doesNotExist("no modal is opened");
});
});
acceptance(
"Discourse Workflows | User modal (feature unused)",
function (needs) {
// No `discourse_workflows_user_modal_last_id` on the user: no published
// workflow uses a modal node, so the initializer must not subscribe.
needs.user();
test("does not subscribe when no workflow uses a modal node", async function (assert) {
await visit("/");
await publishToMessageBus(
`/discourse-workflows/user-modal/${loggedInUser().id}`,
{
type: "show_modal",
title: "Should not appear",
buttons: [],
}
);
await settled();
assert.dom(".workflows-user-modal").doesNotExist("no modal is opened");
});
}
);