@evanp/activitypub-bot 0.9.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/main.yml +34 -0
- package/.github/workflows/{tag-docker.yml → tag.yml} +57 -5
- package/.nvmrc +1 -0
- package/Dockerfile +11 -16
- package/README.md +87 -13
- package/activitypub-bot.js +68 -0
- package/lib/activitydeliverer.js +260 -0
- package/lib/activityhandler.js +14 -0
- package/lib/activitypubclient.js +52 -1
- package/lib/activitystreams.js +31 -0
- package/lib/actorstorage.js +18 -28
- package/lib/app.js +18 -7
- package/lib/bot.js +7 -0
- package/lib/botcontext.js +62 -0
- package/lib/botdatastorage.js +0 -13
- package/lib/botfactory.js +24 -0
- package/lib/botmaker.js +23 -0
- package/lib/keystorage.js +7 -24
- package/lib/migrations/001-initial.js +107 -0
- package/lib/migrations/index.js +28 -0
- package/lib/objectcache.js +4 -1
- package/lib/objectstorage.js +0 -36
- package/lib/remotekeystorage.js +0 -24
- package/lib/routes/collection.js +6 -2
- package/lib/routes/inbox.js +7 -20
- package/lib/routes/sharedinbox.js +54 -0
- package/lib/routes/user.js +11 -5
- package/lib/routes/webfinger.js +11 -2
- package/lib/urlformatter.js +8 -0
- package/package.json +14 -7
- package/tests/activitydistributor.test.js +3 -3
- package/tests/activityhandler.test.js +96 -5
- package/tests/activitypubclient.test.js +115 -130
- package/tests/actorstorage.test.js +26 -4
- package/tests/authorizer.test.js +3 -8
- package/tests/botcontext.test.js +109 -63
- package/tests/botdatastorage.test.js +3 -2
- package/tests/botfactory.provincebotfactory.test.js +430 -0
- package/tests/fixtures/bots.js +13 -1
- package/tests/fixtures/eventloggingbot.js +57 -0
- package/tests/fixtures/provincebotfactory.js +53 -0
- package/tests/httpsignature.test.js +3 -4
- package/tests/httpsignatureauthenticator.test.js +3 -3
- package/tests/keystorage.test.js +37 -2
- package/tests/microsyntax.test.js +3 -2
- package/tests/objectstorage.test.js +4 -3
- package/tests/remotekeystorage.test.js +10 -8
- package/tests/routes.actor.test.js +7 -0
- package/tests/routes.collection.test.js +0 -1
- package/tests/routes.inbox.test.js +1 -0
- package/tests/routes.object.test.js +44 -38
- package/tests/routes.sharedinbox.test.js +473 -0
- package/tests/routes.webfinger.test.js +27 -0
- package/tests/utils/nock.js +250 -27
- package/.github/workflows/main-docker.yml +0 -45
- package/index.js +0 -23
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
import { describe, it, before } from 'node:test'
|
|
2
|
+
import assert from 'node:assert'
|
|
3
|
+
import as2 from '../lib/activitystreams.js'
|
|
4
|
+
import request from 'supertest'
|
|
5
|
+
|
|
6
|
+
import { makeApp } from '../lib/app.js'
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
nockSetup,
|
|
10
|
+
nockSignature,
|
|
11
|
+
nockFormat,
|
|
12
|
+
makeActor,
|
|
13
|
+
addFollower,
|
|
14
|
+
addFollowing,
|
|
15
|
+
addToCollection
|
|
16
|
+
} from './utils/nock.js'
|
|
17
|
+
import { makeDigest } from './utils/digest.js'
|
|
18
|
+
import bots from './fixtures/bots.js'
|
|
19
|
+
|
|
20
|
+
describe('routes.sharedinbox', async () => {
|
|
21
|
+
const host = 'activitypubbot.test'
|
|
22
|
+
const remoteHost = 'social.example'
|
|
23
|
+
const origin = `https://${host}`
|
|
24
|
+
const databaseUrl = 'sqlite::memory:'
|
|
25
|
+
let app = null
|
|
26
|
+
let formatter = null
|
|
27
|
+
let actorStorage = null
|
|
28
|
+
|
|
29
|
+
before(async () => {
|
|
30
|
+
nockSetup(remoteHost)
|
|
31
|
+
app = await makeApp(databaseUrl, origin, bots, 'silent')
|
|
32
|
+
formatter = app.locals.formatter
|
|
33
|
+
actorStorage = app.locals.actorStorage
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
describe('can handle an directly addressed activity', async () => {
|
|
37
|
+
const username = 'actor1'
|
|
38
|
+
const botName = 'test0'
|
|
39
|
+
const path = '/shared/inbox'
|
|
40
|
+
const url = `${origin}${path}`
|
|
41
|
+
const date = new Date().toUTCString()
|
|
42
|
+
let response = null
|
|
43
|
+
let signature = null
|
|
44
|
+
let body = null
|
|
45
|
+
let digest = null
|
|
46
|
+
let activity = null
|
|
47
|
+
before(async () => {
|
|
48
|
+
activity = await as2.import({
|
|
49
|
+
type: 'Activity',
|
|
50
|
+
actor: nockFormat({ username }),
|
|
51
|
+
id: nockFormat({ username, type: 'activity', num: 1 }),
|
|
52
|
+
to: formatter.format({ username: botName })
|
|
53
|
+
})
|
|
54
|
+
body = await activity.write()
|
|
55
|
+
digest = makeDigest(body)
|
|
56
|
+
signature = await nockSignature({
|
|
57
|
+
method: 'POST',
|
|
58
|
+
username,
|
|
59
|
+
url,
|
|
60
|
+
digest,
|
|
61
|
+
date
|
|
62
|
+
})
|
|
63
|
+
})
|
|
64
|
+
it('should work without an error', async () => {
|
|
65
|
+
response = await request(app)
|
|
66
|
+
.post(path)
|
|
67
|
+
.send(body)
|
|
68
|
+
.set('Signature', signature)
|
|
69
|
+
.set('Date', date)
|
|
70
|
+
.set('Host', host)
|
|
71
|
+
.set('Digest', digest)
|
|
72
|
+
.set('Content-Type', 'application/activity+json')
|
|
73
|
+
assert.ok(response)
|
|
74
|
+
await app.onIdle()
|
|
75
|
+
})
|
|
76
|
+
it('should return a 200 status', async () => {
|
|
77
|
+
assert.strictEqual(response.status, 200)
|
|
78
|
+
})
|
|
79
|
+
it('should appear in the inbox', async () => {
|
|
80
|
+
assert.strictEqual(
|
|
81
|
+
true,
|
|
82
|
+
await actorStorage.isInCollection(
|
|
83
|
+
botName,
|
|
84
|
+
'inbox',
|
|
85
|
+
activity
|
|
86
|
+
)
|
|
87
|
+
)
|
|
88
|
+
})
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
describe('can handle an followers-only activity', async () => {
|
|
92
|
+
const username = 'actor2'
|
|
93
|
+
const botNames = ['test1', 'test2']
|
|
94
|
+
const path = '/shared/inbox'
|
|
95
|
+
const url = `${origin}${path}`
|
|
96
|
+
const date = new Date().toUTCString()
|
|
97
|
+
let response = null
|
|
98
|
+
let signature = null
|
|
99
|
+
let body = null
|
|
100
|
+
let digest = null
|
|
101
|
+
let activity = null
|
|
102
|
+
let actor = null
|
|
103
|
+
before(async () => {
|
|
104
|
+
actor = await makeActor(username, remoteHost)
|
|
105
|
+
for (const botName of botNames) {
|
|
106
|
+
const botId = formatter.format({ username: botName })
|
|
107
|
+
addFollower(username, botId, remoteHost)
|
|
108
|
+
await actorStorage.addToCollection(botName, 'following', actor)
|
|
109
|
+
}
|
|
110
|
+
activity = await as2.import({
|
|
111
|
+
type: 'Activity',
|
|
112
|
+
actor: actor.id,
|
|
113
|
+
id: nockFormat({ username, type: 'activity', num: 1 }),
|
|
114
|
+
to: nockFormat({ username, collection: 'followers' })
|
|
115
|
+
})
|
|
116
|
+
body = await activity.write()
|
|
117
|
+
digest = makeDigest(body)
|
|
118
|
+
signature = await nockSignature({
|
|
119
|
+
method: 'POST',
|
|
120
|
+
username,
|
|
121
|
+
url,
|
|
122
|
+
digest,
|
|
123
|
+
date
|
|
124
|
+
})
|
|
125
|
+
})
|
|
126
|
+
it('should work without an error', async () => {
|
|
127
|
+
response = await request(app)
|
|
128
|
+
.post(path)
|
|
129
|
+
.send(body)
|
|
130
|
+
.set('Signature', signature)
|
|
131
|
+
.set('Date', date)
|
|
132
|
+
.set('Host', host)
|
|
133
|
+
.set('Digest', digest)
|
|
134
|
+
.set('Content-Type', 'application/activity+json')
|
|
135
|
+
assert.ok(response)
|
|
136
|
+
await app.onIdle()
|
|
137
|
+
})
|
|
138
|
+
it('should return a 200 status', async () => {
|
|
139
|
+
assert.strictEqual(response.status, 200)
|
|
140
|
+
})
|
|
141
|
+
it('should appear in all inboxes', async () => {
|
|
142
|
+
for (const botName of botNames) {
|
|
143
|
+
assert.strictEqual(
|
|
144
|
+
true,
|
|
145
|
+
await actorStorage.isInCollection(
|
|
146
|
+
botName,
|
|
147
|
+
'inbox',
|
|
148
|
+
activity
|
|
149
|
+
)
|
|
150
|
+
)
|
|
151
|
+
}
|
|
152
|
+
})
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
describe('can handle an public activity', async () => {
|
|
156
|
+
const username = 'actor3'
|
|
157
|
+
const path = '/shared/inbox'
|
|
158
|
+
const url = `${origin}${path}`
|
|
159
|
+
const date = new Date().toUTCString()
|
|
160
|
+
let response = null
|
|
161
|
+
let signature = null
|
|
162
|
+
let body = null
|
|
163
|
+
let digest = null
|
|
164
|
+
let activity = null
|
|
165
|
+
let actor = null
|
|
166
|
+
before(async () => {
|
|
167
|
+
actor = await makeActor(username, remoteHost)
|
|
168
|
+
activity = await as2.import({
|
|
169
|
+
type: 'Activity',
|
|
170
|
+
actor: actor.id,
|
|
171
|
+
id: nockFormat({ username, type: 'activity', num: 1 }),
|
|
172
|
+
to: 'as:Public'
|
|
173
|
+
})
|
|
174
|
+
body = await activity.write()
|
|
175
|
+
digest = makeDigest(body)
|
|
176
|
+
signature = await nockSignature({
|
|
177
|
+
method: 'POST',
|
|
178
|
+
username,
|
|
179
|
+
url,
|
|
180
|
+
digest,
|
|
181
|
+
date
|
|
182
|
+
})
|
|
183
|
+
})
|
|
184
|
+
it('should work without an error', async () => {
|
|
185
|
+
response = await request(app)
|
|
186
|
+
.post(path)
|
|
187
|
+
.send(body)
|
|
188
|
+
.set('Signature', signature)
|
|
189
|
+
.set('Date', date)
|
|
190
|
+
.set('Host', host)
|
|
191
|
+
.set('Digest', digest)
|
|
192
|
+
.set('Content-Type', 'application/activity+json')
|
|
193
|
+
assert.ok(response)
|
|
194
|
+
await app.onIdle()
|
|
195
|
+
})
|
|
196
|
+
it('should return a 200 status', async () => {
|
|
197
|
+
assert.strictEqual(response.status, 200)
|
|
198
|
+
})
|
|
199
|
+
it('should appear in all inboxes', async () => {
|
|
200
|
+
const lb = bots.logging
|
|
201
|
+
assert.ok(lb.publics.has(activity.id))
|
|
202
|
+
})
|
|
203
|
+
})
|
|
204
|
+
|
|
205
|
+
describe('can handle an activity to local followers collection', async () => {
|
|
206
|
+
const username = 'actor4'
|
|
207
|
+
const botNames = ['test3', 'test4', 'test5']
|
|
208
|
+
const followedBot = 'test6'
|
|
209
|
+
const path = '/shared/inbox'
|
|
210
|
+
const url = `${origin}${path}`
|
|
211
|
+
const date = new Date().toUTCString()
|
|
212
|
+
let response = null
|
|
213
|
+
let signature = null
|
|
214
|
+
let body = null
|
|
215
|
+
let digest = null
|
|
216
|
+
let activity = null
|
|
217
|
+
let actor = null
|
|
218
|
+
before(async () => {
|
|
219
|
+
actor = await makeActor(username, remoteHost)
|
|
220
|
+
const followed = await as2.import({
|
|
221
|
+
id: formatter.format({ username: followedBot })
|
|
222
|
+
})
|
|
223
|
+
for (const botName of botNames) {
|
|
224
|
+
const botId = formatter.format({ username: botName })
|
|
225
|
+
const bot = await as2.import({ id: botId })
|
|
226
|
+
await actorStorage.addToCollection(followedBot, 'followers', bot)
|
|
227
|
+
await actorStorage.addToCollection(botName, 'following', followed)
|
|
228
|
+
}
|
|
229
|
+
activity = await as2.import({
|
|
230
|
+
type: 'Activity',
|
|
231
|
+
actor: actor.id,
|
|
232
|
+
id: nockFormat({ username, type: 'activity', num: 1 }),
|
|
233
|
+
to: formatter.format({ username: followedBot, collection: 'followers' })
|
|
234
|
+
})
|
|
235
|
+
body = await activity.write()
|
|
236
|
+
digest = makeDigest(body)
|
|
237
|
+
signature = await nockSignature({
|
|
238
|
+
method: 'POST',
|
|
239
|
+
username,
|
|
240
|
+
url,
|
|
241
|
+
digest,
|
|
242
|
+
date
|
|
243
|
+
})
|
|
244
|
+
})
|
|
245
|
+
it('should work without an error', async () => {
|
|
246
|
+
response = await request(app)
|
|
247
|
+
.post(path)
|
|
248
|
+
.send(body)
|
|
249
|
+
.set('Signature', signature)
|
|
250
|
+
.set('Date', date)
|
|
251
|
+
.set('Host', host)
|
|
252
|
+
.set('Digest', digest)
|
|
253
|
+
.set('Content-Type', 'application/activity+json')
|
|
254
|
+
assert.ok(response)
|
|
255
|
+
await app.onIdle()
|
|
256
|
+
})
|
|
257
|
+
it('should return a 200 status', async () => {
|
|
258
|
+
assert.strictEqual(response.status, 200)
|
|
259
|
+
})
|
|
260
|
+
it('should appear in all inboxes', async () => {
|
|
261
|
+
for (const botName of botNames) {
|
|
262
|
+
assert.strictEqual(
|
|
263
|
+
true,
|
|
264
|
+
await actorStorage.isInCollection(
|
|
265
|
+
botName,
|
|
266
|
+
'inbox',
|
|
267
|
+
activity
|
|
268
|
+
)
|
|
269
|
+
)
|
|
270
|
+
}
|
|
271
|
+
})
|
|
272
|
+
})
|
|
273
|
+
|
|
274
|
+
describe('can handle an activity to local following collection', async () => {
|
|
275
|
+
const username = 'actor5'
|
|
276
|
+
const botNames = ['test7', 'test8']
|
|
277
|
+
const followingBot = 'test9'
|
|
278
|
+
const path = '/shared/inbox'
|
|
279
|
+
const url = `${origin}${path}`
|
|
280
|
+
const date = new Date().toUTCString()
|
|
281
|
+
let response = null
|
|
282
|
+
let signature = null
|
|
283
|
+
let body = null
|
|
284
|
+
let digest = null
|
|
285
|
+
let activity = null
|
|
286
|
+
let actor = null
|
|
287
|
+
before(async () => {
|
|
288
|
+
actor = await makeActor(username, remoteHost)
|
|
289
|
+
const following = await as2.import({
|
|
290
|
+
id: formatter.format({ username: followingBot })
|
|
291
|
+
})
|
|
292
|
+
for (const botName of botNames) {
|
|
293
|
+
const botId = formatter.format({ username: botName })
|
|
294
|
+
const bot = await as2.import({ id: botId })
|
|
295
|
+
await actorStorage.addToCollection(followingBot, 'following', bot)
|
|
296
|
+
await actorStorage.addToCollection(botName, 'followers', following)
|
|
297
|
+
}
|
|
298
|
+
activity = await as2.import({
|
|
299
|
+
type: 'Activity',
|
|
300
|
+
actor: actor.id,
|
|
301
|
+
id: nockFormat({ username, type: 'activity', num: 1 }),
|
|
302
|
+
to: formatter.format({
|
|
303
|
+
username: followingBot,
|
|
304
|
+
collection: 'following'
|
|
305
|
+
})
|
|
306
|
+
})
|
|
307
|
+
body = await activity.write()
|
|
308
|
+
digest = makeDigest(body)
|
|
309
|
+
signature = await nockSignature({
|
|
310
|
+
method: 'POST',
|
|
311
|
+
username,
|
|
312
|
+
url,
|
|
313
|
+
digest,
|
|
314
|
+
date
|
|
315
|
+
})
|
|
316
|
+
})
|
|
317
|
+
it('should work without an error', async () => {
|
|
318
|
+
response = await request(app)
|
|
319
|
+
.post(path)
|
|
320
|
+
.send(body)
|
|
321
|
+
.set('Signature', signature)
|
|
322
|
+
.set('Date', date)
|
|
323
|
+
.set('Host', host)
|
|
324
|
+
.set('Digest', digest)
|
|
325
|
+
.set('Content-Type', 'application/activity+json')
|
|
326
|
+
assert.ok(response)
|
|
327
|
+
await app.onIdle()
|
|
328
|
+
})
|
|
329
|
+
it('should return a 200 status', async () => {
|
|
330
|
+
assert.strictEqual(response.status, 200)
|
|
331
|
+
})
|
|
332
|
+
it('should appear in all inboxes', async () => {
|
|
333
|
+
for (const botName of botNames) {
|
|
334
|
+
assert.strictEqual(
|
|
335
|
+
true,
|
|
336
|
+
await actorStorage.isInCollection(
|
|
337
|
+
botName,
|
|
338
|
+
'inbox',
|
|
339
|
+
activity
|
|
340
|
+
)
|
|
341
|
+
)
|
|
342
|
+
}
|
|
343
|
+
})
|
|
344
|
+
})
|
|
345
|
+
|
|
346
|
+
describe('can handle an activity to remote following collection', async () => {
|
|
347
|
+
const username = 'actor6'
|
|
348
|
+
const botNames = ['test10', 'test11', 'test12']
|
|
349
|
+
const path = '/shared/inbox'
|
|
350
|
+
const url = `${origin}${path}`
|
|
351
|
+
const date = new Date().toUTCString()
|
|
352
|
+
let response = null
|
|
353
|
+
let signature = null
|
|
354
|
+
let body = null
|
|
355
|
+
let digest = null
|
|
356
|
+
let activity = null
|
|
357
|
+
let actor = null
|
|
358
|
+
before(async () => {
|
|
359
|
+
actor = await makeActor(username, remoteHost)
|
|
360
|
+
for (const botName of botNames) {
|
|
361
|
+
const botId = formatter.format({ username: botName })
|
|
362
|
+
addFollowing(username, botId, remoteHost)
|
|
363
|
+
await actorStorage.addToCollection(botName, 'followers', actor)
|
|
364
|
+
}
|
|
365
|
+
activity = await as2.import({
|
|
366
|
+
type: 'Activity',
|
|
367
|
+
actor: actor.id,
|
|
368
|
+
id: nockFormat({ username, type: 'activity', num: 1 }),
|
|
369
|
+
to: nockFormat({ username, collection: 'following' })
|
|
370
|
+
})
|
|
371
|
+
body = await activity.write()
|
|
372
|
+
digest = makeDigest(body)
|
|
373
|
+
signature = await nockSignature({
|
|
374
|
+
method: 'POST',
|
|
375
|
+
username,
|
|
376
|
+
url,
|
|
377
|
+
digest,
|
|
378
|
+
date
|
|
379
|
+
})
|
|
380
|
+
})
|
|
381
|
+
it('should work without an error', async () => {
|
|
382
|
+
response = await request(app)
|
|
383
|
+
.post(path)
|
|
384
|
+
.send(body)
|
|
385
|
+
.set('Signature', signature)
|
|
386
|
+
.set('Date', date)
|
|
387
|
+
.set('Host', host)
|
|
388
|
+
.set('Digest', digest)
|
|
389
|
+
.set('Content-Type', 'application/activity+json')
|
|
390
|
+
assert.ok(response)
|
|
391
|
+
await app.onIdle()
|
|
392
|
+
})
|
|
393
|
+
it('should return a 200 status', async () => {
|
|
394
|
+
assert.strictEqual(response.status, 200)
|
|
395
|
+
})
|
|
396
|
+
it('should appear in all inboxes', async () => {
|
|
397
|
+
for (const botName of botNames) {
|
|
398
|
+
assert.strictEqual(
|
|
399
|
+
true,
|
|
400
|
+
await actorStorage.isInCollection(
|
|
401
|
+
botName,
|
|
402
|
+
'inbox',
|
|
403
|
+
activity
|
|
404
|
+
)
|
|
405
|
+
)
|
|
406
|
+
}
|
|
407
|
+
})
|
|
408
|
+
})
|
|
409
|
+
|
|
410
|
+
describe('can handle an activity to remote actor collection', async () => {
|
|
411
|
+
const username = 'actor7'
|
|
412
|
+
const botNames = ['test13', 'test14', 'test15']
|
|
413
|
+
const path = '/shared/inbox'
|
|
414
|
+
const url = `${origin}${path}`
|
|
415
|
+
const collection = 1
|
|
416
|
+
const date = new Date().toUTCString()
|
|
417
|
+
let response = null
|
|
418
|
+
let signature = null
|
|
419
|
+
let body = null
|
|
420
|
+
let digest = null
|
|
421
|
+
let activity = null
|
|
422
|
+
let actor = null
|
|
423
|
+
before(async () => {
|
|
424
|
+
actor = await makeActor(username, remoteHost)
|
|
425
|
+
for (const botName of botNames) {
|
|
426
|
+
const botId = formatter.format({ username: botName })
|
|
427
|
+
addToCollection(username, collection, botId, remoteHost)
|
|
428
|
+
}
|
|
429
|
+
activity = await as2.import({
|
|
430
|
+
type: 'Activity',
|
|
431
|
+
actor: actor.id,
|
|
432
|
+
id: nockFormat({ username, type: 'activity', num: 1 }),
|
|
433
|
+
to: nockFormat({ username, type: 'collection', num: collection })
|
|
434
|
+
})
|
|
435
|
+
body = await activity.write()
|
|
436
|
+
digest = makeDigest(body)
|
|
437
|
+
signature = await nockSignature({
|
|
438
|
+
method: 'POST',
|
|
439
|
+
username,
|
|
440
|
+
url,
|
|
441
|
+
digest,
|
|
442
|
+
date
|
|
443
|
+
})
|
|
444
|
+
})
|
|
445
|
+
it('should work without an error', async () => {
|
|
446
|
+
response = await request(app)
|
|
447
|
+
.post(path)
|
|
448
|
+
.send(body)
|
|
449
|
+
.set('Signature', signature)
|
|
450
|
+
.set('Date', date)
|
|
451
|
+
.set('Host', host)
|
|
452
|
+
.set('Digest', digest)
|
|
453
|
+
.set('Content-Type', 'application/activity+json')
|
|
454
|
+
assert.ok(response)
|
|
455
|
+
await app.onIdle()
|
|
456
|
+
})
|
|
457
|
+
it('should return a 200 status', async () => {
|
|
458
|
+
assert.strictEqual(response.status, 200)
|
|
459
|
+
})
|
|
460
|
+
it('should appear in all inboxes', async () => {
|
|
461
|
+
for (const botName of botNames) {
|
|
462
|
+
assert.strictEqual(
|
|
463
|
+
true,
|
|
464
|
+
await actorStorage.isInCollection(
|
|
465
|
+
botName,
|
|
466
|
+
'inbox',
|
|
467
|
+
activity
|
|
468
|
+
)
|
|
469
|
+
)
|
|
470
|
+
}
|
|
471
|
+
})
|
|
472
|
+
})
|
|
473
|
+
})
|
|
@@ -38,4 +38,31 @@ describe('webfinger routes', async () => {
|
|
|
38
38
|
assert.strictEqual(response.body.links[0].href, 'https://activitypubbot.test/user/ok')
|
|
39
39
|
})
|
|
40
40
|
})
|
|
41
|
+
describe('Webfinger discovery for non-existent user', async () => {
|
|
42
|
+
let response = null
|
|
43
|
+
it('should work without an error', async () => {
|
|
44
|
+
response = await request(app).get('/.well-known/webfinger?resource=acct%3Adne%40activitypubbot.test')
|
|
45
|
+
})
|
|
46
|
+
it('should return 404 Not Found', async () => {
|
|
47
|
+
assert.strictEqual(response.status, 404)
|
|
48
|
+
})
|
|
49
|
+
})
|
|
50
|
+
describe('Webfinger discovery for wrong domain', async () => {
|
|
51
|
+
let response = null
|
|
52
|
+
it('should work without an error', async () => {
|
|
53
|
+
response = await request(app).get('/.well-known/webfinger?resource=acct%3Adne%wrongdomain.test')
|
|
54
|
+
})
|
|
55
|
+
it('should return 400 Bad Request', async () => {
|
|
56
|
+
assert.strictEqual(response.status, 400)
|
|
57
|
+
})
|
|
58
|
+
})
|
|
59
|
+
describe('Webfinger discovery for HTTPS', async () => {
|
|
60
|
+
let response = null
|
|
61
|
+
it('should work without an error', async () => {
|
|
62
|
+
response = await request(app).get('/.well-known/webfinger?resource=' + encodeURIComponent('https://activitypubbot.test/user/ok'))
|
|
63
|
+
})
|
|
64
|
+
it('should return 400 Bad Request', async () => {
|
|
65
|
+
assert.strictEqual(response.status, 400)
|
|
66
|
+
})
|
|
67
|
+
})
|
|
41
68
|
})
|