From 75245f0d3dbaf402e1fda869329d859b01dd0b5c Mon Sep 17 00:00:00 2001 From: Kevin Ansfield Date: Tue, 12 Mar 2019 17:50:45 +0000 Subject: [PATCH] Improved duplication checking in notifications service closes https://github.com/TryGhost/Ghost/issues/10514 - deduplicates alerts based on message content as well as key --- ghost/admin/app/services/notifications.js | 11 +++++++++-- .../admin/tests/unit/services/notifications-test.js | 13 ++++++++++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/ghost/admin/app/services/notifications.js b/ghost/admin/app/services/notifications.js index fcc05eb0d4..118e7e534d 100644 --- a/ghost/admin/app/services/notifications.js +++ b/ghost/admin/app/services/notifications.js @@ -1,5 +1,5 @@ import Service, {inject as service} from '@ember/service'; -import {dasherize} from '@ember/string'; +import {dasherize, htmlSafe} from '@ember/string'; import {A as emberA, isArray as isEmberArray} from '@ember/array'; import {filter} from '@ember/object/computed'; import {get, set} from '@ember/object'; @@ -43,7 +43,7 @@ export default Service.extend({ handleNotification(message, delayed) { // If this is an alert message from the server, treat it as html safe if (typeof message.toJSON === 'function' && message.get('status') === 'alert') { - message.set('message', message.get('message').htmlSafe()); + message.set('message', htmlSafe(message.get('message'))); } if (!get(message, 'status')) { @@ -55,6 +55,13 @@ export default Service.extend({ this._removeItems(get(message, 'status'), get(message, 'key')); } + // close existing alerts/notifications which have the same text to avoid stacking + let newText = get(message, 'message').string || get(message, 'message'); + this.set('content', this.content.reject((notification) => { + let existingText = get(notification, 'message').string || get(notification, 'message'); + return existingText === newText; + })); + if (!delayed) { this.content.pushObject(message); } else { diff --git a/ghost/admin/tests/unit/services/notifications-test.js b/ghost/admin/tests/unit/services/notifications-test.js index ba1513f59e..0591290445 100644 --- a/ghost/admin/tests/unit/services/notifications-test.js +++ b/ghost/admin/tests/unit/services/notifications-test.js @@ -83,7 +83,7 @@ describe('Unit: Service: notifications', function () { // in order to cater for complex keys that are suitable for i18n // we split on the second period and treat the resulting base as // the key for duplicate checking - it('#showAlert clears duplicates', function () { + it('#showAlert clears duplicates using keys', function () { let notifications = this.subject(); run(() => { @@ -101,6 +101,17 @@ describe('Unit: Service: notifications', function () { expect(notifications.get('alerts.lastObject.message')).to.equal('Duplicate with new message'); }); + it('#showAlert clears duplicates using message text', function () { + let notifications = this.subject(); + + notifications.showAlert('Not duplicate'); + notifications.showAlert('Duplicate', {key: 'duplicate'}); + notifications.showAlert('Duplicate'); + + expect(notifications.get('alerts.length')).to.equal(2); + expect(notifications.get('alerts.lastObject.key')).to.not.exist; + }); + it('#showNotification adds POJO notifications', function () { let notifications = this.subject();