test: updated activitypub test suite

This commit is contained in:
Julian Lam
2023-05-23 16:13:16 -04:00
parent 4bd8d28a8b
commit 1c8e13bb12
2 changed files with 169 additions and 9 deletions

View File

@@ -21,7 +21,7 @@ ActivityPub.getPublicKey = async (uid) => {
};
async function generateKeys(uid) {
winston.info(`[activitypub] Generating RSA key-pair for uid ${uid}`);
winston.verbose(`[activitypub] Generating RSA key-pair for uid ${uid}`);
const {
publicKey,
privateKey,

View File

@@ -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: false,
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: {
'x-csrf-token': token,
},
form: {
email: '',
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: 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'));
});
});
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)));
});
});
});