Skip to content

Commit

Permalink
add more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Multivit4min committed Dec 11, 2019
1 parent d93d4af commit c8d6a96
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 8 deletions.
4 changes: 2 additions & 2 deletions src/Commander.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,14 @@ export class Commander {
commands.forEach(cmd => this.runCommand(cmd, args, event, t))
}

private runCommand(
private async runCommand(
cmd: BaseCommand,
args: string,
event: CommanderTextMessage,
translate: TranslationStringGetter
) {
try {
cmd.handleRequest(args, event)
await cmd.handleRequest(args, event)
} catch (error) {
if (error instanceof CommandNotFoundError) {
event.reply(translate(this.config.SUBCOMMAND_NOT_FOUND, { error, cmd }))
Expand Down
8 changes: 4 additions & 4 deletions src/command/BaseCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Throttle } from "../util/Throttle"
import { ThrottleError } from "../exceptions/ThrottleError"

export type permissionHandler = (invoker: TeamSpeakClient) => Promise<boolean>|boolean
export type runHandler = (event: CommanderTextMessage) => void
export type runHandler = (event: CommanderTextMessage) => (Promise<void>|void)

export abstract class BaseCommand {
protected commander: Commander
Expand All @@ -26,7 +26,7 @@ export abstract class BaseCommand {
abstract getUsage(): string
abstract hasPermission(client: TeamSpeakClient): Promise<boolean>
abstract validate(args: string): Record<string, any>
abstract handleRequest(args: string, ev: CommanderTextMessage): void
abstract async handleRequest(args: string, ev: CommanderTextMessage): Promise<void>

/** checks if the command is enabled */
isEnabled() {
Expand Down Expand Up @@ -160,8 +160,8 @@ export abstract class BaseCommand {
return (await Promise.all(this.permissionHandler.map(cb => cb(client)))).every(result => result)
}

protected dispatchCommand(ev: CommanderTextMessage) {
protected async dispatchCommand(ev: CommanderTextMessage) {
this.handleThrottle(ev.invoker)
this.runHandler.forEach(handle => handle({...ev}))
await Promise.all(this.runHandler.map(handle => handle({...ev})))
}
}
2 changes: 1 addition & 1 deletion src/command/Command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export class Command extends BaseCommand {
}

handleRequest(args: string, ev: CommanderTextMessage) {
this.dispatchCommand({ ...ev, arguments: this.validate(args) })
return this.dispatchCommand({ ...ev, arguments: this.validate(args) })
}

/**
Expand Down
94 changes: 94 additions & 0 deletions tests/Commander.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import { CommandNotFoundError } from "../src/exceptions/CommandNotFoundError"
import { ParseError } from "../src/exceptions/ParseError"
import { ThrottleError } from "../src/exceptions/ThrottleError"
import { TooManyArgumentsError } from "../src/exceptions/TooManyArgumentsError"
import { BaseCommand } from "../src/command/BaseCommand"
import { TranslationStringGetter } from "../src/util/types"
import { PermissionError } from "../src/exceptions/PermissionError"
import { TextMessageTargetMode } from "ts3-nodejs-library"
const replyMock = jest.fn()

describe("Command", () => {
Expand Down Expand Up @@ -109,6 +113,96 @@ describe("Command", () => {
})
})

describe("runCommand()", () => {
let cmd: BaseCommand
let translate: TranslationStringGetter
let teamspeak: any = {}
let handleRequestMock: jest.Mock

beforeEach(() => {
cmd = commander.createCommand("foo")
handleRequestMock = jest.fn()
cmd["handleRequest"] = handleRequestMock
translate = commander["getTranslator"](textEvent, teamspeak)
})

describe("error handling", () => {
it("should catch a CommandNotFoundError", async () => {
expect.assertions(1)
handleRequestMock.mockRejectedValue(new CommandNotFoundError("not found"))
await commander["runCommand"](cmd, "", textEvent, translate)
expect(replyMock).toBeCalledTimes(1)
})
it("should catch a PermissionError", async () => {
expect.assertions(1)
handleRequestMock.mockRejectedValue(new PermissionError("permission error"))
await commander["runCommand"](cmd, "", textEvent, translate)
expect(replyMock).toBeCalledTimes(1)
})
it("should catch a ParseError", async () => {
const argument: any = {}
expect.assertions(1)
handleRequestMock.mockRejectedValue(new ParseError("parse error", argument))
await commander["runCommand"](cmd, "", textEvent, translate)
expect(replyMock).toBeCalledTimes(1)
})
it("should catch a ThrottleError", async () => {
expect.assertions(1)
handleRequestMock.mockRejectedValue(new ThrottleError("throttle error"))
await commander["runCommand"](cmd, "", textEvent, translate)
expect(replyMock).toBeCalledTimes(1)
})
it("should catch a TooManyArgumentsError", async () => {
expect.assertions(1)
handleRequestMock.mockRejectedValue(new TooManyArgumentsError("too many arguments error"))
await commander["runCommand"](cmd, "", textEvent, translate)
expect(replyMock).toBeCalledTimes(1)
})
it("should throw a generic error", async () => {
expect.assertions(2)
const error = new Error("generic error")
handleRequestMock.mockRejectedValue(error)
await expect(commander["runCommand"](cmd, "", textEvent, translate)).rejects.toEqual(error)
expect(replyMock).toBeCalledTimes(0)
})
})
})

describe("getReplyOutput()", () => {
let sendTextMessageMock: jest.Mock
const teamspeak: any = {
}

beforeEach(() => {
sendTextMessageMock = jest.fn()
teamspeak.sendTextMessage = sendTextMessageMock
})

it("should retrieve the correct function to reply to a client", async () => {
expect.assertions(2)
textEvent.targetmode = TextMessageTargetMode.CLIENT
await Commander.getReplyFunction(textEvent, teamspeak)("foo")
expect(sendTextMessageMock).toHaveBeenCalledTimes(1)
expect(sendTextMessageMock).toBeCalledWith(1337, TextMessageTargetMode.CLIENT, "foo")
})

it("should retrieve the correct function to reply to a channel", async () => {
expect.assertions(2)
textEvent.targetmode = TextMessageTargetMode.CHANNEL
await Commander.getReplyFunction(textEvent, teamspeak)("foo")
expect(sendTextMessageMock).toHaveBeenCalledTimes(1)
expect(sendTextMessageMock).toBeCalledWith(1338, TextMessageTargetMode.CHANNEL, "foo")
})

it("should retrieve the correct function to reply to a server", async () => {
expect.assertions(2)
textEvent.targetmode = TextMessageTargetMode.SERVER
await Commander.getReplyFunction(textEvent, teamspeak)("foo")
expect(sendTextMessageMock).toHaveBeenCalledTimes(1)
expect(sendTextMessageMock).toBeCalledWith(0, TextMessageTargetMode.SERVER, "foo")
})
})

describe("addInstance()", () => {
let teamspeak: any = {
on: jest.fn(),
Expand Down
2 changes: 1 addition & 1 deletion tests/mocks/textmessageEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { CommanderTextMessage } from "../../src/util/types"
import { TextMessageTargetMode } from "ts3-nodejs-library"

export const textmessageEvent = (mock: (...args: any) => any): CommanderTextMessage => ({
invoker: <any>{ nick: "foo", isQuery: () => false },
invoker: <any>{ nick: "foo", isQuery: () => false, clid: 1337, cid: 1338 },
msg: "!test 123",
targetmode: TextMessageTargetMode.CHANNEL,
reply: mock,
Expand Down

0 comments on commit c8d6a96

Please sign in to comment.