1052 lines
36 KiB
JavaScript
1052 lines
36 KiB
JavaScript
/** @odoo-module **/
|
|
|
|
import { patchDate, patchWithCleanup } from "@web/../tests/helpers/utils";
|
|
import { makeWithSearch, setupControlPanelServiceRegistry } from "./helpers";
|
|
|
|
import { Component, xml } from "@odoo/owl";
|
|
|
|
class TestComponent extends Component {}
|
|
TestComponent.template = xml`<div class="o_test_component"/>`;
|
|
|
|
async function makeSearchModel(params) {
|
|
const component = await makeWithSearch({
|
|
Component: TestComponent,
|
|
resModel: "foo",
|
|
searchViewId: false,
|
|
...params,
|
|
});
|
|
return component.env.searchModel;
|
|
}
|
|
|
|
function sanitizeSearchItems(model) {
|
|
// We should not access searchItems but there is a problem with getSearchItems:
|
|
// comparisons are not sent back in some cases
|
|
const searchItems = Object.values(model.searchItems);
|
|
return searchItems.map((searchItem) => {
|
|
const copy = Object.assign({}, searchItem);
|
|
delete copy.groupId;
|
|
delete copy.groupNumber;
|
|
delete copy.id;
|
|
return copy;
|
|
});
|
|
}
|
|
|
|
let serverData;
|
|
QUnit.module("Search", (hooks) => {
|
|
hooks.beforeEach(() => {
|
|
serverData = {
|
|
models: {
|
|
foo: {
|
|
fields: {
|
|
display_name: { string: "Displayed name", type: "char" },
|
|
foo: {
|
|
string: "Foo",
|
|
type: "char",
|
|
default: "My little Foo Value",
|
|
store: true,
|
|
sortable: true,
|
|
},
|
|
date_field: { string: "Date", type: "date", store: true, sortable: true },
|
|
float_field: { string: "Float", type: "float" },
|
|
bar: { string: "Bar", type: "many2one", relation: "partner" },
|
|
properties: {
|
|
string: "Properties",
|
|
type: "properties",
|
|
definition_record: "bar",
|
|
definition_record_field: "child_properties",
|
|
},
|
|
},
|
|
records: [],
|
|
},
|
|
partner: {
|
|
fields: {
|
|
foo: { string: "Foo", type: "char" },
|
|
bar: { string: "Bar", type: "boolean" },
|
|
int_field: { string: "Int Field", type: "integer", group_operator: "sum" },
|
|
company_id: { string: "company", type: "many2one", relation: "company" },
|
|
company_ids: {
|
|
string: "Companies",
|
|
type: "many2many",
|
|
relation: "company",
|
|
},
|
|
category_id: { string: "category", type: "many2one", relation: "category" },
|
|
state: {
|
|
string: "State",
|
|
type: "selection",
|
|
selection: [
|
|
["abc", "ABC"],
|
|
["def", "DEF"],
|
|
["ghi", "GHI"],
|
|
],
|
|
},
|
|
},
|
|
records: [
|
|
{
|
|
id: 1,
|
|
bar: true,
|
|
foo: "yop",
|
|
int_field: 1,
|
|
company_ids: [3],
|
|
company_id: 3,
|
|
state: "abc",
|
|
category_id: 6,
|
|
},
|
|
{
|
|
id: 2,
|
|
bar: true,
|
|
foo: "blip",
|
|
int_field: 2,
|
|
company_ids: [3],
|
|
company_id: 5,
|
|
state: "def",
|
|
category_id: 7,
|
|
},
|
|
{
|
|
id: 3,
|
|
bar: true,
|
|
foo: "gnap",
|
|
int_field: 4,
|
|
company_ids: [],
|
|
company_id: 3,
|
|
state: "ghi",
|
|
category_id: 7,
|
|
},
|
|
{
|
|
id: 4,
|
|
bar: false,
|
|
foo: "blip",
|
|
int_field: 8,
|
|
company_ids: [5],
|
|
company_id: 5,
|
|
state: "ghi",
|
|
category_id: 7,
|
|
},
|
|
],
|
|
},
|
|
company: {
|
|
fields: {
|
|
name: { string: "Display Name", type: "char" },
|
|
parent_id: {
|
|
string: "Parent company",
|
|
type: "many2one",
|
|
relation: "company",
|
|
},
|
|
category_id: { string: "Category", type: "many2one", relation: "category" },
|
|
},
|
|
records: [
|
|
{ id: 3, name: "asustek", category_id: 6 },
|
|
{ id: 5, name: "agrolait", category_id: 7 },
|
|
],
|
|
},
|
|
category: {
|
|
fields: {
|
|
name: { string: "Category Name", type: "char" },
|
|
},
|
|
records: [
|
|
{ id: 6, name: "gold" },
|
|
{ id: 7, name: "silver" },
|
|
],
|
|
},
|
|
},
|
|
views: {
|
|
"foo,false,search": `<search/>`,
|
|
"partner,false,search": `<search/>`,
|
|
},
|
|
};
|
|
setupControlPanelServiceRegistry();
|
|
});
|
|
|
|
QUnit.module("SearchModel");
|
|
|
|
QUnit.test("parsing empty arch", async function (assert) {
|
|
assert.expect(1);
|
|
const model = await makeSearchModel({ serverData });
|
|
assert.deepEqual(sanitizeSearchItems(model), []);
|
|
});
|
|
|
|
QUnit.test("parsing one field tag", async function (assert) {
|
|
assert.expect(1);
|
|
const model = await makeSearchModel({
|
|
serverData,
|
|
searchViewArch: `
|
|
<search>
|
|
<field name="bar"/>
|
|
</search>
|
|
`,
|
|
});
|
|
assert.deepEqual(sanitizeSearchItems(model), [
|
|
{
|
|
description: "Bar",
|
|
fieldName: "bar",
|
|
fieldType: "many2one",
|
|
type: "field",
|
|
},
|
|
]);
|
|
});
|
|
|
|
QUnit.test("parsing one separator tag", async function (assert) {
|
|
assert.expect(1);
|
|
const model = await makeSearchModel({
|
|
serverData,
|
|
searchViewArch: `
|
|
<search>
|
|
<separator/>
|
|
</search>
|
|
`,
|
|
});
|
|
assert.deepEqual(sanitizeSearchItems(model), []);
|
|
});
|
|
|
|
QUnit.test("parsing one separator tag and one field tag", async function (assert) {
|
|
assert.expect(1);
|
|
const model = await makeSearchModel({
|
|
serverData,
|
|
searchViewArch: `
|
|
<search>
|
|
<separator/>
|
|
<field name="bar"/>
|
|
</search>
|
|
`,
|
|
});
|
|
assert.deepEqual(sanitizeSearchItems(model), [
|
|
{
|
|
description: "Bar",
|
|
fieldName: "bar",
|
|
fieldType: "many2one",
|
|
type: "field",
|
|
},
|
|
]);
|
|
});
|
|
|
|
QUnit.test("parsing one filter tag", async function (assert) {
|
|
assert.expect(1);
|
|
const model = await makeSearchModel({
|
|
serverData,
|
|
searchViewArch: `
|
|
<search>
|
|
<filter name="filter" string="Hello" domain="[]"/>
|
|
</search>
|
|
`,
|
|
});
|
|
assert.deepEqual(sanitizeSearchItems(model), [
|
|
{
|
|
description: "Hello",
|
|
domain: "[]",
|
|
name: "filter",
|
|
type: "filter",
|
|
},
|
|
]);
|
|
});
|
|
|
|
QUnit.test(
|
|
"parsing one filter tag with default_period date attribute",
|
|
async function (assert) {
|
|
assert.expect(1);
|
|
const model = await makeSearchModel({
|
|
serverData,
|
|
searchViewArch: `
|
|
<search>
|
|
<filter name="date_filter" string="Date" date="date_field" default_period="this_year,last_year"/>
|
|
</search>
|
|
`,
|
|
});
|
|
const dateFilterId = model.getSearchItems((f) => f.type === "dateFilter")[0].id;
|
|
assert.deepEqual(sanitizeSearchItems(model), [
|
|
{
|
|
defaultGeneratorIds: ["this_year", "last_year"],
|
|
description: "Date",
|
|
fieldName: "date_field",
|
|
fieldType: "date",
|
|
type: "dateFilter",
|
|
name: "date_filter",
|
|
},
|
|
{
|
|
comparisonOptionId: "previous_period",
|
|
dateFilterId,
|
|
description: "Date: Previous Period",
|
|
type: "comparison",
|
|
},
|
|
{
|
|
comparisonOptionId: "previous_year",
|
|
dateFilterId,
|
|
description: "Date: Previous Year",
|
|
type: "comparison",
|
|
},
|
|
]);
|
|
}
|
|
);
|
|
|
|
QUnit.test("parsing one filter tag with date attribute ", async function (assert) {
|
|
assert.expect(1);
|
|
const model = await makeSearchModel({
|
|
serverData,
|
|
searchViewArch: `
|
|
<search>
|
|
<filter name="date_filter" string="Date" date="date_field"/>
|
|
</search>
|
|
`,
|
|
});
|
|
const dateFilterId = model.getSearchItems((f) => f.type === "dateFilter")[0].id;
|
|
assert.deepEqual(sanitizeSearchItems(model), [
|
|
{
|
|
defaultGeneratorIds: ["this_month"],
|
|
description: "Date",
|
|
fieldName: "date_field",
|
|
fieldType: "date",
|
|
name: "date_filter",
|
|
type: "dateFilter",
|
|
},
|
|
{
|
|
comparisonOptionId: "previous_period",
|
|
dateFilterId,
|
|
description: "Date: Previous Period",
|
|
type: "comparison",
|
|
},
|
|
{
|
|
comparisonOptionId: "previous_year",
|
|
dateFilterId,
|
|
description: "Date: Previous Year",
|
|
type: "comparison",
|
|
},
|
|
]);
|
|
});
|
|
|
|
QUnit.test("parsing one groupBy tag", async function (assert) {
|
|
assert.expect(1);
|
|
const model = await makeSearchModel({
|
|
serverData,
|
|
searchViewArch: `
|
|
<search>
|
|
<filter name="groupby" string="Hi" context="{ 'group_by': 'date_field:day'}"/>
|
|
</search>
|
|
`,
|
|
});
|
|
assert.deepEqual(sanitizeSearchItems(model), [
|
|
{
|
|
defaultIntervalId: "day",
|
|
description: "Hi",
|
|
fieldName: "date_field",
|
|
fieldType: "date",
|
|
name: "groupby",
|
|
type: "dateGroupBy",
|
|
},
|
|
]);
|
|
});
|
|
|
|
QUnit.test("parsing two filter tags", async function (assert) {
|
|
assert.expect(1);
|
|
const model = await makeSearchModel({
|
|
serverData,
|
|
searchViewArch: `
|
|
<search>
|
|
<filter name="filter_1" string="Hello One" domain="[]"/>
|
|
<filter name="filter_2" string="Hello Two" domain="[('bar', '=', 3)]"/>
|
|
</search>
|
|
`,
|
|
});
|
|
assert.deepEqual(sanitizeSearchItems(model), [
|
|
{
|
|
description: "Hello One",
|
|
domain: "[]",
|
|
name: "filter_1",
|
|
type: "filter",
|
|
},
|
|
{
|
|
description: "Hello Two",
|
|
domain: "[('bar', '=', 3)]",
|
|
name: "filter_2",
|
|
type: "filter",
|
|
},
|
|
]);
|
|
});
|
|
|
|
QUnit.test("parsing two filter tags separated by a separator", async function (assert) {
|
|
assert.expect(1);
|
|
const model = await makeSearchModel({
|
|
serverData,
|
|
searchViewArch: `
|
|
<search>
|
|
<filter name="filter_1" string="Hello One" domain="[]"/>
|
|
<separator/>
|
|
<filter name="filter_2" string="Hello Two" domain="[('bar', '=', 3)]"/>
|
|
</search>
|
|
`,
|
|
});
|
|
assert.deepEqual(sanitizeSearchItems(model), [
|
|
{
|
|
description: "Hello One",
|
|
domain: "[]",
|
|
name: "filter_1",
|
|
type: "filter",
|
|
},
|
|
{
|
|
description: "Hello Two",
|
|
domain: "[('bar', '=', 3)]",
|
|
name: "filter_2",
|
|
type: "filter",
|
|
},
|
|
]);
|
|
});
|
|
|
|
QUnit.test("parsing one filter tag and one field", async function (assert) {
|
|
assert.expect(1);
|
|
const model = await makeSearchModel({
|
|
serverData,
|
|
searchViewArch: `
|
|
<search>
|
|
<filter name="filter" string="Hello" domain="[]"/>
|
|
<field name="bar"/>
|
|
</search>
|
|
`,
|
|
});
|
|
assert.deepEqual(sanitizeSearchItems(model), [
|
|
{
|
|
description: "Hello",
|
|
domain: "[]",
|
|
name: "filter",
|
|
type: "filter",
|
|
},
|
|
{
|
|
description: "Bar",
|
|
fieldName: "bar",
|
|
fieldType: "many2one",
|
|
type: "field",
|
|
},
|
|
]);
|
|
});
|
|
|
|
QUnit.test("parsing two field tags", async function (assert) {
|
|
assert.expect(1);
|
|
const model = await makeSearchModel({
|
|
serverData,
|
|
searchViewArch: `
|
|
<search>
|
|
<field name="foo"/>
|
|
<field name="bar"/>
|
|
</search>
|
|
`,
|
|
});
|
|
assert.deepEqual(sanitizeSearchItems(model), [
|
|
{
|
|
description: "Foo",
|
|
fieldName: "foo",
|
|
fieldType: "char",
|
|
type: "field",
|
|
},
|
|
{
|
|
description: "Bar",
|
|
fieldName: "bar",
|
|
fieldType: "many2one",
|
|
type: "field",
|
|
},
|
|
]);
|
|
});
|
|
|
|
QUnit.test("parsing a searchpanel tag", async function (assert) {
|
|
assert.expect(1);
|
|
const model = await makeSearchModel({
|
|
serverData,
|
|
searchViewArch: `
|
|
<search>
|
|
<searchpanel/>
|
|
</search>
|
|
`,
|
|
config: { viewType: "kanban" },
|
|
});
|
|
assert.deepEqual(model.getSections(), []);
|
|
});
|
|
|
|
QUnit.test("parsing a searchpanel field select one", async function (assert) {
|
|
assert.expect(1);
|
|
const model = await makeSearchModel({
|
|
serverData,
|
|
searchViewArch: `
|
|
<search>
|
|
<searchpanel>
|
|
<field name="company_id"/>
|
|
</searchpanel>
|
|
</search>
|
|
`,
|
|
resModel: "partner",
|
|
config: { viewType: "kanban" },
|
|
});
|
|
const sections = model.getSections();
|
|
for (const section of sections) {
|
|
section.values = [...section.values];
|
|
}
|
|
assert.deepEqual(sections, [
|
|
{
|
|
activeValueId: false,
|
|
color: null,
|
|
description: "company",
|
|
empty: false,
|
|
enableCounters: false,
|
|
expand: false,
|
|
fieldName: "company_id",
|
|
hierarchize: true,
|
|
icon: "fa-folder",
|
|
id: 1,
|
|
limit: 200,
|
|
parentField: "parent_id",
|
|
rootIds: [false, 3, 5],
|
|
type: "category",
|
|
values: [
|
|
[
|
|
false,
|
|
{
|
|
bold: true,
|
|
childrenIds: [],
|
|
display_name: "All",
|
|
id: false,
|
|
parentId: false,
|
|
},
|
|
],
|
|
[
|
|
3,
|
|
{
|
|
childrenIds: [],
|
|
display_name: "asustek",
|
|
id: 3,
|
|
parentId: false,
|
|
parent_id: false,
|
|
},
|
|
],
|
|
[
|
|
5,
|
|
{
|
|
childrenIds: [],
|
|
display_name: "agrolait",
|
|
id: 5,
|
|
parentId: false,
|
|
parent_id: false,
|
|
},
|
|
],
|
|
],
|
|
},
|
|
]);
|
|
});
|
|
|
|
QUnit.test("parsing a searchpanel field select multi", async function (assert) {
|
|
assert.expect(1);
|
|
const model = await makeSearchModel({
|
|
serverData,
|
|
searchViewArch: `
|
|
<search>
|
|
<searchpanel>
|
|
<field name="company_id" select="multi"/>
|
|
</searchpanel>
|
|
</search>
|
|
`,
|
|
resModel: "partner",
|
|
config: { viewType: "kanban" },
|
|
});
|
|
const sections = model.getSections();
|
|
for (const section of sections) {
|
|
section.values = [...section.values];
|
|
}
|
|
assert.deepEqual(sections, [
|
|
{
|
|
color: null,
|
|
description: "company",
|
|
domain: "[]",
|
|
empty: false,
|
|
enableCounters: false,
|
|
expand: false,
|
|
fieldName: "company_id",
|
|
groupBy: null,
|
|
icon: "fa-filter",
|
|
id: 1,
|
|
limit: 200,
|
|
type: "filter",
|
|
values: [
|
|
[
|
|
3,
|
|
{
|
|
checked: false,
|
|
display_name: "asustek",
|
|
id: 3,
|
|
},
|
|
],
|
|
[
|
|
5,
|
|
{
|
|
checked: false,
|
|
display_name: "agrolait",
|
|
id: 5,
|
|
},
|
|
],
|
|
],
|
|
},
|
|
]);
|
|
});
|
|
|
|
QUnit.test("parsing a filter and a dateFilter", async function (assert) {
|
|
assert.expect(1);
|
|
const model = await makeSearchModel({
|
|
serverData,
|
|
searchViewArch: `
|
|
<search>
|
|
<filter name="filter" string="Filter" domain="[['foo', '=', 'a']]"/>
|
|
<filter name="date_filter" string="Date" date="date_field"/>
|
|
</search>
|
|
`,
|
|
});
|
|
const groupNumbers = model.getSearchItems(() => true).map((i) => i.groupNumber);
|
|
assert.deepEqual(groupNumbers, [1, 1]);
|
|
});
|
|
|
|
QUnit.test("parsing a groupBy and a dateGroupBy", async function (assert) {
|
|
assert.expect(1);
|
|
const model = await makeSearchModel({
|
|
serverData,
|
|
searchViewArch: `
|
|
<search>
|
|
<filter name="group_by" context="{ 'group_by': 'foo'}"/>
|
|
<filter name="date_groupBy" string="DateGroupBy" context="{'group_by': 'date_field:day'}"/>
|
|
</search>
|
|
`,
|
|
});
|
|
const groupNumbers = model.getSearchItems(() => true).map((i) => i.groupNumber);
|
|
assert.deepEqual(groupNumbers, [1, 1]);
|
|
});
|
|
|
|
QUnit.test("parsing a filter and a groupBy", async function (assert) {
|
|
assert.expect(1);
|
|
const model = await makeSearchModel({
|
|
serverData,
|
|
searchViewArch: `
|
|
<search>
|
|
<filter name="filter" string="Filter" domain="[['foo', '=', 'a']]"/>
|
|
<filter name="group_by" context="{ 'group_by': 'foo'}"/>
|
|
</search>
|
|
`,
|
|
});
|
|
const groupNumbers = model.getSearchItems(() => true).map((i) => i.groupNumber);
|
|
assert.deepEqual(groupNumbers, [1, 2]);
|
|
});
|
|
|
|
QUnit.test("parsing a groupBy and a filter", async function (assert) {
|
|
assert.expect(1);
|
|
const model = await makeSearchModel({
|
|
serverData,
|
|
searchViewArch: `
|
|
<search>
|
|
<filter name="group_by" context="{ 'group_by': 'foo'}"/>
|
|
<filter name="filter" string="Filter" domain="[['foo', '=', 'a']]"/>
|
|
</search>
|
|
`,
|
|
});
|
|
const groupNumbers = model.getSearchItems(() => true).map((i) => i.groupNumber);
|
|
assert.deepEqual(groupNumbers, [2, 1]);
|
|
});
|
|
|
|
QUnit.test("process search default group by", async function (assert) {
|
|
assert.expect(1);
|
|
const model = await makeSearchModel({
|
|
serverData,
|
|
searchViewArch: `
|
|
<search>
|
|
<filter name="group_by" context="{ 'group_by': 'foo'}"/>
|
|
</search>
|
|
`,
|
|
context: { search_default_group_by: 14 },
|
|
});
|
|
assert.deepEqual(sanitizeSearchItems(model), [
|
|
{
|
|
defaultRank: 14,
|
|
description: "Foo",
|
|
fieldName: "foo",
|
|
fieldType: "char",
|
|
name: "group_by",
|
|
type: "groupBy",
|
|
isDefault: true,
|
|
},
|
|
]);
|
|
});
|
|
|
|
QUnit.test("process and toggle a field with a context to evaluate", async function (assert) {
|
|
assert.expect(2);
|
|
const model = await makeSearchModel({
|
|
serverData,
|
|
searchViewArch: `
|
|
<search>
|
|
<field name="foo" context="{ 'a': self }"/>
|
|
</search>
|
|
`,
|
|
});
|
|
assert.deepEqual(sanitizeSearchItems(model), [
|
|
{
|
|
context: "{ 'a': self }",
|
|
description: "Foo",
|
|
fieldName: "foo",
|
|
fieldType: "char",
|
|
type: "field",
|
|
},
|
|
]);
|
|
model.addAutoCompletionValues(1, { label: "7", operator: "=", value: 7 });
|
|
assert.deepEqual(model.context, { a: [7], lang: "en", tz: "taht", uid: 7 });
|
|
});
|
|
|
|
QUnit.test("process favorite filters", async function (assert) {
|
|
assert.expect(1);
|
|
const model = await makeSearchModel({
|
|
serverData,
|
|
irFilters: [
|
|
{
|
|
user_id: [2, "Mitchell Admin"],
|
|
name: "Sorted filter",
|
|
id: 5,
|
|
context: `{"group_by":["foo","bar"]}`,
|
|
sort: '["foo", "-bar"]',
|
|
domain: "[('user_id', '=', uid)]",
|
|
is_default: false,
|
|
model_id: "res.partner",
|
|
action_id: false,
|
|
},
|
|
],
|
|
});
|
|
assert.deepEqual(sanitizeSearchItems(model), [
|
|
{
|
|
context: {},
|
|
description: "Sorted filter",
|
|
domain: "[('user_id', '=', uid)]",
|
|
groupBys: ["foo", "bar"],
|
|
orderBy: [
|
|
{
|
|
asc: true,
|
|
name: "foo",
|
|
},
|
|
{
|
|
asc: false,
|
|
name: "bar",
|
|
},
|
|
],
|
|
removable: true,
|
|
serverSideId: 5,
|
|
type: "favorite",
|
|
userId: 2,
|
|
},
|
|
]);
|
|
});
|
|
|
|
QUnit.test("process dynamic filters", async function (assert) {
|
|
assert.expect(1);
|
|
assert.expect(1);
|
|
const model = await makeSearchModel({
|
|
serverData,
|
|
dynamicFilters: [
|
|
{
|
|
description: "Quick search",
|
|
domain: [["id", "in", [1, 3, 4]]],
|
|
},
|
|
],
|
|
});
|
|
assert.deepEqual(sanitizeSearchItems(model), [
|
|
{
|
|
description: "Quick search",
|
|
domain: [["id", "in", [1, 3, 4]]],
|
|
isDefault: true,
|
|
type: "filter",
|
|
},
|
|
]);
|
|
});
|
|
|
|
QUnit.test("process a dynamic filter with a isDefault key to false", async function (assert) {
|
|
const model = await makeSearchModel({
|
|
serverData,
|
|
dynamicFilters: [
|
|
{
|
|
description: "Quick search",
|
|
domain: [],
|
|
is_default: false,
|
|
},
|
|
],
|
|
});
|
|
assert.deepEqual(sanitizeSearchItems(model), [
|
|
{
|
|
description: "Quick search",
|
|
domain: [],
|
|
isDefault: false,
|
|
type: "filter",
|
|
},
|
|
]);
|
|
});
|
|
|
|
QUnit.test("toggle a filter", async function (assert) {
|
|
assert.expect(1);
|
|
assert.expect(3);
|
|
const model = await makeSearchModel({
|
|
serverData,
|
|
searchViewArch: `
|
|
<search>
|
|
<filter name="filter" string="Filter" domain="[['foo', '=', 'a']]"/>
|
|
</search>
|
|
`,
|
|
});
|
|
const filterId = Object.keys(model.searchItems).map((key) => Number(key))[0];
|
|
assert.deepEqual([], model.domain);
|
|
model.toggleSearchItem(filterId);
|
|
assert.deepEqual([["foo", "=", "a"]], model.domain);
|
|
model.toggleSearchItem(filterId);
|
|
assert.deepEqual([], model.domain);
|
|
});
|
|
|
|
QUnit.test("toggle a date filter", async function (assert) {
|
|
assert.expect(3);
|
|
patchDate(2019, 0, 6, 15, 0, 0);
|
|
const model = await makeSearchModel({
|
|
serverData,
|
|
searchViewArch: `
|
|
<search>
|
|
<filter name="date_filter" date="date_field" string="DateFilter"/>
|
|
</search>
|
|
`,
|
|
});
|
|
const filterId = Object.keys(model.searchItems).map((key) => Number(key))[0];
|
|
model.toggleDateFilter(filterId);
|
|
assert.deepEqual(
|
|
["&", ["date_field", ">=", "2019-01-01"], ["date_field", "<=", "2019-01-31"]],
|
|
model.domain
|
|
);
|
|
model.toggleDateFilter(filterId, "first_quarter");
|
|
assert.deepEqual(
|
|
[
|
|
"|",
|
|
"&",
|
|
["date_field", ">=", "2019-01-01"],
|
|
["date_field", "<=", "2019-01-31"],
|
|
"&",
|
|
["date_field", ">=", "2019-01-01"],
|
|
["date_field", "<=", "2019-03-31"],
|
|
],
|
|
model.domain
|
|
);
|
|
model.toggleDateFilter(filterId, "this_year");
|
|
assert.deepEqual([], model.domain);
|
|
});
|
|
|
|
QUnit.test("toggle a groupBy", async function (assert) {
|
|
assert.expect(3);
|
|
const model = await makeSearchModel({
|
|
serverData,
|
|
searchViewArch: `
|
|
<search>
|
|
<filter name="groupBy" string="GroupBy" context="{'group_by': 'foo'}"/>
|
|
</search>
|
|
`,
|
|
});
|
|
const filterId = Object.keys(model.searchItems).map((key) => Number(key))[0];
|
|
assert.deepEqual(model.groupBy, []);
|
|
model.toggleSearchItem(filterId);
|
|
assert.deepEqual(model.groupBy, ["foo"]);
|
|
model.toggleSearchItem(filterId);
|
|
assert.deepEqual(model.groupBy, []);
|
|
});
|
|
|
|
QUnit.test("toggle a date groupBy", async function (assert) {
|
|
assert.expect(5);
|
|
const model = await makeSearchModel({
|
|
serverData,
|
|
searchViewArch: `
|
|
<search>
|
|
<filter name="date_groupBy" string="DateGroupBy" context="{'group_by': 'date_field:day'}"/>
|
|
</search>
|
|
`,
|
|
});
|
|
const filterId = Object.keys(model.searchItems).map((key) => Number(key))[0];
|
|
assert.deepEqual(model.groupBy, []);
|
|
model.toggleDateGroupBy(filterId);
|
|
assert.deepEqual(model.groupBy, ["date_field:day"]);
|
|
model.toggleDateGroupBy(filterId, "week");
|
|
assert.deepEqual(model.groupBy, ["date_field:week", "date_field:day"]);
|
|
model.toggleDateGroupBy(filterId);
|
|
assert.deepEqual(model.groupBy, ["date_field:week"]);
|
|
model.toggleDateGroupBy(filterId, "week");
|
|
assert.deepEqual(model.groupBy, []);
|
|
});
|
|
|
|
QUnit.test("create a new groupBy", async function (assert) {
|
|
assert.expect(2);
|
|
const model = await makeSearchModel({ serverData });
|
|
model.createNewGroupBy("foo");
|
|
assert.deepEqual(sanitizeSearchItems(model), [
|
|
{
|
|
custom: true,
|
|
description: "Foo",
|
|
fieldName: "foo",
|
|
fieldType: "char",
|
|
type: "groupBy",
|
|
},
|
|
]);
|
|
assert.deepEqual(model.groupBy, ["foo"]);
|
|
});
|
|
|
|
QUnit.test("create a new dateGroupBy", async function (assert) {
|
|
assert.expect(2);
|
|
const model = await makeSearchModel({
|
|
serverData,
|
|
searchViewArch: `
|
|
<search>
|
|
<filter name="foo" string="Foo" context="{'group_by': 'foo'}"/>
|
|
</search>
|
|
`,
|
|
});
|
|
model.createNewGroupBy("date_field");
|
|
assert.deepEqual(sanitizeSearchItems(model), [
|
|
{
|
|
description: "Foo",
|
|
fieldName: "foo",
|
|
fieldType: "char",
|
|
name: "foo",
|
|
type: "groupBy",
|
|
},
|
|
{
|
|
custom: true,
|
|
defaultIntervalId: "month",
|
|
description: "Date",
|
|
fieldName: "date_field",
|
|
fieldType: "date",
|
|
type: "dateGroupBy",
|
|
},
|
|
]);
|
|
assert.deepEqual(model.groupBy, ["date_field:month"]);
|
|
});
|
|
|
|
QUnit.test("dynamic domains evaluation", async function (assert) {
|
|
patchDate(2021, 8, 17, 10, 0, 0);
|
|
|
|
patchWithCleanup(Date.prototype, {
|
|
getTimezoneOffset() {
|
|
return -120;
|
|
},
|
|
});
|
|
|
|
const searchViewArch = `
|
|
<search>
|
|
<filter name="filter_0" domain="[('datetime', '=', (datetime.datetime.combine(context_today(), datetime.time(0,0,0)).to_utc()))]"/>
|
|
<filter name="filter_1" domain="[('date', '=', context_today() + relativedelta(days=-365))]"/>
|
|
<filter name="filter_2" domain="[('create_date', '>', (context_today() - datetime.timedelta(days=1)).strftime('%Y-%m-%d'))]"/>
|
|
<filter name="filter_3" domain="[('date_deadline', '<', current_date)]"/>
|
|
</search>
|
|
`;
|
|
|
|
const evaluatedDomains = [
|
|
[["datetime", "=", "2021-09-16 22:00:00"]],
|
|
[["date", "=", "2020-09-17"]],
|
|
[["create_date", ">", "2021-09-16"]],
|
|
[["date_deadline", "<", "2021-09-17"]],
|
|
];
|
|
|
|
const model = await makeSearchModel({ serverData, searchViewArch });
|
|
|
|
for (let i = 0; i < evaluatedDomains.length; i++) {
|
|
model.toggleSearchItem(i + 1);
|
|
assert.deepEqual(model.domain, evaluatedDomains[i]);
|
|
model.toggleSearchItem(i + 1);
|
|
}
|
|
});
|
|
|
|
QUnit.test("dynamic domains evaluation using global context", async function (assert) {
|
|
const searchViewArch = `
|
|
<search>
|
|
<filter name="filter" domain="[('date_deadline', '<', context.get('my_date'))]"/>
|
|
</search>
|
|
`;
|
|
|
|
const model = await makeSearchModel({
|
|
serverData,
|
|
searchViewArch,
|
|
context: {
|
|
my_date: "2021-09-17",
|
|
},
|
|
});
|
|
|
|
model.toggleSearchItem(1);
|
|
assert.deepEqual(model.domain, [["date_deadline", "<", "2021-09-17"]]);
|
|
});
|
|
|
|
QUnit.test("field tags with invisible attribute", async function (assert) {
|
|
const model = await makeSearchModel({
|
|
serverData,
|
|
searchViewArch: `
|
|
<search>
|
|
<field name="foo" invisible="context.get('abc')"/>
|
|
<field name="bar" invisible="context.get('def')"/>
|
|
<field name="float_field" invisible="1"/>
|
|
</search>
|
|
`,
|
|
context: { abc: true },
|
|
});
|
|
assert.deepEqual(
|
|
model.getSearchItems((f) => f.type === "field").map((item) => item.fieldName),
|
|
["bar"]
|
|
);
|
|
});
|
|
|
|
QUnit.test("filter tags with invisible attribute", async function (assert) {
|
|
const model = await makeSearchModel({
|
|
serverData,
|
|
searchViewArch: `
|
|
<search>
|
|
<filter name="filter1" string="Invisible ABC" domain="[]" invisible="context.get('abc')"/>
|
|
<filter name="filter2" string="Invisible DEF" domain="[]" invisible="context.get('def')"/>
|
|
<filter name="filter3" string="Always invisible" domain="[]" invisible="1"/>
|
|
</search>
|
|
`,
|
|
context: { abc: true },
|
|
});
|
|
assert.deepEqual(
|
|
model
|
|
.getSearchItems((item) => ["filter", "dateFilter"].includes(item.type))
|
|
.map((item) => item.name),
|
|
["filter2"]
|
|
);
|
|
});
|
|
|
|
QUnit.test("no search items created for search panel sections", async function (assert) {
|
|
const model = await makeSearchModel({
|
|
serverData,
|
|
searchViewArch: `
|
|
<search>
|
|
<searchpanel>
|
|
<field name="company_id"/>
|
|
<field name="company_id" select="multi"/>
|
|
</searchpanel>
|
|
</search>
|
|
`,
|
|
resModel: "partner",
|
|
config: { viewType: "kanban" },
|
|
});
|
|
const sections = model.getSections();
|
|
assert.strictEqual(sections.length, 2);
|
|
assert.deepEqual(sanitizeSearchItems(model), []);
|
|
});
|
|
|
|
QUnit.test(
|
|
"a field of type 'properties' should not be accepted as a search_default",
|
|
async function (assert) {
|
|
const searchViewArch = `
|
|
<search>
|
|
<field name="properties"/>
|
|
</search>
|
|
`;
|
|
|
|
const model = await makeSearchModel({
|
|
serverData,
|
|
searchViewArch,
|
|
context: {
|
|
search_default_properties: true,
|
|
},
|
|
});
|
|
assert.deepEqual(sanitizeSearchItems(model), [
|
|
{
|
|
description: "Properties",
|
|
fieldName: "properties",
|
|
fieldType: "properties",
|
|
type: "field",
|
|
},
|
|
]);
|
|
}
|
|
);
|
|
});
|