Files
odoo_source/addons/pad/static/tests/pad_tests.js
T
Khoi Nguyen f6c660b752 [FIX] web,pad: ensure pad content is displayed after discard
Up to this revision, clicking on 'edit' in a record with an existing pad
and discarding the changes straight away caused the pad content not to
be displayed.

The root cause of this issue is twofold:

- a hack tricks the model into thinking the pad URL has changed by
  replacing it with an object yielding the URL when JSONified;
- the pad never affects the 'dirtiness' of a record and BasicModel only
  actually discards changes when the record is dirty.

When a user clicks on discard, the model does not actually discard the
changes, thereby leaving the web client into thinking the pad URL is the
object mentioned above.

We fix this issue by requiring that the model always discard changes
when clicking 'Discard', regardless of whether the record is dirty.
In fact, the lines we changed were no longer correct since the
introduction of 'doNotSetDirty' (see
https://github.com/odoo/odoo/commit/72ed3a1), as a record could be
changed without being dirty. This commit thus also ensures that such
records are also properly discarded.
2017-08-16 11:00:44 +02:00

267 lines
9.1 KiB
JavaScript

odoo.define('pad.pad_tests', function (require) {
"use strict";
var FieldPad = require('pad.pad');
var FormView = require('web.FormView');
var testUtils = require('web.test_utils');
var createView = testUtils.createView;
QUnit.module('pad widget', {
beforeEach: function () {
this.data = {
task: {
fields: {
description: {string: "Description", type: "char"},
},
records: [
{id: 1, description: false},
{id: 2, description: "https://pad.odoo.pad/p/test-03AK6RCJT"},
],
pad_is_configured: function () {
return true;
},
pad_generate_url: function (route, args) {
return {
url:'https://pad.odoo.pad/p/test/' + args.context.object_id
};
},
pad_get_content: function () {
return "we should rewrite this server in haskell";
},
},
};
},
});
QUnit.test('pad widget display help if server not configured', function (assert) {
assert.expect(4);
var form = createView({
View: FormView,
model: 'task',
data: this.data,
arch:'<form>' +
'<sheet>' +
'<group>' +
'<field name="description" widget="pad"/>' +
'</group>' +
'</sheet>' +
'</form>',
res_id: 1,
mockRPC: function (route, args) {
if (args.method === 'pad_is_configured') {
return $.when(false);
}
return this._super.apply(this, arguments);
},
});
assert.ok(form.$('p.oe_unconfigured').is(':visible'),
"help message should be visible");
assert.notOk(form.$('p.oe_pad_content').is(':visible'),
"content should not be visible");
form.$buttons.find('.o_form_button_edit').click();
assert.ok(form.$('p.oe_unconfigured').is(':visible'),
"help message should be visible");
assert.notOk(form.$('p.oe_pad_content').is(':visible'),
"content should not be visible");
form.destroy();
delete FieldPad.prototype.isPadConfigured;
});
QUnit.test('pad widget works, basic case', function (assert) {
assert.expect(5);
var form = createView({
View: FormView,
model: 'task',
data: this.data,
arch:'<form>' +
'<sheet>' +
'<group>' +
'<field name="description" widget="pad"/>' +
'</group>' +
'</sheet>' +
'</form>',
res_id: 1,
mockRPC: function (route, args) {
if (route === 'https://pad.odoo.pad/p/test/1?showChat=false&userName=batman') {
assert.ok(true, "should have an iframe with correct src");
return $.when(true);
}
return this._super.apply(this, arguments);
},
session: {
userName: "batman",
},
});
assert.notOk(form.$('p.oe_unconfigured').is(':visible'),
"help message should not be visible");
assert.ok(form.$('.oe_pad_content').is(':visible'),
"content should be visible");
assert.strictEqual(form.$('.oe_pad_content:contains(This pad will be)').length, 1,
"content should display a message when not initialized");
form.$buttons.find('.o_form_button_edit').click();
assert.strictEqual(form.$('.oe_pad_content iframe').length, 1,
"should have an iframe");
form.destroy();
delete FieldPad.prototype.isPadConfigured;
});
QUnit.test('pad widget works, with existing data', function (assert) {
assert.expect(3);
var contentDef = $.Deferred();
var form = createView({
View: FormView,
model: 'task',
data: this.data,
arch:'<form>' +
'<sheet>' +
'<group>' +
'<field name="description" widget="pad"/>' +
'</group>' +
'</sheet>' +
'</form>',
res_id: 2,
mockRPC: function (route, args) {
if (_.str.startsWith(route, 'http')) {
return $.when(true);
}
var result = this._super.apply(this, arguments);
if (args.method === 'pad_get_content') {
return contentDef.then(_.constant(result));
}
if (args.method === 'write') {
assert.ok('description' in args.args[1],
"should always send the description value");
}
return result;
},
session: {
userName: "batman",
},
});
assert.strictEqual(form.$('.oe_pad_content').text(), "Loading",
"should display loading message");
contentDef.resolve();
assert.strictEqual(form.$('.oe_pad_content').text(), "we should rewrite this server in haskell",
"should display proper value");
form.$buttons.find('.o_form_button_edit').click();
form.$buttons.find('.o_form_button_save').click();
form.destroy();
delete FieldPad.prototype.isPadConfigured;
});
QUnit.test('pad widget is not considered dirty at creation', function (assert) {
assert.expect(2);
var form = createView({
View: FormView,
model: 'task',
data: this.data,
arch:'<form>' +
'<sheet>' +
'<group>' +
'<field name="description" widget="pad"/>' +
'</group>' +
'</sheet>' +
'</form>',
mockRPC: function (route, args) {
if (!args.method) {
return $.when(true);
}
return this._super.apply(this, arguments);
},
session: {
userName: "batman",
},
});
var def = form.canBeDiscarded();
assert.strictEqual($('.modal').length, 0,
"should have no confirmation modal opened");
assert.strictEqual(def.state(), 'resolved',
"can be discarded was succesfully resolved");
form.destroy();
delete FieldPad.prototype.isPadConfigured;
});
QUnit.test('pad widget is not considered dirty at edition', function (assert) {
assert.expect(2);
var form = createView({
View: FormView,
model: 'task',
data: this.data,
arch:'<form>' +
'<sheet>' +
'<group>' +
'<field name="description" widget="pad"/>' +
'</group>' +
'</sheet>' +
'</form>',
res_id: 2,
mockRPC: function (route, args) {
if (!args.method) {
return $.when(true);
}
return this._super.apply(this, arguments);
},
session: {
userName: "batman",
},
});
form.$buttons.find('.o_form_button_edit').click();
var def = form.canBeDiscarded();
assert.strictEqual($('.modal').length, 0,
"should have no confirmation modal opened");
assert.strictEqual(def.state(), 'resolved',
"can be discarded was succesfully resolved");
form.destroy();
delete FieldPad.prototype.isPadConfigured;
});
QUnit.test('record should be discarded properly even if only pad has changed', function (assert) {
assert.expect(1);
var form = createView({
View: FormView,
model: 'task',
data: this.data,
arch:'<form>' +
'<sheet>' +
'<group>' +
'<field name="description" widget="pad"/>' +
'</group>' +
'</sheet>' +
'</form>',
res_id: 2,
mockRPC: function (route, args) {
if (!args.method) {
return $.when(true);
}
return this._super.apply(this, arguments);
},
session: {
userName: "batman",
},
});
form.$buttons.find('.o_form_button_edit').click();
form.$buttons.find('.o_form_button_cancel').click();
assert.strictEqual(form.$('.oe_pad_readonly').text(), this.data.task.pad_get_content(),
"pad content should not have changed");
form.destroy();
delete FieldPad.prototype.isPadConfigured;
});
});