@evanp/activitypub-bot 0.9.0 → 0.12.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 +10 -16
- package/README.md +87 -13
- package/bin/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/index.js +3 -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/index.test.js +10 -0
- 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
package/tests/keystorage.test.js
CHANGED
|
@@ -3,6 +3,7 @@ import { KeyStorage } from '../lib/keystorage.js'
|
|
|
3
3
|
import assert from 'node:assert'
|
|
4
4
|
import { Sequelize } from 'sequelize'
|
|
5
5
|
import Logger from 'pino'
|
|
6
|
+
import { runMigrations } from '../lib/migrations/index.js'
|
|
6
7
|
|
|
7
8
|
describe('KeyStorage', async () => {
|
|
8
9
|
let connection = null
|
|
@@ -12,9 +13,14 @@ describe('KeyStorage', async () => {
|
|
|
12
13
|
let firstPrivateKey = null
|
|
13
14
|
let secondPublicKey = null
|
|
14
15
|
let secondPrivateKey = null
|
|
16
|
+
let firstSystemPublicKey = null
|
|
17
|
+
let firstSystemPrivateKey = null
|
|
18
|
+
let secondSystemPublicKey = null
|
|
19
|
+
let secondSystemPrivateKey = null
|
|
15
20
|
before(async () => {
|
|
16
|
-
connection = new Sequelize('sqlite
|
|
21
|
+
connection = new Sequelize({ dialect: 'sqlite', storage: ':memory:', logging: false })
|
|
17
22
|
await connection.authenticate()
|
|
23
|
+
await runMigrations(connection)
|
|
18
24
|
logger = new Logger({
|
|
19
25
|
level: 'silent'
|
|
20
26
|
})
|
|
@@ -26,7 +32,6 @@ describe('KeyStorage', async () => {
|
|
|
26
32
|
})
|
|
27
33
|
it('can initialize', async () => {
|
|
28
34
|
storage = new KeyStorage(connection, logger)
|
|
29
|
-
await storage.initialize()
|
|
30
35
|
})
|
|
31
36
|
it('can get a public key', async () => {
|
|
32
37
|
firstPublicKey = await storage.getPublicKey('test1')
|
|
@@ -86,4 +91,34 @@ describe('KeyStorage', async () => {
|
|
|
86
91
|
assert.ok(privateKey2)
|
|
87
92
|
assert.notEqual(privateKey, privateKey2)
|
|
88
93
|
})
|
|
94
|
+
it('can get a system public key', async () => {
|
|
95
|
+
firstSystemPublicKey = await storage.getPublicKey(null)
|
|
96
|
+
assert.ok(firstSystemPublicKey)
|
|
97
|
+
assert.equal(typeof firstSystemPublicKey, 'string')
|
|
98
|
+
assert.match(firstSystemPublicKey, /^-----BEGIN PUBLIC KEY-----\n/)
|
|
99
|
+
assert.match(firstSystemPublicKey, /-----END PUBLIC KEY-----\n$/)
|
|
100
|
+
})
|
|
101
|
+
it('can get a system public key again', async () => {
|
|
102
|
+
secondSystemPublicKey = await storage.getPublicKey(null)
|
|
103
|
+
assert.ok(secondSystemPublicKey)
|
|
104
|
+
assert.equal(typeof secondSystemPublicKey, 'string')
|
|
105
|
+
assert.match(secondSystemPublicKey, /^-----BEGIN PUBLIC KEY-----\n/)
|
|
106
|
+
assert.match(secondSystemPublicKey, /-----END PUBLIC KEY-----\n$/)
|
|
107
|
+
assert.equal(firstSystemPublicKey, secondSystemPublicKey)
|
|
108
|
+
})
|
|
109
|
+
it('can get a system private key', async () => {
|
|
110
|
+
firstSystemPrivateKey = await storage.getPrivateKey(null)
|
|
111
|
+
assert.ok(firstSystemPrivateKey)
|
|
112
|
+
assert.equal(typeof firstSystemPrivateKey, 'string')
|
|
113
|
+
assert.match(firstSystemPrivateKey, /^-----BEGIN PRIVATE KEY-----\n/)
|
|
114
|
+
assert.match(firstSystemPrivateKey, /-----END PRIVATE KEY-----\n$/)
|
|
115
|
+
})
|
|
116
|
+
it('can get a system private key again', async () => {
|
|
117
|
+
secondSystemPrivateKey = await storage.getPrivateKey(null)
|
|
118
|
+
assert.ok(secondSystemPrivateKey)
|
|
119
|
+
assert.equal(typeof secondSystemPrivateKey, 'string')
|
|
120
|
+
assert.match(secondSystemPrivateKey, /^-----BEGIN PRIVATE KEY-----\n/)
|
|
121
|
+
assert.match(secondSystemPrivateKey, /-----END PRIVATE KEY-----\n$/)
|
|
122
|
+
assert.equal(firstSystemPrivateKey, secondSystemPrivateKey)
|
|
123
|
+
})
|
|
89
124
|
})
|
|
@@ -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
|
|
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
|
|
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(
|
|
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
|
|
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
|
|
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(
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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')
|
|
@@ -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
|
|
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(
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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',
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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')
|