You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
gristlabs_grist-core/test/server/lib/GristAuditLogger.ts

118 lines
3.3 KiB

import {IAuditLogger} from 'app/server/lib/AuditLogger';
import {LogMethods} from 'app/server/lib/LogMethods';
import {assert} from 'chai';
import moment from 'moment-timezone';
import nock from 'nock';
import * as sinon from 'sinon';
import {TestServer} from 'test/gen-server/apiUtils';
import * as testUtils from 'test/server/testUtils';
describe('GristAuditLogger', function() {
let auditLogger: IAuditLogger;
let oldEnv: testUtils.EnvironmentSnapshot;
let server: TestServer;
before(async function() {
oldEnv = new testUtils.EnvironmentSnapshot();
process.env.GRIST_AUDIT_HTTP_ENDPOINT = 'https://api.getgrist.com/events';
process.env.GRIST_AUDIT_HTTP_AUTHORIZATION_HEADER = 'Grist bb48d1f8-8f6c-4065-8951-8543a8e70597';
server = new TestServer(this);
await server.start();
auditLogger = server.server.getAuditLogger();
});
after(async function() {
await server.stop();
oldEnv.restore();
});
describe('logEventAsync', function() {
const sandbox: sinon.SinonSandbox = sinon.createSandbox();
let logErrorCallArguments: any[] = [];
before(async function() {
sandbox
.stub(LogMethods.prototype, 'error')
.callsFake((...args) => logErrorCallArguments.push([...args]));
});
after(async function() {
sandbox.restore();
});
afterEach(function() {
logErrorCallArguments = [];
nock.cleanAll();
});
it('logs audit events', async function() {
const timestamp = moment().toISOString();
const scope = nock('https://api.getgrist.com')
.matchHeader('Authorization', 'Grist bb48d1f8-8f6c-4065-8951-8543a8e70597')
.post('/events', {
event: {
name: 'createDocument',
user: null,
details: {
id: 'docId',
},
},
timestamp,
})
.reply(200);
await assert.isFulfilled(
auditLogger.logEventAsync(null, {
event: {
name: 'createDocument',
details: {id: 'docId'},
},
timestamp,
})
);
assert.isTrue(scope.isDone());
});
it('throws on failure to log', async function() {
nock('https://api.getgrist.com')
.post('/events')
.reply(404, 'Not found');
await assert.isRejected(
auditLogger.logEventAsync(null, {
event: {
name: 'createDocument',
details: {id: 'docId'},
},
}),
'received a non-200 response from https://api.getgrist.com/events: 404 Not found'
);
});
it('throws if max pending requests exceeded', async function() {
nock('https://api.getgrist.com')
.persist()
.post('/events')
.delay(2000)
.reply(200);
// Queue up enough pending requests to reach the limit (25).
for (let i = 0; i < 25; i++) {
void auditLogger.logEvent(null, {
event: {
name: 'createDocument',
details: {id: 'docId'},
},
});
}
await assert.isRejected(
auditLogger.logEventAsync(null, {
event: {
name: 'createDocument',
details: {id: 'docId'},
},
}),
'exceeded the maximum number of pending audit event calls (25)'
);
nock.abortPendingRequests();
});
});
});