Skip to content

Commit fef1ea2

Browse files
committed
fix: Use XML Date Format in Notifications
Using XML Date format instead of Internet Date format for Solid-PREP Notifications.
1 parent 41a2ba3 commit fef1ea2

File tree

2 files changed

+36
-11
lines changed

2 files changed

+36
-11
lines changed

lib/handlers/notify.js

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,21 @@ function getParentActivity (method, status) {
3838
return 'Update'
3939
}
4040

41+
function filterMillseconds (isoDate) {
42+
return `${isoDate.substring(0, 19)}${isoDate.substring(23)}`
43+
}
44+
45+
function getDate (date) {
46+
if (date) {
47+
const eventDate = new Date(date)
48+
if (!isNaN(eventDate.valueOf())) {
49+
return filterMillseconds(eventDate.toISOString())
50+
}
51+
}
52+
const now = new Date()
53+
return filterMillseconds(now.toISOString())
54+
}
55+
4156
function handler (req, res, next) {
4257
const { trigger, defaultNotification } = res.events.prep
4358

@@ -48,8 +63,7 @@ function handler (req, res, next) {
4863

4964
// Date is a hack since node does not seem to provide access to send date.
5065
// Date needs to be shared with parent notification
51-
const eventDate = res._header.match(/^Date: (.*?)$/m)?.[1] ||
52-
new Date().toUTCString()
66+
const eventDate = getDate(res._header.match(/^Date: (.*?)$/m)?.[1])
5367

5468
// If the resource itself newly created,
5569
// it could not have been subscribed for notifications already

test/integration/prep-test.js

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ const { parseDictionary } = require('structured-headers')
55
const prepFetch = require('prep-fetch').default
66
const { createServer } = require('../utils')
77

8+
const dateTimeRegex = /^-?\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?(?:Z|(?:\+|-)\d{2}:\d{2})$/
9+
810
const samplePath = path.join(__dirname, '../resources', 'sampleContainer')
911
const sampleFile = fs.readFileSync(path.join(samplePath, 'example1.ttl'))
1012

@@ -92,7 +94,8 @@ describe('Per Resource Events Protocol', function () {
9294
const { value } = await notificationsIterator.next()
9395
expect(value.headers.get('content-type')).to.match(/application\/ld\+json/)
9496
const notification = await value.json()
95-
expect(notification).to.haveOwnProperty('published')
97+
expect(notification.published).to.match(dateTimeRegex)
98+
expect(isNaN((new Date(notification.published)).valueOf())).to.equal(false)
9699
expect(notification.type).to.equal('Add')
97100
expect(notification.target).to.match(/sampleContainer\/example-prep\.ttl$/)
98101
expect(notification.object).to.match(/sampleContainer\/$/)
@@ -111,7 +114,8 @@ solid:inserts { <u> <v> <z>. }.`
111114
const { value } = await notificationsIterator.next()
112115
expect(value.headers.get('content-type')).to.match(/application\/ld\+json/)
113116
const notification = await value.json()
114-
expect(notification).to.haveOwnProperty('published')
117+
expect(notification.published).to.match(dateTimeRegex)
118+
expect(isNaN((new Date(notification.published)).valueOf())).to.equal(false)
115119
expect(notification.type).to.equal('Update')
116120
expect(notification.object).to.match(/sampleContainer\/$/)
117121
})
@@ -124,7 +128,8 @@ solid:inserts { <u> <v> <z>. }.`
124128
const { value } = await notificationsIterator.next()
125129
expect(value.headers.get('content-type')).to.match(/application\/ld\+json/)
126130
const notification = await value.json()
127-
expect(notification).to.haveOwnProperty('published')
131+
expect(notification.published).to.match(dateTimeRegex)
132+
expect(isNaN((new Date(notification.published)).valueOf())).to.equal(false)
128133
expect(notification.type).to.equal('Remove')
129134
expect(notification.object).to.match(/sampleContainer\/$/)
130135
expect(notification.origin).to.match(/sampleContainer\/.*example-prep.ttl$/)
@@ -140,7 +145,8 @@ solid:inserts { <u> <v> <z>. }.`
140145
const { value } = await notificationsIterator.next()
141146
expect(value.headers.get('content-type')).to.match(/application\/ld\+json/)
142147
const notification = await value.json()
143-
expect(notification).to.haveOwnProperty('published')
148+
expect(notification.published).to.match(dateTimeRegex)
149+
expect(isNaN((new Date(notification.published)).valueOf())).to.equal(false)
144150
expect(notification.type).to.equal('Add')
145151
expect(notification.target).to.match(/sampleContainer\/example-prep\/$/)
146152
expect(notification.object).to.match(/sampleContainer\/$/)
@@ -153,7 +159,8 @@ solid:inserts { <u> <v> <z>. }.`
153159
const { value } = await notificationsIterator.next()
154160
expect(value.headers.get('content-type')).to.match(/application\/ld\+json/)
155161
const notification = await value.json()
156-
expect(notification).to.haveOwnProperty('published')
162+
expect(notification.published).to.match(dateTimeRegex)
163+
expect(isNaN((new Date(notification.published)).valueOf())).to.equal(false)
157164
expect(notification.type).to.equal('Remove')
158165
expect(notification.origin).to.match(/sampleContainer\/example-prep\/$/)
159166
expect(notification.object).to.match(/sampleContainer\/$/)
@@ -172,7 +179,8 @@ solid:inserts { <u> <v> <z>. }.`
172179
const { value } = await notificationsIterator.next()
173180
expect(value.headers.get('content-type')).to.match(/application\/ld\+json/)
174181
const notification = await value.json()
175-
expect(notification).to.haveOwnProperty('published')
182+
expect(notification.published).to.match(dateTimeRegex)
183+
expect(isNaN((new Date(notification.published)).valueOf())).to.equal(false)
176184
expect(notification.type).to.equal('Add')
177185
expect(notification.object).to.match(/sampleContainer\/$/)
178186
expect(notification.target).to.match(/sampleContainer\/.*example-post\/$/)
@@ -191,7 +199,8 @@ solid:inserts { <u> <v> <z>. }.`
191199
const { value } = await notificationsIterator.next()
192200
expect(value.headers.get('content-type')).to.match(/application\/ld\+json/)
193201
const notification = await value.json()
194-
expect(notification).to.haveOwnProperty('published')
202+
expect(notification.published).to.match(dateTimeRegex)
203+
expect(isNaN((new Date(notification.published)).valueOf())).to.equal(false)
195204
expect(notification.type).to.equal('Add')
196205
expect(notification.object).to.match(/sampleContainer\/$/)
197206
expect(notification.target).to.match(/sampleContainer\/.*example-prep.ttl$/)
@@ -254,7 +263,8 @@ solid:inserts { <u> <v> <z>. }.`
254263
const { value } = await notificationsIterator.next()
255264
expect(value.headers.get('content-type')).to.match(/application\/ld\+json/)
256265
const notification = await value.json()
257-
expect(notification).to.haveOwnProperty('published')
266+
expect(notification.published).to.match(dateTimeRegex)
267+
expect(isNaN((new Date(notification.published)).valueOf())).to.equal(false)
258268
expect(notification).to.haveOwnProperty('state')
259269
expect(notification.type).to.equal('Update')
260270
expect(notification.object).to.match(/sampleContainer\/example-prep\.ttl$/)
@@ -268,7 +278,8 @@ solid:inserts { <u> <v> <z>. }.`
268278
const { value } = await notificationsIterator.next()
269279
expect(value.headers.get('content-type')).to.match(/application\/ld\+json/)
270280
const notification = await value.json()
271-
expect(notification).to.haveOwnProperty('published')
281+
expect(notification.published).to.match(dateTimeRegex)
282+
expect(isNaN((new Date(notification.published)).valueOf())).to.equal(false)
272283
expect(notification).to.haveOwnProperty('state')
273284
expect(notification.type).to.equal('Delete')
274285
expect(notification.object).to.match(/sampleContainer\/example-prep\.ttl$/)

0 commit comments

Comments
 (0)