[TEST] start adding some testing to new editable listview, validate structure of editionView in Editor

bzr revid: xmo@openerp.com-20120704095626-j7wtbgdmoti0kjie
This commit is contained in:
Xavier Morel 2012-07-04 11:56:26 +02:00
parent db4aa8dfe7
commit 039cf85e32
5 changed files with 109 additions and 9 deletions

View File

@ -50,11 +50,12 @@ openerp.web.list_editable = function (instance) {
* @param {Boolean} [force] forces the list to editability. Sets new row edition status to "bottom".
*/
set_editable: function (force) {
// TODO: fix handling of editability status to be simpler & clearer & more coherent
// If ``force``, set editability to bottom
// otherwise rely on view default
// view' @editable is handled separately as we have not yet
// fetched and processed the view at this point.
this.options.editable = true || (
this.options.editable = (
! this.options.read_only && ((force && "bottom") || this.defaults.editable));
},
/**
@ -82,7 +83,7 @@ openerp.web.list_editable = function (instance) {
// tree/@editable takes priority on everything else if present.
this.options.editable = ! this.options.read_only && (data.arch.attrs.editable || this.options.editable);
var result = this._super(data, grouped);
if (this.options.editable || true) {
if (this.options.editable) {
this.editor = new instance.web.list.Editor(this);
var editor_ready = this.editor.prependTo(this.$element)
@ -168,6 +169,7 @@ openerp.web.list_editable = function (instance) {
*/
saveEdition: function () {
var self = this;
// TODO: save:after should be invoked after reload
return this.withEvent('save', {
editor: this.editor,
form: this.editor.form,
@ -349,16 +351,44 @@ openerp.web.list_editable = function (instance) {
start: function () {
var self = this;
var _super = this._super();
this.form.embedded_view = this.delegate.editionView(this);
this.form.embedded_view = this._validateView(
this.delegate.editionView(this));
var form_ready = this.form.appendTo(this.$element).then(
self.form.proxy('do_hide'));
return $.when(_super, form_ready);
},
_validateView: function (edition_view) {
if (!edition_view) {
throw new Error("editor delegate's #editionView must return "
+ "a view descriptor");
}
var arch = edition_view.arch;
if (!(arch && arch.children instanceof Array)) {
throw new Error("Editor delegate's #editionView must have a" +
" non-empty arch")
}
if (!(arch.tag === "form")) {
throw new Error("Editor delegate's #editionView must have a" +
" 'form' root node");
}
if (!(arch.attrs && arch.attrs.version === "7.0")) {
throw new Error("Editor delegate's #editionView must be a" +
" version 7 view");
}
if (!/\boe_form_container\b/.test(arch.attrs['class'])) {
throw new Error("Editor delegate's #editionView must have the" +
" class 'oe_form_container' on its root" +
" element");
}
return edition_view;
},
isEditing: function () {
return !!this.record;
},
edit: function (record, configureField) {
// TODO: specify sequence of edit calls
var self = this;
var form = self.form;
record = _.extend({}, record);

View File

@ -1238,7 +1238,9 @@ instance.web.json_node_to_xml = function(node, human_readable, indent) {
if (typeof(node) === 'string') {
return sindent + node;
} else if (typeof(node.tag) !== 'string' || !node.children instanceof Array || !node.attrs instanceof Object) {
throw("Node a json node");
throw new Error(
_.str.sprintf("Node [%s] is not a JSONified XML node",
JSON.stringify(node)));
}
for (var attr in node.attrs) {
var vattr = node.attrs[attr];

View File

@ -0,0 +1,71 @@
$(document).ready(function () {
var $fix = $('#qunit-fixture');
var xhr = QWeb2.Engine.prototype.get_xhr();
xhr.open('GET', '/web/static/src/xml/base.xml', false);
xhr.send(null);
var doc = xhr.responseXML;
var noop = function () {};
/**
* Make connection RPC responses mockable by setting keys on the
* Connection#responses object (key is the URL, value is the function to
* call with the RPC request payload)
*
* @param {openerp.web.Connection} connection connection instance to mockify
* @param {Object} [responses] url:function mapping to seed the mock connection
*/
var mockifyRPC = function (connection, responses) {
connection.responses = responses || {};
connection.rpc_function = function (url, payload) {
if (!(url.url in this.responses)) {
return $.Deferred().reject({}, 'failed', _.str.sprintf("Url %s not found in mock responses", url.url)).promise();
}
return $.when(this.responses[url.url](payload));
};
};
var instance;
var baseSetup = function () {
instance = window.openerp.init([]);
window.openerp.web.corelib(instance);
window.openerp.web.coresetup(instance);
window.openerp.web.chrome(instance);
window.openerp.web.data(instance);
window.openerp.web.views(instance);
window.openerp.web.list(instance);
window.openerp.web.form(instance);
window.openerp.web.list_editable(instance);
instance.web.qweb.add_template(doc);
mockifyRPC(instance.connection);
};
module('editor', {
setup: baseSetup
});
asyncTest('base-state', 2, function () {
var e = new instance.web.list.Editor({
dataset: {},
editionView: function () {
return {
arch: {
tag: 'form',
attrs: {
version: '7.0',
'class': 'oe_form_container'
},
children: []
}
};
}
});
e.appendTo($fix)
.always(start)
.fail(function (error) { ok(false, error && error.message); })
.done(function () {
ok(!e.isEditing(), "should not be editing");
ok(e.form instanceof instance.web.FormView,
"should use default form type");
});
});
});

View File

@ -38,6 +38,7 @@
<script src="/web/static/src/js/search.js"></script>
<script src="/web/static/src/js/view_form.js"></script>
<script src="/web/static/src/js/view_list.js"></script>
<script src="/web/static/src/js/view_list_editable.js"></script>
</head>
<body id="oe" class="openerp">
<h1 id="qunit-header">OpenERP web Test Suite</h1>
@ -55,4 +56,5 @@
<script type="text/javascript" src="/web/static/test/rpc.js"></script>
<script type="text/javascript" src="/web/static/test/evals.js"></script>
<script type="text/javascript" src="/web/static/test/search.js"></script>
<script type="text/javascript" src="/web/static/test/list-editable.js"></script>
</html>

View File

@ -163,9 +163,6 @@ view provides a number of dedicated events to its lifecycle.
Invoked after a save has been completed
.. todo:: currently invoked before the record has reloaded, which
is kinda shitty
``cancel:before`` *cancellable*
Invoked before cancelling a pending edition, provided with the
@ -193,8 +190,6 @@ formview, delegating instead to its
e.g. :js:func:`~openerp.web.list.Editor.edit` multiple times in a
row without saving or cancelling each edit is undefined.
.. todo:: define this behavior
:param parent:
:type parent: :js:class:`~openerp.web.Widget`
:param EditorOptions options: