[FIX] mass_mailing: do not raise a traceback for unsupported domain

With the mailing filter widget, a traceback was raised when unfocussing
the domain editor. We now check if the format is correct and return
early without raising a traceback. It is also now no longer possible
to try to save the unsupported domain in the favorite.

task-3569969

closes odoo/odoo#141490

X-original-commit: f2f3b185e9f2d069e3fb3975b20ba2a1002e20ca
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
Signed-off-by: Jérémy Hennecart (jeh) <jeh@odoo.com>
This commit is contained in:
Jérémy Hennecart (jeh)
2023-11-08 05:31:11 +00:00
parent 593db9bc1f
commit 05681c6f79
3 changed files with 52 additions and 3 deletions
@@ -63,8 +63,18 @@ export class FieldMany2OneMailingFilter extends Many2OneField {
}
// By default, domains in recordData are in string format, but adding / removing a leaf from domain widget converts
// value into object, so we use 'Domain' class to convert them in same (string) format, allowing proper comparison.
const recordDomain = new Domain(this.props.record.data[this.props.domain_field] || []).toString();
const filterDomain = new Domain(this.props.record.data.mailing_filter_domain || []).toString();
let recordDomain;
let filterDomain;
try {
recordDomain = new Domain(this.props.record.data[this.props.domain_field] || []).toString();
filterDomain = new Domain(this.props.record.data.mailing_filter_domain || []).toString();
} catch {
// Don't raise a traceback if a domain set manually doesn't match the format expected.
// This can happen when we unfocus the domain editor
this.filter.canSaveFilter = false;
this.filter.canRemoveFilter = false;
return;
}
const modelFieldElement = this.props.model_field && document.querySelector(
`input#${this.props.model_field},div [name="${this.props.model_field}"]`);
@@ -81,6 +91,7 @@ export class FieldMany2OneMailingFilter extends Many2OneField {
|| value.length
|| this.state.isFloating
|| filterDomain !== recordDomain;
this.filter.canRemoveFilter = !this.filter.canSaveFilter
}
// HANDLERS
@@ -24,7 +24,7 @@
</div>
</MailingFilterDropdown>
</div>
<a t-attf-class="o_mass_mailing_remove_filter btn px-1 pt-1 pb-0 {{ this.filter.canSaveFilter ? 'd-none': '' }}" t-on-click="onRemoveFilter">
<a t-attf-class="o_mass_mailing_remove_filter btn px-1 pt-1 pb-0 {{ !this.filter.canRemoveFilter ? 'd-none': '' }}" t-on-click="onRemoveFilter">
<i class="fa fa-trash px-3 py-1 align-bottom" title="Remove from Favorites"/>
</a>
</div>
@@ -409,6 +409,44 @@ QUnit.module('favorite filter widget', (hooks) => {
"should not have option to remove filter because mailing domain is changed");
});
QUnit.test('filter widget does not raise traceback when losing focus with unexpected domain format', async (assert) => {
assert.expect(4);
await makeView({
type: "form",
resModel: "mailing.mailing",
resId: 2,
serverData,
arch: `<form>
<field name="display_name"/>
<field name="subject"/>
<field name="mailing_domain"/>
<field name="mailing_model_name" invisible="1"/>
<field name="mailing_model_id"/>
<field name="mailing_filter_count"/>
<field name="mailing_filter_domain" invisible="1"/>
<field name="mailing_filter_id"
widget="mailing_filter"
options="{'no_create': '1', 'no_open': '1', 'domain_field': 'mailing_domain', 'model': 'mailing_model_id'}"/>
</form>`,
});
// Initial state of icons with no filter
assert.isVisible(fixture.querySelector('.o_mass_mailing_save_filter_container'),
"should have option to save filter if no filter is set");
assert.isNotVisible(fixture.querySelector('.o_mass_mailing_remove_filter'));
// Set incorrect domain format
await testUtils.editInput(fixture, "div[name='mailing_domain'] input", "[");
// Wait to lose the focus
await testUtils.nextTick();
assert.isNotVisible(fixture.querySelector('.o_mass_mailing_save_filter_container'),
"should not have option to save filter if domain format is incorrect");
assert.isNotVisible(fixture.querySelector('.o_mass_mailing_remove_filter'),
"should still not be visible");
});
QUnit.test('filter widget works in edit and readonly', async (assert) => {
assert.expect(4);