From 5c795bdaa7408c690b88b149ec3e4082cf756d72 Mon Sep 17 00:00:00 2001 From: Christopher Kolstad Date: Thu, 4 Mar 2021 14:08:53 +0100 Subject: [PATCH] fix: makes eventstore emit id and createdAt (#746) fixes: #703 --- src/lib/db/event-store.js | 50 ++++++++++++--------- src/test/e2e/stores/event-store.e2e.test.js | 30 +++++++++++-- 2 files changed, 57 insertions(+), 23 deletions(-) diff --git a/src/lib/db/event-store.js b/src/lib/db/event-store.js index bf92156b5d..67ca664941 100644 --- a/src/lib/db/event-store.js +++ b/src/lib/db/event-store.js @@ -12,6 +12,8 @@ const EVENT_COLUMNS = [ 'tags', ]; +const TABLE = 'events'; + class EventStore extends EventEmitter { constructor(db, getLogger) { super(); @@ -21,13 +23,16 @@ class EventStore extends EventEmitter { async store(event) { try { - await this.db('events').insert({ - type: event.type, + const rows = await this.db(TABLE) + .insert({ + type: event.type, created_by: event.createdBy, // eslint-disable-line - data: event.data, - tags: event.tags ? JSON.stringify(event.tags) : [], - }); - process.nextTick(() => this.emit(event.type, event)); + data: event.data, + tags: event.tags ? JSON.stringify(event.tags) : [], + }) + .returning(EVENT_COLUMNS); + const savedEvent = this.rowToEvent(rows[0]); + process.nextTick(() => this.emit(event.type, savedEvent)); } catch (e) { this.logger.warn(`Failed to store event ${e}`); } @@ -35,27 +40,23 @@ class EventStore extends EventEmitter { async batchStore(events) { try { - await this.db('events').insert(events.map(this.eventToDbRow)); - process.nextTick(() => events.forEach(e => this.emit(e.type, e))); + const savedRows = await this.db(TABLE) + .insert(events.map(this.eventToDbRow)) + .returning(EVENT_COLUMNS); + const savedEvents = savedRows.map(this.rowToEvent); + process.nextTick(() => + savedEvents.forEach(e => this.emit(e.type, e)), + ); } catch (e) { this.logger.warn('Failed to store events'); } } - eventToDbRow(e) { - return { - type: e.type, - created_by: e.createdBy, - data: e.data, - tags: e.tags ? JSON.stringify(e.tags) : [], - }; - } - async getEvents() { try { const rows = await this.db .select(EVENT_COLUMNS) - .from('events') + .from(TABLE) .limit(100) .orderBy('created_at', 'desc'); @@ -69,7 +70,7 @@ class EventStore extends EventEmitter { try { const rows = await this.db .select(EVENT_COLUMNS) - .from('events') + .from(TABLE) .limit(100) .whereRaw("data ->> 'name' = ?", [name]) .andWhere( @@ -77,7 +78,7 @@ class EventStore extends EventEmitter { '>=', this.db .select(this.db.raw('coalesce(max(id),0) as id')) - .from('events') + .from(TABLE) .where({ type: DROP_FEATURES }), ) .orderBy('created_at', 'desc'); @@ -97,6 +98,15 @@ class EventStore extends EventEmitter { tags: row.tags, }; } + + eventToDbRow(e) { + return { + type: e.type, + created_by: e.createdBy, + data: e.data, + tags: e.tags ? JSON.stringify(e.tags) : [], + }; + } } module.exports = EventStore; diff --git a/src/test/e2e/stores/event-store.e2e.test.js b/src/test/e2e/stores/event-store.e2e.test.js index 882894e6ce..b1ec525251 100644 --- a/src/test/e2e/stores/event-store.e2e.test.js +++ b/src/test/e2e/stores/event-store.e2e.test.js @@ -19,6 +19,26 @@ test.before(async () => { test.after(async () => { await stores.db.destroy(); }); +test.serial('Should include id and createdAt when saving', async t => { + const clock = sinon.useFakeTimers(); + const event1 = { + type: APPLICATION_CREATED, + createdBy: '127.0.0.1', + data: { + clientIp: '127.0.0.1', + appName: 'test1', + }, + }; + const seen = []; + eventStore.on(APPLICATION_CREATED, e => seen.push(e)); + await eventStore.store(event1); + await clock.tickAsync(100); + t.is(seen.length, 1); + t.truthy(seen[0].id); + t.truthy(seen[0].createdAt); + t.is(seen[0].data.clientIp, event1.data.clientIp); + t.is(seen[0].data.appName, event1.data.appName); +}); test.serial('Should be able to store multiple events at once', async t => { const clock = sinon.useFakeTimers(); @@ -47,10 +67,14 @@ test.serial('Should be able to store multiple events at once', async t => { }, tags: [{ type: 'simple', value: 'mytest' }], }; - let seen = 0; - eventStore.on(APPLICATION_CREATED, () => seen++); + const seen = []; + eventStore.on(APPLICATION_CREATED, e => seen.push(e)); await eventStore.batchStore([event1, event2, event3]); await clock.tickAsync(100); - t.is(seen, 3); + t.is(seen.length, 3); + seen.forEach(e => { + t.truthy(e.id); + t.truthy(e.createdAt); + }); clock.restore(); });