summaryrefslogtreecommitdiff
path: root/addons/hr/static/tests
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/hr/static/tests
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/hr/static/tests')
-rw-r--r--addons/hr/static/tests/helpers/mock_models.js34
-rw-r--r--addons/hr/static/tests/many2one_avatar_employee_tests.js215
-rw-r--r--addons/hr/static/tests/standalone_m2o_avatar_employee_tests.js124
3 files changed, 373 insertions, 0 deletions
diff --git a/addons/hr/static/tests/helpers/mock_models.js b/addons/hr/static/tests/helpers/mock_models.js
new file mode 100644
index 00000000..d4ae7c86
--- /dev/null
+++ b/addons/hr/static/tests/helpers/mock_models.js
@@ -0,0 +1,34 @@
+odoo.define('hr/static/tests/helpers/mock_models.js', function (require) {
+'use strict';
+
+const MockModels = require('mail/static/tests/helpers/mock_models.js');
+
+MockModels.patch('hr/static/tests/helpers/mock_models.js', T =>
+ class extends T {
+
+ //----------------------------------------------------------------------
+ // Public
+ //----------------------------------------------------------------------
+
+ /**
+ * @override
+ */
+ static generateData() {
+ const data = super.generateData(...arguments);
+ Object.assign(data, {
+ 'hr.employee.public': {
+ fields: {
+ display_name: { string: "Name", type: "char" },
+ user_id: { string: "User", type: "many2one", relation: 'res.users' },
+ user_partner_id: { string: "Partner", type: "many2one", relation: 'res.partner' },
+ },
+ records: [],
+ },
+ });
+ return data;
+ }
+
+ }
+);
+
+});
diff --git a/addons/hr/static/tests/many2one_avatar_employee_tests.js b/addons/hr/static/tests/many2one_avatar_employee_tests.js
new file mode 100644
index 00000000..c1eef47b
--- /dev/null
+++ b/addons/hr/static/tests/many2one_avatar_employee_tests.js
@@ -0,0 +1,215 @@
+odoo.define('hr.Many2OneAvatarEmployeeTests', function (require) {
+"use strict";
+
+const {
+ afterEach,
+ afterNextRender,
+ beforeEach,
+ start,
+} = require('mail/static/src/utils/test_utils.js');
+
+const FormView = require('web.FormView');
+const KanbanView = require('web.KanbanView');
+const ListView = require('web.ListView');
+const { Many2OneAvatarEmployee } = require('hr.Many2OneAvatarEmployee');
+const { dom, mock } = require('web.test_utils');
+
+QUnit.module('hr', {}, function () {
+ QUnit.module('Many2OneAvatarEmployee', {
+ beforeEach() {
+ beforeEach(this);
+
+ // reset the cache before each test
+ Many2OneAvatarEmployee.prototype.partnerIds = {};
+
+ Object.assign(this.data, {
+ 'foo': {
+ fields: {
+ employee_id: { string: "Employee", type: 'many2one', relation: 'hr.employee.public' },
+ },
+ records: [
+ { id: 1, employee_id: 11 },
+ { id: 2, employee_id: 7 },
+ { id: 3, employee_id: 11 },
+ { id: 4, employee_id: 23 },
+ ],
+ },
+ });
+ this.data['hr.employee.public'].records.push(
+ { id: 11, name: "Mario", user_id: 11, user_partner_id: 11 },
+ { id: 7, name: "Luigi", user_id: 12, user_partner_id: 12 },
+ { id: 23, name: "Yoshi", user_id: 13, user_partner_id: 13 }
+ );
+ this.data['res.users'].records.push(
+ { id: 11, partner_id: 11 },
+ { id: 12, partner_id: 12 },
+ { id: 13, partner_id: 13 }
+ );
+ this.data['res.partner'].records.push(
+ { id: 11, display_name: "Mario" },
+ { id: 12, display_name: "Luigi" },
+ { id: 13, display_name: "Yoshi" }
+ );
+ },
+ afterEach() {
+ afterEach(this);
+ },
+ });
+
+ QUnit.test('many2one_avatar_employee widget in list view', async function (assert) {
+ assert.expect(11);
+
+ const { widget: list } = await start({
+ hasChatWindow: true,
+ hasView: true,
+ View: ListView,
+ model: 'foo',
+ data: this.data,
+ arch: '<tree><field name="employee_id" widget="many2one_avatar_employee"/></tree>',
+ mockRPC(route, args) {
+ if (args.method === 'read') {
+ assert.step(`read ${args.model} ${args.args[0]}`);
+ }
+ return this._super(...arguments);
+ },
+ });
+
+ assert.strictEqual(list.$('.o_data_cell span').text(), 'MarioLuigiMarioYoshi');
+
+ // click on first employee
+ await afterNextRender(() =>
+ dom.click(list.$('.o_data_cell:nth(0) .o_m2o_avatar'))
+ );
+ assert.verifySteps(
+ ['read hr.employee.public 11'],
+ "first employee should have been read to find its partner"
+ );
+ assert.containsOnce(
+ document.body,
+ '.o_ChatWindowHeader_name',
+ 'should have opened chat window'
+ );
+ assert.strictEqual(
+ document.querySelector('.o_ChatWindowHeader_name').textContent,
+ "Mario",
+ 'chat window should be with clicked employee'
+ );
+
+ // click on second employee
+ await afterNextRender(() =>
+ dom.click(list.$('.o_data_cell:nth(1) .o_m2o_avatar')
+ ));
+ assert.verifySteps(
+ ['read hr.employee.public 7'],
+ "second employee should have been read to find its partner"
+ );
+ assert.containsN(
+ document.body,
+ '.o_ChatWindowHeader_name',
+ 2,
+ 'should have opened second chat window'
+ );
+ assert.strictEqual(
+ document.querySelectorAll('.o_ChatWindowHeader_name')[1].textContent,
+ "Luigi",
+ 'chat window should be with clicked employee'
+ );
+
+ // click on third employee (same as first)
+ await afterNextRender(() =>
+ dom.click(list.$('.o_data_cell:nth(2) .o_m2o_avatar'))
+ );
+ assert.verifySteps(
+ [],
+ "employee should not have been read again because we already know its partner"
+ );
+ assert.containsN(
+ document.body,
+ '.o_ChatWindowHeader_name',
+ 2,
+ "should still have only 2 chat windows because third is the same partner as first"
+ );
+
+ list.destroy();
+ });
+
+ QUnit.test('many2one_avatar_employee widget in kanban view', async function (assert) {
+ assert.expect(6);
+
+ const { widget: kanban } = await start({
+ hasView: true,
+ View: KanbanView,
+ model: 'foo',
+ data: this.data,
+ arch: `
+ <kanban>
+ <templates>
+ <t t-name="kanban-box">
+ <div>
+ <field name="employee_id" widget="many2one_avatar_employee"/>
+ </div>
+ </t>
+ </templates>
+ </kanban>`,
+ });
+
+ assert.strictEqual(kanban.$('.o_kanban_record').text().trim(), '');
+ assert.containsN(kanban, '.o_m2o_avatar', 4);
+ assert.strictEqual(kanban.$('.o_m2o_avatar:nth(0)').data('src'), '/web/image/hr.employee.public/11/image_128');
+ assert.strictEqual(kanban.$('.o_m2o_avatar:nth(1)').data('src'), '/web/image/hr.employee.public/7/image_128');
+ assert.strictEqual(kanban.$('.o_m2o_avatar:nth(2)').data('src'), '/web/image/hr.employee.public/11/image_128');
+ assert.strictEqual(kanban.$('.o_m2o_avatar:nth(3)').data('src'), '/web/image/hr.employee.public/23/image_128');
+
+ kanban.destroy();
+ });
+
+ QUnit.test('many2one_avatar_employee: click on an employee not associated with a user', async function (assert) {
+ assert.expect(6);
+
+ this.data['hr.employee.public'].records[0].user_id = false;
+ this.data['hr.employee.public'].records[0].user_partner_id = false;
+ const { widget: form } = await start({
+ hasView: true,
+ View: FormView,
+ model: 'foo',
+ data: this.data,
+ arch: '<form><field name="employee_id" widget="many2one_avatar_employee"/></form>',
+ mockRPC(route, args) {
+ if (args.method === 'read') {
+ assert.step(`read ${args.model} ${args.args[0]}`);
+ }
+ return this._super(...arguments);
+ },
+ res_id: 1,
+ });
+
+ mock.intercept(form, 'call_service', (ev) => {
+ if (ev.data.service === 'notification') {
+ assert.step(`display notification "${ev.data.args[0].message}"`);
+ }
+ }, true);
+
+ assert.strictEqual(form.$('.o_field_widget[name=employee_id]').text().trim(), 'Mario');
+
+ await dom.click(form.$('.o_m2o_avatar'));
+
+ assert.verifySteps([
+ 'read foo 1',
+ 'read hr.employee.public 11',
+ ]);
+
+ assert.containsOnce(
+ document.body,
+ '.toast .o_notification_content',
+ "should display a toast notification after failing to open chat"
+ );
+ assert.strictEqual(
+ document.querySelector('.o_notification_content').textContent,
+ "You can only chat with employees that have a dedicated user.",
+ "should display the correct information in the notification"
+ );
+
+ form.destroy();
+ });
+});
+});
diff --git a/addons/hr/static/tests/standalone_m2o_avatar_employee_tests.js b/addons/hr/static/tests/standalone_m2o_avatar_employee_tests.js
new file mode 100644
index 00000000..976cd34d
--- /dev/null
+++ b/addons/hr/static/tests/standalone_m2o_avatar_employee_tests.js
@@ -0,0 +1,124 @@
+odoo.define('hr.StandaloneM2OEmployeeTests', function (require) {
+ "use strict";
+
+ const { xml } = owl.tags;
+
+ const AbstractRendererOwl = require('web.AbstractRendererOwl');
+ const BasicView = require("web.BasicView");
+ const BasicRenderer = require("web.BasicRenderer");
+ const RendererWrapper = require('web.RendererWrapper');
+ const { createView } = require('web.test_utils');
+
+ const StandaloneM2OAvatarEmployee = require('hr.StandaloneM2OAvatarEmployee');
+
+ function getHtmlRenderer(html) {
+ return BasicRenderer.extend({
+ start: function () {
+ this.$el.html(html);
+ return this._super.apply(this, arguments);
+ }
+ });
+ }
+
+ function getOwlView(owlRenderer, viewType) {
+ viewType = viewType || "test";
+ return BasicView.extend({
+ viewType: viewType,
+ config: Object.assign({}, BasicView.prototype.config, {
+ Renderer: owlRenderer,
+ }),
+ getRenderer() {
+ return new RendererWrapper(null, this.config.Renderer, {});
+ }
+ });
+ }
+
+ function getHtmlView(html, viewType) {
+ viewType = viewType || "test";
+ return BasicView.extend({
+ viewType: viewType,
+ config: Object.assign({}, BasicView.prototype.config, {
+ Renderer: getHtmlRenderer(html)
+ })
+ });
+ }
+
+ QUnit.module('hr', {}, function () {
+ QUnit.module('StandaloneM2OEmployeeTests', {
+ beforeEach: function () {
+ this.data = {
+ 'foo': {
+ fields: {
+ employee_id: {string: "Employee", type: 'many2one', relation: 'hr.employee'},
+ },
+ records: [],
+ },
+ 'hr.employee': {
+ fields: {},
+ records: [
+ {id: 10, name: "Mario"},
+ {id: 20, name: "Luigi"},
+ {id: 30, name: "Yoshi"}
+ ],
+ },
+ };
+ },
+ });
+
+ QUnit.test('standalone_m2o_avatar_employee: legacy view', async function (assert) {
+ assert.expect(1);
+
+ const html = "<div class='coucou_test'></div>";
+ const view = await createView({
+ View: getHtmlView(html, "test"),
+ data: this.data,
+ model: "foo",
+ arch: "<test/>"
+ });
+
+ const avatar10 = new StandaloneM2OAvatarEmployee(view, 10);
+ const avatar20 = new StandaloneM2OAvatarEmployee(view, 20);
+ const avatar30 = new StandaloneM2OAvatarEmployee(view, [30, 'Bowser']);
+
+ await avatar10.appendTo(view.el.querySelector('.coucou_test'));
+ await avatar20.appendTo(view.el.querySelector('.coucou_test'));
+ await avatar30.appendTo(view.el.querySelector('.coucou_test'));
+
+ assert.deepEqual(
+ [...view.el.querySelectorAll('.o_field_many2one_avatar span')].map(el => el.innerText),
+ ["Mario", "Luigi", "Bowser"]
+ );
+
+ view.destroy();
+ });
+
+ QUnit.test('standalone_m2o_avatar_employee: Owl view', async function (assert) {
+ assert.expect(1);
+
+ class Renderer extends AbstractRendererOwl { }
+ Renderer.template = xml`<div class='coucou_test'></div>`;
+
+ const view = await createView({
+ View: getOwlView(Renderer, "test"),
+ data: this.data,
+ model: "foo",
+ arch: "<test/>"
+ });
+
+ const avatar10 = new StandaloneM2OAvatarEmployee(view, 10);
+ const avatar20 = new StandaloneM2OAvatarEmployee(view, 20);
+ const avatar30 = new StandaloneM2OAvatarEmployee(view, [30, 'Bowser']);
+
+ await avatar10.appendTo(view.el.querySelector('.coucou_test'));
+ await avatar20.appendTo(view.el.querySelector('.coucou_test'));
+ await avatar30.appendTo(view.el.querySelector('.coucou_test'));
+
+ assert.deepEqual(
+ [...view.el.querySelectorAll('.o_field_many2one_avatar span')].map(el => el.innerText),
+ ["Mario", "Luigi", "Bowser"]
+ );
+
+ view.destroy();
+ });
+ });
+});