odoo.define('web.basic_fields_tests', function (require) { "use strict"; var basicFields = require('web.basic_fields'); var concurrency = require('web.concurrency'); var config = require('web.config'); var core = require('web.core'); var FormView = require('web.FormView'); var KanbanView = require('web.KanbanView'); var ListView = require('web.ListView'); var session = require('web.session'); var testUtils = require('web.test_utils'); var testUtilsDom = require('web.test_utils_dom'); var field_registry = require('web.field_registry'); const legacyViewRegistry = require('web.view_registry'); const makeTestEnvironment = require("web.test_env"); const { makeLegacyCommandService } = require("@web/legacy/utils"); const { registry } = require("@web/core/registry"); const { getFixture, legacyExtraNextTick, triggerHotkey, nextTick, click, patchWithCleanup } = require("@web/../tests/helpers/utils"); const { createWebClient, doAction } = require('@web/../tests/webclient/helpers'); const { registerCleanup } = require("@web/../tests/helpers/cleanup"); var createView = testUtils.createView; var patchDate = testUtils.mock.patchDate; var DebouncedField = basicFields.DebouncedField; var JournalDashboardGraph = basicFields.JournalDashboardGraph; var _t = core._t; // Base64 images for testing purpose const MY_IMAGE = 'iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=='; const PRODUCT_IMAGE = 'R0lGODlhDAAMAKIFAF5LAP/zxAAAANyuAP/gaP///wAAAAAAACH5BAEAAAUALAAAAAAMAAwAAAMlWLPcGjDKFYi9lxKBOaGcF35DhWHamZUW0K4mAbiwWtuf0uxFAgA7'; const FR_FLAG_URL = '/base/static/img/country_flags/fr.png'; const EN_FLAG_URL = '/base/static/img/country_flags/gb.png'; let target; QUnit.module('Legacy fields', {}, function () { QUnit.module('Legacy basic_fields', { beforeEach: function () { registry.category("views").remove("list"); // remove new list from registry registry.category("views").remove("kanban"); // remove new kanban from registry registry.category("views").remove("form"); // remove new form from registry legacyViewRegistry.add("list", ListView); // add legacy list -> will be wrapped and added to new registry legacyViewRegistry.add("kanban", KanbanView); // add legacy kanban -> will be wrapped and added to new registry legacyViewRegistry.add("form", FormView); // add legacy form -> will be wrapped and added to new registry this.data = { partner: { fields: { date: {string: "A date", type: "date", searchable: true}, datetime: {string: "A datetime", type: "datetime", searchable: true}, display_name: {string: "Displayed name", type: "char", searchable: true}, foo: {string: "Foo", type: "char", default: "My little Foo Value", searchable: true, trim: true}, bar: {string: "Bar", type: "boolean", default: true, searchable: true}, empty_string: {string: "Empty string", type: "char", default: false, searchable: true, trim: true}, txt: {string: "txt", type: "text", default: "My little txt Value\nHo-ho-hoooo Merry Christmas"}, int_field: {string: "int_field", type: "integer", sortable: true, searchable: true}, qux: {string: "Qux", type: "float", digits: [16,1], searchable: true}, monetary: {string: "MMM", type: "monetary", digits: [16,1], searchable: true}, p: {string: "one2many field", type: "one2many", relation: 'partner', searchable: true}, trululu: {string: "Trululu", type: "many2one", relation: 'partner', searchable: true}, timmy: {string: "pokemon", type: "many2many", relation: 'partner_type', searchable: true}, product_id: {string: "Product", type: "many2one", relation: 'product', searchable: true}, sequence: {type: "integer", string: "Sequence", searchable: true}, currency_id: {string: "Currency", type: "many2one", relation: "currency", searchable: true}, selection: {string: "Selection", type: "selection", searchable:true, selection: [['normal', 'Normal'],['blocked', 'Blocked'],['done', 'Done']]}, document: {string: "Binary", type: "binary"}, hex_color: {string: "hexadecimal color", type: "char"}, }, records: [{ id: 1, date: "2017-02-03", datetime: "2017-02-08 10:00:00", display_name: "first record", bar: true, foo: "yop", int_field: 10, qux: 0.44444, p: [], timmy: [], trululu: 4, selection: 'blocked', document: 'coucou==\n', hex_color: '#ff0000', }, { id: 2, display_name: "second record", bar: true, foo: "blip", int_field: 0, qux: 0, p: [], timmy: [], trululu: 1, sequence: 4, currency_id: 2, selection: 'normal', }, { id: 4, display_name: "aaa", foo: "abc", sequence: 9, int_field: false, qux: false, selection: 'done', }, {id: 3, bar: true, foo: "gnap", int_field: 80, qux: -3.89859}, {id: 5, bar: false, foo: "blop", int_field: -4, qux: 9.1, currency_id: 1, monetary: 99.9}], onchanges: {}, }, team: { fields: { partner_ids: { string: "Partner", type: "one2many", relation: 'partner' }, }, records: [{ id: 1, partner_ids: [5], }], onchanges: {}, }, product: { fields: { name: {string: "Product Name", type: "char", searchable: true} }, records: [{ id: 37, display_name: "xphone", }, { id: 41, display_name: "xpad", }] }, partner_type: { fields: { name: {string: "Partner Type", type: "char", searchable: true}, color: {string: "Color index", type: "integer", searchable: true}, }, records: [ {id: 12, display_name: "gold", color: 2}, {id: 14, display_name: "silver", color: 5}, ] }, currency: { fields: { digits: { string: "Digits" }, symbol: {string: "Currency Sumbol", type: "char", searchable: true}, position: {string: "Currency Position", type: "char", searchable: true}, }, records: [{ id: 1, display_name: "$", symbol: "$", position: "before", }, { id: 2, display_name: "€", symbol: "€", position: "after", }] }, }; target = getFixture(); }, }, function () { QUnit.module('DebouncedField'); QUnit.test('debounced fields do not trigger call _setValue once destroyed', async function (assert) { assert.expect(4); var def = testUtils.makeTestPromise(); var _doAction = DebouncedField.prototype._doAction; DebouncedField.prototype._doAction = function () { _doAction.apply(this, arguments); def.resolve(); }; var _setValue = DebouncedField.prototype._setValue; DebouncedField.prototype._setValue = function () { assert.step('_setValue'); _setValue.apply(this, arguments); }; var form = await createView({ View: FormView, model: 'partner', data: this.data, arch: '
' + '' + '' + '' + '' + '' + '
', res_id: 1, fieldDebounce: 3, viewOptions: { mode: 'edit', }, }); // change the value testUtils.fields.editInput(form.$('input[name=foo]'), 'new value'); assert.verifySteps([], "_setValue shouldn't have been called yet"); // save await testUtils.form.clickSave(form); assert.verifySteps(['_setValue'], "_setValue should have been called once"); // destroy the form view def = testUtils.makeTestPromise(); form.destroy(); await testUtils.nextMicrotaskTick(); // wait for the debounced callback to be called assert.verifySteps([], "_setValue should not have been called after widget destruction"); DebouncedField.prototype._doAction = _doAction; DebouncedField.prototype._setValue = _setValue; }); QUnit.module('FieldBoolean'); QUnit.test('boolean field in form view', async function (assert) { assert.expect(15); var form = await createView({ View: FormView, model: 'partner', data: this.data, arch: '