discourse/test/javascripts/components/select-kit/single-select-test.js

298 lines
6.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import componentTest from "helpers/component-test";
import { testSelectKitModule } from "helpers/select-kit-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);
}
});
componentTest("selected value can be 0", {
template: template(),
beforeEach() {
setDefaultState(this, {
value: 1,
content: [
{ id: 0, name: "foo" },
{ id: 1, name: "bar" }
]
});
},
async test(assert) {
assert.equal(this.subject.header().value(), 1);
await this.subject.expand();
await this.subject.selectRowByValue(0);
assert.equal(this.subject.header().value(), 0);
}
});
componentTest("prevents propagating click event on header", {
template:
"{{#d-button icon='times' action=onClick}}{{single-select options=(hash preventsClickPropagation=true) value=value content=content}}{{/d-button}}",
beforeEach() {
this.setProperties({
onClick: () => this.set("value", "foo"),
content: DEFAULT_CONTENT,
value: DEFAULT_VALUE
});
},
async test(assert) {
assert.equal(this.value, DEFAULT_VALUE);
await this.subject.expand();
assert.equal(this.value, DEFAULT_VALUE);
}
});
componentTest("focusAfterOnChange", {
template:
"{{d-button class='focus-me'}}{{single-select options=(hash focusAfterOnchange=focusAfterOnchange) value=value content=content onChange=onChange}}",
beforeEach() {
this.setProperties({
onChange: () => {
find(".focus-me").focus();
this.set("value", "foo");
},
content: DEFAULT_CONTENT,
value: DEFAULT_VALUE
});
},
async test(assert) {
this.set("focusAfterOnchange", true);
await this.subject.expand();
await this.subject.selectRowByIndex(0);
assert.ok(
document.activeElement.classList.contains("single-select-header"),
"it selects the header"
);
this.set("focusAfterOnchange", false);
await this.subject.expand();
await this.subject.selectRowByIndex(0);
assert.notOk(
document.activeElement.classList.contains("single-select-header"),
"it doesnt select the header"
);
}
});