[ADD] im_support: test suite
This revs. add a new test suite for the im_support module. Defining a new suite was necessary as the im_support JS feature needs specific keys to be defined in the session, otherwise its files are simply skipped.
This commit is contained in:
@@ -1,2 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import controllers
|
||||
from . import models
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import main
|
||||
@@ -0,0 +1,12 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import http
|
||||
from odoo.http import request
|
||||
|
||||
|
||||
class ImSupport(http.Controller):
|
||||
|
||||
@http.route('/im_support/tests', type='http', auth="user")
|
||||
def test_suite(self, mod=None, **kwargs):
|
||||
return request.render('im_support.support_qunit_suite')
|
||||
@@ -0,0 +1,81 @@
|
||||
odoo.define('im_support.test_utils', function (require) {
|
||||
"use strict";
|
||||
|
||||
var supportSession = require('im_support.SupportSession');
|
||||
|
||||
var testUtils = require('web.test_utils');
|
||||
|
||||
|
||||
/**
|
||||
* Extended version of addMockEnvironment that mocks RPCs done to the Support
|
||||
* server (CORS), and enables a longpolling to the Support server, optionally.
|
||||
*
|
||||
* @param {Widget} widget
|
||||
* @param {Object} params
|
||||
* @param {function} [params.mockSupportRPC]
|
||||
* @param {boolean} [params.enableSupportPoll=false]
|
||||
*/
|
||||
function addMockSupportEnvironment(widget, params) {
|
||||
// mock CORS RPCs
|
||||
var originalRPC = supportSession.rpc;
|
||||
var defaultMockSupportRPC = function (route, args) {
|
||||
if (route === '/odoo_im_support/get_support_channel') {
|
||||
return $.when({
|
||||
available: true,
|
||||
channel_type: 'livechat',
|
||||
public: 'private',
|
||||
uuid: args.channel_uuid,
|
||||
});
|
||||
}
|
||||
if (route === '/odoo_im_support/fetch_messages') { // fetching history
|
||||
return $.when([]);
|
||||
}
|
||||
if (route === '/odoo_im_support/chat_post') {
|
||||
return $.when();
|
||||
}
|
||||
if (route === '/longpolling/support_poll') {
|
||||
return $.Deferred();
|
||||
}
|
||||
};
|
||||
supportSession.rpc = function (route, args) {
|
||||
var result;
|
||||
if (params.mockSupportRPC) {
|
||||
var _super = this._super;
|
||||
this._super = defaultMockSupportRPC.bind(this, route, args);
|
||||
result = params.mockSupportRPC.apply(this, arguments);
|
||||
this._super = _super;
|
||||
} else {
|
||||
result = defaultMockSupportRPC.apply(this, arguments);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
testUtils.addMockEnvironment(widget, params);
|
||||
var widgetDestroy = widget.destroy;
|
||||
widget.destroy = function () {
|
||||
supportSession.rpc = originalRPC;
|
||||
widgetDestroy.call(this);
|
||||
};
|
||||
|
||||
// intercepts the getItem call to localStorage service for key
|
||||
// 'im_support.poll_timeout', to simulate a pending longpolling connection to
|
||||
// the Support server, such that the initSupport initiates a poll connection
|
||||
if (params.enableSupportPoll) {
|
||||
testUtils.intercept(widget, 'call_service', function (ev) {
|
||||
if (ev.data.service === 'local_storage') {
|
||||
if (ev.data.method === 'getItem' && ev.data.args[0] === 'im_support.poll_timeout') {
|
||||
ev.data.callback(Date.now() + (60 * 1000));
|
||||
// hack to prevent the default mock to handle the request and erase the above value
|
||||
ev.data.callback = function () {};
|
||||
}
|
||||
}
|
||||
}, true);
|
||||
// manually call initSupport (which is supposed to be called at webclient startup)
|
||||
widget.call('chat_manager', 'initSupport');
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
addMockSupportEnvironment: addMockSupportEnvironment,
|
||||
};
|
||||
|
||||
});
|
||||
@@ -0,0 +1,45 @@
|
||||
odoo.define('im_support.systray_no_support_tests', function (require) {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* The purpose of these tests is to ensure that im_support doesn't have an impact
|
||||
* on the webclient when the support is not available.
|
||||
*/
|
||||
|
||||
var ChatManager = require('mail.ChatManager');
|
||||
var systray = require('mail.systray');
|
||||
var mailTestUtils = require('mail.testUtils');
|
||||
|
||||
var testUtils = require('web.test_utils');
|
||||
|
||||
var createBusService = mailTestUtils.createBusService;
|
||||
|
||||
QUnit.module('im_support', {}, function () {
|
||||
|
||||
QUnit.module('systray', {
|
||||
beforeEach: function () {
|
||||
this.services = [ChatManager, createBusService()];
|
||||
},
|
||||
});
|
||||
|
||||
QUnit.test('messaging menu does not display the Support channel if not available', function (assert) {
|
||||
// the Support channel should only be displayed if a support_token and a support_origin are
|
||||
// specified in the session, which is not the case for this test
|
||||
assert.expect(1);
|
||||
|
||||
var messagingMenu = new systray.MessagingMenu();
|
||||
testUtils.addMockEnvironment(messagingMenu, {
|
||||
services: this.services,
|
||||
});
|
||||
messagingMenu.appendTo($('#qunit-fixture'));
|
||||
|
||||
messagingMenu.$('.dropdown-toggle').click();
|
||||
assert.strictEqual(messagingMenu.$('.o_mail_channel_preview[data-channel_id=SupportChannel]').length,
|
||||
0, "should not display the Support channel");
|
||||
|
||||
messagingMenu.destroy();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,320 @@
|
||||
odoo.define('im_support.systray_tests', function (require) {
|
||||
"use strict";
|
||||
|
||||
var supportBus = require('im_support.SupportBus');
|
||||
var imSupportTestUtils = require('im_support.test_utils');
|
||||
|
||||
var ChatManager = require('mail.ChatManager');
|
||||
var ChatWindowManager = require('mail.ChatWindowManager');
|
||||
var systray = require('mail.systray');
|
||||
var mailTestUtils = require('mail.testUtils');
|
||||
|
||||
var testUtils = require('web.test_utils');
|
||||
|
||||
var addMockSupportEnvironment = imSupportTestUtils.addMockSupportEnvironment;
|
||||
var createBusService = mailTestUtils.createBusService;
|
||||
|
||||
QUnit.module('im_support', {}, function () {
|
||||
|
||||
QUnit.module('systray', {
|
||||
beforeEach: function () {
|
||||
this.services = [ChatManager, ChatWindowManager, createBusService()];
|
||||
this.supportParams = {
|
||||
db_uuid: 'some_uuid',
|
||||
support_token: 'ABCDEFGHIJ',
|
||||
support_origin: 'something.com',
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
QUnit.test('messaging menu displays the Support channel', function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
var messagingMenu = new systray.MessagingMenu();
|
||||
addMockSupportEnvironment(messagingMenu, {
|
||||
services: this.services,
|
||||
session: this.supportParams,
|
||||
});
|
||||
messagingMenu.appendTo($('#qunit-fixture'));
|
||||
|
||||
messagingMenu.$('.dropdown-toggle').click();
|
||||
assert.strictEqual(messagingMenu.$('.o_mail_navbar_dropdown_bottom .o_mail_channel_preview[data-channel_id=SupportChannel]').length,
|
||||
1, "should display the Support channel");
|
||||
|
||||
messagingMenu.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('clicking on Support channel: channel not available', function (assert) {
|
||||
assert.expect(9);
|
||||
|
||||
var messagingMenu = new systray.MessagingMenu();
|
||||
addMockSupportEnvironment(messagingMenu, {
|
||||
mockRPC: function (route, args) {
|
||||
assert.step(args.method || route);
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
mockSupportRPC: function (route) {
|
||||
assert.step('cors: ' + route);
|
||||
if (route === '/odoo_im_support/get_support_channel') {
|
||||
return this._super.apply(this, arguments).then(function (supportChannel) {
|
||||
supportChannel.available = false;
|
||||
return supportChannel;
|
||||
});
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
services: this.services,
|
||||
session: this.supportParams,
|
||||
});
|
||||
messagingMenu.appendTo($('#qunit-fixture'));
|
||||
|
||||
messagingMenu.$('.dropdown-toggle').click();
|
||||
assert.strictEqual(messagingMenu.$('.o_mail_channel_preview[data-channel_id=SupportChannel]').length,
|
||||
1, "should display the Support channel");
|
||||
|
||||
messagingMenu.$('.o_mail_channel_preview[data-channel_id=SupportChannel]').click();
|
||||
assert.strictEqual($('.o_chat_window').length, 1,
|
||||
"should have open a chat window");
|
||||
assert.strictEqual($('.o_chat_window .o_chat_title').text().trim(), 'Support (offline)',
|
||||
"should display the offline status in the header");
|
||||
assert.strictEqual($('.o_chat_window .o_composer_input').length, 0,
|
||||
"should have no composer");
|
||||
|
||||
assert.verifySteps([
|
||||
'/mail/init_messaging',
|
||||
'message_fetch',
|
||||
'cors: /odoo_im_support/get_support_channel',
|
||||
'cors: /odoo_im_support/fetch_messages',
|
||||
]);
|
||||
|
||||
messagingMenu.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('clicking on Support channel: channel available', function (assert) {
|
||||
assert.expect(9);
|
||||
|
||||
var messagingMenu = new systray.MessagingMenu();
|
||||
addMockSupportEnvironment(messagingMenu, {
|
||||
mockRPC: function (route, args) {
|
||||
assert.step(args.method || route);
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
mockSupportRPC: function (route) {
|
||||
if (route.split('/')[1] === 'odoo_im_support') {
|
||||
assert.step('cors: ' + route);
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
services: this.services,
|
||||
session: this.supportParams,
|
||||
});
|
||||
messagingMenu.appendTo($('#qunit-fixture'));
|
||||
|
||||
messagingMenu.$('.dropdown-toggle').click();
|
||||
assert.strictEqual(messagingMenu.$('.o_mail_channel_preview[data-channel_id=SupportChannel]').length,
|
||||
1, "should display the Support channel");
|
||||
|
||||
messagingMenu.$('.o_mail_channel_preview[data-channel_id=SupportChannel]').click();
|
||||
assert.strictEqual($('.o_chat_window').length, 1,
|
||||
"should have open a chat window");
|
||||
assert.strictEqual($('.o_chat_window .o_chat_title').text().trim(), 'Support',
|
||||
"should display the correct channel title");
|
||||
assert.strictEqual($('.o_chat_window .o_composer_input').length, 1,
|
||||
"should have a composer");
|
||||
|
||||
assert.verifySteps([
|
||||
'/mail/init_messaging',
|
||||
'message_fetch',
|
||||
'cors: /odoo_im_support/get_support_channel',
|
||||
'cors: /odoo_im_support/fetch_messages',
|
||||
]);
|
||||
|
||||
messagingMenu.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('post messages in Support channel', function (assert) {
|
||||
assert.expect(8);
|
||||
|
||||
var messagingMenu = new systray.MessagingMenu();
|
||||
addMockSupportEnvironment(messagingMenu, {
|
||||
mockRPC: function (route, args) {
|
||||
assert.step(args.method || route);
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
mockSupportRPC: function (route) {
|
||||
if (route.split('/')[1] === 'odoo_im_support') {
|
||||
assert.step('cors: ' + route);
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
services: this.services,
|
||||
session: this.supportParams,
|
||||
});
|
||||
messagingMenu.appendTo($('#qunit-fixture'));
|
||||
|
||||
messagingMenu.$('.dropdown-toggle').click();
|
||||
assert.strictEqual(messagingMenu.$('.o_mail_channel_preview[data-channel_id=SupportChannel]').length,
|
||||
1, "should display the Support channel");
|
||||
|
||||
messagingMenu.$('.o_mail_channel_preview[data-channel_id=SupportChannel]').click();
|
||||
assert.strictEqual($('.o_chat_window .o_composer_input').length, 1,
|
||||
"should have a composer");
|
||||
|
||||
$('.o_chat_window .o_composer_input .o_input')
|
||||
.val('some message')
|
||||
.trigger($.Event('keydown', {which: $.ui.keyCode.ENTER}));
|
||||
|
||||
assert.verifySteps([
|
||||
'/mail/init_messaging',
|
||||
'message_fetch',
|
||||
'cors: /odoo_im_support/get_support_channel',
|
||||
'cors: /odoo_im_support/fetch_messages',
|
||||
'cors: /odoo_im_support/chat_post',
|
||||
]);
|
||||
|
||||
messagingMenu.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('fold Support channel', function (assert) {
|
||||
assert.expect(11);
|
||||
|
||||
var messagingMenu = new systray.MessagingMenu();
|
||||
addMockSupportEnvironment(messagingMenu, {
|
||||
mockRPC: function (route, args) {
|
||||
assert.step(args.method || route);
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
mockSupportRPC: function (route) {
|
||||
if (route.split('/')[1] === 'odoo_im_support') {
|
||||
assert.step('cors: ' + route);
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
services: this.services,
|
||||
session: this.supportParams,
|
||||
});
|
||||
testUtils.intercept(messagingMenu, 'call_service', function (ev) {
|
||||
if (ev.data.service === 'local_storage') {
|
||||
assert.step('LocalStorage: ' + ev.data.method + ' ' + ev.data.args);
|
||||
}
|
||||
}, true);
|
||||
messagingMenu.appendTo($('#qunit-fixture'));
|
||||
|
||||
messagingMenu.$('.dropdown-toggle').click();
|
||||
assert.strictEqual(messagingMenu.$('.o_mail_channel_preview[data-channel_id=SupportChannel]').length,
|
||||
1, "should display the Support channel");
|
||||
|
||||
messagingMenu.$('.o_mail_channel_preview[data-channel_id=SupportChannel]').click();
|
||||
assert.strictEqual($('.o_chat_window').length, 1,
|
||||
"should have open a chat window");
|
||||
|
||||
// fold, re-open and close channel
|
||||
$('.o_chat_window .o_chat_title').click();
|
||||
$('.o_chat_window .o_chat_title').click();
|
||||
$('.o_chat_window .o_chat_window_close').click();
|
||||
|
||||
assert.verifySteps([
|
||||
'/mail/init_messaging',
|
||||
'message_fetch',
|
||||
'cors: /odoo_im_support/get_support_channel',
|
||||
'LocalStorage: setItem im_support.channel_state,open',
|
||||
'cors: /odoo_im_support/fetch_messages',
|
||||
'LocalStorage: setItem im_support.channel_state,folded',
|
||||
'LocalStorage: setItem im_support.channel_state,open',
|
||||
'LocalStorage: setItem im_support.channel_state,closed',
|
||||
]);
|
||||
|
||||
messagingMenu.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('restore Support channel if necessary', function (assert) {
|
||||
assert.expect(5);
|
||||
|
||||
var messagingMenu = new systray.MessagingMenu();
|
||||
addMockSupportEnvironment(messagingMenu, {
|
||||
enableSupportPoll: true,
|
||||
mockRPC: function (route, args) {
|
||||
assert.step(args.method || route);
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
mockSupportRPC: function (route) {
|
||||
if (route.split('/')[1] === 'odoo_im_support') {
|
||||
assert.step('cors: ' + route);
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
services: this.services,
|
||||
session: this.supportParams,
|
||||
});
|
||||
messagingMenu.appendTo($('#qunit-fixture'));
|
||||
|
||||
assert.strictEqual($('.o_chat_window').length, 1,
|
||||
"should have open a chat window");
|
||||
|
||||
assert.verifySteps([
|
||||
'/mail/init_messaging',
|
||||
'cors: /odoo_im_support/get_support_channel',
|
||||
'cors: /odoo_im_support/fetch_messages',
|
||||
]);
|
||||
|
||||
messagingMenu.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('receive messages in the Support channel', function (assert) {
|
||||
assert.expect(10);
|
||||
|
||||
var supportChannelID;
|
||||
|
||||
var messagingMenu = new systray.MessagingMenu();
|
||||
addMockSupportEnvironment(messagingMenu, {
|
||||
enableSupportPoll: true,
|
||||
mockRPC: function (route, args) {
|
||||
assert.step(args.method || route);
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
mockSupportRPC: function (route) {
|
||||
if (route.split('/')[1] === 'odoo_im_support') {
|
||||
assert.step('cors: ' + route);
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
services: this.services,
|
||||
session: this.supportParams,
|
||||
});
|
||||
messagingMenu.appendTo($('#qunit-fixture'));
|
||||
|
||||
assert.strictEqual($('.o_chat_window').length, 1,
|
||||
"should have open a chat window");
|
||||
assert.strictEqual($('.o_chat_window .o_thread_message').length, 0,
|
||||
"there should be no message in the thread");
|
||||
|
||||
// simulate an incoming message on the supportBus
|
||||
var data = {
|
||||
author_id: [42, 'An operator'],
|
||||
body: 'A message',
|
||||
channel_ids: [supportChannelID],
|
||||
};
|
||||
var notification = [[false, 'mail.channel'], data];
|
||||
supportBus.trigger('notification', [notification]);
|
||||
|
||||
assert.strictEqual($('.o_chat_window .o_thread_message').length, 1,
|
||||
"there should be a new message in the thread");
|
||||
assert.strictEqual($('.o_chat_window .o_thread_message .o_thread_author ').text().trim(),
|
||||
'An operator', "should correctly display the author");
|
||||
assert.strictEqual($('.o_chat_window .o_thread_message .o_thread_message_avatar').attr('src'),
|
||||
'/mail/static/src/img/odoo_o.png', "should have correct avatar");
|
||||
assert.strictEqual($('.o_chat_window .o_thread_message .o_thread_message_content ').text().trim(),
|
||||
'A message', "message is correct");
|
||||
|
||||
assert.verifySteps([
|
||||
'/mail/init_messaging',
|
||||
'cors: /odoo_im_support/get_support_channel',
|
||||
'cors: /odoo_im_support/fetch_messages',
|
||||
]);
|
||||
|
||||
messagingMenu.destroy();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import test_js
|
||||
@@ -0,0 +1,11 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import odoo.tests
|
||||
|
||||
|
||||
@odoo.tests.tagged('post_install', '-at_install')
|
||||
class IMSupportSuite(odoo.tests.HttpCase):
|
||||
|
||||
def test_im_support_js(self):
|
||||
self.phantom_js('/im_support/tests?mod=web&failfast', "", "", login='admin', timeout=180)
|
||||
@@ -12,5 +12,34 @@
|
||||
<script type="text/javascript" src="/im_support/static/src/js/systray.js"></script>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="qunit_suite" name="im_support_tests" inherit_id="web.qunit_suite">
|
||||
<xpath expr="//t[@t-set='head']" position="inside">
|
||||
<script type="text/javascript" src="/im_support/static/tests/systray_no_support_tests.js"></script>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="im_support.support_qunit_suite">
|
||||
<t t-call="web.layout">
|
||||
<t t-set="html_data" t-value="{'style': 'height: 100%;'}"/>
|
||||
<t t-set="title">IM Support Tests</t>
|
||||
<t t-set="head">
|
||||
<script type="text/javascript">
|
||||
odoo.session_info = {
|
||||
support_token: 'ABCDEFGHIJ',
|
||||
support_origin: 'https://something.com'
|
||||
};
|
||||
</script>
|
||||
<t t-call="web.js_tests_assets"/>
|
||||
|
||||
<script type="text/javascript" src="/im_support/static/tests/helpers/test_utils.js"></script>
|
||||
|
||||
<script type="text/javascript" src="/im_support/static/tests/systray_tests.js"></script>
|
||||
</t>
|
||||
|
||||
<div id="qunit"/>
|
||||
<div id="qunit-fixture"/>
|
||||
</t>
|
||||
</template>
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
Reference in New Issue
Block a user