[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:
committed by
Mathieu Duckerts-Antoine
parent
eb05ce9111
commit
d9257d3aae
@@ -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 });
|
||||
|
||||
@@ -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/);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user