DEV: select-kit 2 (#7998)
This new iteration of select-kit focuses on following best principales and disallowing mutations inside select-kit components. A best effort has been made to avoid breaking changes, however if you content was a flat array, eg: ["foo", "bar"] You will need to set valueProperty=null and nameProperty=null on the component. Also almost every component should have an `onChange` handler now to decide what to do with the updated data. **select-kit will not mutate your data by itself anymore**
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import selectKit from "helpers/select-kit-helper";
|
||||
import { acceptance } from "helpers/qunit-helpers";
|
||||
|
||||
acceptance("Admin - User Index", {
|
||||
@@ -84,15 +85,10 @@ QUnit.test("will clear unsaved groups when switching user", async assert => {
|
||||
"the name should be correct"
|
||||
);
|
||||
|
||||
await fillIn(".admin-group-selector .filter-input", "Macdonald");
|
||||
await click(".admin-group-selector .filter-input");
|
||||
await keyEvent(".admin-group-selector .filter-input", "keydown", 13);
|
||||
|
||||
assert.equal(
|
||||
find('.admin-group-selector span[title="Macdonald"]').length,
|
||||
1,
|
||||
"group should be set"
|
||||
);
|
||||
const groupSelector = selectKit(".admin-group-selector");
|
||||
await groupSelector.expand();
|
||||
await groupSelector.selectRowByValue(42);
|
||||
assert.equal(groupSelector.header().value(), 42, "group should be set");
|
||||
|
||||
await visit("/admin/users/1/eviltrout");
|
||||
|
||||
|
||||
@@ -447,6 +447,8 @@ QUnit.test("Composer can toggle whispers", async assert => {
|
||||
|
||||
await click(".toggle-fullscreen");
|
||||
|
||||
await menu.expand();
|
||||
|
||||
assert.ok(
|
||||
menu.rowByValue("toggleWhisper").exists(),
|
||||
"whisper toggling is still present when going fullscreen"
|
||||
@@ -638,7 +640,6 @@ QUnit.test("Checks for existing draft", async assert => {
|
||||
|
||||
QUnit.test("Can switch states without abandon popup", async assert => {
|
||||
try {
|
||||
const composerActions = selectKit(".composer-actions");
|
||||
toggleCheckDraftPopup(true);
|
||||
|
||||
await visit("/t/internationalization-localization/280");
|
||||
@@ -659,8 +660,9 @@ QUnit.test("Can switch states without abandon popup", async assert => {
|
||||
|
||||
await click("article#post_3 button.reply");
|
||||
|
||||
const composerActions = selectKit(".composer-actions");
|
||||
await composerActions.expand();
|
||||
await composerActions.selectRowByValue("reply_to_topic");
|
||||
await composerActions.selectRowByValue("reply_as_private_message");
|
||||
|
||||
assert.equal(
|
||||
find(".modal-body").text(),
|
||||
@@ -668,9 +670,10 @@ QUnit.test("Can switch states without abandon popup", async assert => {
|
||||
"abandon popup shouldn't come"
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
find(".d-editor-input").val(),
|
||||
longText,
|
||||
assert.ok(
|
||||
find(".d-editor-input")
|
||||
.val()
|
||||
.includes(longText),
|
||||
"entered text should still be there"
|
||||
);
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ QUnit.test("Disable body until category is selected", async assert => {
|
||||
|
||||
await fillIn(".d-editor-input", "Now I can type stuff");
|
||||
await categoryChooser.expand();
|
||||
await categoryChooser.selectRowByValue("__none__");
|
||||
await categoryChooser.selectRowByIndex(0);
|
||||
|
||||
assert.ok(
|
||||
find(".d-editor-textarea-wrapper.disabled").length === 0,
|
||||
|
||||
@@ -51,29 +51,22 @@ QUnit.test("Anonymous Viewing Group", async assert => {
|
||||
);
|
||||
assert.ok(count(".user-stream-item") > 0, "it lists stream items");
|
||||
|
||||
await selectKit(".group-dropdown").expand();
|
||||
const groupDropdown = selectKit(".group-dropdown");
|
||||
await groupDropdown.expand();
|
||||
|
||||
assert.equal(groupDropdown.rowByIndex(1).name(), "discourse");
|
||||
|
||||
assert.equal(
|
||||
find(".select-kit-row")
|
||||
.text()
|
||||
.trim(),
|
||||
"discourse",
|
||||
"it displays the right row"
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
find(".group-dropdown-filter")
|
||||
.text()
|
||||
.trim(),
|
||||
I18n.t("groups.index.all").toLowerCase(),
|
||||
"it displays the right header"
|
||||
groupDropdown.rowByIndex(0).name(),
|
||||
I18n.t("groups.index.all").toLowerCase()
|
||||
);
|
||||
|
||||
Discourse.SiteSettings.enable_group_directory = false;
|
||||
|
||||
await visit("/g");
|
||||
await visit("/g/discourse");
|
||||
await selectKit(".group-dropdown").expand();
|
||||
|
||||
await groupDropdown.expand();
|
||||
|
||||
assert.equal(
|
||||
find(".group-dropdown-filter").length,
|
||||
|
||||
@@ -39,8 +39,11 @@ QUnit.test("Settings", async assert => {
|
||||
|
||||
assert.ok(find(".reviewable-score-type").length, "has a list of bonuses");
|
||||
|
||||
await fillIn(".reviewable-score-type:eq(0) .field input ", "0.5");
|
||||
const field = selectKit(".reviewable-score-type:eq(0) .field .combo-box");
|
||||
await field.expand();
|
||||
await field.selectRowByValue("5");
|
||||
await click(".save-settings");
|
||||
|
||||
assert.ok(find(".reviewable-settings .saved").length, "it saved");
|
||||
});
|
||||
|
||||
@@ -124,7 +127,7 @@ QUnit.test("Editing a reviewable", async assert => {
|
||||
let tags = selectKit(`${topic} .payload-tags .mini-tag-chooser`);
|
||||
await tags.expand();
|
||||
await tags.fillInFilter("monkey");
|
||||
await tags.keyboard("enter");
|
||||
await tags.selectRowByValue("monkey");
|
||||
|
||||
await fillIn(".editable-field.payload-raw textarea", "new raw contents");
|
||||
await click(`${topic} .reviewable-action.save-edit`);
|
||||
|
||||
@@ -322,8 +322,9 @@ QUnit.test("update in filter through advanced search ui", async assert => {
|
||||
await inSelector.expand();
|
||||
await inSelector.selectRowByValue("bookmarks");
|
||||
|
||||
assert.ok(
|
||||
inSelector.rowByName("I bookmarked").exists(),
|
||||
assert.equal(
|
||||
inSelector.header().label(),
|
||||
"I bookmarked",
|
||||
'has "I bookmarked" populated'
|
||||
);
|
||||
assert.equal(
|
||||
@@ -344,8 +345,9 @@ QUnit.test("update status through advanced search ui", async assert => {
|
||||
await statusSelector.expand();
|
||||
await statusSelector.selectRowByValue("closed");
|
||||
|
||||
assert.ok(
|
||||
statusSelector.rowByName("are closed").exists(),
|
||||
assert.equal(
|
||||
statusSelector.header().label(),
|
||||
"are closed",
|
||||
'has "are closed" populated'
|
||||
);
|
||||
assert.equal(
|
||||
@@ -375,8 +377,9 @@ QUnit.test("update post time through advanced search ui", async assert => {
|
||||
await postTimeSelector.expand();
|
||||
await postTimeSelector.selectRowByValue("after");
|
||||
|
||||
assert.ok(
|
||||
postTimeSelector.rowByName("after").exists(),
|
||||
assert.equal(
|
||||
postTimeSelector.header().label(),
|
||||
"after",
|
||||
'has "after" populated'
|
||||
);
|
||||
|
||||
@@ -409,7 +412,7 @@ QUnit.test("validate advanced search when initially empty", async assert => {
|
||||
await click(".search-advanced-options .in-likes");
|
||||
|
||||
assert.ok(
|
||||
exists(".search-advanced-options .in-likes:checked"),
|
||||
selectKit(".search-advanced-options .in-likes:checked"),
|
||||
'has "I liked" populated'
|
||||
);
|
||||
assert.equal(
|
||||
|
||||
@@ -28,15 +28,15 @@ QUnit.test("default", async assert => {
|
||||
await click(".toggle-admin-menu");
|
||||
await click(".topic-admin-status-update button");
|
||||
|
||||
assert.equal(futureDateInputSelector.header().title(), "Select a timeframe");
|
||||
assert.equal(futureDateInputSelector.header().label(), "Select a timeframe");
|
||||
assert.equal(futureDateInputSelector.header().value(), null);
|
||||
|
||||
await click("#private-topic-timer");
|
||||
|
||||
assert.equal(timerType.header().title(), "Remind Me");
|
||||
assert.equal(timerType.header().label(), "Remind Me");
|
||||
assert.equal(timerType.header().value(), "reminder");
|
||||
|
||||
assert.equal(futureDateInputSelector.header().title(), "Select a timeframe");
|
||||
assert.equal(futureDateInputSelector.header().label(), "Select a timeframe");
|
||||
assert.equal(futureDateInputSelector.header().value(), null);
|
||||
});
|
||||
|
||||
@@ -51,7 +51,12 @@ QUnit.test("autoclose - specific time", async assert => {
|
||||
await futureDateInputSelector.expand();
|
||||
await futureDateInputSelector.selectRowByValue("next_week");
|
||||
|
||||
assert.equal(futureDateInputSelector.header().title(), "Next week");
|
||||
assert.ok(
|
||||
futureDateInputSelector
|
||||
.header()
|
||||
.label()
|
||||
.includes("Next week")
|
||||
);
|
||||
assert.equal(futureDateInputSelector.header().value(), "next_week");
|
||||
|
||||
const regex = /will automatically close in/g;
|
||||
@@ -72,7 +77,12 @@ QUnit.test("autoclose", async assert => {
|
||||
await futureDateInputSelector.expand();
|
||||
await futureDateInputSelector.selectRowByValue("next_week");
|
||||
|
||||
assert.equal(futureDateInputSelector.header().title(), "Next week");
|
||||
assert.ok(
|
||||
futureDateInputSelector
|
||||
.header()
|
||||
.label()
|
||||
.includes("Next week")
|
||||
);
|
||||
assert.equal(futureDateInputSelector.header().value(), "next_week");
|
||||
|
||||
const regex1 = /will automatically close in/g;
|
||||
@@ -86,7 +96,12 @@ QUnit.test("autoclose", async assert => {
|
||||
|
||||
await fillIn(".future-date-input .date-picker", "2099-11-24");
|
||||
|
||||
assert.equal(futureDateInputSelector.header().title(), "Pick date and time");
|
||||
assert.ok(
|
||||
futureDateInputSelector
|
||||
.header()
|
||||
.label()
|
||||
.includes("Pick date and time")
|
||||
);
|
||||
assert.equal(futureDateInputSelector.header().value(), "pick_date_and_time");
|
||||
|
||||
const regex2 = /will automatically close in/g;
|
||||
@@ -100,9 +115,11 @@ QUnit.test("autoclose", async assert => {
|
||||
|
||||
await fillIn(".future-date-input input[type=number]", "2");
|
||||
|
||||
assert.equal(
|
||||
futureDateInputSelector.header().title(),
|
||||
"Close based on last post"
|
||||
assert.ok(
|
||||
futureDateInputSelector
|
||||
.header()
|
||||
.label()
|
||||
.includes("Close based on last post")
|
||||
);
|
||||
assert.equal(
|
||||
futureDateInputSelector.header().value(),
|
||||
@@ -128,13 +145,18 @@ QUnit.test("close temporarily", async assert => {
|
||||
await timerType.expand();
|
||||
await timerType.selectRowByValue("open");
|
||||
|
||||
assert.equal(futureDateInputSelector.header().title(), "Select a timeframe");
|
||||
assert.equal(futureDateInputSelector.header().label(), "Select a timeframe");
|
||||
assert.equal(futureDateInputSelector.header().value(), null);
|
||||
|
||||
await futureDateInputSelector.expand();
|
||||
await futureDateInputSelector.selectRowByValue("next_week");
|
||||
|
||||
assert.equal(futureDateInputSelector.header().title(), "Next week");
|
||||
assert.ok(
|
||||
futureDateInputSelector
|
||||
.header()
|
||||
.label()
|
||||
.includes("Next week")
|
||||
);
|
||||
assert.equal(futureDateInputSelector.header().value(), "next_week");
|
||||
|
||||
const regex1 = /will automatically open in/g;
|
||||
@@ -148,7 +170,7 @@ QUnit.test("close temporarily", async assert => {
|
||||
|
||||
await fillIn(".future-date-input .date-picker", "2099-11-24");
|
||||
|
||||
assert.equal(futureDateInputSelector.header().title(), "Pick date and time");
|
||||
assert.equal(futureDateInputSelector.header().label(), "Pick date and time");
|
||||
assert.equal(futureDateInputSelector.header().value(), "pick_date_and_time");
|
||||
|
||||
const regex2 = /will automatically open in/g;
|
||||
@@ -171,10 +193,10 @@ QUnit.test("schedule", async assert => {
|
||||
await timerType.expand();
|
||||
await timerType.selectRowByValue("publish_to_category");
|
||||
|
||||
assert.equal(categoryChooser.header().title(), "uncategorized");
|
||||
assert.equal(categoryChooser.header().label(), "uncategorized");
|
||||
assert.equal(categoryChooser.header().value(), null);
|
||||
|
||||
assert.equal(futureDateInputSelector.header().title(), "Select a timeframe");
|
||||
assert.equal(futureDateInputSelector.header().label(), "Select a timeframe");
|
||||
assert.equal(futureDateInputSelector.header().value(), null);
|
||||
|
||||
await categoryChooser.expand();
|
||||
@@ -183,7 +205,12 @@ QUnit.test("schedule", async assert => {
|
||||
await futureDateInputSelector.expand();
|
||||
await futureDateInputSelector.selectRowByValue("next_week");
|
||||
|
||||
assert.equal(futureDateInputSelector.header().title(), "Next week");
|
||||
assert.ok(
|
||||
futureDateInputSelector
|
||||
.header()
|
||||
.label()
|
||||
.includes("Next week")
|
||||
);
|
||||
assert.equal(futureDateInputSelector.header().value(), "next_week");
|
||||
|
||||
const regex = /will be published to #dev/g;
|
||||
@@ -219,13 +246,18 @@ QUnit.test("auto delete", async assert => {
|
||||
await timerType.expand();
|
||||
await timerType.selectRowByValue("delete");
|
||||
|
||||
assert.equal(futureDateInputSelector.header().title(), "Select a timeframe");
|
||||
assert.equal(futureDateInputSelector.header().label(), "Select a timeframe");
|
||||
assert.equal(futureDateInputSelector.header().value(), null);
|
||||
|
||||
await futureDateInputSelector.expand();
|
||||
await futureDateInputSelector.selectRowByValue("two_weeks");
|
||||
|
||||
assert.equal(futureDateInputSelector.header().title(), "Two Weeks");
|
||||
assert.ok(
|
||||
futureDateInputSelector
|
||||
.header()
|
||||
.label()
|
||||
.includes("Two Weeks")
|
||||
);
|
||||
assert.equal(futureDateInputSelector.header().value(), "two_weeks");
|
||||
|
||||
const regex = /will be automatically deleted/g;
|
||||
|
||||
@@ -26,7 +26,7 @@ QUnit.test("Updating topic notification level", async assert => {
|
||||
await notificationOptions.selectRowByValue("3");
|
||||
|
||||
assert.equal(
|
||||
notificationOptions.selectedRow().name(),
|
||||
notificationOptions.header().label(),
|
||||
"Watching",
|
||||
"it should display the right notification level"
|
||||
);
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
import selectKit from "helpers/select-kit-helper";
|
||||
import componentTest from "helpers/component-test";
|
||||
moduleForComponent("categories-admin-dropdown", { integration: true });
|
||||
|
||||
componentTest("default", {
|
||||
template: "{{categories-admin-dropdown}}",
|
||||
|
||||
async test(assert) {
|
||||
const subject = selectKit();
|
||||
|
||||
assert.equal(subject.el().find(".d-icon-bars").length, 1);
|
||||
|
||||
await subject.expand();
|
||||
|
||||
assert.equal(subject.rowByValue("create").name(), "New Category");
|
||||
}
|
||||
});
|
||||
@@ -1,81 +0,0 @@
|
||||
import selectKit from "helpers/select-kit-helper";
|
||||
import componentTest from "helpers/component-test";
|
||||
import Category from "discourse/models/category";
|
||||
|
||||
moduleForComponent("category-drop", {
|
||||
integration: true,
|
||||
beforeEach: function() {
|
||||
this.set("subject", selectKit());
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("subcatgories - no selection", {
|
||||
template:
|
||||
"{{category-drop onSelect=onSelect category=category parentCategory=parentCategory categories=childCategories subCategory=true noSubcategories=false}}",
|
||||
|
||||
beforeEach() {
|
||||
const parentCategory = Category.findById(2);
|
||||
|
||||
const childCategories = this.site.get("categoriesList").filter(c => {
|
||||
return c.get("parentCategory") === parentCategory;
|
||||
});
|
||||
|
||||
this.set("childCategories", childCategories);
|
||||
this.set("parentCategory", parentCategory);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
assert.equal(
|
||||
this.subject.header().title(),
|
||||
I18n.t("categories.all_subcategories")
|
||||
);
|
||||
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(
|
||||
this.subject.rowByIndex(0).name(),
|
||||
I18n.t("categories.no_subcategory")
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
this.subject.rowByIndex(1).name(),
|
||||
this.get("childCategories.firstObject.name")
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("subcatgories - selection", {
|
||||
template:
|
||||
"{{category-drop onSelect=onSelect category=category parentCategory=parentCategory categories=childCategories subCategory=true noSubcategories=false}}",
|
||||
|
||||
beforeEach() {
|
||||
const parentCategory = Category.findById(2);
|
||||
|
||||
const childCategories = this.site.get("categoriesList").filter(c => {
|
||||
return c.get("parentCategory") === parentCategory;
|
||||
});
|
||||
|
||||
this.set("childCategories", childCategories);
|
||||
this.set("category", childCategories.get("firstObject"));
|
||||
this.set("parentCategory", parentCategory);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
assert.equal(
|
||||
this.subject.header().title(),
|
||||
this.get("childCategories.firstObject.name")
|
||||
);
|
||||
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(
|
||||
this.subject.rowByIndex(0).name(),
|
||||
I18n.t("categories.all_subcategories")
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
this.subject.rowByIndex(1).name(),
|
||||
I18n.t("categories.no_subcategory")
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -1,81 +0,0 @@
|
||||
import selectKit from "helpers/select-kit-helper";
|
||||
import componentTest from "helpers/component-test";
|
||||
import Category from "discourse/models/category";
|
||||
|
||||
moduleForComponent("category-selector", {
|
||||
integration: true,
|
||||
beforeEach: function() {
|
||||
this.set("subject", selectKit());
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("default", {
|
||||
template: "{{category-selector categories=categories}}",
|
||||
|
||||
beforeEach() {
|
||||
this.set("categories", [Category.findById(2)]);
|
||||
},
|
||||
|
||||
test(assert) {
|
||||
assert.equal(this.subject.header().value(), 2);
|
||||
assert.notOk(
|
||||
this.subject.rowByValue(2).exists(),
|
||||
"selected categories are not in the list"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with blacklist", {
|
||||
template: "{{category-selector categories=categories blacklist=blacklist}}",
|
||||
|
||||
beforeEach() {
|
||||
this.set("categories", [Category.findById(2)]);
|
||||
this.set("blacklist", [Category.findById(8)]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.ok(
|
||||
this.subject.rowByValue(6).exists(),
|
||||
"not blacklisted categories are in the list"
|
||||
);
|
||||
assert.notOk(
|
||||
this.subject.rowByValue(8).exists(),
|
||||
"blacklisted categories are not in the list"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("interactions", {
|
||||
template: "{{category-selector categories=categories}}",
|
||||
|
||||
beforeEach() {
|
||||
this.set("categories", [Category.findById(2), Category.findById(6)]);
|
||||
},
|
||||
|
||||
skip: true,
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
await this.subject.selectRowByValue(8);
|
||||
|
||||
assert.equal(
|
||||
this.subject.header().value(),
|
||||
"2,6,8",
|
||||
"it adds the selected category"
|
||||
);
|
||||
assert.equal(this.categories.length, 3);
|
||||
|
||||
await this.subject.expand();
|
||||
|
||||
await this.subject.keyboard("backspace");
|
||||
await this.subject.keyboard("backspace");
|
||||
|
||||
assert.equal(
|
||||
this.subject.header().value(),
|
||||
"2,6",
|
||||
"it removes the last selected category"
|
||||
);
|
||||
assert.equal(this.categories.length, 2);
|
||||
}
|
||||
});
|
||||
@@ -1,209 +0,0 @@
|
||||
import selectKit from "helpers/select-kit-helper";
|
||||
import componentTest from "helpers/component-test";
|
||||
|
||||
moduleForComponent("combo-box", {
|
||||
integration: true,
|
||||
beforeEach: function() {
|
||||
this.set("subject", selectKit());
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("default", {
|
||||
template: "{{combo-box content=items}}",
|
||||
beforeEach() {
|
||||
this.set("items", [
|
||||
{ id: 1, name: "hello" },
|
||||
{ id: 2, name: "world" }
|
||||
]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(this.subject.header().name(), "hello");
|
||||
assert.equal(this.subject.rowByValue(1).name(), "hello");
|
||||
assert.equal(this.subject.rowByValue(2).name(), "world");
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with valueAttribute", {
|
||||
template: '{{combo-box content=items valueAttribute="value"}}',
|
||||
beforeEach() {
|
||||
this.set("items", [
|
||||
{ value: 0, name: "hello" },
|
||||
{ value: 1, name: "world" }
|
||||
]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(this.subject.rowByValue(0).name(), "hello");
|
||||
assert.equal(this.subject.rowByValue(1).name(), "world");
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with nameProperty", {
|
||||
template: '{{combo-box content=items nameProperty="text"}}',
|
||||
beforeEach() {
|
||||
this.set("items", [
|
||||
{ id: 0, text: "hello" },
|
||||
{ id: 1, text: "world" }
|
||||
]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(this.subject.rowByValue(0).name(), "hello");
|
||||
assert.equal(this.subject.rowByValue(1).name(), "world");
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with an array as content", {
|
||||
template: "{{combo-box content=items value=value}}",
|
||||
beforeEach() {
|
||||
this.set("items", ["evil", "trout", "hat"]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(this.subject.rowByValue("evil").name(), "evil");
|
||||
assert.equal(this.subject.rowByValue("trout").name(), "trout");
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with value and none as a string", {
|
||||
template: '{{combo-box content=items none="test.none" value=value}}',
|
||||
beforeEach() {
|
||||
I18n.translations[I18n.locale].js.test = { none: "none" };
|
||||
this.set("items", ["evil", "trout", "hat"]);
|
||||
this.set("value", "trout");
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(this.subject.noneRow().name(), "none");
|
||||
assert.equal(this.subject.rowByValue("evil").name(), "evil");
|
||||
assert.equal(this.subject.rowByValue("trout").name(), "trout");
|
||||
assert.equal(this.subject.header().name(), "trout");
|
||||
assert.equal(this.value, "trout");
|
||||
|
||||
await this.subject.selectNoneRow();
|
||||
|
||||
assert.equal(this.value, null);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with value and none as an object", {
|
||||
template: "{{combo-box content=items none=none value=value}}",
|
||||
beforeEach() {
|
||||
this.set("none", { id: "something", name: "none" });
|
||||
this.set("items", ["evil", "trout", "hat"]);
|
||||
this.set("value", "evil");
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(this.subject.noneRow().name(), "none");
|
||||
assert.equal(this.subject.rowByValue("evil").name(), "evil");
|
||||
assert.equal(this.subject.rowByValue("trout").name(), "trout");
|
||||
assert.equal(this.subject.header().name(), "evil");
|
||||
assert.equal(this.value, "evil");
|
||||
|
||||
await this.subject.selectNoneRow();
|
||||
|
||||
assert.equal(this.value, null);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with no value and none as an object", {
|
||||
template: "{{combo-box content=items none=none value=value}}",
|
||||
beforeEach() {
|
||||
I18n.translations[I18n.locale].js.test = { none: "none" };
|
||||
this.set("none", { id: "something", name: "none" });
|
||||
this.set("items", ["evil", "trout", "hat"]);
|
||||
this.set("value", null);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(this.subject.header().name(), "none");
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with no value and none string", {
|
||||
template: "{{combo-box content=items none=none value=value}}",
|
||||
beforeEach() {
|
||||
I18n.translations[I18n.locale].js.test = { none: "none" };
|
||||
this.set("none", "test.none");
|
||||
this.set("items", ["evil", "trout", "hat"]);
|
||||
this.set("value", null);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(this.subject.header().name(), "none");
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with no value and no none", {
|
||||
template: "{{combo-box content=items value=value}}",
|
||||
beforeEach() {
|
||||
this.set("items", ["evil", "trout", "hat"]);
|
||||
this.set("value", null);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(
|
||||
this.subject.header().name(),
|
||||
"evil",
|
||||
"it sets the first row as value"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with empty string as value", {
|
||||
template: "{{combo-box content=items value=value}}",
|
||||
beforeEach() {
|
||||
this.set("items", ["evil", "trout", "hat"]);
|
||||
this.set("value", "");
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(
|
||||
this.subject.header().name(),
|
||||
"evil",
|
||||
"it sets the first row as value"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with noneLabel", {
|
||||
template:
|
||||
"{{combo-box content=items allowAutoSelectFirst=false noneLabel=noneLabel}}",
|
||||
beforeEach() {
|
||||
I18n.translations[I18n.locale].js.test = { none: "none" };
|
||||
this.set("items", ["evil", "trout", "hat"]);
|
||||
this.set("noneLabel", "test.none");
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(
|
||||
this.subject.header().name(),
|
||||
"none",
|
||||
"it displays noneLabel as the header name"
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -1,94 +0,0 @@
|
||||
import selectKit from "helpers/select-kit-helper";
|
||||
import componentTest from "helpers/component-test";
|
||||
|
||||
moduleForComponent("list-setting", { integration: true });
|
||||
|
||||
componentTest("default", {
|
||||
template: "{{list-setting settingValue=settingValue choices=choices}}",
|
||||
|
||||
beforeEach() {
|
||||
this.set("settingValue", "bold|italic");
|
||||
this.set("choices", ["bold", "italic", "underline"]);
|
||||
},
|
||||
|
||||
test(assert) {
|
||||
assert.equal(
|
||||
selectKit()
|
||||
.header()
|
||||
.title(),
|
||||
"bold,italic"
|
||||
);
|
||||
assert.equal(
|
||||
selectKit()
|
||||
.header()
|
||||
.value(),
|
||||
"bold,italic"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with empty string as value", {
|
||||
template: "{{list-setting settingValue=settingValue}}",
|
||||
|
||||
beforeEach() {
|
||||
this.set("settingValue", "");
|
||||
},
|
||||
|
||||
test(assert) {
|
||||
assert.equal(
|
||||
selectKit()
|
||||
.header()
|
||||
.value(),
|
||||
""
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with only setting value", {
|
||||
template: "{{list-setting settingValue=settingValue}}",
|
||||
|
||||
beforeEach() {
|
||||
this.set("settingValue", "bold|italic");
|
||||
},
|
||||
|
||||
test(assert) {
|
||||
assert.equal(
|
||||
selectKit()
|
||||
.header()
|
||||
.value(),
|
||||
"bold,italic"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("interactions", {
|
||||
template: "{{list-setting settingValue=settingValue choices=choices}}",
|
||||
|
||||
beforeEach() {
|
||||
this.set("settingValue", "bold|italic");
|
||||
this.set("choices", ["bold", "italic", "underline"]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
const listSetting = selectKit();
|
||||
|
||||
await listSetting.expand();
|
||||
await listSetting.selectRowByValue("underline");
|
||||
|
||||
assert.equal(listSetting.header().value(), "bold,italic,underline");
|
||||
|
||||
await listSetting.expand();
|
||||
await listSetting.fillInFilter("strike");
|
||||
|
||||
assert.equal(listSetting.highlightedRow().value(), "strike");
|
||||
|
||||
await listSetting.keyboard("enter");
|
||||
|
||||
assert.equal(listSetting.header().value(), "bold,italic,underline,strike");
|
||||
|
||||
await listSetting.keyboard("backspace");
|
||||
await listSetting.keyboard("backspace");
|
||||
|
||||
assert.equal(listSetting.header().value(), "bold,italic,underline");
|
||||
}
|
||||
});
|
||||
@@ -1,121 +0,0 @@
|
||||
import selectKit from "helpers/select-kit-helper";
|
||||
import componentTest from "helpers/component-test";
|
||||
|
||||
moduleForComponent("mini-tag-chooser", {
|
||||
integration: true,
|
||||
beforeEach: function() {
|
||||
this.set("subject", selectKit());
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("default", {
|
||||
template: "{{mini-tag-chooser allowAny=true filterable=true tags=tags}}",
|
||||
|
||||
beforeEach() {
|
||||
this.siteSettings.max_tag_length = 24;
|
||||
this.siteSettings.force_lowercase_tags = true;
|
||||
this.siteSettings.tags_sort_alphabetically = true;
|
||||
|
||||
this.site.set("can_create_tag", true);
|
||||
this.set("tags", ["jeff", "neil", "arpit"]);
|
||||
|
||||
const response = object => {
|
||||
return [200, { "Content-Type": "application/json" }, object];
|
||||
};
|
||||
|
||||
// prettier-ignore
|
||||
server.get("/tags/filter/search", (params) => { //eslint-disable-line
|
||||
if (params.queryParams.q === "régis") {
|
||||
return response({
|
||||
results: [{ text: "régis", count: 5 }]
|
||||
});
|
||||
}
|
||||
|
||||
if (params.queryParams.q.toLowerCase() === "joffrey" || params.queryParams.q === "invalid'tag" || params.queryParams.q === "01234567890123456789012345") {
|
||||
return response({results: []});
|
||||
}
|
||||
|
||||
return response({
|
||||
results: [{ text: "penar", count: 3 }, { text: "bianca", count: 3 }, { text: "régis", count: 5 }]
|
||||
});
|
||||
});
|
||||
},
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(
|
||||
this.subject.rowByIndex(0).name(),
|
||||
"bianca",
|
||||
"it has the correct tag"
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
this.subject.rowByIndex(1).name(),
|
||||
"penar",
|
||||
"it has the correct tag at the correct position after alphabetical sorting"
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
this.subject.rowByIndex(2).name(),
|
||||
"régis",
|
||||
"it has the correct tag"
|
||||
);
|
||||
|
||||
await this.subject.fillInFilter("régis");
|
||||
await this.subject.keyboard("enter");
|
||||
assert.deepEqual(
|
||||
this.tags,
|
||||
["jeff", "neil", "arpit", "régis"],
|
||||
"it selects the tag"
|
||||
);
|
||||
|
||||
await this.subject.expand();
|
||||
await this.subject.fillInFilter("joffrey");
|
||||
await this.subject.keyboard("enter");
|
||||
assert.deepEqual(
|
||||
this.tags,
|
||||
["jeff", "neil", "arpit", "régis", "joffrey"],
|
||||
"it creates the tag"
|
||||
);
|
||||
|
||||
await this.subject.expand();
|
||||
await this.subject.fillInFilter("Joffrey");
|
||||
await this.subject.keyboard("enter");
|
||||
await this.subject.collapse();
|
||||
assert.deepEqual(
|
||||
this.tags,
|
||||
["jeff", "neil", "arpit", "régis", "joffrey"],
|
||||
"it does not allow case insensitive duplicate tags"
|
||||
);
|
||||
|
||||
await this.subject.expand();
|
||||
await this.subject.fillInFilter("invalid' Tag");
|
||||
await this.subject.keyboard("enter");
|
||||
assert.deepEqual(
|
||||
this.tags,
|
||||
["jeff", "neil", "arpit", "régis", "joffrey", "invalid-tag"],
|
||||
"it strips invalid characters in tag"
|
||||
);
|
||||
|
||||
await this.subject.expand();
|
||||
await this.subject.fillInFilter("01234567890123456789012345");
|
||||
await this.subject.keyboard("enter");
|
||||
assert.deepEqual(
|
||||
this.tags,
|
||||
["jeff", "neil", "arpit", "régis", "joffrey", "invalid-tag"],
|
||||
"it does not allow creating long tags"
|
||||
);
|
||||
|
||||
await click(
|
||||
this.subject
|
||||
.el()
|
||||
.find(".selected-tag")
|
||||
.last()
|
||||
);
|
||||
assert.deepEqual(
|
||||
this.tags,
|
||||
["jeff", "neil", "arpit", "régis", "joffrey"],
|
||||
"it removes the tag"
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -1,323 +0,0 @@
|
||||
import selectKit from "helpers/select-kit-helper";
|
||||
import componentTest from "helpers/component-test";
|
||||
import { withPluginApi } from "discourse/lib/plugin-api";
|
||||
import { clearCallbacks } from "select-kit/mixins/plugin-api";
|
||||
|
||||
moduleForComponent("multi-select", {
|
||||
integration: true,
|
||||
beforeEach: function() {
|
||||
this.set("subject", selectKit());
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with objects and values", {
|
||||
template: "{{multi-select content=items values=values}}",
|
||||
|
||||
beforeEach() {
|
||||
this.set("items", [
|
||||
{ id: 1, name: "hello" },
|
||||
{ id: 2, name: "world" }
|
||||
]);
|
||||
this.set("values", [1, 2]);
|
||||
},
|
||||
|
||||
test(assert) {
|
||||
assert.equal(this.subject.header().value(), "1,2");
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with title", {
|
||||
template: '{{multi-select title=(i18n "test.title")}}',
|
||||
|
||||
beforeEach() {
|
||||
I18n.translations[I18n.locale].js.test = { title: "My title" };
|
||||
},
|
||||
|
||||
test(assert) {
|
||||
assert.equal(
|
||||
selectKit()
|
||||
.header()
|
||||
.title(),
|
||||
"My title"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("interactions", {
|
||||
template: "{{multi-select none=none content=items values=values}}",
|
||||
|
||||
beforeEach() {
|
||||
I18n.translations[I18n.locale].js.test = { none: "none" };
|
||||
this.set("items", [
|
||||
{ id: 1, name: "regis" },
|
||||
{ id: 2, name: "sam" },
|
||||
{ id: 3, name: "robin" }
|
||||
]);
|
||||
this.set("values", [1, 2]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(
|
||||
this.subject.highlightedRow().name(),
|
||||
"robin",
|
||||
"it highlights the first content row"
|
||||
);
|
||||
|
||||
await this.set("none", "test.none");
|
||||
|
||||
assert.ok(this.subject.noneRow().exists());
|
||||
assert.equal(
|
||||
this.subject.highlightedRow().name(),
|
||||
"robin",
|
||||
"it highlights the first content row"
|
||||
);
|
||||
|
||||
await this.subject.selectRowByValue(3);
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(
|
||||
this.subject.highlightedRow().name(),
|
||||
"none",
|
||||
"it highlights none row if no content"
|
||||
);
|
||||
|
||||
await this.subject.fillInFilter("joffrey");
|
||||
|
||||
assert.equal(
|
||||
this.subject.highlightedRow().name(),
|
||||
"joffrey",
|
||||
"it highlights create row when filling filter"
|
||||
);
|
||||
|
||||
await this.subject.keyboard("enter");
|
||||
|
||||
assert.equal(
|
||||
this.subject.highlightedRow().name(),
|
||||
"none",
|
||||
"it highlights none row after creating content and no content left"
|
||||
);
|
||||
|
||||
await this.subject.keyboard("backspace");
|
||||
|
||||
const $lastSelectedName = this.subject
|
||||
.header()
|
||||
.el()
|
||||
.find(".selected-name")
|
||||
.last();
|
||||
assert.equal($lastSelectedName.attr("data-name"), "joffrey");
|
||||
assert.ok(
|
||||
$lastSelectedName.hasClass("is-highlighted"),
|
||||
"it highlights the last selected name when using backspace"
|
||||
);
|
||||
|
||||
await this.subject.keyboard("backspace");
|
||||
|
||||
const $lastSelectedName1 = this.subject
|
||||
.header()
|
||||
.el()
|
||||
.find(".selected-name")
|
||||
.last();
|
||||
assert.equal(
|
||||
$lastSelectedName1.attr("data-name"),
|
||||
"robin",
|
||||
"it removes the previous highlighted selected content"
|
||||
);
|
||||
assert.notOk(
|
||||
this.subject.rowByValue("joffrey").exists(),
|
||||
"generated content shouldn’t appear in content when removed"
|
||||
);
|
||||
|
||||
await this.subject.keyboard("selectAll");
|
||||
|
||||
const $highlightedSelectedNames2 = this.subject
|
||||
.header()
|
||||
.el()
|
||||
.find(".selected-name.is-highlighted");
|
||||
assert.equal(
|
||||
$highlightedSelectedNames2.length,
|
||||
3,
|
||||
"it highlights each selected name"
|
||||
);
|
||||
|
||||
await this.subject.keyboard("backspace");
|
||||
|
||||
const $selectedNames = this.subject
|
||||
.header()
|
||||
.el()
|
||||
.find(".selected-name");
|
||||
assert.equal($selectedNames.length, 0, "it removed all selected content");
|
||||
|
||||
assert.ok(this.subject.isFocused());
|
||||
assert.ok(this.subject.isExpanded());
|
||||
|
||||
await this.subject.keyboard("escape");
|
||||
|
||||
assert.ok(this.subject.isFocused());
|
||||
assert.notOk(this.subject.isExpanded());
|
||||
|
||||
await this.subject.keyboard("escape");
|
||||
|
||||
assert.notOk(this.subject.isFocused());
|
||||
assert.notOk(this.subject.isExpanded());
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with limitMatches", {
|
||||
template: "{{multi-select content=content limitMatches=2}}",
|
||||
|
||||
beforeEach() {
|
||||
this.set("content", ["sam", "jeff", "neil"]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(this.subject.el().find(".select-kit-row").length, 2);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with minimum", {
|
||||
template: "{{multi-select content=content minimum=1}}",
|
||||
|
||||
beforeEach() {
|
||||
this.set("content", ["sam", "jeff", "neil"]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(this.subject.validationMessage(), "Select at least 1 item.");
|
||||
|
||||
await this.subject.selectRowByValue("sam");
|
||||
|
||||
assert.equal(this.subject.header().label(), "sam");
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with minimumLabel", {
|
||||
template:
|
||||
'{{multi-select content=content minimum=1 minimumLabel="test.minimum"}}',
|
||||
|
||||
beforeEach() {
|
||||
I18n.translations[I18n.locale].js.test = { minimum: "min %{count}" };
|
||||
this.set("content", ["sam", "jeff", "neil"]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(this.subject.validationMessage(), "min 1");
|
||||
|
||||
await this.subject.selectRowByValue("jeff");
|
||||
|
||||
assert.equal(this.subject.header().label(), "jeff");
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with forceEscape", {
|
||||
template: "{{multi-select content=content forceEscape=true}}",
|
||||
|
||||
beforeEach() {
|
||||
this.set("content", ["<div>sam</div>"]);
|
||||
},
|
||||
skip: true,
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
const row = this.subject.rowByIndex(0);
|
||||
assert.equal(
|
||||
row
|
||||
.el()
|
||||
.find(".name")
|
||||
.html()
|
||||
.trim(),
|
||||
"<div>sam</div>"
|
||||
);
|
||||
|
||||
await this.subject.fillInFilter("<div>jeff</div>");
|
||||
await this.subject.keyboard("enter");
|
||||
|
||||
assert.equal(
|
||||
this.subject
|
||||
.header()
|
||||
.el()
|
||||
.find(".name")
|
||||
.html()
|
||||
.trim(),
|
||||
"<div>jeff</div>"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with forceEscape", {
|
||||
template: "{{multi-select content=content forceEscape=false}}",
|
||||
|
||||
beforeEach() {
|
||||
this.set("content", ["<div>sam</div>"]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
const row = this.subject.rowByIndex(0);
|
||||
assert.equal(
|
||||
row
|
||||
.el()
|
||||
.find(".name")
|
||||
.html()
|
||||
.trim(),
|
||||
"<div>sam</div>"
|
||||
);
|
||||
|
||||
await this.subject.fillInFilter("<div>jeff</div>");
|
||||
await this.subject.keyboard("enter");
|
||||
|
||||
assert.equal(
|
||||
this.subject
|
||||
.header()
|
||||
.el()
|
||||
.find(".name")
|
||||
.html()
|
||||
.trim(),
|
||||
"<div>jeff</div>"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("support modifying on select behavior through plugin api", {
|
||||
template:
|
||||
'<span class="on-select-test"></span>{{multi-select content=content}}',
|
||||
|
||||
beforeEach() {
|
||||
withPluginApi("0.8.13", api => {
|
||||
api.modifySelectKit("select-kit").onSelect((context, value) => {
|
||||
find(".on-select-test").html(value);
|
||||
});
|
||||
});
|
||||
|
||||
this.set("content", [
|
||||
{ id: "1", name: "robin" },
|
||||
{ id: "2", name: "arpit", __sk_row_type: "noopRow" }
|
||||
]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
await this.subject.selectRowByValue(1);
|
||||
|
||||
assert.equal(find(".on-select-test").html(), "1");
|
||||
|
||||
await this.subject.expand();
|
||||
await this.subject.selectRowByValue(2);
|
||||
|
||||
assert.equal(
|
||||
find(".on-select-test").html(),
|
||||
"2",
|
||||
"it calls onSelect for noopRows"
|
||||
);
|
||||
|
||||
clearCallbacks();
|
||||
}
|
||||
});
|
||||
+37
-30
@@ -1,25 +1,34 @@
|
||||
import selectKit from "helpers/select-kit-helper";
|
||||
import componentTest from "helpers/component-test";
|
||||
import { testSelectKitModule } from "./select-kit-test-helper";
|
||||
|
||||
moduleForComponent("category-chooser", {
|
||||
integration: true,
|
||||
beforeEach: function() {
|
||||
this.set("subject", selectKit());
|
||||
}
|
||||
});
|
||||
testSelectKitModule("category-chooser");
|
||||
|
||||
function template(options = []) {
|
||||
return `
|
||||
{{category-chooser
|
||||
value=value
|
||||
options=(hash
|
||||
${options.join("\n")}
|
||||
)
|
||||
}}
|
||||
`;
|
||||
}
|
||||
|
||||
componentTest("with value", {
|
||||
template: "{{category-chooser value=2}}",
|
||||
template: template(),
|
||||
|
||||
test(assert) {
|
||||
beforeEach() {
|
||||
this.set("value", 2);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
assert.equal(this.subject.header().value(), 2);
|
||||
assert.equal(this.subject.header().title(), "feature");
|
||||
assert.equal(this.subject.header().label(), "feature");
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with excludeCategoryId", {
|
||||
template: "{{category-chooser excludeCategoryId=2}}",
|
||||
|
||||
template: template(["excludeCategoryId=2"]),
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
@@ -28,7 +37,7 @@ componentTest("with excludeCategoryId", {
|
||||
});
|
||||
|
||||
componentTest("with scopedCategoryId", {
|
||||
template: "{{category-chooser scopedCategoryId=2}}",
|
||||
template: template(["scopedCategoryId=2"]),
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
@@ -52,7 +61,7 @@ componentTest("with scopedCategoryId", {
|
||||
});
|
||||
|
||||
componentTest("with allowUncategorized=null", {
|
||||
template: "{{category-chooser allowUncategorized=null}}",
|
||||
template: template(["allowUncategorized=null"]),
|
||||
|
||||
beforeEach() {
|
||||
this.siteSettings.allow_uncategorized_topics = false;
|
||||
@@ -60,12 +69,12 @@ componentTest("with allowUncategorized=null", {
|
||||
|
||||
test(assert) {
|
||||
assert.equal(this.subject.header().value(), null);
|
||||
assert.equal(this.subject.header().title(), "category");
|
||||
assert.equal(this.subject.header().label(), "category…");
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with allowUncategorized=null rootNone=true", {
|
||||
template: "{{category-chooser allowUncategorized=null rootNone=true}}",
|
||||
template: template(["allowUncategorized=null", "none=true"]),
|
||||
|
||||
beforeEach() {
|
||||
this.siteSettings.allow_uncategorized_topics = false;
|
||||
@@ -73,13 +82,12 @@ componentTest("with allowUncategorized=null rootNone=true", {
|
||||
|
||||
test(assert) {
|
||||
assert.equal(this.subject.header().value(), null);
|
||||
assert.equal(this.subject.header().title(), "(no category)");
|
||||
assert.equal(this.subject.header().label(), "(no category)");
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with disallowed uncategorized, rootNone and rootNoneLabel", {
|
||||
template:
|
||||
'{{category-chooser allowUncategorized=null rootNone=true rootNoneLabel="test.root"}}',
|
||||
componentTest("with disallowed uncategorized, none", {
|
||||
template: template(["allowUncategorized=null", "none='test.root'"]),
|
||||
|
||||
beforeEach() {
|
||||
I18n.translations[I18n.locale].js.test = { root: "root none label" };
|
||||
@@ -88,12 +96,12 @@ componentTest("with disallowed uncategorized, rootNone and rootNoneLabel", {
|
||||
|
||||
test(assert) {
|
||||
assert.equal(this.subject.header().value(), null);
|
||||
assert.equal(this.subject.header().title(), "root none label");
|
||||
assert.equal(this.subject.header().label(), "root none label");
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with allowed uncategorized", {
|
||||
template: "{{category-chooser allowUncategorized=true}}",
|
||||
template: template(["allowUncategorized=true"]),
|
||||
|
||||
beforeEach() {
|
||||
this.siteSettings.allow_uncategorized_topics = true;
|
||||
@@ -101,12 +109,12 @@ componentTest("with allowed uncategorized", {
|
||||
|
||||
test(assert) {
|
||||
assert.equal(this.subject.header().value(), null);
|
||||
assert.equal(this.subject.header().title(), "uncategorized");
|
||||
assert.equal(this.subject.header().label(), "uncategorized");
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with allowed uncategorized and rootNone", {
|
||||
template: "{{category-chooser allowUncategorized=true rootNone=true}}",
|
||||
componentTest("with allowed uncategorized and none=true", {
|
||||
template: template(["allowUncategorized=true", "none=true"]),
|
||||
|
||||
beforeEach() {
|
||||
this.siteSettings.allow_uncategorized_topics = true;
|
||||
@@ -114,13 +122,12 @@ componentTest("with allowed uncategorized and rootNone", {
|
||||
|
||||
test(assert) {
|
||||
assert.equal(this.subject.header().value(), null);
|
||||
assert.equal(this.subject.header().title(), "(no category)");
|
||||
assert.equal(this.subject.header().label(), "(no category)");
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with allowed uncategorized rootNone and rootNoneLabel", {
|
||||
template:
|
||||
'{{category-chooser allowUncategorized=true rootNone=true rootNoneLabel="test.root"}}',
|
||||
componentTest("with allowed uncategorized and none", {
|
||||
template: template(["allowUncategorized=true", "none='test.root'"]),
|
||||
|
||||
beforeEach() {
|
||||
I18n.translations[I18n.locale].js.test = { root: "root none label" };
|
||||
@@ -129,6 +136,6 @@ componentTest("with allowed uncategorized rootNone and rootNoneLabel", {
|
||||
|
||||
test(assert) {
|
||||
assert.equal(this.subject.header().value(), null);
|
||||
assert.equal(this.subject.header().title(), "root none label");
|
||||
assert.equal(this.subject.header().label(), "root none label");
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,336 @@
|
||||
import Category from "discourse/models/category";
|
||||
import componentTest from "helpers/component-test";
|
||||
import { testSelectKitModule } from "./select-kit-test-helper";
|
||||
import {
|
||||
NO_CATEGORIES_ID,
|
||||
ALL_CATEGORIES_ID
|
||||
} from "select-kit/components/category-drop";
|
||||
|
||||
testSelectKitModule("category-drop");
|
||||
|
||||
function initCategories(context) {
|
||||
const categories = context.site.categoriesList;
|
||||
context.setProperties({
|
||||
category: categories.firstObject,
|
||||
categories
|
||||
});
|
||||
}
|
||||
|
||||
function initCategoriesWithParentCategory(context) {
|
||||
const parentCategory = Category.findById(2);
|
||||
const childCategories = context.site.categoriesList.filter(c => {
|
||||
return c.parentCategory === parentCategory;
|
||||
});
|
||||
|
||||
context.setProperties({
|
||||
parentCategory,
|
||||
category: null,
|
||||
categories: childCategories
|
||||
});
|
||||
}
|
||||
|
||||
function template(options = []) {
|
||||
return `
|
||||
{{category-drop
|
||||
category=category
|
||||
categories=categories
|
||||
parentCategory=parentCategory
|
||||
options=(hash
|
||||
${options.join("\n")}
|
||||
)
|
||||
}}
|
||||
`;
|
||||
}
|
||||
|
||||
componentTest("caretUpIcon", {
|
||||
template: `
|
||||
{{category-drop
|
||||
category=value
|
||||
categories=content
|
||||
}}
|
||||
`,
|
||||
|
||||
async test(assert) {
|
||||
const $header = this.subject.header().el();
|
||||
|
||||
assert.ok(
|
||||
exists($header.find(`.d-icon-caret-right`)),
|
||||
"it uses the correct default icon"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("none", {
|
||||
template: `
|
||||
{{category-drop
|
||||
category=value
|
||||
categories=content
|
||||
}}
|
||||
`,
|
||||
|
||||
async test(assert) {
|
||||
const text = this.subject.header().label();
|
||||
assert.equal(
|
||||
text,
|
||||
I18n.t("category.all").toLowerCase(),
|
||||
"it uses the noneLabel"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("[not staff - TL0] displayCategoryDescription", {
|
||||
template: template(),
|
||||
|
||||
beforeEach() {
|
||||
Ember.set(this.currentUser, "staff", false);
|
||||
Ember.set(this.currentUser, "trustLevel", 0);
|
||||
|
||||
initCategories(this);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
const row = this.subject.rowByValue(this.category.id);
|
||||
assert.ok(
|
||||
exists(row.el().find(".category-desc")),
|
||||
"it shows category description for newcomers"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("[not staff - TL1] displayCategoryDescription", {
|
||||
template: template(),
|
||||
|
||||
beforeEach() {
|
||||
Ember.set(this.currentUser, "staff", false);
|
||||
Ember.set(this.currentUser, "trustLevel", 1);
|
||||
|
||||
initCategories(this);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
const row = this.subject.rowByValue(this.category.id);
|
||||
assert.ok(
|
||||
exists(row.el().find(".category-desc")),
|
||||
"it doesn't show category description for TL0+"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("[staff - TL0] displayCategoryDescription", {
|
||||
template: template(),
|
||||
|
||||
beforeEach() {
|
||||
Ember.set(this.currentUser, "staff", true);
|
||||
Ember.set(this.currentUser, "trustLevel", 0);
|
||||
|
||||
initCategories(this);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
const row = this.subject.rowByValue(this.category.id);
|
||||
assert.ok(
|
||||
exists(row.el().find(".category-desc")),
|
||||
"it doesn't show category description for staff"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("hideParentCategory (default: false)", {
|
||||
template: template(),
|
||||
|
||||
beforeEach() {
|
||||
initCategories(this);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
const row = this.subject.rowByValue(this.category.id);
|
||||
assert.equal(row.value(), this.category.id);
|
||||
assert.equal(this.category.parent_category_id, null);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("hideParentCategory (true)", {
|
||||
template: template(["hideParentCategory=true"]),
|
||||
|
||||
beforeEach() {
|
||||
initCategoriesWithParentCategory(this);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
const parentRow = this.subject.rowByValue(this.parentCategory.id);
|
||||
assert.notOk(parentRow.exists(), "the parent row is not showing");
|
||||
|
||||
const childCategory = this.categories.firstObject;
|
||||
const childCategoryId = childCategory.id;
|
||||
const childRow = this.subject.rowByValue(childCategoryId);
|
||||
assert.ok(childRow.exists(), "the child row is showing");
|
||||
|
||||
const $categoryStatus = childRow.el().find(".category-status");
|
||||
assert.ok(
|
||||
$categoryStatus
|
||||
.text()
|
||||
.trim()
|
||||
.match(/^spec/)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("allowUncategorized (default: true)", {
|
||||
template: template(),
|
||||
|
||||
beforeEach() {
|
||||
initCategories(this);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
const uncategorizedCategoryId = this.site.uncategorized_category_id;
|
||||
const row = this.subject.rowByValue(uncategorizedCategoryId);
|
||||
assert.ok(row.exists(), "the uncategorized row is showing");
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("allowUncategorized (false)", {
|
||||
template: template(["allowUncategorized=false"]),
|
||||
|
||||
beforeEach() {
|
||||
initCategories(this);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
const uncategorizedCategoryId = this.site.uncategorized_category_id;
|
||||
const row = this.subject.rowByValue(uncategorizedCategoryId);
|
||||
assert.notOk(row.exists(), "the uncategorized row is not showing");
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("countSubcategories (default: false)", {
|
||||
template: template(),
|
||||
|
||||
beforeEach() {
|
||||
initCategories(this);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
const category = Category.findById(7);
|
||||
const row = this.subject.rowByValue(category.id);
|
||||
const topicCount = row
|
||||
.el()
|
||||
.find(".topic-count")
|
||||
.text()
|
||||
.trim();
|
||||
|
||||
assert.equal(
|
||||
topicCount,
|
||||
"× 481",
|
||||
"it doesn't include the topic count of subcategories"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("countSubcategories (true)", {
|
||||
template: template(["countSubcategories=true"]),
|
||||
|
||||
beforeEach() {
|
||||
initCategories(this);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
const category = Category.findById(7);
|
||||
const row = this.subject.rowByValue(category.id);
|
||||
const topicCount = row
|
||||
.el()
|
||||
.find(".topic-count")
|
||||
.text()
|
||||
.trim();
|
||||
|
||||
assert.equal(
|
||||
topicCount,
|
||||
"× 584",
|
||||
"it includes the topic count of subcategories"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("shortcuts:default", {
|
||||
template: template(),
|
||||
|
||||
beforeEach() {
|
||||
initCategories(this);
|
||||
this.set("category", null);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(
|
||||
this.subject.rowByIndex(0).value(),
|
||||
this.categories.firstObject.id,
|
||||
"Shortcuts are not prepended when no category is selected"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("shortcuts:category is set", {
|
||||
template: template(),
|
||||
|
||||
beforeEach() {
|
||||
initCategories(this);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(this.subject.rowByIndex(0).value(), ALL_CATEGORIES_ID);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("shortcuts with parentCategory/subCategory=true:default", {
|
||||
template: template(["subCategory=true"]),
|
||||
|
||||
beforeEach() {
|
||||
initCategoriesWithParentCategory(this);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(this.subject.rowByIndex(0).value(), NO_CATEGORIES_ID);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest(
|
||||
"shortcuts with parentCategory/subCategory=true:category is selected",
|
||||
{
|
||||
template: template(["subCategory=true"]),
|
||||
|
||||
beforeEach() {
|
||||
initCategoriesWithParentCategory(this);
|
||||
this.set("category", this.categories.firstObject);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(this.subject.rowByIndex(0).value(), ALL_CATEGORIES_ID);
|
||||
assert.equal(this.subject.rowByIndex(1).value(), NO_CATEGORIES_ID);
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -0,0 +1,102 @@
|
||||
import selectKit from "helpers/select-kit-helper";
|
||||
import componentTest from "helpers/component-test";
|
||||
|
||||
moduleForComponent("select-kit/combo-box", {
|
||||
integration: true,
|
||||
beforeEach() {
|
||||
this.set("subject", selectKit());
|
||||
}
|
||||
});
|
||||
|
||||
const DEFAULT_CONTENT = [
|
||||
{ id: 1, name: "foo" },
|
||||
{ id: 2, name: "bar" },
|
||||
{ id: 3, name: "baz" }
|
||||
];
|
||||
|
||||
const DEFAULT_VALUE = 1;
|
||||
|
||||
const setDefaultState = (ctx, options) => {
|
||||
const properties = Object.assign(
|
||||
{
|
||||
content: DEFAULT_CONTENT,
|
||||
value: DEFAULT_VALUE
|
||||
},
|
||||
options || {}
|
||||
);
|
||||
ctx.setProperties(properties);
|
||||
};
|
||||
|
||||
componentTest("options.clearable", {
|
||||
template: `
|
||||
{{combo-box
|
||||
value=value
|
||||
content=content
|
||||
onChange=onChange
|
||||
options=(hash clearable=clearable)
|
||||
}}
|
||||
`,
|
||||
|
||||
beforeEach() {
|
||||
setDefaultState(this, {
|
||||
clearable: true,
|
||||
onChange: value => {
|
||||
this.set("value", value);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
const $header = this.subject.header();
|
||||
|
||||
assert.ok(
|
||||
exists($header.el().find(".btn-clear")),
|
||||
"it shows the clear button"
|
||||
);
|
||||
assert.equal($header.value(), DEFAULT_VALUE);
|
||||
|
||||
await click($header.el().find(".btn-clear"));
|
||||
|
||||
assert.notOk(
|
||||
exists($header.el().find(".btn-clear")),
|
||||
"it hides the clear button"
|
||||
);
|
||||
assert.equal($header.value(), null);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("options.{caretUpIcon,caretDownIcon}", {
|
||||
template: `
|
||||
{{combo-box
|
||||
value=value
|
||||
content=content
|
||||
options=(hash
|
||||
caretUpIcon=caretUpIcon
|
||||
caretDownIcon=caretDownIcon
|
||||
)
|
||||
}}
|
||||
`,
|
||||
|
||||
beforeEach() {
|
||||
setDefaultState(this, {
|
||||
caretUpIcon: "pencil-alt",
|
||||
caretDownIcon: "trash-alt"
|
||||
});
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
const $header = this.subject.header().el();
|
||||
|
||||
assert.ok(
|
||||
exists($header.find(`.d-icon-${this.caretDownIcon}`)),
|
||||
"it uses the icon provided"
|
||||
);
|
||||
|
||||
await this.subject.expand();
|
||||
|
||||
assert.ok(
|
||||
exists($header.find(`.d-icon-${this.caretUpIcon}`)),
|
||||
"it uses the icon provided"
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,111 @@
|
||||
import selectKit from "helpers/select-kit-helper";
|
||||
import componentTest from "helpers/component-test";
|
||||
|
||||
moduleForComponent("select-kit/dropdown-select-box", {
|
||||
integration: true,
|
||||
beforeEach() {
|
||||
this.set("subject", selectKit());
|
||||
}
|
||||
});
|
||||
|
||||
const DEFAULT_CONTENT = [
|
||||
{ id: 1, name: "foo" },
|
||||
{ id: 2, name: "bar" },
|
||||
{ id: 3, name: "baz" }
|
||||
];
|
||||
|
||||
const DEFAULT_VALUE = 1;
|
||||
|
||||
const setDefaultState = (ctx, options) => {
|
||||
const properties = Object.assign(
|
||||
{
|
||||
content: DEFAULT_CONTENT,
|
||||
value: DEFAULT_VALUE,
|
||||
onChange: value => {
|
||||
this.set("value", value);
|
||||
}
|
||||
},
|
||||
options || {}
|
||||
);
|
||||
ctx.setProperties(properties);
|
||||
};
|
||||
|
||||
componentTest("selection behavior", {
|
||||
template: `
|
||||
{{dropdown-select-box
|
||||
value=value
|
||||
content=content
|
||||
}}
|
||||
`,
|
||||
|
||||
beforeEach() {
|
||||
setDefaultState(this);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
assert.ok(this.subject.isExpanded());
|
||||
|
||||
await this.subject.selectRowByValue(DEFAULT_VALUE);
|
||||
assert.notOk(
|
||||
this.subject.isExpanded(),
|
||||
"it collapses the dropdown on select"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("options.showFullTitle=false", {
|
||||
template: `
|
||||
{{dropdown-select-box
|
||||
value=value
|
||||
content=content
|
||||
options=(hash
|
||||
showFullTitle=showFullTitle
|
||||
)
|
||||
}}
|
||||
`,
|
||||
|
||||
beforeEach() {
|
||||
setDefaultState(this, { showFullTitle: false });
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
assert.ok(
|
||||
!exists(
|
||||
this.subject
|
||||
.header()
|
||||
.el()
|
||||
.find(".selected-name .body")
|
||||
),
|
||||
"it hides the text of the selected item"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("options.showFullTitle=true", {
|
||||
template: `
|
||||
{{dropdown-select-box
|
||||
value=value
|
||||
content=content
|
||||
options=(hash
|
||||
showFullTitle=showFullTitle
|
||||
)
|
||||
}}
|
||||
`,
|
||||
|
||||
beforeEach() {
|
||||
setDefaultState(this, { showFullTitle: true });
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
assert.ok(
|
||||
exists(
|
||||
this.subject
|
||||
.header()
|
||||
.el()
|
||||
.find(".selected-name")
|
||||
),
|
||||
"it shows the text of the selected item"
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,35 @@
|
||||
import componentTest from "helpers/component-test";
|
||||
import { testSelectKitModule } from "./select-kit-test-helper";
|
||||
|
||||
testSelectKitModule("list-setting");
|
||||
|
||||
function template(options = []) {
|
||||
return `
|
||||
{{list-setting
|
||||
value=value
|
||||
choices=choices
|
||||
options=(hash
|
||||
${options.join("\n")}
|
||||
)
|
||||
}}
|
||||
`;
|
||||
}
|
||||
|
||||
componentTest("default", {
|
||||
template: template(),
|
||||
|
||||
beforeEach() {
|
||||
this.set("value", ["bold", "italic"]);
|
||||
this.set("choices", ["bold", "italic", "underline"]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
assert.equal(this.subject.header().name(), "bold,italic");
|
||||
assert.equal(this.subject.header().value(), "bold,italic");
|
||||
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(this.subject.rows().length, 1);
|
||||
assert.equal(this.subject.rowByIndex(0).value(), "underline");
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,63 @@
|
||||
import componentTest from "helpers/component-test";
|
||||
import { testSelectKitModule } from "./select-kit-test-helper";
|
||||
|
||||
testSelectKitModule("multi-select");
|
||||
|
||||
function template(options = []) {
|
||||
return `
|
||||
{{multi-select
|
||||
value=value
|
||||
content=content
|
||||
options=(hash
|
||||
${options.join("\n")}
|
||||
)
|
||||
}}
|
||||
`;
|
||||
}
|
||||
|
||||
const DEFAULT_CONTENT = [
|
||||
{ id: 1, name: "foo" },
|
||||
{ id: 2, name: "bar" },
|
||||
{ id: 3, name: "baz" }
|
||||
];
|
||||
|
||||
const setDefaultState = (ctx, options) => {
|
||||
const properties = Object.assign(
|
||||
{
|
||||
content: DEFAULT_CONTENT,
|
||||
value: null
|
||||
},
|
||||
options || {}
|
||||
);
|
||||
ctx.setProperties(properties);
|
||||
};
|
||||
|
||||
componentTest("content", {
|
||||
template: template(),
|
||||
|
||||
beforeEach() {
|
||||
setDefaultState(this);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
const content = this.subject.displayedContent();
|
||||
assert.equal(content.length, 3, "it shows rows");
|
||||
assert.equal(
|
||||
content[0].name,
|
||||
this.content.firstObject.name,
|
||||
"it has the correct name"
|
||||
);
|
||||
assert.equal(
|
||||
content[0].id,
|
||||
this.content.firstObject.id,
|
||||
"it has the correct value"
|
||||
);
|
||||
assert.equal(
|
||||
this.subject.header().value(),
|
||||
null,
|
||||
"it doesn't set a value from the content"
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,40 @@
|
||||
import componentTest from "helpers/component-test";
|
||||
import { testSelectKitModule, setDefaultState } from "./select-kit-test-helper";
|
||||
|
||||
testSelectKitModule("notifications-button");
|
||||
|
||||
componentTest("default", {
|
||||
template: `
|
||||
{{notifications-button
|
||||
value=value
|
||||
options=(hash
|
||||
i18nPrefix=i18nPrefix
|
||||
i18nPostfix=i18nPostfix
|
||||
)
|
||||
}}
|
||||
`,
|
||||
|
||||
beforeEach() {
|
||||
this.set("value", 1);
|
||||
|
||||
setDefaultState(this, 1, { i18nPrefix: "pre", i18nPostfix: "post" });
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
assert.ok(this.subject.header().value());
|
||||
|
||||
assert.ok(
|
||||
this.subject
|
||||
.header()
|
||||
.label()
|
||||
.includes(`${this.i18nPrefix}.regular${this.i18nPostfix}`),
|
||||
"it shows the regular choice when value is not set"
|
||||
);
|
||||
|
||||
const icon = this.subject.header().icon()[0];
|
||||
assert.ok(
|
||||
icon.classList.contains("d-icon-d-regular"),
|
||||
"it shows the correct icon"
|
||||
);
|
||||
}
|
||||
});
|
||||
+3
-2
@@ -11,7 +11,7 @@ const buildTopic = function() {
|
||||
});
|
||||
};
|
||||
|
||||
moduleForComponent("pinned-options", {
|
||||
moduleForComponent("select-kit/pinned-options", {
|
||||
integration: true,
|
||||
beforeEach: function() {
|
||||
this.set("subject", selectKit());
|
||||
@@ -24,12 +24,13 @@ componentTest("updating the content refreshes the list", {
|
||||
beforeEach() {
|
||||
this.siteSettings.automatically_unpin_topics = false;
|
||||
this.set("topic", buildTopic());
|
||||
this.set("pinned", true);
|
||||
this.set("pinned", "pinned");
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
assert.equal(this.subject.header().name(), "pinned");
|
||||
|
||||
// we do it manually as clearPin is an ajax call
|
||||
await this.set("pinned", false);
|
||||
|
||||
assert.equal(this.subject.header().name(), "unpinned");
|
||||
@@ -0,0 +1,33 @@
|
||||
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);
|
||||
}
|
||||
@@ -0,0 +1,217 @@
|
||||
import componentTest from "helpers/component-test";
|
||||
import { testSelectKitModule } from "./select-kit-test-helper";
|
||||
|
||||
testSelectKitModule("single-select");
|
||||
|
||||
function template(options = []) {
|
||||
return `
|
||||
{{single-select
|
||||
value=value
|
||||
content=content
|
||||
nameProperty=nameProperty
|
||||
valueProperty=valueProperty
|
||||
onChange=onChange
|
||||
options=(hash
|
||||
${options.join("\n")}
|
||||
)
|
||||
}}
|
||||
`;
|
||||
}
|
||||
|
||||
const DEFAULT_CONTENT = [
|
||||
{ id: 1, name: "foo" },
|
||||
{ id: 2, name: "bar" },
|
||||
{ id: 3, name: "baz" }
|
||||
];
|
||||
|
||||
const DEFAULT_VALUE = 1;
|
||||
|
||||
const setDefaultState = (ctx, options) => {
|
||||
const properties = Object.assign(
|
||||
{
|
||||
content: DEFAULT_CONTENT,
|
||||
value: DEFAULT_VALUE,
|
||||
nameProperty: "name",
|
||||
valueProperty: "id",
|
||||
onChange: value => {
|
||||
ctx.set("value", value);
|
||||
}
|
||||
},
|
||||
options || {}
|
||||
);
|
||||
ctx.setProperties(properties);
|
||||
};
|
||||
|
||||
componentTest("content", {
|
||||
template: "{{single-select content=content}}",
|
||||
|
||||
beforeEach() {
|
||||
setDefaultState(this);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
const content = this.subject.displayedContent();
|
||||
assert.equal(content.length, 3, "it shows rows");
|
||||
assert.equal(
|
||||
content[0].name,
|
||||
this.content.firstObject.name,
|
||||
"it has the correct name"
|
||||
);
|
||||
assert.equal(
|
||||
content[0].id,
|
||||
this.content.firstObject.id,
|
||||
"it has the correct value"
|
||||
);
|
||||
assert.equal(
|
||||
this.subject.header().value(),
|
||||
null,
|
||||
"it doesn't set a value from the content"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("value", {
|
||||
template: template(),
|
||||
|
||||
beforeEach() {
|
||||
setDefaultState(this);
|
||||
},
|
||||
|
||||
test(assert) {
|
||||
assert.equal(
|
||||
this.subject.header().value(this.content),
|
||||
1,
|
||||
"it selects the correct content to display"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("options.filterable", {
|
||||
template: template(["filterable=filterable"]),
|
||||
|
||||
beforeEach() {
|
||||
setDefaultState(this, { filterable: true });
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
assert.ok(this.subject.filter().exists(), "it shows the filter");
|
||||
|
||||
const filter = this.subject.displayedContent()[1].name;
|
||||
await this.subject.fillInFilter(filter);
|
||||
assert.equal(
|
||||
this.subject.displayedContent()[0].name,
|
||||
filter,
|
||||
"it filters the list"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("options.limitMatches", {
|
||||
template: template(["limitMatches=limitMatches", "filterable=filterable"]),
|
||||
|
||||
beforeEach() {
|
||||
setDefaultState(this, { limitMatches: 1, filterable: true });
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
await this.subject.fillInFilter("ba");
|
||||
|
||||
assert.equal(
|
||||
this.subject.displayedContent().length,
|
||||
1,
|
||||
"it returns only 1 result"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("valueAttribute (deprecated)", {
|
||||
template: `
|
||||
{{single-select
|
||||
value=value
|
||||
content=content
|
||||
valueAttribute="value"
|
||||
}}
|
||||
`,
|
||||
|
||||
beforeEach() {
|
||||
this.set("value", "normal");
|
||||
|
||||
const content = [
|
||||
{ name: "Smaller", value: "smaller" },
|
||||
{ name: "Normal", value: "normal" },
|
||||
{ name: "Larger", value: "larger" },
|
||||
{ name: "Largest", value: "largest" }
|
||||
];
|
||||
this.set("content", content);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(this.subject.selectedRow().value(), this.value);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("none:string", {
|
||||
template: template(['none="test.none"']),
|
||||
|
||||
beforeEach() {
|
||||
I18n.translations[I18n.locale].js.test = { none: "(default)" };
|
||||
setDefaultState(this, { value: 1 });
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
const noneRow = this.subject.rowByIndex(0);
|
||||
assert.equal(noneRow.value(), null);
|
||||
assert.equal(noneRow.name(), I18n.t("test.none"));
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("none:object", {
|
||||
template: template(["none=none"]),
|
||||
|
||||
beforeEach() {
|
||||
setDefaultState(this, { none: { value: null, name: "(default)" } });
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
const noneRow = this.subject.rowByIndex(0);
|
||||
assert.equal(noneRow.value(), null);
|
||||
assert.equal(noneRow.name(), "(default)");
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("content is a basic array", {
|
||||
template: template(['none="test.none"']),
|
||||
|
||||
beforeEach() {
|
||||
I18n.translations[I18n.locale].js.test = { none: "(default)" };
|
||||
setDefaultState(this, {
|
||||
nameProperty: null,
|
||||
valueProperty: null,
|
||||
value: "foo",
|
||||
content: ["foo", "bar", "baz"]
|
||||
});
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
const noneRow = this.subject.rowByIndex(0);
|
||||
assert.equal(noneRow.value(), I18n.t("test.none"));
|
||||
assert.equal(noneRow.name(), I18n.t("test.none"));
|
||||
assert.equal(this.value, "foo");
|
||||
|
||||
await this.subject.selectRowByIndex(0);
|
||||
|
||||
assert.equal(this.value, null);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,78 @@
|
||||
import componentTest from "helpers/component-test";
|
||||
import { testSelectKitModule } from "./select-kit-test-helper";
|
||||
import Site from "discourse/models/site";
|
||||
|
||||
testSelectKitModule("tag-drop", {
|
||||
beforeEach() {
|
||||
const site = Site.current();
|
||||
Ember.set(site, "top_tags", ["jeff", "neil", "arpit", "régis"]);
|
||||
|
||||
const response = object => {
|
||||
return [200, { "Content-Type": "application/json" }, object];
|
||||
};
|
||||
|
||||
// prettier-ignore
|
||||
server.get("/tags/filter/search", (params) => { //eslint-disable-line
|
||||
if (params.queryParams.q === "rég") {
|
||||
return response({
|
||||
"results": [
|
||||
{ "id": "régis", "text": "régis", "count": 2, "pm_count": 0 }
|
||||
]
|
||||
});
|
||||
}else if (params.queryParams.q === "dav") {
|
||||
return response({
|
||||
"results": [
|
||||
{ "id": "David", "text": "David", "count": 2, "pm_count": 0 }
|
||||
]
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function initTags(context) {
|
||||
const categories = context.site.categoriesList;
|
||||
const parentCategory = categories.findBy("id", 2);
|
||||
const childCategories = categories.filter(
|
||||
c => c.parentCategory === parentCategory
|
||||
);
|
||||
|
||||
// top_tags
|
||||
context.setProperties({
|
||||
firstCategory: parentCategory,
|
||||
secondCategory: childCategories.firstObject,
|
||||
tagId: "jeff"
|
||||
});
|
||||
}
|
||||
|
||||
function template(options = []) {
|
||||
return `
|
||||
{{tag-drop
|
||||
firstCategory=firstCategory
|
||||
secondCategory=secondCategory
|
||||
tagId=tagId
|
||||
options=(hash
|
||||
${options.join("\n")}
|
||||
)
|
||||
}}
|
||||
`;
|
||||
}
|
||||
|
||||
componentTest("default", {
|
||||
template: template(["tagId=tagId"]),
|
||||
|
||||
beforeEach() {
|
||||
initTags(this);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.ok(true);
|
||||
// const row = this.subject.rowByValue(this.category.id);
|
||||
// assert.ok(
|
||||
// exists(row.el().find(".category-desc")),
|
||||
// "it shows category description for newcomers"
|
||||
// );
|
||||
}
|
||||
});
|
||||
+7
-7
@@ -16,7 +16,7 @@ const buildTopic = function(level, archetype = "regular") {
|
||||
const originalTranslation =
|
||||
I18n.translations.en.js.topic.notifications.tracking_pm.title;
|
||||
|
||||
moduleForComponent("topic-notifications-button", {
|
||||
moduleForComponent("select-kit/topic-notifications-button", {
|
||||
integration: true,
|
||||
|
||||
afterEach() {
|
||||
@@ -36,9 +36,9 @@ componentTest("the header has a localized title", {
|
||||
assert.equal(
|
||||
selectKit()
|
||||
.header()
|
||||
.name(),
|
||||
.label(),
|
||||
"Normal",
|
||||
"it has the correct title"
|
||||
"it has the correct label"
|
||||
);
|
||||
|
||||
await this.set("topic", buildTopic(2));
|
||||
@@ -46,9 +46,9 @@ componentTest("the header has a localized title", {
|
||||
assert.equal(
|
||||
selectKit()
|
||||
.header()
|
||||
.name(),
|
||||
.label(),
|
||||
"Tracking",
|
||||
"it correctly changes the title"
|
||||
"it correctly changes the label"
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -66,9 +66,9 @@ componentTest("the header has a localized title", {
|
||||
assert.equal(
|
||||
selectKit()
|
||||
.header()
|
||||
.name(),
|
||||
.label(),
|
||||
`${originalTranslation} PM`,
|
||||
"it has the correct title for PMs"
|
||||
"it has the correct label for PMs"
|
||||
);
|
||||
}
|
||||
});
|
||||
+11
-3
@@ -27,15 +27,20 @@ function getTranslations(type = "") {
|
||||
});
|
||||
}
|
||||
|
||||
moduleForComponent("topic-notifications-options", { integration: true });
|
||||
moduleForComponent("select-kit/topic-notifications-options", {
|
||||
integration: true
|
||||
});
|
||||
|
||||
componentTest("regular topic notification level descriptions", {
|
||||
template:
|
||||
"{{topic-notifications-options value=topic.details.notification_level topic=topic}}",
|
||||
|
||||
beforeEach() {
|
||||
this.set("topic", buildTopic("regular"));
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await selectKit().expand();
|
||||
await this.set("topic", buildTopic("regular"));
|
||||
|
||||
const uiTexts = extractDescs(selectKit().rows());
|
||||
const descriptions = getTranslations();
|
||||
@@ -59,9 +64,12 @@ componentTest("PM topic notification level descriptions", {
|
||||
template:
|
||||
"{{topic-notifications-options value=topic.details.notification_level topic=topic}}",
|
||||
|
||||
beforeEach() {
|
||||
this.set("topic", buildTopic("private_message"));
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await selectKit().expand();
|
||||
await this.set("topic", buildTopic("private_message"));
|
||||
|
||||
const uiTexts = extractDescs(selectKit().rows());
|
||||
const descriptions = getTranslations("_pm");
|
||||
@@ -1,822 +0,0 @@
|
||||
import selectKit from "helpers/select-kit-helper";
|
||||
import componentTest from "helpers/component-test";
|
||||
import { withPluginApi } from "discourse/lib/plugin-api";
|
||||
import { clearCallbacks } from "select-kit/mixins/plugin-api";
|
||||
|
||||
moduleForComponent("single-select", {
|
||||
integration: true,
|
||||
beforeEach: function() {
|
||||
this.set("subject", selectKit());
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("updating the content refreshes the list", {
|
||||
template: "{{single-select value=1 content=content}}",
|
||||
|
||||
beforeEach() {
|
||||
this.set("content", [{ id: 1, name: "BEFORE" }]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(this.subject.rowByValue(1).name(), "BEFORE");
|
||||
|
||||
await this.set("content", [{ id: 1, name: "AFTER" }]);
|
||||
|
||||
assert.equal(this.subject.rowByValue(1).name(), "AFTER");
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("accepts a value by reference", {
|
||||
template: "{{single-select value=value content=content}}",
|
||||
|
||||
beforeEach() {
|
||||
this.set("value", 1);
|
||||
this.set("content", [
|
||||
{ id: 1, name: "robin" },
|
||||
{ id: 2, name: "regis" }
|
||||
]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(
|
||||
this.subject.selectedRow().name(),
|
||||
"robin",
|
||||
"it highlights the row corresponding to the value"
|
||||
);
|
||||
|
||||
await this.subject.selectRowByValue(1);
|
||||
|
||||
assert.equal(this.value, 1, "it mutates the value");
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("no default icon", {
|
||||
template: "{{single-select}}",
|
||||
|
||||
test(assert) {
|
||||
assert.equal(
|
||||
this.subject.header().icon().length,
|
||||
0,
|
||||
"it doesn’t have an icon if not specified"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("default search icon", {
|
||||
template: "{{single-select filterable=true}}",
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.ok(exists(this.subject.filter().icon()), "it has an icon");
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with no search icon", {
|
||||
template: "{{single-select filterable=true filterIcon=null}}",
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.notOk(exists(this.subject.filter().icon()), "it has no icon");
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("custom search icon", {
|
||||
template: '{{single-select filterable=true filterIcon="shower"}}',
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.ok(
|
||||
this.subject
|
||||
.filter()
|
||||
.icon()
|
||||
.hasClass("d-icon-shower"),
|
||||
"it has a the correct icon"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("is expandable", {
|
||||
template: "{{single-select}}",
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.ok(this.subject.isExpanded());
|
||||
|
||||
await this.subject.collapse();
|
||||
|
||||
assert.notOk(this.subject.isExpanded());
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("accepts custom value/name keys", {
|
||||
template:
|
||||
'{{single-select value=value nameProperty="item" content=content valueAttribute="identifier"}}',
|
||||
|
||||
beforeEach() {
|
||||
this.set("value", 1);
|
||||
this.set("content", [{ identifier: 1, item: "robin" }]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(this.subject.selectedRow().name(), "robin");
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("doesn’t render collection content before first expand", {
|
||||
template: "{{single-select value=1 content=content}}",
|
||||
|
||||
beforeEach() {
|
||||
this.set("content", [{ value: 1, name: "robin" }]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
assert.notOk(exists(find(".select-kit-collection")));
|
||||
|
||||
await this.subject.expand();
|
||||
|
||||
assert.ok(exists(find(".select-kit-collection")));
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("dynamic headerText", {
|
||||
template: "{{single-select value=1 content=content}}",
|
||||
|
||||
beforeEach() {
|
||||
this.set("content", [
|
||||
{ id: 1, name: "robin" },
|
||||
{ id: 2, name: "regis" }
|
||||
]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(this.subject.header().name(), "robin");
|
||||
|
||||
await this.subject.selectRowByValue(2);
|
||||
|
||||
assert.equal(
|
||||
this.subject.header().name(),
|
||||
"regis",
|
||||
"it changes header text"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("supports custom row template", {
|
||||
template: "{{single-select content=content templateForRow=templateForRow}}",
|
||||
|
||||
beforeEach() {
|
||||
this.set("content", [{ id: 1, name: "robin" }]);
|
||||
this.set("templateForRow", rowComponent => {
|
||||
return `<b>${rowComponent.get("computedContent.name")}</b>`;
|
||||
});
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(
|
||||
this.subject
|
||||
.rowByValue(1)
|
||||
.el()
|
||||
.html()
|
||||
.trim(),
|
||||
"<b>robin</b>"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("supports converting select value to integer", {
|
||||
template: "{{single-select value=value content=content castInteger=true}}",
|
||||
|
||||
beforeEach() {
|
||||
this.set("value", 2);
|
||||
this.set("content", [
|
||||
{ id: "1", name: "robin" },
|
||||
{ id: "2", name: "régis" }
|
||||
]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(this.subject.selectedRow().name(), "régis");
|
||||
|
||||
await this.set("value", 1);
|
||||
|
||||
assert.equal(
|
||||
this.subject.selectedRow().name(),
|
||||
"robin",
|
||||
"it works with dynamic content"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("supports converting string as boolean to boolean", {
|
||||
template: "{{single-select value=value content=content castBoolean=true}}",
|
||||
|
||||
beforeEach() {
|
||||
this.set("value", true);
|
||||
this.set("content", [
|
||||
{ id: "true", name: "ASC" },
|
||||
{ id: "false", name: "DESC" }
|
||||
]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(this.subject.selectedRow().name(), "ASC");
|
||||
|
||||
await this.set("value", false);
|
||||
|
||||
assert.equal(
|
||||
this.subject.selectedRow().name(),
|
||||
"DESC",
|
||||
"it works with dynamic content"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("supports keyboard events", {
|
||||
template: "{{single-select content=content filterable=true}}",
|
||||
|
||||
beforeEach() {
|
||||
this.set("content", [
|
||||
{ id: 1, name: "robin" },
|
||||
{ id: 2, name: "regis" }
|
||||
]);
|
||||
},
|
||||
|
||||
skip: true,
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
await this.subject.keyboard("down");
|
||||
|
||||
assert.equal(
|
||||
this.subject.highlightedRow().title(),
|
||||
"regis",
|
||||
"the next row is highlighted"
|
||||
);
|
||||
|
||||
await this.subject.keyboard("down");
|
||||
|
||||
assert.equal(
|
||||
this.subject.highlightedRow().title(),
|
||||
"robin",
|
||||
"it returns to the first row"
|
||||
);
|
||||
|
||||
await this.subject.keyboard("up");
|
||||
|
||||
assert.equal(
|
||||
this.subject.highlightedRow().title(),
|
||||
"regis",
|
||||
"it highlights the last row"
|
||||
);
|
||||
|
||||
await this.subject.keyboard("enter");
|
||||
|
||||
assert.equal(
|
||||
this.subject.selectedRow().title(),
|
||||
"regis",
|
||||
"it selects the row when pressing enter"
|
||||
);
|
||||
assert.notOk(
|
||||
this.subject.isExpanded(),
|
||||
"it collapses the select box when selecting a row"
|
||||
);
|
||||
|
||||
await this.subject.expand();
|
||||
await this.subject.keyboard("escape");
|
||||
|
||||
assert.notOk(this.subject.isExpanded(), "it collapses the select box");
|
||||
|
||||
await this.subject.expand();
|
||||
await this.subject.fillInFilter("regis");
|
||||
await this.subject.keyboard("tab");
|
||||
|
||||
assert.notOk(
|
||||
this.subject.isExpanded(),
|
||||
"it collapses the select box when selecting a row"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with allowInitialValueMutation", {
|
||||
template:
|
||||
"{{single-select value=value content=content allowInitialValueMutation=true}}",
|
||||
|
||||
beforeEach() {
|
||||
this.set("value", "");
|
||||
this.set("content", [
|
||||
{ id: "1", name: "robin" },
|
||||
{ id: "2", name: "régis" }
|
||||
]);
|
||||
},
|
||||
|
||||
test(assert) {
|
||||
assert.equal(this.value, "1", "it mutates the value on initial rendering");
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("support appending content through plugin api", {
|
||||
template: "{{single-select content=content}}",
|
||||
|
||||
beforeEach() {
|
||||
withPluginApi("0.8.13", api => {
|
||||
api
|
||||
.modifySelectKit("select-kit")
|
||||
.appendContent([{ id: "2", name: "regis" }]);
|
||||
});
|
||||
|
||||
this.set("content", [{ id: "1", name: "robin" }]);
|
||||
},
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(this.subject.rows().length, 2);
|
||||
assert.equal(this.subject.rowByIndex(1).name(), "regis");
|
||||
|
||||
clearCallbacks();
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("support modifying content through plugin api", {
|
||||
template: "{{single-select content=content}}",
|
||||
|
||||
beforeEach() {
|
||||
withPluginApi("0.8.13", api => {
|
||||
api
|
||||
.modifySelectKit("select-kit")
|
||||
.modifyContent((context, existingContent) => {
|
||||
existingContent.splice(1, 0, { id: "2", name: "sam" });
|
||||
return existingContent;
|
||||
});
|
||||
});
|
||||
|
||||
this.set("content", [
|
||||
{ id: "1", name: "robin" },
|
||||
{ id: "3", name: "regis" }
|
||||
]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(this.subject.rows().length, 3);
|
||||
assert.equal(this.subject.rowByIndex(1).name(), "sam");
|
||||
|
||||
clearCallbacks();
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("support prepending content through plugin api", {
|
||||
template: "{{single-select content=content}}",
|
||||
|
||||
beforeEach() {
|
||||
withPluginApi("0.8.13", api => {
|
||||
api
|
||||
.modifySelectKit("select-kit")
|
||||
.prependContent([{ id: "2", name: "regis" }]);
|
||||
});
|
||||
|
||||
this.set("content", [{ id: "1", name: "robin" }]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(this.subject.rows().length, 2);
|
||||
assert.equal(this.subject.rowByIndex(0).name(), "regis");
|
||||
|
||||
clearCallbacks();
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("support modifying on select behavior through plugin api", {
|
||||
template:
|
||||
'<span class="on-select-test"></span>{{single-select content=content}}',
|
||||
|
||||
beforeEach() {
|
||||
withPluginApi("0.8.13", api => {
|
||||
api.modifySelectKit("select-kit").onSelect((context, value) => {
|
||||
find(".on-select-test").html(value);
|
||||
});
|
||||
});
|
||||
|
||||
this.set("content", [
|
||||
{ id: "1", name: "robin" },
|
||||
{ id: "2", name: "arpit", __sk_row_type: "noopRow" }
|
||||
]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
await this.subject.selectRowByValue(1);
|
||||
|
||||
assert.equal(find(".on-select-test").html(), "1");
|
||||
|
||||
await this.subject.expand();
|
||||
await this.subject.selectRowByValue(2);
|
||||
|
||||
assert.equal(
|
||||
find(".on-select-test").html(),
|
||||
"2",
|
||||
"it calls onSelect for noopRows"
|
||||
);
|
||||
|
||||
clearCallbacks();
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("support modifying on select none behavior through plugin api", {
|
||||
template:
|
||||
'<span class="on-select-none-test"></span>{{single-select none="none" content=content}}',
|
||||
|
||||
beforeEach() {
|
||||
withPluginApi("0.8.25", api => {
|
||||
api.modifySelectKit("select-kit").onSelectNone(() => {
|
||||
find(".on-select-none-test").html("NONE");
|
||||
});
|
||||
});
|
||||
|
||||
this.set("content", [{ id: "1", name: "robin" }]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
await this.subject.selectRowByValue(1);
|
||||
await this.subject.expand();
|
||||
await this.subject.selectNoneRow();
|
||||
|
||||
assert.equal(find(".on-select-none-test").html(), "NONE");
|
||||
|
||||
clearCallbacks();
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with nameChanges", {
|
||||
template: "{{single-select content=content nameChanges=true}}",
|
||||
|
||||
beforeEach() {
|
||||
this.set("robin", { id: "1", name: "robin" });
|
||||
this.set("content", [this.robin]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(this.subject.header().name(), "robin");
|
||||
|
||||
await this.set("robin.name", "robin2");
|
||||
|
||||
assert.equal(this.subject.header().name(), "robin2");
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with null value", {
|
||||
template: "{{single-select content=content}}",
|
||||
|
||||
beforeEach() {
|
||||
this.set("content", [{ name: "robin" }]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(this.subject.header().name(), "robin");
|
||||
assert.equal(this.subject.header().value(), undefined);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with collection header", {
|
||||
template: "{{single-select collectionHeader=collectionHeader}}",
|
||||
|
||||
beforeEach() {
|
||||
this.set("collectionHeader", "<h2>Hello</h2>");
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.ok(exists(".collection-header h2"));
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with title", {
|
||||
template: '{{single-select title=(i18n "test.title")}}',
|
||||
|
||||
beforeEach() {
|
||||
I18n.translations[I18n.locale].js.test = { title: "My title" };
|
||||
},
|
||||
|
||||
test(assert) {
|
||||
assert.equal(this.subject.header().title(), "My title");
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("support modifying header computed content through plugin api", {
|
||||
template: "{{single-select content=content}}",
|
||||
|
||||
beforeEach() {
|
||||
withPluginApi("0.8.15", api => {
|
||||
api
|
||||
.modifySelectKit("select-kit")
|
||||
.modifyHeaderComputedContent((context, computedContent) => {
|
||||
computedContent.title = "Not so evil";
|
||||
return computedContent;
|
||||
});
|
||||
});
|
||||
|
||||
this.set("content", [{ id: "1", name: "robin" }]);
|
||||
},
|
||||
|
||||
test(assert) {
|
||||
assert.equal(this.subject.header().title(), "Not so evil");
|
||||
|
||||
clearCallbacks();
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with limitMatches", {
|
||||
template: "{{single-select content=content limitMatches=2}}",
|
||||
|
||||
beforeEach() {
|
||||
this.set("content", ["sam", "jeff", "neil"]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(this.subject.el().find(".select-kit-row").length, 2);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with minimum", {
|
||||
template:
|
||||
"{{single-select content=content minimum=1 allowAutoSelectFirst=false}}",
|
||||
|
||||
beforeEach() {
|
||||
this.set("content", ["sam", "jeff", "neil"]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(this.subject.validationMessage(), "Select at least 1 item.");
|
||||
|
||||
await this.subject.selectRowByValue("sam");
|
||||
|
||||
assert.equal(this.subject.header().label(), "sam");
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with minimumLabel", {
|
||||
template:
|
||||
'{{single-select content=content minimum=1 minimumLabel="test.minimum" allowAutoSelectFirst=false}}',
|
||||
|
||||
beforeEach() {
|
||||
I18n.translations[I18n.locale].js.test = { minimum: "min %{count}" };
|
||||
this.set("content", ["sam", "jeff", "neil"]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(this.subject.validationMessage(), "min 1");
|
||||
|
||||
await this.subject.selectRowByValue("jeff");
|
||||
|
||||
assert.equal(this.subject.header().label(), "jeff");
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with accents in filter", {
|
||||
template: "{{single-select content=content filterable=true}}",
|
||||
|
||||
beforeEach() {
|
||||
this.set("content", ["sam", "jeff", "neil"]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
await this.subject.fillInFilter("jéff");
|
||||
|
||||
assert.equal(this.subject.rows().length, 1);
|
||||
assert.equal(this.subject.rowByIndex(0).name(), "jeff");
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with accents in content", {
|
||||
template: "{{single-select content=content filterable=true}}",
|
||||
|
||||
beforeEach() {
|
||||
this.set("content", ["sam", "jéff", "neil"]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
await this.subject.fillInFilter("jeff");
|
||||
|
||||
assert.equal(this.subject.rows().length, 1);
|
||||
assert.equal(this.subject.rowByIndex(0).name(), "jéff");
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with no content and allowAny", {
|
||||
template: "{{single-select allowAny=true}}",
|
||||
|
||||
skip: true,
|
||||
async test(assert) {
|
||||
await click(this.subject.header().el());
|
||||
|
||||
const $filter = this.subject.filter().el();
|
||||
|
||||
assert.ok($filter.hasClass("is-focused"));
|
||||
assert.ok(!$filter.hasClass("is-hidden"));
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with forceEscape", {
|
||||
template: "{{single-select content=content forceEscape=true}}",
|
||||
|
||||
beforeEach() {
|
||||
this.set("content", ["<div>sam</div>"]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
const row = this.subject.rowByIndex(0);
|
||||
assert.equal(
|
||||
row
|
||||
.el()
|
||||
.find(".name")
|
||||
.html()
|
||||
.trim(),
|
||||
"<div>sam</div>"
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
this.subject
|
||||
.header()
|
||||
.el()
|
||||
.find(".selected-name")
|
||||
.html()
|
||||
.trim(),
|
||||
"<div>sam</div>"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("without forceEscape", {
|
||||
template: "{{single-select content=content forceEscape=false}}",
|
||||
|
||||
beforeEach() {
|
||||
this.set("content", ["<div>sam</div>"]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
const row = this.subject.rowByIndex(0);
|
||||
assert.equal(
|
||||
row
|
||||
.el()
|
||||
.find(".name")
|
||||
.html()
|
||||
.trim(),
|
||||
"<div>sam</div>"
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
this.subject
|
||||
.header()
|
||||
.el()
|
||||
.find(".selected-name")
|
||||
.html()
|
||||
.trim(),
|
||||
"<div>sam</div>"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("onSelect", {
|
||||
template:
|
||||
"<div class='test-external-action'></div>{{single-select content=content onSelect=(action externalAction)}}",
|
||||
|
||||
beforeEach() {
|
||||
this.set("externalAction", actual => {
|
||||
find(".test-external-action").text(actual);
|
||||
});
|
||||
|
||||
this.set("content", ["red", "blue"]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
await this.subject.selectRowByValue("red");
|
||||
|
||||
assert.equal(
|
||||
find(".test-external-action")
|
||||
.text()
|
||||
.trim(),
|
||||
"red"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("onDeselect", {
|
||||
template:
|
||||
"<div class='test-external-action'></div>{{single-select content=content onDeselect=(action externalAction)}}",
|
||||
|
||||
beforeEach() {
|
||||
this.set("externalAction", actual => {
|
||||
find(".test-external-action").text(actual);
|
||||
});
|
||||
|
||||
this.set("content", ["red", "blue"]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
await this.subject.selectRowByValue("red");
|
||||
await this.subject.expand();
|
||||
await this.subject.selectRowByValue("blue");
|
||||
|
||||
assert.equal(
|
||||
find(".test-external-action")
|
||||
.text()
|
||||
.trim(),
|
||||
"red"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("noopRow", {
|
||||
template: "{{single-select value=value content=content}}",
|
||||
|
||||
beforeEach() {
|
||||
this.set("value", "blue");
|
||||
this.set("content", [
|
||||
{ id: "red", name: "Red", __sk_row_type: "noopRow" },
|
||||
"blue",
|
||||
"green"
|
||||
]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
await this.subject.selectRowByValue("red");
|
||||
assert.equal(this.value, "blue", "it doesn’t change the value");
|
||||
|
||||
await this.subject.expand();
|
||||
await this.subject.selectRowByValue("green");
|
||||
assert.equal(this.value, "green");
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("onSelectAny", {
|
||||
template: `<div class='test-external-action'></div>{{single-select none="none" content=content onSelectAny=(action externalAction)}}`,
|
||||
|
||||
beforeEach() {
|
||||
this.set("externalAction", actual => {
|
||||
find(".test-external-action").text(actual.value);
|
||||
});
|
||||
|
||||
this.set("content", ["blue"]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.get("subject").expand();
|
||||
await this.get("subject").selectRowByValue("blue");
|
||||
|
||||
assert.equal(
|
||||
find(".test-external-action")
|
||||
.text()
|
||||
.trim(),
|
||||
"blue"
|
||||
);
|
||||
|
||||
await this.get("subject").expand();
|
||||
await this.get("subject").selectNoneRow();
|
||||
|
||||
assert.equal(
|
||||
find(".test-external-action")
|
||||
.text()
|
||||
.trim(),
|
||||
"__none__"
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -1,133 +0,0 @@
|
||||
import selectKit from "helpers/select-kit-helper";
|
||||
import componentTest from "helpers/component-test";
|
||||
import DiscourseURL from "discourse/lib/url";
|
||||
|
||||
moduleForComponent("tag-drop", {
|
||||
integration: true,
|
||||
beforeEach: function() {
|
||||
this.set("subject", selectKit());
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("default", {
|
||||
template: "{{tag-drop}}",
|
||||
|
||||
beforeEach() {
|
||||
this.site.set("can_create_tag", true);
|
||||
this.set("site.top_tags", ["jeff", "neil", "arpit", "régis"]);
|
||||
|
||||
const response = object => {
|
||||
return [200, { "Content-Type": "application/json" }, object];
|
||||
};
|
||||
|
||||
// prettier-ignore
|
||||
server.get("/tags/filter/search", (params) => { //eslint-disable-line
|
||||
if (params.queryParams.q === "rég") {
|
||||
return response({
|
||||
"results": [
|
||||
{ "id": "régis", "text": "régis", "count": 2, "pm_count": 0, target_tag: null }
|
||||
]
|
||||
});
|
||||
} else if (params.queryParams.q === "dav") {
|
||||
return response({
|
||||
"results": [
|
||||
{ "id": "David", "text": "David", "count": 2, "pm_count": 0, target_tag: null }
|
||||
]
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(
|
||||
this.subject.rowByIndex(1).name(),
|
||||
"jeff",
|
||||
"it has the correct tag"
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
this.subject.rowByIndex(2).name(),
|
||||
"neil",
|
||||
"it has the correct tag"
|
||||
);
|
||||
|
||||
await this.subject.fillInFilter("rég");
|
||||
assert.equal(
|
||||
this.subject.rowByIndex(0).name(),
|
||||
"régis",
|
||||
"it displays the searched tag"
|
||||
);
|
||||
|
||||
await this.subject.fillInFilter("");
|
||||
assert.equal(
|
||||
this.subject.rowByIndex(1).name(),
|
||||
"jeff",
|
||||
"it returns top tags for an empty search"
|
||||
);
|
||||
|
||||
sandbox.stub(DiscourseURL, "routeTo");
|
||||
await this.subject.fillInFilter("dav");
|
||||
await this.subject.keyboard("enter");
|
||||
assert.ok(
|
||||
DiscourseURL.routeTo.calledWith("/tag/david"),
|
||||
"it uses lowercase URLs for tags"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("synonym", {
|
||||
template: "{{tag-drop}}",
|
||||
|
||||
beforeEach() {
|
||||
this.site.set("can_create_tag", true);
|
||||
this.set("site.top_tags", ["jeff", "neil", "arpit", "régis"]);
|
||||
|
||||
const response = object => {
|
||||
return [200, { "Content-Type": "application/json" }, object];
|
||||
};
|
||||
|
||||
// prettier-ignore
|
||||
server.get("/tags/filter/search", (params) => { //eslint-disable-line
|
||||
if (params.queryParams.q === "robin") {
|
||||
return response({
|
||||
"results": [
|
||||
{ "id": "Robin", "text": "Robin", "count": 2, "pm_count": 0, target_tag: 'EvilTrout' }
|
||||
]
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
sandbox.stub(DiscourseURL, "routeTo");
|
||||
await this.subject.fillInFilter("robin");
|
||||
await this.subject.keyboard("enter");
|
||||
assert.ok(
|
||||
DiscourseURL.routeTo.calledWith("/tag/eviltrout"),
|
||||
"it routes to the target tag"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("no tags", {
|
||||
template: "{{tag-drop}}",
|
||||
|
||||
beforeEach() {
|
||||
this.site.set("can_create_tag", true);
|
||||
this.set("site.top_tags", undefined);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(
|
||||
this.subject.rowByIndex(1).name(),
|
||||
undefined,
|
||||
"it has no tags and doesn’t crash"
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -1,184 +0,0 @@
|
||||
import { withPluginApi } from "discourse/lib/plugin-api";
|
||||
import componentTest from "helpers/component-test";
|
||||
import Topic from "discourse/models/topic";
|
||||
import { clearTopicFooterButtons } from "discourse/lib/register-topic-footer-button";
|
||||
|
||||
const buildTopic = function() {
|
||||
return Topic.create({
|
||||
id: 1234,
|
||||
title: "Qunit Test Topic"
|
||||
});
|
||||
};
|
||||
|
||||
moduleForComponent("topic-footer-buttons-desktop", {
|
||||
integration: true,
|
||||
beforeEach() {
|
||||
I18n.translations[I18n.locale].js.test = {
|
||||
title: "My title",
|
||||
label: "My Label"
|
||||
};
|
||||
},
|
||||
|
||||
afterEach() {
|
||||
clearTopicFooterButtons();
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("default", {
|
||||
template: "{{topic-footer-buttons topic=topic}}",
|
||||
beforeEach() {
|
||||
withPluginApi("0.8.28", api => {
|
||||
api.registerTopicFooterButton({
|
||||
id: "my-button",
|
||||
icon: "user",
|
||||
label: "test.label",
|
||||
title: "test.title"
|
||||
});
|
||||
});
|
||||
|
||||
this.set("topic", buildTopic());
|
||||
},
|
||||
async test(assert) {
|
||||
const button = await find("#topic-footer-button-my-button");
|
||||
assert.ok(exists(button), "it creates an inline button");
|
||||
|
||||
const icon = await button.find(".d-icon-user");
|
||||
assert.ok(exists(icon), "the button has the correct icon");
|
||||
|
||||
const label = await button.find(".d-button-label");
|
||||
assert.ok(exists(label), "the button has a label");
|
||||
assert.equal(
|
||||
label.text(),
|
||||
I18n.t("test.label"),
|
||||
"the button has the correct label"
|
||||
);
|
||||
|
||||
const title = button.attr("title");
|
||||
assert.equal(
|
||||
title,
|
||||
I18n.t("test.title"),
|
||||
"the button has the correct title"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("priority", {
|
||||
template: "{{topic-footer-buttons topic=topic}}",
|
||||
beforeEach() {
|
||||
withPluginApi("0.8.28", api => {
|
||||
api.registerTopicFooterButton({
|
||||
id: "my-second-button",
|
||||
priority: 750,
|
||||
icon: "user"
|
||||
});
|
||||
|
||||
api.registerTopicFooterButton({
|
||||
id: "my-third-button",
|
||||
priority: 500,
|
||||
icon: "flag"
|
||||
});
|
||||
|
||||
api.registerTopicFooterButton({
|
||||
id: "my-first-button",
|
||||
priority: 1000,
|
||||
icon: "times"
|
||||
});
|
||||
});
|
||||
|
||||
this.set("topic", buildTopic());
|
||||
},
|
||||
async test(assert) {
|
||||
const buttons = await find(".topic-footer-button");
|
||||
const firstButton = find("#topic-footer-button-my-first-button");
|
||||
const secondButton = find("#topic-footer-button-my-second-button");
|
||||
const thirdButton = find("#topic-footer-button-my-third-button");
|
||||
|
||||
assert.ok(buttons.index(firstButton) < buttons.index(secondButton));
|
||||
assert.ok(buttons.index(secondButton) < buttons.index(thirdButton));
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with functions", {
|
||||
template: "{{topic-footer-buttons topic=topic}}",
|
||||
beforeEach() {
|
||||
withPluginApi("0.8.28", api => {
|
||||
api.registerTopicFooterButton({
|
||||
id: "my-button",
|
||||
icon() {
|
||||
return "user";
|
||||
},
|
||||
label() {
|
||||
return "test.label";
|
||||
},
|
||||
title() {
|
||||
return "test.title";
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
this.set("topic", buildTopic());
|
||||
},
|
||||
async test(assert) {
|
||||
const button = await find("#topic-footer-button-my-button");
|
||||
assert.ok(exists(button), "it creates an inline button");
|
||||
|
||||
const icon = await button.find(".d-icon-user");
|
||||
assert.ok(exists(icon), "the button has the correct icon");
|
||||
|
||||
const label = await button.find(".d-button-label");
|
||||
assert.ok(exists(label), "the button has a label");
|
||||
assert.equal(
|
||||
label.text(),
|
||||
I18n.t("test.label"),
|
||||
"the button has the correct label"
|
||||
);
|
||||
|
||||
const title = button.attr("title");
|
||||
assert.equal(
|
||||
title,
|
||||
I18n.t("test.title"),
|
||||
"the button has the correct title"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("action", {
|
||||
template: "<div id='test-action'></div>{{topic-footer-buttons topic=topic}}",
|
||||
beforeEach() {
|
||||
withPluginApi("0.8.28", api => {
|
||||
api.registerTopicFooterButton({
|
||||
id: "my-button",
|
||||
icon: "flag",
|
||||
action() {
|
||||
$("#test-action").text(this.get("topic.title"));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
this.set("topic", buildTopic());
|
||||
},
|
||||
async test(assert) {
|
||||
await click("#topic-footer-button-my-button");
|
||||
|
||||
assert.equal(find("#test-action").text(), this.get("topic.title"));
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("dropdown", {
|
||||
template: "{{topic-footer-buttons topic=topic}}",
|
||||
beforeEach() {
|
||||
withPluginApi("0.8.28", api => {
|
||||
api.registerTopicFooterButton({
|
||||
id: "my-button",
|
||||
icon: "flag",
|
||||
dropdown: true
|
||||
});
|
||||
});
|
||||
|
||||
this.set("topic", buildTopic());
|
||||
},
|
||||
async test(assert) {
|
||||
const button = await find("#topic-footer-button-my-button");
|
||||
assert.notOk(exists(button), "it doesn’t create an inline button");
|
||||
}
|
||||
});
|
||||
@@ -1,35 +0,0 @@
|
||||
import selectKit from "helpers/select-kit-helper";
|
||||
import componentTest from "helpers/component-test";
|
||||
import Topic from "discourse/models/topic";
|
||||
|
||||
const buildTopic = function() {
|
||||
return Topic.create({
|
||||
id: 1234,
|
||||
title: "Qunit Test Topic"
|
||||
});
|
||||
};
|
||||
|
||||
moduleForComponent("topic-footer-mobile-dropdown", {
|
||||
integration: true,
|
||||
beforeEach: function() {
|
||||
this.set("subject", selectKit());
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("default", {
|
||||
template: "{{topic-footer-mobile-dropdown topic=topic}}",
|
||||
beforeEach() {
|
||||
this.set("topic", buildTopic());
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await this.subject.expand();
|
||||
|
||||
assert.equal(this.subject.header().title(), "Topic Controls");
|
||||
assert.equal(this.subject.header().value(), null);
|
||||
assert.notOk(
|
||||
this.subject.selectedRow().exists(),
|
||||
"it doesn’t preselect first row"
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -6,9 +6,12 @@ componentTest("adding a value", {
|
||||
template: "{{value-list values=values}}",
|
||||
|
||||
skip: true,
|
||||
async test(assert) {
|
||||
this.set("values", "vinkas\nosama");
|
||||
|
||||
beforeEach() {
|
||||
this.set("values", "vinkas\nosama");
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await selectKit().expand();
|
||||
await selectKit().fillInFilter("eviltrout");
|
||||
await selectKit().keyboard("enter");
|
||||
@@ -29,9 +32,11 @@ componentTest("adding a value", {
|
||||
componentTest("removing a value", {
|
||||
template: "{{value-list values=values}}",
|
||||
|
||||
async test(assert) {
|
||||
beforeEach() {
|
||||
this.set("values", "vinkas\nosama");
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await click(".values .value[data-index='0'] .remove-value-btn");
|
||||
|
||||
assert.ok(
|
||||
@@ -46,10 +51,14 @@ componentTest("removing a value", {
|
||||
componentTest("selecting a value", {
|
||||
template: "{{value-list values=values choices=choices}}",
|
||||
|
||||
async test(assert) {
|
||||
this.set("values", "vinkas\nosama");
|
||||
this.set("choices", ["maja", "michael"]);
|
||||
beforeEach() {
|
||||
this.setProperties({
|
||||
values: "vinkas\nosama",
|
||||
choices: ["maja", "michael"]
|
||||
});
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await selectKit().expand();
|
||||
await selectKit().selectRowByValue("maja");
|
||||
|
||||
@@ -69,6 +78,10 @@ componentTest("selecting a value", {
|
||||
componentTest("array support", {
|
||||
template: "{{value-list values=values inputType='array'}}",
|
||||
|
||||
beforeEach() {
|
||||
this.set("values", ["vinkas", "osama"]);
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
this.set("values", ["vinkas", "osama"]);
|
||||
|
||||
@@ -92,10 +105,13 @@ componentTest("array support", {
|
||||
componentTest("delimiter support", {
|
||||
template: "{{value-list values=values inputDelimiter='|'}}",
|
||||
|
||||
skip: true,
|
||||
async test(assert) {
|
||||
beforeEach() {
|
||||
this.set("values", "vinkas|osama");
|
||||
},
|
||||
|
||||
skip: true,
|
||||
|
||||
async test(assert) {
|
||||
await selectKit().expand();
|
||||
await selectKit().fillInFilter("eviltrout");
|
||||
await selectKit().keyboard("enter");
|
||||
|
||||
@@ -24,7 +24,10 @@ async function collapseSelectKit(selector) {
|
||||
|
||||
async function selectKitFillInFilter(filter, selector) {
|
||||
checkSelectKitIsNotCollapsed(selector);
|
||||
await fillIn(`${selector} .filter-input`, filter);
|
||||
await fillIn(
|
||||
`${selector} .filter-input`,
|
||||
find(`${selector} .filter-input`).val() + filter
|
||||
);
|
||||
}
|
||||
|
||||
async function selectKitSelectRowByValue(value, selector) {
|
||||
@@ -66,7 +69,11 @@ async function keyboardHelper(value, target, selector) {
|
||||
tab: { keyCode: 9 }
|
||||
};
|
||||
|
||||
await triggerEvent(target, "keydown", mapping[value]);
|
||||
await triggerEvent(
|
||||
target,
|
||||
"keydown",
|
||||
mapping[value] || { keyCode: value.charCodeAt(0) }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +89,8 @@ function rowHelper(row) {
|
||||
return row.attr("title");
|
||||
},
|
||||
value() {
|
||||
return row.attr("data-value");
|
||||
const value = row.attr("data-value");
|
||||
return Ember.isEmpty(value) ? null : value;
|
||||
},
|
||||
exists() {
|
||||
return exists(row);
|
||||
@@ -96,7 +104,8 @@ function rowHelper(row) {
|
||||
function headerHelper(header) {
|
||||
return {
|
||||
value() {
|
||||
return header.attr("data-value");
|
||||
const value = header.attr("data-value");
|
||||
return Ember.isEmpty(value) ? null : value;
|
||||
},
|
||||
name() {
|
||||
return header.attr("data-name");
|
||||
@@ -105,7 +114,7 @@ function headerHelper(header) {
|
||||
return header.text().trim();
|
||||
},
|
||||
icon() {
|
||||
return header.find(".icon");
|
||||
return header.find(".d-icon");
|
||||
},
|
||||
title() {
|
||||
return header.attr("title");
|
||||
@@ -124,6 +133,9 @@ function filterHelper(filter) {
|
||||
exists() {
|
||||
return exists(filter);
|
||||
},
|
||||
value() {
|
||||
return filter.find("input").val();
|
||||
},
|
||||
el() {
|
||||
return filter;
|
||||
}
|
||||
@@ -194,6 +206,17 @@ export default function selectKit(selector) {
|
||||
return find(selector).find(".select-kit-row");
|
||||
},
|
||||
|
||||
displayedContent() {
|
||||
return this.rows()
|
||||
.map((_, row) => {
|
||||
return {
|
||||
name: row.getAttribute("data-name"),
|
||||
id: row.getAttribute("data-value")
|
||||
};
|
||||
})
|
||||
.toArray();
|
||||
},
|
||||
|
||||
rowByValue(value) {
|
||||
return rowHelper(
|
||||
find(selector).find('.select-kit-row[data-value="' + value + '"]')
|
||||
|
||||
@@ -164,7 +164,9 @@ QUnit.testDone(function() {
|
||||
Object.keys(events).forEach(function(eventKey) {
|
||||
var event = events[eventKey];
|
||||
event.forEach(function(listener) {
|
||||
appEvents.off(eventKey, listener.target, listener.fn);
|
||||
if (appEvents.has(eventKey)) {
|
||||
appEvents.off(eventKey, listener.target, listener.fn);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user