Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Remove Code Climate Smell #90

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 21 additions & 4 deletions __tests__/commands/search.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ beforeEach(() => {
const setupRequiredMessage = 'Setup Required: Configure Google API keys in the environment variables';

describe('Search Command', () => {
const mockedConsoleError = jest.spyOn(console, 'error').mockImplementation(() => { return; });

afterEach(() => {
mockedConsoleError.mockReset();
});

describe('Environment Variables', () => {
test('Setup message when missing Google API Key ENV Var', async () => {
config.googleApiKey = undefined;
Expand All @@ -31,22 +37,33 @@ describe('Search Command', () => {
expect(sendMock).lastCalledWith(setupRequiredMessage);
});
});

test('With no results', async () => {
const mockedData = Promise.resolve({ data: noResults });
axiosMock.get.mockResolvedValueOnce(mockedData);
await Search.execute(['Nothing here'], mockMessage);
expect(sendMock).lastCalledWith('`No results found.`');
});

test('With results', async () => {
const mockedData = Promise.resolve({ data: results });
axiosMock.get.mockResolvedValueOnce(mockedData);
await Search.execute(['dingusy'], mockMessage);
expect(sendMock).lastCalledWith(results.items[0].link);
});
test('Malformed Response', async () => {

describe('Malformed Response', () => {
const mockedData = Promise.resolve({ data: {} });
axiosMock.get.mockResolvedValueOnce(mockedData);
await Search.execute(['NOPE'], mockMessage);
expect(sendMock).lastCalledWith("I'm Sorry Dave, I'm afraid I can't do that...");
beforeEach(async () => {
axiosMock.get.mockResolvedValueOnce(mockedData);
await Search.execute(['NOPE'], mockMessage);
});

test('it sends error message', () => {
expect(sendMock).lastCalledWith("I'm Sorry Dave, I'm afraid I can't do that...");
});
test('it logs an error message', () => {
expect(mockedConsoleError).lastCalledWith('Malformed Google Search Response: {}');
});
});
});
21 changes: 6 additions & 15 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

83 changes: 48 additions & 35 deletions src/commands/purge.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Client, DMChannel, Message } from 'discord.js';
import { Client, DMChannel, GroupDMChannel, Guild, Message, TextChannel } from 'discord.js';
import ICommand from '../library/iCommand';

let Purge: ICommand;
type channelTypes = 'dm' | 'group' | 'text' | 'voice' | 'category' | 'text';

export default Purge = class {

Expand All @@ -11,42 +12,54 @@ export default Purge = class {
}

public static execute(args: string[], msg: Message, bot: Client) {
const { guild } = msg;

/* global bot */
if (!guild.member(bot.user).hasPermission('MANAGE_CHANNELS')) {
return msg.reply("Bot doesn't have manage channels permissions.");
const { guild, channel } = msg;
if (!this.canManageChannels(guild, bot)) { return this.cannotManageChannelReply(msg); }
if (!this.userHasAccess(guild, msg)) { return this.unauthorizedReply(msg); }
if (channel instanceof DMChannel || channel instanceof GroupDMChannel) {
return this.invalidChannelType(msg);
}

// Make sure the person doing the command is a Board Member
const boardRole = guild.roles.find(role => role.name === 'Board Member' || role.name === 'Admin');
if (msg.member.roles.has(boardRole.id)) {
const { channel } = msg;

if (channel instanceof DMChannel) {
return;
}

// Grab the channels info
const chanName = channel.name;
const chanType = channel.type || 'text';

if (chanType === 'dm' || chanType === 'group') {
return;
}

// Delete the channel
channel.delete()
.then()
.catch(console.error);

// Now re-create the channel with the same name and type
guild.createChannel(chanName, chanType)
.then(newChannelName => console.log(`Created new channel ${newChannelName}`))
.catch(console.error);
} else {
return msg.reply("Sorry m8, you're not authorized to use that command.");
}
const safeChannel: TextChannel = channel;
return this.recreateChannel(guild, safeChannel, msg);
}

private static canManageChannels(guild: Guild, bot: Client) {
return guild.member(bot.user).hasPermission('MANAGE_CHANNELS');
}

private static userHasAccess(guild: Guild, msg: Message) {
const validRoles = ['Board Member', 'Admin'];
const boardRole = guild.roles.find(role => validRoles.includes(role.name));
return msg.member.roles.has(boardRole.id);
}

private static getChannelType(channel: TextChannel): channelTypes {
return channel.type || 'text';
}

private static recreateChannel(guild: Guild, channel: TextChannel, msg: Message) {
const chanName = channel.name;
const channelType = this.getChannelType(channel);
if (channelType === 'dm' || channelType === 'group') { return this.invalidChannelType(msg); }

channel.delete()
.then()
.catch(console.error);

return guild.createChannel(chanName, channelType)
.then(newChannelName => console.log(`Created new channel ${newChannelName}`))
.catch(console.error);
}

private static cannotManageChannelReply(msg: Message) {
return msg.reply("Bot doesn't have manage channels permissions.");
}

private static unauthorizedReply(msg: Message) {
return msg.reply("Sorry m8, you're not authorized to use that command.");
}

private static invalidChannelType(msg: Message) {
return msg.reply("Invalid channel type.");
}
};
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/* Basic Options */
"target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
// "lib": [], /* Specify library files to be included in the compilation. */
"lib": ["es2017"], /* Specify library files to be included in the compilation. */
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add access to array.includes

// "allowJs": true, /* Allow javascript files to be compiled. */
// "checkJs": true, /* Report errors in .js files. */
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
Expand Down