[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:
parent
db4aa8dfe7
commit
039cf85e32
|
@ -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);
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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");
|
||||
});
|
||||
});
|
||||
});
|
|
@ -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>
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue