Skip to content

Commit

Permalink
Fixed bugs and added test coverage (#49)
Browse files Browse the repository at this point in the history
  • Loading branch information
amthorn authored May 25, 2021
1 parent 1cfdbab commit a3efa33
Show file tree
Hide file tree
Showing 11 changed files with 102 additions and 11 deletions.
4 changes: 2 additions & 2 deletions docs/administration.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ You can add individual admins to a project by tagging them using the following c
```
=== "Regex"
```
^\s*create admin [\w\s]+\s*$
^\s*create admin [\S]+\s*$
```

???+ important
Expand Down Expand Up @@ -67,7 +67,7 @@ You can remove individual admins to a project by tagging them using the followin
```
=== "Regex"
```
^\s*(delete|remove) admin [\w\s]+\s*$
^\s*(delete|remove) admin [\S]+\s*$
```

???+ important
Expand Down
2 changes: 1 addition & 1 deletion docs/queues.md
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ You can list out the members of a queue by issueing the following command:
```
=== "Regex"
```
^\s*get queue\s*$
^\s*get queue( \w+)?\s*$
```

???+ example
Expand Down
1 change: 1 addition & 0 deletions services/bot/src/commands/admins/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export class Create extends CommandBase implements ICommand {
public readonly AUTHORIZATION: Auth = Auth.PROJECT_ADMIN;
public readonly COMMAND_TYPE: CommandType = CommandType.CREATE;
public readonly COMMAND_BASE: string = 'admin';
public readonly ARGS: string = '{name:\\S+?}';
public readonly DESCRIPTION: string = 'Adds a target project admin';
/* eslint-enable jsdoc/require-jsdoc */

Expand Down
1 change: 1 addition & 0 deletions services/bot/src/commands/admins/remove.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export class Remove extends CommandBase implements ICommand {
public readonly AUTHORIZATION: Auth = Auth.PROJECT_ADMIN;
public readonly COMMAND_TYPE: CommandType = CommandType.OPERATION;
public readonly COMMAND_BASE: string = 'remove admin';
public readonly ARGS: string = '{name:\\S+?}';
public readonly DESCRIPTION: string = 'Removes a user as a project admin';
/* eslint-enable jsdoc/require-jsdoc */

Expand Down
6 changes: 5 additions & 1 deletion services/bot/src/commands/graphs/queueLengthHistory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export class Get extends CommandBase implements ICommand {
public readonly AUTHORIZATION: Auth = Auth.NONE;
public readonly COMMAND_TYPE: CommandType = CommandType.GET;
public readonly COMMAND_BASE: string = 'queue length history';
public readonly QUEUE: boolean = true;
public readonly DESCRIPTION: string = 'creates a graph of the queue length history';
/* eslint-enable jsdoc/require-jsdoc */

Expand All @@ -32,7 +33,10 @@ export class Get extends CommandBase implements ICommand {
const project = await CommandBase.getProject(initiative);
if (typeof project === 'string') return String(project);

const queue = project.queues.filter(i => i.name === project.currentQueue)[0];
// Get queue
const queueName = initiative.data.queue?.toUpperCase() || project.currentQueue;

const queue = project.queues.filter(i => i.name === queueName)[0];
if (queue.history.length > 0) {
const chart = await new QueueLength(queue).url;

Expand Down
2 changes: 1 addition & 1 deletion services/bot/src/commands/queue/addPerson.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export class AddPerson extends CommandBase implements ICommand {
public readonly AUTHORIZATION: Auth = Auth.PROJECT_ADMIN;
public readonly COMMAND_TYPE: CommandType = CommandType.OPERATION;
public readonly COMMAND_BASE: string = 'add person';
public readonly ARGS: string = '{name:.+?}';
public readonly ARGS: string = '{name:\\S+?}';
public readonly DESCRIPTION: string = 'Adds a tagged person to the current queue';
public readonly QUEUE: boolean = true;
/* eslint-enable jsdoc/require-jsdoc */
Expand Down
2 changes: 1 addition & 1 deletion services/bot/src/commands/queue/get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export class Get extends CommandBase implements ICommand {
/* eslint-disable jsdoc/require-jsdoc */
public readonly AUTHORIZATION: Auth = Auth.NONE;
public readonly COMMAND_TYPE: CommandType = CommandType.GET;
public readonly COMMAND_BASE: string = 'queue( {queue:[\\w\\s]+})?';
public readonly COMMAND_BASE: string = 'queue( {queue:[\\w]+})?';
public readonly DESCRIPTION: string = 'Gets the current queue and shows the contents of the queue';
/* eslint-enable jsdoc/require-jsdoc */

Expand Down
2 changes: 1 addition & 1 deletion services/bot/src/commands/queue/removePerson.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export class RemovePerson extends CommandBase implements ICommand {
public readonly AUTHORIZATION: Auth = Auth.PROJECT_ADMIN;
public readonly COMMAND_TYPE: CommandType = CommandType.OPERATION;
public readonly COMMAND_BASE: string = 'remove person';
public readonly ARGS: string = '{name:.+?}';
public readonly ARGS: string = '{name:\\S+?}';
public readonly QUEUE: boolean = true;
public readonly DESCRIPTION: string = 'Removes a tagged person from the current queue';
/* eslint-enable jsdoc/require-jsdoc */
Expand Down
3 changes: 2 additions & 1 deletion services/bot/src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export class Parser {
let messageData = null;
if (request.body.resource == 'attachmentActions') {
messageData = await BOT.attachmentActions.get(messageId);
} else { // if (request.body.resource == 'messages') {
} else {
messageData = await BOT.messages.get(messageId);
}

Expand All @@ -36,6 +36,7 @@ export class Parser {
const destination: Destination = {};
const mentions: string[] = messageData.mentionedPeople || [];

LOGGER.verbose(`Mentions: ${mentions}`);
// Email is not sent for attachmentActions. Thus, use the personId as first
// priority so that "card" commands and regular text commands will have the same
// information parsed and correlated into mongo
Expand Down
28 changes: 27 additions & 1 deletion services/bot/tests/commands/graphs/getQueueLengthHistory.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { AddMe } from '../../../src/commands/queue/addMe';
import { PROJECT_MODEL } from '../../../src/models/project';
import { BOT } from '../../../src/bot';
import MockDate from 'mockdate';
import { CREATE_PROJECT, TEST_INITIATIVE, STRICT_DATE, STANDARD_USER } from '../../util';
import { CREATE_PROJECT, TEST_INITIATIVE, STRICT_DATE, STANDARD_USER, CREATE_QUEUE } from '../../util';

TEST_INITIATIVE.rawCommand = 'get largest queue depth';
TEST_INITIATIVE.action = new Get();
Expand Down Expand Up @@ -52,6 +52,32 @@ describe('Getting queue length history works appropriately', () => {
'toPersonId': 'notReal'
});
});
test('Should return the correct largest queue result for non-default queue', async () => {
const project = await CREATE_PROJECT();
await CREATE_QUEUE(project, 'FOO');
let queue = project.queues.filter(i => i.name === 'FOO')[0];
expect(queue.members).toHaveLength(0);
expect(queue.history).toHaveLength(0);

await new AddMe().relax({ ...TEST_INITIATIVE, data: { queue: 'FOO' } });
queue = (await PROJECT_MODEL.find({ name: project.name }).exec())[0].queues.filter(i => i.name === 'FOO')[0];
expect(queue.history).toHaveLength(1);
await new AddMe().relax({ ...TEST_INITIATIVE, data: { queue: 'FOO' } });
queue = (await PROJECT_MODEL.find({ name: project.name }).exec())[0].queues.filter(i => i.name === 'FOO')[0];
expect(queue.history).toHaveLength(2);
await new AddMe().relax({ ...TEST_INITIATIVE, data: { queue: 'FOO' } });
queue = (await PROJECT_MODEL.find({ name: project.name }).exec())[0].queues.filter(i => i.name === 'FOO')[0];
expect(queue.history).toHaveLength(3); // eslint-disable-line @typescript-eslint/no-magic-numbers
expect(queue.history[2].members).toHaveLength(3); // eslint-disable-line @typescript-eslint/no-magic-numbers
expect(queue.history[2].time).toEqual(new Date(STRICT_DATE));

expect(await new Get().relax({ ...TEST_INITIATIVE, data: { queue: 'FOO' } })).toEqual('');
expect(BOT.messages.create).toBeCalledWith({
'files': ['myShortUrl'],
'markdown': 'Click [here](myShortUrl) to see your chart in a browser!',
'toPersonId': 'notReal'
});
});
});

describe('Getting queue depth history errors appropriately', () => {
Expand Down
62 changes: 60 additions & 2 deletions services/bot/tests/parser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,22 +88,80 @@ describe('Parser is working', () => {

describe('add person', () => {
test('Add person no queue specification', async () => {
BOT.messages.get.mockReturnValue({ text: 'add person FOO', mentionedPeople: ['fooId'] });
BOT.messages.get.mockReturnValue({ text: 'add person FOO', mentionedPeople: ['fooId2'] });
const result = await new Parser().parse(MOCK_REQUEST);
expect(result.action).toEqual(expect.objectContaining({
DESCRIPTION: 'Adds a tagged person to the current queue'
}));
expect(result.data).toEqual(expect.objectContaining({ queue: undefined }));
expect(result.mentions).toEqual(['fooId2']);
});
test('Add person with queue specification', async () => {
await CREATE_QUEUE(project as ProjectDocument, 'FOOBAR');
BOT.messages.get
.mockReturnValue({ text: 'add person FOO to queue FOOBAR', mentionedPeople: ['fooId'] });
.mockReturnValue({ text: 'add person FOO to queue FOOBAR', mentionedPeople: ['fooId2'] });
const result = await new Parser().parse(MOCK_REQUEST);
expect(result.action).toEqual(expect.objectContaining({
DESCRIPTION: 'Adds a tagged person to the current queue'
}));
expect(result.data).toEqual(expect.objectContaining({ name: 'foo', queue: 'foobar' }));
expect(result.mentions).toEqual(['fooId2']);
});
});
describe('get queue length history', () => {
test('get queue length history no queue specification', async () => {
BOT.messages.get.mockReturnValue({ text: 'get queue length history' });
const result = await new Parser().parse(MOCK_REQUEST);
expect(result.action).toEqual(expect.objectContaining({
DESCRIPTION: 'creates a graph of the queue length history'
}));
expect(result.data).toEqual({ queue: undefined });
});
test('get queue length history with queue specification', async () => {
BOT.messages.get.mockReturnValue({ text: 'get queue length history for queue FOOBAR' });
const result = await new Parser().parse(MOCK_REQUEST);
expect(result.action).toEqual(expect.objectContaining({
DESCRIPTION: 'creates a graph of the queue length history'
}));
expect(result.data).toEqual(expect.objectContaining({ queue: 'foobar' }));
});
});
describe('create admin', () => {
test('create admin no queue specification', async () => {
BOT.messages.get.mockReturnValue({ text: 'create admin FOO', mentionedPeople: ['fooId2'] });
const result = await new Parser().parse(MOCK_REQUEST);
expect(result.action).toEqual(expect.objectContaining({
DESCRIPTION: 'Adds a target project admin'
}));
expect(result.data).toEqual({ name: 'foo' });
expect(result.mentions).toEqual(['fooId2']);
});
test('create admin with queue specification', async () => {
await CREATE_QUEUE(project as ProjectDocument, 'FOOBAR');
BOT.messages.get
.mockReturnValue({ text: 'create admin FOO on queue FOOBAR', mentionedPeople: ['fooId2'] });
const result = await new Parser().parse(MOCK_REQUEST);
// Not a real command
expect(result.action).toEqual(undefined);
});
});
describe('remove admin', () => {
test('remove admin no queue specification', async () => {
BOT.messages.get.mockReturnValue({ text: 'remove admin FOO', mentionedPeople: ['fooId2'] });
const result = await new Parser().parse(MOCK_REQUEST);
expect(result.action).toEqual(expect.objectContaining({
DESCRIPTION: 'Removes a user as a project admin'
}));
expect(result.data).toEqual({ name: 'foo' });
expect(result.mentions).toEqual(['fooId2']);
});
test('remove admin with queue specification', async () => {
await CREATE_QUEUE(project as ProjectDocument, 'FOOBAR');
BOT.messages.get
.mockReturnValue({ text: 'remove admin FOO on queue FOOBAR', mentionedPeople: ['fooId2'] });
const result = await new Parser().parse(MOCK_REQUEST);
// Not a real command
expect(result.action).toEqual(undefined);
});
});

Expand Down

0 comments on commit a3efa33

Please sign in to comment.