Skip to content

Commit 7f08f3b

Browse files
committed
chore: support for custom filter for in app notifications and tests
1 parent a97d879 commit 7f08f3b

File tree

3 files changed

+123
-3
lines changed

3 files changed

+123
-3
lines changed

src/assets/notifications/dev/root/toast.json

Lines changed: 0 additions & 2 deletions
This file was deleted.

src/extensionsIntegrated/InAppNotifications/banner.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ define(function (require, exports, module) {
3535

3636
ExtensionUtils.loadStyleSheet(module, "styles/styles.css");
3737

38+
let latestBannerJSON;
39+
let customFilterCallback;
40+
3841
// duration of one day in milliseconds
3942
const ONE_DAY = 1000 * 60 * 60 * 24;
4043
const IN_APP_NOTIFICATIONS_BANNER_SHOWN_STATE = "InAppNotificationsBannerShown";
@@ -64,6 +67,14 @@ define(function (require, exports, module) {
6467
return false;
6568
}
6669

70+
/**
71+
* Registers a custom filter callback function for notifications
72+
* @param {Function} cfbn - async function that filters notifications
73+
*/
74+
function registerCustomFilter(cfbn) {
75+
customFilterCallback = cfbn;
76+
}
77+
6778
/**
6879
* If there are multiple notifications, thew will be shown one after the other and not all at once.
6980
* A sample notifications is as follows:
@@ -112,6 +123,9 @@ define(function (require, exports, module) {
112123
if(!_isValidForThisPlatform(notification.PLATFORM)){
113124
continue;
114125
}
126+
if(customFilterCallback && !(await customFilterCallback(notification, notificationID))){
127+
continue;
128+
}
115129
if(!notification.DANGER_SHOW_ON_EVERY_BOOT){
116130
// One time notification. mark as shown and never show again
117131
// all notifications are one time, we track metrics for each notification separately
@@ -136,6 +150,12 @@ define(function (require, exports, module) {
136150
return null;
137151
}
138152
return response.json();
153+
})
154+
.then(json => {
155+
if (json !== null) {
156+
latestBannerJSON = json;
157+
}
158+
return json;
139159
});
140160
}
141161

@@ -167,6 +187,15 @@ define(function (require, exports, module) {
167187
});
168188
}
169189

190+
/**
191+
* Re-renders notifications using the latest cached banner JSON
192+
*/
193+
function reRenderNotifications() {
194+
if(latestBannerJSON) {
195+
_renderNotifications(latestBannerJSON);
196+
}
197+
}
198+
170199

171200
/**
172201
* Removes and cleans up the notification bar from DOM
@@ -232,8 +261,14 @@ define(function (require, exports, module) {
232261
setInterval(_fetchAndRenderNotifications, ONE_DAY);
233262
});
234263

264+
exports.registerCustomFilter = registerCustomFilter;
265+
exports.reRenderNotifications = reRenderNotifications;
266+
235267
if(Phoenix.isTestWindow){
236268
exports.cleanNotificationBanner = cleanNotificationBanner;
237269
exports._renderNotifications = _renderNotifications;
270+
exports._setBannerCache = function(notifications) {
271+
latestBannerJSON = notifications;
272+
};
238273
}
239274
});

test/spec/Extn-InAppNotifications-integ-test.js

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
*
2020
*/
2121

22-
/*global describe, it, expect, beforeAll, afterAll, awaits, Phoenix */
22+
/*global describe, it, expect, beforeAll, afterAll, awaits, awaitsFor */
2323

2424
define(function (require, exports, module) {
2525
// Recommended to avoid reloading the integration test window Phoenix instance for each test.
@@ -40,6 +40,12 @@ define(function (require, exports, module) {
4040
await SpecRunnerUtils.loadProjectInTestWindow(testPath);
4141
}, 30000);
4242

43+
async function _waitForBannerShown() {
44+
await awaitsFor(function () {
45+
return testWindow.$('#notification-bar').is(":visible");
46+
}, "banner to be shown");
47+
}
48+
4349
afterAll(async function () {
4450
testWindow = null;
4551
// comment out below line if you want to debug the test window post running tests
@@ -182,5 +188,86 @@ define(function (require, exports, module) {
182188
banner._renderNotifications(notification);
183189
expect(testWindow.$(id).length).toEqual(0);
184190
});
191+
192+
it("Should apply custom filter to block notification", async function () {
193+
banner.cleanNotificationBanner();
194+
banner.registerCustomFilter(async () => false);
195+
196+
const {notification, id} = getRandomNotification("all", true);
197+
banner._renderNotifications(notification);
198+
await awaits(50);
199+
200+
expect(testWindow.$('#notification-bar').is(":visible")).toBe(false);
201+
expect(testWindow.$(id).length).toEqual(0);
202+
203+
// Cleanup: remove custom filter
204+
banner.registerCustomFilter(null);
205+
});
206+
207+
it("Should apply custom filter to allow notification", async function () {
208+
banner.cleanNotificationBanner();
209+
banner.registerCustomFilter(async () => true);
210+
211+
const {notification, id} = getRandomNotification("all", true);
212+
banner._renderNotifications(notification);
213+
await _waitForBannerShown();
214+
215+
expect(testWindow.$(id).length).toEqual(1);
216+
217+
// Cleanup
218+
banner.registerCustomFilter(null);
219+
banner.cleanNotificationBanner();
220+
});
221+
222+
it("Should pass correct parameters to custom filter", async function () {
223+
banner.cleanNotificationBanner();
224+
let receivedNotification, receivedID;
225+
226+
const {notification} = getRandomNotification("all", true);
227+
const expectedID = Object.keys(notification)[0];
228+
229+
banner.registerCustomFilter(async (notif, notifID) => {
230+
receivedNotification = notif;
231+
receivedID = notifID;
232+
return true;
233+
});
234+
235+
banner._renderNotifications(notification);
236+
await _waitForBannerShown();
237+
238+
expect(receivedID).toEqual(expectedID);
239+
expect(receivedNotification).toEqual(notification[expectedID]);
240+
241+
// Cleanup
242+
banner.registerCustomFilter(null);
243+
banner.cleanNotificationBanner();
244+
});
245+
246+
it("Should apply custom filter on reRenderNotifications", async function () {
247+
banner.cleanNotificationBanner();
248+
249+
const {notification, id} = getRandomNotification("all", true);
250+
251+
// Set cache and render
252+
banner._setBannerCache(notification);
253+
banner._renderNotifications(notification);
254+
await _waitForBannerShown();
255+
expect(testWindow.$(id).length).toEqual(1);
256+
257+
banner.cleanNotificationBanner();
258+
259+
// Set filter to block
260+
banner.registerCustomFilter(async () => false);
261+
262+
// Re-render should not show notification due to filter
263+
banner.reRenderNotifications();
264+
await awaits(50);
265+
expect(testWindow.$('#notification-bar').is(":visible")).toBe(false);
266+
expect(testWindow.$(id).length).toEqual(0);
267+
268+
// Cleanup
269+
banner.registerCustomFilter(null);
270+
banner.cleanNotificationBanner();
271+
});
185272
});
186273
});

0 commit comments

Comments
 (0)