diff --git a/CHANGELOG.md b/CHANGELOG.md index c403358..8a87142 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/). ### Added +- Export class `AuditLogService` for extending in custom implementations + ### Changed ### Fixed diff --git a/cds-plugin.js b/cds-plugin.js index 75a123f..ee6eecb 100644 --- a/cds-plugin.js +++ b/cds-plugin.js @@ -46,3 +46,10 @@ cds.on('served', services => { } } }) + +/* + * Export base class for extending in custom implementations + */ +module.exports = { + AuditLogService: require('./srv/service') +} diff --git a/test/api/MyAuditLogService.js b/test/api/MyAuditLogService.js new file mode 100644 index 0000000..b16e4f1 --- /dev/null +++ b/test/api/MyAuditLogService.js @@ -0,0 +1,16 @@ +const { AuditLogService } = require('../../') //> package root + +class MyAuditLogService extends AuditLogService { + async init() { + this.on('*', function (req) { + const { event, data } = req + + console.log(`[my-audit-log] - ${event}:`, data) + }) + + // call AuditLogService's init + await super.init() + } +} + +module.exports = MyAuditLogService diff --git a/test/api/api.test.js b/test/api/api.test.js index 7f0399b..92a69c0 100644 --- a/test/api/api.test.js +++ b/test/api/api.test.js @@ -88,38 +88,4 @@ describe('AuditLogService API', () => { await audit.log('foo', { data_subject: { ID: { bar: 'baz' } } }) expect(_logs).toContainMatchObject({ data_subject: { ID: { bar: 'baz' } } }) }) - - describe('intercept audit logs', () => { - let _intercept - - beforeAll(async () => { - const als = cds.services['audit-log'] || (await cds.connect.to('audit-log')) - - const _log = als.log - als.log = async function (event, data) { - if (!_intercept) return _log.call(this, event, data) - } - }) - - beforeEach(async () => { - _intercept = undefined - }) - - test('intercept on', async () => { - _intercept = true - - const response = await POST('/api/testLog', {}, { auth: ALICE }) - expect(response).toMatchObject({ status: 204 }) - expect(_logs.length).toBe(0) - }) - - test('intercept off', async () => { - _intercept = false - - const response = await POST('/api/testLog', {}, { auth: ALICE }) - expect(response).toMatchObject({ status: 204 }) - expect(_logs.length).toBe(1) - expect(_logs).toContainMatchObject({ user: 'alice', bar: 'baz' }) - }) - }) }) diff --git a/test/api/custom.test.js b/test/api/custom.test.js new file mode 100644 index 0000000..c06ea09 --- /dev/null +++ b/test/api/custom.test.js @@ -0,0 +1,39 @@ +const cds = require('@sap/cds') + +cds.env.requires['audit-log'] = { + impl: 'MyAuditLogService.js' +} + +// set cwd for resolving impl +cds.test(__dirname) + +describe('Custom Implementation', () => { + let __log, _logs + const _log = (...args) => { + if (!(args.length === 2 && typeof args[0] === 'string' && args[0].match(/\[my-audit-log\]/i))) { + // > not an audit log (most likely, anyway) + return __log(...args) + } + + _logs.push(args[1]) + } + + beforeAll(() => { + __log = global.console.log + global.console.log = _log + }) + + afterAll(() => { + global.console.log = __log + }) + + beforeEach(async () => { + _logs = [] + }) + + test('extending AuditLogService exported by plugin', async () => { + const audit = await cds.connect.to('audit-log') + await audit.log('foo', { data_subject: { ID: { bar: 'baz' } } }) + expect(_logs).toContainMatchObject({ data_subject: { ID: { bar: 'baz' } } }) + }) +})