Spiegel von
https://github.com/paviliondev/discourse-custom-wizard.git
synchronisiert 2024-11-10 04:12:53 +01:00
WIP
Dieser Commit ist enthalten in:
Ursprung
4605b23585
Commit
b62aee8a48
3 geänderte Dateien mit 258 neuen und 0 gelöschten Zeilen
74
test/javascripts/wizard/test_helper.js
Normale Datei
74
test/javascripts/wizard/test_helper.js
Normale Datei
|
@ -0,0 +1,74 @@
|
||||||
|
// discourse-skip-module
|
||||||
|
/*global document, Logster, QUnit */
|
||||||
|
|
||||||
|
window.Discourse = {};
|
||||||
|
window.Wizard = {};
|
||||||
|
Wizard.SiteSettings = {};
|
||||||
|
Discourse.__widget_helpers = {};
|
||||||
|
Discourse.SiteSettings = Wizard.SiteSettings;
|
||||||
|
|
||||||
|
//= require env
|
||||||
|
//= require jquery.debug
|
||||||
|
//= require ember.debug
|
||||||
|
//= require locales/i18n
|
||||||
|
//= require locales/en
|
||||||
|
//= require route-recognizer
|
||||||
|
//= require fake_xml_http_request
|
||||||
|
//= require pretender
|
||||||
|
//= require qunit
|
||||||
|
//= require ember-qunit
|
||||||
|
//= require discourse-loader
|
||||||
|
//= require jquery.debug
|
||||||
|
//= require handlebars
|
||||||
|
//= require ember-template-compiler
|
||||||
|
//= require wizard-application
|
||||||
|
//= require wizard-vendor
|
||||||
|
//= require_tree ./helpers
|
||||||
|
//= require_tree ./acceptance
|
||||||
|
//= require_tree ./models
|
||||||
|
//= require_tree ./components
|
||||||
|
//= require ./wizard-pretender
|
||||||
|
//= require test-shims
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
document.body.insertAdjacentHTML(
|
||||||
|
"afterbegin",
|
||||||
|
`
|
||||||
|
<div id="ember-testing-container"><div id="ember-testing"></div></div>
|
||||||
|
<style>#ember-testing-container { position: absolute; background: white; bottom: 0; right: 0; width: 640px; height: 384px; overflow: auto; z-index: 9999; border: 1px solid #ccc; } #ember-testing { zoom: 50%; }</style>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (window.Logster) {
|
||||||
|
Logster.enabled = false;
|
||||||
|
} else {
|
||||||
|
window.Logster = { enabled: false };
|
||||||
|
}
|
||||||
|
Ember.Test.adapter = window.QUnitAdapter.create();
|
||||||
|
|
||||||
|
let createPretendServer = requirejs(
|
||||||
|
"wizard/test/wizard-pretender",
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
false
|
||||||
|
).default;
|
||||||
|
|
||||||
|
let server;
|
||||||
|
QUnit.testStart(function () {
|
||||||
|
server = createPretendServer();
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.testDone(function () {
|
||||||
|
server.shutdown();
|
||||||
|
});
|
||||||
|
|
||||||
|
let _testApp = requirejs("wizard/test/helpers/start-app").default();
|
||||||
|
let _buildResolver = requirejs("discourse-common/resolver").buildResolver;
|
||||||
|
window.setResolver(_buildResolver("wizard").create({ namespace: _testApp }));
|
||||||
|
|
||||||
|
Object.keys(requirejs.entries).forEach(function (entry) {
|
||||||
|
if (/\-test/.test(entry)) {
|
||||||
|
requirejs(entry, null, null, true);
|
||||||
|
}
|
||||||
|
});
|
106
test/javascripts/wizard/wizard-pretender.js
Normale Datei
106
test/javascripts/wizard/wizard-pretender.js
Normale Datei
|
@ -0,0 +1,106 @@
|
||||||
|
import Pretender from "pretender";
|
||||||
|
|
||||||
|
// TODO: This file has some copied and pasted functions from `create-pretender` - would be good
|
||||||
|
// to centralize that code at some point.
|
||||||
|
|
||||||
|
function parsePostData(query) {
|
||||||
|
const result = {};
|
||||||
|
query.split("&").forEach(function (part) {
|
||||||
|
const item = part.split("=");
|
||||||
|
const firstSeg = decodeURIComponent(item[0]);
|
||||||
|
const m = /^([^\[]+)\[([^\]]+)\]/.exec(firstSeg);
|
||||||
|
|
||||||
|
const val = decodeURIComponent(item[1]).replace(/\+/g, " ");
|
||||||
|
if (m) {
|
||||||
|
result[m[1]] = result[m[1]] || {};
|
||||||
|
result[m[1]][m[2]] = val;
|
||||||
|
} else {
|
||||||
|
result[firstSeg] = val;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function response(code, obj) {
|
||||||
|
if (typeof code === "object") {
|
||||||
|
obj = code;
|
||||||
|
code = 200;
|
||||||
|
}
|
||||||
|
return [code, { "Content-Type": "application/json" }, obj];
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function () {
|
||||||
|
const server = new Pretender(function () {
|
||||||
|
this.get("/wizard.json", () => {
|
||||||
|
return response(200, {
|
||||||
|
wizard: {
|
||||||
|
start: "hello-world",
|
||||||
|
completed: true,
|
||||||
|
steps: [
|
||||||
|
{
|
||||||
|
id: "hello-world",
|
||||||
|
title: "hello there",
|
||||||
|
index: 0,
|
||||||
|
description: "hello!",
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
id: "full_name",
|
||||||
|
type: "text",
|
||||||
|
required: true,
|
||||||
|
description: "Your name",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
next: "second-step",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "second-step",
|
||||||
|
title: "Second step",
|
||||||
|
index: 1,
|
||||||
|
fields: [{ id: "some-title", type: "text" }],
|
||||||
|
previous: "hello-world",
|
||||||
|
next: "last-step",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "last-step",
|
||||||
|
index: 2,
|
||||||
|
fields: [
|
||||||
|
{ id: "snack", type: "dropdown", required: true },
|
||||||
|
{ id: "theme-preview", type: "component" },
|
||||||
|
{ id: "an-image", type: "image" },
|
||||||
|
],
|
||||||
|
previous: "second-step",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
this.put("/wizard/steps/:id", (request) => {
|
||||||
|
const body = parsePostData(request.requestBody);
|
||||||
|
|
||||||
|
if (body.fields.full_name === "Server Fail") {
|
||||||
|
return response(422, {
|
||||||
|
errors: [{ field: "full_name", description: "Invalid name" }],
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return response(200, { success: true });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
server.prepareBody = function (body) {
|
||||||
|
if (body && typeof body === "object") {
|
||||||
|
return JSON.stringify(body);
|
||||||
|
}
|
||||||
|
return body;
|
||||||
|
};
|
||||||
|
|
||||||
|
server.unhandledRequest = function (verb, path) {
|
||||||
|
const error =
|
||||||
|
"Unhandled request in test environment: " + path + " (" + verb + ")";
|
||||||
|
window.console.error(error);
|
||||||
|
throw error;
|
||||||
|
};
|
||||||
|
|
||||||
|
return server;
|
||||||
|
}
|
78
test/javascripts/wizard/wizard-test.js
Normale Datei
78
test/javascripts/wizard/wizard-test.js
Normale Datei
|
@ -0,0 +1,78 @@
|
||||||
|
import { click, currentRouteName, fillIn, visit } from "@ember/test-helpers";
|
||||||
|
import { module, test } from "qunit";
|
||||||
|
import { run } from "@ember/runloop";
|
||||||
|
import startApp from "wizard/test/helpers/start-app";
|
||||||
|
|
||||||
|
let wizard;
|
||||||
|
module("Acceptance: wizard", {
|
||||||
|
beforeEach() {
|
||||||
|
wizard = startApp();
|
||||||
|
},
|
||||||
|
|
||||||
|
afterEach() {
|
||||||
|
run(wizard, "destroy");
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
function exists(selector) {
|
||||||
|
return document.querySelector(selector) !== null;
|
||||||
|
}
|
||||||
|
|
||||||
|
test("Wizard starts", async function (assert) {
|
||||||
|
await visit("/");
|
||||||
|
assert.ok(exists(".wizard-column-contents"));
|
||||||
|
assert.strictEqual(currentRouteName(), "step");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Going back and forth in steps", async function (assert) {
|
||||||
|
await visit("/steps/hello-world");
|
||||||
|
assert.ok(exists(".wizard-step"));
|
||||||
|
assert.ok(
|
||||||
|
exists(".wizard-step-hello-world"),
|
||||||
|
"it adds a class for the step id"
|
||||||
|
);
|
||||||
|
assert.ok(!exists(".wizard-btn.finish"), "can’t finish on first step");
|
||||||
|
assert.ok(exists(".wizard-progress"));
|
||||||
|
assert.ok(exists(".wizard-step-title"));
|
||||||
|
assert.ok(exists(".wizard-step-description"));
|
||||||
|
assert.ok(
|
||||||
|
!exists(".invalid .field-full-name"),
|
||||||
|
"don't show it as invalid until the user does something"
|
||||||
|
);
|
||||||
|
assert.ok(exists(".wizard-field .field-description"));
|
||||||
|
assert.ok(!exists(".wizard-btn.back"));
|
||||||
|
assert.ok(!exists(".wizard-field .field-error-description"));
|
||||||
|
|
||||||
|
// invalid data
|
||||||
|
await click(".wizard-btn.next");
|
||||||
|
assert.ok(exists(".invalid .field-full-name"));
|
||||||
|
|
||||||
|
// server validation fail
|
||||||
|
await fillIn("input.field-full-name", "Server Fail");
|
||||||
|
await click(".wizard-btn.next");
|
||||||
|
assert.ok(exists(".invalid .field-full-name"));
|
||||||
|
assert.ok(exists(".wizard-field .field-error-description"));
|
||||||
|
|
||||||
|
// server validation ok
|
||||||
|
await fillIn("input.field-full-name", "Evil Trout");
|
||||||
|
await click(".wizard-btn.next");
|
||||||
|
assert.ok(!exists(".wizard-field .field-error-description"));
|
||||||
|
assert.ok(!exists(".wizard-step-description"));
|
||||||
|
assert.ok(
|
||||||
|
exists(".wizard-btn.finish"),
|
||||||
|
"shows finish on an intermediate step"
|
||||||
|
);
|
||||||
|
|
||||||
|
await click(".wizard-btn.next");
|
||||||
|
assert.ok(exists(".select-kit.field-snack"), "went to the next step");
|
||||||
|
assert.ok(exists(".preview-area"), "renders the component field");
|
||||||
|
assert.ok(exists(".wizard-btn.done"), "last step shows a done button");
|
||||||
|
assert.ok(exists(".action-link.back"), "shows the back button");
|
||||||
|
assert.ok(!exists(".wizard-step-title"));
|
||||||
|
assert.ok(!exists(".wizard-btn.finish"), "can’t finish on last step");
|
||||||
|
|
||||||
|
await click(".action-link.back");
|
||||||
|
assert.ok(exists(".wizard-step-title"));
|
||||||
|
assert.ok(exists(".wizard-btn.next"));
|
||||||
|
assert.ok(!exists(".wizard-prev"));
|
||||||
|
});
|
Laden …
In neuem Issue referenzieren