refactor: crossposts.get to support multiple tids

This commit is contained in:
Barış Soner Uşaklı
2026-01-14 18:47:52 -05:00
parent be5b36bcd1
commit 57a73c4854
3 changed files with 35 additions and 25 deletions

View File

@@ -101,7 +101,7 @@ module.exports = function (Categories) {
tids, tids,
['tid', 'mainPid', 'slug', 'title', 'teaserPid', 'cid', 'postcount'] ['tid', 'mainPid', 'slug', 'title', 'teaserPid', 'cid', 'postcount']
), ),
Promise.all(tids.map(async tid => topics.crossposts.get(tid))), topics.crossposts.get(tids),
]); ]);
topicData.forEach((topic) => { topicData.forEach((topic) => {

View File

@@ -1,5 +1,6 @@
'use strict'; 'use strict';
const _ = require('lodash');
const db = require('../database'); const db = require('../database');
const topics = require('.'); const topics = require('.');
const user = require('../user'); const user = require('../user');
@@ -10,30 +11,39 @@ const utils = require('../utils');
const Crossposts = module.exports; const Crossposts = module.exports;
Crossposts.get = async function (tid) { Crossposts.get = async function (tids) {
const crosspostIds = await db.getSortedSetMembers(`tid:${tid}:crossposts`); const isArray = Array.isArray(tids);
let crossposts = await db.getObjects(crosspostIds.map(id => `crosspost:${id}`)); if (!isArray) {
const cids = crossposts.reduce((cids, crossposts) => { tids = [tids];
cids.add(crossposts.cid); }
return cids;
}, new Set()); const crosspostIds = await db.getSortedSetsMembers(tids.map(tid => `tid:${tid}:crossposts`));
let categoriesData = await categories.getCategoriesFields( const allCrosspostIds = crosspostIds.flat();
Array.from(cids), ['cid', 'name', 'icon', 'bgColor', 'color', 'slug'] const allCrossposts = await db.getObjects(allCrosspostIds.map(id => `crosspost:${id}`));
const categoriesData = await categories.getCategoriesFields(
_.uniq(allCrossposts.map(c => c.cid)), ['cid', 'name', 'icon', 'bgColor', 'color', 'slug']
); );
categoriesData = categoriesData.reduce((map, category) => {
const categoriesMap = categoriesData.reduce((map, category) => {
map.set(parseInt(category.cid, 10), category); map.set(parseInt(category.cid, 10), category);
return map; return map;
}, new Map()); }, new Map());
crossposts = crossposts.map((crosspost, idx) => {
crosspost.id = crosspostIds[idx];
crosspost.category = categoriesData.get(parseInt(crosspost.cid, 10));
crosspost.uid = utils.isNumber(crosspost.uid) ? parseInt(crosspost.uid) : crosspost.uid;
crosspost.cid = utils.isNumber(crosspost.cid) ? parseInt(crosspost.cid) : crosspost.cid;
return crosspost; const crosspostMap = allCrossposts.reduce((map, crosspost, index) => {
}); const id = allCrosspostIds[index];
if (id && crosspost) {
map.set(id, crosspost);
crosspost.id = id;
crosspost.category = categoriesMap.get(parseInt(crosspost.cid, 10));
crosspost.uid = utils.isNumber(crosspost.uid) ? parseInt(crosspost.uid, 10) : crosspost.uid;
crosspost.cid = utils.isNumber(crosspost.cid) ? parseInt(crosspost.cid, 10) : crosspost.cid;
}
return map;
}, new Map());
return crossposts; const crossposts = crosspostIds.map(ids => ids.map(id => crosspostMap.get(id)));
return isArray ? crossposts : crossposts[0];
}; };
Crossposts.add = async function (tid, cid, uid) { Crossposts.add = async function (tid, cid, uid) {

View File

@@ -159,9 +159,9 @@ describe('Crossposting (& related logic)', () => {
it('should not let another user uncrosspost', async () => { it('should not let another user uncrosspost', async () => {
const uid2 = await user.create({ username: utils.generateUUID().slice(0, 8) }); const uid2 = await user.create({ username: utils.generateUUID().slice(0, 8) });
assert.rejects( await assert.rejects(
topics.crossposts.remove(tid, cid2, uid2), topics.crossposts.remove(tid, cid2, uid2),
'[[error:invalid-data]]', { message: '[[error:invalid-data]]' },
); );
}); });
@@ -184,9 +184,9 @@ describe('Crossposting (& related logic)', () => {
}); });
it('should throw on uncrossposting if already uncrossposted', async () => { it('should throw on uncrossposting if already uncrossposted', async () => {
assert.rejects( await assert.rejects(
topics.crossposts.remove(tid, cid2, uid), topics.crossposts.remove(tid, cid2, uid),
'[[error:invalid-data]]', { message: '[[error:invalid-data]]' },
); );
}); });
}); });
@@ -286,9 +286,9 @@ describe('Crossposting (& related logic)', () => {
it('should fail to uncrosspost if not mod of passed-in category', async () => { it('should fail to uncrosspost if not mod of passed-in category', async () => {
await privileges.categories.give(['moderate'], cid1, [privUid]); await privileges.categories.give(['moderate'], cid1, [privUid]);
assert.rejects( await assert.rejects(
topics.crossposts.remove(tid, cid2, privUid), topics.crossposts.remove(tid, cid2, privUid),
'[[error:invalid-data]]', { message: '[[error:invalid-data]]' },
); );
}); });