diff --git a/src/entity/Tick.ts b/src/entity/Tick.ts index 4ec5af0db..77eb28cda 100644 --- a/src/entity/Tick.ts +++ b/src/entity/Tick.ts @@ -36,6 +36,7 @@ export class Tick extends BaseEntity { createdAt: this.createdAt, id: this.id, intervalId: this.intervalId, + status: this.status, updatedAt: this.updatedAt, }; } diff --git a/src/parser/YamlParser.ts b/src/parser/YamlParser.ts index d731d1c73..13586efb4 100644 --- a/src/parser/YamlParser.ts +++ b/src/parser/YamlParser.ts @@ -24,14 +24,8 @@ export class YamlParser extends BaseParser implements Parser { public async parse(msg: Message): Promise> { const ctx = mustExist(msg.context); const data = await this.decode(msg); - - if (isObject(data)) { - // TODO: this cast and conversion should not be necessary - const map = makeMap(data.data); - return [await this.createCommand(ctx, map)]; - } else { - return []; - } + const map = makeMap(data.data); + return [await this.createCommand(ctx, map)]; } public async decode(msg: Message): Promise { diff --git a/test/TestBot.ts b/test/TestBot.ts index 14df361cf..9f6c1a03e 100644 --- a/test/TestBot.ts +++ b/test/TestBot.ts @@ -4,12 +4,16 @@ import { LogLevel } from 'noicejs'; import { Registry } from 'prom-client'; import { spy } from 'sinon'; -import { INJECT_METRICS, INJECT_SCHEMA } from '../src/BaseService'; +import { INJECT_LOGGER, INJECT_METRICS, INJECT_SCHEMA } from '../src/BaseService'; import { Bot, BotData } from '../src/Bot'; +import { Command, CommandVerb } from '../src/entity/Command'; import { BotModule } from '../src/module/BotModule'; +import { EntityModule } from '../src/module/EntityModule'; +import { MigrationModule } from '../src/module/MigrationModule'; import { ServiceModule } from '../src/module/ServiceModule'; import { Schema } from '../src/schema'; import { ServiceEvent } from '../src/Service'; +import { defer } from '../src/utils/Async'; import { describeLeaks, itLeaks } from './helpers/async'; import { createContainer } from './helpers/container'; import { getTestLogger } from './helpers/logger'; @@ -36,7 +40,7 @@ const TEST_CONFIG: BotData = { parsers: [], process: { pid: { - file: '../out/isolex.pid', + file: './out/test.pid', }, }, services: { @@ -44,9 +48,9 @@ const TEST_CONFIG: BotData = { }, storage: { data: { - migrate: false, + migrate: true, orm: { - database: '', + database: './out/test.db', type: 'sqlite', }, }, @@ -97,4 +101,57 @@ describeLeaks('bot service', async () => { }); expect(bot.isConnected).to.equal(false); }); + + xit('should execute commands', async () => { + const { container } = await createContainer(new BotModule({ + logger: getTestLogger(), + }), new ServiceModule({ + timeout: 1000, + }), new EntityModule(), new MigrationModule()); + const bot = await container.create(Bot, { + [INJECT_LOGGER]: getTestLogger(true), + [INJECT_SCHEMA]: new Schema(), + data: TEST_CONFIG, + metadata: { + kind: 'bot', + name: 'test-bot', + }, + }); + await bot.start(); + const results = await bot.executeCommand(new Command({ + data: {}, + labels: {}, + noun: 'test', + verb: CommandVerb.Create, + })); + await defer(50); + await bot.stop(); + expect(results.length).to.equal(0); + }); + + xit('should send messages', async () => { + const { container } = await createContainer(new BotModule({ + logger: getTestLogger(), + }), new ServiceModule({ + timeout: 1000, + }), new EntityModule(), new MigrationModule()); + const bot = await container.create(Bot, { + [INJECT_SCHEMA]: new Schema(), + data: TEST_CONFIG, + metadata: { + kind: 'bot', + name: 'test-bot', + }, + }); + await bot.start(); + const results = await bot.sendMessage(/* new Message({ + body: 'test', + labels: {}, + reactions: [], + type: TYPE_TEXT, + }) */); + await defer(50); + await bot.stop(); + expect(results.length).to.equal(0); + }); }); diff --git a/test/entity/TestTick.ts b/test/entity/TestTick.ts new file mode 100644 index 000000000..efb9caaa9 --- /dev/null +++ b/test/entity/TestTick.ts @@ -0,0 +1,16 @@ +import { expect } from 'chai'; + +import { Tick } from '../../src/entity/Tick'; +import { describeLeaks, itLeaks } from '../helpers/async'; + +describeLeaks('tick entity', async () => { + itLeaks('should convert itself to JSON', async () => { + const tick = new Tick({ + intervalId: '0', + status: 0, + }); + const json = tick.toJSON(); + expect(json).to.have.property('intervalId'); + expect(json).to.have.property('status'); + }); +}); diff --git a/test/entity/auth/TestToken.ts b/test/entity/auth/TestToken.ts index 90710eb4a..13178c0c3 100644 --- a/test/entity/auth/TestToken.ts +++ b/test/entity/auth/TestToken.ts @@ -20,4 +20,55 @@ describeLeaks('token entity', async () => { const token = new Token(data); expect(token).to.deep.include(testProps); }); + + itLeaks('should sign tokens', async () => { + const token = new Token({ + audience: ['test'], + createdAt: new Date(), + data: {}, + expiresAt: new Date(), + grants: [], + issuer: 'test', + labels: {}, + subject: 'test', + }); + token.id = 'test'; + const signed = token.sign('test'); + expect(signed).to.match(/[-_a-zA-Z0-9]+\.[-_a-zA-Z0-9]+\.[-_a-zA-Z0-9]+/); + }); + + itLeaks('should convert itself to json', async () => { + const token = new Token({ + audience: ['test'], + createdAt: new Date(), + data: {}, + expiresAt: new Date(), + grants: [], + issuer: 'test', + labels: {}, + subject: 'test', + }); + const json = token.toJSON(); + expect(json).to.have.property('audience'); + expect(json).to.have.property('issuer'); + expect(json).to.have.property('subject'); + }); + + itLeaks('should check grants', async () => { + const token = new Token({ + audience: ['test'], + createdAt: new Date(), + data: {}, + expiresAt: new Date(), + grants: ['test:*'], + issuer: 'test', + labels: {}, + subject: 'test', + }); + expect(token.permit(['fail:foo'])).to.equal(false); + expect(token.permit(['test:foo'])).to.equal(true); + }); + + itLeaks('should issue sessions with a user'); + itLeaks('should not issue sessions without a user'); }); diff --git a/test/filter/TestMessageFilter.ts b/test/filter/TestMessageFilter.ts index 758914510..0378ef4ec 100644 --- a/test/filter/TestMessageFilter.ts +++ b/test/filter/TestMessageFilter.ts @@ -6,6 +6,7 @@ import { Context } from '../../src/entity/Context'; import { Message } from '../../src/entity/Message'; import { FilterBehavior } from '../../src/filter'; import { MessageFilter, MessageFilterData } from '../../src/filter/MessageFilter'; +import { RuleOperator } from '../../src/utils/match'; import { TYPE_TEXT } from '../../src/utils/Mime'; import { describeLeaks, itLeaks } from '../helpers/async'; import { createService, createServiceContainer } from '../helpers/container'; @@ -44,8 +45,7 @@ describeLeaks('message filter', async () => { expect(result).to.equal(FilterBehavior.Allow); }); - xit('should drop other messages'); - it('should ignore other entities', async () => { + itLeaks('should ignore other entities', async () => { const { filter } = await createFilter({ filters: [], match: { @@ -62,4 +62,28 @@ describeLeaks('message filter', async () => { })); expect(result).to.equal(FilterBehavior.Ignore); }); + + it('should reject unmatched messages', async () => { + const { filter } = await createFilter({ + filters: [], + match: { + rules: [{ + key: '$.type', + operator: RuleOperator.Every, + values: [{ + string: 'jpeg', + }], + }], + }, + strict: true, + }); + const result = await filter.check(new Message({ + body: '', + context: ineeda(), + labels: {}, + reactions: [], + type: TYPE_TEXT, + })); + expect(result).to.equal(FilterBehavior.Drop); + }); }); diff --git a/test/parser/TestYamlParser.ts b/test/parser/TestYamlParser.ts index 35d4dca7e..2aef5ad71 100644 --- a/test/parser/TestYamlParser.ts +++ b/test/parser/TestYamlParser.ts @@ -1,5 +1,6 @@ import { expect } from 'chai'; import { ineeda } from 'ineeda'; +import { BaseError } from 'noicejs'; import { Repository } from 'typeorm'; import { INJECT_STORAGE } from '../../src/BotService'; @@ -88,4 +89,25 @@ describeLeaks('yaml parser', async () => { }); return expect(svc.parse(msg)).to.eventually.be.rejectedWith(MimeTypeError); }); + + it('should throw when the root value is not an object', async () => { + const { container } = await createServiceContainer(); + const svc = await createService(container, YamlParser, { + [INJECT_STORAGE]: TEST_STORAGE, + data: TEST_CONFIG, + metadata: { + kind: 'test', + name: 'test', + }, + }); + + const msg = new Message({ + body: '[]', + context: ineeda(), + labels: {}, + reactions: [], + type: TYPE_JPEG, + }); + return expect(svc.parse(msg)).to.eventually.be.rejectedWith(BaseError); + }); }); diff --git a/test/schema/TestGraph.ts b/test/schema/TestGraph.ts index e2bb2db22..c5e85bd34 100644 --- a/test/schema/TestGraph.ts +++ b/test/schema/TestGraph.ts @@ -7,11 +7,12 @@ import { Repository } from 'typeorm'; import { Bot } from '../../src/Bot'; import { INJECT_BOT, INJECT_STORAGE } from '../../src/BotService'; import { User } from '../../src/entity/auth/User'; -import { Command } from '../../src/entity/Command'; +import { Command, CommandVerb } from '../../src/entity/Command'; import { Message } from '../../src/entity/Message'; import { GraphSchema } from '../../src/schema/graph'; import { Service } from '../../src/Service'; import { Storage } from '../../src/storage'; +import { TYPE_TEXT } from '../../src/utils/Mime'; import { describeLeaks, itLeaks } from '../helpers/async'; import { createService, createServiceContainer } from '../helpers/container'; @@ -36,7 +37,12 @@ describeLeaks('graph schema', async () => { metadata: TEST_SCHEMA, }); await graph.executeCommands({ - commands: [], + commands: [{ + data: [], + labels: [], + noun: 'test', + verb: CommandVerb.Create, + }], }, ineeda({ user: ineeda(), })); @@ -57,7 +63,12 @@ describeLeaks('graph schema', async () => { metadata: TEST_SCHEMA, }); await graph.sendMessages({ - messages: [], + messages: [{ + body: 'msg', + labels: [], + reactions: [], + type: TYPE_TEXT, + }], }, ineeda({ user: ineeda(), }));