Skip to content

Commit

Permalink
Merge pull request #98 from gisce/feature/json-attrs-testing-and-impr…
Browse files Browse the repository at this point in the history
…ovement

attributeParser: Add same tests for json_Attrs and adjust behaviour
  • Loading branch information
mguellsegarra authored Nov 24, 2023
2 parents b363013 + 778ac48 commit d3b4eb3
Show file tree
Hide file tree
Showing 3 changed files with 272 additions and 12 deletions.
42 changes: 31 additions & 11 deletions src/helpers/attributeParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,13 @@ export const parseJsonAttributes = ({
return finalAttributes;
} catch (error) {
console.error(error);
throw new Error("Error parsing new json_attrs. Original string: " + attrs);
if (error instanceof SyntaxError) {
throw new Error(
"Error parsing new json_attrs. Original string: " + attrs,
);
} else {
throw error;
}
}
};

Expand All @@ -169,31 +175,45 @@ const evaluateAttributes = ({
values,
fields,
widgetType,
fallbackMode = true,
}: {
tagAttributes: any;
values: any;
fields: any;
widgetType?: string;
fallbackMode?: boolean;
}) => {
let newTagAttributes = {};

if (tagAttributes.json_attrs) {
newTagAttributes = parseJsonAttributes({
attrs: tagAttributes.json_attrs,
values,
});
} else if (tagAttributes.attrs) {
newTagAttributes = parseAttributes({
let finalTagAttributes = {};
let oldTagAttributes = {};
if (tagAttributes.attrs) {
oldTagAttributes = parseAttributes({
attrs: tagAttributes.attrs,
values,
fields,
widgetType,
});
}

if (tagAttributes.json_attrs) {
try {
finalTagAttributes = parseJsonAttributes({
attrs: tagAttributes.json_attrs,
values,
});
} catch (error) {
if (fallbackMode && tagAttributes.attrs) {
finalTagAttributes = oldTagAttributes;
} else {
throw error;
}
}
} else if (tagAttributes.attrs) {
finalTagAttributes = oldTagAttributes;
}

return {
...tagAttributes,
...newTagAttributes,
...finalTagAttributes,
attrs: undefined,
json_attrs: undefined,
};
Expand Down
29 changes: 29 additions & 0 deletions src/spec/Form.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3259,4 +3259,33 @@ describe("A Form", () => {
const buttonWidget = form.findById("example_button") as Button;
expect(buttonWidget.readOnly).toBeFalsy();
});
it("Should be able to parse a specifically enabled button even though in the form is disabled, with json_attrs", () => {
const arch = `<form>
<button name="example_button" string="Example" type="object" json_attrs="{'readonly': {'condition': 'AND', 'rules': [{'field': 'state', 'operator': '!=', 'value': 'actiu'}]}}" />
</form>`;
const form = new Form({
state: {
selection: [
["esborrany", "Esborrany"],
["actiu", "Actiu"],
["pendent", "Pendent d'activació"],
["baixa", "Baixa"],
["baixa2", "Baixa per modificació"],
["baixa3", "Baixa per renovació"],
["baixa4", "Baixa per nova pòlissa"],
],
string: "Estat",
type: "selection",
views: {},
},
});
form.parse(arch, {
readOnly: true,
values: {
state: "actiu",
},
});
const buttonWidget = form.findById("example_button") as Button;
expect(buttonWidget.readOnly).toBeFalsy();
});
});
213 changes: 212 additions & 1 deletion src/spec/attributeParser.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const fields = {
};

describe("An Attribute Parser", () => {
describe("in evaluateAttributes method", () => {
describe("in evaluateAttributes method with attrs", () => {
it("should properly parse a simple attribute with = operator", () => {
const tagAttributes = {
attrs: "{'invisible':[('per_enviar', '=', 'postal')]}",
Expand Down Expand Up @@ -277,4 +277,215 @@ describe("An Attribute Parser", () => {
).toStrictEqual({ invisible: true });
});
});
describe("in evaluateAttributes method with json_attrs", () => {
it("should properly parse a simple attribute with = operator", () => {
const tagAttributes = {
json_attrs: `{"invisible": {"condition": "AND", "rules": [{"field": "per_enviar", "operator": "=", "value": "postal"}]}}`,
};
const values = {
per_enviar: "postal",
};
const evaluatedAttrs = evaluateAttributes({
tagAttributes,
values,
fields,
fallbackMode: false,
});
expect(evaluatedAttrs.invisible).toBeTruthy();
});
it("should properly parse a simple attribute with == operator and numeric value", () => {
const tagAttributes = {
json_attrs: `{"invisible": {"condition": "AND", "rules": [{"field": "check_total", "operator": "==", "value": 0.0}]}}`,
};
const values = {
check_total: 0.0,
};
const evaluatedAttrs = evaluateAttributes({
tagAttributes,
values,
fields,
fallbackMode: false,
});
expect(evaluatedAttrs.invisible).toBeTruthy();
});
it("should properly parse a simple attribute with 'in' operator", () => {
const tagAttributes = {
json_attrs: `{"invisible": {"condition": "AND", "rules": [{"field": "rectificative_type", "operator": "in", "value": ["N", "C", "G"]}]}}`,
};
const values = {
rectificative_type: "G",
};
const evaluatedAttrs = evaluateAttributes({
tagAttributes,
values,
fields,
fallbackMode: false,
});
expect(evaluatedAttrs.invisible).toBeTruthy();
});
it("should properly parse a simple attribute with 'not_in' operator", () => {
const tagAttributes = {
json_attrs: `{"invisible": {"condition": "AND", "rules": [{"field": "type", "operator": "not in", "value": ["in_refund", "in_invoice"]}]}}`,
};
const values = {
type: "not_found_type",
};
const evaluatedAttrs = evaluateAttributes({
tagAttributes,
values,
fields,
fallbackMode: false,
});
expect(evaluatedAttrs.invisible).toBeTruthy();
});
it("should properly parse a boolean attribute with '>' operator", () => {
const tagAttributes = {
json_attrs: `{"readonly": {"condition": "AND", "rules": [{"field": "force_potencia_adscrita", "operator": "&gt;", "value": 0}]}}`,
};
const values = {
force_potencia_adscrita: 10,
};
const evaluatedAttrs = evaluateAttributes({
tagAttributes,
values,
fields,
fallbackMode: false,
});
expect(evaluatedAttrs.readonly).toBeTruthy();
});
it("should properly parse a boolean attribute with '<' operator", () => {
const tagAttributes = {
json_attrs: `{"readonly": {"condition": "AND", "rules": [{"field": "force_potencia_adscrita", "operator": "&lt;", "value": 10}]}}`,
};
const values = {
force_potencia_adscrita: 5,
};
const evaluatedAttrs = evaluateAttributes({
tagAttributes,
values,
fields,
fallbackMode: false,
});
expect(evaluatedAttrs.readonly).toBeTruthy();
});
it("should properly parse a boolean attribute with '=' operator", () => {
const tagAttributes = {
json_attrs: `{"readonly": {"condition": "AND", "rules": [{"field": "force_potencia_adscrita", "operator": "=", "value": 0}]}}`,
};
const values = {
force_potencia_adscrita: true,
};
const evaluatedAttrs = evaluateAttributes({
tagAttributes,
values,
fields,
fallbackMode: false,
});
expect(evaluatedAttrs.readonly).toBeFalsy();
});
it("should properly parse a boolean attribute with '=' operator with True", () => {
const tagAttributes = {
json_attrs: `{"readonly": {"condition": "AND", "rules": [{"field": "force_potencia_adscrita", "operator": "=", "value": true}]}}`,
};
const values = {
force_potencia_adscrita: true,
};
const evaluatedAttrs = evaluateAttributes({
tagAttributes,
values,
fields,
fallbackMode: false,
});
expect(evaluatedAttrs.readonly).toBeTruthy();
});
it("should properly parse a boolean attribute with several conditions", () => {
const tagAttributes = {
json_attrs: `{"invisible": {"condition": "AND", "rules": [{"field": "id", "operator": "!=", "value": false}, {"field": "link", "operator": "!=", "value": false}]}}`,
};
const values = {
id: 1,
link: false,
};
const evaluatedAttrs = evaluateAttributes({
tagAttributes,
values,
fields,
fallbackMode: false,
});
expect(evaluatedAttrs.invisible).toBeFalsy();
});
it("should properly parse a boolean attribute without value (default false)", () => {
const tagAttributes = {
json_attrs: `{"invisible": {"condition": "AND", "rules": [{"field": "change_adm", "operator": "!=", "value": true}]}}`,
};
const values = {};
const evaluatedAttrs = evaluateAttributes({
tagAttributes,
values,
fields,
fallbackMode: false,
});
expect(evaluatedAttrs.invisible).toBeTruthy();
});
// TODO: This test is failing
it.skip("should properly parse a boolean attribute without value (default true)", () => {
const tagAttributes = {
json_attrs: `{"invisible": {"condition": "AND", "rules": [{"field": "change_adm", "operator": "=", "value": false}]}}`,
};
const values = {};
const evaluatedAttrs = evaluateAttributes({
tagAttributes,
values,
fields,
fallbackMode: false,
});
expect(evaluatedAttrs.invisible).toBeTruthy();
});
it("should properly parse a many2one attribute with false value", () => {
const tagAttributes = {
json_attrs:
'{"invisible":{"condition":"AND","rules":[{"field":"autoconsum_id","operator":"=","value":false}]}}',
};
const values = { autoconsum_id: false };
const evaluatedAttrs = evaluateAttributes({
tagAttributes,
values,
fields,
fallbackMode: false,
});
expect(evaluatedAttrs.invisible).toBeTruthy();
});
// TODO: This test is failing
it.skip("should properly parse a many2one attribute with undefined value", () => {
const tagAttributes = {
json_attrs:
'{"invisible":{"condition":"AND","rules":[{"field":"autoconsum_id","operator":"=","value":false}]}}',
};
const values = { autoconsum_id: undefined };
const evaluatedAttrs = evaluateAttributes({
tagAttributes,
values,
fields,
fallbackMode: false,
});
expect(evaluatedAttrs.invisible).toBeTruthy();
});
});
describe("in evaluateAttributes method with faulty json_attrs and attrs ", () => {
it("it should fallback to use attrs when json_attrs is faulty", () => {
const tagAttributes = {
attrs: "{'invisible':[('per_enviar', '=', 'postal')]}",
json_attrs: "faulty",
};
const values = {
per_enviar: "postal",
};
const evaluatedAttrs = evaluateAttributes({
tagAttributes,
values,
fields,
});
expect(evaluatedAttrs.invisible).toBeTruthy();
});
});
});

0 comments on commit d3b4eb3

Please sign in to comment.