From 3751379f1e9a4c215fb6eb898b4ccc67659b9ace Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Tue, 10 May 2022 21:51:50 +0700 Subject: initial commit 2 --- .../tests/services/notification_service_tests.js | 289 +++++++++++++++++++++ 1 file changed, 289 insertions(+) create mode 100644 addons/web/static/tests/services/notification_service_tests.js (limited to 'addons/web/static/tests/services/notification_service_tests.js') diff --git a/addons/web/static/tests/services/notification_service_tests.js b/addons/web/static/tests/services/notification_service_tests.js new file mode 100644 index 00000000..45b4de51 --- /dev/null +++ b/addons/web/static/tests/services/notification_service_tests.js @@ -0,0 +1,289 @@ +odoo.define('web.notification_tests', function (require) { +"use strict"; + +var AbstractView = require('web.AbstractView'); +var Notification = require('web.Notification'); +var NotificationService = require('web.NotificationService'); + +var testUtils = require('web.test_utils'); +var createView = testUtils.createView; + +var waitCloseNotification = function () { + return new Promise(function (resolve) { + setTimeout(resolve, 1); + }); +} + +QUnit.module('Services', { + beforeEach: function () { + // We need to use a delay above 0 ms because otherwise the notification will close right after it opens + // before we can perform any test. + testUtils.mock.patch(Notification, { + _autoCloseDelay: 1, + _animation: false, + }); + this.viewParams = { + View: AbstractView, + arch: '', + data: { + fake_model: { + fields: {}, + record: [], + }, + }, + model: 'fake_model', + services: { + notification: NotificationService, + }, + }; + }, + afterEach: function () { + // The Notification Service has a side effect: it adds a div inside + // document.body. We could implement a cleanup mechanism for services, + // but this seems a little overkill since services are not supposed to + // be destroyed anyway. + $('.o_notification_manager').remove(); + testUtils.mock.unpatch(Notification); + } +}, function () { + QUnit.module('Notification'); + + QUnit.test('Display a warning notification', async function (assert) { + assert.expect(4); + + var view = await createView(this.viewParams); + view.call('notification', 'notify', { + title: 'a', + message: 'b', + }); + await testUtils.nextMicrotaskTick(); + var $notification = $('body .o_notification_manager .o_notification'); + assert.strictEqual($notification.html().trim().replace(/\s+/g, ' '), + "
a
b
", + "should display notification"); + assert.containsOnce($notification, '.o_notification_close'); + await waitCloseNotification(); + assert.strictEqual($notification.is(':hidden'), true, "should hide the notification"); + assert.strictEqual($('body .o_notification_manager .o_notification').length, 0, "should destroy the notification"); + view.destroy(); + }); + + QUnit.test('Display a danger notification', async function (assert) { + assert.expect(1); + + var view = await createView(this.viewParams); + view.call('notification', 'notify', { + title: 'a', + message: 'b', + type: 'danger' + }); + await testUtils.nextMicrotaskTick(); + var $notification = $('body .o_notification_manager .o_notification'); + assert.strictEqual($notification.html().trim().replace(/\s+/g, ' '), + "
a
b
", + "should display notification"); + view.destroy(); + }); + + QUnit.test('Display a sticky notification', async function (assert) { + assert.expect(3); + + var view = await createView(this.viewParams); + view.call('notification', 'notify', { + title: 'a', + message: 'b', + sticky: true, + }); + await testUtils.nextTick(); + var $notification = $('body .o_notification_manager .o_notification'); + assert.containsOnce($notification, '.o_notification_close', "should display the close button in notification"); + + assert.strictEqual($notification.is(':hidden'), false, "should not hide the notification automatically"); + await testUtils.dom.click($notification.find('.o_notification_close')); + assert.strictEqual($('body .o_notification_manager .o_notification').length, + 0, "should destroy the notification"); + view.destroy(); + }); + + QUnit.test('Display a notification without title', async function (assert) { + assert.expect(3); + + const view = await createView(this.viewParams); + view.call('notification', 'notify', { + title: false, + message: 'b', + sticky: true, + }); + await testUtils.nextTick(); + const $notification = $('body .o_notification_manager .o_notification'); + assert.containsNone($notification, '.toast-header .o_notification_title'); + assert.containsNone($notification, '.o_notification_icon'); + assert.containsOnce($notification, '.toast-body .o_notification_close'); + + view.destroy(); + }); + + // FIXME skip because the feature is unused and do not understand why the test even worked before + QUnit.skip('Display a simple notification with onClose callback when automatically close', async function (assert) { + assert.expect(2); + + var close = 0; + var view = await createView(this.viewParams); + view.call('notification', 'notify', { + title: 'a', + message: 'b', + onClose: function () { + close++; + } + }); + await testUtils.nextMicrotaskTick(); + view.destroy(); + assert.strictEqual(close, 0, "should wait to call onClose method once"); + await testUtils.nextTick(); + assert.strictEqual(close, 1, "should call onClose method once"); + }); + + QUnit.test('Display a sticky notification with onClose callback', async function (assert) { + assert.expect(2); + + testUtils.mock.unpatch(Notification); + testUtils.mock.patch(Notification, { + _autoCloseDelay: 2500, + _animation: false, + }); + var view = await createView(this.viewParams); + + var close = 0; + view.call('notification', 'notify', { + title: 'a', + message: 'b', + sticky: true, + onClose: function () { + close++; + } + }); + await testUtils.nextMicrotaskTick(); + assert.strictEqual(close, 0, "should wait to call onClose method once"); + testUtils.dom.click($('body .o_notification_manager .o_notification .o_notification_close')); + assert.strictEqual(close, 1, "should call onClose method once"); + view.destroy(); + }); + + QUnit.test('Display a question', async function (assert) { + assert.expect(8); + + var view = await createView(this.viewParams); + function notification (inc) { + return { + title: 'a' + inc, + message: 'b' + inc, + buttons: [ + { + text: 'accept' + inc, + primary: true, + click: function () { + assert.step('accept' + inc); + }, + }, + { + text: 'refuse' + inc, + click: function () { + assert.step('refuse' + inc); + }, + } + ], + onClose: function () { + assert.step('close' + inc); + } + }; + }; + view.call('notification', 'notify', notification(0)); + view.call('notification', 'notify', notification(1)); + view.call('notification', 'notify', notification(2)); + await testUtils.nextTick(); + + var $notification = $('body .o_notification_manager .o_notification'); + assert.containsOnce($notification.eq(0), '.o_notification_close', + "should display the close button in notification"); + assert.strictEqual($notification.html().trim().replace(/\s+/g, ' '), + "
a0
b0
", + "should display notification"); + + testUtils.dom.click($notification.find('.o_notification_buttons button:contains(accept0)')); + testUtils.dom.click($notification.find('.o_notification_buttons button:contains(refuse1)')); + testUtils.dom.click($notification.eq(2).find('.o_notification_close')); + + assert.strictEqual($notification.is(':hidden'), true, "should hide the notification"); + assert.strictEqual($('body .o_notification_manager .o_notification').length, + 0, "should destroy the notification"); + assert.verifySteps(['accept0', 'refuse1', 'close2']); + view.destroy(); + }); + + QUnit.test('call close notification service', async function (assert) { + assert.expect(2); + + testUtils.mock.unpatch(Notification); + testUtils.mock.patch(Notification, { + _autoCloseDelay: 2500, + _animation: false, + }); + var view = await createView(this.viewParams); + + var close = 0; + var notificationId0 = view.call('notification', 'notify', { + title: 'a', + message: 'b', + onClose: function () { + close++; + } + }); + var notificationId1 = view.call('notification', 'notify', { + title: 'a', + message: 'b', + sticky: true, + onClose: function () { + close++; + } + }); + await testUtils.nextTick(); + + view.call('notification', 'close', notificationId0); + view.call('notification', 'close', notificationId1); + await testUtils.nextTick(); + + assert.strictEqual($('body .o_notification_manager .o_notification').length, 0, "should destroy the notifications"); + assert.strictEqual(close, 2, "should call onClose method twice"); + view.destroy(); + }); + + QUnit.test('Display a custom notification', async function (assert) { + assert.expect(3); + + var Custom = Notification.extend({ + init: function (parent, params) { + this._super.apply(this, arguments); + assert.ok(params.customParams, 'instantiate custom notification'); + }, + start: function () { + var self = this; + return this._super().then(function () { + self.$el.html('Custom'); + }); + }, + }); + + var view = await createView(this.viewParams); + view.call('notification', 'notify', { + Notification: Custom, + customParams: true, + }); + await testUtils.nextMicrotaskTick(); + assert.containsOnce($('body'), '.o_notification_manager .o_notification:contains(Custom)', + "should display the notification"); + view.destroy(); + assert.containsNone($('body'), '.o_notification_manager .o_notification', + "should destroy the notification"); + }); + +});}); -- cgit v1.2.3