[FIX] web: core: domain supports domain as tuples

Have a domain declared somewhere in the XML as:
`("&", ("field", "=", "value"), ("field2", "=", "value2"))`

Before this commit, that expression made the Domain algorithm crash, because tuples
were not allowed.

After this commit, only tuples containing at least one other tuple and some optional strings are accepted.

closes odoo/odoo#97850

Signed-off-by: Mathieu Duckerts-Antoine <dam@odoo.com>
This commit is contained in:
Lucas Perais
2022-08-16 16:28:14 +02:00
committed by Mathieu Duckerts-Antoine
parent eb05ce9111
commit d9257d3aae
2 changed files with 39 additions and 6 deletions
+14 -3
View File
@@ -152,20 +152,31 @@ function toAST(domain) {
function normalizeDomainAST(domain, op = "&") {
if (domain.type !== 4 /* List */) {
throw new InvalidDomainError("Invalid domain AST");
if (domain.type === 10 /* Tuple */) {
const value = domain.value;
/* Tuple contains at least one Tuple and optionally string */
if (
value.findIndex((e) => e.type === 10) === -1 ||
!value.every((e) => e.type === 10 || e.type === 1)
) {
throw new InvalidDomainError("Invalid domain AST");
}
} else {
throw new InvalidDomainError("Invalid domain AST");
}
}
if (domain.value.length === 0) {
return domain;
}
let expected = 1;
for (let child of domain.value) {
for (const child of domain.value) {
if (child.type === 1 /* String */ && (child.value === "&" || child.value === "|")) {
expected++;
} else if (child.type !== 1 /* String */ || child.value !== "!") {
expected--;
}
}
let values = domain.value.slice();
const values = domain.value.slice();
while (expected < 0) {
expected++;
values.unshift({ type: 1 /* String */, value: op });
+25 -3
View File
@@ -286,10 +286,18 @@ QUnit.module("domain", {}, () => {
assert.deepEqual(new Domain(domainStr).toList(), [["date", ">=", "2013-03-25"]]);
domainStr = "[('date', '>=', context_today() - relativedelta(days=30))]";
const domainList = new Domain(domainStr).toList(); // domain creation using `parseExpr` function since the parameter is a string.
assert.deepEqual(domainList[0][2], PyDate.create({ day: 25, month: 3, year: 2013 }), 'The right item in the rule in the domain should be a PyDate object');
assert.deepEqual(
domainList[0][2],
PyDate.create({ day: 25, month: 3, year: 2013 }),
"The right item in the rule in the domain should be a PyDate object"
);
assert.deepEqual(JSON.stringify(domainList), '[["date",">=","2013-03-25"]]');
const domainList2 = new Domain(domainList).toList(); // domain creation using `toAST` function since the parameter is a list.
assert.deepEqual(domainList2[0][2], PyDate.create({ day: 25, month: 3, year: 2013 }), 'The right item in the rule in the domain should be a PyDate object');
assert.deepEqual(
domainList2[0][2],
PyDate.create({ day: 25, month: 3, year: 2013 }),
"The right item in the rule in the domain should be a PyDate object"
);
assert.deepEqual(JSON.stringify(domainList2), '[["date",">=","2013-03-25"]]');
});
@@ -375,7 +383,7 @@ QUnit.module("domain", {}, () => {
QUnit.test("return simple (normalized) domains", function (assert) {
const domains = ["[]", `[("a", "=", 1)]`, `["!", ("a", "=", 1)]`];
for (let domain of domains) {
for (const domain of domains) {
assert.strictEqual(new Domain(domain).toString(), domain);
}
});
@@ -527,4 +535,18 @@ QUnit.module("domain", {}, () => {
`["!", ("a", "=", 1)]`
);
});
QUnit.test("tuple are supported", (assert) => {
assert.deepEqual(
new Domain(`(("field", "like", "string"), ("field", "like", "strOng"))`).toList(),
["&", ["field", "like", "string"], ["field", "like", "strOng"]]
);
assert.deepEqual(new Domain(`("!",("field", "like", "string"))`).toList(), [
"!",
["field", "like", "string"],
]);
assert.throws(() => new Domain(`(("field", "like", "string"))`), /Invalid domain AST/);
assert.throws(() => new Domain(`("&", "&", "|")`), /Invalid domain AST/);
assert.throws(() => new Domain(`("&", "&", 3)`), /Invalid domain AST/);
});
});