Skip to content

Commit

Permalink
Merge pull request #1128 from ProcessMaker/bugfix/FOUR-4849
Browse files Browse the repository at this point in the history
Catch invalid bind and visibility rules
  • Loading branch information
ryancooley authored Dec 17, 2021
2 parents 872bfd1 + 21f501f commit 03940a2
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/mixins/Json2Vue.js
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ export default {
Object.keys(component.watch).forEach((key) => {
const watch = { deep: true };
component.watch[key].forEach(w => Object.assign(watch, w.options));
watch.handler = new Function('value', component.watch[key].map(w => w.code).join('\n'));
watch.handler = new Function('value', component.watch[key].map(w => `try{${w.code}}catch(e){console.warn(e)}`).join('\n'));
component.watch[key] = watch;
});
// Add validation rules
Expand Down
16 changes: 14 additions & 2 deletions src/mixins/extensions/LoadFieldComponents.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export default {
}
});
},
loadFieldProperties({ properties, element, componentName, definition , formIndex}) {
loadFieldProperties({ properties, element, componentName, definition , formIndex, screen}) {
properties.class = this.elementCssClass(element);
properties[':validation-data'] = 'getValidationData()';

Expand All @@ -38,7 +38,19 @@ export default {
properties[':image'] = this.byRef(element.config.image);
} else if (this.validVariableName(element.config.name)) {
this.registerVariable(element.config.name, element);
properties['v-model'] = `${element.config.name}`;
// v-model are not assigned directly to the field name, to prevent invalid references like:
// `person.content` when `person`=null
const computed_property = `computedProxy__${element.config.name.split('.').join('_DOT_')}`;
properties['v-model'] = computed_property;
screen.computed[computed_property] = {
get() {
return this.getValue(element.config.name);
},
set(value) {
this.setValue(element.config.name, value);
return true;
},
};
}
}
// Do not replace mustache in RichText control, it is replaced by the control
Expand Down
1 change: 1 addition & 0 deletions tests/e2e/fixtures/FOUR-4849.json

Large diffs are not rendered by default.

55 changes: 55 additions & 0 deletions tests/e2e/specs/FOUR4849.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
describe('Tests null object property bind to an input text', () => {
beforeEach(() => {
cy.server();
cy.visit('/');
});

it('Verify visibility rules do not break', () => {
cy.loadFromJson('FOUR-4849.json', 0);
cy.get('[data-cy=mode-preview]').click();

// When the person is null, the visibility rules should be working
cy.get('[data-cy=preview-content] [name="select1.form_input_1"]').should('not.be.visible');
cy.get('[data-cy=preview-content] [name=check]').click();
cy.get('[data-cy=preview-content] [name="select1.form_input_1"]').should('be.visible');
cy.get('[data-cy=preview-content] [name="select1.form_input_1"]').clear().type('it works with person=null');

cy.get('[data-cy=preview-content] [data-cy="screen-field-person"]').selectOption('1');

// When a person is selected, the visibility rules should still be working
cy.get('[data-cy=preview-content] [name=check]').click();
cy.get('[data-cy=preview-content] [name="select1.form_input_1"]').should('not.be.visible');
cy.get('[data-cy=preview-content] [name=check]').click();
cy.get('[data-cy=preview-content] [name="select1.form_input_1"]').should('be.visible');
cy.get('[data-cy=preview-content] [name="select1.form_input_1"]').clear().type('still working with person=1');
// Check the data of the screen
cy.assertPreviewData({
'check': true,
'select1': {
'form_input_1': 'still working with person=1',
},
'person': {
'value': '1',
'content': '1',
},
});

cy.get('[data-cy=preview-content] [data-cy="screen-field-person"]').unselectOption('1');

// When the person is deselected, the visibility rules should still be working
cy.get('[data-cy=preview-content] [name=check]').click();
cy.get('[data-cy=preview-content] [name="select1.form_input_1"]').should('not.be.visible');
cy.get('[data-cy=preview-content] [name=check]').click();
cy.get('[data-cy=preview-content] [name="select1.form_input_1"]').should('be.visible');
cy.get('[data-cy=preview-content] [name="select1.form_input_1"]').clear().type('still working with person back to null');

// Check the data of the screen
cy.assertPreviewData({
'check': true,
'select1': {
'form_input_1': 'still working with person back to null',
},
'person': null,
});
});
});
5 changes: 5 additions & 0 deletions tests/e2e/support/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,3 +173,8 @@ Cypress.Commands.add('selectOption', { prevSubject: true }, (subject, option) =>
cy.get(subject).find('input').clear().type(option);
cy.get(subject).find(`span:not(.multiselect__option--disabled) span:contains("${option}"):first`).click();
});

Cypress.Commands.add('unselectOption', { prevSubject: true }, (subject, option) => {
cy.get(subject).click();
cy.get(subject).find(`span:not(.multiselect__option--disabled) span:contains("${option}"):first`).click();
});

0 comments on commit 03940a2

Please sign in to comment.