From 177b66d1bf637ccd715a30aa150807afe96c34eb Mon Sep 17 00:00:00 2001 From: Filip Maj Date: Tue, 20 Jul 2021 12:30:32 -0400 Subject: [PATCH] Add basic test for SocketModeReceiver constructor (#750) --- src/receivers/SocketModeReceiver.spec.ts | 113 +++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 src/receivers/SocketModeReceiver.spec.ts diff --git a/src/receivers/SocketModeReceiver.spec.ts b/src/receivers/SocketModeReceiver.spec.ts new file mode 100644 index 000000000..62b9a274d --- /dev/null +++ b/src/receivers/SocketModeReceiver.spec.ts @@ -0,0 +1,113 @@ +/* eslint-disable @typescript-eslint/no-unsafe-call, @typescript-eslint/naming-convention */ + +import 'mocha'; +import sinon, { SinonSpy } from 'sinon'; +import { assert } from 'chai'; +import { Override, mergeOverrides } from '../test-helpers'; +import rewiremock from 'rewiremock'; +import { Logger, LogLevel } from '@slack/logger'; +import { EventEmitter } from 'events'; + +describe('SocketModeReceiver', function () { + const noopLogger: Logger = { + debug(..._msg: any[]): void { + /* noop */ + }, + info(..._msg: any[]): void { + /* noop */ + }, + warn(..._msg: any[]): void { + /* noop */ + }, + error(..._msg: any[]): void { + /* noop */ + }, + setLevel(_level: LogLevel): void { + /* noop */ + }, + getLevel(): LogLevel { + return LogLevel.DEBUG; + }, + setName(_name: string): void { + /* noop */ + }, + }; + + describe('constructor', () => { + // NOTE: it would be more informative to test known valid combinations of options, as well as invalid combinations + it('should accept supported arguments and use default arguments when not provided', async () => { + // Arrange + const fakeServer = new FakeServer(); + const fakeCreateServer = sinon.fake.returns(fakeServer); + const overrides = mergeOverrides( + withHttpCreateServer(fakeCreateServer), + withHttpsCreateServer(sinon.fake.throws('Should not be used.')), + ); + const SocketModeReceiver = await importSocketModeReceiver(overrides); + + const receiver = new SocketModeReceiver({ + appToken: 'my-secret', + logger: noopLogger, + clientId: 'my-clientId', + clientSecret: 'my-client-secret', + stateSecret: 'state-secret', + scopes: ['channels:read'], + installerOptions: { + authVersion: 'v2', + userScopes: ['chat:write'], + }, + }); + assert.isNotNull(receiver); + assert.isOk(fakeServer.listen.calledWith(3000)); + }); + }); +}); + +/* Testing Harness */ + +// Loading the system under test using overrides +async function importSocketModeReceiver( + overrides: Override = {}, +): Promise { + return (await rewiremock.module(() => import('./SocketModeReceiver'), overrides)).default; +} + +// Composable overrides +function withHttpCreateServer(spy: SinonSpy): Override { + return { + http: { + createServer: spy, + }, + }; +} + +function withHttpsCreateServer(spy: SinonSpy): Override { + return { + https: { + createServer: spy, + }, + }; +} + +// Fakes +class FakeServer extends EventEmitter { + public on = sinon.fake(); + public listen = sinon.fake(() => { + if (this.listeningFailure !== undefined) { + this.emit('error', this.listeningFailure); + return; + } + }); + public close = sinon.fake((...args: any[]) => { + setImmediate(() => { + this.emit('close'); + setImmediate(() => { + args[0](); + }); + }); + }); + + constructor(private listeningFailure?: Error) { + super(); + } +}