mirror of
https://github.com/pieartsy/PluralFlux.git
synced 2026-04-17 02:05:29 +10:00
Compare commits
13 Commits
webhook-re
...
bf4f55c91b
| Author | SHA1 | Date | |
|---|---|---|---|
| bf4f55c91b | |||
| b3566010a2 | |||
| 0eee2988ce | |||
| a86260cc4a | |||
| 506e3ef9dd | |||
| 6a33fb592a | |||
| 2f255cefd1 | |||
| c54016de77 | |||
| 31da15eaeb | |||
| 43f4302dbc | |||
| af3da44946 | |||
| af57e2e6a3 | |||
| 77191566e3 |
@@ -1,12 +1,10 @@
|
||||
name: Build Dev instance
|
||||
name: nodeJS remote worker
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["develop", "Develop"]
|
||||
branches: ["develop"]
|
||||
pull_request:
|
||||
branches: ["develop", "Develop"]
|
||||
|
||||
workflow_dispatch:
|
||||
branches: ["develop"]
|
||||
|
||||
jobs:
|
||||
|
||||
@@ -34,16 +32,14 @@ jobs:
|
||||
context: .
|
||||
push: true
|
||||
tags: |
|
||||
engineering.sanya.gay/pluralflux/pluralflux-dev:latest
|
||||
engineering.sanya.gay/pluralflux/pluralflux:latest
|
||||
|
||||
- name: Deploy bot
|
||||
uses: appleboy/ssh-action@v1.0.3
|
||||
with:
|
||||
host: ${{ secrets.SSH_HOST }}
|
||||
username: ${{ secrets.SSH_USER }}
|
||||
key: ${{ secrets.SSH_PRIVATE_KEY }}
|
||||
port: 22
|
||||
script: |
|
||||
cd ${{ secrets.BOT_DIRECTORY }}
|
||||
docker compose pull
|
||||
docker compose up -d pluralflux-dev
|
||||
cd /root/pluralflux-dev/PluralFlux
|
||||
docker compose up -d
|
||||
|
||||
@@ -6,8 +6,6 @@ on:
|
||||
pull_request:
|
||||
branches: ["main"]
|
||||
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
|
||||
build:
|
||||
@@ -35,7 +33,7 @@ jobs:
|
||||
push: true
|
||||
tags: |
|
||||
engineering.sanya.gay/pluralflux/pluralflux:latest
|
||||
|
||||
|
||||
- name: Deploy bot
|
||||
uses: appleboy/ssh-action@v1.0.3
|
||||
with:
|
||||
@@ -44,6 +42,5 @@ jobs:
|
||||
key: ${{ secrets.SSH_PRIVATE_KEY }}
|
||||
port: 22
|
||||
script: |
|
||||
cd ${{ secrets.BOT_DIRECTORY }}
|
||||
docker compose pull
|
||||
docker compose up -d pluralflux-prod
|
||||
cd /root/pluralflux-prod/PluralFlux
|
||||
docker compose up -d
|
||||
@@ -1,26 +0,0 @@
|
||||
name: Auto-Sync from Mirror
|
||||
on:
|
||||
push:
|
||||
repository: "Pluralflux/Pluralflux"
|
||||
branches: [main,develop]
|
||||
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
sync:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Fork
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.GITEA_TOKEN }}
|
||||
|
||||
- name: Pull from Mirror
|
||||
run: |
|
||||
git remote add upstream https://engineering.sanya.gay/PluralFlux/PluralFlux.git
|
||||
git fetch upstream --prune
|
||||
git reset --hard origin/main
|
||||
git push origin "refs/remotes/upstream/*:refs/heads/*" --force-with-lease
|
||||
git merge upstream/main -m "Syncing from github"
|
||||
git push origin main
|
||||
11
.gitignore
vendored
11
.gitignore
vendored
@@ -1,13 +1,8 @@
|
||||
node_modules/
|
||||
build/
|
||||
tmp/
|
||||
temp/
|
||||
node_modules
|
||||
.idea
|
||||
secrets/
|
||||
coverage
|
||||
config.json
|
||||
coverage
|
||||
log.txt
|
||||
.env
|
||||
oya.png
|
||||
variables.env
|
||||
.env.production
|
||||
oya.png
|
||||
@@ -7,4 +7,4 @@ FROM node:20-alpine
|
||||
WORKDIR /app
|
||||
COPY --from=builder /app/node_modules ./node_modules
|
||||
COPY . .
|
||||
CMD ["npm", "start"]
|
||||
CMD ["node", "src/bot.js"]
|
||||
@@ -7,6 +7,8 @@ PluralFlux is a proxybot akin to PluralKit and Tupperbox, but for [Fluxer](https
|
||||
|
||||
[Sponsor the project](https://github.com/sponsors/pieartsy)
|
||||
|
||||
If it's not running at the moment, it's because my computer crashed or something. I'm looking to move running it to a somewhat more permanent solution.
|
||||
|
||||
## Commands
|
||||
All commands are prefixed by `pf;`. Currently only a few are implemented.
|
||||
|
||||
|
||||
25
compose.yaml
25
compose.yaml
@@ -1,26 +1,35 @@
|
||||
services:
|
||||
main:
|
||||
image: engineering.sanya.gay/pluralflux/pluralflux
|
||||
image: engineering.sanya.gay/pluralflux/pluralflux-dev
|
||||
container_name: pluralflux
|
||||
restart: unless-stopped
|
||||
env_file: "variables.env"
|
||||
networks:
|
||||
- pluralflux-net
|
||||
env_file: "secrets.env"
|
||||
postgres:
|
||||
image: postgres:latest
|
||||
env_file: "variables.env"
|
||||
container_name: pluralflux-postgres
|
||||
env_file: "secrets.env"
|
||||
volumes:
|
||||
- pgdata:/var/lib/postgresql
|
||||
- ./pgBackup:/mnt/pgBackup
|
||||
ports:
|
||||
- "5432:5432"
|
||||
networks:
|
||||
- pluralflux-net
|
||||
pgadmin:
|
||||
image: dpage/pgadmin4:latest
|
||||
container_name: pluralflux-pgadmin
|
||||
ports:
|
||||
- "5050:80"
|
||||
env_file: "variables.env"
|
||||
env_file: "secrets.env"
|
||||
depends_on:
|
||||
- postgres
|
||||
volumes:
|
||||
- pgadmindata:/var/lib/pgadmin
|
||||
networks:
|
||||
- pluralflux-net
|
||||
|
||||
networks:
|
||||
pluralflux-net:
|
||||
|
||||
volumes:
|
||||
pgdata:
|
||||
pgadmindata:
|
||||
secrets:
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
import "reflect-metadata"
|
||||
import { DataSource } from "typeorm"
|
||||
import * as env from 'dotenv';
|
||||
import * as path from "path";
|
||||
|
||||
env.config();
|
||||
|
||||
export const AppDataSource = new DataSource({
|
||||
type: "postgres",
|
||||
host: process.env.POSTGRES_ENDPOINT,
|
||||
port: 5432,
|
||||
username: "postgres",
|
||||
password: process.env.POSTGRES_PASSWORD,
|
||||
database: "postgres",
|
||||
synchronize: false,
|
||||
logging: false,
|
||||
entities: [path.join(__dirname, "./entity/*.{ts,js}")],
|
||||
migrations: [path.join(__dirname, "./migrations/*.{ts,js}")],
|
||||
migrationsRun: true,
|
||||
migrationsTableName: 'migrations',
|
||||
migrationsTransactionMode: 'all',
|
||||
invalidWhereValuesBehavior: {
|
||||
null: "sql-null",
|
||||
undefined: "throw",
|
||||
},
|
||||
});
|
||||
@@ -1,40 +0,0 @@
|
||||
import {Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn, Unique} from "typeorm"
|
||||
|
||||
@Entity({name: "Member", synchronize: true})
|
||||
@Unique("UQ_Member_userid_name", ['userid', 'name'])
|
||||
export class Member {
|
||||
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number
|
||||
|
||||
@Column()
|
||||
userid: string
|
||||
|
||||
@Column({
|
||||
length: 100
|
||||
})
|
||||
name: string
|
||||
|
||||
@Column({
|
||||
type: "varchar",
|
||||
nullable: true,
|
||||
length: 100
|
||||
})
|
||||
displayname: string
|
||||
|
||||
@Column({
|
||||
nullable: true,
|
||||
})
|
||||
proxy: string
|
||||
|
||||
@Column({
|
||||
nullable: true,
|
||||
})
|
||||
propic: string
|
||||
|
||||
@CreateDateColumn({ type: 'timestamptz' })
|
||||
createdAt: Date
|
||||
|
||||
@UpdateDateColumn({ type: 'timestamptz' })
|
||||
updatedAt: Date
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||
|
||||
export class Update1772417745487 implements MigrationInterface {
|
||||
name = 'Update1772417745487'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`CREATE TABLE "Member" ("id" SERIAL NOT NULL, "userid" character varying NOT NULL, "name" character varying(100) NOT NULL, "displayname" character varying(100), "proxy" character varying, "propic" character varying, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), CONSTRAINT "PK_235428a1d87c5f639ef7b7cf170" PRIMARY KEY ("id"))`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`DROP TABLE "Member"`);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||
|
||||
export class AddData1772419448503 implements MigrationInterface {
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`INSERT INTO "Member"(id, userid, name,displayname, proxy, propic, "createdAt", "updatedAt") SELECT id,userid, name,displayname, proxy, propic, "createdAt", "updatedAt" FROM "Members";`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`TRUNCATE TABLE "Member"`);
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||
|
||||
export class DeleteDuplicates1772825438973 implements MigrationInterface {
|
||||
name= "DeleteDuplicates1772825438973"
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`DELETE
|
||||
FROM "Member" a USING "Member" b
|
||||
WHERE a.id
|
||||
> b.id
|
||||
AND a.name = b.name
|
||||
AND a.userid = b.userid;`)
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||
|
||||
export class Update1772830252670 implements MigrationInterface {
|
||||
name = 'Update1772830252670'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE "Member" ADD CONSTRAINT "UQ_Member_userid_name" UNIQUE ("userid", "name")`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE "Member" DROP CONSTRAINT "UQ_Member_userid_name"`);
|
||||
}
|
||||
|
||||
}
|
||||
2026
package-lock.json
generated
2026
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
19
package.json
19
package.json
@@ -7,36 +7,27 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/pieartsy/PluralFlux.git"
|
||||
},
|
||||
"type": "commonjs",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@fluxerjs/core": "^1.2.2",
|
||||
"dotenv": "^17.3.1",
|
||||
"pg": "^8.19.0",
|
||||
"pg": "^8.18.0",
|
||||
"pg-hstore": "^2.3.4",
|
||||
"pm2": "^6.0.14",
|
||||
"psql": "^0.0.1",
|
||||
"reflect-metadata": "^0.2.2",
|
||||
"tmp": "^0.2.5",
|
||||
"typeorm": "^0.3.28"
|
||||
"sequelize": "^6.37.7",
|
||||
"tmp": "^0.2.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.29.0",
|
||||
"@babel/plugin-transform-modules-commonjs": "^7.28.6",
|
||||
"@babel/preset-env": "^7.29.0",
|
||||
"@fetch-mock/jest": "^0.2.20",
|
||||
"@types/node": "^25.3.3",
|
||||
"babel-jest": "^30.2.0",
|
||||
"fetch-mock": "^12.6.0",
|
||||
"jest": "^30.2.0",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.9.3"
|
||||
"jest-fetch-mock": "^3.0.3"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "jest",
|
||||
"start": "ts-node src/bot.js",
|
||||
"new-migration": "typeorm-ts-node-commonjs migration:create database/migrations/update",
|
||||
"generate-db": "typeorm-ts-node-commonjs migration:generate -d database/data-source.ts database/migrations/update",
|
||||
"run-migration": "typeorm-ts-node-commonjs migration:run -d database/data-source.ts"
|
||||
"test": "jest"
|
||||
}
|
||||
}
|
||||
|
||||
6
secrets.env
Normal file
6
secrets.env
Normal file
@@ -0,0 +1,6 @@
|
||||
FLUXER_BOT_TOKEN=<your bot token here>
|
||||
POSTGRES_PASSWORD=<your postgres password here>
|
||||
PGADMIN_DEFAULT_EMAIL: <default postgres admin login>
|
||||
PGADMIN_DEFAULT_PASSWORD: <your postgres password here>
|
||||
PGADMIN_CONFIG_SERVER_MODE: 'False'
|
||||
PGADMIN_CONFIG_MASTER_PASSWORD_REQUIRED: 'False'
|
||||
66
src/bot.js
66
src/bot.js
@@ -1,28 +1,24 @@
|
||||
const {Client, Events, Message} = require('@fluxerjs/core');
|
||||
const {messageHelper} = require("./helpers/messageHelper.js");
|
||||
const {enums} = require("./enums.js");
|
||||
const {commands} = require("./commands.js");
|
||||
const {webhookHelper} = require("./helpers/webhookHelper.js");
|
||||
const env = require('dotenv');
|
||||
const {utils} = require("./helpers/utils.js");
|
||||
const { AppDataSource } = require("../database/data-source");
|
||||
import { Client, Events, Message } from '@fluxerjs/core';
|
||||
import { messageHelper } from "./helpers/messageHelper.js";
|
||||
import {enums} from "./enums.js";
|
||||
import {commands} from "./commands.js";
|
||||
import {webhookHelper} from "./helpers/webhookHelper.js";
|
||||
import env from 'dotenv';
|
||||
import {utils} from "./helpers/utils.js";
|
||||
|
||||
env.config();
|
||||
env.config({path: './.env'});
|
||||
|
||||
const token = process.env.FLUXER_BOT_TOKEN;
|
||||
const debug = process.env.debug;
|
||||
export const token = process.env.FLUXER_BOT_TOKEN;
|
||||
|
||||
if (!token) {
|
||||
console.error("Missing FLUXER_BOT_TOKEN environment variable.");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
client = new Client({ intents: 0 });
|
||||
|
||||
module.exports.client = client;
|
||||
export const client = new Client({ intents: 0 });
|
||||
|
||||
client.on(Events.MessageCreate, async (message) => {
|
||||
await module.exports.handleMessageCreate(message);
|
||||
await handleMessageCreate(message);
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -32,15 +28,19 @@ client.on(Events.MessageCreate, async (message) => {
|
||||
* @param {Message} message - The message object
|
||||
*
|
||||
**/
|
||||
module.exports.handleMessageCreate = async function(message) {
|
||||
export const handleMessageCreate = async function(message) {
|
||||
try {
|
||||
// Ignore bots
|
||||
if (message.author.bot) return;
|
||||
// Parse command and arguments
|
||||
const content = message.content.trim();
|
||||
// Ignore bots and messages without content
|
||||
if (message.author.bot || content.length === 0) return;
|
||||
|
||||
// If message doesn't start with the bot prefix, it could still be a message with a proxy tag. If it's not, return.
|
||||
if (!content.startsWith(messageHelper.prefix)) {
|
||||
return await webhookHelper.sendMessageAsMember(client, message);
|
||||
await webhookHelper.sendMessageAsMember(client, message).catch((e) => {
|
||||
throw e
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const commandName = content.slice(messageHelper.prefix.length).split(" ")[0];
|
||||
@@ -57,22 +57,22 @@ module.exports.handleMessageCreate = async function(message) {
|
||||
}
|
||||
|
||||
if (command) {
|
||||
await command.execute(message, args);
|
||||
await command.execute(message, args).catch(e => {
|
||||
throw e
|
||||
});
|
||||
}
|
||||
else {
|
||||
await message.reply(enums.err.COMMAND_NOT_RECOGNIZED);
|
||||
}
|
||||
}
|
||||
catch(error) {
|
||||
if(debug){console.error("An error occurred at unix timestamp " + Date.now() + "while processing the command: " + message + " with error:" + error);}
|
||||
else{console.error(error);}
|
||||
process.exit(2); //need this for now just to make sure the bot continues to restart on errors, since it would seem that fluxer.js doesn't define custom error types. TODO: map out some exit codes
|
||||
console.error(error);
|
||||
// return await message.reply(error.message);
|
||||
}
|
||||
}
|
||||
|
||||
client.on(Events.Ready, () => {
|
||||
console.log(`Logged in as ${client.user?.username}`);
|
||||
if(debug){console.log(Date.now() + `: Currently running in debug mode!`)}
|
||||
});
|
||||
|
||||
let guildCount = 0;
|
||||
@@ -86,23 +86,15 @@ function printGuilds() {
|
||||
}
|
||||
|
||||
const debouncePrintGuilds = utils.debounce(printGuilds, 2000);
|
||||
// export const debounceLogin = utils.debounce(client.login, 60000);
|
||||
export const debounceLogin = utils.debounce(client.login, 60000);
|
||||
|
||||
module.exports.login = async function() {
|
||||
(async () => {
|
||||
try {
|
||||
if (!AppDataSource.isInitialized) {
|
||||
await AppDataSource.initialize();
|
||||
}
|
||||
|
||||
await client.login(token);
|
||||
// await db.check_connection();
|
||||
} catch (err) {
|
||||
console.error('Login failed:', err);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
function main()
|
||||
{
|
||||
exports.login();
|
||||
}
|
||||
|
||||
main();
|
||||
})();
|
||||
@@ -1,20 +1,20 @@
|
||||
const {messageHelper} = require("./helpers/messageHelper.js");
|
||||
const {enums} = require("./enums.js");
|
||||
const {memberHelper} = require("./helpers/memberHelper.js");
|
||||
const {EmbedBuilder} = require("@fluxerjs/core");
|
||||
const {importHelper} = require("./helpers/importHelper.js");
|
||||
import {messageHelper} from "./helpers/messageHelper.js";
|
||||
import {enums} from "./enums.js";
|
||||
import {memberHelper} from "./helpers/memberHelper.js";
|
||||
import {EmbedBuilder} from "@fluxerjs/core";
|
||||
import {importHelper} from "./helpers/importHelper.js";
|
||||
|
||||
const commands = {
|
||||
const cmds = {
|
||||
commandsMap: new Map(),
|
||||
aliasesMap: new Map()
|
||||
};
|
||||
|
||||
commands.aliasesMap.set('m', {command: 'member'})
|
||||
cmds.aliasesMap.set('m', {command: 'member'})
|
||||
|
||||
commands.commandsMap.set('member', {
|
||||
cmds.commandsMap.set('member', {
|
||||
description: enums.help.SHORT_DESC_MEMBER,
|
||||
async execute(message, args) {
|
||||
await commands.memberCommand(message, args)
|
||||
await cmds.memberCommand(message, args)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -26,37 +26,31 @@ commands.commandsMap.set('member', {
|
||||
* @param {string[]} args - The parsed arguments
|
||||
*
|
||||
**/
|
||||
commands.memberCommand = async function (message, args) {
|
||||
cmds.memberCommand = async function(message, args) {
|
||||
const authorFull = `${message.author.username}#${message.author.discriminator}`
|
||||
const attachmentUrl = message.attachments.size > 0 ? message.attachments.first().url : null;
|
||||
const attachmentExpires = message.attachments.size > 0 ? message.attachments.first().expires_at : null;
|
||||
let reply;
|
||||
try {
|
||||
reply = await memberHelper.parseMemberCommand(message.author.id, authorFull, args, attachmentUrl, attachmentExpires)
|
||||
} catch (e) {
|
||||
return await message.reply(e.message);
|
||||
}
|
||||
|
||||
const reply = await memberHelper.parseMemberCommand(message.author.id, authorFull, args, attachmentUrl, attachmentExpires).catch(async (e) =>{console.error(e); await message.reply(e.message);});
|
||||
|
||||
if (typeof reply === 'string') {
|
||||
await message.reply(reply);
|
||||
} else if (reply instanceof EmbedBuilder) {
|
||||
}
|
||||
else if (reply instanceof EmbedBuilder) {
|
||||
await message.reply({embeds: [reply]})
|
||||
} else if (typeof reply === 'object') {
|
||||
// The little dash is so that the errors print out in bullet points in Fluxer
|
||||
const errorsText = reply.errors.length > 0 ? '- ' + reply.errors.join('\n- ') : null;
|
||||
return await message.reply({
|
||||
content: `${reply.success} ${errorsText ? `\n\n${enums.err.ERRORS_OCCURRED}\n` + errorsText : ""}`,
|
||||
embeds: [reply.embed]
|
||||
})
|
||||
}
|
||||
else if (typeof reply === 'object') {
|
||||
const errorsText = reply.errors.length > 0 ? reply.errors.join('\n- ') : null;
|
||||
return await message.reply({content: `${reply.success} ${errorsText ? `\n\n${enums.err.ERRORS_OCCURRED}\n` + errorsText : ""}`, embeds: [reply.embed]})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
commands.commandsMap.set('help', {
|
||||
cmds.commandsMap.set('help', {
|
||||
description: enums.help.SHORT_DESC_HELP,
|
||||
async execute(message) {
|
||||
const fields = [...commands.commandsMap.entries()].map(([name, cmd]) => ({
|
||||
const fields = [...cmds.commandsMap.entries()].map(([name, cmd]) => ({
|
||||
name: `${messageHelper.prefix}${name}`,
|
||||
value: cmd.description,
|
||||
inline: true,
|
||||
@@ -66,17 +60,17 @@ commands.commandsMap.set('help', {
|
||||
.setTitle('Commands')
|
||||
.setDescription(enums.help.PLURALFLUX)
|
||||
.addFields(...fields)
|
||||
.setFooter({text: `Prefix: ${messageHelper.prefix}`})
|
||||
.setFooter({ text: `Prefix: ${messageHelper.prefix}` })
|
||||
.setTimestamp();
|
||||
|
||||
await message.reply({embeds: [embed]});
|
||||
await message.reply({ embeds: [embed] });
|
||||
},
|
||||
})
|
||||
|
||||
commands.commandsMap.set('import', {
|
||||
cmds.commandsMap.set('import', {
|
||||
description: enums.help.SHORT_DESC_IMPORT,
|
||||
async execute(message, args) {
|
||||
await commands.importCommand(message, args);
|
||||
await cmds.importCommand(message, args);
|
||||
}
|
||||
})
|
||||
|
||||
@@ -88,35 +82,29 @@ commands.commandsMap.set('import', {
|
||||
* @param {string[]} args - The parsed arguments
|
||||
*
|
||||
**/
|
||||
commands.importCommand = async function (message, args) {
|
||||
cmds.importCommand = async function(message, args) {
|
||||
const attachmentUrl = message.attachments.size > 0 ? message.attachments.first().url : null;
|
||||
if ((message.content.includes('--help') || (args[0] === '' && args.length === 1)) && !attachmentUrl) {
|
||||
if ((message.content.includes('--help') || (args[0] === '' && args.length === 1)) && !attachmentUrl ) {
|
||||
return await message.reply(enums.help.IMPORT);
|
||||
}
|
||||
let errorsText;
|
||||
try {
|
||||
const successfullyAdded = await importHelper.pluralKitImport(message.author.id, attachmentUrl)
|
||||
return await message.reply(successfullyAdded);
|
||||
} catch (error) {
|
||||
return await importHelper.pluralKitImport(message.author.id, attachmentUrl).then(async (successfullyAdded) => {
|
||||
await message.reply(successfullyAdded);
|
||||
}).catch(async (error) => {
|
||||
if (error instanceof AggregateError) {
|
||||
// errors.message can be a list of successfully added members, or say that none were successful.
|
||||
errorsText = `${error.message}.\n\n${enums.err.ERRORS_OCCURRED}\n\n${error.errors.join('\n')}`;
|
||||
let errorsText = `${error.message}.\n\n${enums.err.ERRORS_OCCURRED}\n${error.errors.join('\n')}`;
|
||||
|
||||
await message.reply(errorsText).catch(async () => {
|
||||
const returnedBuffer = messageHelper.returnBufferFromText(errorsText);
|
||||
await message.reply({content: returnedBuffer.text, files: [{ name: 'text.txt', data: returnedBuffer.file }]
|
||||
})
|
||||
});
|
||||
}
|
||||
// If just one error was returned.
|
||||
else {
|
||||
console.error(error);
|
||||
errorsText = error.message;
|
||||
return await message.reply(error.message);
|
||||
}
|
||||
}
|
||||
if (errorsText.length > 2000) {
|
||||
const returnedBuffer = messageHelper.returnBufferFromText(errorsText);
|
||||
await message.reply({
|
||||
content: returnedBuffer.text, files: [{name: 'text.txt', data: returnedBuffer.file}]
|
||||
})
|
||||
} else {
|
||||
await message.reply(errorsText)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
module.exports.commands = commands;
|
||||
export const commands = cmds;
|
||||
84
src/database.js
Normal file
84
src/database.js
Normal file
@@ -0,0 +1,84 @@
|
||||
import {DataTypes, Sequelize} from 'sequelize';
|
||||
import * as env from 'dotenv';
|
||||
|
||||
env.config();
|
||||
|
||||
const password = process.env.POSTGRES_PASSWORD;
|
||||
|
||||
if (!password) {
|
||||
console.error("Missing POSTGRES_PWD environment variable.");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const db = {};
|
||||
|
||||
const sequelize = new Sequelize('postgres', 'postgres', password, {
|
||||
host: 'localhost',
|
||||
logging: false,
|
||||
dialect: 'postgres'
|
||||
});
|
||||
|
||||
db.sequelize = sequelize;
|
||||
db.Sequelize = Sequelize;
|
||||
|
||||
db.members = sequelize.define('Member', {
|
||||
userid: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
},
|
||||
name: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
},
|
||||
displayname: {
|
||||
type: DataTypes.STRING,
|
||||
},
|
||||
propic: {
|
||||
type: DataTypes.STRING,
|
||||
},
|
||||
proxy: {
|
||||
type: DataTypes.STRING,
|
||||
}
|
||||
});
|
||||
|
||||
db.systems = sequelize.define('System', {
|
||||
userid: {
|
||||
type: DataTypes.STRING,
|
||||
},
|
||||
fronter: {
|
||||
type: DataTypes.STRING
|
||||
},
|
||||
grouptag: {
|
||||
type: DataTypes.STRING
|
||||
},
|
||||
autoproxy: {
|
||||
type: DataTypes.BOOLEAN,
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* Checks Sequelize database connection.
|
||||
*/
|
||||
db.check_connection = async function() {
|
||||
await sequelize.authenticate().then(async () => {
|
||||
console.log('Connection has been established successfully.');
|
||||
await syncModels();
|
||||
}).catch(err => {
|
||||
console.error('Unable to connect to the database:', err);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Syncs Sequelize models.
|
||||
*/
|
||||
async function syncModels() {
|
||||
await sequelize.sync().then(() => {
|
||||
console.log('Models synced successfully.');
|
||||
}).catch((err) => {
|
||||
console.error('Syncing models did not work', err);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
export const database = db;
|
||||
18
src/enums.js
18
src/enums.js
@@ -1,6 +1,6 @@
|
||||
const enums = {};
|
||||
const helperEnums = {};
|
||||
|
||||
enums.err = {
|
||||
helperEnums.err = {
|
||||
NO_MEMBER: "No such member was found.",
|
||||
NO_NAME_PROVIDED: "No member name was provided for",
|
||||
NO_VALUE: "has not been set for this member.",
|
||||
@@ -22,11 +22,10 @@ enums.err = {
|
||||
NO_MEMBERS_IMPORTED: 'No members were imported.',
|
||||
ERRORS_OCCURRED: "These errors occurred:",
|
||||
COMMAND_NOT_RECOGNIZED: "Command not recognized. Try typing `pf;help` for command list.",
|
||||
SET_TO_NULL: "It has been set to null instead.",
|
||||
CANNOT_FETCH_RESOURCE: "Could not download the file at this time."
|
||||
SET_TO_NULL: "It has been set to null instead."
|
||||
}
|
||||
|
||||
enums.help = {
|
||||
helperEnums.help = {
|
||||
SHORT_DESC_HELP: "Lists available commands.",
|
||||
SHORT_DESC_MEMBER: "Accesses subcommands related to proxy members.",
|
||||
SHORT_DESC_IMPORT: "Imports from PluralKit.",
|
||||
@@ -43,11 +42,8 @@ enums.help = {
|
||||
IMPORT: "Imports from PluralKit using the JSON file provided by their export command. Importing from other proxy bots is TBD. `pf;import` and attach your JSON file to the message. This will only save the fields that are present in the bot currently, not anything else like birthdays or system handles (yet?). **Only one proxy can be set per member currently.**\n\n**PRO TIP**: For privacy reasons, try DMing the bot with this command and your JSON file--it should still work the same."
|
||||
}
|
||||
|
||||
enums.misc = {
|
||||
ATTACHMENT_SENT_BY: "Attachment sent by:",
|
||||
ATTACHMENT_EXPIRATION_WARNING: "**NOTE:** Because this profile picture is hosted on Fluxer, it will expire. To avoid this, upload the picture to another website like <https://imgbb.com/> and link to it directly.",
|
||||
FLUXER_ATTACHMENT_URL: "https://fluxerusercontent.com/attachments/"
|
||||
|
||||
helperEnums.misc = {
|
||||
ATTACHMENT_SENT_BY: "Attachment sent by:"
|
||||
}
|
||||
|
||||
module.exports.enums = enums;
|
||||
export const enums = helperEnums;
|
||||
@@ -1,7 +1,7 @@
|
||||
const {enums} = require("../enums.js");
|
||||
const {memberHelper} = require("./memberHelper.js");
|
||||
import {enums} from "../enums.js";
|
||||
import {memberHelper} from "./memberHelper.js";
|
||||
|
||||
const importHelper = {};
|
||||
const ih = {};
|
||||
|
||||
/**
|
||||
* Tries to import from Pluralkit.
|
||||
@@ -9,50 +9,35 @@ const importHelper = {};
|
||||
* @async
|
||||
* @param {string} authorId - The author of the message
|
||||
* @param {string | null} [attachmentUrl] - The attached JSON url.
|
||||
* @returns {Promise<string>} A successful addition of all members.
|
||||
* @returns {string} A successful addition of all members.
|
||||
* @throws {Error} When the member exists, or creating a member doesn't work.
|
||||
*/
|
||||
importHelper.pluralKitImport = async function (authorId, attachmentUrl= null) {
|
||||
let fetchResult, pkData;
|
||||
ih.pluralKitImport = async function (authorId, attachmentUrl= null) {
|
||||
if (!attachmentUrl) {
|
||||
throw new Error(enums.err.NOT_JSON_FILE);
|
||||
}
|
||||
try {
|
||||
fetchResult = await fetch(attachmentUrl);
|
||||
}
|
||||
catch(e) {
|
||||
throw new Error(enums.err.CANNOT_FETCH_RESOURCE, { cause: e });
|
||||
}
|
||||
|
||||
try {
|
||||
pkData = await fetchResult.json();
|
||||
}
|
||||
catch(e) {
|
||||
throw new Error(enums.err.NOT_JSON_FILE, { cause: e })
|
||||
}
|
||||
|
||||
const pkMembers = pkData.members;
|
||||
let errors = [];
|
||||
let addedMembers = [];
|
||||
for (let pkMember of pkMembers) {
|
||||
const proxy = pkMember.proxy_tags[0] ? `${pkMember.proxy_tags[0].prefix ?? ''}text${pkMember.proxy_tags[0].suffix ?? ''}` : null;
|
||||
try {
|
||||
const memberObj = await memberHelper.addFullMember(authorId, pkMember.name, pkMember.display_name, proxy, pkMember.avatar_url);
|
||||
addedMembers.push(memberObj.member.name);
|
||||
if (memberObj.errors.length > 0) {
|
||||
errors.push(`\n**${pkMember.name}:** `);
|
||||
errors = errors.concat(memberObj.errors);
|
||||
return fetch(attachmentUrl).then((res) => res.json()).then(async(pkData) => {
|
||||
const pkMembers = pkData.members;
|
||||
let errors = [];
|
||||
const addedMembers = [];
|
||||
for (let pkMember of pkMembers) {
|
||||
const proxy = pkMember.proxy_tags[0] ? `${pkMember.proxy_tags[0].prefix ?? ''}text${pkMember.proxy_tags[0].suffix ?? ''}` : null;
|
||||
await memberHelper.addFullMember(authorId, pkMember.name, pkMember.display_name, proxy, pkMember.avatar_url).then((memberObj) => {
|
||||
addedMembers.push(memberObj.member.name);
|
||||
if (memberObj.errors.length > 0) {
|
||||
errors.push(`\n**${pkMember.name}:** `)
|
||||
errors = errors.concat(memberObj.errors);
|
||||
}
|
||||
}).catch(e => {
|
||||
errors.push(e.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
catch(e) {
|
||||
errors.push(e.message);
|
||||
}
|
||||
}
|
||||
const aggregatedText = addedMembers.length > 0 ? `Successfully added members: ${addedMembers.join(', ')}` : `${enums.err.NO_MEMBERS_IMPORTED}`;
|
||||
if (errors.length > 0) {
|
||||
throw new AggregateError(errors, aggregatedText);
|
||||
}
|
||||
return aggregatedText;
|
||||
const aggregatedText = addedMembers.length > 0 ? `Successfully added members: ${addedMembers.join(', ')}` : `${enums.err.NO_MEMBERS_IMPORTED}`;
|
||||
if (errors.length > 0) {
|
||||
throw new AggregateError(errors, aggregatedText);
|
||||
}
|
||||
return aggregatedText;
|
||||
});
|
||||
}
|
||||
|
||||
exports.importHelper = importHelper;
|
||||
export const importHelper = ih;
|
||||
@@ -1,9 +1,10 @@
|
||||
const {enums} = require("../enums.js");
|
||||
const {EmbedBuilder} = require("@fluxerjs/core");
|
||||
const {utils} = require("./utils.js");
|
||||
const {memberRepo} = require("../repositories/memberRepo.js");
|
||||
import {database} from '../database.js';
|
||||
import {enums} from "../enums.js";
|
||||
import {Op} from "sequelize";
|
||||
import {EmbedBuilder} from "@fluxerjs/core";
|
||||
import {utils} from "./utils.js";
|
||||
|
||||
const memberHelper = {};
|
||||
const mh = {};
|
||||
|
||||
const commandList = ['new', 'remove', 'name', 'list', 'displayname', 'proxy', 'propic'];
|
||||
const newAndRemoveCommands = ['new', 'remove'];
|
||||
@@ -21,15 +22,16 @@ const newAndRemoveCommands = ['new', 'remove'];
|
||||
* @returns {Promise <EmbedBuilder>} A list of 25 members as an embed.
|
||||
* @returns {Promise <EmbedBuilder>} A list of member commands and descriptions.
|
||||
* @returns {Promise<{EmbedBuilder, string[], string}>} A member info embed + info/errors.
|
||||
* @throws {Error}
|
||||
*/
|
||||
memberHelper.parseMemberCommand = async function (authorId, authorFull, args, attachmentUrl = null, attachmentExpiration = null) {
|
||||
mh.parseMemberCommand = async function (authorId, authorFull, args, attachmentUrl = null, attachmentExpiration = null) {
|
||||
let memberName, command, isHelp = false;
|
||||
// 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
|
||||
if (args.length === 0 || args[0] === '--help' || args[0] === '') {
|
||||
return memberHelper.getMemberCommandInfo();
|
||||
return mh.getMemberCommandInfo();
|
||||
}
|
||||
// ex: pf;member remove somePerson
|
||||
if (commandList.includes(args[0])) {
|
||||
@@ -51,7 +53,7 @@ memberHelper.parseMemberCommand = async function (authorId, authorFull, args, at
|
||||
isHelp = true;
|
||||
}
|
||||
|
||||
return await memberHelper.memberArgumentHandler(authorId, authorFull, isHelp, command, memberName, args, attachmentUrl, attachmentExpiration);
|
||||
return await mh.memberArgumentHandler(authorId, authorFull, isHelp, command, memberName, args, attachmentUrl, attachmentExpiration)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,18 +72,17 @@ memberHelper.parseMemberCommand = async function (authorId, authorFull, args, at
|
||||
* @returns {Promise <EmbedBuilder>} A list of 25 members as an embed.
|
||||
* @returns {Promise <EmbedBuilder>} A list of member commands and descriptions.
|
||||
* @returns {Promise<{EmbedBuilder, [string], string}>} A member info embed + info/errors.
|
||||
* @returns {Promise<string>} - A help message
|
||||
* @throws {Error} When there's no member or a command is not recognized.
|
||||
* @throws {Error}
|
||||
*/
|
||||
memberHelper.memberArgumentHandler = async function(authorId, authorFull, isHelp, command = null, memberName = null, args = [], attachmentUrl = null, attachmentExpiration = null) {
|
||||
mh.memberArgumentHandler = async function(authorId, authorFull, isHelp, command = null, memberName = null, args = [], attachmentUrl = null, attachmentExpiration = null) {
|
||||
if (!command && !memberName && !isHelp) {
|
||||
throw new Error(enums.err.COMMAND_NOT_RECOGNIZED);
|
||||
}
|
||||
else if (isHelp) {
|
||||
return memberHelper.sendHelpEnum(command);
|
||||
return mh.sendHelpEnum(command);
|
||||
}
|
||||
else if (command === "list") {
|
||||
return await memberHelper.getAllMembersInfo(authorId, authorFull);
|
||||
return await mh.getAllMembersInfo(authorId, authorFull);
|
||||
}
|
||||
else if (!memberName && !isHelp) {
|
||||
throw new Error(enums.err.NO_MEMBER);
|
||||
@@ -92,10 +93,10 @@ memberHelper.memberArgumentHandler = async function(authorId, authorFull, isHelp
|
||||
|
||||
// ex: pf;member blah blah
|
||||
if (command && memberName && (values.length > 0 || newAndRemoveCommands.includes(command) || attachmentUrl)) {
|
||||
return await memberHelper.memberCommandHandler(authorId, command, memberName, values, attachmentUrl, attachmentExpiration);
|
||||
return await mh.memberCommandHandler(authorId, command, memberName, values, attachmentUrl, attachmentExpiration).catch((e) => {throw e});
|
||||
}
|
||||
else if (memberName && values.length === 0) {
|
||||
return await memberHelper.sendCurrentValue(authorId, memberName, command);
|
||||
return await mh.sendCurrentValue(authorId, memberName, command).catch((e) => {throw e});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,14 +111,15 @@ memberHelper.memberArgumentHandler = async function(authorId, authorFull, isHelp
|
||||
* @returns {Promise <EmbedBuilder>} A list of 25 members as an embed.
|
||||
* @returns {Promise <EmbedBuilder>} A list of member commands and descriptions.
|
||||
* @returns {Promise<{EmbedBuilder, string[], string}>} A member info embed + info/errors.
|
||||
* @throws {Error} When there's no member
|
||||
*/
|
||||
memberHelper.sendCurrentValue = async function(authorId, memberName, command= null) {
|
||||
const member = await memberRepo.getMemberByName(authorId, memberName);
|
||||
if (!member) throw new Error(enums.err.NO_MEMBER);
|
||||
mh.sendCurrentValue = async function(authorId, memberName, command= null) {
|
||||
const member = await mh.getMemberByName(authorId, memberName).then((m) => {
|
||||
if (!m) throw new Error(enums.err.NO_MEMBER);
|
||||
return m;
|
||||
});
|
||||
|
||||
if (!command) {
|
||||
return memberHelper.getMemberInfo(member);
|
||||
return mh.getMemberInfo(member);
|
||||
}
|
||||
|
||||
switch (command) {
|
||||
@@ -138,7 +140,7 @@ memberHelper.sendCurrentValue = async function(authorId, memberName, command= nu
|
||||
* @param {string} command - The command being called.
|
||||
* @returns {string} - The help text associated with a command.
|
||||
*/
|
||||
memberHelper.sendHelpEnum = function(command) {
|
||||
mh.sendHelpEnum = function(command) {
|
||||
switch (command) {
|
||||
case 'new':
|
||||
return enums.help.NEW;
|
||||
@@ -167,24 +169,26 @@ memberHelper.sendHelpEnum = function(command) {
|
||||
* @param {string[]} values - The values to be passed in. Only includes the values after member name and command name.
|
||||
* @param {string | null} attachmentUrl - The attachment URL, if any
|
||||
* @param {string | null} attachmentExpiration - The attachment expiry date, if any
|
||||
* @returns {Promise<string> | Promise <EmbedBuilder> | Promise<{EmbedBuilder, [string], string}>}
|
||||
* @returns {Promise<string>} A success message.
|
||||
* @returns {Promise <EmbedBuilder>} A list of 25 members as an embed.
|
||||
* @returns {Promise <EmbedBuilder>} A list of member commands and descriptions.
|
||||
* @returns {Promise<{EmbedBuilder, [string], string}>} A member info embed + info/errors.
|
||||
* @throws {Error}
|
||||
*/
|
||||
memberHelper.memberCommandHandler = async function(authorId, command, memberName, values, attachmentUrl = null, attachmentExpiration = null) {
|
||||
mh.memberCommandHandler = async function(authorId, command, memberName, values, attachmentUrl = null, attachmentExpiration = null) {
|
||||
switch (command) {
|
||||
case 'new':
|
||||
return await memberHelper.addNewMember(authorId, memberName, values, attachmentUrl, attachmentExpiration);
|
||||
return await mh.addNewMember(authorId, memberName, values, attachmentUrl, attachmentExpiration).catch((e) => {throw e});
|
||||
case 'remove':
|
||||
return await memberHelper.removeMember(authorId, memberName);
|
||||
return await mh.removeMember(authorId, memberName).catch((e) => {throw e});
|
||||
case 'name':
|
||||
return await memberHelper.updateName(authorId, memberName, values[0]);
|
||||
return await mh.updateName(authorId, memberName, values[0]).catch((e) => {throw e});
|
||||
case 'displayname':
|
||||
return await memberHelper.updateDisplayName(authorId, memberName, values[0]);
|
||||
return await mh.updateDisplayName(authorId, memberName, values[0]).catch((e) => {throw e});
|
||||
case 'proxy':
|
||||
return await memberHelper.updateProxy(authorId, memberName, values[0]);
|
||||
return await mh.updateProxy(authorId, memberName, values[0]).catch((e) => {throw e});
|
||||
case 'propic':
|
||||
return await memberHelper.updatePropic(authorId, memberName, values[0], attachmentUrl, attachmentExpiration);
|
||||
default:
|
||||
throw new Error(enums.err.COMMAND_NOT_RECOGNIZED);
|
||||
return await mh.updatePropic(authorId, memberName, values[0], attachmentUrl, attachmentExpiration).catch((e) => {throw e});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,15 +202,20 @@ memberHelper.memberCommandHandler = async function(authorId, command, memberName
|
||||
* @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 creating a member doesn't work.
|
||||
*/
|
||||
memberHelper.addNewMember = async function (authorId, memberName, values, attachmentUrl = null, attachmentExpiration = null) {
|
||||
mh.addNewMember = async function (authorId, memberName, values, attachmentUrl = null, attachmentExpiration = null) {
|
||||
const displayName = values[0];
|
||||
const proxy = values[1];
|
||||
const propic = values[2] ?? attachmentUrl;
|
||||
|
||||
const memberObj = await memberHelper.addFullMember(authorId, memberName, displayName, proxy, propic, attachmentExpiration);
|
||||
const memberInfoEmbed = memberHelper.getMemberInfo(memberObj.member);
|
||||
return {embed: memberInfoEmbed, errors: memberObj.errors, success: `${memberName} has been added successfully.`}
|
||||
return await mh.addFullMember(authorId, memberName, displayName, proxy, propic, attachmentExpiration).then((response) => {
|
||||
const memberInfoEmbed = mh.getMemberInfo(response.member);
|
||||
return {embed: memberInfoEmbed, errors: response.errors, success: `${memberName} has been added successfully.`};
|
||||
}).catch(e => {
|
||||
console.error(e);
|
||||
throw e;
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -219,12 +228,14 @@ memberHelper.addNewMember = async function (authorId, memberName, values, attach
|
||||
* @returns {Promise<string>} A successful update.
|
||||
* @throws {RangeError} When the name doesn't exist.
|
||||
*/
|
||||
memberHelper.updateName = async function (authorId, memberName, name) {
|
||||
mh.updateName = async function (authorId, memberName, name) {
|
||||
const trimmedName = name.trim();
|
||||
if (trimmedName === '') {
|
||||
throw new RangeError(`Name ${enums.err.NO_VALUE}`);
|
||||
}
|
||||
return await memberHelper.updateMemberField(authorId, memberName, "name", trimmedName);
|
||||
return await mh.updateMemberField(authorId, memberName, "name", trimmedName).catch((e) => {
|
||||
throw e
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -237,7 +248,7 @@ memberHelper.updateName = async function (authorId, memberName, name) {
|
||||
* @returns {Promise<string>} A successful update.
|
||||
* @throws {RangeError} When the display name is too long or doesn't exist.
|
||||
*/
|
||||
memberHelper.updateDisplayName = async function (authorId, membername, displayname) {
|
||||
mh.updateDisplayName = async function (authorId, membername, displayname) {
|
||||
const trimmedName = displayname.trim();
|
||||
|
||||
if (trimmedName.length > 32) {
|
||||
@@ -246,7 +257,9 @@ memberHelper.updateDisplayName = async function (authorId, membername, displayna
|
||||
else if (trimmedName === '') {
|
||||
throw new RangeError(`Display name ${enums.err.NO_VALUE}`);
|
||||
}
|
||||
return await memberHelper.updateMemberField(authorId, membername, "displayname", trimmedName);
|
||||
return await mh.updateMemberField(authorId, membername, "displayname", trimmedName).catch((e) => {
|
||||
throw e
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -257,12 +270,13 @@ memberHelper.updateDisplayName = async function (authorId, membername, displayna
|
||||
* @param {string} memberName - The member to update
|
||||
* @param {string} proxy - The proxy to set
|
||||
* @returns {Promise<string> } A successful update.
|
||||
* @throws {Error} When an empty proxy was provided, or a proxy exists.
|
||||
*/
|
||||
memberHelper.updateProxy = async function (authorId, memberName, proxy) {
|
||||
mh.updateProxy = async function (authorId, memberName, proxy) {
|
||||
// Throws error if exists
|
||||
await memberHelper.checkIfProxyExists(authorId, proxy);
|
||||
await mh.checkIfProxyExists(authorId, proxy).catch((e) => { throw e; });
|
||||
|
||||
return await memberHelper.updateMemberField(authorId, memberName, "proxy", proxy);
|
||||
return await mh.updateMemberField(authorId, memberName, "proxy", proxy).catch((e) => { throw e;});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -275,13 +289,14 @@ memberHelper.updateProxy = async function (authorId, memberName, proxy) {
|
||||
* @param {string | null} attachmentUrl - The attachment URL, if any
|
||||
* @param {string | null} attachmentExpiration - The attachment expiry date, if any
|
||||
* @returns {Promise<string>} A successful update.
|
||||
* @throws {Error} When loading the profile picture from a URL doesn't work.
|
||||
*/
|
||||
memberHelper.updatePropic = async function (authorId, memberName, values, attachmentUrl = null, attachmentExpiration = null) {
|
||||
mh.updatePropic = async function (authorId, memberName, values, attachmentUrl = null, attachmentExpiration = null) {
|
||||
const imgUrl = values ?? attachmentUrl;
|
||||
// Throws error if invalid
|
||||
await utils.checkImageFormatValidity(imgUrl);
|
||||
const expirationWarning = utils.setExpirationWarning(imgUrl, attachmentExpiration);
|
||||
return await memberHelper.updateMemberField(authorId, memberName, "propic", imgUrl, expirationWarning);
|
||||
await utils.checkImageFormatValidity(imgUrl).catch((e) => { throw e });
|
||||
|
||||
return await mh.updateMemberField(authorId, memberName, "propic", imgUrl, attachmentExpiration).catch((e) => { throw e });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -293,13 +308,18 @@ memberHelper.updatePropic = async function (authorId, memberName, values, attach
|
||||
* @returns {Promise<string>} A successful removal.
|
||||
* @throws {Error} When there is no member to remove.
|
||||
*/
|
||||
memberHelper.removeMember = async function (authorId, memberName) {
|
||||
const destroyed = await memberRepo.removeMember(authorId, memberName);
|
||||
if (destroyed > 0) {
|
||||
return `Member "${memberName}" has been deleted.`;
|
||||
} else {
|
||||
mh.removeMember = async function (authorId, memberName) {
|
||||
return await database.members.destroy({
|
||||
where: {
|
||||
name: {[Op.iLike]: memberName},
|
||||
userid: authorId
|
||||
}
|
||||
}).then((result) => {
|
||||
if (result) {
|
||||
return `Member "${memberName}" has been deleted.`;
|
||||
}
|
||||
throw new Error(`${enums.err.NO_MEMBER}`);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/*======Non-Subcommands======*/
|
||||
@@ -314,14 +334,15 @@ memberHelper.removeMember = async function (authorId, memberName) {
|
||||
* @param {string | null} [proxy] - The proxy tag of the member.
|
||||
* @param {string | null} [propic] - The profile picture URL of the member.
|
||||
* @param {string | null} [attachmentExpiration] - The expiration date of an uploaded profile picture.
|
||||
* @returns {Promise<{Members, 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.
|
||||
*/
|
||||
memberHelper.addFullMember = async function (authorId, memberName, displayName = null, proxy = null, propic = null, attachmentExpiration = null) {
|
||||
const existingMember = await memberRepo.getMemberByName(authorId, memberName);
|
||||
if (existingMember) {
|
||||
throw new Error(`Can't add ${memberName}. ${enums.err.MEMBER_EXISTS}`);
|
||||
}
|
||||
mh.addFullMember = async function (authorId, memberName, displayName = null, proxy = null, propic = null, attachmentExpiration = null) {
|
||||
await mh.getMemberByName(authorId, memberName).then((member) => {
|
||||
if (member) {
|
||||
throw new Error(`Can't add ${memberName}. ${enums.err.MEMBER_EXISTS}`);
|
||||
}
|
||||
});
|
||||
const errors = [];
|
||||
|
||||
const trimmedName = memberName.trim();
|
||||
@@ -345,34 +366,30 @@ memberHelper.addFullMember = async function (authorId, memberName, displayName =
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let isValidProxy;
|
||||
if (proxy && proxy.length > 0) {
|
||||
try {
|
||||
const proxyExists = await memberHelper.checkIfProxyExists(authorId, proxy);
|
||||
isValidProxy = !proxyExists;
|
||||
}
|
||||
catch(e) {
|
||||
await mh.checkIfProxyExists(authorId, proxy).then(() => {
|
||||
isValidProxy = true;
|
||||
}).catch((e) => {
|
||||
errors.push(`Tried to set proxy to \"${proxy}\". ${e.message}. ${enums.err.SET_TO_NULL}`);
|
||||
isValidProxy = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let isValidPropic, expirationWarning;
|
||||
let isValidPropic;
|
||||
if (propic && propic.length > 0) {
|
||||
try {
|
||||
isValidPropic = await utils.checkImageFormatValidity(propic);
|
||||
expirationWarning = utils.setExpirationWarning(propic, attachmentExpiration);
|
||||
if (expirationWarning) {
|
||||
errors.push(expirationWarning);
|
||||
}
|
||||
}
|
||||
catch(e) {
|
||||
await utils.checkImageFormatValidity(propic).then(() => {
|
||||
isValidPropic = true;
|
||||
}).catch((e) => {
|
||||
errors.push(`Tried to set profile picture to \"${propic}\". ${e.message}. ${enums.err.SET_TO_NULL}`);
|
||||
isValidPropic = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const member = await memberRepo.createMember({
|
||||
if (isValidPropic && attachmentExpiration) {
|
||||
errors.push(mh.setExpirationWarning(attachmentExpiration));
|
||||
}
|
||||
const member = await database.members.create({
|
||||
name: memberName, userid: authorId, displayname: isValidDisplayName ? displayName : null, proxy: isValidProxy ? proxy : null, propic: isValidPropic ? propic : null
|
||||
});
|
||||
|
||||
@@ -387,26 +404,52 @@ memberHelper.addFullMember = async function (authorId, memberName, displayName =
|
||||
* @param {string} memberName - The member to update
|
||||
* @param {string} columnName - The column name to update.
|
||||
* @param {string} value - The value to update to.
|
||||
* @param {string | null} [expirationWarning] - The attachment expiration warning (if any)
|
||||
* @param {string | null} [attachmentExpiration] - The attachment expiration date (if any)
|
||||
* @returns {Promise<string>} A successful update.
|
||||
* @throws {Error} When no member row was updated.
|
||||
*/
|
||||
memberHelper.updateMemberField = async function (authorId, memberName, columnName, value, expirationWarning = null) {
|
||||
const res = await memberRepo.updateMemberField(authorId, memberName, columnName, value);
|
||||
if (res === 0) {
|
||||
throw new Error(`Can't update ${memberName}. ${enums.err.NO_MEMBER}.`);
|
||||
} else {
|
||||
return `Updated ${columnName} for ${memberName} to ${value}${expirationWarning ? `. ${expirationWarning}.` : '.'}`;
|
||||
mh.updateMemberField = async function (authorId, memberName, columnName, value, attachmentExpiration = null) {
|
||||
let fluxerPropicWarning;
|
||||
|
||||
// indicates that an attachment was uploaded on Fluxer directly
|
||||
if (columnName === "propic" && attachmentExpiration) {
|
||||
fluxerPropicWarning = mh.setExpirationWarning(value);
|
||||
}
|
||||
return await database.members.update({[columnName]: value}, {
|
||||
where: {
|
||||
name: {[Op.iLike]: memberName},
|
||||
userid: authorId
|
||||
}
|
||||
}).then((res) => {
|
||||
if (res[0] === 0) {
|
||||
throw new Error(`Can't update ${memberName}. ${enums.err.NO_MEMBER}.`);
|
||||
} else {
|
||||
return `Updated ${columnName} for ${memberName} to ${value}${fluxerPropicWarning ?? ''}.`;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the warning for an expiration date.
|
||||
*
|
||||
* @param {string} expirationString - An expiration date string.
|
||||
* @returns {string} A description of the expiration, interpolating the expiration string.
|
||||
*/
|
||||
mh.setExpirationWarning = function (expirationString) {
|
||||
let expirationDate = new Date(expirationString);
|
||||
if (!isNaN(expirationDate.valueOf())) {
|
||||
expirationDate = expirationDate.toDateString();
|
||||
return `\n**NOTE:** Because this profile picture was uploaded via Fluxer, it will currently expire on *${expirationDate}*. To avoid this, upload the picture to another website like <https://imgbb.com/> and link to it directly`
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the details for a member.
|
||||
*
|
||||
* @param {{Member, string[]}} member - The member object
|
||||
* @param {model} member - The member object
|
||||
* @returns {EmbedBuilder} The member's info.
|
||||
*/
|
||||
memberHelper.getMemberInfo = function (member) {
|
||||
mh.getMemberInfo = function (member) {
|
||||
return new EmbedBuilder()
|
||||
.setTitle(member.name)
|
||||
.setDescription(`Details for ${member.name}`)
|
||||
@@ -427,17 +470,40 @@ memberHelper.getMemberInfo = function (member) {
|
||||
* @returns {Promise<EmbedBuilder>} The info for all members.
|
||||
* @throws {Error} When there are no members for an author.
|
||||
*/
|
||||
memberHelper.getAllMembersInfo = async function (authorId, authorName) {
|
||||
const members = await memberRepo.getMembersByAuthor(authorId);
|
||||
if (members.length === 0) throw Error(enums.err.USER_NO_MEMBERS);
|
||||
const fields = [...members.entries()].map(([index, member]) => ({
|
||||
mh.getAllMembersInfo = async function (authorId, authorName) {
|
||||
const members = await mh.getMembersByAuthor(authorId);
|
||||
if (members == null) throw Error(enums.err.USER_NO_MEMBERS);
|
||||
const fields = [...members.entries()].map(([name, member]) => ({
|
||||
name: member.name, value: `(Proxy: \`${member.proxy ?? "unset"}\`)`, inline: true,
|
||||
}));
|
||||
return new EmbedBuilder()
|
||||
.setTitle(`${fields.length > 25 ? "First 25 m" : "M"}embers for ${authorName}`)
|
||||
.setTitle(`${fields > 25 ? "First 25 m" : "M"}embers for ${authorName}`)
|
||||
.addFields(...fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a member based on the author and proxy tag.
|
||||
*
|
||||
* @async
|
||||
* @param {string} authorId - The author of the message.
|
||||
* @param {string} memberName - The member's name.
|
||||
* @returns {Promise<model>} The member object.
|
||||
*/
|
||||
mh.getMemberByName = async function (authorId, memberName) {
|
||||
return await database.members.findOne({where: {userid: authorId, name: {[Op.iLike]: memberName}}});
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all members belonging to the author.
|
||||
*
|
||||
* @async
|
||||
* @param {string} authorId - The author of the message
|
||||
* @returns {Promise<model[] | null>} The member object array.
|
||||
*/
|
||||
mh.getMembersByAuthor = async function (authorId) {
|
||||
return await database.members.findAll({where: {userid: authorId}});
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if proxy exists for a member.
|
||||
*
|
||||
@@ -446,16 +512,19 @@ memberHelper.getAllMembersInfo = async function (authorId, authorName) {
|
||||
* @returns {Promise<boolean> } Whether the proxy exists.
|
||||
* @throws {Error} When an empty proxy was provided, or no proxy exists.
|
||||
*/
|
||||
memberHelper.checkIfProxyExists = async function (authorId, proxy) {
|
||||
mh.checkIfProxyExists = async function (authorId, proxy) {
|
||||
const splitProxy = proxy.trim().split("text");
|
||||
if (splitProxy.length < 2) throw new Error(enums.err.NO_TEXT_FOR_PROXY);
|
||||
if (!splitProxy[0] && !splitProxy[1]) throw new Error(enums.err.NO_PROXY_WRAPPER);
|
||||
|
||||
const memberList = await memberRepo.getMembersByAuthor(authorId);
|
||||
const proxyExists = memberList.some(member => member.proxy === proxy);
|
||||
if (proxyExists) {
|
||||
throw new Error(enums.err.PROXY_EXISTS);
|
||||
}
|
||||
await mh.getMembersByAuthor(authorId).then((memberList) => {
|
||||
const proxyExists = memberList.some(member => member.proxy === proxy);
|
||||
if (proxyExists) {
|
||||
throw new Error(enums.err.PROXY_EXISTS);
|
||||
}
|
||||
}).catch(e => {
|
||||
throw e
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -464,7 +533,7 @@ memberHelper.checkIfProxyExists = async function (authorId, proxy) {
|
||||
*
|
||||
* @returns {EmbedBuilder } An embed of member commands.
|
||||
*/
|
||||
memberHelper.getMemberCommandInfo = function() {
|
||||
mh.getMemberCommandInfo = function() {
|
||||
const fields = [
|
||||
{name: `**new**`, value: enums.help.NEW, inline: false},
|
||||
{name: `**remove**`, value: enums.help.REMOVE, inline: false},
|
||||
@@ -481,4 +550,4 @@ memberHelper.getMemberCommandInfo = function() {
|
||||
}
|
||||
|
||||
|
||||
module.exports.memberHelper = memberHelper;
|
||||
export const memberHelper = mh;
|
||||
@@ -1,4 +1,4 @@
|
||||
const {memberRepo} = require('../repositories/memberRepo.js');
|
||||
import {memberHelper} from "./memberHelper.js";
|
||||
|
||||
const msgh = {};
|
||||
|
||||
@@ -36,10 +36,11 @@ msgh.parseCommandArgs = function(content, commandName) {
|
||||
* @param {string} authorId - The author of the message.
|
||||
* @param {string} content - The full message content
|
||||
* @param {string | null} [attachmentUrl] - The url for an attachment to the message, if any exists.
|
||||
* @returns {Promise<{model, string, bool}>} The proxy message object.
|
||||
* @returns {{model, string, bool}} The proxy message object.
|
||||
* @throws {Error} If a proxy message is sent with no message or attachment within it.
|
||||
*/
|
||||
msgh.parseProxyTags = async function (authorId, content, attachmentUrl = null){
|
||||
const members = await memberRepo.getMembersByAuthor(authorId);
|
||||
const members = await memberHelper.getMembersByAuthor(authorId);
|
||||
// If an author has no members, no sense in searching for proxy
|
||||
if (members.length === 0) {
|
||||
return;
|
||||
@@ -80,4 +81,4 @@ msgh.returnBufferFromText = function (text) {
|
||||
return {text: text, file: undefined}
|
||||
}
|
||||
|
||||
module.exports.messageHelper = msgh;
|
||||
export const messageHelper = msgh;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
const {enums} = require('../enums');
|
||||
import {enums} from '../enums.js'
|
||||
|
||||
const utils = {};
|
||||
const u = {};
|
||||
|
||||
utils.debounce = function(func, delay) {
|
||||
u.debounce = function(func, delay) {
|
||||
let timeout = null;
|
||||
return function (...args) {
|
||||
clearTimeout(timeout);
|
||||
@@ -15,43 +15,15 @@ utils.debounce = function(func, delay) {
|
||||
*
|
||||
* @async
|
||||
* @param {string} imageUrl - The url of the image
|
||||
* @returns {bool} - Whether the image is in a valid format
|
||||
* @throws {Error} When loading the profile picture from a URL doesn't work, or it fails requirements.
|
||||
*/
|
||||
utils.checkImageFormatValidity = async function (imageUrl) {
|
||||
u.checkImageFormatValidity = async function (imageUrl) {
|
||||
const acceptableImages = ['image/png', 'image/jpg', 'image/jpeg', 'image/webp'];
|
||||
let response, blobFile;
|
||||
try {
|
||||
response = await fetch(imageUrl);
|
||||
}
|
||||
catch(e) {
|
||||
throw new Error(`${enums.err.PROPIC_CANNOT_LOAD}: ${e.message}`);
|
||||
}
|
||||
|
||||
blobFile = await response.blob();
|
||||
if (blobFile.size > 10000000 || !acceptableImages.includes(blobFile.type)) throw new Error(enums.err.PROPIC_FAILS_REQUIREMENTS);
|
||||
|
||||
return true;
|
||||
await fetch(imageUrl).then(r => r.blob()).then(blobFile => {
|
||||
if (blobFile.size > 1000000 || !acceptableImages.includes(blobFile.type)) throw new Error(enums.err.PROPIC_FAILS_REQUIREMENTS);
|
||||
}).catch((error) => {
|
||||
throw new Error(`${enums.err.PROPIC_CANNOT_LOAD}: ${error.message}`);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the warning that a Fluxer-uploaded image will expire.
|
||||
*
|
||||
* @param {string | null} [imgUrl] - An image URL.
|
||||
* @param {string | null} [expirationString] - An expiration date string.
|
||||
* @returns {string | null} A description of the expiration, or null.
|
||||
*/
|
||||
utils.setExpirationWarning = function (imgUrl = null, expirationString = null) {
|
||||
if (imgUrl && imgUrl.startsWith(enums.misc.FLUXER_ATTACHMENT_URL)) {
|
||||
return enums.misc.ATTACHMENT_EXPIRATION_WARNING;
|
||||
}
|
||||
else if (expirationString) {
|
||||
let expirationDate = new Date(expirationString);
|
||||
if (!isNaN(expirationDate.valueOf())) {
|
||||
return `${enums.misc.ATTACHMENT_EXPIRATION_WARNING}. Expiration date: *${expirationString}*.`;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
module.exports.utils = utils;
|
||||
export const utils = u;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
const {messageHelper} = require("./messageHelper.js");
|
||||
const {Webhook, Channel, Message, Client} = require('@fluxerjs/core');
|
||||
const {enums} = require("../enums.js");
|
||||
import {messageHelper} from "./messageHelper.js";
|
||||
import {Webhook, Channel, Message, Client} from '@fluxerjs/core';
|
||||
import {enums} from "../enums.js";
|
||||
|
||||
const webhookHelper = {};
|
||||
const wh = {};
|
||||
|
||||
const name = 'PluralFlux Proxy Webhook';
|
||||
|
||||
@@ -13,9 +13,9 @@ const name = 'PluralFlux Proxy Webhook';
|
||||
* @param {Message} message - The full message object.
|
||||
* @throws {Error} When the proxy message is not in a server.
|
||||
*/
|
||||
webhookHelper.sendMessageAsMember = async function(client, message) {
|
||||
wh.sendMessageAsMember = async function(client, message) {
|
||||
const attachmentUrl = message.attachments.size > 0 ? message.attachments.first().url : null;
|
||||
const proxyMatch = await messageHelper.parseProxyTags(message.author.id, message.content, attachmentUrl);
|
||||
const proxyMatch = await messageHelper.parseProxyTags(message.author.id, message.content, attachmentUrl).catch(e =>{throw e});
|
||||
// If the message doesn't match a proxy, just return.
|
||||
if (!proxyMatch || !proxyMatch.member || (proxyMatch.message.length === 0 && !proxyMatch.hasAttachment) ) {
|
||||
return;
|
||||
@@ -27,7 +27,7 @@ webhookHelper.sendMessageAsMember = async function(client, message) {
|
||||
if (proxyMatch.hasAttachment) {
|
||||
return await message.reply(`${enums.misc.ATTACHMENT_SENT_BY} ${proxyMatch.member.displayname ?? proxyMatch.member.name}`)
|
||||
}
|
||||
await webhookHelper.replaceMessage(client, message, proxyMatch.message, proxyMatch.member);
|
||||
await wh.replaceMessage(client, message, proxyMatch.message, proxyMatch.member).catch(e =>{throw e});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,23 +39,24 @@ webhookHelper.sendMessageAsMember = async function(client, message) {
|
||||
* @param {model} member - A member object from the database.
|
||||
* @throws {Error} When there's no message to send.
|
||||
*/
|
||||
webhookHelper.replaceMessage = async function(client, message, text, member) {
|
||||
wh.replaceMessage = async function(client, message, text, member) {
|
||||
// attachment logic is not relevant yet, text length will always be over 0 right now
|
||||
if (text.length > 0 || message.attachments.size > 0) {
|
||||
const channel = client.channels.get(message.channelId);
|
||||
const webhook = await webhookHelper.getOrCreateWebhook(client, channel);
|
||||
const webhook = await wh.getOrCreateWebhook(client, channel).catch((e) =>{throw e});
|
||||
const username = member.displayname ?? member.name;
|
||||
if (text.length <= 2000) {
|
||||
await webhook.send({content: text, username: username, avatar_url: member.propic})
|
||||
}
|
||||
else if (text.length > 2000) {
|
||||
const returnedBuffer = messageHelper.returnBufferFromText(text);
|
||||
await webhook.send({content: returnedBuffer.text, username: username, avatar_url: member.propic, files: [{ name: 'text.txt', data: returnedBuffer.file }]
|
||||
})
|
||||
if (text.length > 0) {
|
||||
await webhook.send({content: text, username: username, avatar_url: member.propic}).catch(async(e) => {
|
||||
const returnedBuffer = messageHelper.returnBufferFromText(text);
|
||||
await webhook.send({content: returnedBuffer.text, username: username, avatar_url: member.propic, files: [{ name: 'text.txt', data: returnedBuffer.file }]
|
||||
})
|
||||
console.error(e);
|
||||
});
|
||||
}
|
||||
if (message.attachments.size > 0) {
|
||||
// Not implemented yet
|
||||
}
|
||||
|
||||
await message.delete();
|
||||
}
|
||||
}
|
||||
@@ -68,10 +69,10 @@ webhookHelper.replaceMessage = async function(client, message, text, member) {
|
||||
* @returns {Webhook} A webhook object.
|
||||
* @throws {Error} When no webhooks are allowed in the channel.
|
||||
*/
|
||||
webhookHelper.getOrCreateWebhook = async function(client, channel) {
|
||||
wh.getOrCreateWebhook = async function(client, channel) {
|
||||
// If channel doesn't allow webhooks
|
||||
if (!channel?.createWebhook) throw new Error(enums.err.NO_WEBHOOKS_ALLOWED);
|
||||
let webhook = await webhookHelper.getWebhook(client, channel)
|
||||
let webhook = await wh.getWebhook(client, channel).catch((e) =>{throw e});
|
||||
if (!webhook) {
|
||||
webhook = await channel.createWebhook({name: name});
|
||||
}
|
||||
@@ -85,12 +86,18 @@ webhookHelper.getOrCreateWebhook = async function(client, channel) {
|
||||
* @param {Channel} channel - The channel the message was sent in.
|
||||
* @returns {Webhook} A webhook object.
|
||||
*/
|
||||
webhookHelper.getWebhook = async function(client, channel) {
|
||||
wh.getWebhook = async function(client, channel) {
|
||||
const channelWebhooks = await channel?.fetchWebhooks() ?? [];
|
||||
if (channelWebhooks.length === 0) {
|
||||
return;
|
||||
}
|
||||
return channelWebhooks.find((webhook) => webhook.name === name);
|
||||
let pf_webhook;
|
||||
channelWebhooks.forEach((webhook) => {
|
||||
if (webhook.name === name) {
|
||||
pf_webhook = webhook;
|
||||
}
|
||||
})
|
||||
return pf_webhook;
|
||||
}
|
||||
|
||||
module.exports.webhookHelper = webhookHelper;
|
||||
export const webhookHelper = wh;
|
||||
@@ -1,74 +0,0 @@
|
||||
const Member = require("../../database/entity/Member");
|
||||
const { AppDataSource } = require("../../database/data-source");
|
||||
const {ILike} = require("typeorm");
|
||||
const members = AppDataSource.getRepository(Member.Member)
|
||||
|
||||
const memberRepo = {};
|
||||
/**
|
||||
* Gets a member based on the author and proxy tag.
|
||||
*
|
||||
* @async
|
||||
* @param {string} authorId - The author of the message.
|
||||
* @param {string} memberName - The member's name.
|
||||
* @returns {Promise<Member | null>} The member object or null if not found.
|
||||
*/
|
||||
memberRepo.getMemberByName = async function (authorId, memberName) {
|
||||
return await members.findOne({where: {userid: authorId, name: ILike(memberName)}});
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all members belonging to the author.
|
||||
*
|
||||
* @async
|
||||
* @param {string} authorId - The author of the message
|
||||
* @returns {Promise<Member[]>} The member object array.
|
||||
*/
|
||||
memberRepo.getMembersByAuthor = async function (authorId) {
|
||||
return await members.findBy({userid: authorId});
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a member.
|
||||
*
|
||||
* @async
|
||||
* @param {string} authorId - The author of the message
|
||||
* @param {string} memberName - The name of the member to remove
|
||||
* @returns {Promise<number>} Number of results removed.
|
||||
*/
|
||||
memberRepo.removeMember = async function (authorId, memberName) {
|
||||
const deleted = await members.delete({ name: ILike(memberName), userid: authorId })
|
||||
return deleted.affected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a member with full details.
|
||||
*
|
||||
* @async
|
||||
* @param {{name: string, userid: string, displayname: (string|null), proxy: (string|null), propic: (string|null)}} createObj - Object with parameters in it
|
||||
* @returns {Promise<Member>} A successful inserted object.
|
||||
*/
|
||||
memberRepo.createMember = async function (createObj) {
|
||||
return await members.save({
|
||||
name: createObj.name, userid: createObj.userid, displayname: createObj.displayname, proxy: createObj.proxy, propic: createObj.propic
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates one fields for a member in the database.
|
||||
*
|
||||
* @async
|
||||
* @param {string} authorId - The author of the message
|
||||
* @param {string} memberName - The member to update
|
||||
* @param {string} columnName - The column name to update.
|
||||
* @param {string} value - The value to update to.
|
||||
* @returns {Promise<number>} A successful update.
|
||||
*/
|
||||
memberRepo.updateMemberField = async function (authorId, memberName, columnName, value) {
|
||||
const updated = await members.update({
|
||||
name: ILike(memberName),
|
||||
userid: authorId
|
||||
}, {[columnName]: value})
|
||||
return updated.affected;
|
||||
}
|
||||
|
||||
module.exports.memberRepo = memberRepo;
|
||||
@@ -56,15 +56,6 @@ jest.mock("../src/commands.js", () => {
|
||||
}
|
||||
})
|
||||
|
||||
jest.mock('../database/data-source.ts', () => {
|
||||
return {
|
||||
AppDataSource: {
|
||||
isInitialized: false,
|
||||
initialize: jest.fn().mockResolvedValue()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
const {Client, Events} = require('@fluxerjs/core');
|
||||
const {messageHelper} = require("../src/helpers/messageHelper.js");
|
||||
@@ -74,7 +65,6 @@ const {webhookHelper} = require("../src/helpers/webhookHelper.js");
|
||||
|
||||
const {utils} = require("../src/helpers/utils.js");
|
||||
let {handleMessageCreate, client} = require("../src/bot.js");
|
||||
const {login} = require("../src/bot");
|
||||
|
||||
describe('bot', () => {
|
||||
beforeEach(() => {
|
||||
@@ -84,7 +74,7 @@ describe('bot', () => {
|
||||
|
||||
describe('handleMessageCreate', () => {
|
||||
|
||||
test('on message creation, if message is from bot, return', async () => {
|
||||
test('on message creation, if message is from bot, return', () => {
|
||||
// Arrange
|
||||
const message = {
|
||||
author: {
|
||||
@@ -92,11 +82,27 @@ describe('bot', () => {
|
||||
}
|
||||
}
|
||||
// Act
|
||||
const res = await handleMessageCreate(message);
|
||||
expect(res).toBeUndefined();
|
||||
return handleMessageCreate(message).then((res) => {
|
||||
expect(res).toBe(undefined);
|
||||
});
|
||||
})
|
||||
|
||||
test("if message doesn't start with bot prefix, call sendMessageAsMember", async () => {
|
||||
test('on message creation, if message is empty, return', () => {
|
||||
// Arrange
|
||||
const message = {
|
||||
content: " ",
|
||||
author: {
|
||||
bot: false
|
||||
}
|
||||
}
|
||||
// Act
|
||||
return handleMessageCreate(message).then((res) => {
|
||||
// Assert
|
||||
expect(res).toBe(undefined);
|
||||
});
|
||||
})
|
||||
|
||||
test("if message doesn't start with bot prefix, call sendMessageAsMember", () => {
|
||||
// Arrange
|
||||
webhookHelper.sendMessageAsMember.mockResolvedValue();
|
||||
const message = {
|
||||
@@ -106,32 +112,38 @@ describe('bot', () => {
|
||||
}
|
||||
}
|
||||
// Act
|
||||
const res = await handleMessageCreate(message);
|
||||
// Assert
|
||||
expect(webhookHelper.sendMessageAsMember).toHaveBeenCalledTimes(1);
|
||||
expect(webhookHelper.sendMessageAsMember).toHaveBeenCalledWith(client, message)
|
||||
return handleMessageCreate(message).then(() => {
|
||||
// Assert
|
||||
expect(webhookHelper.sendMessageAsMember).toHaveBeenCalledTimes(1);
|
||||
expect(webhookHelper.sendMessageAsMember).toHaveBeenCalledWith(client, message)
|
||||
});
|
||||
})
|
||||
|
||||
test("if sendMessageAsMember returns error, catch and log error", async () => {
|
||||
test("if sendMessageAsMember returns error, log error", () => {
|
||||
// Arrange
|
||||
webhookHelper.sendMessageAsMember.mockRejectedValue(new Error("error"));
|
||||
webhookHelper.sendMessageAsMember.mockImplementation(() => {
|
||||
throw Error("error")
|
||||
});
|
||||
const message = {
|
||||
content: "hello",
|
||||
author: {
|
||||
bot: false
|
||||
}
|
||||
}
|
||||
jest.spyOn(global.console, 'error').mockImplementation(() => {});
|
||||
jest.mock('console', () => {
|
||||
return {error: jest.fn()}
|
||||
})
|
||||
// Act
|
||||
await handleMessageCreate(message);
|
||||
// Assert
|
||||
expect(webhookHelper.sendMessageAsMember).toHaveBeenCalledTimes(1);
|
||||
expect(webhookHelper.sendMessageAsMember).toHaveBeenCalledWith(client, message)
|
||||
expect(console.error).toHaveBeenCalledTimes(1);
|
||||
expect(console.error).toHaveBeenCalledWith(new Error('error'));
|
||||
return handleMessageCreate(message).catch(() => {
|
||||
// Assert
|
||||
expect(webhookHelper.sendMessageAsMember).toHaveBeenCalledTimes(1);
|
||||
expect(webhookHelper.sendMessageAsMember).toHaveBeenCalledWith(client, message)
|
||||
expect(console.error).toHaveBeenCalledTimes(1);
|
||||
expect(console.error).toHaveBeenCalledWith(new Error('error'))
|
||||
});
|
||||
})
|
||||
|
||||
test("if no command after prefix, return correct enum", async () => {
|
||||
test("if no command after prefix, return correct enum", () => {
|
||||
// Arrange
|
||||
const message = {
|
||||
content: "pf;",
|
||||
@@ -141,14 +153,15 @@ describe('bot', () => {
|
||||
reply: jest.fn()
|
||||
}
|
||||
// Act
|
||||
await handleMessageCreate(message);
|
||||
// Assert
|
||||
expect(message.reply).toHaveBeenCalledTimes(1);
|
||||
expect(message.reply).toHaveBeenCalledWith(enums.help.SHORT_DESC_PLURALFLUX);
|
||||
expect(webhookHelper.sendMessageAsMember).not.toHaveBeenCalled();
|
||||
return handleMessageCreate(message).then(() => {
|
||||
// Assert
|
||||
expect(message.reply).toHaveBeenCalledTimes(1);
|
||||
expect(message.reply).toHaveBeenCalledWith(enums.help.SHORT_DESC_PLURALFLUX);
|
||||
expect(webhookHelper.sendMessageAsMember).not.toHaveBeenCalled();
|
||||
});
|
||||
})
|
||||
|
||||
test("if command after prefix, call parseCommandArgs and commandsMap.get", async () => {
|
||||
test("if command after prefix, call parseCommandArgs and commandsMap.get", () => {
|
||||
// Arrange
|
||||
const message = {
|
||||
content: "pf;help",
|
||||
@@ -162,16 +175,17 @@ describe('bot', () => {
|
||||
}
|
||||
commands.commandsMap.get = jest.fn().mockReturnValue(command);
|
||||
// Act
|
||||
await handleMessageCreate(message);
|
||||
// Assert
|
||||
expect(messageHelper.parseCommandArgs).toHaveBeenCalledTimes(1);
|
||||
expect(messageHelper.parseCommandArgs).toHaveBeenCalledWith('pf;help', 'help');
|
||||
expect(commands.commandsMap.get).toHaveBeenCalledTimes(1);
|
||||
expect(commands.commandsMap.get).toHaveBeenCalledWith('help');
|
||||
expect(webhookHelper.sendMessageAsMember).not.toHaveBeenCalled();
|
||||
return handleMessageCreate(message).then(() => {
|
||||
// Assert
|
||||
expect(messageHelper.parseCommandArgs).toHaveBeenCalledTimes(1);
|
||||
expect(messageHelper.parseCommandArgs).toHaveBeenCalledWith('pf;help', 'help');
|
||||
expect(commands.commandsMap.get).toHaveBeenCalledTimes(1);
|
||||
expect(commands.commandsMap.get).toHaveBeenCalledWith('help');
|
||||
expect(webhookHelper.sendMessageAsMember).not.toHaveBeenCalled();
|
||||
});
|
||||
})
|
||||
|
||||
test('if commands.commandsMap.get returns undefined, call aliasesMap.get and commandsMap.get again with that value', async () => {
|
||||
test('if commands.commandsMap.get returns undefined, call aliasesMap.get and commandsMap.get again with that value', () => {
|
||||
// Arrange
|
||||
const message = {
|
||||
content: "pf;m",
|
||||
@@ -186,17 +200,18 @@ describe('bot', () => {
|
||||
commands.commandsMap.get = jest.fn().mockReturnValueOnce();
|
||||
commands.aliasesMap.get = jest.fn().mockReturnValueOnce(mockAlias);
|
||||
// Act
|
||||
await handleMessageCreate(message);
|
||||
// Assert
|
||||
expect(commands.commandsMap.get).toHaveBeenCalledTimes(2);
|
||||
expect(commands.commandsMap.get).toHaveBeenNthCalledWith(1, 'm');
|
||||
expect(commands.commandsMap.get).toHaveBeenNthCalledWith(2, 'member');
|
||||
expect(commands.aliasesMap.get).toHaveBeenCalledTimes(1);
|
||||
expect(commands.aliasesMap.get).toHaveBeenCalledWith('m');
|
||||
return handleMessageCreate(message).then(() => {
|
||||
// Assert
|
||||
expect(commands.commandsMap.get).toHaveBeenCalledTimes(2);
|
||||
expect(commands.commandsMap.get).toHaveBeenNthCalledWith(1, 'm');
|
||||
expect(commands.commandsMap.get).toHaveBeenNthCalledWith(2, 'member');
|
||||
expect(commands.aliasesMap.get).toHaveBeenCalledTimes(1);
|
||||
expect(commands.aliasesMap.get).toHaveBeenCalledWith('m');
|
||||
});
|
||||
})
|
||||
|
||||
|
||||
test('if aliasesMap.get returns undefined, do not call commandsMap again', async () => {
|
||||
test('if aliasesMap.get returns undefined, do not call commandsMap again', () => {
|
||||
// Arrange
|
||||
const message = {
|
||||
content: "pf;m",
|
||||
@@ -211,13 +226,16 @@ describe('bot', () => {
|
||||
commands.commandsMap.get = jest.fn().mockReturnValueOnce();
|
||||
commands.aliasesMap.get = jest.fn().mockReturnValueOnce();
|
||||
// Act
|
||||
await handleMessageCreate(message);
|
||||
// Assert
|
||||
expect(commands.aliasesMap.get).toHaveBeenCalledTimes(1);
|
||||
expect(commands.aliasesMap.get).toHaveBeenCalledWith('m');
|
||||
return handleMessageCreate(message).then(() => {
|
||||
// Assert
|
||||
expect(commands.commandsMap.get).toHaveBeenCalledTimes(1);
|
||||
expect(commands.commandsMap.get).toHaveBeenNthCalledWith(1, 'm');
|
||||
expect(commands.aliasesMap.get).toHaveBeenCalledTimes(1);
|
||||
expect(commands.aliasesMap.get).toHaveBeenCalledWith('m');
|
||||
});
|
||||
})
|
||||
|
||||
test("if command exists, call command.execute", async () => {
|
||||
test("if command exists, call command.execute", () => {
|
||||
// Arrange
|
||||
const message = {
|
||||
content: "pf;member test",
|
||||
@@ -234,60 +252,64 @@ describe('bot', () => {
|
||||
command.execute = jest.fn().mockResolvedValue();
|
||||
|
||||
// Act
|
||||
await handleMessageCreate(message)
|
||||
// Assert
|
||||
expect(command.execute).toHaveBeenCalledTimes(1);
|
||||
expect(command.execute).toHaveBeenCalledWith(message, ['test']);
|
||||
expect(webhookHelper.sendMessageAsMember).not.toHaveBeenCalled();
|
||||
});
|
||||
})
|
||||
|
||||
test("if command.execute returns error, log error", async () => {
|
||||
// Arrange
|
||||
const command = {
|
||||
execute: jest.fn()
|
||||
}
|
||||
commands.commandsMap.get = jest.fn().mockReturnValue(command);
|
||||
command.execute.mockRejectedValue(new Error("error"));
|
||||
const message = {
|
||||
content: "pf;member test",
|
||||
author: {
|
||||
bot: false
|
||||
},
|
||||
reply: jest.fn()
|
||||
}
|
||||
jest.spyOn(global.console, 'error').mockImplementation(() => {
|
||||
return handleMessageCreate(message).then(() => {
|
||||
// Assert
|
||||
expect(command.execute).toHaveBeenCalledTimes(1);
|
||||
expect(command.execute).toHaveBeenCalledWith(message, ['test']);
|
||||
expect(webhookHelper.sendMessageAsMember).not.toHaveBeenCalled();
|
||||
});
|
||||
})
|
||||
|
||||
test("if command.execute returns error, log error", () => {
|
||||
// Arrange
|
||||
const command = {
|
||||
execute: jest.fn()
|
||||
}
|
||||
commands.get = jest.fn().mockReturnValue(command);
|
||||
command.execute.mockImplementation(() => {
|
||||
throw Error("error")
|
||||
});
|
||||
const message = {
|
||||
content: "pf;member test",
|
||||
author: {
|
||||
bot: false
|
||||
},
|
||||
reply: jest.fn()
|
||||
}
|
||||
jest.mock('console', () => {
|
||||
return {error: jest.fn()}
|
||||
})
|
||||
// Act
|
||||
return handleMessageCreate(message).catch(() => {
|
||||
// Assert
|
||||
expect(console.error).toHaveBeenCalledTimes(1);
|
||||
expect(console.error).toHaveBeenCalledWith(new Error('error'))
|
||||
});
|
||||
})
|
||||
|
||||
test("if command does not exist, return correct enum", () => {
|
||||
// Arrange
|
||||
commands.commandsMap.get = jest.fn().mockReturnValue();
|
||||
commands.aliasesMap.get = jest.fn().mockReturnValue();
|
||||
const message = {
|
||||
content: "pf;asdfjlas",
|
||||
author: {
|
||||
bot: false
|
||||
},
|
||||
reply: jest.fn()
|
||||
}
|
||||
// Act
|
||||
return handleMessageCreate(message).then(() => {
|
||||
// Assert
|
||||
expect(message.reply).toHaveBeenCalledWith(enums.err.COMMAND_NOT_RECOGNIZED);
|
||||
expect(message.reply).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
})
|
||||
// Act
|
||||
await handleMessageCreate(message);
|
||||
// Assert
|
||||
expect(console.error).toHaveBeenCalledTimes(1);
|
||||
expect(console.error).toHaveBeenCalledWith(new Error('error'))
|
||||
})
|
||||
|
||||
test("if command does not exist, return correct enum", async () => {
|
||||
// Arrange
|
||||
commands.commandsMap.get = jest.fn().mockReturnValue();
|
||||
commands.aliasesMap.get = jest.fn().mockReturnValue();
|
||||
const message = {
|
||||
content: "pf;asdfjlas",
|
||||
author: {
|
||||
bot: false
|
||||
},
|
||||
reply: jest.fn()
|
||||
}
|
||||
test('calls client.login with correct argument', () => {
|
||||
// Act
|
||||
await handleMessageCreate(message);
|
||||
// Assert
|
||||
expect(message.reply).toHaveBeenCalledWith(enums.err.COMMAND_NOT_RECOGNIZED);
|
||||
expect(message.reply).toHaveBeenCalledTimes(1);
|
||||
})
|
||||
|
||||
test('login calls client.login with correct argument', async () => {
|
||||
// Arrange
|
||||
client.login = jest.fn().mockResolvedValue();
|
||||
// Act
|
||||
await login();
|
||||
// Assert
|
||||
expect(client.login).toHaveBeenCalledTimes(1);
|
||||
expect(client.login).toHaveBeenCalledWith(process.env.FLUXER_BOT_TOKEN)
|
||||
|
||||
@@ -24,8 +24,11 @@ jest.mock('../src/helpers/importHelper.js', () => {
|
||||
}
|
||||
}
|
||||
})
|
||||
jest.mock('console', () => {
|
||||
return {error: jest.fn()}
|
||||
})
|
||||
|
||||
import {messageHelper} from "../src/helpers/messageHelper.js";
|
||||
import {messageHelper, prefix} from "../src/helpers/messageHelper.js";
|
||||
|
||||
import {memberHelper} from "../src/helpers/memberHelper.js";
|
||||
import {EmbedBuilder} from "@fluxerjs/core";
|
||||
@@ -37,169 +40,139 @@ describe('commands', () => {
|
||||
const authorId = '123';
|
||||
const discriminator = '123';
|
||||
const username = 'somePerson'
|
||||
const attachmentUrl = 'oya.json';
|
||||
const attachmentUrl = 'oya.png';
|
||||
const attachmentExpiration = new Date('2026-01-01').toDateString();
|
||||
let message;
|
||||
const message = {
|
||||
author: {
|
||||
username: username,
|
||||
id: authorId,
|
||||
discriminator: discriminator,
|
||||
},
|
||||
attachments: {
|
||||
size: 1,
|
||||
first: jest.fn().mockImplementation(() => ({
|
||||
expires_at: attachmentExpiration,
|
||||
url: attachmentUrl
|
||||
}))
|
||||
},
|
||||
reply: jest.fn().mockResolvedValue(),
|
||||
}
|
||||
const args = ['new']
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
jest.resetModules();
|
||||
jest.clearAllMocks();
|
||||
message = {
|
||||
author: {
|
||||
username: username,
|
||||
id: authorId,
|
||||
discriminator: discriminator,
|
||||
},
|
||||
attachments: {
|
||||
size: 1,
|
||||
first: jest.fn().mockImplementation(() => {
|
||||
return {
|
||||
url: attachmentUrl,
|
||||
expires_at: attachmentExpiration
|
||||
}
|
||||
})
|
||||
},
|
||||
reply: jest.fn().mockResolvedValue(),
|
||||
content: 'pf;import'
|
||||
}
|
||||
})
|
||||
|
||||
describe('memberCommand', () => {
|
||||
|
||||
|
||||
test('calls parseMemberCommand with the correct arguments', async () => {
|
||||
test('calls parseMemberCommand with the correct arguments', () => {
|
||||
// Arrange
|
||||
memberHelper.parseMemberCommand = jest.fn().mockResolvedValue("parsed command");
|
||||
// Act
|
||||
await commands.memberCommand(message, args)
|
||||
// Assert
|
||||
expect(memberHelper.parseMemberCommand).toHaveBeenCalledTimes(1);
|
||||
expect(memberHelper.parseMemberCommand).toHaveBeenCalledWith(authorId, `${username}#${discriminator}`, args, attachmentUrl, attachmentExpiration);
|
||||
});
|
||||
})
|
||||
return commands.memberCommand(message, args).then(() => {
|
||||
expect(memberHelper.parseMemberCommand).toHaveBeenCalledTimes(1);
|
||||
expect(memberHelper.parseMemberCommand).toHaveBeenCalledWith(authorId, `${username}#${discriminator}`, args, attachmentUrl, attachmentExpiration);
|
||||
});
|
||||
})
|
||||
|
||||
test('if parseMemberCommand returns error, log error and reply with error', async () => {
|
||||
// Arrange
|
||||
memberHelper.parseMemberCommand = jest.fn().mockRejectedValue(new Error('error'));
|
||||
// Act
|
||||
await commands.memberCommand(message, args)
|
||||
// Assert
|
||||
expect(message.reply).toHaveBeenCalledTimes(1);
|
||||
expect(message.reply).toHaveBeenCalledWith('error');
|
||||
});
|
||||
test('if parseMemberCommand returns error, log error and reply with error', () => {
|
||||
// Arrange
|
||||
memberHelper.parseMemberCommand = jest.fn().mockImplementation(() => {throw new Error('error')});
|
||||
// Act
|
||||
return commands.memberCommand(message, args).catch(() => {
|
||||
expect(message.reply).toHaveBeenCalledTimes(1);
|
||||
expect(message.reply).toHaveBeenCalledWith('error');
|
||||
expect(console.error).toHaveBeenCalledWith(new Error('error'));
|
||||
});
|
||||
})
|
||||
|
||||
test('if parseMemberCommand returns embed, reply with embed', async () => {
|
||||
// Arrange
|
||||
const embed = new EmbedBuilder();
|
||||
memberHelper.parseMemberCommand = jest.fn().mockResolvedValue(embed);
|
||||
// Act
|
||||
await commands.memberCommand(message, args);
|
||||
expect(message.reply).toHaveBeenCalledTimes(1);
|
||||
expect(message.reply).toHaveBeenCalledWith({embeds: [embed]})
|
||||
})
|
||||
test('if parseMemberCommand returns embed, reply with embed', () => {
|
||||
// Arrange
|
||||
const embed = new EmbedBuilder();
|
||||
memberHelper.parseMemberCommand = jest.fn().mockResolvedValue();
|
||||
// Act
|
||||
return commands.memberCommand(message, args).catch(() => {
|
||||
// Assert
|
||||
expect(message.reply).toHaveBeenCalledTimes(1);
|
||||
expect(message.reply).toHaveBeenCalledWith({embeds: [embed]})
|
||||
});
|
||||
})
|
||||
|
||||
test('if parseMemberCommand returns object, reply with embed and content', async () => {
|
||||
// Arrange
|
||||
const reply = {
|
||||
errors: ['error', 'error2'],
|
||||
success: 'success',
|
||||
embed: {title: 'hi'}
|
||||
}
|
||||
const expected = {
|
||||
content: `success \n\n${enums.err.ERRORS_OCCURRED}\n- error\n- error2`,
|
||||
embeds: [reply.embed]
|
||||
}
|
||||
console.log(expected)
|
||||
memberHelper.parseMemberCommand = jest.fn().mockResolvedValue(reply);
|
||||
// Act
|
||||
await commands.memberCommand(message, args);
|
||||
// Assert
|
||||
expect(message.reply).toHaveBeenCalledTimes(1);
|
||||
expect(message.reply).toHaveBeenCalledWith(expected)
|
||||
test('if parseMemberCommand returns object, reply with embed and content', () => {
|
||||
// Arrange
|
||||
const reply = {
|
||||
errors: ['error', 'error2'],
|
||||
success: 'success',
|
||||
embed: {}
|
||||
}
|
||||
memberHelper.parseMemberCommand = jest.fn().mockResolvedValue(reply);
|
||||
// Act
|
||||
return commands.memberCommand(message, args).catch(() => {
|
||||
// Assert
|
||||
expect(message.reply).toHaveBeenCalledTimes(1);
|
||||
expect(message.reply).toHaveBeenCalledWith({content: `success\n\n${enums.err.ERRORS_OCCURRED}\n\nerror\nerror2}`, embeds: [reply.embed]})
|
||||
});
|
||||
})
|
||||
})
|
||||
|
||||
describe('importCommand', () => {
|
||||
test('if message includes --help and no attachmentURL, return help message', async () => {
|
||||
// Arrange
|
||||
test('if message includes --help and no attachmentURL, return help message', () => {
|
||||
const args = ["--help"];
|
||||
message.content = "pf;import --help";
|
||||
message.attachments.size = 0;
|
||||
// Act
|
||||
await commands.importCommand(message, args)
|
||||
// Assert
|
||||
expect(message.reply).toHaveBeenCalledTimes(1);
|
||||
expect(message.reply).toHaveBeenCalledWith(enums.help.IMPORT);
|
||||
expect(importHelper.pluralKitImport).not.toHaveBeenCalled();
|
||||
return commands.importCommand(message, args).then(() => {
|
||||
expect(message.reply).toHaveBeenCalledTimes(1);
|
||||
expect(message.reply).toHaveBeenCalledWith(enums.help.IMPORT);
|
||||
expect(importHelper.pluralKitImport).not.toHaveBeenCalled();
|
||||
})
|
||||
})
|
||||
|
||||
test('if no args and no attachmentURL, return help message', async () => {
|
||||
// Arrange
|
||||
test('if no args and no attachmentURL, return help message', () => {
|
||||
const args = [""];
|
||||
message.content = 'pf;import'
|
||||
message.attachments.size = 0;
|
||||
// Act
|
||||
await commands.importCommand(message, args)
|
||||
// Assert
|
||||
expect(message.reply).toHaveBeenCalledTimes(1);
|
||||
expect(message.reply).toHaveBeenCalledWith(enums.help.IMPORT);
|
||||
expect(importHelper.pluralKitImport).not.toHaveBeenCalled();
|
||||
return commands.importCommand(message, args).then(() => {
|
||||
expect(message.reply).toHaveBeenCalledTimes(1);
|
||||
expect(message.reply).toHaveBeenCalledWith(enums.help.IMPORT);
|
||||
expect(importHelper.pluralKitImport).not.toHaveBeenCalled();
|
||||
})
|
||||
})
|
||||
|
||||
test('if attachment URL, call pluralKitImport with correct arguments', async () => {
|
||||
// Arrange
|
||||
test('if attachment URL, call pluralKitImport with correct arguments', () => {
|
||||
const args = [""];
|
||||
message.content = 'pf;import';
|
||||
message.content = 'pf;import'
|
||||
importHelper.pluralKitImport = jest.fn().mockResolvedValue('success');
|
||||
// Act
|
||||
await commands.importCommand(message, args);
|
||||
// Assert
|
||||
expect(message.reply).toHaveBeenCalledTimes(1);
|
||||
expect(message.reply).toHaveBeenCalledWith('success');
|
||||
expect(importHelper.pluralKitImport).toHaveBeenCalledTimes(1);
|
||||
expect(importHelper.pluralKitImport).toHaveBeenCalledWith(authorId, attachmentUrl);
|
||||
return commands.importCommand(message, args).then(() => {
|
||||
expect(message.reply).toHaveBeenCalledTimes(1);
|
||||
expect(message.reply).toHaveBeenCalledWith('success');
|
||||
expect(importHelper.pluralKitImport).toHaveBeenCalledTimes(1);
|
||||
expect(importHelper.pluralKitImport).toHaveBeenCalledWith(authorId, attachmentUrl);
|
||||
})
|
||||
})
|
||||
|
||||
test('if pluralKitImport returns aggregate errors with length <= 2000, send errors.', async () => {
|
||||
test('if pluralKitImport returns aggregate errors, send errors.', () => {
|
||||
const args = [""];
|
||||
message.content = 'pf;import'
|
||||
importHelper.pluralKitImport = jest.fn().mockImplementation(() => {throw new AggregateError(['error1', 'error2'], 'errors')});
|
||||
return commands.importCommand(message, args).catch(() => {
|
||||
expect(message.reply).toHaveBeenCalledTimes(1);
|
||||
expect(message.reply).toHaveBeenCalledWith(`errors. \n\n${enums.err.ERRORS_OCCURRED}\n\nerror1\nerror2`);
|
||||
})
|
||||
})
|
||||
|
||||
test('if message.reply throws error, call returnBufferFromText and message.reply again.', () => {
|
||||
// Arrange
|
||||
const args = [""];
|
||||
message.content = 'pf;import'
|
||||
importHelper.pluralKitImport = jest.fn().mockRejectedValue(new AggregateError(['error1', 'error2'], 'errors'));
|
||||
// Act
|
||||
await commands.importCommand(message, args);
|
||||
// Assert
|
||||
expect(message.reply).toHaveBeenCalledTimes(1);
|
||||
expect(message.reply).toHaveBeenCalledWith(`errors.\n\n${enums.err.ERRORS_OCCURRED}\n\nerror1\nerror2`);
|
||||
})
|
||||
|
||||
test('if pluralKitImport returns aggregate errors with length > 2000, call returnBufferFromText and message.reply.', async () => {
|
||||
// Arrange
|
||||
const args = [""];
|
||||
const text = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbb";
|
||||
const file = Buffer.from(text, 'utf-8');
|
||||
const returnedBuffer = {text: 'bbbb', file: file};
|
||||
const expected = {content: returnedBuffer.text, files: [{name: 'text.txt', data: returnedBuffer.file}]};
|
||||
|
||||
importHelper.pluralKitImport = jest.fn().mockRejectedValue(new AggregateError([text, 'error2'], 'errors'));
|
||||
messageHelper.returnBufferFromText = jest.fn().mockReturnValue(returnedBuffer);
|
||||
// Act
|
||||
await commands.importCommand(message, args);
|
||||
// Assert
|
||||
expect(message.reply).toHaveBeenCalledTimes(1);
|
||||
expect(message.reply).toHaveBeenCalledWith(expected);
|
||||
})
|
||||
|
||||
test('if pluralKitImport returns one error, reply with error and log it', async () => {
|
||||
// Arrange
|
||||
importHelper.pluralKitImport = jest.fn().mockRejectedValue(new Error('error'));
|
||||
jest.spyOn(global.console, 'error').mockImplementation(() => {})
|
||||
// Act
|
||||
await commands.importCommand(message, args);
|
||||
expect(message.reply).toHaveBeenCalledTimes(1);
|
||||
expect(message.reply).toHaveBeenCalledWith('error');
|
||||
expect(console.error).toHaveBeenCalledTimes(1);
|
||||
expect(console.error).toHaveBeenCalledWith(new Error('error'));
|
||||
message.reply = jest.fn().mockImplementationOnce(() => {throw e})
|
||||
messageHelper.returnBufferFromText = jest.fn().mockResolvedValue({file: 'test.txt', text: 'normal content'});
|
||||
return commands.importCommand(message, args).catch(() => {
|
||||
expect(message.reply).toHaveBeenCalledTimes(2);
|
||||
expect(message.reply).toHaveBeenNthCalledWith(1, {content: 'normal content', files: [{name: 'test.txt', data: 'test.txt' }],});
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
const {enums} = require('../../src/enums.js');
|
||||
const fetchMock = require('jest-fetch-mock');
|
||||
|
||||
jest.mock('../../src/helpers/memberHelper.js', () => {
|
||||
return {
|
||||
@@ -8,6 +9,7 @@ jest.mock('../../src/helpers/memberHelper.js', () => {
|
||||
}
|
||||
})
|
||||
|
||||
fetchMock.enableMocks();
|
||||
const {memberHelper} = require("../../src/helpers/memberHelper.js");
|
||||
const {importHelper} = require('../../src/helpers/importHelper.js');
|
||||
|
||||
@@ -38,63 +40,58 @@ describe('importHelper', () => {
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
jest.clearAllMocks();
|
||||
global.fetch = jest.fn();
|
||||
global.fetch = jest.fn().mockResolvedValue({
|
||||
ok: true,
|
||||
json: () => Promise.resolve(mockData)
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
describe('pluralKitImport', () => {
|
||||
|
||||
test('if no attachment URL, throws error', async () => {
|
||||
await expect(importHelper.pluralKitImport(authorId)).rejects.toThrow(enums.err.NOT_JSON_FILE);
|
||||
})
|
||||
|
||||
test('if attachment URL, calls fetch and addFullMember and returns value', async () => {
|
||||
memberHelper.addFullMember.mockResolvedValue(mockAddReturn);
|
||||
const result = await importHelper.pluralKitImport(authorId, attachmentUrl);
|
||||
|
||||
expect(fetch).toHaveBeenCalledTimes(1);
|
||||
expect(fetch).toHaveBeenCalledWith(attachmentUrl);
|
||||
expect(memberHelper.addFullMember).toHaveBeenCalledWith(authorId, mockImportedMember.name, mockImportedMember.display_name, 'SP{text}', mockImportedMember.avatar_url);
|
||||
expect(result).toEqual(`Successfully added members: ${mockAddReturnMember.name}`)
|
||||
})
|
||||
|
||||
|
||||
test('if fetch fails, throws error', async () => {
|
||||
global.fetch = jest.fn().mockRejectedValue("can't get");
|
||||
await expect(importHelper.pluralKitImport(authorId, attachmentUrl)).rejects.toThrow(enums.err.CANNOT_FETCH_RESOURCE, "can't get file");
|
||||
})
|
||||
|
||||
test('if json conversion fails, throws error', async () => {
|
||||
global.fetch = jest.fn().mockResolvedValue({
|
||||
ok: true,
|
||||
json: () => Promise.reject("not json")
|
||||
test('if no attachment URL, throws error', () => {
|
||||
return importHelper.pluralKitImport(authorId).catch((e) => {
|
||||
expect(e).toEqual(new Error(enums.err.NOT_JSON_FILE));
|
||||
})
|
||||
await expect(importHelper.pluralKitImport(authorId, attachmentUrl)).rejects.toThrow(enums.err.NOT_JSON_FILE, "not json");
|
||||
})
|
||||
|
||||
test('if addFullMember returns nothing, return correct enum', async () => {
|
||||
test('if attachment URL, calls fetch and addFullMember and returns value', () => {
|
||||
memberHelper.addFullMember.mockResolvedValue(mockAddReturn);
|
||||
return importHelper.pluralKitImport(authorId, attachmentUrl).then((res) => {
|
||||
expect(fetch).toHaveBeenCalledTimes(1);
|
||||
expect(fetch).toHaveBeenCalledWith(attachmentUrl);
|
||||
expect(memberHelper.addFullMember).toHaveBeenCalledWith(authorId, mockImportedMember.name, mockImportedMember.display_name, 'SP{text}', mockImportedMember.avatar_url);
|
||||
expect(res).toEqual(`Successfully added members: ${mockAddReturnMember.name}`)
|
||||
})
|
||||
})
|
||||
|
||||
test('if addFullMember returns nothing, return correct enum', () => {
|
||||
memberHelper.addFullMember.mockResolvedValue();
|
||||
const promise = importHelper.pluralKitImport(authorId, attachmentUrl);
|
||||
await expect(promise).rejects.toBeInstanceOf(AggregateError);
|
||||
await expect(promise).rejects.toMatchObject(AggregateError([], enums.err.NO_MEMBERS_IMPORTED));
|
||||
return importHelper.pluralKitImport(authorId, attachmentUrl).catch((res) => {
|
||||
expect(res).toEqual(new AggregateError([], enums.err.NO_MEMBERS_IMPORTED));
|
||||
})
|
||||
})
|
||||
|
||||
test('if addFullMember throws error, catch and return error', async () => {
|
||||
memberHelper.addFullMember.mockRejectedValue(new Error('error'));
|
||||
await expect(importHelper.pluralKitImport(authorId, attachmentUrl)).rejects.toMatchObject(new AggregateError(['error'], enums.err.NO_MEMBERS_IMPORTED));
|
||||
});
|
||||
test('if addFullMember returns nothing and throws error, catch and return error', () => {
|
||||
memberHelper.addFullMember.mockResolvedValue(new Error('error'));
|
||||
return importHelper.pluralKitImport(authorId, attachmentUrl).catch((res) => {
|
||||
expect(res).toEqual(new AggregateError([new Error('error')], enums.err.NO_MEMBERS_IMPORTED))
|
||||
})
|
||||
})
|
||||
|
||||
test('if addFullMember returns member but also contains error, return member and error', async () => {
|
||||
test('if addFullMember returns member but also contains error, return member and error', () => {
|
||||
// Arrange
|
||||
const memberObj = {errors: ['error'], member: mockAddReturnMember};
|
||||
memberHelper.addFullMember.mockResolvedValue(memberObj);
|
||||
await expect(importHelper.pluralKitImport(authorId, attachmentUrl)).rejects.toMatchObject(new AggregateError(['error'], `Successfully added members: ${mockAddReturnMember.name}`));
|
||||
});
|
||||
});
|
||||
// Act
|
||||
return importHelper.pluralKitImport(authorId, attachmentUrl).catch((res) => {
|
||||
// Assert
|
||||
expect(res).toEqual(new AggregateError(['error'], `Successfully added members: ${mockAddReturnMember.name}`))
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
// restore the spy created with spyOn
|
||||
|
||||
@@ -2,15 +2,17 @@ const {enums} = require('../../src/enums.js');
|
||||
const {utils} = require("../../src/helpers/utils.js");
|
||||
|
||||
jest.mock('@fluxerjs/core', () => jest.fn());
|
||||
jest.mock('../../src/repositories/memberRepo.js', () => {
|
||||
jest.mock('../../src/database.js', () => {
|
||||
return {
|
||||
memberRepo: {
|
||||
getMemberByName: jest.fn().mockResolvedValue(),
|
||||
getMembersByAuthor: jest.fn().mockResolvedValue(),
|
||||
removeMember: jest.fn().mockResolvedValue(),
|
||||
createMember: jest.fn().mockResolvedValue(),
|
||||
updateMemberField: jest.fn().mockResolvedValue(),
|
||||
database: {
|
||||
members: {
|
||||
create: jest.fn().mockResolvedValue(),
|
||||
update: jest.fn().mockResolvedValue(),
|
||||
destroy: jest.fn().mockResolvedValue(),
|
||||
findOne: jest.fn().mockResolvedValue(),
|
||||
findAll: jest.fn().mockResolvedValue(),
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -23,8 +25,10 @@ jest.mock("../../src/helpers/utils.js", () => {
|
||||
}
|
||||
});
|
||||
|
||||
const {Op} = require('sequelize');
|
||||
|
||||
const {memberHelper} = require("../../src/helpers/memberHelper.js");
|
||||
const {memberRepo} = require("../../src/repositories/memberRepo.js");
|
||||
const {database} = require("../../src/database");
|
||||
|
||||
describe('MemberHelper', () => {
|
||||
const authorId = "0001";
|
||||
@@ -35,7 +39,7 @@ describe('MemberHelper', () => {
|
||||
name: "somePerson",
|
||||
displayname: "Some Person",
|
||||
proxy: "--text",
|
||||
propic: 'ono.png'
|
||||
propic: attachmentUrl
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -59,11 +63,12 @@ describe('MemberHelper', () => {
|
||||
[[]]
|
||||
])('%s calls getMemberCommandInfo and returns expected result', async (args) => {
|
||||
// Act
|
||||
const result = await memberHelper.parseMemberCommand(authorId, authorFull, args);
|
||||
// Assert
|
||||
expect(result).toEqual("member command info");
|
||||
expect(memberHelper.getMemberCommandInfo).toHaveBeenCalledTimes(1);
|
||||
expect(memberHelper.getMemberCommandInfo).toHaveBeenCalledWith();
|
||||
return memberHelper.parseMemberCommand(authorId, authorFull, args).then((result) => {
|
||||
// Assert
|
||||
expect(result).toEqual("member command info");
|
||||
expect(memberHelper.getMemberCommandInfo).toHaveBeenCalledTimes(1);
|
||||
expect(memberHelper.getMemberCommandInfo).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
test.each([
|
||||
@@ -87,12 +92,12 @@ describe('MemberHelper', () => {
|
||||
[[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, 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, 'new', '', mockMember.proxy], 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],
|
||||
@@ -110,7 +115,7 @@ describe('MemberHelper', () => {
|
||||
[['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.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],
|
||||
@@ -121,14 +126,15 @@ describe('MemberHelper', () => {
|
||||
[['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]
|
||||
])('%s args with attachmentURL %s and attachment expiration %s calls memberCommandHandler with correct values', async (args, attachmentUrl, attachmentExpiration, command, isHelp, memberName) => {
|
||||
])('%s args with attachmentURL %s and attachment expiration %s calls memberCommandHandler with correct values', (args, attachmentUrl, attachmentExpiration, command, isHelp, memberName) => {
|
||||
console.log(args, command, isHelp)
|
||||
// Act
|
||||
const result = await memberHelper.parseMemberCommand(authorId, authorFull, args, attachmentUrl, attachmentExpiration);
|
||||
// Assert
|
||||
expect(result).toEqual("handled argument");
|
||||
expect(memberHelper.memberArgumentHandler).toHaveBeenCalledTimes(1);
|
||||
expect(memberHelper.memberArgumentHandler).toHaveBeenCalledWith(authorId, authorFull, isHelp, command, memberName, args, attachmentUrl, attachmentExpiration);
|
||||
return memberHelper.parseMemberCommand(authorId, authorFull, args, attachmentUrl, attachmentExpiration).then((result) => {
|
||||
// Assert
|
||||
expect(result).toEqual("handled argument");
|
||||
expect(memberHelper.memberArgumentHandler).toHaveBeenCalledTimes(1);
|
||||
expect(memberHelper.memberArgumentHandler).toHaveBeenCalledWith(authorId, authorFull, isHelp, command, memberName, args, attachmentUrl, attachmentExpiration);
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
@@ -140,10 +146,12 @@ describe('MemberHelper', () => {
|
||||
jest.spyOn(memberHelper, 'sendHelpEnum').mockReturnValue("help enum");
|
||||
})
|
||||
|
||||
test('when all values are null should throw command not recognized enum', async () => {
|
||||
test('when all values are null should return command not recognized enum', () => {
|
||||
// Arrange
|
||||
await expect(memberHelper.memberArgumentHandler(authorId, authorFull, false, null, null, [])).rejects.toThrow(enums.err.COMMAND_NOT_RECOGNIZED);
|
||||
|
||||
return memberHelper.memberArgumentHandler(authorId, authorFull, false, null, null, []).catch((result) => {
|
||||
// Assert
|
||||
expect(result).toEqual(new Error(enums.err.COMMAND_NOT_RECOGNIZED));
|
||||
});
|
||||
})
|
||||
|
||||
test.each([
|
||||
@@ -153,9 +161,12 @@ describe('MemberHelper', () => {
|
||||
['displayname'],
|
||||
['proxy'],
|
||||
['propic'],
|
||||
])('when %s is present but other values are null, should throw no member enum', async (command) => {
|
||||
])('when %s is present but other values are null, should return no member enum', (command) => {
|
||||
// Arrange
|
||||
await expect(memberHelper.memberArgumentHandler(authorId, authorFull, false, command, null, [])).rejects.toThrow(enums.err.NO_MEMBER);
|
||||
return memberHelper.memberArgumentHandler(authorId, authorFull, false, command, null, []).catch((result) => {
|
||||
// Assert
|
||||
expect(result).toEqual(new Error(enums.err.NO_MEMBER));
|
||||
});
|
||||
})
|
||||
|
||||
|
||||
@@ -167,22 +178,24 @@ describe('MemberHelper', () => {
|
||||
['displayname'],
|
||||
['proxy'],
|
||||
['propic'],
|
||||
])('%s calls sendHelpEnum', async (command) => {
|
||||
])('%s calls sendHelpEnum', (command) => {
|
||||
// Arrange
|
||||
const result = await memberHelper.memberArgumentHandler(authorId, authorFull, true, command, mockMember.name, []);
|
||||
// Assert
|
||||
expect(result).toEqual("help enum");
|
||||
expect(memberHelper.sendHelpEnum).toHaveBeenCalledTimes(1);
|
||||
expect(memberHelper.sendHelpEnum).toHaveBeenCalledWith(command);
|
||||
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', async () => {
|
||||
test('list should call getAllMembersInfo', () => {
|
||||
// Arrange
|
||||
const result = await memberHelper.memberArgumentHandler(authorId, authorFull, false, 'list', mockMember.name, []);
|
||||
// Assert
|
||||
expect(result).toEqual("all member info");
|
||||
expect(memberHelper.getAllMembersInfo).toHaveBeenCalledTimes(1);
|
||||
expect(memberHelper.getAllMembersInfo).toHaveBeenCalledWith(authorId, authorFull);
|
||||
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([
|
||||
@@ -190,14 +203,14 @@ describe('MemberHelper', () => {
|
||||
[[mockMember.name, 'remove', 'test'], null, null, 'remove'],
|
||||
[[mockMember.name, 'new'], null, null, 'new'],
|
||||
[[mockMember.name, 'new', mockMember.displayname], null, null, 'new'],
|
||||
[[mockMember.name, 'new', mockMember.displayname, mockMember.proxy], null, null, 'new'],
|
||||
[[mockMember.name, 'new', mockMember.displayname, mockMember.proxy, mockMember.propic], null, null, 'new'],
|
||||
[[mockMember.name, 'new', mockMember.displayname, mockMember.proxy, null], mockMember.propic, null, 'new'],
|
||||
[[mockMember.name, 'new', mockMember.displayname, mockMember.proxy], null, null, 'new'],
|
||||
[[mockMember.name, 'new', mockMember.displayname, mockMember.proxy,mockMember.propic], null, null, 'new'],
|
||||
[[mockMember.name, 'new',mockMember.displayname, mockMember.proxy, null], mockMember.propic, null, 'new'],
|
||||
[[mockMember.name, 'new', mockMember.displayname, mockMember.proxy, null], mockMember.propic, attachmentExpiration, 'new'],
|
||||
[[mockMember.name, 'name', mockMember.name], null, null, 'name'],
|
||||
[[mockMember.name, 'displayname', mockMember.displayname], null, null, 'displayname'],
|
||||
[[mockMember.name, 'new', mockMember.displayname], null, null, 'new'],
|
||||
[[mockMember.name, 'new', '', mockMember.proxy], null, null, 'new'],
|
||||
[[mockMember.name, 'new', '', mockMember.proxy], null, null, 'new'],
|
||||
[[mockMember.name, 'new', '', '', mockMember.propic], null, null, 'new'],
|
||||
[[mockMember.name, 'new', '', '', undefined], mockMember.propic, null, 'new'],
|
||||
[[mockMember.name, 'new', '', '', undefined], mockMember.propic, attachmentExpiration, 'new'],
|
||||
@@ -217,7 +230,7 @@ describe('MemberHelper', () => {
|
||||
[['new', mockMember.name, mockMember.displayname, mockMember.proxy, mockMember.propic], null, null, 'new'],
|
||||
[['new', mockMember.name, undefined, mockMember.displayname, mockMember.proxy, undefined], mockMember.propic, null, 'new'],
|
||||
[['new', mockMember.name, undefined, mockMember.displayname, mockMember.proxy, undefined], mockMember.propic, attachmentExpiration, 'new'],
|
||||
[['new', mockMember.name, '', mockMember.proxy], null, null, 'new'],
|
||||
[['new', mockMember.name, '', mockMember.proxy], null, null, 'new'],
|
||||
[['new', mockMember.name, '', '', mockMember.propic], null, null, 'new'],
|
||||
[['new', mockMember.name, '', '', undefined], mockMember.propic, null, 'new'],
|
||||
[['new', mockMember.name, '', '', undefined], mockMember.propic, attachmentExpiration, 'new'],
|
||||
@@ -229,16 +242,16 @@ describe('MemberHelper', () => {
|
||||
[['propic', mockMember.name, mockMember.name, mockMember.displayname, mockMember.proxy, mockMember.propic], null, null, 'propic'],
|
||||
[['propic', mockMember.name, undefined, mockMember.name, mockMember.displayname, mockMember.proxy, undefined], mockMember.propic, null, 'propic'],
|
||||
[['propic', mockMember.name, undefined, mockMember.name, mockMember.displayname, mockMember.proxy, undefined], mockMember.propic, attachmentExpiration, 'propic']
|
||||
])('%s args with attachmentURL %s and attachment expiration %s calls memberCommandHandler', async (args, attachmentUrl, attachmentExpiration, command) => {
|
||||
])('%s args with attachmentURL %s and attachment expiration %s calls memberCommandHandler', (args, attachmentUrl, attachmentExpiration, command) => {
|
||||
// Arrange
|
||||
let values = args.slice(2);
|
||||
|
||||
const result = await memberHelper.memberArgumentHandler(authorId, authorFull, false, command, mockMember.name, args, attachmentUrl, attachmentExpiration);
|
||||
// Assert
|
||||
expect(result).toEqual("handled command");
|
||||
expect(memberHelper.memberCommandHandler).toHaveBeenCalledTimes(1);
|
||||
expect(memberHelper.memberCommandHandler).toHaveBeenCalledWith(authorId, command, mockMember.name, values, attachmentUrl, attachmentExpiration);
|
||||
|
||||
return memberHelper.memberArgumentHandler(authorId, authorFull, false, command, mockMember.name, args, attachmentUrl, attachmentExpiration).then((result) => {
|
||||
// Assert
|
||||
expect(result).toEqual("handled command");
|
||||
expect(memberHelper.memberCommandHandler).toHaveBeenCalledTimes(1);
|
||||
expect(memberHelper.memberCommandHandler).toHaveBeenCalledWith(authorId, command, mockMember.name, values, attachmentUrl, attachmentExpiration);
|
||||
});
|
||||
})
|
||||
|
||||
test.each([
|
||||
@@ -247,14 +260,16 @@ describe('MemberHelper', () => {
|
||||
['displayname'],
|
||||
['proxy'],
|
||||
['propic'],
|
||||
])('%s calls sendCurrentValue', async (command) => {
|
||||
const result = await memberHelper.memberArgumentHandler(authorId, authorFull, false, command, mockMember.name, []);
|
||||
// Assert
|
||||
expect(result).toEqual("current value");
|
||||
expect(memberHelper.sendCurrentValue).toHaveBeenCalledTimes(1);
|
||||
expect(memberHelper.sendCurrentValue).toHaveBeenCalledWith(authorId, mockMember.name, command);
|
||||
|
||||
])('%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', () => {
|
||||
@@ -264,87 +279,88 @@ describe('MemberHelper', () => {
|
||||
['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', async (command, expected) => {
|
||||
])('%s calls getMemberByName and returns value', (command, expected) => {
|
||||
// Arrange
|
||||
memberRepo.getMemberByName.mockResolvedValue(mockMember);
|
||||
jest.spyOn(memberHelper, 'getMemberByName').mockResolvedValue(mockMember);
|
||||
// Act
|
||||
const result = await memberHelper.sendCurrentValue(authorId, mockMember.name, command);
|
||||
// Assert
|
||||
expect(result).toEqual(expected);
|
||||
expect(memberRepo.getMemberByName).toHaveBeenCalledTimes(1);
|
||||
expect(memberRepo.getMemberByName).toHaveBeenCalledWith(authorId, mockMember.name);
|
||||
|
||||
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', async () => {
|
||||
test('returns error if no member found', () => {
|
||||
// Arrange
|
||||
memberRepo.getMemberByName.mockResolvedValue(null);
|
||||
jest.spyOn(memberHelper, 'getMemberByName').mockResolvedValue(null);
|
||||
// Act
|
||||
await expect(memberHelper.sendCurrentValue(authorId, mockMember.name, 'name')).rejects.toThrow(enums.err.NO_MEMBER);
|
||||
// Assert
|
||||
expect(memberRepo.getMemberByName).toHaveBeenCalledTimes(1);
|
||||
expect(memberRepo.getMemberByName).toHaveBeenCalledWith(authorId, mockMember.name);
|
||||
});
|
||||
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', async () => {
|
||||
test('calls getMemberInfo with member if no command present', () => {
|
||||
// Arrange
|
||||
memberRepo.getMemberByName.mockResolvedValue(mockMember);
|
||||
jest.spyOn(memberHelper, 'getMemberByName').mockResolvedValue(mockMember);
|
||||
jest.spyOn(memberHelper, 'getMemberInfo').mockResolvedValue('member info');
|
||||
// Act
|
||||
const result = await memberHelper.sendCurrentValue(authorId, mockMember.name, null);
|
||||
// Assert
|
||||
expect(result).toEqual('member info');
|
||||
expect(memberHelper.getMemberInfo).toHaveBeenCalledTimes(1);
|
||||
expect(memberHelper.getMemberInfo).toHaveBeenCalledWith(mockMember);
|
||||
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 value found', async (command, expected) => {
|
||||
])('returns null message if no member found', (command, expected) => {
|
||||
// Arrange
|
||||
const empty = {name: mockMember.name, displayname: null, proxy: null, propic: null}
|
||||
memberRepo.getMemberByName.mockResolvedValue(empty);
|
||||
jest.spyOn(memberHelper, 'getMemberByName').mockResolvedValue(empty);
|
||||
// Act
|
||||
const result = await memberHelper.sendCurrentValue(authorId, mockMember.name, command);
|
||||
// Assert
|
||||
expect(result).toEqual(expected);
|
||||
expect(memberRepo.getMemberByName).toHaveBeenCalledTimes(1);
|
||||
expect(memberRepo.getMemberByName).toHaveBeenCalledWith(authorId, mockMember.name);
|
||||
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);
|
||||
});
|
||||
})
|
||||
})
|
||||
|
||||
describe('addNewMember', () => {
|
||||
test('calls addFullMember with correct arguments', async () => {
|
||||
test('calls addFullMember with correct arguments', async() => {
|
||||
// Arrange
|
||||
const args = [mockMember.displayname, mockMember.proxy, mockMember.propic];
|
||||
jest.spyOn(memberHelper, 'addFullMember').mockResolvedValue(mockMember);
|
||||
jest.spyOn(memberHelper, 'getMemberInfo').mockResolvedValue();
|
||||
// Act
|
||||
const result = await memberHelper.addNewMember(authorId, mockMember.name, args, attachmentUrl, attachmentExpiration);
|
||||
// Assert
|
||||
expect(memberHelper.addFullMember).toHaveBeenCalledTimes(1);
|
||||
expect(memberHelper.addFullMember).toHaveBeenCalledWith(authorId, mockMember.name, mockMember.displayname, mockMember.proxy, mockMember.propic, attachmentExpiration);
|
||||
return memberHelper.addNewMember(authorId, mockMember.name, args, attachmentUrl, attachmentExpiration).then(() => {
|
||||
expect(memberHelper.addFullMember).toHaveBeenCalledTimes(1);
|
||||
expect(memberHelper.addFullMember).toHaveBeenCalledWith(authorId, mockMember.name, mockMember.displayname, mockMember.proxy, mockMember.propic, attachmentExpiration);
|
||||
})
|
||||
})
|
||||
|
||||
test('calls getMemberInfo when successful and returns result', async () => {
|
||||
// Arrange
|
||||
const args = [mockMember.displayname, mockMember.proxy, mockMember.propic];
|
||||
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, 'getMemberInfo').mockReturnValue(mockMember);
|
||||
//Act
|
||||
const result = await memberHelper.addNewMember(authorId, mockMember.name, args, attachmentUrl, attachmentExpiration);
|
||||
// Assert
|
||||
expect(result).toEqual(expected);
|
||||
expect(memberHelper.getMemberInfo).toHaveBeenCalledTimes(1);
|
||||
expect(memberHelper.getMemberInfo).toHaveBeenCalledWith(mockMember);
|
||||
return memberHelper.addNewMember(authorId, mockMember.name, args, attachmentUrl, attachmentExpiration).then((result) => {
|
||||
// Assert
|
||||
expect(result).toEqual(expected);
|
||||
expect(memberHelper.getMemberInfo).toHaveBeenCalledTimes(1);
|
||||
expect(memberHelper.getMemberInfo).toHaveBeenCalledWith(mockMember);
|
||||
})
|
||||
})
|
||||
|
||||
test('throws expected error when getMemberInfo throws error', async () => {
|
||||
@@ -352,19 +368,29 @@ describe('MemberHelper', () => {
|
||||
const args = [];
|
||||
const memberObject = {name: args[1]}
|
||||
jest.spyOn(memberHelper, 'addFullMember').mockResolvedValue(memberObject);
|
||||
jest.spyOn(memberHelper, 'getMemberInfo').mockImplementation(() => {throw new Error('getMemberInfo error')});
|
||||
jest.spyOn(memberHelper, 'getMemberInfo').mockImplementation(() => {
|
||||
throw new Error('getMemberInfo error')
|
||||
});
|
||||
//Act
|
||||
await expect(memberHelper.addNewMember(authorId, mockMember.name, args)).rejects.toThrow('getMemberInfo error');
|
||||
return memberHelper.addNewMember(authorId, mockMember.name, args).catch((result) => {
|
||||
// Assert
|
||||
expect(result).toEqual(new Error('getMemberInfo error'));
|
||||
})
|
||||
})
|
||||
|
||||
test('throws expected error when addFullMember throws error', async () => {
|
||||
// Arrange
|
||||
const args = [];
|
||||
const expected = 'add full member error';
|
||||
jest.spyOn(memberHelper, 'addFullMember').mockRejectedValue(new Error(expected));
|
||||
jest.spyOn(memberHelper, 'addFullMember').mockImplementation(() => {
|
||||
throw new Error(expected)
|
||||
});
|
||||
|
||||
//Act
|
||||
await expect(memberHelper.addNewMember(authorId, mockMember.name, args)).rejects.toThrow(expected)
|
||||
return memberHelper.addNewMember(authorId, mockMember.name, args).catch((result) => {
|
||||
// Assert
|
||||
expect(result).toEqual(new Error(expected));
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -374,20 +400,23 @@ describe('MemberHelper', () => {
|
||||
// Arrange;
|
||||
jest.spyOn(memberHelper, 'updateMemberField').mockResolvedValue("Updated");
|
||||
// Act
|
||||
const result = await memberHelper.updateName(authorId, mockMember.name, " somePerson ")
|
||||
// Assert
|
||||
expect(result).toEqual("Updated");
|
||||
expect(memberHelper.updateMemberField).toHaveBeenCalledTimes(1);
|
||||
expect(memberHelper.updateMemberField).toHaveBeenCalledWith(authorId, mockMember.name, "name", "somePerson");
|
||||
return memberHelper.updateName(authorId, mockMember.name, " somePerson ").then((result) => {
|
||||
// Assert
|
||||
expect(result).toEqual("Updated");
|
||||
expect(memberHelper.updateMemberField).toHaveBeenCalledTimes(1);
|
||||
expect(memberHelper.updateMemberField).toHaveBeenCalledWith(authorId, mockMember.name, "name", "somePerson");
|
||||
})
|
||||
})
|
||||
|
||||
test('throws error when name is blank', async () => {
|
||||
// Arrange;
|
||||
jest.spyOn(memberHelper, 'updateMemberField').mockResolvedValue("Updated");
|
||||
// Act & Assert
|
||||
await expect(memberHelper.updateName(authorId, mockMember.name, " ")).rejects.toThrow('Name ' + enums.err.NO_VALUE);
|
||||
// Assert
|
||||
expect(memberHelper.updateMemberField).not.toHaveBeenCalled();
|
||||
// Act
|
||||
return memberHelper.updateName(authorId, mockMember.name, " ").catch((result) => {
|
||||
// Assert
|
||||
expect(result).toEqual(new RangeError("Name " + enums.err.NO_VALUE));
|
||||
expect(memberHelper.updateMemberField).not.toHaveBeenCalled();
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -396,117 +425,114 @@ describe('MemberHelper', () => {
|
||||
test('throws error when displayname is blank', async () => {
|
||||
// Arrange
|
||||
jest.spyOn(memberHelper, 'updateMemberField').mockResolvedValue();
|
||||
// Act & Assert
|
||||
await expect(memberHelper.updateDisplayName(authorId, mockMember.name, " ")).rejects.toThrow("Display name " + enums.err.NO_VALUE);
|
||||
// Assert
|
||||
expect(memberHelper.updateMemberField).not.toHaveBeenCalled();
|
||||
// Act
|
||||
return memberHelper.updateDisplayName(authorId, mockMember.name, mockMember.displayname).catch((result) => {
|
||||
// Assert
|
||||
expect(result).toEqual(new Error(`Display name ${enums.err.NO_VALUE}`));
|
||||
expect(memberHelper.updateMemberField).not.toHaveBeenCalled();
|
||||
})
|
||||
})
|
||||
|
||||
test('Sends error when display name is too long', async () => {
|
||||
// Arrange
|
||||
const tooLongDisplayName = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
|
||||
jest.spyOn(memberHelper, 'updateMemberField').mockResolvedValue();
|
||||
// Act & Assert
|
||||
await expect(memberHelper.updateDisplayName(authorId, mockMember.name, tooLongDisplayName)).rejects.toThrow(enums.err.DISPLAY_NAME_TOO_LONG);
|
||||
// Assert
|
||||
expect(memberHelper.updateMemberField).not.toHaveBeenCalled();
|
||||
// Act
|
||||
return memberHelper.updateDisplayName(authorId, mockMember.name, tooLongDisplayName).catch((result) => {
|
||||
// Assert
|
||||
expect(result).toEqual(new RangeError(enums.err.DISPLAY_NAME_TOO_LONG));
|
||||
expect(memberHelper.updateMemberField).not.toHaveBeenCalled();
|
||||
})
|
||||
})
|
||||
|
||||
test('call updateMemberField with correct arguments when displayname passed in correctly and returns string', async () => {
|
||||
// Arrange
|
||||
jest.spyOn(memberHelper, 'updateMemberField').mockResolvedValue("Updated");
|
||||
// Act
|
||||
const result = await memberHelper.updateDisplayName(authorId, mockMember.name, " Some Person ");
|
||||
// Assert
|
||||
expect(result).toEqual("Updated");
|
||||
expect(memberHelper.updateMemberField).toHaveBeenCalledWith(authorId, mockMember.name, "displayname", mockMember.displayname);
|
||||
expect(memberHelper.updateMemberField).toHaveBeenCalledTimes(1);
|
||||
return memberHelper.updateDisplayName(authorId, mockMember.name, " Some Person ").then((result) => {
|
||||
// Assert
|
||||
expect(result).toEqual("Updated");
|
||||
expect(memberHelper.updateMemberField).toHaveBeenCalledWith(authorId, mockMember.name, "displayname", mockMember.displayname);
|
||||
expect(memberHelper.updateMemberField).toHaveBeenCalledTimes(1);
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('updateProxy', () => {
|
||||
test('calls checkIfProxyExists and updateMemberField and returns string', async () => {
|
||||
test('calls checkIfProxyExists and updateMemberField and returns string', async() => {
|
||||
// Arrange
|
||||
jest.spyOn(memberHelper, 'checkIfProxyExists').mockResolvedValue();
|
||||
jest.spyOn(memberHelper, 'updateMemberField').mockResolvedValue("Updated");
|
||||
// Act
|
||||
const result = await memberHelper.updateProxy(authorId, mockMember.name, "--text");
|
||||
// Assert
|
||||
expect(result).toEqual("Updated");
|
||||
expect(memberHelper.checkIfProxyExists).toHaveBeenCalledTimes(1);
|
||||
expect(memberHelper.checkIfProxyExists).toHaveBeenCalledWith(authorId, mockMember.proxy);
|
||||
expect(memberHelper.updateMemberField).toHaveBeenCalledTimes(1);
|
||||
expect(memberHelper.updateMemberField).toHaveBeenCalledWith(authorId, mockMember.name, "proxy", mockMember.proxy);
|
||||
return memberHelper.updateProxy(authorId, mockMember.name, "--text").then((result) => {
|
||||
expect(result).toEqual("Updated");
|
||||
expect(memberHelper.checkIfProxyExists).toHaveBeenCalledTimes(1);
|
||||
expect(memberHelper.checkIfProxyExists).toHaveBeenCalledWith(authorId, mockMember.proxy);
|
||||
expect(memberHelper.updateMemberField).toHaveBeenCalledTimes(1);
|
||||
expect(memberHelper.updateMemberField).toHaveBeenCalledWith(authorId, mockMember.name, "proxy", mockMember.proxy);
|
||||
});
|
||||
})
|
||||
})
|
||||
|
||||
describe('updatePropic', () => {
|
||||
test.each([
|
||||
[null, attachmentUrl, undefined, attachmentUrl],
|
||||
[mockMember.propic, null, undefined, mockMember.propic],
|
||||
[mockMember.propic, attachmentUrl, undefined, mockMember.propic],
|
||||
])('calls checkImageFormatValidity and updateMemberField and returns string', async (imgUrl, attachmentUrl, attachmentExpiration, expected) => {
|
||||
[null, attachmentUrl, null, attachmentUrl],
|
||||
[mockMember.propic, null, null, mockMember.propic],
|
||||
[mockMember.propic, attachmentUrl, null, attachmentUrl],
|
||||
[null, attachmentUrl, attachmentExpiration, attachmentUrl]
|
||||
])('calls checkImageFormatValidity and updateMemberField and returns string', async(imgUrl, attachmentUrl, attachmentExpiration, expected) => {
|
||||
// Arrange
|
||||
jest.spyOn(memberHelper, 'updateMemberField').mockResolvedValue("Updated");
|
||||
utils.setExpirationWarning = jest.fn().mockReturnValue(undefined);
|
||||
// Act
|
||||
const result = await memberHelper.updatePropic(authorId, mockMember.name, imgUrl, attachmentUrl, attachmentExpiration);
|
||||
// Assert
|
||||
expect(result).toEqual("Updated");
|
||||
expect(utils.checkImageFormatValidity).toHaveBeenCalledTimes(1);
|
||||
expect(utils.checkImageFormatValidity).toHaveBeenCalledWith(expected);
|
||||
expect(memberHelper.updateMemberField).toHaveBeenCalledTimes(1);
|
||||
expect(memberHelper.updateMemberField).toHaveBeenCalledWith(authorId, mockMember.name, "propic", expected, undefined);
|
||||
})
|
||||
|
||||
test('calls setExpirationWarning', async() => {
|
||||
// Arrange
|
||||
jest.spyOn(memberHelper, 'updateMemberField').mockResolvedValue("Updated");
|
||||
utils.setExpirationWarning = jest.fn().mockReturnValue(enums.misc.ATTACHMENT_EXPIRATION_WARNING);
|
||||
// Act
|
||||
const result = await memberHelper.updatePropic(authorId, mockMember.name, null, attachmentUrl, attachmentExpiration);
|
||||
// Assert
|
||||
expect(result).toEqual("Updated");
|
||||
expect(utils.setExpirationWarning).toHaveBeenCalledTimes(1);
|
||||
expect(utils.setExpirationWarning).toHaveBeenCalledWith(attachmentUrl, attachmentExpiration);
|
||||
expect(memberHelper.updateMemberField).toHaveBeenCalledTimes(1);
|
||||
expect(memberHelper.updateMemberField).toHaveBeenCalledWith(authorId, mockMember.name, "propic", attachmentUrl, enums.misc.ATTACHMENT_EXPIRATION_WARNING);
|
||||
return memberHelper.updatePropic(authorId, mockMember.name, imgUrl, attachmentUrl, attachmentExpiration).then((result) => {
|
||||
expect(result).toEqual("Updated");
|
||||
expect(utils.checkImageFormatValidity).toHaveBeenCalledTimes(1);
|
||||
expect(utils.checkImageFormatValidity).toHaveBeenCalledWith(expected);
|
||||
expect(memberHelper.updateMemberField).toHaveBeenCalledTimes(1);
|
||||
expect(memberHelper.updateMemberField).toHaveBeenCalledWith(authorId, mockMember.name, "propic", expected, attachmentExpiration);
|
||||
});
|
||||
})
|
||||
})
|
||||
|
||||
describe('addFullMember', () => {
|
||||
const { database} = require('../../src/database.js');
|
||||
beforeEach(() => {
|
||||
jest.spyOn(memberHelper, 'getMemberByName').mockResolvedValue();
|
||||
})
|
||||
|
||||
test('calls getMemberByName', async () => {
|
||||
// Arrange
|
||||
memberRepo.getMemberByName.mockResolvedValue();
|
||||
// Act
|
||||
await memberHelper.addFullMember(authorId, mockMember.name)
|
||||
// Assert
|
||||
expect(memberRepo.getMemberByName).toHaveBeenCalledWith(authorId, mockMember.name);
|
||||
expect(memberRepo.getMemberByName).toHaveBeenCalledTimes(1);
|
||||
return await memberHelper.addFullMember(authorId, mockMember.name).then(() => {
|
||||
// Assert
|
||||
expect(memberHelper.getMemberByName).toHaveBeenCalledWith(authorId, mockMember.name);
|
||||
expect(memberHelper.getMemberByName).toHaveBeenCalledTimes(1);
|
||||
})
|
||||
})
|
||||
|
||||
test('if getMemberByName returns member, throw error', async () => {
|
||||
// Arrange
|
||||
memberRepo.getMemberByName.mockResolvedValue({name: mockMember.name});
|
||||
// Act & Assert
|
||||
await expect(memberHelper.addFullMember(authorId, mockMember.name)).rejects.toThrow(`Can't add ${mockMember.name}. ${enums.err.MEMBER_EXISTS}`)
|
||||
// Assert
|
||||
expect(memberRepo.createMember).not.toHaveBeenCalled();
|
||||
memberHelper.getMemberByName.mockResolvedValue({name: mockMember.name});
|
||||
// Act
|
||||
return await memberHelper.addFullMember(authorId, mockMember.name).catch((e) => {
|
||||
// Assert
|
||||
expect(e).toEqual(new Error(`Can't add ${mockMember.name}. ${enums.err.MEMBER_EXISTS}`))
|
||||
expect(database.members.create).not.toHaveBeenCalled();
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
test('if name is not filled out, throw error', async () => {
|
||||
// Arrange
|
||||
memberRepo.getMemberByName.mockResolvedValue();
|
||||
// Act
|
||||
await expect(memberHelper.addFullMember(authorId, " ")).rejects.toThrow(`Name ${enums.err.NO_VALUE}. ${enums.err.NAME_REQUIRED}`);
|
||||
// Assert
|
||||
expect(memberRepo.createMember).not.toHaveBeenCalled();
|
||||
return await memberHelper.addFullMember(authorId, " ").catch((e) => {
|
||||
// Assert
|
||||
expect(e).toEqual(new Error(`Name ${enums.err.NO_VALUE}. ${enums.err.NAME_REQUIRED}`))
|
||||
expect(database.members.create).not.toHaveBeenCalled();
|
||||
})
|
||||
})
|
||||
|
||||
test('if displayname is over 32 characters, call memberRepo.createMember with null value', async () => {
|
||||
test('if displayname is over 32 characters, call database.member.create with null value', async () => {
|
||||
// Arrange
|
||||
memberRepo.getMemberByName.mockResolvedValue();
|
||||
memberHelper.getMemberByName.mockResolvedValue();
|
||||
const tooLongDisplayName = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
|
||||
const expectedMemberArgs = {
|
||||
name: mockMember.name,
|
||||
@@ -515,46 +541,50 @@ describe('MemberHelper', () => {
|
||||
proxy: null,
|
||||
propic: null
|
||||
}
|
||||
memberRepo.createMember = jest.fn().mockResolvedValue(expectedMemberArgs);
|
||||
database.members.create = jest.fn().mockResolvedValue(expectedMemberArgs);
|
||||
const expectedReturn = {
|
||||
member: expectedMemberArgs,
|
||||
errors: [`Tried to set displayname to \"${tooLongDisplayName}\". ${enums.err.DISPLAY_NAME_TOO_LONG}. ${enums.err.SET_TO_NULL}`]
|
||||
}
|
||||
|
||||
// Act
|
||||
const res = await memberHelper.addFullMember(authorId, mockMember.name, tooLongDisplayName, null, null);
|
||||
// Assert
|
||||
expect(res).toEqual(expectedReturn);
|
||||
expect(memberRepo.createMember).toHaveBeenCalledWith(expectedMemberArgs);
|
||||
expect(memberRepo.createMember).toHaveBeenCalledTimes(1);
|
||||
return await memberHelper.addFullMember(authorId, mockMember.name, tooLongDisplayName, null, null).then((res) => {
|
||||
// Assert
|
||||
expect(res).toEqual(expectedReturn);
|
||||
expect(database.members.create).toHaveBeenCalledWith(expectedMemberArgs);
|
||||
expect(database.members.create).toHaveBeenCalledTimes(1);
|
||||
})
|
||||
})
|
||||
|
||||
test('if proxy, call checkIfProxyExists', async () => {
|
||||
// Arrange
|
||||
jest.spyOn(memberHelper, 'checkIfProxyExists').mockResolvedValue(true);
|
||||
jest.spyOn(memberHelper, 'checkIfProxyExists').mockResolvedValue();
|
||||
const expectedMemberArgs = {
|
||||
name: mockMember.name,
|
||||
userid: authorId,
|
||||
displayname: null,
|
||||
proxy: null,
|
||||
proxy: mockMember.proxy,
|
||||
propic: null
|
||||
}
|
||||
memberRepo.createMember = jest.fn().mockResolvedValue(expectedMemberArgs);
|
||||
database.members.create = jest.fn().mockResolvedValue(expectedMemberArgs);
|
||||
const expectedReturn = {member: expectedMemberArgs, errors: []}
|
||||
|
||||
// Act
|
||||
const res = await memberHelper.addFullMember(authorId, mockMember.name, null, mockMember.proxy)
|
||||
// Assert
|
||||
expect(res).toEqual(expectedReturn);
|
||||
expect(memberHelper.checkIfProxyExists).toHaveBeenCalledWith(authorId, mockMember.proxy);
|
||||
expect(memberHelper.checkIfProxyExists).toHaveBeenCalledTimes(1);
|
||||
expect(memberRepo.createMember).toHaveBeenCalledWith(expectedMemberArgs);
|
||||
expect(memberRepo.createMember).toHaveBeenCalledTimes(1);
|
||||
return await memberHelper.addFullMember(authorId, mockMember.name, null, mockMember.proxy).then((res) => {
|
||||
// Assert
|
||||
expect(res).toEqual(expectedReturn);
|
||||
expect(memberHelper.checkIfProxyExists).toHaveBeenCalledWith(authorId, mockMember.proxy);
|
||||
expect(memberHelper.checkIfProxyExists).toHaveBeenCalledTimes(1);
|
||||
expect(database.members.create).toHaveBeenCalledWith(expectedMemberArgs);
|
||||
expect(database.members.create).toHaveBeenCalledTimes(1);
|
||||
})
|
||||
})
|
||||
|
||||
test('if checkProxyExists throws error, call database.member.create with null value', async () => {
|
||||
// Arrange
|
||||
jest.spyOn(memberHelper, 'checkIfProxyExists').mockRejectedValue(new Error('error'));
|
||||
jest.spyOn(memberHelper, 'checkIfProxyExists').mockImplementation(() => {
|
||||
throw new Error('error')
|
||||
});
|
||||
const expectedMemberArgs = {
|
||||
name: mockMember.name,
|
||||
userid: authorId,
|
||||
@@ -562,18 +592,19 @@ describe('MemberHelper', () => {
|
||||
proxy: null,
|
||||
propic: null
|
||||
}
|
||||
memberRepo.createMember = jest.fn().mockResolvedValue(expectedMemberArgs);
|
||||
database.members.create = jest.fn().mockResolvedValue(expectedMemberArgs);
|
||||
const expectedReturn = {
|
||||
member: expectedMemberArgs,
|
||||
errors: [`Tried to set proxy to \"${mockMember.proxy}\". error. ${enums.err.SET_TO_NULL}`]
|
||||
}
|
||||
|
||||
// Act
|
||||
const res = await memberHelper.addFullMember(authorId, mockMember.name, null, mockMember.proxy, null)
|
||||
// Assert
|
||||
expect(res).toEqual(expectedReturn);
|
||||
expect(memberRepo.createMember).toHaveBeenCalledWith(expectedMemberArgs);
|
||||
expect(memberRepo.createMember).toHaveBeenCalledTimes(1);
|
||||
return await memberHelper.addFullMember(authorId, mockMember.name, null, mockMember.proxy, null).then((res) => {
|
||||
// Assert
|
||||
expect(res).toEqual(expectedReturn);
|
||||
expect(database.members.create).toHaveBeenCalledWith(expectedMemberArgs);
|
||||
expect(database.members.create).toHaveBeenCalledTimes(1);
|
||||
})
|
||||
})
|
||||
|
||||
test('if propic, call checkImageFormatValidity', async () => {
|
||||
@@ -583,24 +614,24 @@ describe('MemberHelper', () => {
|
||||
userid: authorId,
|
||||
displayname: null,
|
||||
proxy: null,
|
||||
propic: null
|
||||
propic: mockMember.propic
|
||||
}
|
||||
utils.setExpirationWarning = jest.fn().mockReturnValue();
|
||||
memberRepo.createMember = jest.fn().mockResolvedValue(expectedMemberArgs);
|
||||
database.members.create = jest.fn().mockResolvedValue(expectedMemberArgs);
|
||||
const expectedReturn = {member: expectedMemberArgs, errors: []}
|
||||
// Act
|
||||
const res = await memberHelper.addFullMember(authorId, mockMember.name, null, null, mockMember.propic);
|
||||
// Assert
|
||||
expect(res).toEqual(expectedReturn);
|
||||
expect(utils.checkImageFormatValidity).toHaveBeenCalledWith(mockMember.propic);
|
||||
expect(utils.checkImageFormatValidity).toHaveBeenCalledTimes(1);
|
||||
expect(memberRepo.createMember).toHaveBeenCalledWith(expectedMemberArgs);
|
||||
expect(memberRepo.createMember).toHaveBeenCalledTimes(1);
|
||||
return await memberHelper.addFullMember(authorId, mockMember.name, null, null, mockMember.propic).then((res) => {
|
||||
// Assert
|
||||
expect(res).toEqual(expectedReturn);
|
||||
expect(utils.checkImageFormatValidity).toHaveBeenCalledWith(mockMember.propic);
|
||||
expect(utils.checkImageFormatValidity).toHaveBeenCalledTimes(1);
|
||||
expect(database.members.create).toHaveBeenCalledWith(expectedMemberArgs);
|
||||
expect(database.members.create).toHaveBeenCalledTimes(1);
|
||||
})
|
||||
})
|
||||
|
||||
test('if checkImageFormatValidity throws error, call database.member.create with null value', async () => {
|
||||
// Arrange
|
||||
utils.checkImageFormatValidity = jest.fn().mockRejectedValue(new Error("error"));
|
||||
utils.checkImageFormatValidity = jest.fn().mockImplementation(() => {throw new Error("error")})
|
||||
const expectedMemberArgs = {
|
||||
name: mockMember.name,
|
||||
userid: authorId,
|
||||
@@ -608,33 +639,23 @@ describe('MemberHelper', () => {
|
||||
proxy: null,
|
||||
propic: null
|
||||
}
|
||||
memberRepo.createMember = jest.fn().mockResolvedValue(expectedMemberArgs);
|
||||
database.members.create = jest.fn().mockResolvedValue(expectedMemberArgs);
|
||||
const expectedReturn = {
|
||||
member: expectedMemberArgs,
|
||||
errors: [`Tried to set profile picture to \"${mockMember.propic}\". error. ${enums.err.SET_TO_NULL}`]
|
||||
}
|
||||
// Act
|
||||
const res = await memberHelper.addFullMember(authorId, mockMember.name, null, null, mockMember.propic);
|
||||
// Assert
|
||||
expect(res).toEqual(expectedReturn);
|
||||
expect(memberRepo.createMember).toHaveBeenCalledWith(expectedMemberArgs);
|
||||
expect(memberRepo.createMember).toHaveBeenCalledTimes(1);
|
||||
})
|
||||
|
||||
test('calls setExpirationWarning if attachmentExpiration exists', async () => {
|
||||
// Arrange
|
||||
utils.checkImageFormatValidity = jest.fn().mockResolvedValue(true);
|
||||
utils.setExpirationWarning = jest.fn().mockReturnValue(`${enums.misc.ATTACHMENT_EXPIRATION_WARNING}`);
|
||||
// Act
|
||||
await memberHelper.addFullMember(authorId, mockMember.name, null, null, mockMember.propic, attachmentExpiration)
|
||||
// Assert
|
||||
expect(utils.setExpirationWarning).toHaveBeenCalledTimes(1);
|
||||
expect(utils.setExpirationWarning).toHaveBeenCalledWith(mockMember.propic, attachmentExpiration);
|
||||
return await memberHelper.addFullMember(authorId, mockMember.name, null, null, mockMember.propic).then((res) => {
|
||||
// Assert
|
||||
expect(res).toEqual(expectedReturn);
|
||||
expect(database.members.create).toHaveBeenCalledWith(expectedMemberArgs);
|
||||
expect(database.members.create).toHaveBeenCalledTimes(1);
|
||||
})
|
||||
})
|
||||
|
||||
test('if all values are valid, call database.members.create', async () => {
|
||||
// Arrange
|
||||
jest.spyOn(memberHelper, 'checkIfProxyExists').mockResolvedValue(false);
|
||||
jest.spyOn(memberHelper, 'checkIfProxyExists').mockResolvedValue();
|
||||
const expectedMemberArgs = {
|
||||
name: mockMember.name,
|
||||
userid: authorId,
|
||||
@@ -642,54 +663,72 @@ describe('MemberHelper', () => {
|
||||
proxy: mockMember.proxy,
|
||||
propic: mockMember.propic
|
||||
}
|
||||
memberRepo.createMember = jest.fn().mockResolvedValue(expectedMemberArgs);
|
||||
utils.checkImageFormatValidity = jest.fn().mockResolvedValue(true);
|
||||
utils.setExpirationWarning = jest.fn().mockReturnValue();
|
||||
database.members.create = jest.fn().mockResolvedValue(expectedMemberArgs);
|
||||
utils.checkImageFormatValidity = jest.fn().mockResolvedValue();
|
||||
const expectedReturn = {member: expectedMemberArgs, errors: []}
|
||||
// Act
|
||||
const res = await memberHelper.addFullMember(authorId, mockMember.name, mockMember.displayname, mockMember.proxy, mockMember.propic);
|
||||
// Assert
|
||||
expect(res).toEqual(expectedReturn);
|
||||
expect(memberRepo.createMember).toHaveBeenCalledWith(expectedMemberArgs);
|
||||
expect(memberRepo.createMember).toHaveBeenCalledTimes(1);
|
||||
return await memberHelper.addFullMember(authorId, mockMember.name, mockMember.displayname, mockMember.proxy, mockMember.propic).then((res) => {
|
||||
// Assert
|
||||
expect(res).toEqual(expectedReturn);
|
||||
expect(database.members.create).toHaveBeenCalledWith(expectedMemberArgs);
|
||||
expect(database.members.create).toHaveBeenCalledTimes(1);
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
describe('updateMemberField', () => {
|
||||
const {database} = require('../../src/database.js');
|
||||
beforeEach(() => {
|
||||
utils.setExpirationWarning = jest.fn().mockReturnValue(`warning`);
|
||||
memberRepo.updateMemberField = jest.fn().mockResolvedValue([1]);
|
||||
jest.spyOn(memberHelper, "setExpirationWarning").mockReturnValue(' warning');
|
||||
database.members = {
|
||||
update: jest.fn().mockResolvedValue([1])
|
||||
};
|
||||
})
|
||||
|
||||
test('calls setExpirationWarning if attachmentExpiration', async () => {
|
||||
return memberHelper.updateMemberField(authorId, mockMember.name, "propic", mockMember.propic, attachmentExpiration).then((res) => {
|
||||
expect(memberHelper.setExpirationWarning).toHaveBeenCalledTimes(1);
|
||||
expect(memberHelper.setExpirationWarning).toHaveBeenCalledWith(mockMember.propic);
|
||||
})
|
||||
})
|
||||
|
||||
test.each([
|
||||
['name', mockMember.name, undefined, `Updated name for ${mockMember.name} to ${mockMember.name}.`],
|
||||
['displayname', mockMember.displayname, undefined, `Updated displayname for ${mockMember.name} to ${mockMember.displayname}.`],
|
||||
['proxy', mockMember.proxy, undefined, `Updated proxy for ${mockMember.name} to ${mockMember.proxy}.`],
|
||||
['propic', mockMember.propic, undefined, `Updated propic for ${mockMember.name} to ${mockMember.propic}.`],
|
||||
['propic', mockMember.propic,
|
||||
'warning', `Updated propic for ${mockMember.name} to ${mockMember.propic}. warning.`]
|
||||
])('calls database.members.update with correct column and value and return string', async (columnName, value, attachmentExpiration, expected) => {
|
||||
// Act
|
||||
const res = await memberHelper.updateMemberField(authorId, mockMember.name, columnName, value, attachmentExpiration)
|
||||
// Assert
|
||||
expect(res).toEqual(expected);
|
||||
expect(memberRepo.updateMemberField).toHaveBeenCalledTimes(1);
|
||||
expect(memberRepo.updateMemberField).toHaveBeenCalledWith(authorId, mockMember.name, columnName, value)
|
||||
['name', mockMember.name, null, `Updated name for ${mockMember.name} to ${mockMember.name}`],
|
||||
['displayname', mockMember.displayname, null, `Updated name for ${mockMember.name} to ${mockMember.displayname}`],
|
||||
['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, 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) => {
|
||||
// Arrange
|
||||
return memberHelper.updateMemberField(authorId, mockMember.name, columnName, value, attachmentExpiration).then((res) => {
|
||||
// Act
|
||||
expect(database.members.update).toHaveBeenCalledTimes(1);
|
||||
expect(database.members.update).toHaveBeenCalledWith({[columnName]: value}, {
|
||||
where: {
|
||||
name: {[Op.iLike]: mockMember.name},
|
||||
userid: authorId
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('if database.members.update returns 0 rows changed, throw error', async () => {
|
||||
test('if database.members.update returns 0 rows changed, throw error', () => {
|
||||
// Arrange
|
||||
memberRepo.updateMemberField = jest.fn().mockResolvedValue(0);
|
||||
database.members = {
|
||||
update: jest.fn().mockResolvedValue([0])
|
||||
};
|
||||
// Act
|
||||
await expect(memberHelper.updateMemberField(authorId, mockMember.name, "displayname", mockMember.displayname)).rejects.toThrow(`Can't update ${mockMember.name}. ${enums.err.NO_MEMBER}.`);
|
||||
return memberHelper.updateMemberField(authorId, mockMember.name, "displayname", mockMember.displayname).catch((res) => {
|
||||
expect(res).toEqual(new Error(`Can't update ${mockMember.name}. ${enums.err.NO_MEMBER}.`))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('checkIfProxyExists', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
memberRepo.getMembersByAuthor.mockResolvedValue([mockMember]);
|
||||
jest.spyOn(memberHelper, "getMembersByAuthor").mockResolvedValue([mockMember]);
|
||||
})
|
||||
|
||||
test.each([
|
||||
@@ -703,30 +742,32 @@ describe('MemberHelper', () => {
|
||||
['SP: text'],
|
||||
['text --SP'],
|
||||
])('%s should call getMembersByAuthor and return false', async (proxy) => {
|
||||
// Act
|
||||
const res = await memberHelper.checkIfProxyExists(authorId, proxy)
|
||||
// Assert
|
||||
expect(res).toEqual(false)
|
||||
expect(memberRepo.getMembersByAuthor).toHaveBeenCalledTimes(1);
|
||||
expect(memberRepo.getMembersByAuthor).toHaveBeenCalledWith(authorId);
|
||||
return memberHelper.checkIfProxyExists(authorId, proxy).then((res) => {
|
||||
expect(res).toEqual(false)
|
||||
expect(memberHelper.getMembersByAuthor).toHaveBeenCalledTimes(1);
|
||||
expect(memberHelper.getMembersByAuthor).toHaveBeenCalledWith(authorId);
|
||||
})
|
||||
})
|
||||
|
||||
test.each([
|
||||
['--', enums.err.NO_TEXT_FOR_PROXY, false],
|
||||
[' ', enums.err.NO_TEXT_FOR_PROXY, false],
|
||||
['text', enums.err.NO_PROXY_WRAPPER, false],
|
||||
])('%s returns correct error and does not call getMemberByAuthor', async (proxy, error, shouldCall) => {
|
||||
// Act & Assert
|
||||
await expect(memberHelper.checkIfProxyExists(authorId, proxy)).rejects.toThrow(error);
|
||||
|
||||
expect(memberRepo.getMembersByAuthor).not.toHaveBeenCalled();
|
||||
['--text', enums.err.PROXY_EXISTS, true]
|
||||
])('%s returns correct error and calls getMembersByAuthor if appropriate', async (proxy, error, shouldCall) => {
|
||||
return memberHelper.checkIfProxyExists(authorId, proxy).catch((res) => {
|
||||
expect(res).toEqual(new Error(error))
|
||||
if (shouldCall) {
|
||||
expect(memberHelper.getMembersByAuthor).toHaveBeenCalledTimes(1);
|
||||
expect(memberHelper.getMembersByAuthor).toHaveBeenCalledWith(authorId);
|
||||
}
|
||||
else {
|
||||
expect(memberHelper.getMembersByAuthor).not.toHaveBeenCalled();
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
test('--text returns correct error and calls getMemberByAuthor', async () => {
|
||||
await expect(memberHelper.checkIfProxyExists(authorId, "--text")).rejects.toThrow(enums.err.PROXY_EXISTS);
|
||||
expect(memberRepo.getMembersByAuthor).toHaveBeenCalledTimes(1);
|
||||
expect(memberRepo.getMembersByAuthor).toHaveBeenCalledWith(authorId);
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
|
||||
@@ -2,16 +2,14 @@ const env = require('dotenv');
|
||||
env.config();
|
||||
|
||||
|
||||
jest.mock('../../src/repositories/memberRepo.js', () => {
|
||||
return {
|
||||
memberRepo: {
|
||||
getMembersByAuthor: jest.fn()
|
||||
}
|
||||
}
|
||||
jest.mock('../../src/helpers/memberHelper.js', () => {
|
||||
return {memberHelper: {
|
||||
getMembersByAuthor: jest.fn()
|
||||
}}
|
||||
})
|
||||
|
||||
const {memberHelper} = require("../../src/helpers/memberHelper.js");
|
||||
const {messageHelper} = require("../../src/helpers/messageHelper.js");
|
||||
const {memberRepo} = require("../../src/repositories/memberRepo");
|
||||
|
||||
describe('messageHelper', () => {
|
||||
|
||||
@@ -22,11 +20,11 @@ describe('messageHelper', () => {
|
||||
|
||||
describe('parseCommandArgs', () => {
|
||||
test.each([
|
||||
['pf;member', ['']],
|
||||
['pf;member add somePerson "Some Person"', ['add', 'somePerson', 'Some Person']],
|
||||
['pf;member add \"Some Person\"', ['add', 'Some Person']],
|
||||
['pf;member add somePerson \'Some Person\'', ['add', 'somePerson', 'Some Person']],
|
||||
['pf;member add somePerson \"\'Some\' Person\"', ['add', 'somePerson', 'Some Person']],
|
||||
['pk;member', ['']],
|
||||
['pk;member add somePerson "Some Person"', ['add', 'somePerson', 'Some Person']],
|
||||
['pk;member add \"Some Person\"', ['add', 'Some Person']],
|
||||
['pk;member add somePerson \'Some Person\'', ['add', 'somePerson', 'Some Person']],
|
||||
['pk;member add somePerson \"\'Some\' Person\"', ['add', 'somePerson', 'Some Person']],
|
||||
])('%s returns correct arguments', (content, expected) => {
|
||||
// Arrange
|
||||
const command = "member";
|
||||
@@ -54,7 +52,7 @@ describe('messageHelper', () => {
|
||||
const attachmentUrl = "../oya.png"
|
||||
|
||||
beforeEach(() => {
|
||||
memberRepo.getMembersByAuthor = jest.fn().mockImplementation((specificAuthorId) => {
|
||||
memberHelper.getMembersByAuthor = jest.fn().mockImplementation((specificAuthorId) => {
|
||||
if (specificAuthorId === "1") return membersFor1;
|
||||
if (specificAuthorId === "2") return membersFor2;
|
||||
if (specificAuthorId === "3") return membersFor3;
|
||||
@@ -74,16 +72,17 @@ describe('messageHelper', () => {
|
||||
['2', 'hello', null, undefined],
|
||||
['2', '--hello', null, undefined],
|
||||
['2', 'hello', attachmentUrl, undefined],
|
||||
['2', '--hello', attachmentUrl, undefined],
|
||||
['2', '--hello', attachmentUrl,undefined],
|
||||
['3', 'hello', null, {}],
|
||||
['3', '--hello', null, {}],
|
||||
['3', 'hello', attachmentUrl, {}],
|
||||
['3', '--hello', attachmentUrl, {}],
|
||||
])('ID %s with string %s returns correct proxy', async (specificAuthorId, content, attachmentUrl, expected) => {
|
||||
['3', '--hello', attachmentUrl,{}],
|
||||
])('ID %s with string %s returns correct proxy', async(specificAuthorId, content, attachmentUrl, expected) => {
|
||||
// Act
|
||||
const res = await messageHelper.parseProxyTags(specificAuthorId, content, attachmentUrl);
|
||||
// Assert
|
||||
expect(res).toEqual(expected);
|
||||
return messageHelper.parseProxyTags(specificAuthorId, content, attachmentUrl).then((res) => {
|
||||
// Assert
|
||||
expect(res).toEqual(expected);
|
||||
})
|
||||
});
|
||||
})
|
||||
|
||||
|
||||
@@ -1,86 +1,15 @@
|
||||
const {enums} = require("../../src/enums");
|
||||
|
||||
const fetchMock = require('jest-fetch-mock');
|
||||
fetchMock.enableMocks();
|
||||
|
||||
const {utils} = require("../../src/helpers/utils.js");
|
||||
|
||||
describe('utils', () => {
|
||||
|
||||
const attachmentUrl = 'oya.png';
|
||||
const expirationString = new Date("2026-01-01").toDateString();
|
||||
let blob;
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
jest.clearAllMocks();
|
||||
blob = new Blob([JSON.stringify({attachmentUrl: attachmentUrl})], {type: 'image/png'});
|
||||
global.fetch = jest.fn(() =>
|
||||
Promise.resolve({
|
||||
blob: () => Promise.resolve(blob),
|
||||
})
|
||||
);
|
||||
|
||||
})
|
||||
|
||||
describe('checkImageFormatValidity', () => {
|
||||
|
||||
test('calls fetch with imageUrl and returns true if no errors', async() => {
|
||||
// Act
|
||||
const res = await utils.checkImageFormatValidity(attachmentUrl);
|
||||
// Assert
|
||||
expect(res).toBe(true);
|
||||
expect(fetch).toHaveBeenCalledTimes(1);
|
||||
expect(fetch).toHaveBeenCalledWith(attachmentUrl);
|
||||
})
|
||||
|
||||
test('throws error if fetch returns error', async() => {
|
||||
// Arrange
|
||||
global.fetch = jest.fn().mockRejectedValue(new Error('error'));
|
||||
// Act & Assert
|
||||
await expect(utils.checkImageFormatValidity(attachmentUrl)).rejects.toThrow(`${enums.err.PROPIC_CANNOT_LOAD}: error`);
|
||||
})
|
||||
|
||||
test('throws error if blob returns error', async() => {
|
||||
// Arrange
|
||||
global.fetch = jest.fn(() =>
|
||||
Promise.resolve({
|
||||
blob: () => Promise.reject(new Error('error'))
|
||||
}))
|
||||
// Act & Assert
|
||||
await expect(utils.checkImageFormatValidity(attachmentUrl)).rejects.toThrow('error');
|
||||
})
|
||||
|
||||
test('throws error if blob in wrong format', async() => {
|
||||
// Arrange
|
||||
blob = new Blob([JSON.stringify({attachmentUrl})], {type: 'text/html'});
|
||||
global.fetch = jest.fn(() =>
|
||||
Promise.resolve({
|
||||
blob: () => Promise.resolve(blob),
|
||||
})
|
||||
);
|
||||
// Act & Assert
|
||||
await expect(utils.checkImageFormatValidity(attachmentUrl)).rejects.toThrow(enums.err.PROPIC_FAILS_REQUIREMENTS);
|
||||
})
|
||||
})
|
||||
|
||||
describe('setExpirationWarning', () => {
|
||||
test('sets warning if image Url starts with Fluxer host', () => {
|
||||
// Act
|
||||
const result = utils.setExpirationWarning(`${enums.misc.FLUXER_ATTACHMENT_URL}${attachmentUrl}`);
|
||||
// Assert
|
||||
expect(result).toEqual(enums.misc.ATTACHMENT_EXPIRATION_WARNING);
|
||||
})
|
||||
|
||||
test('sets warning if expiration string exists', () => {
|
||||
const result = utils.setExpirationWarning(null, expirationString);
|
||||
// Assert
|
||||
expect(result).toEqual(`${enums.misc.ATTACHMENT_EXPIRATION_WARNING}. Expiration date: *${expirationString}*.`);
|
||||
})
|
||||
|
||||
test('returns null if img url does not start iwth fluxer host and no expiration', () => {
|
||||
// Act
|
||||
const result = utils.setExpirationWarning(attachmentUrl);
|
||||
// Assert
|
||||
expect(result).toBeNull();
|
||||
})
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
|
||||
@@ -14,44 +14,10 @@ const {webhookHelper} = require("../../src/helpers/webhookHelper.js");
|
||||
const {enums} = require("../../src/enums");
|
||||
|
||||
describe('webhookHelper', () => {
|
||||
const channelId = '123';
|
||||
const authorId = '456';
|
||||
const guildId = '789';
|
||||
const text = "hello";
|
||||
let client, member, attachments, message, webhook;
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
jest.clearAllMocks();
|
||||
client = {
|
||||
channels: {
|
||||
get: jest.fn().mockReturnValue(channelId)
|
||||
}
|
||||
}
|
||||
member = {proxy: "--text", name: 'somePerson', displayname: "Some Person", propic: 'oya.png'};
|
||||
attachments = {
|
||||
size: 1,
|
||||
first: () => {return channelId;}
|
||||
};
|
||||
|
||||
message = {
|
||||
client,
|
||||
channelId: channelId,
|
||||
content: text,
|
||||
attachments: attachments,
|
||||
author: {
|
||||
id: authorId
|
||||
},
|
||||
guild: {
|
||||
guildId: guildId
|
||||
},
|
||||
reply: jest.fn().mockResolvedValue(),
|
||||
delete: jest.fn().mockResolvedValue()
|
||||
}
|
||||
|
||||
webhook = {
|
||||
send: async() => jest.fn().mockResolvedValue()
|
||||
}
|
||||
})
|
||||
|
||||
describe(`sendMessageAsMember`, () => {
|
||||
@@ -68,7 +34,9 @@ describe('webhookHelper', () => {
|
||||
author: {
|
||||
id: '123'
|
||||
},
|
||||
guildId: '123',
|
||||
guild: {
|
||||
guildId: '123'
|
||||
},
|
||||
reply: jest.fn()
|
||||
}
|
||||
const member = {proxy: "--text", name: 'somePerson', displayname: "Some Person"};
|
||||
@@ -82,24 +50,25 @@ describe('webhookHelper', () => {
|
||||
// Arrange
|
||||
messageHelper.parseProxyTags.mockResolvedValue({});
|
||||
// Act
|
||||
const res = await webhookHelper.sendMessageAsMember(client, message)
|
||||
// Assert
|
||||
expect(res).toBeUndefined();
|
||||
expect(messageHelper.parseProxyTags).toHaveBeenCalledTimes(1);
|
||||
expect(messageHelper.parseProxyTags).toHaveBeenCalledWith(message.author.id, content, null);
|
||||
expect(webhookHelper.replaceMessage).not.toHaveBeenCalled();
|
||||
return webhookHelper.sendMessageAsMember(client, message).then((res) => {
|
||||
expect(res).toBeUndefined();
|
||||
expect(messageHelper.parseProxyTags).toHaveBeenCalledTimes(1);
|
||||
expect(messageHelper.parseProxyTags).toHaveBeenCalledWith(message.author.id, content, null);
|
||||
expect(webhookHelper.replaceMessage).not.toHaveBeenCalled();
|
||||
})
|
||||
})
|
||||
|
||||
test('calls parseProxyTags and returns if proxyMatch is undefined', async() => {
|
||||
// Arrange
|
||||
messageHelper.parseProxyTags.mockResolvedValue(undefined);
|
||||
// Act
|
||||
const res = await webhookHelper.sendMessageAsMember(client, message)
|
||||
// Assert
|
||||
expect(res).toBeUndefined();
|
||||
expect(messageHelper.parseProxyTags).toHaveBeenCalledTimes(1);
|
||||
expect(messageHelper.parseProxyTags).toHaveBeenCalledWith(message.author.id, content, null);
|
||||
expect(webhookHelper.replaceMessage).not.toHaveBeenCalled();
|
||||
return webhookHelper.sendMessageAsMember(client, message).then((res) => {
|
||||
// Assert
|
||||
expect(res).toBeUndefined();
|
||||
expect(messageHelper.parseProxyTags).toHaveBeenCalledTimes(1);
|
||||
expect(messageHelper.parseProxyTags).toHaveBeenCalledWith(message.author.id, content, null);
|
||||
expect(webhookHelper.replaceMessage).not.toHaveBeenCalled();
|
||||
})
|
||||
})
|
||||
|
||||
test('calls parseProxyTags with attachmentUrl', async() => {
|
||||
@@ -110,22 +79,27 @@ describe('webhookHelper', () => {
|
||||
return {url: 'oya.png'}
|
||||
}
|
||||
}
|
||||
// message.attachments.set('attachment', {url: 'oya.png'})
|
||||
// message.attachments.set('first', () => {return {url: 'oya.png'}})
|
||||
messageHelper.parseProxyTags.mockResolvedValue(undefined);
|
||||
// Act
|
||||
const res = await webhookHelper.sendMessageAsMember(client, message)
|
||||
// Assert
|
||||
expect(res).toBeUndefined();
|
||||
expect(messageHelper.parseProxyTags).toHaveBeenCalledTimes(1);
|
||||
expect(messageHelper.parseProxyTags).toHaveBeenCalledWith(message.author.id, content, 'oya.png');
|
||||
return webhookHelper.sendMessageAsMember(client, message).then((res) => {
|
||||
// Assert
|
||||
expect(res).toBeUndefined();
|
||||
expect(messageHelper.parseProxyTags).toHaveBeenCalledTimes(1);
|
||||
expect(messageHelper.parseProxyTags).toHaveBeenCalledWith(message.author.id, content, 'oya.png');
|
||||
})
|
||||
})
|
||||
|
||||
test('if message matches member proxy but is not sent from a guild, throw an error', async() => {
|
||||
// Arrange
|
||||
message.guildId = null;
|
||||
messageHelper.parseProxyTags.mockResolvedValue(proxyMessage);
|
||||
// Act and Assert
|
||||
await expect(webhookHelper.sendMessageAsMember(client, message)).rejects.toThrow(enums.err.NOT_IN_SERVER);
|
||||
expect(webhookHelper.replaceMessage).not.toHaveBeenCalled();
|
||||
// Act
|
||||
return webhookHelper.sendMessageAsMember(client, message).catch((res) => {
|
||||
// Assert
|
||||
expect(res).toEqual(new Error(enums.err.NOT_IN_SERVER));
|
||||
expect(webhookHelper.replaceMessage).not.toHaveBeenCalled();
|
||||
})
|
||||
})
|
||||
|
||||
test('if message matches member proxy and sent in a guild and has an attachment, reply to message with ping', async() => {
|
||||
@@ -135,11 +109,12 @@ describe('webhookHelper', () => {
|
||||
messageHelper.parseProxyTags.mockResolvedValue(proxyMessage);
|
||||
const expected = `${enums.misc.ATTACHMENT_SENT_BY} ${proxyMessage.member.displayname}`
|
||||
// Act
|
||||
await webhookHelper.sendMessageAsMember(client, message)
|
||||
// Assert
|
||||
expect(message.reply).toHaveBeenCalledTimes(1);
|
||||
expect(message.reply).toHaveBeenCalledWith(expected);
|
||||
expect(webhookHelper.replaceMessage).not.toHaveBeenCalled();
|
||||
return webhookHelper.sendMessageAsMember(client, message).then((res) => {
|
||||
// Assert
|
||||
expect(message.reply).toHaveBeenCalledTimes(1);
|
||||
expect(message.reply).toHaveBeenCalledWith(expected);
|
||||
expect(webhookHelper.replaceMessage).not.toHaveBeenCalled();
|
||||
})
|
||||
})
|
||||
|
||||
test('if message matches member proxy and sent in a guild channel and no attachment, calls replace message', async() => {
|
||||
@@ -149,26 +124,63 @@ describe('webhookHelper', () => {
|
||||
messageHelper.parseProxyTags.mockResolvedValue(proxyMessage);
|
||||
jest.spyOn(webhookHelper, 'replaceMessage').mockResolvedValue();
|
||||
// Act
|
||||
await webhookHelper.sendMessageAsMember(client, message);
|
||||
// Assert
|
||||
expect(message.reply).not.toHaveBeenCalled();
|
||||
expect(webhookHelper.replaceMessage).toHaveBeenCalledTimes(1);
|
||||
expect(webhookHelper.replaceMessage).toHaveBeenCalledWith(client, message, proxyMessage.message, proxyMessage.member);
|
||||
return webhookHelper.sendMessageAsMember(client, message).then((res) => {
|
||||
// Assert
|
||||
expect(message.reply).not.toHaveBeenCalled();
|
||||
expect(webhookHelper.replaceMessage).toHaveBeenCalledTimes(1);
|
||||
expect(webhookHelper.replaceMessage).toHaveBeenCalledWith(client, message, proxyMessage.message, proxyMessage.member);
|
||||
})
|
||||
})
|
||||
|
||||
test('if replace message throws error, throw same error and does not call message.reply', async () => {
|
||||
test('if replace message throws error, throw same error', async() => {
|
||||
// Arrange
|
||||
message.guildId = '123';
|
||||
messageHelper.parseProxyTags.mockResolvedValue(proxyMessage);
|
||||
jest.spyOn(webhookHelper, 'replaceMessage').mockRejectedValue(new Error("error"));
|
||||
jest.spyOn(webhookHelper, 'replaceMessage').mockImplementation(() => {throw new Error("error")});
|
||||
// Act
|
||||
await expect(webhookHelper.sendMessageAsMember(client, message)).rejects.toThrow("error");
|
||||
// Assert
|
||||
expect(message.reply).not.toHaveBeenCalled();
|
||||
return webhookHelper.sendMessageAsMember(client, message).catch((res) => {
|
||||
// Assert
|
||||
expect(message.reply).not.toHaveBeenCalled();
|
||||
expect(webhookHelper.replaceMessage).toHaveBeenCalledTimes(1);
|
||||
expect(webhookHelper.replaceMessage).toHaveBeenCalledWith(client, message, proxyMessage.message, proxyMessage.member);
|
||||
expect(res).toEqual(new Error('error'));
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe(`replaceMessage`, () => {
|
||||
const channelId = '123';
|
||||
const authorId = '456';
|
||||
const guildId = '789';
|
||||
const text = "hello";
|
||||
const client = {
|
||||
channels: {
|
||||
get: jest.fn().mockReturnValue(channelId)
|
||||
}
|
||||
}
|
||||
const member = {proxy: "--text", name: 'somePerson', displayname: "Some Person", propic: 'oya.png'};
|
||||
const attachments= {
|
||||
size: 1,
|
||||
first: () => {return channelId;}
|
||||
};
|
||||
const message = {
|
||||
client,
|
||||
channelId: channelId,
|
||||
content: text,
|
||||
attachments: attachments,
|
||||
author: {
|
||||
id: authorId
|
||||
},
|
||||
guild: {
|
||||
guildId: guildId
|
||||
},
|
||||
reply: jest.fn(),
|
||||
delete: jest.fn()
|
||||
}
|
||||
|
||||
const webhook = {
|
||||
send: async() => jest.fn().mockResolvedValue()
|
||||
}
|
||||
|
||||
test('does not call anything if text is 0 or message has no attachments', async() => {
|
||||
// Arrange
|
||||
@@ -180,12 +192,13 @@ describe('webhookHelper', () => {
|
||||
message.attachments = noAttachments;
|
||||
jest.spyOn(webhookHelper, 'getOrCreateWebhook').mockResolvedValue(webhook);
|
||||
// Act
|
||||
await webhookHelper.replaceMessage(client, message, emptyText, member)
|
||||
expect(webhookHelper.getOrCreateWebhook).not.toHaveBeenCalled();
|
||||
expect(message.delete).not.toHaveBeenCalled();
|
||||
return webhookHelper.replaceMessage(client, message, emptyText, member).then(() => {
|
||||
expect(webhookHelper.getOrCreateWebhook).not.toHaveBeenCalled();
|
||||
expect(message.delete).not.toHaveBeenCalled();
|
||||
})
|
||||
})
|
||||
|
||||
test('calls getOrCreateWebhook and message.delete with correct arguments if text > 0 & < 2000', async() => {
|
||||
test('calls getOrCreateWebhook and message.delete with correct arguments if text >= 0', async() => {
|
||||
// Arrange
|
||||
message.attachments = {
|
||||
size: 0,
|
||||
@@ -194,108 +207,58 @@ describe('webhookHelper', () => {
|
||||
};
|
||||
jest.spyOn(webhookHelper, 'getOrCreateWebhook').mockResolvedValue(webhook);
|
||||
// Act
|
||||
await webhookHelper.replaceMessage(client, message, text, member);
|
||||
// Assert
|
||||
expect(webhookHelper.getOrCreateWebhook).toHaveBeenCalledTimes(1);
|
||||
expect(webhookHelper.getOrCreateWebhook).toHaveBeenCalledWith(client, channelId);
|
||||
expect(message.delete).toHaveBeenCalledTimes(1);
|
||||
expect(message.delete).toHaveBeenCalledWith();
|
||||
return webhookHelper.replaceMessage(client, message, text, member).then((res) => {
|
||||
// Assert
|
||||
expect(webhookHelper.getOrCreateWebhook).toHaveBeenCalledTimes(1);
|
||||
expect(webhookHelper.getOrCreateWebhook).toHaveBeenCalledWith(client, channelId);
|
||||
expect(message.delete).toHaveBeenCalledTimes(1);
|
||||
expect(message.delete).toHaveBeenCalledWith();
|
||||
})
|
||||
})
|
||||
|
||||
// TODO: Flaky for some reason. Skipping until attachments are implemented
|
||||
test.skip('calls getOrCreateWebhook and message.delete with correct arguments if attachments exist', async() => {
|
||||
// TODO: flaky for some reason
|
||||
test('calls getOrCreateWebhook and message.delete with correct arguments if attachments exist', async() => {
|
||||
// Arrange
|
||||
const emptyText = ''
|
||||
jest.spyOn(webhookHelper, 'getOrCreateWebhook').mockResolvedValue(webhook);
|
||||
// Act
|
||||
await webhookHelper.replaceMessage(client, message, emptyText, member);
|
||||
// Assert
|
||||
// expect(webhookHelper.getOrCreateWebhook).toHaveBeenCalledTimes(1);
|
||||
// expect(webhookHelper.getOrCreateWebhook).toHaveBeenCalledWith(client, channelId);
|
||||
expect(message.delete).toHaveBeenCalledTimes(1);
|
||||
expect(message.delete).toHaveBeenCalledWith();
|
||||
return webhookHelper.replaceMessage(client, message, emptyText, member).then((res) => {
|
||||
// Assert
|
||||
expect(webhookHelper.getOrCreateWebhook).toHaveBeenCalledTimes(1);
|
||||
expect(webhookHelper.getOrCreateWebhook).toHaveBeenCalledWith(client, channelId);
|
||||
expect(message.delete).toHaveBeenCalledTimes(1);
|
||||
expect(message.delete).toHaveBeenCalledWith();
|
||||
})
|
||||
})
|
||||
|
||||
test('calls returnBufferFromText if text is more than 2000 characters', async() => {
|
||||
test('calls returnBufferFromText and console error if webhook.send returns error', async() => {
|
||||
// Arrange
|
||||
const text = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbb";
|
||||
message.content = text;
|
||||
const file = Buffer.from(text, 'utf-8');
|
||||
const returnedBuffer = {text: 'bbbb', file: file};
|
||||
const expected = {content: returnedBuffer.text, username: member.displayname, avatar_url: member.propic, files: [{name: 'text.txt', data: returnedBuffer.file}]};
|
||||
|
||||
const returnedBuffer = {text: text, file: file};
|
||||
const expected2ndSend = {content: returnedBuffer.text, username: member.displayname, avatar_url: member.propic, files: [{name: 'text.txt', data: returnedBuffer.file}]};
|
||||
jest.mock('console', () => ({error: jest.fn()}));
|
||||
jest.spyOn(webhookHelper, 'getOrCreateWebhook').mockResolvedValue(webhook);
|
||||
webhook.send = jest.fn();
|
||||
messageHelper.returnBufferFromText = jest.fn().mockReturnValue(returnedBuffer);
|
||||
|
||||
webhook.send = jest.fn().mockImplementationOnce(async() => {throw new Error('error')});
|
||||
messageHelper.returnBufferFromText = jest.fn().mockResolvedValue(returnedBuffer);
|
||||
// Act
|
||||
await webhookHelper.replaceMessage(client, message, text, member);
|
||||
// Assert
|
||||
expect(messageHelper.returnBufferFromText).toHaveBeenCalledTimes(1);
|
||||
expect(messageHelper.returnBufferFromText).toHaveBeenCalledWith(text);
|
||||
expect(webhook.send).toHaveBeenCalledTimes(1);
|
||||
expect(webhook.send).toHaveBeenCalledWith(expected);
|
||||
return webhookHelper.replaceMessage(client, message, text, member).catch((res) => {
|
||||
// Assert
|
||||
expect(messageHelper.returnBufferFromText).toHaveBeenCalledTimes(1);
|
||||
expect(messageHelper.returnBufferFromText).toHaveBeenCalledWith(text);
|
||||
expect(webhook.send).toHaveBeenCalledTimes(2);
|
||||
expect(webhook.send).toHaveBeenNthCalledWith(2, expected2ndSend);
|
||||
expect(console.error).toHaveBeenCalledTimes(1);
|
||||
expect(console.error).toHaveBeenCalledWith(new Error('error'));
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe(`getOrCreateWebhook`, () => {
|
||||
let channel;
|
||||
|
||||
beforeEach(async () => {
|
||||
channel = {
|
||||
createWebhook: jest.fn().mockResolvedValue()
|
||||
}
|
||||
jest.spyOn(webhookHelper, 'getWebhook').mockResolvedValue(webhook);
|
||||
})
|
||||
|
||||
test('throws error if channel does not allow webhooks', async() => {
|
||||
channel.createWebhook = false;
|
||||
|
||||
await expect(webhookHelper.getOrCreateWebhook(client, channel)).rejects.toThrow(enums.err.NO_WEBHOOKS_ALLOWED);
|
||||
})
|
||||
|
||||
test('calls getWebhook if channel allows webhooks and returns webhook', async() => {
|
||||
const res = await webhookHelper.getOrCreateWebhook(client, channel);
|
||||
expect(webhookHelper.getWebhook).toHaveBeenCalledTimes(1);
|
||||
expect(webhookHelper.getWebhook).toHaveBeenCalledWith(client, channel);
|
||||
expect(res).toEqual(webhook);
|
||||
})
|
||||
|
||||
test("calls createWebhook if getWebhook doesn't return webhook", async() => {
|
||||
jest.spyOn(webhookHelper, 'getWebhook').mockResolvedValue();
|
||||
await webhookHelper.getOrCreateWebhook(client, channel);
|
||||
expect(channel.createWebhook).toHaveBeenCalledTimes(1);
|
||||
expect(channel.createWebhook).toHaveBeenCalledWith({name: 'PluralFlux Proxy Webhook'});
|
||||
})
|
||||
})
|
||||
|
||||
describe(`getWebhook`, () => {
|
||||
let webhook1, webhook2, channel;
|
||||
beforeEach(() => {
|
||||
webhook1 = {name: 'PluralFlux Proxy Webhook'};
|
||||
webhook2 = {name: 'other webhook'};
|
||||
channel = {
|
||||
fetchWebhooks: jest.fn().mockResolvedValue([webhook1, webhook2])
|
||||
}
|
||||
})
|
||||
|
||||
test('calls fetchWebhooks and returns correct webhook', async() => {
|
||||
// Act
|
||||
const res = await webhookHelper.getWebhook(client, channel);
|
||||
// Assert
|
||||
expect(res).toEqual(webhook1);
|
||||
expect(channel.fetchWebhooks).toHaveBeenCalledTimes(1);
|
||||
expect(channel.fetchWebhooks).toHaveBeenCalledWith();
|
||||
})
|
||||
|
||||
test('if fetchWebhooks returns no webhooks, return', async() => {
|
||||
// Arrange
|
||||
channel.fetchWebhooks = jest.fn().mockResolvedValue([]);
|
||||
// Act
|
||||
const res = await webhookHelper.getWebhook(client, channel);
|
||||
// Assert
|
||||
expect(res).toBeUndefined();
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": [
|
||||
"es2021"
|
||||
],
|
||||
"target": "es2021",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"outDir": "./database/build",
|
||||
"rootDir": "./database",
|
||||
"esModuleInterop": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"sourceMap": true
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
FLUXER_BOT_TOKEN=<>
|
||||
POSTGRES_PASSWORD=<>
|
||||
POSTGRES_ENDPOINT=postgres
|
||||
PGADMIN_DEFAULT_EMAIL: <>
|
||||
PGADMIN_DEFAULT_PASSWORD: <>
|
||||
PGADMIN_CONFIG_SERVER_MODE: 'False'
|
||||
PGADMIN_CONFIG_MASTER_PASSWORD_REQUIRED: 'False'
|
||||
Reference in New Issue
Block a user