summaryrefslogtreecommitdiff
path: root/addons/web/static/tests/helpers/test_utils.js
diff options
context:
space:
mode:
authorAaron Bohy <aab@odoo.com>2017-11-17 13:14:02 +0100
committerAaron Bohy <aab@odoo.com>2018-01-16 20:49:19 +0100
commit32b8cec5361174c92c45a4975d4e02f1fb448aa2 (patch)
tree110bd6986c2da1ed5047002b7ea40c91ea9fa5ed /addons/web/static/tests/helpers/test_utils.js
parent9bee25a9df65f657fef0f2f32a7ad823fdc7d4e1 (diff)
[REF] web,*: ActionManager/ViewManager refactoring
This rev. is the first part (out of 3) of the refactoring of the ActionManager and ViewManager layer of the webclient. The main changes are: - there is no ViewManager anymore, its work is now handled by the ActionManager itself, but isolated in a specific file ; this eases a lot of things, as the breadcrumbs handling for example. - the ActionManager code is converted to the new coding principles and guidelines ; mainly, children widgets communicate with it by triggering events up, and not by function calls anymore. - the ActionManager layer is now testable, and a lot of tests have already been written. - the code in other addons has been adapted consequently. What's coming next: - introduce the 'AbstractAction' Widget, and make client actions and view controllers inherit from it ; this widget will implement a common API that could be used uniformly by the ActionManager (e.g. restore(), canBeLeft(), renderButtons(), getTitle()...). - move the ControlPanel handling from the ActionManager to the AbstractAction.
Diffstat (limited to 'addons/web/static/tests/helpers/test_utils.js')
-rw-r--r--addons/web/static/tests/helpers/test_utils.js89
1 files changed, 72 insertions, 17 deletions
diff --git a/addons/web/static/tests/helpers/test_utils.js b/addons/web/static/tests/helpers/test_utils.js
index e049ba968b2..afeb579eb02 100644
--- a/addons/web/static/tests/helpers/test_utils.js
+++ b/addons/web/static/tests/helpers/test_utils.js
@@ -10,9 +10,11 @@ odoo.define('web.test_utils', function (require) {
* instance of a view, appended in the dom, ready to be tested.
*/
+var ActionManager = require('web.ActionManager');
var ajax = require('web.ajax');
var basic_fields = require('web.basic_fields');
var config = require('web.config');
+var ControlPanel = require('web.ControlPanel');
var core = require('web.core');
var dom = require('web.dom');
var session = require('web.session');
@@ -59,6 +61,58 @@ function observe(widget) {
}
/**
+ * create and return an instance of ActionManager with all rpcs going through a
+ * mock method using the data, actions and archs objects as sources.
+ *
+ * @param {Object} [params]
+ * @param {Object} [params.actions] the actions given to the mock server
+ * @param {Object} [params.archs] this archs given to the mock server
+ * @param {Object} [params.data] the business data given to the mock server
+ * @param {boolean} [params.debug]
+ * @param {function} [params.mockRPC]
+ * @returns {ActionManager}
+ */
+var createActionManager = function (params) {
+ params = params || {};
+ var $target = $('#qunit-fixture');
+ if (params.debug) {
+ $target = $('body');
+ }
+
+ var widget = new Widget();
+ // when 'document' addon is installed, the sidebar does a 'search_read' on
+ // model 'ir_attachment' each time a record is open, so we monkey-patch
+ // 'mockRPC' to mute those RPCs, so that the tests can be written uniformly,
+ // whether or not 'document' is installed
+ var mockRPC = params.mockRPC;
+ _.extend(params, {
+ mockRPC: function (route, args) {
+ if (args.model === 'ir.attachment') {
+ return $.when([]);
+ }
+ if (mockRPC) {
+ return mockRPC.apply(this, arguments);
+ }
+ return this._super.apply(this, arguments);
+ },
+ });
+ addMockEnvironment(widget, _.defaults(params, {debounce: false}));
+ widget.appendTo($target);
+ widget.$el.addClass('o_web_client');
+
+ var userContext = params.context && params.context.user_context || {};
+ var actionManager = new ActionManager(widget, userContext);
+ var originalDestroy = ActionManager.prototype.destroy;
+ actionManager.destroy = function () {
+ actionManager.destroy = originalDestroy;
+ widget.destroy();
+ };
+ actionManager.appendTo(widget.$el);
+
+ return actionManager;
+};
+
+/**
* create a view synchronously. This method uses the createAsyncView method.
* Most views are synchronous, so the deferred can be resolved immediately and
* this method will work.
@@ -87,8 +141,7 @@ function createView(params) {
*
* It returns the instance of the view, properly created, with all rpcs going
* through a mock method using the data object as source, and already loaded/
- * started (with a do_search). The buttons/pager should also be created, if
- * appropriate.
+ * started.
*
* Most views can be tested synchronously (@see createView), but some view have
* external dependencies (like lazy loaded libraries). In that case, it is
@@ -145,9 +198,9 @@ function createAsyncView(params) {
// reproduce the DOM environment of views
var $web_client = $('<div>').addClass('o_web_client').prependTo($target);
- var $control_panel = $('<div>').addClass('o_control_panel').appendTo($web_client);
+ var controlPanel = new ControlPanel(widget);
+ controlPanel.appendTo($web_client);
var $content = $('<div>').addClass('o_content').appendTo($web_client);
- var $view_manager = $('<div>').addClass('o_view_manager_content').appendTo($content);
return view.getController(widget).then(function (view) {
// override the view's 'destroy' so that it calls 'destroy' on the widget
@@ -159,29 +212,21 @@ function createAsyncView(params) {
widget.destroy();
$('#qunit-fixture').off('DOMNodeInserted.removeSRC');
};
+
+ // link the view to the control panel
+ view.set_cp_bus(controlPanel.get_bus());
+
// render the view in a fragment as they must be able to render correctly
// without being in the DOM
var fragment = document.createDocumentFragment();
return view.appendTo(fragment).then(function () {
- dom.append($view_manager, fragment, {
+ dom.append($content, fragment, {
callbacks: [{widget: view}],
in_DOM: true,
});
view.$el.on('click', 'a', function (ev) {
ev.preventDefault();
});
- }).then(function () {
- var $buttons = $('<div>');
- view.renderButtons($buttons);
- $buttons.contents().appendTo($control_panel);
-
- var $sidebar = $('<div>');
- view.renderSidebar($sidebar);
- $sidebar.contents().appendTo($control_panel);
-
- var $pager = $('<div>');
- view.renderPager($pager);
- $pager.contents().appendTo($control_panel);
return view;
});
@@ -250,6 +295,7 @@ function addMockEnvironment(widget, params) {
console.log('%c[debug] debug mode activated', 'color: blue; font-weight: bold;', url);
}
var mockServer = new Server(params.data, {
+ actions: params.actions,
archs: params.archs,
currentDate: params.currentDate,
debug: params.debug,
@@ -336,6 +382,14 @@ function addMockEnvironment(widget, params) {
}
});
+ intercept(widget, 'load_action', function (event) {
+ mockServer.performRpc('/web/action/load', {
+ kwargs: {action_id: event.data.actionID},
+ }).then(function (action) {
+ event.data.on_success(action);
+ });
+ });
+
intercept(widget, "load_views", function (event) {
mockServer.performRpc('/web/dataset/call_kw/' + event.data.modelName, {
args: [],
@@ -617,6 +671,7 @@ return $.when(
}, 0);
return {
addMockEnvironment: addMockEnvironment,
+ createActionManager: createActionManager,
createAsyncView: createAsyncView,
createModel: createModel,
createParent: createParent,