From 67d1ff4ac0a93c051e8491826414f3471c2f05aa Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Fri, 3 Feb 2023 13:48:46 +0100 Subject: [PATCH] feat: Ignore unsupported notifications features in subscriptions --- src/server/notifications/BaseChannelType.ts | 25 +++++++++++-------- .../notifications/BaseChannelType.test.ts | 20 +++++++++++++++ 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/server/notifications/BaseChannelType.ts b/src/server/notifications/BaseChannelType.ts index 4b4fc61e3..a3a7234f6 100644 --- a/src/server/notifications/BaseChannelType.ts +++ b/src/server/notifications/BaseChannelType.ts @@ -223,18 +223,21 @@ export abstract class BaseChannelType implements NotificationChannelType { // Apply the values for all present features that are enabled for (const feature of DEFAULT_NOTIFICATION_FEATURES) { - const objects = data.getObjects(subject, feature, null); - if (objects.length === 1) { - // Will always succeed since we are iterating over a list which was built using `featureDefinitions` - const { dataType, key } = featureDefinitions.find((feat): boolean => feat.predicate.value === feature)!; - let val: string | number = objects[0].value; - if (dataType === XSD.dateTime) { - val = Date.parse(val); - } else if (dataType === XSD.duration) { - val = toSeconds(parse(val)) * 1000; + const featNode = this.features.find((node): boolean => node.value === feature); + if (featNode) { + const objects = data.getObjects(subject, feature, null); + if (objects.length === 1) { + // Will always succeed since we are iterating over a list which was built using `featureDefinitions` + const { dataType, key } = featureDefinitions.find((feat): boolean => feat.predicate.value === feature)!; + let val: string | number = objects[0].value; + if (dataType === XSD.dateTime) { + val = Date.parse(val); + } else if (dataType === XSD.duration) { + val = toSeconds(parse(val)) * 1000; + } + // Need to convince TS that we can assign `string | number` to this key + (channel as Record)[key] = val; } - // Need to convince TS that we can assign `string | number` to this key - (channel as Record)[key] = val; } } diff --git a/test/unit/server/notifications/BaseChannelType.test.ts b/test/unit/server/notifications/BaseChannelType.test.ts index a8f1e6d2d..8ee4baa87 100644 --- a/test/unit/server/notifications/BaseChannelType.test.ts +++ b/test/unit/server/notifications/BaseChannelType.test.ts @@ -142,6 +142,26 @@ describe('A BaseChannelType', (): void => { })); }); + it('removes features from the input that are not supported.', async(): Promise => { + const date = '1988-03-09T14:48:00.000Z'; + + data.addQuad(quad(subject, NOTIFY.terms.startAt, literal(date, XSD.terms.dateTime))); + data.addQuad(quad(subject, NOTIFY.terms.endAt, literal(date, XSD.terms.dateTime))); + data.addQuad(quad(subject, NOTIFY.terms.rate, literal('PT10S', XSD.terms.duration))); + data.addQuad(quad(subject, NOTIFY.terms.accept, literal('text/turtle'))); + data.addQuad(quad(subject, NOTIFY.terms.state, literal('123456'))); + + const featChannelType = new DummyChannelType([ 'notify:endAt', 'notify:accept', NOTIFY.state ]); + await expect(featChannelType.initChannel(data, credentials)).resolves.toEqual({ + id, + type: dummyType.value, + topic: 'https://storage.example/resource', + endAt: Date.parse(date), + accept: 'text/turtle', + state: '123456', + }); + }); + it('requires correct datatypes on the features.', async(): Promise => { for (const feature of DEFAULT_NOTIFICATION_FEATURES) { const badData = new Store(data.getQuads(null, null, null, null));