UNPKG

@elastic.io/maester-client

Version:
726 lines (725 loc) 45.3 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); /* eslint-disable no-unused-expressions */ const nock_1 = __importDefault(require("nock")); const sinon_1 = __importDefault(require("sinon")); const get_stream_1 = __importDefault(require("get-stream")); const chai_1 = require("chai"); const jsonwebtoken_1 = require("jsonwebtoken"); const errors_1 = require("../src/errors"); const logger_1 = __importDefault(require("../src/logger")); const src_1 = require("../src"); const helpers_1 = require("./helpers"); const interfaces_1 = require("../src/interfaces"); describe('Object Storage', () => { const config = { uri: 'https://ma.es.ter', jwtSecret: 'jwt', userAgent: 'userAgent' }; const objectStorage = new src_1.ObjectStorage(config); const postData = { test: 'test' }; const responseData = { contentLength: 'meta.contentLength', contentType: 'meta.contentType', createdAt: 'meta.createdAt', md5: 'meta.md5Hash', objectId: 'obj.id', metadata: 'meta.userMetadata', }; afterEach(sinon_1.default.restore); function authHeaderMatch(jwtPayload) { return (val) => { const decoded = (0, jsonwebtoken_1.verify)(val.split(' ')[1], config.jwtSecret); if (jwtPayload) { (0, chai_1.expect)(decoded).to.deep.include(jwtPayload); } return !!decoded; }; } describe('basic', () => { describe('data mode', () => { it(`should fail after ${interfaces_1.RETRIES_COUNT.defaultValue} retries`, async () => { const log = sinon_1.default.stub(logger_1.default, 'warn'); const objectStorageCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch()) .get('/objects/1') .replyWithError({ code: 'ETIMEDOUT' }) .get('/objects/1') .reply(500) .get('/objects/1') .replyWithError({ code: 'ENOTFOUND' }); let err; try { await objectStorage.getOne('1', { jwtPayloadOrToken: {} }); } catch (e) { err = e; } (0, chai_1.expect)(objectStorageCalls.isDone()).to.be.true; (0, chai_1.expect)(err).to.be.instanceOf(errors_1.ServerTransportError); (0, chai_1.expect)(log.getCall(1).args[1].toString()).to.include('Error during object request'); (0, chai_1.expect)(log.callCount).to.be.equal(interfaces_1.RETRIES_COUNT.defaultValue); }); it(`should retry get request ${interfaces_1.RETRIES_COUNT.defaultValue} times on errors`, async () => { const objectStorageCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch()) .get('/objects/1') .reply(500) .get('/objects/1') .replyWithError({ code: 'ECONNRESET' }) .get('/objects/1') .reply(200, (0, helpers_1.streamFromObject)(responseData)); const { data } = await objectStorage.getOne('1', { jwtPayloadOrToken: {} }); (0, chai_1.expect)(objectStorageCalls.isDone()).to.be.true; (0, chai_1.expect)(data).to.be.deep.equal(responseData); }); it(`should retry get as string request ${interfaces_1.RETRIES_COUNT.defaultValue} times on errors`, async () => { const objectStorageCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch()) .get('/objects/1') .reply(500) .get('/objects/1') .replyWithError({ code: 'ECONNRESET' }) .get('/objects/1') .reply(200, (0, helpers_1.streamFromObject)(responseData)); const { data } = await objectStorage.getOne('1', { jwtPayloadOrToken: {} }); (0, chai_1.expect)(objectStorageCalls.isDone()).to.be.true; (0, chai_1.expect)(data).to.be.deep.equal(responseData); }); it(`should retry post request ${interfaces_1.RETRIES_COUNT.defaultValue} times on errors`, async () => { const objectStorageCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch()) .post('/objects') .replyWithError({ code: 'ECONNREFUSED' }) .post('/objects') .reply(500) .post('/objects') .reply(200, responseData); await objectStorage.add(postData, { jwtPayloadOrToken: {} }); (0, chai_1.expect)(objectStorageCalls.isDone()).to.be.true; }); it(`should retry put request ${interfaces_1.RETRIES_COUNT.defaultValue} times on errors`, async () => { const objectStorageCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch()) .put('/objects/1') .replyWithError({ code: 'ECONNREFUSED' }) .put('/objects/1') .reply(500) .put('/objects/1') .reply(200, responseData); const response = await objectStorage.update('1', postData, { jwtPayloadOrToken: {} }); (0, chai_1.expect)(response).to.deep.equal(responseData); (0, chai_1.expect)(objectStorageCalls.isDone()).to.be.true; }); it('should return headers', async () => { const objectStorageCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch()) .get('/objects/1') .reply(200, (0, helpers_1.streamFromObject)(responseData), { 'Content-Length': '200' }); const { data, headers } = await objectStorage.getOne('1', { jwtPayloadOrToken: {} }); const expectedHeaders = { 'content-length': '200' }; (0, chai_1.expect)(objectStorageCalls.isDone()).to.be.true; (0, chai_1.expect)(data).to.be.deep.equal(responseData); (0, chai_1.expect)(headers.toJSON()).to.deep.equal(expectedHeaders); }); it('should accept jwt token on add', async () => { const jwtPayload = { tenantId: '12', contractId: '1' }; const objectStorageCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch(jwtPayload)) .post('/objects') .reply(200); const objectId = await objectStorage.add(postData, { jwtPayloadOrToken: (0, jsonwebtoken_1.sign)(jwtPayload, config.jwtSecret) }); (0, chai_1.expect)(objectStorageCalls.isDone()).to.be.true; (0, chai_1.expect)(objectId).to.match(/^[0-9a-z-]+$/); }); it('should accept jwt token on get', async () => { const jwtPayload = { tenantId: '12', contractId: '1' }; const objectStorageCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch(jwtPayload)) .get('/objects/1') .reply(200, (0, helpers_1.streamFromObject)(responseData)); const { data } = await objectStorage.getOne('1', { jwtPayloadOrToken: (0, jsonwebtoken_1.sign)(jwtPayload, config.jwtSecret) }); (0, chai_1.expect)(objectStorageCalls.isDone()).to.be.true; (0, chai_1.expect)(data).to.be.deep.equal(responseData); }); it('should accept jwt token on delete', async () => { const jwtPayload = { tenantId: '12', contractId: '1' }; const objectStorageCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch(jwtPayload)) .delete('/objects/1') .reply(204); await objectStorage.deleteOne('1', { jwtPayloadOrToken: (0, jsonwebtoken_1.sign)(jwtPayload, config.jwtSecret) }); (0, chai_1.expect)(objectStorageCalls.isDone()).to.be.true; }); it('should accept jwt token on put', async () => { const jwtPayload = { tenantId: '12', contractId: '1' }; const objectStorageCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch(jwtPayload)) .put('/objects/1') .reply(200, responseData); const response = await objectStorage.update('1', postData, { jwtPayloadOrToken: (0, jsonwebtoken_1.sign)(jwtPayload, config.jwtSecret) }); (0, chai_1.expect)(response).to.deep.equal(responseData); (0, chai_1.expect)(objectStorageCalls.isDone()).to.be.true; }); it('should throw exception if neither jwt secret, nor jwt token provided', async () => { // @ts-ignore const objectStorage2 = new src_1.ObjectStorage({ uri: config.uri }); let err; try { await objectStorage2.getOne('1', { jwtPayloadOrToken: {} }); } catch (e) { err = e; } (0, chai_1.expect)(err).to.be.instanceOf(errors_1.JwtNotProvidedError); }); }); describe('stream mode', () => { it(`should fail after ${interfaces_1.RETRIES_COUNT.defaultValue} get retries`, async () => { const log = sinon_1.default.stub(logger_1.default, 'warn'); const objectStorageCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch()) .get('/objects/1') .replyWithError({ code: 'ETIMEDOUT' }) .get('/objects/1') .reply(500) .get('/objects/1') .replyWithError({ code: 'ENOTFOUND' }); let err; try { await objectStorage.getOne('1', { jwtPayloadOrToken: {} }); } catch (e) { err = e; } (0, chai_1.expect)(objectStorageCalls.isDone()).to.be.true; (0, chai_1.expect)(err).to.be.instanceOf(errors_1.ServerTransportError); (0, chai_1.expect)(log.getCall(1).args[1].toString()).to.include('Error during object request'); (0, chai_1.expect)(log.callCount).to.be.equal(interfaces_1.RETRIES_COUNT.defaultValue); }); it('should retry get request on errors', async () => { const objectStorageCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch()) .get('/objects/1') .reply(500) .get('/objects/1') .reply(200, (0, helpers_1.streamFromObject)(responseData)); const { data } = await objectStorage.getOne('1', { jwtPayloadOrToken: {}, responseType: 'stream' }); const out = JSON.parse(await (0, get_stream_1.default)(data)); (0, chai_1.expect)(objectStorageCalls.isDone()).to.be.true; (0, chai_1.expect)(out).to.be.deep.equal(responseData); }); it('should throw an error on put request connection error', async () => { const objectStorageCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch()) .post('/objects') .replyWithError({ code: 'ECONNREFUSED' }) .post('/objects') .replyWithError({ code: 'ECONNREFUSED' }) .post('/objects') .replyWithError({ code: 'ECONNREFUSED' }); let err; try { await objectStorage.add((0, helpers_1.streamFromObject)(postData), { jwtPayloadOrToken: {} }); } catch (e) { err = e; } (0, chai_1.expect)(objectStorageCalls.isDone()).to.be.true; (0, chai_1.expect)(err).to.be.instanceOf(errors_1.ServerTransportError); }); it('should throw an error on put request http error', async () => { const objectStorageCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch()) .post('/objects') .reply(500) .post('/objects') .reply(500) .post('/objects') .reply(500); let err; try { await objectStorage.add((0, helpers_1.streamFromObject)(postData), { jwtPayloadOrToken: {} }); } catch (e) { err = e; } (0, chai_1.expect)(objectStorageCalls.isDone()).to.be.true; (0, chai_1.expect)(err).to.be.instanceOf(errors_1.ServerTransportError); }); it(`should retry put request ${interfaces_1.RETRIES_COUNT.defaultValue} times on errors`, async () => { const objectStorageCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch()) .put('/objects/1') .replyWithError({ code: 'ECONNREFUSED' }) .put('/objects/1') .reply(500) .put('/objects/1') .reply(200, responseData); const response = await objectStorage.update('1', (0, helpers_1.streamFromObject)(postData), { jwtPayloadOrToken: {} }); (0, chai_1.expect)(response).to.deep.equal(responseData); (0, chai_1.expect)(objectStorageCalls.isDone()).to.be.true; }); it('should put successfully', async () => { const objectStorageCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch()) .post('/objects') .reply(200); const objectId = await objectStorage.add((0, helpers_1.streamFromObject)(postData), { jwtPayloadOrToken: {} }); (0, chai_1.expect)(objectStorageCalls.isDone()).to.be.true; (0, chai_1.expect)(objectId).to.match(/^[0-9a-z-]+$/); }); it('should use valid jwt token', async () => { const jwtPayload = { tenantId: '12', contractId: '1' }; const objectStorageCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch(jwtPayload)) .post('/objects') .reply(200); const objectId = await objectStorage.add((0, helpers_1.streamFromObject)(postData), { jwtPayloadOrToken: jwtPayload }); (0, chai_1.expect)(objectStorageCalls.isDone()).to.be.true; (0, chai_1.expect)(objectId).to.match(/^[0-9a-z-]+$/); }); it('should accept jwt token on put', async () => { const jwtPayload = { tenantId: '12', contractId: '1' }; const objectStorageCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch(jwtPayload)) .put('/objects/1') .reply(200, responseData); const response = await objectStorage.update('1', (0, helpers_1.streamFromObject)(postData), { jwtPayloadOrToken: jwtPayload }); (0, chai_1.expect)(response).to.deep.equal(responseData); (0, chai_1.expect)(objectStorageCalls.isDone()).to.be.true; }); }); describe('middlewares + zip/unzip and encrypt/decrypt', () => { describe('data mode', () => { it(`should fail after ${interfaces_1.RETRIES_COUNT.defaultValue} retries`, async () => { const objectStorageWithMiddlewares = new src_1.ObjectStorage(config); objectStorageWithMiddlewares.use(helpers_1.encryptStream, helpers_1.decryptStream); objectStorageWithMiddlewares.use(helpers_1.zip, helpers_1.unzip); const log = sinon_1.default.stub(logger_1.default, 'warn'); const objectStorageWithMiddlewaresCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch()) .get('/objects/1') .replyWithError({ code: 'ETIMEDOUT' }) .get('/objects/1') .reply(500) .get('/objects/1') .replyWithError({ code: 'ENOTFOUND' }); let err; try { await objectStorageWithMiddlewares.getOne('1', { jwtPayloadOrToken: {} }); } catch (e) { err = e; } (0, chai_1.expect)(objectStorageWithMiddlewaresCalls.isDone()).to.be.true; (0, chai_1.expect)(err).to.be.instanceOf(errors_1.ServerTransportError); (0, chai_1.expect)(log.getCall(1).args[1].toString()).to.include('Error during object request'); (0, chai_1.expect)(log.callCount).to.be.equal(interfaces_1.RETRIES_COUNT.defaultValue); }); it(`should retry get request ${interfaces_1.RETRIES_COUNT.defaultValue} times on errors`, async () => { const objectStorageWithMiddlewares = new src_1.ObjectStorage(config); objectStorageWithMiddlewares.use(helpers_1.encryptStream, helpers_1.decryptStream); objectStorageWithMiddlewares.use(helpers_1.zip, helpers_1.unzip); const objectStorageWithMiddlewaresCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch()) .get('/objects/1') .reply(500) .get('/objects/1') .replyWithError({ code: 'ECONNRESET' }) .get('/objects/1') .reply(200, () => { const stream = (0, helpers_1.streamFromObject)(responseData); return stream.pipe((0, helpers_1.encryptStream)()).pipe((0, helpers_1.zip)()); }); const { data } = await objectStorageWithMiddlewares.getOne('1', { jwtPayloadOrToken: {} }); (0, chai_1.expect)(objectStorageWithMiddlewaresCalls.isDone()).to.be.true; (0, chai_1.expect)(data).to.be.deep.equal(responseData); }); it(`should retry post request ${interfaces_1.RETRIES_COUNT.defaultValue} times on errors`, async () => { const objectStorageWithMiddlewares = new src_1.ObjectStorage(config); objectStorageWithMiddlewares.use(helpers_1.encryptStream, helpers_1.decryptStream); objectStorageWithMiddlewares.use(helpers_1.zip, helpers_1.unzip); const objectStorageWithMiddlewaresCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch()) .post('/objects') .replyWithError({ code: 'ECONNREFUSED' }) .post('/objects') .reply(500) .post('/objects') .reply(200, responseData); await objectStorageWithMiddlewares.add(postData, { jwtPayloadOrToken: {} }); (0, chai_1.expect)(objectStorageWithMiddlewaresCalls.isDone()).to.be.true; }); it(`should retry put request ${interfaces_1.RETRIES_COUNT.defaultValue} times on errors`, async () => { const objectStorageWithMiddlewares = new src_1.ObjectStorage(config); objectStorageWithMiddlewares.use(helpers_1.encryptStream, helpers_1.decryptStream); objectStorageWithMiddlewares.use(helpers_1.zip, helpers_1.unzip); const objectStorageWithMiddlewaresCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch()) .put('/objects/1') .replyWithError({ code: 'ECONNREFUSED' }) .put('/objects/1') .reply(500) .put('/objects/1') .reply(200, responseData); const response = await objectStorageWithMiddlewares.update('1', postData, { jwtPayloadOrToken: {} }); (0, chai_1.expect)(response).to.deep.equal(responseData); (0, chai_1.expect)(objectStorageWithMiddlewaresCalls.isDone()).to.be.true; }); it('should accept jwt token on add', async () => { const objectStorageWithMiddlewares = new src_1.ObjectStorage(config); objectStorageWithMiddlewares.use(helpers_1.encryptStream, helpers_1.decryptStream); objectStorageWithMiddlewares.use(helpers_1.zip, helpers_1.unzip); const jwtPayload = { tenantId: '12', contractId: '1' }; const objectStorageWithMiddlewaresCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch(jwtPayload)) .post('/objects') .reply(200); const objectId = await objectStorageWithMiddlewares.add(postData, { jwtPayloadOrToken: (0, jsonwebtoken_1.sign)(jwtPayload, config.jwtSecret) }); (0, chai_1.expect)(objectStorageWithMiddlewaresCalls.isDone()).to.be.true; (0, chai_1.expect)(objectId).to.match(/^[0-9a-z-]+$/); }); it('should accept jwt token on put', async () => { const objectStorageWithMiddlewares = new src_1.ObjectStorage(config); objectStorageWithMiddlewares.use(helpers_1.encryptStream, helpers_1.decryptStream); objectStorageWithMiddlewares.use(helpers_1.zip, helpers_1.unzip); const jwtPayload = { tenantId: '12', contractId: '1' }; const objectStorageWithMiddlewaresCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch(jwtPayload)) .put('/objects/1') .reply(200, responseData); const response = await objectStorageWithMiddlewares.update('1', postData, { jwtPayloadOrToken: (0, jsonwebtoken_1.sign)(jwtPayload, config.jwtSecret) }); (0, chai_1.expect)(response).to.deep.equal(responseData); (0, chai_1.expect)(objectStorageWithMiddlewaresCalls.isDone()).to.be.true; }); it('should accept jwt token on get', async () => { const objectStorageWithMiddlewares = new src_1.ObjectStorage(config); objectStorageWithMiddlewares.use(helpers_1.encryptStream, helpers_1.decryptStream); objectStorageWithMiddlewares.use(helpers_1.zip, helpers_1.unzip); const jwtPayload = { tenantId: '12', contractId: '1' }; const objectStorageWithMiddlewaresCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch(jwtPayload)) .get('/objects/1') .reply(200, () => { const stream = (0, helpers_1.streamFromObject)(responseData); return stream.pipe((0, helpers_1.encryptStream)()).pipe((0, helpers_1.zip)()); }); const { data } = await objectStorageWithMiddlewares.getOne('1', { jwtPayloadOrToken: (0, jsonwebtoken_1.sign)(jwtPayload, config.jwtSecret) }); (0, chai_1.expect)(objectStorageWithMiddlewaresCalls.isDone()).to.be.true; (0, chai_1.expect)(data).to.be.deep.equal(responseData); }); it('should add 2 objects successfully', async () => { const objectStorageWithMiddlewares = new src_1.ObjectStorage(config); objectStorageWithMiddlewares.use(helpers_1.encryptStream, helpers_1.decryptStream); objectStorageWithMiddlewares.use(helpers_1.zip, helpers_1.unzip); const jwtPayload = { tenantId: '12', contractId: '1' }; const objectStorageWithMiddlewaresCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch(jwtPayload)) .post('/objects') .reply(200, { objectId: '1' }) .post('/objects') .reply(200, { objectId: '2' }); const objectIdFirst = await objectStorageWithMiddlewares.add(postData, { jwtPayloadOrToken: (0, jsonwebtoken_1.sign)(jwtPayload, config.jwtSecret) }); const objectIdSecond = await objectStorageWithMiddlewares.add(postData, { jwtPayloadOrToken: (0, jsonwebtoken_1.sign)(jwtPayload, config.jwtSecret) }); (0, chai_1.expect)(objectStorageWithMiddlewaresCalls.isDone()).to.be.true; (0, chai_1.expect)(objectIdFirst).to.be.equal('1'); (0, chai_1.expect)(objectIdSecond).to.be.equal('2'); }); it('should put 2 objects successfully', async () => { const objectStorageWithMiddlewares = new src_1.ObjectStorage(config); objectStorageWithMiddlewares.use(helpers_1.encryptStream, helpers_1.decryptStream); objectStorageWithMiddlewares.use(helpers_1.zip, helpers_1.unzip); const jwtPayload = { tenantId: '12', contractId: '1' }; const objectStorageWithMiddlewaresCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch(jwtPayload)) .put('/objects/1') .reply(200, responseData) .put('/objects/2') .reply(200, responseData); const responseFirst = await objectStorageWithMiddlewares.update('1', postData, { jwtPayloadOrToken: (0, jsonwebtoken_1.sign)(jwtPayload, config.jwtSecret) }); const responseSecond = await objectStorageWithMiddlewares.update('2', postData, { jwtPayloadOrToken: (0, jsonwebtoken_1.sign)(jwtPayload, config.jwtSecret) }); (0, chai_1.expect)(objectStorageWithMiddlewaresCalls.isDone()).to.be.true; (0, chai_1.expect)(responseFirst).to.deep.equal(responseData); (0, chai_1.expect)(responseSecond).to.deep.equal(responseData); }); it('should get 2 objects successfully', async () => { const objectStorageWithMiddlewares = new src_1.ObjectStorage(config); objectStorageWithMiddlewares.use(helpers_1.encryptStream, helpers_1.decryptStream); objectStorageWithMiddlewares.use(helpers_1.zip, helpers_1.unzip); const jwtPayload = { tenantId: '12', contractId: '1' }; const objectStorageWithMiddlewaresCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch(jwtPayload)) .get('/objects/1') .reply(200, () => { const stream = (0, helpers_1.streamFromObject)(responseData); return stream.pipe((0, helpers_1.encryptStream)()).pipe((0, helpers_1.zip)()); }) .get('/objects/2') .reply(200, () => { const stream = (0, helpers_1.streamFromObject)(responseData); return stream.pipe((0, helpers_1.encryptStream)()).pipe((0, helpers_1.zip)()); }); const { data: dataFirst } = await objectStorageWithMiddlewares.getOne('1', { jwtPayloadOrToken: (0, jsonwebtoken_1.sign)(jwtPayload, config.jwtSecret) }); const { data: dataSecond } = await objectStorageWithMiddlewares.getOne('2', { jwtPayloadOrToken: (0, jsonwebtoken_1.sign)(jwtPayload, config.jwtSecret) }); (0, chai_1.expect)(objectStorageWithMiddlewaresCalls.isDone()).to.be.true; (0, chai_1.expect)(dataFirst).to.be.deep.equal(responseData); (0, chai_1.expect)(dataSecond).to.be.deep.equal(responseData); }); it('should throw exception if neither jwt secret, nor jwt token provided', async () => { // @ts-ignore const objectStorageWithMiddlewares = new src_1.ObjectStorage({ uri: config.uri }); let err; try { await objectStorageWithMiddlewares.getOne('1', { jwtPayloadOrToken: {} }); } catch (e) { err = e; } (0, chai_1.expect)(err).to.be.instanceOf(errors_1.JwtNotProvidedError); }); }); describe('stream mode', () => { it(`should fail after ${interfaces_1.RETRIES_COUNT.defaultValue} get retries`, async () => { const objectStorageWithMiddlewares = new src_1.ObjectStorage(config); objectStorageWithMiddlewares.use(helpers_1.encryptStream, helpers_1.decryptStream); objectStorageWithMiddlewares.use(helpers_1.zip, helpers_1.unzip); const log = sinon_1.default.stub(logger_1.default, 'warn'); const objectStorageWithMiddlewaresCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch()) .get('/objects/1') .replyWithError({ code: 'ETIMEDOUT' }) .get('/objects/1') .reply(500) .get('/objects/1') .replyWithError({ code: 'ENOTFOUND' }); let err; try { await objectStorageWithMiddlewares.getOne('1', { jwtPayloadOrToken: {} }); } catch (e) { err = e; } (0, chai_1.expect)(objectStorageWithMiddlewaresCalls.isDone()).to.be.true; (0, chai_1.expect)(err).to.be.instanceOf(errors_1.ServerTransportError); (0, chai_1.expect)(log.getCall(1).args[1].toString()).to.include('Error during object request'); (0, chai_1.expect)(log.callCount).to.be.equal(interfaces_1.RETRIES_COUNT.defaultValue); }); it('should retry get request on errors', async () => { const objectStorageWithMiddlewares = new src_1.ObjectStorage(config); objectStorageWithMiddlewares.use(helpers_1.encryptStream, helpers_1.decryptStream); objectStorageWithMiddlewares.use(helpers_1.zip, helpers_1.unzip); const objectStorageWithMiddlewaresCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch()) .get('/objects/1') .reply(500) .get('/objects/1') .reply(200, () => { const stream = (0, helpers_1.streamFromObject)(responseData); return stream.pipe((0, helpers_1.encryptStream)()).pipe((0, helpers_1.zip)()); }); const { data } = await objectStorageWithMiddlewares.getOne('1', { jwtPayloadOrToken: {} }); (0, chai_1.expect)(objectStorageWithMiddlewaresCalls.isDone()).to.be.true; (0, chai_1.expect)(data).to.be.deep.equal(responseData); }); it('should throw an error on put request connection error', async () => { const objectStorageWithMiddlewares = new src_1.ObjectStorage(config); objectStorageWithMiddlewares.use(helpers_1.encryptStream, helpers_1.decryptStream); objectStorageWithMiddlewares.use(helpers_1.zip, helpers_1.unzip); const objectStorageWithMiddlewaresCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch()) .post('/objects') .replyWithError({ code: 'ECONNREFUSED' }) .post('/objects') .replyWithError({ code: 'ECONNREFUSED' }) .post('/objects') .replyWithError({ code: 'ECONNREFUSED' }); let err; try { await objectStorageWithMiddlewares.add((0, helpers_1.streamFromObject)(postData), { jwtPayloadOrToken: {} }); } catch (e) { err = e; } (0, chai_1.expect)(objectStorageWithMiddlewaresCalls.isDone()).to.be.true; (0, chai_1.expect)(err).to.be.instanceOf(errors_1.ServerTransportError); }); it('should throw an error on post request http error and no retries', async () => { const objectStorageWithMiddlewares = new src_1.ObjectStorage(config); objectStorageWithMiddlewares.use(helpers_1.encryptStream, helpers_1.decryptStream); objectStorageWithMiddlewares.use(helpers_1.zip, helpers_1.unzip); const objectStorageWithMiddlewaresCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch()) .post('/objects') .reply(500) .post('/objects') .reply(500) .post('/objects') .reply(500); let err; try { await objectStorageWithMiddlewares.add((0, helpers_1.streamFromObject)(postData), { jwtPayloadOrToken: {} }); } catch (e) { err = e; } (0, chai_1.expect)(objectStorageWithMiddlewaresCalls.isDone()).to.be.true; (0, chai_1.expect)(err).to.be.instanceOf(errors_1.ServerTransportError); }); it(`should retry put request ${interfaces_1.RETRIES_COUNT.defaultValue} times on errors`, async () => { const objectStorageWithMiddlewares = new src_1.ObjectStorage(config); objectStorageWithMiddlewares.use(helpers_1.encryptStream, helpers_1.decryptStream); objectStorageWithMiddlewares.use(helpers_1.zip, helpers_1.unzip); const objectStorageWithMiddlewaresCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch()) .put('/objects/1') .replyWithError({ code: 'ECONNREFUSED' }) .put('/objects/1') .reply(500) .put('/objects/1') .reply(200, responseData); const response = await objectStorageWithMiddlewares .update('1', (0, helpers_1.streamFromObject)(postData), { jwtPayloadOrToken: {} }); (0, chai_1.expect)(response).to.deep.equal(responseData); (0, chai_1.expect)(objectStorageWithMiddlewaresCalls.isDone()).to.be.true; }); it('should post successfully', async () => { const objectStorageWithMiddlewares = new src_1.ObjectStorage(config); objectStorageWithMiddlewares.use(helpers_1.encryptStream, helpers_1.decryptStream); objectStorageWithMiddlewares.use(helpers_1.zip, helpers_1.unzip); const objectStorageWithMiddlewaresCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch()) .post('/objects') .reply(200, { objectId: '1' }); const objectId = await objectStorageWithMiddlewares.add((0, helpers_1.streamFromObject)(postData), { jwtPayloadOrToken: {} }); (0, chai_1.expect)(objectStorageWithMiddlewaresCalls.isDone()).to.be.true; (0, chai_1.expect)(objectId).to.be.equal('1'); }); it('should add 2 objects successfully', async () => { const objectStorageWithMiddlewares = new src_1.ObjectStorage(config); objectStorageWithMiddlewares.use(helpers_1.encryptStream, helpers_1.decryptStream); objectStorageWithMiddlewares.use(helpers_1.zip, helpers_1.unzip); const jwtPayload = { tenantId: '12', contractId: '1' }; const objectStorageWithMiddlewaresCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch(jwtPayload)) .post('/objects') .reply(200, { objectId: '1' }) .post('/objects') .reply(200, { objectId: '2' }); const objectIdFirst = await objectStorageWithMiddlewares.add((0, helpers_1.streamFromObject)(postData), { jwtPayloadOrToken: (0, jsonwebtoken_1.sign)(jwtPayload, config.jwtSecret) }); const objectIdSecond = await objectStorageWithMiddlewares.add((0, helpers_1.streamFromObject)(postData), { jwtPayloadOrToken: (0, jsonwebtoken_1.sign)(jwtPayload, config.jwtSecret) }); (0, chai_1.expect)(objectStorageWithMiddlewaresCalls.isDone()).to.be.true; (0, chai_1.expect)(objectIdFirst).to.be.equal('1'); (0, chai_1.expect)(objectIdSecond).to.be.equal('2'); }); it('should put 2 objects successfully', async () => { const objectStorageWithMiddlewares = new src_1.ObjectStorage(config); objectStorageWithMiddlewares.use(helpers_1.encryptStream, helpers_1.decryptStream); objectStorageWithMiddlewares.use(helpers_1.zip, helpers_1.unzip); const jwtPayload = { tenantId: '12', contractId: '1' }; const objectStorageWithMiddlewaresCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch(jwtPayload)) .put('/objects/1') .reply(200, responseData) .put('/objects/2') .reply(200, responseData); const responseFirst = await objectStorageWithMiddlewares.update('1', (0, helpers_1.streamFromObject)(postData), { jwtPayloadOrToken: (0, jsonwebtoken_1.sign)(jwtPayload, config.jwtSecret) }); const responseSecond = await objectStorageWithMiddlewares.update('2', (0, helpers_1.streamFromObject)(postData), { jwtPayloadOrToken: (0, jsonwebtoken_1.sign)(jwtPayload, config.jwtSecret) }); (0, chai_1.expect)(objectStorageWithMiddlewaresCalls.isDone()).to.be.true; (0, chai_1.expect)(responseFirst).to.deep.equal(responseData); (0, chai_1.expect)(responseSecond).to.deep.equal(responseData); }); it('should get 2 objects successfully', async () => { const objectStorageWithMiddlewares = new src_1.ObjectStorage(config); objectStorageWithMiddlewares.use(helpers_1.encryptStream, helpers_1.decryptStream); objectStorageWithMiddlewares.use(helpers_1.zip, helpers_1.unzip); const jwtPayload = { tenantId: '12', contractId: '1' }; const objectStorageWithMiddlewaresCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch(jwtPayload)) .get('/objects/1') .reply(200, () => { const stream = (0, helpers_1.streamFromObject)(responseData); return stream.pipe((0, helpers_1.encryptStream)()).pipe((0, helpers_1.zip)()); }) .get('/objects/2') .reply(200, () => { const stream = (0, helpers_1.streamFromObject)(responseData); return stream.pipe((0, helpers_1.encryptStream)()).pipe((0, helpers_1.zip)()); }); const { data: dataStreamFirst } = await objectStorageWithMiddlewares.getOne('1', { jwtPayloadOrToken: (0, jsonwebtoken_1.sign)(jwtPayload, config.jwtSecret), responseType: 'stream' }); const outFirst = JSON.parse(await (0, get_stream_1.default)(dataStreamFirst)); const { data: dataStreamSecond } = await objectStorageWithMiddlewares.getOne('2', { jwtPayloadOrToken: (0, jsonwebtoken_1.sign)(jwtPayload, config.jwtSecret), responseType: 'stream' }); const outSecond = JSON.parse(await (0, get_stream_1.default)(dataStreamSecond)); (0, chai_1.expect)(objectStorageWithMiddlewaresCalls.isDone()).to.be.true; (0, chai_1.expect)(outFirst).to.be.deep.equal(responseData); (0, chai_1.expect)(outSecond).to.be.deep.equal(responseData); }); it('should use valid jwt token', async () => { const objectStorageWithMiddlewares = new src_1.ObjectStorage(config); objectStorageWithMiddlewares.use(helpers_1.encryptStream, helpers_1.decryptStream); objectStorageWithMiddlewares.use(helpers_1.zip, helpers_1.unzip); const jwtPayload = { tenantId: '12', contractId: '1' }; const objectStorageWithMiddlewaresCalls = (0, nock_1.default)(config.uri) .matchHeader('authorization', authHeaderMatch(jwtPayload)) .post('/objects') .reply(200); const objectId = await objectStorageWithMiddlewares.add((0, helpers_1.streamFromObject)(postData), { jwtPayloadOrToken: jwtPayload }); (0, chai_1.expect)(objectStorageWithMiddlewaresCalls.isDone()).to.be.true; (0, chai_1.expect)(objectId).to.match(/^[0-9a-z-]+$/); }); }); }); }); });