@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.
Files changed (56) hide show
  1. package/.github/workflows/main.yml +34 -0
  2. package/.github/workflows/{tag-docker.yml → tag.yml} +57 -5
  3. package/.nvmrc +1 -0
  4. package/Dockerfile +11 -16
  5. package/README.md +87 -13
  6. package/activitypub-bot.js +68 -0
  7. package/lib/activitydeliverer.js +260 -0
  8. package/lib/activityhandler.js +14 -0
  9. package/lib/activitypubclient.js +52 -1
  10. package/lib/activitystreams.js +31 -0
  11. package/lib/actorstorage.js +18 -28
  12. package/lib/app.js +18 -7
  13. package/lib/bot.js +7 -0
  14. package/lib/botcontext.js +62 -0
  15. package/lib/botdatastorage.js +0 -13
  16. package/lib/botfactory.js +24 -0
  17. package/lib/botmaker.js +23 -0
  18. package/lib/keystorage.js +7 -24
  19. package/lib/migrations/001-initial.js +107 -0
  20. package/lib/migrations/index.js +28 -0
  21. package/lib/objectcache.js +4 -1
  22. package/lib/objectstorage.js +0 -36
  23. package/lib/remotekeystorage.js +0 -24
  24. package/lib/routes/collection.js +6 -2
  25. package/lib/routes/inbox.js +7 -20
  26. package/lib/routes/sharedinbox.js +54 -0
  27. package/lib/routes/user.js +11 -5
  28. package/lib/routes/webfinger.js +11 -2
  29. package/lib/urlformatter.js +8 -0
  30. package/package.json +14 -7
  31. package/tests/activitydistributor.test.js +3 -3
  32. package/tests/activityhandler.test.js +96 -5
  33. package/tests/activitypubclient.test.js +115 -130
  34. package/tests/actorstorage.test.js +26 -4
  35. package/tests/authorizer.test.js +3 -8
  36. package/tests/botcontext.test.js +109 -63
  37. package/tests/botdatastorage.test.js +3 -2
  38. package/tests/botfactory.provincebotfactory.test.js +430 -0
  39. package/tests/fixtures/bots.js +13 -1
  40. package/tests/fixtures/eventloggingbot.js +57 -0
  41. package/tests/fixtures/provincebotfactory.js +53 -0
  42. package/tests/httpsignature.test.js +3 -4
  43. package/tests/httpsignatureauthenticator.test.js +3 -3
  44. package/tests/keystorage.test.js +37 -2
  45. package/tests/microsyntax.test.js +3 -2
  46. package/tests/objectstorage.test.js +4 -3
  47. package/tests/remotekeystorage.test.js +10 -8
  48. package/tests/routes.actor.test.js +7 -0
  49. package/tests/routes.collection.test.js +0 -1
  50. package/tests/routes.inbox.test.js +1 -0
  51. package/tests/routes.object.test.js +44 -38
  52. package/tests/routes.sharedinbox.test.js +473 -0
  53. package/tests/routes.webfinger.test.js +27 -0
  54. package/tests/utils/nock.js +250 -27
  55. package/.github/workflows/main-docker.yml +0 -45
  56. package/index.js +0 -23
@@ -9,6 +9,7 @@ import { nockSetup } from './utils/nock.js'
9
9
  import { HTTPSignature } from '../lib/httpsignature.js'
10
10
  import Logger from 'pino'
11
11
  import { Digester } from '../lib/digester.js'
12
+ import { runMigrations } from '../lib/migrations/index.js'
12
13
 
13
14
  const AS2 = 'https://www.w3.org/ns/activitystreams#'
14
15
 
@@ -22,10 +23,10 @@ describe('microsyntax', async () => {
22
23
  level: 'silent'
23
24
  })
24
25
  const digester = new Digester(logger)
25
- const connection = new Sequelize('sqlite::memory:', { logging: false })
26
+ const connection = new Sequelize({ dialect: 'sqlite', storage: ':memory:', logging: false })
26
27
  await connection.authenticate()
28
+ await runMigrations(connection)
27
29
  const keyStorage = new KeyStorage(connection, logger)
28
- await keyStorage.initialize()
29
30
  const formatter = new UrlFormatter(origin)
30
31
  const signer = new HTTPSignature(logger)
31
32
  const client = new ActivityPubClient(keyStorage, formatter, signer, digester, logger)
@@ -3,6 +3,7 @@ import as2 from '../lib/activitystreams.js'
3
3
  import assert from 'node:assert'
4
4
  import { ObjectStorage, NoSuchObjectError } from '../lib/objectstorage.js'
5
5
  import { Sequelize } from 'sequelize'
6
+ import { runMigrations } from '../lib/migrations/index.js'
6
7
 
7
8
  describe('ObjectStorage', async () => {
8
9
  let doc = null
@@ -33,15 +34,15 @@ describe('ObjectStorage', async () => {
33
34
  name: 'test',
34
35
  content: 'test'
35
36
  })
36
- connection = new Sequelize('sqlite::memory:', { logging: false })
37
+ connection = new Sequelize({ dialect: 'sqlite', storage: ':memory:', logging: false })
37
38
  await connection.authenticate()
39
+ await runMigrations(connection)
38
40
  })
39
41
  after(async () => {
40
42
  await connection.close()
41
43
  })
42
44
  it('can initialize', async () => {
43
45
  storage = new ObjectStorage(connection)
44
- await storage.initialize()
45
46
  })
46
47
  it('can create a new object', async () => {
47
48
  await storage.create(doc)
@@ -59,7 +60,7 @@ describe('ObjectStorage', async () => {
59
60
  })
60
61
  await storage.update(doc2)
61
62
  const read = await storage.read(doc2.id)
62
- assert.equal(read.name.get('en'), 'test2')
63
+ assert.equal(read.name.get(), 'test2')
63
64
  })
64
65
  it('can delete a created object', async () => {
65
66
  await storage.delete(doc)
@@ -9,9 +9,12 @@ import { nockSetup, nockFormat, getPublicKey, nockKeyRotate } from './utils/nock
9
9
  import { HTTPSignature } from '../lib/httpsignature.js'
10
10
  import Logger from 'pino'
11
11
  import { Digester } from '../lib/digester.js'
12
+ import { runMigrations } from '../lib/migrations/index.js'
12
13
 
13
14
  describe('RemoteKeyStorage', async () => {
14
- const origin = 'https://activitypubbot.example'
15
+ const host = 'activitypubbot.example'
16
+ const remoteHost = 'social.example'
17
+ const origin = `https://${host}`
15
18
  let connection = null
16
19
  let remoteKeyStorage = null
17
20
  let client = null
@@ -20,15 +23,15 @@ describe('RemoteKeyStorage', async () => {
20
23
  logger = Logger({
21
24
  level: 'silent'
22
25
  })
23
- connection = new Sequelize('sqlite::memory:', { logging: false })
26
+ connection = new Sequelize({ dialect: 'sqlite', storage: ':memory:', logging: false })
24
27
  await connection.authenticate()
28
+ await runMigrations(connection)
25
29
  const keyStorage = new KeyStorage(connection, logger)
26
- await keyStorage.initialize()
27
30
  const formatter = new UrlFormatter(origin)
28
31
  const digester = new Digester(logger)
29
32
  const signer = new HTTPSignature(logger)
30
33
  client = new ActivityPubClient(keyStorage, formatter, signer, digester, logger)
31
- nockSetup('social.example')
34
+ nockSetup(remoteHost)
32
35
  })
33
36
 
34
37
  after(async () => {
@@ -39,13 +42,12 @@ describe('RemoteKeyStorage', async () => {
39
42
  it('can initialize', async () => {
40
43
  remoteKeyStorage = new RemoteKeyStorage(client, connection, logger)
41
44
  assert.ok(remoteKeyStorage)
42
- await remoteKeyStorage.initialize()
43
45
  assert.ok(true)
44
46
  })
45
47
 
46
48
  it('can get a remote public key', async () => {
47
49
  const username = 'test'
48
- const domain = 'social.example'
50
+ const domain = remoteHost
49
51
  const id = nockFormat({ username, key: true, domain })
50
52
  const publicKey = await getPublicKey(username, domain)
51
53
  const remote = await remoteKeyStorage.getPublicKey(id)
@@ -54,7 +56,7 @@ describe('RemoteKeyStorage', async () => {
54
56
 
55
57
  it('can get the same remote public key twice', async () => {
56
58
  const username = 'test'
57
- const domain = 'social.example'
59
+ const domain = remoteHost
58
60
  const id = nockFormat({ username, key: true, domain })
59
61
  const publicKey = await getPublicKey(username, domain)
60
62
  const remote = await remoteKeyStorage.getPublicKey(id)
@@ -63,7 +65,7 @@ describe('RemoteKeyStorage', async () => {
63
65
 
64
66
  it('can get the right public key after key rotation', async () => {
65
67
  const username = 'test'
66
- const domain = 'social.example'
68
+ const domain = remoteHost
67
69
  const id = nockFormat({ username, key: true, domain })
68
70
  const publicKey = await getPublicKey(username, domain)
69
71
  const remote = await remoteKeyStorage.getPublicKey(id)
@@ -97,6 +97,12 @@ describe('actor routes', async () => {
97
97
  assert.match(response.body.publicKey.publicKeyPem, /^-----BEGIN PUBLIC KEY-----\n/)
98
98
  assert.match(response.body.publicKey.publicKeyPem, /\n-----END PUBLIC KEY-----\n$/)
99
99
  })
100
+ it('should include endpoints', async () => {
101
+ assert.strictEqual(typeof response.body.endpoints, 'object')
102
+ })
103
+ it('should include a sharedInbox endpoint', async () => {
104
+ assert.strictEqual(typeof response.body.endpoints.sharedInbox, 'string')
105
+ })
100
106
  })
101
107
 
102
108
  describe('GET non-existent user', async () => {
@@ -138,6 +144,7 @@ describe('actor routes', async () => {
138
144
  assert.strictEqual(response.body.detail, 'User dne not found')
139
145
  })
140
146
  })
147
+
141
148
  describe('GET /user/{dne}/publickey', async () => {
142
149
  let response = null
143
150
  it('should work without an error', async () => {
@@ -26,7 +26,6 @@ describe('actor collection routes', async () => {
26
26
  })
27
27
  it('should return an object', async () => {
28
28
  assert.strictEqual(typeof response.body, 'object')
29
- console.dir(response.body)
30
29
  })
31
30
  it('should return an object with an id', async () => {
32
31
  assert.strictEqual(typeof response.body.id, 'string')
@@ -68,6 +68,7 @@ describe('routes.inbox', async () => {
68
68
  )
69
69
  })
70
70
  })
71
+
71
72
  describe('can handle a duplicate incoming activity', async () => {
72
73
  const username = 'actor2'
73
74
  const botName = 'test1'
@@ -10,7 +10,9 @@ const uppercase = (string) => string.charAt(0).toUpperCase() + string.slice(1)
10
10
 
11
11
  describe('object collection routes', async () => {
12
12
  const databaseUrl = 'sqlite::memory:'
13
- const origin = 'https://activitypubbot.test'
13
+ const host = 'activitypubbot.test'
14
+ const origin = `https://${host}`
15
+ const remote = 'social.example'
14
16
  const username = 'ok'
15
17
  const type = 'object'
16
18
  const nanoid = 'hUQC9HWian7dzOxZJlJBA'
@@ -25,7 +27,7 @@ describe('object collection routes', async () => {
25
27
  before(async () => {
26
28
  app = await makeApp(databaseUrl, origin, bots, 'silent')
27
29
  const { formatter, objectStorage, actorStorage } = app.locals
28
- nockSetup('social.example')
30
+ nockSetup(remote)
29
31
  obj = await as2.import({
30
32
  id: formatter.format({ username, type, nanoid }),
31
33
  type: uppercase(type),
@@ -42,14 +44,14 @@ describe('object collection routes', async () => {
42
44
  await objectStorage.addToCollection(obj.id, 'thread', obj)
43
45
  reply = await as2.import({
44
46
  id: nockFormat({
45
- domain: 'social.example',
47
+ domain: remote,
46
48
  username: 'replier1',
47
49
  type: 'note',
48
50
  num: 1
49
51
  }),
50
52
  type: 'Note',
51
53
  attributedTo: nockFormat({
52
- domain: 'social.example',
54
+ domain: remote,
53
55
  username: 'replier1'
54
56
  }),
55
57
  content: 'This is a reply to the test object',
@@ -60,7 +62,7 @@ describe('object collection routes', async () => {
60
62
  await objectStorage.addToCollection(obj.id, 'thread', reply)
61
63
  like = await as2.import({
62
64
  id: nockFormat({
63
- domain: 'social.example',
65
+ domain: remote,
64
66
  username: 'liker1',
65
67
  type: 'like',
66
68
  num: 1,
@@ -68,7 +70,7 @@ describe('object collection routes', async () => {
68
70
  }),
69
71
  type: 'Like',
70
72
  attributedTo: nockFormat({
71
- domain: 'social.example',
73
+ domain: remote,
72
74
  username: 'liker1'
73
75
  }),
74
76
  object: obj.id,
@@ -77,7 +79,7 @@ describe('object collection routes', async () => {
77
79
  await objectStorage.addToCollection(obj.id, 'likes', like)
78
80
  share = await as2.import({
79
81
  id: nockFormat({
80
- domain: 'social.example',
82
+ domain: remote,
81
83
  username: 'sharer1',
82
84
  type: 'announce',
83
85
  num: 1,
@@ -85,7 +87,7 @@ describe('object collection routes', async () => {
85
87
  }),
86
88
  type: 'Announce',
87
89
  attributedTo: nockFormat({
88
- domain: 'social.example',
90
+ domain: remote,
89
91
  username: 'sharer1'
90
92
  }),
91
93
  object: obj.id,
@@ -105,10 +107,14 @@ describe('object collection routes', async () => {
105
107
  to: formatter.format({ username, collection: 'followers' })
106
108
  })
107
109
  await objectStorage.create(privateObj)
110
+ const follower = await makeActor('follower1', remote)
108
111
  await actorStorage.addToCollection(
109
112
  username,
110
113
  'followers',
111
- await makeActor('follower1', 'social.example')
114
+ follower
115
+ )
116
+ assert.ok(
117
+ await actorStorage.isInCollection(username, 'followers', follower)
112
118
  )
113
119
  })
114
120
 
@@ -130,7 +136,7 @@ describe('object collection routes', async () => {
130
136
  })
131
137
  it('should return an object with the right id', async () => {
132
138
  assert.strictEqual(typeof response.body.id, 'string')
133
- assert.strictEqual(response.body.id, `https://activitypubbot.test/user/${username}/${type}/${nanoid}`)
139
+ assert.strictEqual(response.body.id, `${origin}/user/${username}/${type}/${nanoid}`)
134
140
  })
135
141
  it('should return an object with the right type', async () => {
136
142
  assert.strictEqual(typeof response.body.type, 'string')
@@ -142,15 +148,15 @@ describe('object collection routes', async () => {
142
148
  })
143
149
  it('should return an object with the right replies', async () => {
144
150
  assert.strictEqual(typeof response.body.replies, 'string')
145
- assert.strictEqual(response.body.replies, `https://activitypubbot.test/user/${username}/${type}/${nanoid}/replies`)
151
+ assert.strictEqual(response.body.replies, `${origin}/user/${username}/${type}/${nanoid}/replies`)
146
152
  })
147
153
  it('should return an object with the right likes', async () => {
148
154
  assert.strictEqual(typeof response.body.likes, 'string')
149
- assert.strictEqual(response.body.likes, `https://activitypubbot.test/user/${username}/${type}/${nanoid}/likes`)
155
+ assert.strictEqual(response.body.likes, `${origin}/user/${username}/${type}/${nanoid}/likes`)
150
156
  })
151
157
  it('should return an object with the right shares', async () => {
152
158
  assert.strictEqual(typeof response.body.shares, 'string')
153
- assert.strictEqual(response.body.shares, `https://activitypubbot.test/user/${username}/${type}/${nanoid}/shares`)
159
+ assert.strictEqual(response.body.shares, `${origin}/user/${username}/${type}/${nanoid}/shares`)
154
160
  })
155
161
  })
156
162
 
@@ -172,7 +178,7 @@ describe('object collection routes', async () => {
172
178
  })
173
179
  it('should return an object the right id', async () => {
174
180
  assert.strictEqual(typeof response.body.id, 'string')
175
- assert.strictEqual(response.body.id, `https://activitypubbot.test/user/${username}/${type}/${nanoid}/replies`)
181
+ assert.strictEqual(response.body.id, `${origin}/user/${username}/${type}/${nanoid}/replies`)
176
182
  })
177
183
  it('should return an object with the right type', async () => {
178
184
  assert.strictEqual(typeof response.body.type, 'string')
@@ -184,11 +190,11 @@ describe('object collection routes', async () => {
184
190
  })
185
191
  it('should return an object with the right first', async () => {
186
192
  assert.strictEqual(typeof response.body.first, 'string')
187
- assert.strictEqual(response.body.first, `https://activitypubbot.test/user/${username}/${type}/${nanoid}/replies/1`)
193
+ assert.strictEqual(response.body.first, `${origin}/user/${username}/${type}/${nanoid}/replies/1`)
188
194
  })
189
195
  it('should return an object with the right last', async () => {
190
196
  assert.strictEqual(typeof response.body.last, 'string')
191
- assert.strictEqual(response.body.last, `https://activitypubbot.test/user/${username}/${type}/${nanoid}/replies/1`)
197
+ assert.strictEqual(response.body.last, `${origin}/user/${username}/${type}/${nanoid}/replies/1`)
192
198
  })
193
199
  it('should return an object with the right repliesOf', async () => {
194
200
  assert.strictEqual(typeof response.body.repliesOf, 'string')
@@ -214,7 +220,7 @@ describe('object collection routes', async () => {
214
220
  })
215
221
  it('should return an object the right id', async () => {
216
222
  assert.strictEqual(typeof response.body.id, 'string')
217
- assert.strictEqual(response.body.id, `https://activitypubbot.test/user/${username}/${type}/${nanoid}/replies/1`)
223
+ assert.strictEqual(response.body.id, `${origin}/user/${username}/${type}/${nanoid}/replies/1`)
218
224
  })
219
225
  it('should return an object with the right type', async () => {
220
226
  assert.strictEqual(typeof response.body.type, 'string')
@@ -222,7 +228,7 @@ describe('object collection routes', async () => {
222
228
  })
223
229
  it('should return an object with the right partOf', async () => {
224
230
  assert.strictEqual(typeof response.body.partOf, 'string')
225
- assert.strictEqual(response.body.partOf, `https://activitypubbot.test/user/${username}/${type}/${nanoid}/replies`)
231
+ assert.strictEqual(response.body.partOf, `${origin}/user/${username}/${type}/${nanoid}/replies`)
226
232
  })
227
233
  it('should return an object with the right items', async () => {
228
234
  assert.strictEqual(typeof response.body.items, 'object')
@@ -249,7 +255,7 @@ describe('object collection routes', async () => {
249
255
  })
250
256
  it('should return an object the right id', async () => {
251
257
  assert.strictEqual(typeof response.body.id, 'string')
252
- assert.strictEqual(response.body.id, `https://activitypubbot.test/user/${username}/${type}/${nanoid}/likes`)
258
+ assert.strictEqual(response.body.id, `${origin}/user/${username}/${type}/${nanoid}/likes`)
253
259
  })
254
260
  it('should return an object with the right type', async () => {
255
261
  assert.strictEqual(typeof response.body.type, 'string')
@@ -261,11 +267,11 @@ describe('object collection routes', async () => {
261
267
  })
262
268
  it('should return an object with the right first', async () => {
263
269
  assert.strictEqual(typeof response.body.first, 'string')
264
- assert.strictEqual(response.body.first, `https://activitypubbot.test/user/${username}/${type}/${nanoid}/likes/1`)
270
+ assert.strictEqual(response.body.first, `${origin}/user/${username}/${type}/${nanoid}/likes/1`)
265
271
  })
266
272
  it('should return an object with the right last', async () => {
267
273
  assert.strictEqual(typeof response.body.last, 'string')
268
- assert.strictEqual(response.body.last, `https://activitypubbot.test/user/${username}/${type}/${nanoid}/likes/1`)
274
+ assert.strictEqual(response.body.last, `${origin}/user/${username}/${type}/${nanoid}/likes/1`)
269
275
  })
270
276
  it('should return an object with the right likesOf', async () => {
271
277
  assert.strictEqual(typeof response.body.likesOf, 'string')
@@ -291,7 +297,7 @@ describe('object collection routes', async () => {
291
297
  })
292
298
  it('should return an object the right id', async () => {
293
299
  assert.strictEqual(typeof response.body.id, 'string')
294
- assert.strictEqual(response.body.id, `https://activitypubbot.test/user/${username}/${type}/${nanoid}/likes/1`)
300
+ assert.strictEqual(response.body.id, `${origin}/user/${username}/${type}/${nanoid}/likes/1`)
295
301
  })
296
302
  it('should return an object with the right type', async () => {
297
303
  assert.strictEqual(typeof response.body.type, 'string')
@@ -299,7 +305,7 @@ describe('object collection routes', async () => {
299
305
  })
300
306
  it('should return an object with the right partOf', async () => {
301
307
  assert.strictEqual(typeof response.body.partOf, 'string')
302
- assert.strictEqual(response.body.partOf, `https://activitypubbot.test/user/${username}/${type}/${nanoid}/likes`)
308
+ assert.strictEqual(response.body.partOf, `${origin}/user/${username}/${type}/${nanoid}/likes`)
303
309
  })
304
310
  it('should return an object with the right items', async () => {
305
311
  assert.strictEqual(typeof response.body.items, 'object')
@@ -326,7 +332,7 @@ describe('object collection routes', async () => {
326
332
  })
327
333
  it('should return an object the right id', async () => {
328
334
  assert.strictEqual(typeof response.body.id, 'string')
329
- assert.strictEqual(response.body.id, `https://activitypubbot.test/user/${username}/${type}/${nanoid}/shares`)
335
+ assert.strictEqual(response.body.id, `${origin}/user/${username}/${type}/${nanoid}/shares`)
330
336
  })
331
337
  it('should return an object with the right type', async () => {
332
338
  assert.strictEqual(typeof response.body.type, 'string')
@@ -338,11 +344,11 @@ describe('object collection routes', async () => {
338
344
  })
339
345
  it('should return an object with the right first', async () => {
340
346
  assert.strictEqual(typeof response.body.first, 'string')
341
- assert.strictEqual(response.body.first, `https://activitypubbot.test/user/${username}/${type}/${nanoid}/shares/1`)
347
+ assert.strictEqual(response.body.first, `${origin}/user/${username}/${type}/${nanoid}/shares/1`)
342
348
  })
343
349
  it('should return an object with the right last', async () => {
344
350
  assert.strictEqual(typeof response.body.last, 'string')
345
- assert.strictEqual(response.body.last, `https://activitypubbot.test/user/${username}/${type}/${nanoid}/shares/1`)
351
+ assert.strictEqual(response.body.last, `${origin}/user/${username}/${type}/${nanoid}/shares/1`)
346
352
  })
347
353
  it('should return an object with the right sharesOf', async () => {
348
354
  assert.strictEqual(typeof response.body.sharesOf, 'string')
@@ -368,7 +374,7 @@ describe('object collection routes', async () => {
368
374
  })
369
375
  it('should return an object the right id', async () => {
370
376
  assert.strictEqual(typeof response.body.id, 'string')
371
- assert.strictEqual(response.body.id, `https://activitypubbot.test/user/${username}/${type}/${nanoid}/shares/1`)
377
+ assert.strictEqual(response.body.id, `${origin}/user/${username}/${type}/${nanoid}/shares/1`)
372
378
  })
373
379
  it('should return an object with the right type', async () => {
374
380
  assert.strictEqual(typeof response.body.type, 'string')
@@ -376,7 +382,7 @@ describe('object collection routes', async () => {
376
382
  })
377
383
  it('should return an object with the right partOf', async () => {
378
384
  assert.strictEqual(typeof response.body.partOf, 'string')
379
- assert.strictEqual(response.body.partOf, `https://activitypubbot.test/user/${username}/${type}/${nanoid}/shares`)
385
+ assert.strictEqual(response.body.partOf, `${origin}/user/${username}/${type}/${nanoid}/shares`)
380
386
  })
381
387
  it('should return an object with the right items', async () => {
382
388
  assert.strictEqual(typeof response.body.items, 'object')
@@ -423,16 +429,16 @@ describe('object collection routes', async () => {
423
429
 
424
430
  describe('Get private object with follower', async () => {
425
431
  let response = null
426
- const path = `/user/${username}/${type}/${privateNanoid}`
427
- const url = `${origin}${path}`
428
- const date = new Date().toISOString()
429
- const signature = await nockSignature({ username: 'follower1', url, date })
430
432
  it('should work without an error', async () => {
433
+ const path = `/user/${username}/${type}/${privateNanoid}`
434
+ const url = `${origin}${path}`
435
+ const date = new Date().toISOString()
436
+ const signature = await nockSignature({ username: 'follower1', url, date })
431
437
  response = await request(app)
432
438
  .get(path)
433
439
  .set('Signature', signature)
434
440
  .set('Date', date)
435
- .set('Host', 'activitypubbot.test')
441
+ .set('Host', host)
436
442
  })
437
443
  it('should return a 200 status', async () => {
438
444
  assert.strictEqual(response.status, 200)
@@ -457,7 +463,7 @@ describe('object collection routes', async () => {
457
463
  })
458
464
  it('should return an object the right id', async () => {
459
465
  assert.strictEqual(typeof response.body.id, 'string')
460
- assert.strictEqual(response.body.id, `https://activitypubbot.test/user/${username}/${type}/${nanoid}/thread`)
466
+ assert.strictEqual(response.body.id, `${origin}/user/${username}/${type}/${nanoid}/thread`)
461
467
  })
462
468
  it('should return an object with the right type', async () => {
463
469
  assert.strictEqual(typeof response.body.type, 'string')
@@ -469,11 +475,11 @@ describe('object collection routes', async () => {
469
475
  })
470
476
  it('should return an object with the right first', async () => {
471
477
  assert.strictEqual(typeof response.body.first, 'string')
472
- assert.strictEqual(response.body.first, `https://activitypubbot.test/user/${username}/${type}/${nanoid}/thread/1`)
478
+ assert.strictEqual(response.body.first, `${origin}/user/${username}/${type}/${nanoid}/thread/1`)
473
479
  })
474
480
  it('should return an object with the right last', async () => {
475
481
  assert.strictEqual(typeof response.body.last, 'string')
476
- assert.strictEqual(response.body.last, `https://activitypubbot.test/user/${username}/${type}/${nanoid}/thread/1`)
482
+ assert.strictEqual(response.body.last, `${origin}/user/${username}/${type}/${nanoid}/thread/1`)
477
483
  })
478
484
  it('should return an object with the right root', async () => {
479
485
  assert.strictEqual(typeof response.body.root, 'string')
@@ -499,7 +505,7 @@ describe('object collection routes', async () => {
499
505
  })
500
506
  it('should return an object the right id', async () => {
501
507
  assert.strictEqual(typeof response.body.id, 'string')
502
- assert.strictEqual(response.body.id, `https://activitypubbot.test/user/${username}/${type}/${nanoid}/thread/1`)
508
+ assert.strictEqual(response.body.id, `${origin}/user/${username}/${type}/${nanoid}/thread/1`)
503
509
  })
504
510
  it('should return an object with the right type', async () => {
505
511
  assert.strictEqual(typeof response.body.type, 'string')
@@ -507,7 +513,7 @@ describe('object collection routes', async () => {
507
513
  })
508
514
  it('should return an object with the right partOf', async () => {
509
515
  assert.strictEqual(typeof response.body.partOf, 'string')
510
- assert.strictEqual(response.body.partOf, `https://activitypubbot.test/user/${username}/${type}/${nanoid}/thread`)
516
+ assert.strictEqual(response.body.partOf, `${origin}/user/${username}/${type}/${nanoid}/thread`)
511
517
  })
512
518
  it('should return an object with the right items', async () => {
513
519
  assert.strictEqual(typeof response.body.items, 'object')