Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor NodeBB/src/flags.js to reduce Cognitive Complexity from 16 to 15 #65

Open
wants to merge 6 commits into
base: f24
Choose a base branch
from
75 changes: 47 additions & 28 deletions src/flags.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,12 +135,34 @@ Flags.getCount = async function ({ uid, filters, query }) {
};

Flags.getFlagIdsWithFilters = async function ({ filters, uid, query }) {
let sets = [];
const orSets = [];
initializeFilters(filters);

const { sets, orSets } = buildSets(filters, uid);

let flagIds = await getFlagIdsFromSets(sets);

if (orSets.length) {
const _flagIds = await getFlagIdsFromOrSets(orSets);
flagIds = mergeFlagIds(flagIds, _flagIds, sets.length > 0);
}

const result = await plugins.hooks.fire('filter:flags.getFlagIdsWithFilters', {
filters,
uid,
query,
flagIds,
});
return result.flagIds;
};

// Default filter
function initializeFilters(filters) {
filters.page = filters.hasOwnProperty('page') ? Math.abs(parseInt(filters.page, 10) || 1) : 1;
filters.perPage = filters.hasOwnProperty('perPage') ? Math.abs(parseInt(filters.perPage, 10) || 20) : 20;
}

function buildSets(filters, uid) {
let sets = [];
const orSets = [];

for (const type of Object.keys(filters)) {
if (Flags._filters.hasOwnProperty(type)) {
Expand All @@ -149,39 +171,36 @@ Flags.getFlagIdsWithFilters = async function ({ filters, uid, query }) {
winston.warn(`[flags/list] No flag filter type found: ${type}`);
}
}
sets = (sets.length || orSets.length) ? sets : ['flags:datetime']; // No filter default

let flagIds = [];
if (!(sets.length || orSets.length)) {
sets = ['flags:datetime']; // No filter default
}

return { sets, orSets };
}

async function getFlagIdsFromSets(sets) {
if (sets.length === 1) {
flagIds = await db.getSortedSetRevRange(sets[0], 0, -1);
return await db.getSortedSetRevRange(sets[0], 0, -1);
} else if (sets.length > 1) {
flagIds = await db.getSortedSetRevIntersect({ sets: sets, start: 0, stop: -1, aggregate: 'MAX' });
return await db.getSortedSetRevIntersect({ sets: sets, start: 0, stop: -1, aggregate: 'MAX' });
}
return [];
}

if (orSets.length) {
let _flagIds = await Promise.all(orSets.map(async orSet => await db.getSortedSetRevUnion({ sets: orSet, start: 0, stop: -1, aggregate: 'MAX' })));

// Each individual orSet is ANDed together to construct the final list of flagIds
_flagIds = _.intersection(..._flagIds);
async function getFlagIdsFromOrSets(orSets) {
const _flagIds = await Promise.all(orSets.map(async orSet => db.getSortedSetRevUnion({ sets: orSet, start: 0, stop: -1, aggregate: 'MAX' })));
return _.intersection(..._flagIds);
}

// Merge with flagIds returned by sets
if (sets.length) {
// If flag ids are already present, return a subset of flags that are in both sets
flagIds = _.intersection(flagIds, _flagIds);
} else {
// Otherwise, return all flags returned via orSets
flagIds = _.union(flagIds, _flagIds);
}
function mergeFlagIds(flagIds, _flagIds, hasSets) {
if (hasSets) {
return _.intersection(flagIds, _flagIds);
}
return _.union(flagIds, _flagIds);
}


const result = await plugins.hooks.fire('filter:flags.getFlagIdsWithFilters', {
filters,
uid,
query,
flagIds,
});
return result.flagIds;
};

Flags.list = async function (data) {
const filters = data.filters || {};
Expand Down