mirror of
https://github.com/NodeBB/NodeBB.git
synced 2026-01-21 15:03:12 +01:00
feat: refactor out.announce.topic to allow user announces, refactor tests to accommodate
This commit is contained in:
@@ -305,12 +305,19 @@ Out.dislike.note = enabledCheck(async (uid, pid) => {
|
|||||||
|
|
||||||
Out.announce = {};
|
Out.announce = {};
|
||||||
|
|
||||||
Out.announce.topic = enabledCheck(async (tid) => {
|
Out.announce.topic = enabledCheck(async (tid, uid) => {
|
||||||
const { mainPid: pid, cid } = await topics.getTopicFields(tid, ['mainPid', 'cid']);
|
const { mainPid: pid, cid } = await topics.getTopicFields(tid, ['mainPid', 'cid']);
|
||||||
|
|
||||||
// Only local categories can announce
|
if (uid) {
|
||||||
if (!utils.isNumber(cid) || parseInt(cid, 10) < 1) {
|
const exists = await user.exists(uid);
|
||||||
return;
|
if (!exists || !utils.isNumber(cid)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Only local categories can announce
|
||||||
|
if (!utils.isNumber(cid) || parseInt(cid, 10) < 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const authorUid = await posts.getPostField(pid, 'uid'); // author
|
const authorUid = await posts.getPostField(pid, 'uid'); // author
|
||||||
@@ -323,16 +330,23 @@ Out.announce.topic = enabledCheck(async (tid) => {
|
|||||||
const { to, cc, targets } = await activitypub.buildRecipients({
|
const { to, cc, targets } = await activitypub.buildRecipients({
|
||||||
id: pid,
|
id: pid,
|
||||||
to: [activitypub._constants.publicAddress],
|
to: [activitypub._constants.publicAddress],
|
||||||
}, { cid });
|
}, uid ? { uid } : { cid });
|
||||||
if (!utils.isNumber(authorUid)) {
|
if (!utils.isNumber(authorUid)) {
|
||||||
cc.push(authorUid);
|
cc.push(authorUid);
|
||||||
targets.add(authorUid);
|
targets.add(authorUid);
|
||||||
}
|
}
|
||||||
|
|
||||||
await activitypub.send('cid', cid, Array.from(targets), {
|
const payload = uid ? {
|
||||||
|
id: `${nconf.get('url')}/post/${encodeURIComponent(pid)}#activity/announce/uid/${uid}`,
|
||||||
|
type: 'Announce',
|
||||||
|
actor: `${nconf.get('url')}/uid/${uid}`,
|
||||||
|
} : {
|
||||||
id: `${nconf.get('url')}/post/${encodeURIComponent(pid)}#activity/announce/cid/${cid}`,
|
id: `${nconf.get('url')}/post/${encodeURIComponent(pid)}#activity/announce/cid/${cid}`,
|
||||||
type: 'Announce',
|
type: 'Announce',
|
||||||
actor: `${nconf.get('url')}/category/${cid}`,
|
actor: `${nconf.get('url')}/category/${cid}`,
|
||||||
|
};
|
||||||
|
await activitypub.send(uid ? 'uid' : 'cid', uid || cid, Array.from(targets), {
|
||||||
|
...payload,
|
||||||
to,
|
to,
|
||||||
cc,
|
cc,
|
||||||
object: utils.isNumber(pid) ? `${nconf.get('url')}/post/${pid}` : pid,
|
object: utils.isNumber(pid) ? `${nconf.get('url')}/post/${pid}` : pid,
|
||||||
|
|||||||
@@ -22,84 +22,133 @@ describe('Outbound activities module', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('.announce', () => {
|
describe('.announce', () => {
|
||||||
describe('.topic() (remote topic; by cid)', () => {
|
function commonTests() {
|
||||||
let pid;
|
it('should not error when called', async function () {
|
||||||
let note;
|
await activitypub.out.announce.topic(this.tid, this.uid);
|
||||||
let tid;
|
const { payload, targets } = Array.from(activitypub._sent).pop()[1];
|
||||||
let cid;
|
this.payload = payload;
|
||||||
|
this.targets = targets;
|
||||||
|
});
|
||||||
|
|
||||||
before(async () => {
|
it('should send an Announce activity', function () {
|
||||||
({ id: pid, note } = helpers.mocks.note());
|
assert.strictEqual(activitypub._sent.size, 1);
|
||||||
({ cid } = await categories.create({ name: utils.generateUUID() }));
|
assert.strictEqual(this.payload.type, 'Announce');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should contain the main post\'s pid in object', function () {
|
||||||
|
assert.strictEqual(this.payload.object, this.pid);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have actor as the calling user or category as appropriate', function () {
|
||||||
|
if (this.uid) {
|
||||||
|
assert.strictEqual(this.payload.actor, `${nconf.get('url')}/uid/${this.uid}`);
|
||||||
|
} else {
|
||||||
|
assert.strictEqual(this.payload.actor, `${nconf.get('url')}/category/${this.cid}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('.topic() (remote topic; by cid)', () => {
|
||||||
|
before(async function () {
|
||||||
|
const { id: pid, note } = helpers.mocks.note();
|
||||||
|
const { cid } = await categories.create({ name: utils.generateUUID() });
|
||||||
await activitypub.notes.assert(0, pid, { skipChecks: 1, cid });
|
await activitypub.notes.assert(0, pid, { skipChecks: 1, cid });
|
||||||
tid = await posts.getPostField(pid, 'tid');
|
|
||||||
|
this.pid = pid;
|
||||||
|
this.note = note;
|
||||||
|
this.cid = cid;
|
||||||
|
this.tid = await posts.getPostField(pid, 'tid');
|
||||||
});
|
});
|
||||||
|
|
||||||
after(() => {
|
after(() => {
|
||||||
activitypub._sent.clear();
|
activitypub._sent.clear();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not error when called', async () => {
|
commonTests();
|
||||||
await activitypub.out.announce.topic(tid);
|
|
||||||
|
it('should include the category\'s followers collection in cc', function () {
|
||||||
|
assert(this.payload.cc.includes(`${nconf.get('url')}/category/${this.cid}/followers`));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should send an Announce activity', () => {
|
it('should include the author in cc', function () {
|
||||||
assert.strictEqual(activitypub._sent.size, 1);
|
assert(this.payload.cc.includes(this.note.attributedTo));
|
||||||
|
|
||||||
const { payload } = Array.from(activitypub._sent).pop()[1];
|
|
||||||
assert.strictEqual(payload.type, 'Announce');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should contain the main post\'s pid in object', () => {
|
it('should include the author in targets', function () {
|
||||||
const { payload } = Array.from(activitypub._sent).pop()[1];
|
assert(this.targets.includes(this.note.attributedTo));
|
||||||
assert.strictEqual(payload.object, pid);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should include the category\'s followers collection in cc', () => {
|
|
||||||
const { payload } = Array.from(activitypub._sent).pop()[1];
|
|
||||||
assert(payload.cc.includes(`${nconf.get('url')}/category/${cid}/followers`));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should include the author in cc', () => {
|
|
||||||
const { payload } = Array.from(activitypub._sent).pop()[1];
|
|
||||||
assert(payload.cc.includes(note.attributedTo));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should include the author in targets', () => {
|
|
||||||
const { targets } = Array.from(activitypub._sent).pop()[1];
|
|
||||||
assert(targets.includes(note.attributedTo));
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('.topic() (local topic; by cid)', () => {
|
describe('.topic() (local topic; by cid)', () => {
|
||||||
let uid;
|
before(async function () {
|
||||||
let tid;
|
const uid = await user.create({ username: utils.generateUUID().slice(0, 10) });
|
||||||
let cid;
|
const { cid } = await categories.create({ name: utils.generateUUID() });
|
||||||
|
const { postData, topicData } = await topics.post({
|
||||||
before(async () => {
|
|
||||||
uid = await user.create({ username: utils.generateUUID().slice(0, 10) });
|
|
||||||
({ cid } = await categories.create({ name: utils.generateUUID() }));
|
|
||||||
const { topicData } = await topics.post({
|
|
||||||
cid, uid,
|
cid, uid,
|
||||||
title: utils.generateUUID(),
|
title: utils.generateUUID(),
|
||||||
content: utils.generateUUID(),
|
content: utils.generateUUID(),
|
||||||
});
|
});
|
||||||
({ tid } = topicData);
|
|
||||||
|
this.tid = topicData.tid;
|
||||||
|
this.cid = cid;
|
||||||
|
this.pid = `${nconf.get('url')}/post/${topicData.mainPid}`;
|
||||||
|
this.note = await activitypub.mocks.notes.public(postData);
|
||||||
});
|
});
|
||||||
|
|
||||||
after(() => {
|
after(() => {
|
||||||
activitypub._sent.clear();
|
activitypub._sent.clear();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not error when called', async () => {
|
commonTests();
|
||||||
await activitypub.out.announce.topic(tid);
|
|
||||||
|
it('should include the topic\'s mainPid in object', async function () {
|
||||||
|
const mainPid = await topics.getTopicField(this.tid, 'mainPid');
|
||||||
|
assert.strictEqual(this.payload.object, `${nconf.get('url')}/post/${mainPid}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('.topic() (remote topic; by uid)', () => {
|
||||||
|
before(async function () {
|
||||||
|
const uid = await user.create({ username: utils.generateUUID().slice(0, 10) });
|
||||||
|
const { id: pid, note } = helpers.mocks.note();
|
||||||
|
|
||||||
|
await activitypub.notes.assert(0, pid, { skipChecks: 1 });
|
||||||
|
|
||||||
|
this.pid = pid;
|
||||||
|
this.note = note;
|
||||||
|
this.tid = await posts.getPostField(pid, 'tid');
|
||||||
|
this.uid = uid;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should include the topic\'s mainPid in object', async () => {
|
after(() => {
|
||||||
const mainPid = await topics.getTopicField(tid, 'mainPid');
|
activitypub._sent.clear();
|
||||||
const { payload } = Array.from(activitypub._sent).pop()[1];
|
|
||||||
assert.strictEqual(payload.object, `${nconf.get('url')}/post/${mainPid}`);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
commonTests();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('.topic() (local topic; by uid)', () => {
|
||||||
|
before(async function () {
|
||||||
|
const uid = await user.create({ username: utils.generateUUID().slice(0, 10) });
|
||||||
|
const { cid } = await categories.create({ name: utils.generateUUID() });
|
||||||
|
const { postData, topicData } = await topics.post({
|
||||||
|
cid, uid,
|
||||||
|
title: utils.generateUUID(),
|
||||||
|
content: utils.generateUUID(),
|
||||||
|
});
|
||||||
|
|
||||||
|
this.tid = topicData.tid;
|
||||||
|
this.cid = cid;
|
||||||
|
this.pid = `${nconf.get('url')}/post/${topicData.mainPid}`;
|
||||||
|
this.note = await activitypub.mocks.notes.public(postData);
|
||||||
|
this.uid = uid;
|
||||||
|
});
|
||||||
|
|
||||||
|
after(() => {
|
||||||
|
activitypub._sent.clear();
|
||||||
|
});
|
||||||
|
|
||||||
|
commonTests();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
Reference in New Issue
Block a user