2024-08-19 21:42:50 -04:00
|
|
|
import { fillIn, render } from "@ember/test-helpers";
|
2024-08-13 04:03:26 -04:00
|
|
|
import hbs from "htmlbars-inline-precompile";
|
|
|
|
import { module, test } from "qunit";
|
|
|
|
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
|
2024-08-19 21:42:50 -04:00
|
|
|
import formKit from "discourse/tests/helpers/form-kit-helper";
|
2024-08-13 04:03:26 -04:00
|
|
|
import selectKit from "discourse/tests/helpers/select-kit-helper";
|
2024-08-22 05:46:12 -04:00
|
|
|
import { ERRORS } from "discourse/plugins/discourse-data-explorer/discourse/components/param-input-form";
|
2024-08-19 21:42:50 -04:00
|
|
|
|
|
|
|
const InputTestCases = [
|
|
|
|
{
|
|
|
|
type: "string",
|
|
|
|
default: "foo",
|
|
|
|
initial: "bar",
|
|
|
|
tests: [
|
|
|
|
{ input: "", data_null: "", error: ERRORS.REQUIRED },
|
|
|
|
{ input: " ", data_null: " ", error: ERRORS.REQUIRED },
|
|
|
|
{ input: "str", data: "str" },
|
|
|
|
],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: "int",
|
|
|
|
default: "123",
|
|
|
|
initial: "456",
|
|
|
|
tests: [
|
|
|
|
{ input: "", data_null: "", error: ERRORS.REQUIRED },
|
|
|
|
{ input: "1234", data: "1234" },
|
|
|
|
{ input: "0", data: "0" },
|
|
|
|
{ input: "-2147483648", data: "-2147483648" },
|
|
|
|
{ input: "2147483649", error: ERRORS.OVERFLOW_HIGH },
|
|
|
|
{ input: "-2147483649", error: ERRORS.OVERFLOW_LOW },
|
|
|
|
],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: "bigint",
|
|
|
|
default: "123",
|
|
|
|
initial: "456",
|
|
|
|
tests: [
|
|
|
|
{ input: "", data_null: undefined, error: ERRORS.REQUIRED },
|
|
|
|
{ input: "123", data: "123" },
|
|
|
|
{ input: "0", data: "0" },
|
|
|
|
{ input: "-2147483649", data: "-2147483649" },
|
|
|
|
{ input: "2147483649", data: "2147483649" },
|
|
|
|
{ input: "abcd", error: ERRORS.NOT_A_NUMBER },
|
|
|
|
{ input: "114.514", error: ERRORS.NOT_AN_INTEGER },
|
|
|
|
],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: "category_id",
|
|
|
|
default: "4",
|
|
|
|
initial: "3",
|
|
|
|
tests: [
|
|
|
|
{
|
|
|
|
input: null,
|
2024-08-21 03:41:02 -04:00
|
|
|
data_null: "",
|
2024-08-19 21:42:50 -04:00
|
|
|
error: ERRORS.REQUIRED,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
input: async () => {
|
|
|
|
const categoryChooser = selectKit(".category-chooser");
|
|
|
|
|
|
|
|
await categoryChooser.expand();
|
|
|
|
await categoryChooser.selectRowByValue(2);
|
|
|
|
},
|
|
|
|
data: "2",
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
2024-08-22 05:46:12 -04:00
|
|
|
{
|
|
|
|
type: "group_id",
|
|
|
|
default: "trust_level_1",
|
|
|
|
initial: "trust_level_3",
|
|
|
|
tests: [
|
|
|
|
{
|
|
|
|
input: null,
|
|
|
|
data_null: undefined,
|
|
|
|
error: ERRORS.REQUIRED,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
input: async () => {
|
|
|
|
const groupChooser = selectKit(".group-chooser");
|
|
|
|
await groupChooser.expand();
|
|
|
|
await groupChooser.selectRowByValue("trust_level_2");
|
|
|
|
},
|
|
|
|
data: "trust_level_2",
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: "group_list",
|
|
|
|
default: "trust_level_1",
|
|
|
|
initial: "trust_level_3,trust_level_4",
|
|
|
|
tests: [
|
|
|
|
{
|
|
|
|
input: null,
|
|
|
|
data_null: "",
|
|
|
|
error: ERRORS.REQUIRED,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
2024-08-22 11:24:12 -04:00
|
|
|
{
|
|
|
|
type: "date",
|
|
|
|
default: "2024-07-13",
|
|
|
|
initial: "1970-01-01",
|
|
|
|
tests: [
|
|
|
|
{
|
|
|
|
input: null,
|
|
|
|
data_null: undefined,
|
|
|
|
error: ERRORS.REQUIRED,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
input: "2038-01-20",
|
|
|
|
data: "2038-01-20",
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: "time",
|
|
|
|
default: "12:34",
|
|
|
|
initial: "11:45",
|
|
|
|
tests: [
|
|
|
|
{
|
|
|
|
input: null,
|
|
|
|
data_null: undefined,
|
|
|
|
error: ERRORS.REQUIRED,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
input: "03:14",
|
|
|
|
data: "03:14",
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: "datetime",
|
|
|
|
default: "2024-07-13 12:00",
|
|
|
|
initial: "1970-01-01 00:00",
|
|
|
|
tests: [
|
|
|
|
{
|
|
|
|
input: null,
|
|
|
|
data_null: undefined,
|
|
|
|
error: ERRORS.REQUIRED,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
input: "2038-01-19 03:15",
|
|
|
|
data: "2038-01-19 03:15",
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
2024-08-19 21:42:50 -04:00
|
|
|
];
|
2024-08-13 04:03:26 -04:00
|
|
|
|
|
|
|
module("Data Explorer Plugin | Component | param-input", function (hooks) {
|
|
|
|
setupRenderingTest(hooks);
|
|
|
|
|
2024-08-19 21:42:50 -04:00
|
|
|
for (const testcase of InputTestCases) {
|
|
|
|
for (const config of [
|
|
|
|
{ default: testcase.default },
|
|
|
|
{ nullable: false, initial: testcase.initial },
|
|
|
|
{ nullable: false, default: testcase.default, initial: testcase.initial },
|
|
|
|
{ nullable: true },
|
|
|
|
]) {
|
|
|
|
const testName = ["type"];
|
|
|
|
if (config.nullable) {
|
|
|
|
testName.push("nullable");
|
|
|
|
}
|
|
|
|
testName.push(testcase.type);
|
|
|
|
if (config.initial) {
|
|
|
|
testName.push("with initial value");
|
|
|
|
}
|
|
|
|
if (config.initial) {
|
|
|
|
testName.push("with default");
|
|
|
|
}
|
|
|
|
|
|
|
|
test(testName.join(" "), async function (assert) {
|
|
|
|
this.setProperties({
|
|
|
|
param_info: [
|
|
|
|
{
|
|
|
|
identifier: testcase.type,
|
|
|
|
type: testcase.type,
|
|
|
|
default: config.default ?? null,
|
|
|
|
nullable: config.nullable,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
initialValues: config.initial
|
|
|
|
? { [testcase.type]: config.initial }
|
|
|
|
: {},
|
2024-08-21 03:41:02 -04:00
|
|
|
onRegisterApi: ({ submit, allNormalized }) => {
|
2024-08-19 21:42:50 -04:00
|
|
|
this.submit = submit;
|
2024-08-21 03:41:02 -04:00
|
|
|
this.allNormalized = allNormalized;
|
2024-08-19 21:42:50 -04:00
|
|
|
},
|
|
|
|
});
|
2024-08-13 04:03:26 -04:00
|
|
|
|
2024-08-19 21:42:50 -04:00
|
|
|
await render(hbs`
|
|
|
|
<ParamInputForm
|
|
|
|
@hasParams=true
|
|
|
|
@initialValues={{this.initialValues}}
|
|
|
|
@paramInfo={{this.param_info}}
|
|
|
|
@onRegisterApi={{this.onRegisterApi}}
|
|
|
|
/>`);
|
2024-08-13 04:03:26 -04:00
|
|
|
|
2024-08-21 03:41:02 -04:00
|
|
|
await this.allNormalized;
|
|
|
|
|
2024-08-19 21:42:50 -04:00
|
|
|
if (config.initial || config.default) {
|
|
|
|
const data = await this.submit();
|
|
|
|
const val = config.initial || config.default;
|
|
|
|
assert.strictEqual(
|
|
|
|
data[testcase.type],
|
|
|
|
val,
|
|
|
|
`has initial/default value "${val}"`
|
|
|
|
);
|
|
|
|
}
|
2024-08-13 04:03:26 -04:00
|
|
|
|
2024-08-19 21:42:50 -04:00
|
|
|
for (const t of testcase.tests) {
|
|
|
|
if (t.input == null && (config.initial || config.default)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
await formKit().reset();
|
|
|
|
if (t.input != null) {
|
|
|
|
if (typeof t.input === "function") {
|
|
|
|
await t.input();
|
|
|
|
} else {
|
|
|
|
await fillIn(`[name="${testcase.type}"]`, t.input);
|
|
|
|
}
|
|
|
|
}
|
2024-08-13 04:03:26 -04:00
|
|
|
|
2024-08-19 21:42:50 -04:00
|
|
|
if (config.nullable && "data_null" in t) {
|
|
|
|
const data = await this.submit();
|
|
|
|
assert.strictEqual(
|
|
|
|
data[testcase.type],
|
|
|
|
t.data_null,
|
|
|
|
`should have null data`
|
|
|
|
);
|
|
|
|
} else if (t.error) {
|
|
|
|
await formKit().submit();
|
|
|
|
assert.form().field(testcase.type).hasError(t.error);
|
|
|
|
} else {
|
|
|
|
const data = await this.submit();
|
|
|
|
assert.strictEqual(
|
|
|
|
data[testcase.type],
|
|
|
|
t.data,
|
|
|
|
`data should be "${t.data}"`
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
2024-08-19 22:09:48 -04:00
|
|
|
|
|
|
|
test("empty form will reject submit", async function (assert) {
|
|
|
|
this.setProperties({
|
|
|
|
param_info: [
|
|
|
|
{
|
|
|
|
identifier: "string",
|
|
|
|
type: "string",
|
|
|
|
default: null,
|
|
|
|
nullable: false,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
initialValues: {},
|
|
|
|
onRegisterApi: ({ submit }) => {
|
|
|
|
this.submit = submit;
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
await render(hbs`
|
|
|
|
<ParamInputForm
|
|
|
|
@initialValues={{this.initialValues}}
|
|
|
|
@paramInfo={{this.param_info}}
|
|
|
|
@onRegisterApi={{this.onRegisterApi}}
|
|
|
|
/>`);
|
|
|
|
|
|
|
|
assert.rejects(this.submit());
|
|
|
|
|
|
|
|
// After successfully submitting the test once, edit and submit again.
|
|
|
|
await fillIn(`[name="string"]`, "foo");
|
|
|
|
await this.submit();
|
|
|
|
await fillIn(`[name="string"]`, "");
|
|
|
|
assert.rejects(this.submit());
|
|
|
|
});
|
2024-08-21 03:41:02 -04:00
|
|
|
|
|
|
|
test("async normalizion", async function (assert) {
|
|
|
|
this.setProperties({
|
|
|
|
param_info: [
|
|
|
|
{
|
|
|
|
identifier: "category_id",
|
|
|
|
type: "category_id",
|
|
|
|
default: "support",
|
|
|
|
nullable: false,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
initialValues: {},
|
|
|
|
onRegisterApi: (paramInputApi) => {
|
|
|
|
this.paramInputApi = paramInputApi;
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
await render(hbs`
|
|
|
|
<ParamInputForm
|
|
|
|
@initialValues={{this.initialValues}}
|
|
|
|
@paramInfo={{this.param_info}}
|
|
|
|
@onRegisterApi={{this.onRegisterApi}}
|
|
|
|
/>`);
|
|
|
|
|
|
|
|
await this.paramInputApi.allNormalized;
|
|
|
|
|
|
|
|
this.paramInputApi.submit().then((res) => {
|
|
|
|
assert.strictEqual(res.category_id, "1003");
|
|
|
|
});
|
|
|
|
});
|
2024-08-22 05:46:12 -04:00
|
|
|
|
|
|
|
test("show error message when default value is invalid", async function (assert) {
|
|
|
|
this.setProperties({
|
|
|
|
param_info: [
|
|
|
|
{
|
|
|
|
identifier: "group_id",
|
|
|
|
type: "group_id",
|
|
|
|
default: "invalid_group_name",
|
|
|
|
nullable: false,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
initialValues: {},
|
|
|
|
onRegisterApi: () => {},
|
|
|
|
});
|
|
|
|
|
|
|
|
await render(hbs`
|
|
|
|
<ParamInputForm
|
|
|
|
@initialValues={{this.initialValues}}
|
|
|
|
@paramInfo={{this.param_info}}
|
|
|
|
@onRegisterApi={{this.onRegisterApi}}
|
|
|
|
/>`);
|
|
|
|
|
|
|
|
assert
|
|
|
|
.form()
|
|
|
|
.field("group_id")
|
|
|
|
.hasError(`${ERRORS.NO_SUCH_GROUP}: invalid_group_name`);
|
|
|
|
});
|
2024-08-22 11:24:12 -04:00
|
|
|
|
|
|
|
test("date, time, datetime with initial value in other formats", async function (assert) {
|
|
|
|
this.setProperties({
|
|
|
|
param_info: [
|
|
|
|
{
|
|
|
|
identifier: "date",
|
|
|
|
type: "date",
|
|
|
|
default: null,
|
|
|
|
nullable: false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
identifier: "time",
|
|
|
|
type: "time",
|
|
|
|
default: null,
|
|
|
|
nullable: false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
identifier: "datetime",
|
|
|
|
type: "datetime",
|
|
|
|
default: null,
|
|
|
|
nullable: false,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
initialValues: {
|
|
|
|
date: "19 January 2038",
|
|
|
|
time: "3:15 am",
|
|
|
|
datetime: "19 January 2038 3:15 am",
|
|
|
|
},
|
|
|
|
onRegisterApi: ({ submit }) => {
|
|
|
|
this.submit = submit;
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
await render(hbs`
|
|
|
|
<ParamInputForm
|
|
|
|
@initialValues={{this.initialValues}}
|
|
|
|
@paramInfo={{this.param_info}}
|
|
|
|
@onRegisterApi={{this.onRegisterApi}}
|
|
|
|
/>`);
|
|
|
|
|
|
|
|
this.submit().then((res) => {
|
|
|
|
assert.deepEqual(res, {
|
|
|
|
date: "2038-01-19",
|
|
|
|
time: "03:15",
|
|
|
|
datetime: "2038-01-19 03:15",
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
2024-08-13 04:03:26 -04:00
|
|
|
});
|