From e4755c0c2d55a9af3417aa6a735886cb0d54f9ad Mon Sep 17 00:00:00 2001
From: Peter Hooper <diversemix@gmail.com>
Date: Tue, 31 Dec 2019 12:42:12 +0000
Subject: [PATCH] Begin the process of improving tests

---
 src/event-bus/event-bus.ts     |  5 +---
 src/event-bus/event-factory.ts | 11 +++++++
 src/event-bus/index.ts         |  3 +-
 src/event-bus/types.test.ts    | 55 ++++++++++++++++++++++++++++++++++
 4 files changed, 69 insertions(+), 5 deletions(-)
 create mode 100644 src/event-bus/event-factory.ts
 create mode 100644 src/event-bus/types.test.ts

diff --git a/src/event-bus/event-bus.ts b/src/event-bus/event-bus.ts
index ad144af..b2dac5d 100644
--- a/src/event-bus/event-bus.ts
+++ b/src/event-bus/event-bus.ts
@@ -1,5 +1,4 @@
 import { EventType } from './types';
-import { NotImplementedError } from 'funfix';
 
 export abstract class EventBus {
     // register the following:
@@ -7,7 +6,5 @@ export abstract class EventBus {
     // - serviceName - used when subscribing to generate a unique queue for holding
     // incoming messages of the form: `consumer__${eventType}__${serviceName}`
     constructor(readonly eventsToHandle: EventType[], readonly serviceName: string) {}
-    destroy(): Promise<void> {
-        throw new NotImplementedError('destroy() on EventBus');
-    }
+    abstract destroy(): Promise<void>;
 }
diff --git a/src/event-bus/event-factory.ts b/src/event-bus/event-factory.ts
new file mode 100644
index 0000000..8c59039
--- /dev/null
+++ b/src/event-bus/event-factory.ts
@@ -0,0 +1,11 @@
+import { Event } from './types';
+import uuid = require('uuid');
+
+export const eventFactory = <P extends object>(eventType: string, payload: P): Event<P> => {
+    return {
+        eventType,
+        id: uuid.v4(),
+        created: new Date(),
+        payload,
+    };
+};
diff --git a/src/event-bus/index.ts b/src/event-bus/index.ts
index 3067e75..999b47e 100644
--- a/src/event-bus/index.ts
+++ b/src/event-bus/index.ts
@@ -1,2 +1,3 @@
-export * from './event-bus';
 export * from './types';
+export * from './event-bus';
+export * from './event-factory';
diff --git a/src/event-bus/types.test.ts b/src/event-bus/types.test.ts
new file mode 100644
index 0000000..4173234
--- /dev/null
+++ b/src/event-bus/types.test.ts
@@ -0,0 +1,55 @@
+import { EventType, Event } from './types';
+
+const expectedEventProperties = {
+    eventType: true,
+    id: true,
+    created: true,
+    payload: true,
+    version: false,
+    context: false,
+};
+
+function createValidationFunction<T>(properties: Record<keyof T, boolean>): Function {
+    return function<TActual extends T>(value: TActual): T {
+        const result = {} as T;
+        const foundKeys: string[] = [];
+        for (const property of Object.keys(properties) as Array<keyof T>) {
+            if (properties[property]) {
+                if (value[property] === undefined) {
+                    throw new Error(`undefined property '${property}'`);
+                }
+                result[property] = value[property];
+                foundKeys.push(property.toString());
+            } else {
+                if (value[property] !== undefined) {
+                    throw new Error(`not expecting property '${property}'`);
+                }
+            }
+        }
+        const valueKeys = Object.keys(value);
+        const difference = valueKeys.filter(x => !foundKeys.includes(x));
+        if (difference.length) {
+            throw new Error(`extra properties '${JSON.stringify(difference)}'`);
+        }
+        return result;
+    };
+}
+
+describe('Event Bus Types', () => {
+    it('type EventType is string', () => {
+        const et: EventType = 'this is a string';
+        expect(typeof et).toBe('string');
+    });
+
+    it('interface Event contains expected members', () => {
+        class ExpectedToBeAnEvent {
+            id = '234';
+            created: Date = new Date();
+            payload: {} = {};
+            eventType = 'type';
+        }
+        const isValidEvent = createValidationFunction<Event<{}>>(expectedEventProperties);
+        const ee = new ExpectedToBeAnEvent();
+        expect(() => isValidEvent(ee)).not.toThrow();
+    });
+});
-- 
GitLab