mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-26 08:36:12 +01:00
refactor: remove announceObject in favour of feps.announce, added create activity mock to support
This commit is contained in:
@@ -3,7 +3,6 @@
|
||||
const nconf = require('nconf');
|
||||
|
||||
const posts = require('../posts');
|
||||
const utils = require('../utils');
|
||||
|
||||
const activitypub = module.parent.exports;
|
||||
const Feps = module.exports;
|
||||
@@ -53,36 +52,3 @@ Feps.announce = async function announce(id, activity) {
|
||||
object: activity,
|
||||
});
|
||||
};
|
||||
|
||||
Feps.announceObject = async function announceObject(id) {
|
||||
let localId;
|
||||
if (String(id).startsWith(nconf.get('url'))) {
|
||||
({ id: localId } = await activitypub.helpers.resolveLocalId(id));
|
||||
}
|
||||
const cid = await posts.getCidByPid(localId || id);
|
||||
if (cid === -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
const followers = await activitypub.notes.getCategoryFollowers(cid);
|
||||
if (!followers.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
let author = await posts.getPostField(id, 'uid');
|
||||
if (utils.isNumber(author)) {
|
||||
author = `${nconf.get('url')}/uid/${author}`;
|
||||
} else if (!author.startsWith(nconf.get('url'))) {
|
||||
followers.unshift(author);
|
||||
}
|
||||
|
||||
activitypub.helpers.log(`[activitypub/inbox.announce(1b12)] Announcing object (${id}) to followers of cid ${cid}`);
|
||||
await activitypub.send('cid', cid, followers, {
|
||||
id: `${nconf.get('url')}/post/${encodeURIComponent(id)}#activity/announce/${Date.now()}`,
|
||||
type: 'Announce',
|
||||
actor: `${nconf.get('url')}/category/${cid}`,
|
||||
to: [`${nconf.get('url')}/category/${cid}/followers`],
|
||||
cc: [author, activitypub._constants.publicAddress],
|
||||
object: utils.isNumber(id) ? `${nconf.get('url')}/post/${id}` : id,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -754,6 +754,38 @@ Mocks.notes.private = async ({ messageObj }) => {
|
||||
return object;
|
||||
};
|
||||
|
||||
Mocks.activities = {};
|
||||
|
||||
Mocks.activities.create = async (pid, uid, post) => {
|
||||
// Local objects only, post optional
|
||||
if (!utils.isNumber(pid)) {
|
||||
throw new Error('[[error:invalid-pid]]');
|
||||
}
|
||||
|
||||
if (!post) {
|
||||
post = (await posts.getPostSummaryByPids([pid], uid, { stripTags: false })).pop();
|
||||
if (!post) {
|
||||
throw new Error('[[error:invalid-pid]]');
|
||||
}
|
||||
}
|
||||
|
||||
const object = await activitypub.mocks.notes.public(post);
|
||||
const { to, cc, targets } = await activitypub.buildRecipients(object, { pid, uid: post.user.uid });
|
||||
object.to = to;
|
||||
object.cc = cc;
|
||||
|
||||
const activity = {
|
||||
id: `${object.id}#activity/create/${Date.now()}`,
|
||||
type: 'Create',
|
||||
actor: object.attributedTo,
|
||||
to,
|
||||
cc,
|
||||
object,
|
||||
};
|
||||
|
||||
return { activity, targets };
|
||||
};
|
||||
|
||||
Mocks.tombstone = async properties => ({
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
type: 'Tombstone',
|
||||
|
||||
@@ -124,23 +124,11 @@ activitypubApi.create.note = enabledCheck(async (caller, { pid, post }) => {
|
||||
return;
|
||||
}
|
||||
|
||||
const object = await activitypub.mocks.notes.public(post);
|
||||
const { to, cc, targets } = await activitypub.buildRecipients(object, { pid, uid: post.user.uid });
|
||||
object.to = to;
|
||||
object.cc = cc;
|
||||
|
||||
const payload = {
|
||||
id: `${object.id}#activity/create/${Date.now()}`,
|
||||
type: 'Create',
|
||||
actor: object.attributedTo,
|
||||
to,
|
||||
cc,
|
||||
object,
|
||||
};
|
||||
const { payload: activity, targets } = await activitypub.mocks.activities.create(pid, caller.uid, post);
|
||||
|
||||
await Promise.all([
|
||||
activitypub.send('uid', caller.uid, Array.from(targets), payload),
|
||||
activitypub.feps.announce(pid, payload),
|
||||
activitypub.send('uid', caller.uid, Array.from(targets), activity),
|
||||
activitypub.feps.announce(pid, activity),
|
||||
activitypubApi.add(caller, { pid }),
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -342,7 +342,8 @@ topicsAPI.move = async (caller, { tid, cid }) => {
|
||||
if (!topicData.deleted) {
|
||||
socketHelpers.sendNotificationToTopicOwner(tid, caller.uid, 'move', 'notifications:moved-your-topic');
|
||||
activitypubApi.announce.note(caller, { tid });
|
||||
activitypub.feps.announceObject(topicData.mainPid);
|
||||
const { activity } = await activitypub.mocks.activities.create(topicData.mainPid, caller.uid);
|
||||
await activitypub.feps.announce(topicData.mainPid, activity);
|
||||
}
|
||||
|
||||
await events.log({
|
||||
|
||||
@@ -88,9 +88,11 @@ module.exports = function (Topics) {
|
||||
}),
|
||||
db.sortedSetsAdd(['topics:votes', `cid:${cid}:tids:votes`], mainPost.votes, tid),
|
||||
Topics.events.log(fromTid, { type: 'fork', uid, href: `/topic/${tid}` }),
|
||||
activitypub.feps.announceObject(pids[0]),
|
||||
]);
|
||||
|
||||
const { activity } = await activitypub.mocks.activities.create(pids[0], uid);
|
||||
await activitypub.feps.announce(pids[0], activity);
|
||||
|
||||
plugins.hooks.fire('action:topic.fork', { tid, fromTid, uid });
|
||||
|
||||
return await Topics.getTopicData(tid);
|
||||
|
||||
@@ -22,8 +22,8 @@ describe('FEPs', () => {
|
||||
await install.giveWorldPrivileges();
|
||||
});
|
||||
|
||||
describe.only('1b12', () => {
|
||||
describe('announceObject()', () => {
|
||||
describe('1b12', () => {
|
||||
describe('announce()', () => {
|
||||
let cid;
|
||||
let uid;
|
||||
let adminUid;
|
||||
@@ -49,7 +49,7 @@ describe('FEPs', () => {
|
||||
});
|
||||
|
||||
it('should be called when a topic is moved from uncategorized to another category', async () => {
|
||||
const { topicData } = await topics.post({
|
||||
const { topicData, postData } = await topics.post({
|
||||
uid,
|
||||
cid: -1,
|
||||
title: utils.generateUUID(),
|
||||
@@ -63,7 +63,13 @@ describe('FEPs', () => {
|
||||
cid,
|
||||
});
|
||||
|
||||
assert.strictEqual(activitypub._sent.size, 1);
|
||||
assert.strictEqual(activitypub._sent.size, 2);
|
||||
|
||||
const key = Array.from(activitypub._sent.keys())[0];
|
||||
const activity = activitypub._sent.get(key);
|
||||
|
||||
assert(activity && activity.object && typeof activity.object === 'object');
|
||||
assert.strictEqual(activity.object.id, `${nconf.get('url')}/post/${postData.pid}`);
|
||||
});
|
||||
|
||||
it('should be called for a newly forked topic', async () => {
|
||||
@@ -78,17 +84,47 @@ describe('FEPs', () => {
|
||||
topics.reply({ uid, tid, content: utils.generateUUID() }),
|
||||
topics.reply({ uid, tid, content: utils.generateUUID() }),
|
||||
]);
|
||||
const forked = await topics.createTopicFromPosts(
|
||||
await topics.createTopicFromPosts(
|
||||
adminUid, utils.generateUUID(), [reply1Pid, reply2Pid], tid, cid
|
||||
);
|
||||
|
||||
assert.strictEqual(activitypub._sent.size, 1);
|
||||
assert.strictEqual(activitypub._sent.size, 2);
|
||||
|
||||
const key = Array.from(activitypub._sent.keys())[0];
|
||||
const activity = activitypub._sent.get(key);
|
||||
|
||||
assert(activity);
|
||||
assert.strictEqual(activity.object, `${nconf.get('url')}/post/${reply1Pid}`);
|
||||
assert(activity && activity.object && typeof activity.object === 'object');
|
||||
assert.strictEqual(activity.object.id, `${nconf.get('url')}/post/${reply1Pid}`);
|
||||
});
|
||||
|
||||
// it('should be called when a post is moved to another topic', async () => {
|
||||
//
|
||||
// });
|
||||
});
|
||||
|
||||
describe('announceObject()', () => {
|
||||
let cid;
|
||||
let uid;
|
||||
let adminUid;
|
||||
|
||||
before(async () => {
|
||||
const name = utils.generateUUID();
|
||||
const description = utils.generateUUID();
|
||||
({ cid } = await categories.create({ name, description }));
|
||||
|
||||
adminUid = await user.create({ username: utils.generateUUID() });
|
||||
await groups.join('administrators', adminUid);
|
||||
uid = await user.create({ username: utils.generateUUID() });
|
||||
|
||||
const { id: followerId, actor } = helpers.mocks.actor();
|
||||
activitypub._cache.set(`0;${followerId}`, actor);
|
||||
user.setCategoryWatchState(followerId, [cid], categories.watchStates.tracking);
|
||||
|
||||
activitypub._sent.clear();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
activitypub._sent.clear();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user