structure and test revamp for memberHelper

This commit is contained in:
Aster Fialla
2026-02-23 00:18:14 -05:00
parent 72ec047f48
commit d9530a2ccf
3 changed files with 321 additions and 120 deletions

View File

@@ -12,8 +12,7 @@ cmds.set('member', {
const authorFull = `${message.author.username}#${message.author.discriminator}` const authorFull = `${message.author.username}#${message.author.discriminator}`
const attachmentUrl = message.attachments.size > 0 ? message.attachments.first().url : null; const attachmentUrl = message.attachments.size > 0 ? message.attachments.first().url : null;
const attachmentExpires = message.attachments.size > 0 ? message.attachments.first().expires_at : null; const attachmentExpires = message.attachments.size > 0 ? message.attachments.first().expires_at : null;
if (attachmentUrl) args.push(null, attachmentUrl, attachmentExpires); const reply = await memberHelper.parseMemberCommand(message.author.id, authorFull, args, attachmentUrl, attachmentExpires).catch(async (e) =>{await message.reply(e.message);});
const reply = await memberHelper.parseMemberCommand(message.author.id, authorFull, args).catch(async (e) =>{await message.reply(e.message);});
if (typeof reply === 'string') { if (typeof reply === 'string') {
return await message.reply(reply); return await message.reply(reply);
} }

View File

@@ -6,7 +6,7 @@ import {utils} from "./utils.js";
const mh = {}; const mh = {};
const commandList = ['new', 'remove', 'name', 'list', 'displayName', 'proxy', 'propic']; const commandList = ['new', 'remove', 'name', 'list', 'displayname', 'proxy', 'propic'];
const newAndRemoveCommands = ['new', 'remove']; const newAndRemoveCommands = ['new', 'remove'];
/** /**
@@ -16,24 +16,29 @@ const newAndRemoveCommands = ['new', 'remove'];
* @param {string} authorId - The id of the message author * @param {string} authorId - The id of the message author
* @param {string} authorFull - The username and discriminator of the message author * @param {string} authorFull - The username and discriminator of the message author
* @param {string[]} args - The message arguments * @param {string[]} args - The message arguments
* @param {string | null} attachmentUrl - The attachment URL, if any
* @param {string | null} attachmentExpiration - The attachment expiry date, if any
* @returns {Promise<string>} A success message. * @returns {Promise<string>} A success message.
* @returns {Promise <EmbedBuilder>} A list of 25 members as an embed. * @returns {Promise <EmbedBuilder>} A list of 25 members as an embed.
* @returns {Promise <EmbedBuilder>} A list of member commands and descriptions. * @returns {Promise <EmbedBuilder>} A list of member commands and descriptions.
* @returns {Promise<{EmbedBuilder, [string], string}>} A member info embed + info/errors. * @returns {Promise<{EmbedBuilder, [string], string}>} A member info embed + info/errors.
* @throws {Error} * @throws {Error}
*/ */
mh.parseMemberCommand = async function (authorId, authorFull, args) { mh.parseMemberCommand = async function (authorId, authorFull, args, attachmentUrl = null, attachmentExpiration = null) {
let memberName, command, isHelp = false; let memberName, command, isHelp = false;
// checks whether command is in list, otherwise assumes it's a name // checks whether command is in list, otherwise assumes it's a name
// ex: pf;member remove, pf;member remove --help
// ex: pf;member, pf;member --help // ex: pf;member, pf;member --help
if (args.length === 0 || args[0] === '--help' || args[0] === '') { if (args.length === 0 || args[0] === '--help' || args[0] === '') {
return mh.getMemberCommandInfo(); return mh.getMemberCommandInfo();
} }
// ex: pf;member remove somePerson // ex: pf;member remove somePerson
if (commandList.includes(args[0]) && args[1]) { if (commandList.includes(args[0])) {
command = args[0]; command = args[0];
memberName = args[1]; if (args[1]) {
memberName = args[1];
}
} }
// ex: pf;member somePerson propic // ex: pf;member somePerson propic
else if (args[1] && commandList.includes(args[1])) { else if (args[1] && commandList.includes(args[1])) {
@@ -44,42 +49,40 @@ mh.parseMemberCommand = async function (authorId, authorFull, args) {
else if (!commandList.includes(args[0]) && !args[1]) { else if (!commandList.includes(args[0]) && !args[1]) {
memberName = args[0]; memberName = args[0];
} }
// ex: pf;member remove, pf;member remove --help if (args[1] === "--help" || command && (memberName === "--help" || !memberName && command !== 'list')) {
if (command && (!memberName || args.includes("--help"))) {
isHelp = true; isHelp = true;
} }
return await mh.memberArgumentHandler(authorId, authorFull, isHelp, command, memberName, args) return await mh.memberArgumentHandler(authorId, authorFull, isHelp, command, memberName, args, attachmentUrl, attachmentExpiration)
} }
mh.memberArgumentHandler = async function(authorId, authorFull, isHelp, command = null, memberName = null,args = null) { mh.memberArgumentHandler = async function(authorId, authorFull, isHelp, command = null, memberName = null, args = [], attachmentUrl = null, attachmentExpiration = null) {
if (!command && !memberName && !isHelp) { if (!command && !memberName && !isHelp) {
throw new Error(enums.err.COMMAND_NOT_RECOGNIZED); throw new Error(enums.err.COMMAND_NOT_RECOGNIZED);
} }
// ex: pf;member blah blah else if (isHelp) {
if (!memberName && !isHelp) { return mh.sendHelpEnum(command);
throw new Error(enums.err.NO_MEMBER);
}
// remove memberName and command from values to reduce confusion
console.log(command, memberName, isHelp, args);
let values = args.slice(2);
console.log(values);
if (isHelp) {
mh.sendHelpEnum(command);
} }
else if (command === "list") { else if (command === "list") {
return await mh.getAllMembersInfo(authorId, authorFull); return await mh.getAllMembersInfo(authorId, authorFull);
} }
else if (command && memberName && values || newAndRemoveCommands.includes(command) && memberName) { else if (!memberName && !isHelp) {
return await mh.memberCommandHandler(authorId, command, memberName, values); throw new Error(enums.err.NO_MEMBER);
} }
else if (command && memberName) {
return await mh.sendCurrentValue(authorId, memberName, command); // remove memberName and command from values to reduce confusion
const values = args.slice(2);
// ex: pf;member blah blah
if (command && (memberName && values.length > 0 || newAndRemoveCommands.includes(command) && memberName)) {
return await mh.memberCommandHandler(authorId, command, memberName, values, attachmentUrl, attachmentExpiration).catch((e) => {throw e});
}
else if (memberName && values.length === 0) {
return await mh.sendCurrentValue(authorId, memberName, command).catch((e) => {throw e});
} }
} }
mh.sendCurrentValue = async function(authorId, memberName, command) { mh.sendCurrentValue = async function(authorId, memberName, command = null) {
const member = await mh.getMemberByName(authorId, memberName).then((m) => { const member = await mh.getMemberByName(authorId, memberName).then((m) => {
if (!m) throw new Error(enums.err.NO_MEMBER); if (!m) throw new Error(enums.err.NO_MEMBER);
return m; return m;
@@ -93,11 +96,11 @@ mh.sendCurrentValue = async function(authorId, memberName, command) {
case 'name': case 'name':
return `The name of ${member.name} is \"${member.name}\" but you probably already knew that!`; return `The name of ${member.name} is \"${member.name}\" but you probably already knew that!`;
case 'displayname': case 'displayname':
return `The display name for ${member.name} is \"${member.displayname}\".`; return member.displayname ? `The display name for ${member.name} is \"${member.displayname}\".` : `Display name ${enums.err.NO_VALUE}`;
case 'proxy': case 'proxy':
return `The proxy for ${member.name} is \"${member.proxy}\".`; return member.proxy ? `The proxy for ${member.name} is \"${member.proxy}\".` : `Proxy ${enums.err.NO_VALUE}`;
case 'propic': case 'propic':
return `The profile picture for ${member.name} is \"${member.propic}\".`; return member.propic ? `The profile picture for ${member.name} is \"${member.propic}\".` : `Propic ${enums.err.NO_VALUE}`;
} }
} }
@@ -121,10 +124,10 @@ mh.sendHelpEnum = function(command) {
} }
mh.memberCommandHandler = async function(authorId, command, memberName, values) { mh.memberCommandHandler = async function(authorId, command, memberName, values,attachmentUrl = null, attachmentExpiration = null) {
switch (command) { switch (command) {
case 'new': case 'new':
return await mh.addNewMember(authorId, memberName, values).catch((e) => {throw e}); return await mh.addNewMember(authorId, memberName, values, attachmentUrl, attachmentExpiration).catch((e) => {throw e});
case 'remove': case 'remove':
return await mh.removeMember(authorId, memberName).catch((e) => {throw e}); return await mh.removeMember(authorId, memberName).catch((e) => {throw e});
case 'name': case 'name':
@@ -134,7 +137,7 @@ mh.memberCommandHandler = async function(authorId, command, memberName, values)
case 'proxy': case 'proxy':
return await mh.updateProxy(authorId, memberName, values[0]).catch((e) => {throw e}); return await mh.updateProxy(authorId, memberName, values[0]).catch((e) => {throw e});
case 'propic': case 'propic':
return await mh.updatePropic(authorId, memberName, values).catch((e) => {throw e}); return await mh.updatePropic(authorId, memberName, values[0], attachmentUrl, attachmentExpiration).catch((e) => {throw e});
} }
} }
@@ -145,16 +148,17 @@ mh.memberCommandHandler = async function(authorId, command, memberName, values)
* @param {string} authorId - The author of the message * @param {string} authorId - The author of the message
* @param {string} memberName - The member name * @param {string} memberName - The member name
* @param {string[]} values - The arguments following the member name and command * @param {string[]} values - The arguments following the member name and command
* @returns {Promise<string>} A successful addition. * @param {string | null} attachmentUrl - The attachment URL, if any
* @param {string | null} attachmentExpiration - The attachment expiry date, if any
* @returns {Promise<{EmbedBuilder, [string], string}>} A successful addition.
* @throws {Error} When the member exists, or creating a member doesn't work. * @throws {Error} When the member exists, or creating a member doesn't work.
*/ */
mh.addNewMember = async function (authorId, memberName, values) { mh.addNewMember = async function (authorId, memberName, values, attachmentUrl = null, attachmentExpiration = null) {
const displayName = values[2]; const displayName = values[0];
const proxy = values[3]; const proxy = values[1];
const propic = values[4] ?? values[5]; const propic = values[2] ?? attachmentUrl;
return await mh.addFullMember(authorId, memberName, displayName, proxy, propic, attachmentExpiration).then((response) => {
return await mh.addFullMember(authorId, memberName, displayName, proxy, propic).then(async(response) => {
const memberInfoEmbed = mh.getMemberInfo(response.member); const memberInfoEmbed = mh.getMemberInfo(response.member);
return {embed: memberInfoEmbed, errors: response.errors, success: `${memberName} has been added successfully.`}; return {embed: memberInfoEmbed, errors: response.errors, success: `${memberName} has been added successfully.`};
}).catch(e => { }).catch(e => {
@@ -234,13 +238,12 @@ mh.updateProxy = async function (authorId, memberName, proxy) {
* @returns {Promise<string>} A successful update. * @returns {Promise<string>} A successful update.
* @throws {Error} When loading the profile picture from a URL doesn't work. * @throws {Error} When loading the profile picture from a URL doesn't work.
*/ */
mh.updatePropic = async function (authorId, memberName, values) { mh.updatePropic = async function (authorId, memberName, values, attachmentUrl = null, attachmentExpiration = null) {
const imgUrl = values[0] ?? values[1]; const imgUrl = values ?? attachmentUrl;
const attachmentExpiry = values[1] ? values[2] : null;
// Throws error if invalid // Throws error if invalid
await utils.checkImageFormatValidity(attachmentUrl ?? imgUrl).catch((e) => { throw e }); await utils.checkImageFormatValidity(imgUrl).catch((e) => { throw e });
return await mh.updateMemberField(authorId, memberName, "propic", imgUrl, attachmentExpiry).catch((e) => { throw e }); return await mh.updateMemberField(authorId, memberName, "propic", imgUrl, attachmentExpiration).catch((e) => { throw e });
} }
/** /**
@@ -277,10 +280,11 @@ mh.removeMember = async function (authorId, memberName) {
* @param {string | null} displayName - The display name of the member. * @param {string | null} displayName - The display name of the member.
* @param {string | null} proxy - The proxy tag of the member. * @param {string | null} proxy - The proxy tag of the member.
* @param {string | null} propic - The profile picture URL of the member. * @param {string | null} propic - The profile picture URL of the member.
* @param {string | null} attachmentExpiration - The profile picture URL of the member.
* @returns {Promise<{model, string[]}>} A successful addition object, including errors if there are any. * @returns {Promise<{model, string[]}>} A successful addition object, including errors if there are any.
* @throws {Error} When the member already exists, there are validation errors, or adding a member doesn't work. * @throws {Error} When the member already exists, there are validation errors, or adding a member doesn't work.
*/ */
mh.addFullMember = async function (authorId, memberName, displayName = null, proxy = null, propic = null) { mh.addFullMember = async function (authorId, memberName, displayName = null, proxy = null, propic = null, attachmentExpiration = null) {
await mh.getMemberByName(authorId, memberName).then((member) => { await mh.getMemberByName(authorId, memberName).then((member) => {
if (member) { if (member) {
throw new Error(`Can't add ${memberName}. ${enums.err.MEMBER_EXISTS}`); throw new Error(`Can't add ${memberName}. ${enums.err.MEMBER_EXISTS}`);
@@ -329,6 +333,9 @@ mh.addFullMember = async function (authorId, memberName, displayName = null, pro
isValidPropic = false; isValidPropic = false;
}); });
} }
if (isValidPropic && attachmentExpiration) {
errors.push(mh.setExpirationWarning(attachmentExpiration));
}
const member = await database.members.create({ const member = await database.members.create({
name: memberName, userid: authorId, displayname: isValidDisplayName ? displayName : null, proxy: isValidProxy ? proxy : null, propic: isValidPropic ? propic : null name: memberName, userid: authorId, displayname: isValidDisplayName ? displayName : null, proxy: isValidProxy ? proxy : null, propic: isValidPropic ? propic : null
}); });

View File

@@ -34,7 +34,7 @@ describe('MemberHelper', () => {
const authorId = "0001"; const authorId = "0001";
const authorFull = "author#0001"; const authorFull = "author#0001";
const attachmentUrl = "../oya.png"; const attachmentUrl = "../oya.png";
const attachmentExpiry = new Date('2026-01-01T00.00.00.0000Z') const attachmentExpiration = new Date('2026-01-01').toDateString();
const mockMember = { const mockMember = {
name: "somePerson", name: "somePerson",
displayname: "Some Person", displayname: "Some Person",
@@ -50,15 +50,6 @@ describe('MemberHelper', () => {
describe('parseMemberCommand', () => { describe('parseMemberCommand', () => {
beforeEach(() => { beforeEach(() => {
// jest.spyOn(memberHelper, 'getMemberByName').mockResolvedValue(mockMember);
// jest.spyOn(memberHelper, 'getMemberInfo').mockResolvedValue("member info");
// jest.spyOn(memberHelper, 'addNewMember').mockResolvedValue("new member");
// jest.spyOn(memberHelper, 'removeMember').mockResolvedValue("remove member");
// jest.spyOn(memberHelper, 'getAllMembersInfo').mockResolvedValue("all member info");
// jest.spyOn(memberHelper, 'updateName').mockResolvedValue("update name");
// jest.spyOn(memberHelper, 'updateDisplayName').mockResolvedValue("update display name");
// jest.spyOn(memberHelper, 'updateProxy').mockResolvedValue("update proxy");
// jest.spyOn(memberHelper, 'updatePropic').mockResolvedValue("update propic");
jest.spyOn(memberHelper, 'getMemberCommandInfo').mockResolvedValue("member command info"); jest.spyOn(memberHelper, 'getMemberCommandInfo').mockResolvedValue("member command info");
jest.spyOn(memberHelper, 'memberArgumentHandler').mockResolvedValue("handled argument"); jest.spyOn(memberHelper, 'memberArgumentHandler').mockResolvedValue("handled argument");
jest.spyOn(memberHelper, 'memberCommandHandler').mockResolvedValue("called command"); jest.spyOn(memberHelper, 'memberCommandHandler').mockResolvedValue("called command");
@@ -114,59 +105,263 @@ describe('MemberHelper', () => {
}); });
test.each([ test.each([
[[mockMember.name, '--help'], null, true], [[[mockMember.name, '--help'], null, null], undefined, true, undefined],
[['new', '--help'], 'new', true], [[['new', '--help'], null, null], 'new', true, '--help'],
[['remove', '--help'], 'remove', true], [[['remove', '--help'], null, null], 'remove', true, '--help'],
[['name', '--help'], 'name', true], [[['name', '--help'], null, null], 'name', true, '--help'],
[['list', '--help'], 'list', true], [[['list', '--help'], null, null], 'list', true, '--help'],
[['displayname', '--help'], 'displayname', true], [[['name', '--help'], null, null], 'name', true, '--help'],
[['proxy', '--help'], 'proxy', true], [[['displayname', '--help'], null, null], 'displayname', true, '--help'],
[['propic', '--help'], 'propic', true], [[['proxy', '--help'], null, null], 'proxy', true, '--help'],
[['new'], 'new', true], [[['propic', '--help'], null, null], 'propic', true, '--help'],
[['remove'], 'remove', true], [[['new'], null, null], 'new', true, undefined],
[['name'], 'name', true], [[['remove'], null, null], 'remove', true, undefined],
[['list'], 'list', true], [[['name'], null, null], 'name', true, undefined],
[['displayname'], 'displayname', true], [[['list'], null, null], 'list', false, undefined],
[['proxy'], 'proxy', true], [[['displayname'], null, null], 'displayname', true, undefined],
[['propic'], 'propic', true], [[['proxy'], null, null], 'proxy', true, undefined],
[[mockMember.name, 'remove'], 'remove', false], [[['propic'], null, null], 'propic', true, undefined],
[[mockMember.name, 'remove', 'test'], 'remove', false], [[[mockMember.name, 'remove'], null, null], 'remove', false, mockMember.name],
[[mockMember.name, 'new'], 'new', false], [[[mockMember.name, 'remove', 'test'], null, null], 'remove', false, mockMember.name],
[[mockMember.name, 'new', 'test'], 'new', false], [[[mockMember.name, 'new'], null, null], 'new', false, mockMember.name],
[[mockMember.name, 'new', mockMember.displayname], 'new', false], [[[mockMember.name, 'new', mockMember.displayname], null, null], 'new', false, mockMember.name],
[[mockMember.name, 'new', mockMember.proxy], 'new', false], [[[mockMember.name, 'new', mockMember.displayname, mockMember.proxy], null, null], 'new', false, mockMember.name],
[[mockMember.name, 'new', mockMember.propic], 'new', false], [[[mockMember.name, 'new', mockMember.displayname, mockMember.proxy,mockMember.propic], null, null], 'new', false, mockMember.name],
[[mockMember.name, 'new', null, mockMember.propic], 'new', false], [[[mockMember.name, 'new',mockMember.displayname, mockMember.proxy, null], mockMember.propic, null], 'new', false, mockMember.name],
[[mockMember.name, 'new', null, mockMember.propic, attachmentExpiry], 'new', false], [[[mockMember.name, 'new', mockMember.displayname, mockMember.proxy, null], mockMember.propic, attachmentExpiration], 'new', false, mockMember.name],
[[mockMember.name, 'name', mockMember.name], 'name', false], [[[mockMember.name, 'name', mockMember.name], null, null], 'name', false, mockMember.name],
[[mockMember.name, 'displayname', mockMember.displayname], 'displayname', false], [[[mockMember.name, 'new', '', mockMember.proxy], null, null], 'new', false, mockMember.name],
[[mockMember.name, 'proxy', mockMember.proxy], 'proxy', false], [[[mockMember.name, 'new', '', '', mockMember.propic], null, null], 'new', false, mockMember.name],
[[mockMember.name, 'propic', mockMember.propic], 'propic', false], [[[mockMember.name, 'new', '', '', null], mockMember.propic, null], 'new', false, mockMember.name],
[[mockMember.name, 'propic', null, mockMember.propic], 'propic', false], [[[mockMember.name, 'new', '', '', null], mockMember.propic, attachmentExpiration], 'new', false, mockMember.name],
[[mockMember.name, 'propic', null, mockMember.propic, attachmentExpiry], 'propic', false], //
[['remove', mockMember.name], 'remove'], [[[mockMember.name, 'displayname', mockMember.displayname], null, null], 'displayname', false, mockMember.name],
[['remove', mockMember.name, 'test'], 'remove'], [[[mockMember.name, 'proxy', mockMember.proxy], null, null], 'proxy', false, mockMember.name],
[['new', mockMember.name], 'new'], [[[mockMember.name, 'propic', mockMember.propic], null, null], 'propic', false, mockMember.name],
[['new', mockMember.name, mockMember.displayname], 'new'], [[[mockMember.name, 'propic', null], mockMember.propic, null], 'propic', false, mockMember.name],
[['new', mockMember.name, mockMember.displayname, mockMember.proxy], 'new'], [[[mockMember.name, 'propic', null], mockMember.propic, attachmentExpiration], 'propic', false, mockMember.name],
[['new', mockMember.name, mockMember.displayname, mockMember.proxy, mockMember.propic], 'new'], [[['remove', mockMember.name], null, null], 'remove', false, mockMember.name],
[['new', mockMember.name, null, mockMember.displayname, mockMember.proxy, mockMember.propic, attachmentExpiry], 'new'], [[['remove', mockMember.name, 'test'], null, null], 'remove', false, mockMember.name],
[['new', mockMember.name, null, mockMember.displayname, mockMember.proxy, mockMember.propic, attachmentExpiry], 'new'], [[['new', mockMember.name], null, null], 'new', false, mockMember.name],
[['name', mockMember.name, mockMember.name], 'name'], [[['new', mockMember.name, mockMember.displayname], null, null], 'new', false, mockMember.name],
[['displayname', mockMember.name, mockMember.name, mockMember.displayname], 'displayname'], [[['new', mockMember.name, mockMember.displayname, mockMember.proxy], null, null], 'new', false, mockMember.name],
[['proxy', mockMember.name, mockMember.name, mockMember.displayname, mockMember.proxy], 'proxy'], [[['new', mockMember.name, mockMember.displayname, mockMember.proxy, mockMember.propic], null, null], 'new', false, mockMember.name],
[['propic', mockMember.name, mockMember.name, mockMember.displayname, mockMember.proxy, mockMember.propic], 'propic'], [[['new', mockMember.name, undefined, mockMember.displayname, mockMember.proxy, undefined], mockMember.propic, null], 'new', false, mockMember.name],
[['propic', mockMember.name, null, mockMember.name, mockMember.displayname, mockMember.proxy, mockMember.propic, attachmentExpiry], 'propic'], [[['new', mockMember.name, undefined, mockMember.displayname, mockMember.proxy, undefined], mockMember.propic, attachmentExpiration], 'new', false, mockMember.name],
[['propic', mockMember.name, null, mockMember.name, mockMember.displayname, mockMember.proxy, mockMember.propic, attachmentExpiry], 'propic'], [[['new',mockMember.name, '', mockMember.proxy], null, null], 'new', false, mockMember.name],
])('%s calls memberCommandHandler with correct values', async (args, command, isHelp) => { [[['new', mockMember.name, '', '', mockMember.propic], null, null], 'new', false, mockMember.name],
[[['new', mockMember.name, '', '', null], mockMember.propic, null], 'new', false, mockMember.name],
[[['new', mockMember.name, '', '', null], mockMember.propic, attachmentExpiration], 'new', false, mockMember.name],
//
[[['name', mockMember.name, mockMember.name], null, null], 'name', false, mockMember.name],
[[['displayname', mockMember.name, mockMember.name, mockMember.displayname], null, null], 'displayname', false, mockMember.name],
[[['proxy', mockMember.name, mockMember.name, mockMember.displayname, mockMember.proxy], null, null], 'proxy', false, mockMember.name],
[[['propic', mockMember.name, mockMember.name, mockMember.displayname, mockMember.proxy, mockMember.propic], null, null], 'propic', false, mockMember.name],
[[['propic', mockMember.name, undefined, mockMember.name, mockMember.displayname, mockMember.proxy, undefined], mockMember.propic, null], 'propic', false, mockMember.name],
[[['propic', mockMember.name, undefined, mockMember.name, mockMember.displayname, mockMember.proxy, undefined], mockMember.propic, attachmentExpiration], 'propic', false, mockMember.name]
])('calls memberCommandHandler with correct values', (args, command, isHelp, memberName) => {
console.log(args, command, isHelp)
// Act // Act
return memberHelper.parseMemberCommand(authorId, authorFull, args).then((result, command) => { return memberHelper.parseMemberCommand(authorId, authorFull, args[0], args[1], args[2]).then((result) => {
// Assert // Assert
expect(result).toEqual("handled argument"); expect(result).toEqual("handled argument");
expect(memberHelper.memberArgumentHandler).toHaveBeenCalledTimes(1); expect(memberHelper.memberArgumentHandler).toHaveBeenCalledTimes(1);
expect(memberHelper.memberArgumentHandler).toHaveBeenCalledWith(authorId, authorFull, isHelp, command, mockMember.name, args.slice(2)); expect(memberHelper.memberArgumentHandler).toHaveBeenCalledWith(authorId, authorFull, isHelp, command, memberName, args[0], args[1], args[2]);
}); });
}) })
});
describe('memberArgumentHandler', () => {
beforeEach(() => {
jest.spyOn(memberHelper, 'memberCommandHandler').mockResolvedValue("handled command");
jest.spyOn(memberHelper, 'getAllMembersInfo').mockResolvedValue("all member info");
jest.spyOn(memberHelper, 'sendCurrentValue').mockResolvedValue("current value");
jest.spyOn(memberHelper, 'sendHelpEnum').mockReturnValue("help enum");
})
test('when all values are null should return command not recognized enum', () => {
// Arrange
return memberHelper.memberArgumentHandler(authorId, authorFull, false, null, null, []).catch((result) => {
// Assert
expect(result).toEqual(new Error(enums.err.COMMAND_NOT_RECOGNIZED));
});
})
test.each([
['new'],
['remove'],
['name'],
['displayname'],
['proxy'],
['propic'],
])('when %s is present but other values are null, should return no member enum', (command) => {
// Arrange
return memberHelper.memberArgumentHandler(authorId, authorFull, false, command, null, []).catch((result) => {
// Assert
expect(result).toEqual(new Error(enums.err.NO_MEMBER));
});
})
test.each([
['new'],
['remove'],
['name'],
['list'],
['displayname'],
['proxy'],
['propic'],
])('%s calls sendHelpEnum', (command) => {
// Arrange
return memberHelper.memberArgumentHandler(authorId, authorFull, true, command, mockMember.name, []).then((result) => {
// Assert
expect(result).toEqual("help enum");
expect(memberHelper.sendHelpEnum).toHaveBeenCalledTimes(1);
expect(memberHelper.sendHelpEnum).toHaveBeenCalledWith(command);
});
})
test('list should call getAllMembersInfo', () => {
// Arrange
return memberHelper.memberArgumentHandler(authorId, authorFull, false, 'list', mockMember.name, []).then((result) => {
// Assert
expect(result).toEqual("all member info");
expect(memberHelper.getAllMembersInfo).toHaveBeenCalledTimes(1);
expect(memberHelper.getAllMembersInfo).toHaveBeenCalledWith(authorId, authorFull);
});
})
test.each([
[[[mockMember.name, 'remove'], null, null], 'remove', false, mockMember.name],
[[[mockMember.name, 'remove', 'test'], null, null], 'remove', false, mockMember.name],
[[[mockMember.name, 'new'], null, null], 'new', false, mockMember.name],
[[[mockMember.name, 'new', mockMember.displayname], null, null], 'new', false, mockMember.name],
[[[mockMember.name, 'new', mockMember.displayname, mockMember.proxy], null, null], 'new', false, mockMember.name],
[[[mockMember.name, 'new', mockMember.displayname, mockMember.proxy,mockMember.propic], null, null], 'new', false, mockMember.name],
[[[mockMember.name, 'new',mockMember.displayname, mockMember.proxy, null], mockMember.propic, null], 'new', false, mockMember.name],
[[[mockMember.name, 'new', mockMember.displayname, mockMember.proxy, null], mockMember.propic, attachmentExpiration], 'new', false, mockMember.name],
[[[mockMember.name, 'name', mockMember.name], null, null], 'name', false, mockMember.name],
[[[mockMember.name, 'displayname', mockMember.displayname], null, null], 'displayname', false, mockMember.name],
//
[[[mockMember.name, 'new', mockMember.displayname], null, null], 'new', false, mockMember.name],
[[[mockMember.name, 'new', '', mockMember.proxy], null, null], 'new', false, mockMember.name],
[[[mockMember.name, 'new', '', '', mockMember.propic], null, null], 'new', false, mockMember.name],
[[[mockMember.name, 'new', '', '', null], mockMember.propic, null], 'new', false, mockMember.name],
[[[mockMember.name, 'new', '', '', null], mockMember.propic, attachmentExpiration], 'new', false, mockMember.name],
//
[[[mockMember.name, 'proxy', mockMember.proxy], null, null], 'proxy', false, mockMember.name],
[[[mockMember.name, 'propic', mockMember.propic], null, null], 'propic', false, mockMember.name],
[[[mockMember.name, 'propic', null], mockMember.propic, null], 'propic', false, mockMember.name],
[[[mockMember.name, 'propic', null], mockMember.propic, attachmentExpiration], 'propic', false, mockMember.name],
[[['remove', mockMember.name], null, null], 'remove', false, mockMember.name],
[[['remove', mockMember.name, 'test'], null, null], 'remove', false, mockMember.name],
[[['new', mockMember.name], null, null], 'new', false, mockMember.name],
[[['new', mockMember.name, mockMember.displayname], null, null], 'new', false, mockMember.name],
[[['new', mockMember.name, mockMember.displayname, mockMember.proxy], null, null], 'new', false, mockMember.name],
[[['new', mockMember.name, mockMember.displayname, mockMember.proxy, mockMember.propic], null, null], 'new', false, mockMember.name],
[[['new', mockMember.name, undefined, mockMember.displayname, mockMember.proxy, undefined], mockMember.propic, null], 'new', false, mockMember.name],
[[['new', mockMember.name, undefined, mockMember.displayname, mockMember.proxy, undefined], mockMember.propic, attachmentExpiration], 'new', false, mockMember.name],
[[['new', mockMember.name, '', mockMember.proxy], null, null], 'new', false, mockMember.name],
[[['new', mockMember.name, '', '', mockMember.propic], null, null], 'new', false, mockMember.name],
[[['new', mockMember.name, '', '', null], mockMember.propic, null], 'new', false, mockMember.name],
[[['new', mockMember.name, '', '', null], mockMember.propic, attachmentExpiration], 'new', false, mockMember.name],
[[['name', mockMember.name, mockMember.name], null, null], 'name', false, mockMember.name],
[[['displayname', mockMember.name, mockMember.name, mockMember.displayname], null, null], 'displayname', false, mockMember.name],
[[['proxy', mockMember.name, mockMember.name, mockMember.displayname, mockMember.proxy], null, null], 'proxy', false, mockMember.name],
[[['propic', mockMember.name, mockMember.name, mockMember.displayname, mockMember.proxy, mockMember.propic], null, null], 'propic', false, mockMember.name],
[[['propic', mockMember.name, undefined, mockMember.name, mockMember.displayname, mockMember.proxy, undefined], mockMember.propic, null], 'propic', false, mockMember.name],
[[['propic', mockMember.name, undefined, mockMember.name, mockMember.displayname, mockMember.proxy, undefined], mockMember.propic, attachmentExpiration], 'propic', false, mockMember.name]
])('calls memberCommandHandler', (args, command) => {
// Arrange
let values = args[0].slice(2);
return memberHelper.memberArgumentHandler(authorId, authorFull, false, command, mockMember.name, args[0], args[1], args[2]).then((result) => {
// Assert
expect(result).toEqual("handled command");
expect(memberHelper.memberCommandHandler).toHaveBeenCalledTimes(1);
expect(memberHelper.memberCommandHandler).toHaveBeenCalledWith(authorId, command, mockMember.name, values, args[1], args[2]);
});
})
test.each([
[null],
['name'],
['displayname'],
['proxy'],
['propic'],
])('%s calls sendCurrentValue', (command) => {
return memberHelper.memberArgumentHandler(authorId, authorFull, false, command, mockMember.name, []).then((result) => {
// Assert
expect(result).toEqual("current value");
expect(memberHelper.sendCurrentValue).toHaveBeenCalledTimes(1);
expect(memberHelper.sendCurrentValue).toHaveBeenCalledWith(authorId,mockMember.name, command);
});
})
});
describe('sendCurrentValue', () => {
test.each([
['name', `The name of ${mockMember.name} is \"${mockMember.name}\" but you probably already knew that!`],
['displayname', `The display name for ${mockMember.name} is \"${mockMember.displayname}\".`],
['proxy', `The proxy for ${mockMember.name} is \"${mockMember.proxy}\".`],
['propic', `The profile picture for ${mockMember.name} is \"${mockMember.propic}\".`],
])('%s calls getMemberByName and returns value', (command, expected) => {
// Arrange
jest.spyOn(memberHelper, 'getMemberByName').mockResolvedValue(mockMember);
// Act
return memberHelper.sendCurrentValue(authorId, mockMember.name, command).then((result) => {
// Assert
expect(result).toEqual(expected);
expect(memberHelper.getMemberByName).toHaveBeenCalledTimes(1);
expect(memberHelper.getMemberByName).toHaveBeenCalledWith(authorId,mockMember.name);
});
})
test('returns error if no member found', () => {
// Arrange
jest.spyOn(memberHelper, 'getMemberByName').mockResolvedValue(null);
// Act
return memberHelper.sendCurrentValue(authorId, mockMember.name, 'name').catch((result) => {
// Assert
expect(result).toEqual(new Error(enums.err.NO_MEMBER));
expect(memberHelper.getMemberByName).toHaveBeenCalledTimes(1);
expect(memberHelper.getMemberByName).toHaveBeenCalledWith(authorId,mockMember.name);
});
})
test('calls getMemberInfo with member if no command present', () => {
// Arrange
jest.spyOn(memberHelper, 'getMemberByName').mockResolvedValue(mockMember);
jest.spyOn(memberHelper, 'getMemberInfo').mockResolvedValue('member info');
// Act
return memberHelper.sendCurrentValue(authorId, mockMember.name, null).then((result) => {
// Assert
expect(result).toEqual('member info');
expect(memberHelper.getMemberInfo).toHaveBeenCalledTimes(1);
expect(memberHelper.getMemberInfo).toHaveBeenCalledWith(mockMember);
});
})
test.each([
['displayname', `Display name ${enums.err.NO_VALUE}`],
['proxy', `Proxy ${enums.err.NO_VALUE}`],
['propic', `Propic ${enums.err.NO_VALUE}`],
])('returns null message if no member found', (command, expected) => {
// Arrange
const empty = {name: mockMember.name, displayname: null, proxy: null, propic: null}
jest.spyOn(memberHelper, 'getMemberByName').mockResolvedValue(empty);
// Act
return memberHelper.sendCurrentValue(authorId, mockMember.name, command).then((result) => {
// Assert
expect(result).toEqual(expected);
expect(memberHelper.getMemberByName).toHaveBeenCalledTimes(1);
expect(memberHelper.getMemberByName).toHaveBeenCalledWith(authorId,mockMember.name);
});
})
})
// //
// test.each([ // test.each([
// [['somePerson', 'name', 'newPerson'], "updateName", "update name"], // [['somePerson', 'name', 'newPerson'], "updateName", "update name"],
@@ -184,7 +379,7 @@ describe('MemberHelper', () => {
// //
// test.each([ // test.each([
// [["somePerson", "propic", attachmentUrl], null, null], // [["somePerson", "propic", attachmentUrl], null, null],
// [["somePerson", "propic", null], 'ono.png', attachmentExpiry], // [["somePerson", "propic", null], 'ono.png', attachmentExpiration],
// ])('%s calls updatePropic and returns expected values', async (args, attachmentUrl, attachmentExpiration) => { // ])('%s calls updatePropic and returns expected values', async (args, attachmentUrl, attachmentExpiration) => {
// // Act // // Act
// return memberHelper.parseMemberCommand(authorId, authorFull, args, attachmentUrl, attachmentExpiration).then((result) => { // return memberHelper.parseMemberCommand(authorId, authorFull, args, attachmentUrl, attachmentExpiration).then((result) => {
@@ -280,30 +475,30 @@ describe('MemberHelper', () => {
// expect(memberHelper.getMemberByName).not.toHaveBeenCalled(); // expect(memberHelper.getMemberByName).not.toHaveBeenCalled();
// }); // });
// }); // });
}) // })
describe('addNewMember', () => { describe('addNewMember', () => {
test('calls addFullMember with correct arguments', async() => { test('calls addFullMember with correct arguments', async() => {
// Arrange // Arrange
const args = ['new', mockMember.name, mockMember.displayname, mockMember.proxy, mockMember.propic]; const args = [mockMember.displayname, mockMember.proxy, mockMember.propic];
jest.spyOn(memberHelper, 'addFullMember').mockResolvedValue(mockMember); jest.spyOn(memberHelper, 'addFullMember').mockResolvedValue(mockMember);
jest.spyOn(memberHelper, 'getMemberInfo').mockResolvedValue(); jest.spyOn(memberHelper, 'getMemberInfo').mockResolvedValue();
// Act // Act
return memberHelper.addNewMember(authorId, args).then(() => { return memberHelper.addNewMember(authorId, mockMember.name, args, attachmentUrl, attachmentExpiration).then(() => {
expect(memberHelper.addFullMember).toHaveBeenCalledTimes(1); expect(memberHelper.addFullMember).toHaveBeenCalledTimes(1);
expect(memberHelper.addFullMember).toHaveBeenCalledWith(authorId, mockMember.name, mockMember.displayname, mockMember.proxy, mockMember.propic); expect(memberHelper.addFullMember).toHaveBeenCalledWith(authorId, mockMember.name, mockMember.displayname, mockMember.proxy, mockMember.propic, attachmentExpiration);
}) })
}) })
test('calls getMemberInfo when successful and returns result', async () => { test('calls getMemberInfo when successful and returns result', async () => {
// Arrange // Arrange
const args = ['new', mockMember.name, mockMember.displayname, mockMember.proxy, mockMember.propic]; const args = [mockMember.displayname, mockMember.proxy, mockMember.propic];
const fullMemberResponse = {member: mockMember, errors: []} const fullMemberResponse = {member: mockMember, errors: []}
const expected = {embed: mockMember, errors: [], success: `${mockMember.name} has been added successfully.`}; const expected = {embed: mockMember, errors: [], success: `${mockMember.name} has been added successfully.`};
jest.spyOn(memberHelper, 'addFullMember').mockResolvedValue(fullMemberResponse); jest.spyOn(memberHelper, 'addFullMember').mockResolvedValue(fullMemberResponse);
jest.spyOn(memberHelper, 'getMemberInfo').mockResolvedValue(mockMember); jest.spyOn(memberHelper, 'getMemberInfo').mockReturnValue(mockMember);
//Act //Act
return memberHelper.addNewMember(authorId, args).then((result) => { return memberHelper.addNewMember(authorId, mockMember.name, args, attachmentUrl, attachmentExpiration).then((result) => {
// Assert // Assert
expect(result).toEqual(expected); expect(result).toEqual(expected);
expect(memberHelper.getMemberInfo).toHaveBeenCalledTimes(1); expect(memberHelper.getMemberInfo).toHaveBeenCalledTimes(1);
@@ -313,14 +508,14 @@ describe('MemberHelper', () => {
test('throws expected error when getMemberInfo throws error', async () => { test('throws expected error when getMemberInfo throws error', async () => {
// Arrange // Arrange
const args = ['new', 'some person']; const args = [];
const memberObject = {name: args[1]} const memberObject = {name: args[1]}
jest.spyOn(memberHelper, 'addFullMember').mockResolvedValue(memberObject); jest.spyOn(memberHelper, 'addFullMember').mockResolvedValue(memberObject);
jest.spyOn(memberHelper, 'getMemberInfo').mockImplementation(() => { jest.spyOn(memberHelper, 'getMemberInfo').mockImplementation(() => {
throw new Error('getMemberInfo error') throw new Error('getMemberInfo error')
}); });
//Act //Act
return memberHelper.addNewMember(authorId, args).catch((result) => { return memberHelper.addNewMember(authorId, mockMember.name, args).catch((result) => {
// Assert // Assert
expect(result).toEqual(new Error('getMemberInfo error')); expect(result).toEqual(new Error('getMemberInfo error'));
}) })
@@ -328,14 +523,14 @@ describe('MemberHelper', () => {
test('throws expected error when addFullMember throws error', async () => { test('throws expected error when addFullMember throws error', async () => {
// Arrange // Arrange
const args = ['new', 'somePerson']; const args = [];
const expected = 'add full member error'; const expected = 'add full member error';
jest.spyOn(memberHelper, 'addFullMember').mockImplementation(() => { jest.spyOn(memberHelper, 'addFullMember').mockImplementation(() => {
throw new Error(expected) throw new Error(expected)
}); });
//Act //Act
return memberHelper.addNewMember(authorId, args).catch((result) => { return memberHelper.addNewMember(authorId, mockMember.name, args).catch((result) => {
// Assert // Assert
expect(result).toEqual(new Error(expected)); expect(result).toEqual(new Error(expected));
}) })
@@ -427,18 +622,18 @@ describe('MemberHelper', () => {
[null, attachmentUrl, null, attachmentUrl], [null, attachmentUrl, null, attachmentUrl],
[mockMember.propic, null, null, mockMember.propic], [mockMember.propic, null, null, mockMember.propic],
[mockMember.propic, attachmentUrl, null, attachmentUrl], [mockMember.propic, attachmentUrl, null, attachmentUrl],
[null, attachmentUrl, attachmentExpiry, attachmentUrl] [null, attachmentUrl, attachmentExpiration, attachmentUrl]
])('calls checkImageFormatValidity and updateMemberField and returns string', async(imgUrl, attachmentUrl, attachmentExpiry, expected) => { ])('calls checkImageFormatValidity and updateMemberField and returns string', async(imgUrl, attachmentUrl, attachmentExpiration, expected) => {
// Arrange // Arrange
jest.spyOn(memberHelper, 'updateMemberField').mockResolvedValue("Updated"); jest.spyOn(memberHelper, 'updateMemberField').mockResolvedValue("Updated");
// Act // Act
return memberHelper.updatePropic(authorId, mockMember.name, imgUrl, attachmentUrl, attachmentExpiry).then((result) => { return memberHelper.updatePropic(authorId, mockMember.name, imgUrl, attachmentUrl, attachmentExpiration).then((result) => {
expect(result).toEqual("Updated"); expect(result).toEqual("Updated");
expect(utils.checkImageFormatValidity).toHaveBeenCalledTimes(1); expect(utils.checkImageFormatValidity).toHaveBeenCalledTimes(1);
expect(utils.checkImageFormatValidity).toHaveBeenCalledWith(expected); expect(utils.checkImageFormatValidity).toHaveBeenCalledWith(expected);
expect(memberHelper.updateMemberField).toHaveBeenCalledTimes(1); expect(memberHelper.updateMemberField).toHaveBeenCalledTimes(1);
expect(memberHelper.updateMemberField).toHaveBeenCalledWith(authorId, mockMember.name, "propic", expected, attachmentExpiry); expect(memberHelper.updateMemberField).toHaveBeenCalledWith(authorId, mockMember.name, "propic", expected, attachmentExpiration);
}); });
}) })
}) })
@@ -635,7 +830,7 @@ describe('MemberHelper', () => {
}) })
test('calls setExpirationWarning if attachmentExpiration', async () => { test('calls setExpirationWarning if attachmentExpiration', async () => {
return memberHelper.updateMemberField(authorId, mockMember.name, "propic", mockMember.propic, attachmentExpiry).then((res) => { return memberHelper.updateMemberField(authorId, mockMember.name, "propic", mockMember.propic, attachmentExpiration).then((res) => {
expect(memberHelper.setExpirationWarning).toHaveBeenCalledTimes(1); expect(memberHelper.setExpirationWarning).toHaveBeenCalledTimes(1);
expect(memberHelper.setExpirationWarning).toHaveBeenCalledWith(mockMember.propic); expect(memberHelper.setExpirationWarning).toHaveBeenCalledWith(mockMember.propic);
}) })
@@ -646,7 +841,7 @@ describe('MemberHelper', () => {
['displayname', mockMember.displayname, null, `Updated name for ${mockMember.name} to ${mockMember.displayname}`], ['displayname', mockMember.displayname, null, `Updated name for ${mockMember.name} to ${mockMember.displayname}`],
['proxy', mockMember.proxy, null, `Updated name for ${mockMember.name} to ${mockMember.proxy}`], ['proxy', mockMember.proxy, null, `Updated name for ${mockMember.name} to ${mockMember.proxy}`],
['propic', mockMember.propic, null, `Updated name for ${mockMember.name} to ${mockMember.propic}`], ['propic', mockMember.propic, null, `Updated name for ${mockMember.name} to ${mockMember.propic}`],
['propic', mockMember.propic, attachmentExpiry, `Updated name for ${mockMember.name} to ${mockMember.propic} warning}`] ['propic', mockMember.propic, attachmentExpiration, `Updated name for ${mockMember.name} to ${mockMember.propic} warning}`]
])('calls database.members.update with correct column and value and return string', async (columnName, value, attachmentExpiration) => { ])('calls database.members.update with correct column and value and return string', async (columnName, value, attachmentExpiration) => {
// Arrange // Arrange
return memberHelper.updateMemberField(authorId, mockMember.name, columnName, value, attachmentExpiration).then((res) => { return memberHelper.updateMemberField(authorId, mockMember.name, columnName, value, attachmentExpiration).then((res) => {