-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: updated activitypub test suite
- Loading branch information
Showing
2 changed files
with
168 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,187 @@ | ||
'use strict'; | ||
|
||
const assert = require('assert'); | ||
const nconf = require('nconf'); | ||
const request = require('request-promise-native'); | ||
|
||
const db = require('./mocks/databasemock'); | ||
const slugify = require('../src/slugify'); | ||
const utils = require('../src/utils'); | ||
|
||
const user = require('../src/user'); | ||
const privileges = require('../src/privileges'); | ||
|
||
describe('ActivityPub integration', () => { | ||
describe('WebFinger endpoint', () => { | ||
let uid; | ||
let slug; | ||
const { hostname } = nconf.get('url_parsed'); | ||
|
||
beforeEach(async () => { | ||
slug = slugify(utils.generateUUID().slice(0, 8)); | ||
uid = await user.create({ username: slug }); | ||
}); | ||
|
||
it('should return a 404 Not Found if no user exists by that username', async () => { | ||
const response = await request(`${nconf.get('url')}/register/complete`, { | ||
method: 'post', | ||
jar, | ||
const response = await request(`${nconf.get('url')}/.well-known/webfinger?resource=acct:foobar@${hostname}`, { | ||
method: 'get', | ||
json: true, | ||
followRedirect: true, | ||
simple: false, | ||
resolveWithFullResponse: true, | ||
}); | ||
|
||
assert(response); | ||
assert.strictEqual(response.statusCode, 404); | ||
}); | ||
|
||
it('should return a 400 Bad Request if the request is malformed', async () => { | ||
const response = await request(`${nconf.get('url')}/.well-known/webfinger?resource=acct:foobar`, { | ||
method: 'get', | ||
json: true, | ||
followRedirect: true, | ||
simple: false, | ||
resolveWithFullResponse: true, | ||
}); | ||
|
||
assert(response); | ||
assert.strictEqual(response.statusCode, 400); | ||
}); | ||
|
||
it('should return 403 Forbidden if the calling user is not allowed to view the user list/profiles', async () => { | ||
await privileges.global.rescind(['groups:view:users'], 'guests'); | ||
const response = await request(`${nconf.get('url')}/.well-known/webfinger?resource=acct:${slug}@${hostname}`, { | ||
method: 'get', | ||
json: true, | ||
followRedirect: true, | ||
simple: false, | ||
resolveWithFullResponse: true, | ||
}); | ||
|
||
assert(response); | ||
assert.strictEqual(response.statusCode, 403); | ||
await privileges.global.give(['groups:view:users'], 'guests'); | ||
}); | ||
|
||
it('should return a valid WebFinger response otherwise', async () => { | ||
const response = await request(`${nconf.get('url')}/.well-known/webfinger?resource=acct:${slug}@${hostname}`, { | ||
method: 'get', | ||
json: true, | ||
followRedirect: true, | ||
simple: false, | ||
resolveWithFullResponse: true, | ||
}); | ||
|
||
assert(response); | ||
assert.strictEqual(response.statusCode, 200); | ||
|
||
['subject', 'aliases', 'links'].forEach((prop) => { | ||
assert(response.body.hasOwnProperty(prop)); | ||
assert(response.body[prop]); | ||
}); | ||
|
||
assert.strictEqual(response.body.subject, `acct:${slug}@${hostname}`); | ||
|
||
assert(Array.isArray(response.body.aliases)); | ||
assert([`${nconf.get('url')}/uid/${uid}`, `${nconf.get('url')}/user/${slug}`].every(url => response.body.aliases.includes(url))); | ||
|
||
assert(Array.isArray(response.body.links)); | ||
}); | ||
}); | ||
|
||
describe('ActivityPub screener middleware', () => { | ||
let uid; | ||
let slug; | ||
|
||
beforeEach(async () => { | ||
slug = slugify(utils.generateUUID().slice(0, 8)); | ||
uid = await user.create({ username: slug }); | ||
}); | ||
|
||
it('should return regular user profile html if Accept header is not ActivityPub-related', async () => { | ||
const response = await request(`${nconf.get('url')}/user/${slug}`, { | ||
method: 'get', | ||
followRedirect: true, | ||
simple: false, | ||
resolveWithFullResponse: true, | ||
headers: { | ||
Accept: 'text/html', | ||
}, | ||
}); | ||
|
||
assert(response); | ||
assert.strictEqual(response.statusCode, 200); | ||
assert(response.body.startsWith('<!DOCTYPE html>')); | ||
}); | ||
|
||
it('should return the ActivityPub Actor JSON-LD payload if the correct Accept header is provided', async () => { | ||
const response = await request(`${nconf.get('url')}/user/${slug}`, { | ||
method: 'get', | ||
json: true, | ||
followRedirect: false, | ||
followRedirect: true, | ||
simple: false, | ||
resolveWithFullResponse: true, | ||
headers: { | ||
'x-csrf-token': token, | ||
Accept: 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"', | ||
}, | ||
form: { | ||
email: '', | ||
}); | ||
|
||
assert(response); | ||
assert.strictEqual(response.statusCode, 200); | ||
assert(response.body.hasOwnProperty('@context')); | ||
assert(response.body['@context'].includes('https://www.w3.org/ns/activitystreams')); | ||
}); | ||
}); | ||
|
||
describe('Actor endpoint', () => { | ||
let uid; | ||
let slug; | ||
|
||
beforeEach(async () => { | ||
slug = slugify(utils.generateUUID().slice(0, 8)); | ||
uid = await user.create({ username: slug }); | ||
}); | ||
|
||
it('should return a valid ActivityPub Actor JSON-LD payload', async () => { | ||
const response = await request(`${nconf.get('url')}/user/${slug}`, { | ||
method: 'get', | ||
json: true, | ||
followRedirect: true, | ||
simple: false, | ||
resolveWithFullResponse: true, | ||
headers: { | ||
Accept: 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"', | ||
}, | ||
}); | ||
|
||
assert(response); | ||
assert.strictEqual(response.statusCode, 200); | ||
assert(response.body.hasOwnProperty('@context')); | ||
assert(response.body['@context'].includes('https://www.w3.org/ns/activitystreams')); | ||
|
||
['id', 'url', 'followers', 'following', 'inbox', 'outbox'].forEach((prop) => { | ||
assert(response.body.hasOwnProperty(prop)); | ||
assert(response.body[prop]); | ||
}); | ||
|
||
assert.strictEqual(response.body.id, response.body.url); | ||
assert.strictEqual(response.body.type, 'Person'); | ||
}); | ||
|
||
it('should contain a `publicKey` property with a public key', async () => { | ||
const response = await request(`${nconf.get('url')}/user/${slug}`, { | ||
method: 'get', | ||
json: true, | ||
followRedirect: true, | ||
simple: false, | ||
resolveWithFullResponse: true, | ||
headers: { | ||
Accept: 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"', | ||
}, | ||
}); | ||
|
||
assert(response.body.hasOwnProperty('publicKey')); | ||
assert(['id', 'owner', 'publicKeyPem'].every(prop => response.body.publicKey.hasOwnProperty(prop))); | ||
}); | ||
}); | ||
}); |