Merge master

This commit is contained in:
Neil Lalonde
2020-06-24 13:47:36 -04:00
4650 changed files with 229833 additions and 157327 deletions
@@ -1,4 +1,5 @@
import componentTest from "helpers/component-test";
import pretender from "helpers/create-pretender";
moduleForComponent("admin-report", {
integration: true
@@ -133,13 +134,18 @@ componentTest("exception", {
componentTest("rate limited", {
beforeEach() {
const response = object => {
return [429, { "Content-Type": "application/json" }, object];
};
// prettier-ignore
server.get("/admin/reports/bulk", () => { //eslint-disable-line
return response({"errors":["Youve performed this action too many times. Please wait 10 seconds before trying again."],"error_type":"rate_limit","extras":{"wait_seconds":10}});
pretender.get("/admin/reports/bulk", () => {
return [
429,
{ "Content-Type": "application/json" },
{
errors: [
"Youve performed this action too many times. Please wait 10 seconds before trying again."
],
error_type: "rate_limit",
extras: { wait_seconds: 10 }
}
];
});
},
@@ -1,6 +1,7 @@
import selectKit from "helpers/select-kit-helper";
import componentTest from "helpers/component-test";
import EmberObject from "@ember/object";
import pretender from "helpers/create-pretender";
moduleForComponent("badge-title", { integration: true });
@@ -23,8 +24,7 @@ componentTest("badge title", {
},
async test(assert) {
/* global server */
server.put("/u/eviltrout/preferences/badge_title", () => [
pretender.put("/u/eviltrout/preferences/badge_title", () => [
200,
{ "Content-Type": "application/json" },
{}
@@ -0,0 +1,175 @@
import I18n from "I18n";
import componentTest from "helpers/component-test";
moduleForComponent("d-button", { integration: true });
componentTest("icon only button", {
template: '{{d-button icon="plus" tabindex="3"}}',
test(assert) {
assert.ok(
find("button.btn.btn-icon.no-text").length,
"it has all the classes"
);
assert.ok(find("button .d-icon.d-icon-plus").length, "it has the icon");
assert.equal(find("button").attr("tabindex"), "3", "it has the tabindex");
}
});
componentTest("icon and text button", {
template: '{{d-button icon="plus" label="topic.create"}}',
test(assert) {
assert.ok(
find("button.btn.btn-icon-text").length,
"it has all the classes"
);
assert.ok(find("button .d-icon.d-icon-plus").length, "it has the icon");
assert.ok(find("button span.d-button-label").length, "it has the label");
}
});
componentTest("text only button", {
template: '{{d-button label="topic.create"}}',
test(assert) {
assert.ok(find("button.btn.btn-text").length, "it has all the classes");
assert.ok(find("button span.d-button-label").length, "it has the label");
}
});
componentTest("form attribute", {
template: '{{d-button form="login-form"}}',
test(assert) {
assert.ok(exists("button[form=login-form]"), "it has the form attribute");
}
});
componentTest("link-styled button", {
template: '{{d-button display="link"}}',
test(assert) {
assert.ok(
find("button.btn-link:not(.btn)").length,
"it has the right classes"
);
}
});
componentTest("isLoading button", {
template: "{{d-button isLoading=isLoading}}",
beforeEach() {
this.set("isLoading", true);
},
test(assert) {
assert.ok(
find("button.is-loading .loading-icon").length,
"it has a spinner showing"
);
assert.ok(
find("button[disabled]").length,
"while loading the button is disabled"
);
this.set("isLoading", false);
assert.notOk(
find("button .loading-icon").length,
"it doesn't have a spinner showing"
);
assert.ok(
find("button:not([disabled])").length,
"while not loading the button is enabled"
);
}
});
componentTest("disabled button", {
template: "{{d-button disabled=disabled}}",
beforeEach() {
this.set("disabled", true);
},
test(assert) {
assert.ok(find("button[disabled]").length, "the button is disabled");
this.set("disabled", false);
assert.ok(find("button:not([disabled])").length, "the button is enabled");
}
});
componentTest("aria-label", {
template:
"{{d-button ariaLabel=ariaLabel translatedAriaLabel=translatedAriaLabel}}",
beforeEach() {
I18n.translations[I18n.locale].js.test = { fooAriaLabel: "foo" };
},
test(assert) {
this.set("ariaLabel", "test.fooAriaLabel");
assert.equal(
find("button")[0].getAttribute("aria-label"),
I18n.t("test.fooAriaLabel")
);
this.setProperties({
ariaLabel: null,
translatedAriaLabel: "bar"
});
assert.equal(find("button")[0].getAttribute("aria-label"), "bar");
}
});
componentTest("title", {
template: "{{d-button title=title translatedTitle=translatedTitle}}",
beforeEach() {
I18n.translations[I18n.locale].js.test = { fooTitle: "foo" };
},
test(assert) {
this.set("title", "test.fooTitle");
assert.equal(
find("button")[0].getAttribute("title"),
I18n.t("test.fooTitle")
);
this.setProperties({
title: null,
translatedTitle: "bar"
});
assert.equal(find("button")[0].getAttribute("title"), "bar");
}
});
componentTest("label", {
template: "{{d-button label=label translatedLabel=translatedLabel}}",
beforeEach() {
I18n.translations[I18n.locale].js.test = { fooLabel: "foo" };
},
test(assert) {
this.set("label", "test.fooLabel");
assert.equal(
find("button .d-button-label").text(),
I18n.t("test.fooLabel")
);
this.setProperties({
label: null,
translatedLabel: "bar"
});
assert.equal(find("button .d-button-label").text(), "bar");
}
});
@@ -1,56 +0,0 @@
import componentTest from "helpers/component-test";
moduleForComponent("d-button", { integration: true });
componentTest("icon only button", {
template: '{{d-button icon="plus" tabindex="3"}}',
test(assert) {
assert.ok(
find("button.btn.btn-icon.no-text").length,
"it has all the classes"
);
assert.ok(find("button .d-icon.d-icon-plus").length, "it has the icon");
assert.equal(find("button").attr("tabindex"), "3", "it has the tabindex");
}
});
componentTest("icon and text button", {
template: '{{d-button icon="plus" label="topic.create"}}',
test(assert) {
assert.ok(
find("button.btn.btn-icon-text").length,
"it has all the classes"
);
assert.ok(find("button .d-icon.d-icon-plus").length, "it has the icon");
assert.ok(find("button span.d-button-label").length, "it has the label");
}
});
componentTest("text only button", {
template: '{{d-button label="topic.create"}}',
test(assert) {
assert.ok(find("button.btn.btn-text").length, "it has all the classes");
assert.ok(find("button span.d-button-label").length, "it has the label");
}
});
componentTest("form attribute", {
template: '{{d-button form="login-form"}}',
test(assert) {
assert.ok(exists("button[form=login-form]"), "it has the form attribute");
}
});
componentTest("link-styled button", {
template: '{{d-button display="link"}}',
test(assert) {
assert.ok(
find("button.btn-link:not(.btn)").length,
"it has the right classes"
);
}
});
@@ -1,4 +1,6 @@
import I18n from "I18n";
import { next } from "@ember/runloop";
import { clearToolbarCallbacks } from "discourse/components/d-editor";
import componentTest from "helpers/component-test";
import { withPluginApi } from "discourse/lib/plugin-api";
import formatTextWithSelection from "helpers/d-editor-helper";
@@ -583,7 +585,7 @@ testCase(`list button with line sequence`, async function(assert, textarea) {
assert.equal(textarea.selectionEnd, 18);
});
componentTest("clicking the toggle-direction button toggles the direction", {
componentTest("clicking the toggle-direction changes dir from ltr to rtl", {
template: "{{d-editor value=value}}",
beforeEach() {
this.siteSettings.support_mixed_text_direction = true;
@@ -594,8 +596,21 @@ componentTest("clicking the toggle-direction button toggles the direction", {
const textarea = find("textarea.d-editor-input");
await click("button.toggle-direction");
assert.equal(textarea.attr("dir"), "rtl");
}
});
componentTest("clicking the toggle-direction changes dir from ltr to rtl", {
template: "{{d-editor value=value}}",
beforeEach() {
this.siteSettings.support_mixed_text_direction = true;
this.siteSettings.default_locale = "en_US";
},
async test(assert) {
const textarea = find("textarea.d-editor-input");
textarea.attr("dir", "ltr");
await click("button.toggle-direction");
assert.equal(textarea.attr("dir"), "ltr");
assert.equal(textarea.attr("dir"), "rtl");
}
});
@@ -633,6 +648,11 @@ componentTest("emoji", {
});
this.set("value", "hello world.");
},
afterEach() {
clearToolbarCallbacks();
},
async test(assert) {
jumpEnd(find("textarea.d-editor-input")[0]);
await click("button.emoji");
@@ -18,7 +18,7 @@ async function pika(year, month, day) {
function noop() {}
const DEFAULT_DATE = new Date(2019, 0, 29);
const DEFAULT_DATE = moment("2019-01-29");
componentTest("default", {
template: `{{date-input date=date}}`,
@@ -44,7 +44,7 @@ componentTest("prevents mutations", {
await click(dateInput());
await pika(2019, 0, 2);
assert.ok(this.date.getTime() === DEFAULT_DATE.getTime());
assert.ok(this.date.isSame(DEFAULT_DATE));
}
});
@@ -60,6 +60,6 @@ componentTest("allows mutations through actions", {
await click(dateInput());
await pika(2019, 0, 2);
assert.ok(this.date.getTime() === new Date(2019, 0, 2).getTime());
assert.ok(this.date.isSame(moment("2019-01-02")));
}
});
@@ -0,0 +1,36 @@
import componentTest from "helpers/component-test";
moduleForComponent("date-time-input-range", { integration: true });
function fromDateInput() {
return find(".from.d-date-time-input .date-picker")[0];
}
function fromTimeInput() {
return find(".from.d-date-time-input .d-time-input .combo-box-header")[0];
}
function toDateInput() {
return find(".to.d-date-time-input .date-picker")[0];
}
function toTimeInput() {
return find(".to.d-date-time-input .d-time-input .combo-box-header")[0];
}
const DEFAULT_DATE_TIME = moment("2019-01-29 14:45");
componentTest("default", {
template: `{{date-time-input-range from=from to=to}}`,
beforeEach() {
this.setProperties({ from: DEFAULT_DATE_TIME, to: null });
},
test(assert) {
assert.equal(fromDateInput().value, "January 29, 2019");
assert.equal(fromTimeInput().dataset.name, "14:45");
assert.equal(toDateInput().value, "");
assert.equal(toTimeInput().dataset.name, "--:--");
}
});
@@ -1,105 +0,0 @@
import componentTest from "helpers/component-test";
moduleForComponent("date-time-input-range", { integration: true });
function fromDateInput() {
return find(".from .date-picker");
}
function fromHoursInput() {
return find(".from .field.hours");
}
function fromMinutesInput() {
return find(".from .field.minutes");
}
function toDateInput() {
return find(".to .date-picker");
}
function toHoursInput() {
return find(".to .field.hours");
}
function toMinutesInput() {
return find(".to .field.minutes");
}
function setDates(dates) {
this.setProperties(dates);
}
async function pika(year, month, day) {
await click(
`.pika-button.pika-day[data-pika-year="${year}"][data-pika-month="${month}"][data-pika-day="${day}"]`
);
}
const DEFAULT_DATE_TIME = new Date(2019, 0, 29, 14, 45);
componentTest("default", {
template: `{{date-time-input-range from=from to=to}}`,
beforeEach() {
this.setProperties({ from: DEFAULT_DATE_TIME, to: null });
},
test(assert) {
assert.equal(fromDateInput().val(), "January 29, 2019");
assert.equal(fromHoursInput().val(), "14");
assert.equal(fromMinutesInput().val(), "45");
assert.equal(toDateInput().val(), "");
assert.equal(toHoursInput().val(), "");
assert.equal(toMinutesInput().val(), "");
}
});
componentTest("can switch panels", {
template: `{{date-time-input-range}}`,
async test(assert) {
assert.ok(exists(".panel.from.visible"));
assert.notOk(exists(".panel.to.visible"));
await click(".panels button.to-panel");
assert.ok(exists(".panel.to.visible"));
assert.notOk(exists(".panel.from.visible"));
}
});
componentTest("prevents toDate to be before fromDate", {
template: `{{date-time-input-range from=from to=to onChange=onChange}}`,
beforeEach() {
this.setProperties({
from: DEFAULT_DATE_TIME,
to: DEFAULT_DATE_TIME,
onChange: setDates
});
},
async test(assert) {
assert.notOk(exists(".error"), "it begins with no error");
await click(".panels button.to-panel");
await click(toDateInput());
await pika(2019, 0, 1);
assert.ok(exists(".error"), "it shows an error");
assert.deepEqual(this.to, DEFAULT_DATE_TIME, "it didnt trigger a mutation");
await click(".panels button.to-panel");
await click(toDateInput());
await pika(2019, 0, 30);
assert.notOk(exists(".error"), "it removes the error");
assert.deepEqual(
this.to,
new Date(2019, 0, 30, 14, 45),
"it has changed the date"
);
}
});
@@ -3,15 +3,11 @@ import componentTest from "helpers/component-test";
moduleForComponent("date-time-input", { integration: true });
function dateInput() {
return find(".date-picker");
return find(".date-picker")[0];
}
function hoursInput() {
return find(".field.hours");
}
function minutesInput() {
return find(".field.minutes");
function timeInput() {
return find(".d-time-input .combo-box-header")[0];
}
function setDate(date) {
@@ -24,7 +20,7 @@ async function pika(year, month, day) {
);
}
const DEFAULT_DATE_TIME = new Date(2019, 0, 29, 14, 45);
const DEFAULT_DATE_TIME = moment("2019-01-29 14:45");
componentTest("default", {
template: `{{date-time-input date=date}}`,
@@ -34,9 +30,8 @@ componentTest("default", {
},
test(assert) {
assert.equal(dateInput().val(), "January 29, 2019");
assert.equal(hoursInput().val(), "14");
assert.equal(minutesInput().val(), "45");
assert.equal(dateInput().value, "January 29, 2019");
assert.equal(timeInput().dataset.name, "14:45");
}
});
@@ -51,7 +46,7 @@ componentTest("prevents mutations", {
await click(dateInput());
await pika(2019, 0, 2);
assert.ok(this.date.getTime() === DEFAULT_DATE_TIME.getTime());
assert.ok(this.date.isSame(DEFAULT_DATE_TIME));
}
});
@@ -67,7 +62,7 @@ componentTest("allows mutations through actions", {
await click(dateInput());
await pika(2019, 0, 2);
assert.ok(this.date.getTime() === new Date(2019, 0, 2, 14, 45).getTime());
assert.ok(this.date.isSame(moment("2019-01-02 14:45")));
}
});
@@ -79,6 +74,6 @@ componentTest("can hide time", {
},
async test(assert) {
assert.notOk(exists(hoursInput()));
assert.notOk(exists(timeInput()));
}
});
@@ -0,0 +1,22 @@
import componentTest from "helpers/component-test";
moduleForComponent("highlighted-code", { integration: true });
componentTest("highlighting code", {
template: "{{highlighted-code lang='ruby' code=code}}",
beforeEach() {
Discourse.HighlightJSPath =
"assets/highlightjs/highlight-test-bundle.min.js";
this.set("code", "def test; end");
},
async test(assert) {
assert.equal(
find("code.ruby.hljs .hljs-function .hljs-keyword")
.text()
.trim(),
"def"
);
}
});
@@ -0,0 +1,14 @@
import componentTest from "helpers/component-test";
moduleForComponent("html-safe-helper", { integration: true });
componentTest("default", {
template: "{{html-safe string}}",
beforeEach() {
this.set("string", "<p class='cookies'>biscuits</p>");
},
async test(assert) {
assert.ok(exists("p.cookies"), "it displays the string as html");
}
});
@@ -0,0 +1,23 @@
import componentTest from "helpers/component-test";
moduleForComponent("iframed-html", { integration: true });
componentTest("appends the html into the iframe", {
template: `{{iframed-html html="<h1 id='find-me'>hello</h1>" className='this-is-an-iframe'}}`,
async test(assert) {
const iframe = find("iframe.this-is-an-iframe");
assert.equal(iframe.length, 1, "inserts an iframe");
assert.ok(
iframe[0].classList.contains("this-is-an-iframe"),
"Adds className to the iframes classList"
);
assert.equal(
iframe[0].contentWindow.document.body.querySelectorAll("#find-me").length,
1,
"inserts the passed in html into the iframe"
);
}
});
@@ -74,7 +74,7 @@ Object.keys(pathBindings).forEach(path => {
var testName = binding + " goes to " + path;
test(testName, function(assert) {
KeyboardShortcuts.bindEvents(testMouseTrap, Discourse.__container__);
KeyboardShortcuts.bindEvents();
testMouseTrap.trigger(binding);
assert.ok(DiscourseURL.routeTo.calledWith(path));
@@ -89,7 +89,7 @@ Object.keys(clickBindings).forEach(selector => {
var testName = binding + " clicks on " + selector;
test(testName, function(assert) {
KeyboardShortcuts.bindEvents(testMouseTrap, Discourse.__container__);
KeyboardShortcuts.bindEvents();
$(selector).on("click", function() {
assert.ok(true, selector + " was clicked");
});
@@ -109,7 +109,7 @@ Object.keys(functionBindings).forEach(func => {
sandbox.stub(KeyboardShortcuts, func, function() {
assert.ok(true, func + " is called when " + binding + " is triggered");
});
KeyboardShortcuts.bindEvents(testMouseTrap, Discourse.__container__);
KeyboardShortcuts.bindEvents();
testMouseTrap.trigger(binding);
});
@@ -1,3 +1,4 @@
import I18n from "I18n";
import componentTest from "helpers/component-test";
moduleForComponent("secret-value-list", { integration: true });
@@ -0,0 +1,115 @@
import componentTest from "helpers/component-test";
import selectKit, {
testSelectKitModule,
setDefaultState,
DEFAULT_CONTENT
} from "helpers/select-kit-helper";
import { withPluginApi } from "discourse/lib/plugin-api";
import { clearCallbacks } from "select-kit/mixins/plugin-api";
testSelectKitModule("select-kit:api", {
beforeEach() {
this.setProperties({
comboBox: selectKit(".combo-box"),
singleSelect: selectKit(".single-select:not(.combo-box)")
});
},
afterEach() {
clearCallbacks();
}
});
componentTest("modifySelectKit(identifier).appendContent", {
template: `
{{combo-box value=value content=content onChange=onChange}}
{{single-select value=value content=content onChange=onChange}}
`,
beforeEach() {
setDefaultState(this, null, { content: DEFAULT_CONTENT });
withPluginApi("0.8.43", api => {
api.modifySelectKit("combo-box").appendContent(() => {
return {
id: "alpaca",
name: "Alpaca"
};
});
api.modifySelectKit("combo-box").appendContent(() => {});
});
},
async test(assert) {
await this.comboBox.expand();
assert.equal(this.comboBox.rows().length, 4);
const appendedRow = this.comboBox.rowByIndex(3);
assert.ok(appendedRow.exists());
assert.equal(appendedRow.value(), "alpaca");
await this.comboBox.collapse();
assert.notOk(this.singleSelect.rowByValue("alpaca").exists());
}
});
componentTest("modifySelectKit(identifier).prependContent", {
template: `
{{combo-box value=value content=content onChange=onChange}}
{{single-select value=value content=content onChange=onChange}}
`,
beforeEach() {
setDefaultState(this, null, { content: DEFAULT_CONTENT });
withPluginApi("0.8.43", api => {
api.modifySelectKit("combo-box").prependContent(() => {
return {
id: "alpaca",
name: "Alpaca"
};
});
api.modifySelectKit("combo-box").prependContent(() => {});
});
},
async test(assert) {
await this.comboBox.expand();
assert.equal(this.comboBox.rows().length, 4);
const prependedRow = this.comboBox.rowByIndex(0);
assert.ok(prependedRow.exists());
assert.equal(prependedRow.value(), "alpaca");
await this.comboBox.collapse();
assert.notOk(this.singleSelect.rowByValue("alpaca").exists());
}
});
componentTest("modifySelectKit(identifier).onChange", {
template: `
<div id="test"></div>
{{combo-box value=value content=content onChange=onChange}}
`,
beforeEach() {
setDefaultState(this, null, { content: DEFAULT_CONTENT });
withPluginApi("0.8.43", api => {
api.modifySelectKit("combo-box").onChange((component, value, item) => {
find("#test").text(item.name);
});
});
},
async test(assert) {
await this.comboBox.expand();
await this.comboBox.selectRowByIndex(0);
assert.equal(find("#test").text(), "foo");
}
});
@@ -1,5 +1,6 @@
import I18n from "I18n";
import componentTest from "helpers/component-test";
import { testSelectKitModule } from "./select-kit-test-helper";
import { testSelectKitModule } from "helpers/select-kit-helper";
testSelectKitModule("category-chooser");
@@ -1,6 +1,8 @@
import I18n from "I18n";
import DiscourseURL from "discourse/lib/url";
import Category from "discourse/models/category";
import componentTest from "helpers/component-test";
import { testSelectKitModule } from "./select-kit-test-helper";
import { testSelectKitModule } from "helpers/select-kit-helper";
import {
NO_CATEGORIES_ID,
ALL_CATEGORIES_ID
@@ -186,10 +188,11 @@ componentTest("hideParentCategory (true)", {
}
});
componentTest("allowUncategorized (default: true)", {
componentTest("allow_uncategorized_topics (true)", {
template: template(),
beforeEach() {
this.siteSettings.allow_uncategorized_topics = true;
initCategories(this);
},
@@ -202,10 +205,11 @@ componentTest("allowUncategorized (default: true)", {
}
});
componentTest("allowUncategorized (false)", {
template: template(["allowUncategorized=false"]),
componentTest("allow_uncategorized_topics (false)", {
template: template(),
beforeEach() {
this.siteSettings.allow_uncategorized_topics = false;
initCategories(this);
},
@@ -335,3 +339,22 @@ componentTest(
}
}
);
componentTest("category url", {
template: template(),
beforeEach() {
initCategoriesWithParentCategory(this);
sandbox.stub(DiscourseURL, "routeTo");
},
async test(assert) {
await this.subject.expand();
await this.subject.selectRowByValue(26);
assert.ok(
DiscourseURL.routeTo.calledWith("/c/feature/spec/26"),
"it builds a correct URL"
);
}
});
@@ -60,13 +60,19 @@ componentTest("options.showFullTitle=false", {
value=value
content=content
options=(hash
icon="times"
showFullTitle=showFullTitle
none=none
)
}}
`,
beforeEach() {
setDefaultState(this, { showFullTitle: false });
setDefaultState(this, {
value: null,
showFullTitle: false,
none: "test_none"
});
},
async test(assert) {
@@ -75,10 +81,19 @@ componentTest("options.showFullTitle=false", {
this.subject
.header()
.el()
.find(".selected-name .body")
.find(".selected-name")
),
"it hides the text of the selected item"
);
assert.equal(
this.subject
.header()
.el()
.attr("title"),
"[en_US.test_none]",
"it adds a title attribute to the button"
);
}
});
@@ -1,5 +1,5 @@
import componentTest from "helpers/component-test";
import { testSelectKitModule } from "./select-kit-test-helper";
import { testSelectKitModule } from "helpers/select-kit-helper";
testSelectKitModule("list-setting");
@@ -1,5 +1,6 @@
import I18n from "I18n";
import componentTest from "helpers/component-test";
import { testSelectKitModule } from "./select-kit-test-helper";
import { testSelectKitModule } from "helpers/select-kit-helper";
testSelectKitModule("mini-tag-chooser");
@@ -30,7 +31,20 @@ componentTest("create a tag", {
assert.equal(this.subject.header().value(), "foo,bar");
await this.subject.expand();
await this.subject.fillInFilter("monkey");
await this.subject.fillInFilter("mon");
assert.equal(
find(".select-kit-row")
.text()
.trim(),
"monkey x1"
);
await this.subject.fillInFilter("key");
assert.equal(
find(".select-kit-row")
.text()
.trim(),
"monkey x1"
);
await this.subject.keyboard("enter");
assert.equal(this.subject.header().value(), "foo,bar,monkey");
@@ -1,5 +1,5 @@
import componentTest from "helpers/component-test";
import { testSelectKitModule } from "./select-kit-test-helper";
import { testSelectKitModule } from "helpers/select-kit-helper";
testSelectKitModule("multi-select");
@@ -1,5 +1,8 @@
import componentTest from "helpers/component-test";
import { testSelectKitModule, setDefaultState } from "./select-kit-test-helper";
import {
testSelectKitModule,
setDefaultState
} from "helpers/select-kit-helper";
testSelectKitModule("notifications-button");
@@ -1,35 +0,0 @@
import selectKit from "helpers/select-kit-helper";
export function testSelectKitModule(moduleName, options = {}) {
moduleForComponent(`select-kit/${moduleName}`, {
integration: true,
beforeEach() {
this.set("subject", selectKit());
options.beforeEach && options.beforeEach.call(this);
},
afterEach() {
options.afterEach && options.afterEach.call(this);
}
});
}
export const DEFAULT_CONTENT = [
{ id: 1, name: "foo" },
{ id: 2, name: "bar" },
{ id: 3, name: "baz" }
];
export function setDefaultState(ctx, value, options = {}) {
const properties = Object.assign(
{
onChange: v => {
this.set("value", v);
}
},
options || {}
);
ctx.setProperties(properties);
}
@@ -1,5 +1,6 @@
import I18n from "I18n";
import componentTest from "helpers/component-test";
import { testSelectKitModule } from "./select-kit-test-helper";
import { testSelectKitModule } from "helpers/select-kit-helper";
testSelectKitModule("single-select");
@@ -241,7 +242,7 @@ componentTest("selected value can be 0", {
componentTest("prevents propagating click event on header", {
template:
"{{#d-button icon='times' action=onClick}}{{single-select value=value content=content}}{{/d-button}}",
"{{#d-button icon='times' action=onClick}}{{single-select options=(hash preventsClickPropagation=true) value=value content=content}}{{/d-button}}",
beforeEach() {
this.setProperties({
@@ -257,3 +258,45 @@ componentTest("prevents propagating click event on header", {
assert.equal(this.value, DEFAULT_VALUE);
}
});
componentTest("labelProperty", {
template: '{{single-select labelProperty="foo" value=value content=content}}',
beforeEach() {
this.setProperties({
content: [{ id: 1, name: "john", foo: "JACKSON" }],
value: 1
});
},
async test(assert) {
assert.equal(this.subject.header().label(), "JACKSON");
await this.subject.expand();
const row = this.subject.rowByValue(1);
assert.equal(row.label(), "JACKSON");
}
});
componentTest("titleProperty", {
template: '{{single-select titleProperty="foo" value=value content=content}}',
beforeEach() {
this.setProperties({
content: [{ id: 1, name: "john", foo: "JACKSON" }],
value: 1
});
},
async test(assert) {
assert.equal(this.subject.header().title(), "JACKSON");
await this.subject.expand();
const row = this.subject.rowByValue(1);
assert.equal(row.title(), "JACKSON");
}
});
@@ -1,7 +1,9 @@
import I18n from "I18n";
import componentTest from "helpers/component-test";
import { testSelectKitModule } from "./select-kit-test-helper";
import { testSelectKitModule } from "helpers/select-kit-helper";
import Site from "discourse/models/site";
import { set } from "@ember/object";
import pretender from "helpers/create-pretender";
testSelectKitModule("tag-drop", {
beforeEach() {
@@ -12,19 +14,14 @@ testSelectKitModule("tag-drop", {
return [200, { "Content-Type": "application/json" }, object];
};
// prettier-ignore
server.get("/tags/filter/search", (params) => { //eslint-disable-line
pretender.get("/tags/filter/search", params => {
if (params.queryParams.q === "rég") {
return response({
"results": [
{ "id": "régis", "text": "régis", "count": 2, "pm_count": 0 }
]
results: [{ id: "régis", text: "régis", count: 2, pm_count: 0 }]
});
}else if (params.queryParams.q === "dav") {
} else if (params.queryParams.q === "dav") {
return response({
"results": [
{ "id": "David", "text": "David", "count": 2, "pm_count": 0 }
]
results: [{ id: "David", text: "David", count: 2, pm_count: 0 }]
});
}
});
@@ -1,3 +1,4 @@
import I18n from "I18n";
import selectKit from "helpers/select-kit-helper";
import componentTest from "helpers/component-test";
import Topic from "discourse/models/topic";
@@ -1,3 +1,4 @@
import I18n from "I18n";
import selectKit from "helpers/select-kit-helper";
import componentTest from "helpers/component-test";
import Topic from "discourse/models/topic";
@@ -0,0 +1,33 @@
import componentTest from "helpers/component-test";
import { testSelectKitModule } from "helpers/select-kit-helper";
testSelectKitModule("user-chooser");
function template() {
return `{{user-chooser value=value}}`;
}
componentTest("displays usernames", {
template: template(),
beforeEach() {
this.set("value", ["bob", "martin"]);
},
async test(assert) {
assert.equal(this.subject.header().name(), "bob,martin");
}
});
componentTest("can remove a username", {
template: template(),
beforeEach() {
this.set("value", ["bob", "martin"]);
},
async test(assert) {
await this.subject.deselectItem("bob");
assert.equal(this.subject.header().name(), "martin");
}
});
@@ -1,58 +0,0 @@
import componentTest from "helpers/component-test";
import { testSelectKitModule } from "./select-kit-test-helper";
testSelectKitModule("user-chooser");
function template() {
return `{{user-chooser value=value}}`;
}
componentTest("displays usernames", {
template: template(),
beforeEach() {
this.set("value", ["bob", "martin"]);
},
async test(assert) {
assert.equal(this.subject.header().name(), "bob,martin");
}
});
componentTest("can remove a username", {
template: template(),
beforeEach() {
this.set("value", ["bob", "martin"]);
},
async test(assert) {
await this.subject.deselectItem("bob");
assert.equal(this.subject.header().name(), "martin");
}
});
componentTest("can add a username", {
template: template(),
beforeEach() {
this.set("value", ["bob", "martin"]);
const response = object => {
return [200, { "Content-Type": "application/json" }, object];
};
// prettier-ignore
server.get("/u/search/users", () => { //eslint-disable-line
return response({users:[{username: "maja", name: "Maja"}]});
});
},
async test(assert) {
await this.subject.expand();
await this.subject.fillInFilter("maja");
await this.subject.keyboard("enter");
assert.equal(this.subject.header().name(), "bob,martin,maja");
}
});
@@ -0,0 +1,84 @@
import componentTest from "helpers/component-test";
moduleForComponent("simple-list", { integration: true });
componentTest("adding a value", {
template: "{{simple-list values=values}}",
beforeEach() {
this.set("values", "vinkas\nosama");
},
async test(assert) {
assert.ok(
find(".add-value-btn[disabled]").length,
"while loading the + button is disabled"
);
await fillIn(".add-value-input", "penar");
await click(".add-value-btn");
assert.ok(
find(".values .value").length === 3,
"it adds the value to the list of values"
);
assert.ok(
find(".values .value[data-index='2'] .value-input")[0].value === "penar",
"it sets the correct value for added item"
);
await fillIn(".add-value-input", "eviltrout");
await keyEvent(".add-value-input", "keydown", 13); // enter
assert.ok(
find(".values .value").length === 4,
"it adds the value when keying Enter"
);
}
});
componentTest("removing a value", {
template: "{{simple-list values=values}}",
beforeEach() {
this.set("values", "vinkas\nosama");
},
async test(assert) {
await click(".values .value[data-index='0'] .remove-value-btn");
assert.ok(
find(".values .value").length === 1,
"it removes the value from the list of values"
);
assert.ok(
find(".values .value[data-index='0'] .value-input")[0].value === "osama",
"it removes the correct value"
);
}
});
componentTest("delimiter support", {
template: "{{simple-list values=values inputDelimiter='|'}}",
beforeEach() {
this.set("values", "vinkas|osama");
},
async test(assert) {
await fillIn(".add-value-input", "eviltrout");
await click(".add-value-btn");
assert.ok(
find(".values .value").length === 3,
"it adds the value to the list of values"
);
assert.ok(
find(".values .value[data-index='2'] .value-input")[0].value ===
"eviltrout",
"it adds the correct value"
);
}
});
@@ -1,3 +1,4 @@
import I18n from "I18n";
import componentTest from "helpers/component-test";
moduleForComponent("text-field", { integration: true });
@@ -44,3 +45,43 @@ componentTest("sets the dir attribute to ltr for English text", {
assert.equal(find("input").attr("dir"), "ltr");
}
});
componentTest("supports onChange", {
template: `{{text-field class="tf-test" value=value onChange=changed}}`,
beforeEach() {
this.called = false;
this.newValue = null;
this.set("value", "hello");
this.set("changed", v => {
this.newValue = v;
this.called = true;
});
},
async test(assert) {
await fillIn(".tf-test", "hello");
assert.ok(!this.called);
await fillIn(".tf-test", "new text");
assert.ok(this.called);
assert.equal(this.newValue, "new text");
}
});
componentTest("supports onChangeImmediate", {
template: `{{text-field class="tf-test" value=value onChangeImmediate=changed}}`,
beforeEach() {
this.called = false;
this.newValue = null;
this.set("value", "old");
this.set("changed", v => {
this.newValue = v;
this.called = true;
});
},
async test(assert) {
await fillIn(".tf-test", "old");
assert.ok(!this.called);
await fillIn(".tf-test", "no longer old");
assert.ok(this.called);
assert.equal(this.newValue, "no longer old");
}
});
@@ -0,0 +1,55 @@
import selectKit from "helpers/select-kit-helper";
import componentTest from "helpers/component-test";
moduleForComponent("time-input", {
integration: true,
beforeEach() {
this.set("subject", selectKit());
}
});
function setTime(time) {
this.setProperties(time);
}
componentTest("default", {
template: `{{time-input hours=hours minutes=minutes}}`,
beforeEach() {
this.setProperties({ hours: "14", minutes: "58" });
},
test(assert) {
assert.equal(this.subject.header().name(), "14:58");
}
});
componentTest("prevents mutations", {
template: `{{time-input hours=hours minutes=minutes}}`,
beforeEach() {
this.setProperties({ hours: "14", minutes: "58" });
},
async test(assert) {
await this.subject.expand();
await this.subject.selectRowByIndex(3);
assert.equal(this.subject.header().name(), "14:58");
}
});
componentTest("allows mutations through actions", {
template: `{{time-input hours=hours minutes=minutes onChange=onChange}}`,
beforeEach() {
this.setProperties({ hours: "14", minutes: "58" });
this.set("onChange", setTime);
},
async test(assert) {
await this.subject.expand();
await this.subject.selectRowByIndex(3);
assert.equal(this.subject.header().name(), "00:45");
}
});
@@ -1,97 +0,0 @@
import componentTest from "helpers/component-test";
moduleForComponent("time-input", { integration: true });
function hoursInput() {
return find(".field.hours");
}
function minutesInput() {
return find(".field.minutes");
}
function setTime(time) {
this.setProperties(time);
}
function noop() {}
componentTest("default", {
template: `{{time-input hours=hours minutes=minutes}}`,
beforeEach() {
this.setProperties({ hours: "14", minutes: "58" });
},
test(assert) {
assert.equal(hoursInput().val(), "14");
assert.equal(minutesInput().val(), "58");
}
});
componentTest("prevents mutations", {
template: `{{time-input hours=hours minutes=minutes}}`,
beforeEach() {
this.setProperties({ hours: "14", minutes: "58" });
},
async test(assert) {
await fillIn(hoursInput(), "12");
assert.ok(this.hours === "14");
await fillIn(minutesInput(), "36");
assert.ok(this.minutes === "58");
}
});
componentTest("allows mutations through actions", {
template: `{{time-input hours=hours minutes=minutes onChange=onChange}}`,
beforeEach() {
this.setProperties({ hours: "14", minutes: "58" });
this.set("onChange", setTime);
},
async test(assert) {
await fillIn(hoursInput(), "12");
assert.ok(this.hours === "12");
await fillIn(minutesInput(), "36");
assert.ok(this.minutes === "36");
}
});
componentTest("hours and minutes have boundaries", {
template: `{{time-input hours=14 minutes=58 onChange=onChange}}`,
beforeEach() {
this.set("onChange", noop);
},
async test(assert) {
await fillIn(hoursInput(), "2");
assert.equal(hoursInput().val(), "02");
await fillIn(hoursInput(), "@");
assert.equal(hoursInput().val(), "00");
await fillIn(hoursInput(), "24");
assert.equal(hoursInput().val(), "23");
await fillIn(hoursInput(), "-1");
assert.equal(hoursInput().val(), "00");
await fillIn(minutesInput(), "@");
assert.equal(minutesInput().val(), "00");
await fillIn(minutesInput(), "2");
assert.equal(minutesInput().val(), "02");
await fillIn(minutesInput(), "60");
assert.equal(minutesInput().val(), "59");
await fillIn(minutesInput(), "-1");
assert.equal(minutesInput().val(), "00");
}
});