@elastic.io/maester-client
Version:
The official object-storage client
352 lines (351 loc) • 18.3 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
/* eslint-disable max-len */
require("mocha");
const chai_1 = __importStar(require("chai"));
const sinon_1 = __importDefault(require("sinon"));
const get_stream_1 = __importDefault(require("get-stream"));
const chai_as_promised_1 = __importDefault(require("chai-as-promised"));
const helpers_1 = require("./helpers");
const src_1 = require("../src");
chai_1.default.use(chai_as_promised_1.default);
process.env.ELASTICIO_OBJECT_STORAGE_TOKEN = 'eyJhbGciOiJIUzI1NiIsInR5cCI6I';
process.env.ELASTICIO_OBJECT_STORAGE_URI = 'https://ma.estr';
describe('ObjectStorageWrapper', () => {
const objectStorageWrapper = new src_1.ObjectStorageWrapper((0, helpers_1.getContext)(), 'userAgent');
const genHeaders = (amount) => {
const resultHeaders = [];
for (let i = 0; i < amount; i++) {
resultHeaders.push({ key: `key${i}`, value: `value${i}` });
}
return resultHeaders;
};
const data = {
foo: 'bar',
};
const updatedData = {
foo: 'bar',
bap: 'baz',
};
const queryKey = 'baz';
const queryValue = 'bap';
const ttl = 10;
const id = 'id123';
const createObjectWithQueriableField = {
contentType: 'application/json',
createdAt: 1622811501107,
objectId: '2bd48165-119f-489d-8842-8d07b2c7cc1b',
metadata: {},
queriableFields: {
demosearchfield: 'qwerty',
},
};
let finalReqCfg;
afterEach(sinon_1.default.restore);
before(() => {
process.env.ELASTICIO_FLOW_ID = 'flow_id';
process.env.ELASTICIO_STEP_ID = 'step_id';
});
describe('Create object', () => {
beforeEach(async () => {
finalReqCfg = sinon_1.default.stub(src_1.StorageClient.prototype, 'requestRetry').callsFake(async () => ({ data: createObjectWithQueriableField }));
});
describe('valid inputs', () => {
it('Should save the data correctly (1 q-header, ttl-value)', async () => {
const result = await objectStorageWrapper.createObject(data, genHeaders(1), [], ttl);
(0, chai_1.expect)(result).to.be.equal(createObjectWithQueriableField.objectId);
const { firstArg, lastArg } = finalReqCfg.getCall(0);
(0, chai_1.expect)(lastArg).to.be.deep.equal({});
const stream = await firstArg.getFreshStream();
(0, chai_1.expect)(await (0, get_stream_1.default)(stream)).to.be.equal(JSON.stringify(data));
(0, chai_1.expect)(firstArg.axiosReqConfig).to.be.deep.equal({
method: 'post',
url: '/objects',
headers: {
Authorization: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6I',
'User-Agent': 'userAgent axios/^1.8.2',
'x-query-key0': 'value0',
'x-eio-ttl': '10',
'x-request-id': 'f:flow_id;s:step_id;m:',
}
});
});
it('Should save the data correctly (2 q-header, 3 q-header)', async () => {
const result = await objectStorageWrapper.createObject(data, genHeaders(2), genHeaders(3));
(0, chai_1.expect)(result).to.be.equal(createObjectWithQueriableField.objectId);
const { firstArg, lastArg } = finalReqCfg.getCall(0);
(0, chai_1.expect)(lastArg).to.be.deep.equal({});
const stream = await firstArg.getFreshStream();
(0, chai_1.expect)(await (0, get_stream_1.default)(stream)).to.be.equal(JSON.stringify(data));
(0, chai_1.expect)(firstArg.axiosReqConfig).to.be.deep.equal({
method: 'post',
url: '/objects',
headers: {
Authorization: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6I',
'User-Agent': 'userAgent axios/^1.8.2',
'x-query-key0': 'value0',
'x-query-key1': 'value1',
'x-meta-key0': 'value0',
'x-meta-key1': 'value1',
'x-meta-key2': 'value2',
'x-request-id': 'f:flow_id;s:step_id;m:',
}
});
});
it('Should save the data correctly (no headers)', async () => {
const result = await objectStorageWrapper.createObject(data);
(0, chai_1.expect)(result).to.be.equal(createObjectWithQueriableField.objectId);
const { firstArg, lastArg } = finalReqCfg.getCall(0);
(0, chai_1.expect)(lastArg).to.be.deep.equal({});
const stream = await firstArg.getFreshStream();
(0, chai_1.expect)(await (0, get_stream_1.default)(stream)).to.be.equal(JSON.stringify(data));
(0, chai_1.expect)(firstArg.axiosReqConfig).to.be.deep.equal({
method: 'post',
url: '/objects',
headers: {
Authorization: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6I',
'User-Agent': 'userAgent axios/^1.8.2',
'x-request-id': 'f:flow_id;s:step_id;m:',
}
});
});
it('Should save the data correctly (no headers)', async () => {
const result = await objectStorageWrapper.createObject(data, [], []);
(0, chai_1.expect)(result).to.be.equal(createObjectWithQueriableField.objectId);
const { firstArg, lastArg } = finalReqCfg.getCall(0);
(0, chai_1.expect)(lastArg).to.be.deep.equal({});
const stream = await firstArg.getFreshStream();
(0, chai_1.expect)(await (0, get_stream_1.default)(stream)).to.be.equal(JSON.stringify(data));
(0, chai_1.expect)(firstArg.axiosReqConfig).to.be.deep.equal({
method: 'post',
url: '/objects',
headers: {
Authorization: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6I',
'User-Agent': 'userAgent axios/^1.8.2',
'x-request-id': 'f:flow_id;s:step_id;m:',
}
});
});
});
describe('invalid inputs', () => {
it('Should throw error', async () => {
await (0, chai_1.expect)(
// @ts-ignore
objectStorageWrapper.createObject(data, [{ key: 'key0', value: 'value0' }, { key: 'key1' }], [], ttl)).to.be.rejectedWith('header "value" is mandatory if header "key" passed');
});
it('Should throw error', async () => {
await (0, chai_1.expect)(
// @ts-ignore
objectStorageWrapper.createObject(data, [{ value: 'value1' }], [], ttl)).to.be.rejectedWith('header "key" is mandatory if header "value" passed');
});
it(`Should throw error, Maester headers maximum amount is exceed (${src_1.MAESTER_MAX_SUPPORTED_COUNT_OF_QUERY_HEADERS} items)`, async () => {
await (0, chai_1.expect)(
// @ts-ignore
objectStorageWrapper.createObject(data, genHeaders(src_1.MAESTER_MAX_SUPPORTED_COUNT_OF_QUERY_HEADERS + 1), [], ttl)).to.be.rejectedWith(`maximum available amount of headers is ${src_1.MAESTER_MAX_SUPPORTED_COUNT_OF_QUERY_HEADERS}`);
});
it('Should throw error, Header used more than one time', async () => {
await (0, chai_1.expect)(
// @ts-ignore
objectStorageWrapper.createObject(data, [
{ key: 'key0', value: 'value0' },
{ key: 'key1', value: 'value0' },
{ key: 'key0', value: 'value0' },
], [], ttl)).to.be.rejectedWith('header key "key0" was already added');
});
});
});
describe('Lookup object by ID', () => {
beforeEach(async () => {
finalReqCfg = sinon_1.default.stub(src_1.StorageClient.prototype, 'requestRetry').callsFake(async () => ({ data: (0, helpers_1.streamFromObject)(data) }));
});
it('Should successfully return object', async () => {
const result = await objectStorageWrapper.lookupObjectById(id);
(0, chai_1.expect)(result).to.be.deep.equal(data);
const { firstArg, lastArg } = finalReqCfg.getCall(0);
(0, chai_1.expect)(lastArg).to.be.deep.equal({});
(0, chai_1.expect)(firstArg.getFreshStream).to.be.equal(undefined);
(0, chai_1.expect)(firstArg.axiosReqConfig).to.deep.equal({
method: 'get',
url: '/objects/id123',
responseType: 'stream',
params: {},
headers: {
Authorization: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6I',
'User-Agent': 'userAgent axios/^1.8.2',
'x-request-id': 'f:flow_id;s:step_id;m:',
}
});
});
});
describe('Lookup objects by query parameters', () => {
beforeEach(async () => {
finalReqCfg = sinon_1.default.stub(src_1.StorageClient.prototype, 'requestRetry').callsFake(async () => ({
data: (0, helpers_1.streamFromObject)([createObjectWithQueriableField, createObjectWithQueriableField])
}));
});
it('Should return 2 objects', async () => {
const result = await objectStorageWrapper.lookupObjectsByQueryParameters([{ key: queryKey, value: queryValue }]);
(0, chai_1.expect)(result).to.deep.equal([createObjectWithQueriableField, createObjectWithQueriableField]);
const { firstArg, lastArg } = finalReqCfg.getCall(0);
(0, chai_1.expect)(lastArg).to.be.deep.equal({});
(0, chai_1.expect)(firstArg.getFreshStream).to.be.equal(undefined);
(0, chai_1.expect)(firstArg.axiosReqConfig).to.deep.equal({
method: 'get',
url: '/objects',
responseType: 'stream',
params: { 'query[baz]': 'bap' },
headers: {
Authorization: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6I',
'User-Agent': 'userAgent axios/^1.8.2',
'x-request-id': 'f:flow_id;s:step_id;m:',
}
});
});
it('Should throw error: query key set, query value undefined', async () => {
await (0, chai_1.expect)(
// @ts-ignore
objectStorageWrapper.lookupObjectsByQueryParameters([{ key: 'key0', value: 'value0' }, { key: 'key1' }])).to.be.rejectedWith('header "value" is mandatory if header "key" passed');
});
});
describe('Update object', () => {
beforeEach(async () => {
finalReqCfg = sinon_1.default.stub(src_1.StorageClient.prototype, 'requestRetry').callsFake(async () => ({ data: createObjectWithQueriableField }));
});
describe('Valid update request', () => {
it('Should successfully update an object', async () => {
const result = await objectStorageWrapper.updateObjectById(id, updatedData);
(0, chai_1.expect)(result).to.deep.equal(createObjectWithQueriableField);
const { firstArg, lastArg } = finalReqCfg.getCall(0);
(0, chai_1.expect)(lastArg).to.be.deep.equal({});
const stream = await firstArg.getFreshStream();
(0, chai_1.expect)(await (0, get_stream_1.default)(stream)).to.be.equal(JSON.stringify(updatedData));
(0, chai_1.expect)(firstArg.axiosReqConfig).to.be.deep.equal({
method: 'put',
url: '/objects/id123',
headers: {
Authorization: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6I',
'User-Agent': 'userAgent axios/^1.8.2',
'x-request-id': 'f:flow_id;s:step_id;m:',
}
});
});
it('Should successfully update an object with headers', async () => {
const result = await objectStorageWrapper.updateObjectById(id, updatedData, genHeaders(3), genHeaders(2));
(0, chai_1.expect)(result).to.deep.equal(createObjectWithQueriableField);
const { firstArg, lastArg } = finalReqCfg.getCall(0);
(0, chai_1.expect)(lastArg).to.be.deep.equal({});
const stream = await firstArg.getFreshStream();
(0, chai_1.expect)(await (0, get_stream_1.default)(stream)).to.be.equal(JSON.stringify(updatedData));
(0, chai_1.expect)(firstArg.axiosReqConfig).to.be.deep.equal({
method: 'put',
url: '/objects/id123',
headers: {
Authorization: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6I',
'User-Agent': 'userAgent axios/^1.8.2',
'x-query-key0': 'value0',
'x-query-key1': 'value1',
'x-query-key2': 'value2',
'x-meta-key0': 'value0',
'x-meta-key1': 'value1',
'x-request-id': 'f:flow_id;s:step_id;m:',
}
});
});
});
describe('Invalid update request', () => {
it('Should throw an error', async () => {
await (0, chai_1.expect)(
// @ts-ignore
objectStorageWrapper.updateObjectById(id, updatedData, [
{ key: 'key0', value: 'value0' },
{ key: 'key0', value: 'value0' },
])).to.be.rejectedWith('header key "key0" was already added');
});
});
});
describe('Delete object by ID', () => {
beforeEach(async () => {
finalReqCfg = sinon_1.default.stub(src_1.StorageClient.prototype, 'requestRetry').callsFake(async () => ({ data: '' }));
});
it('should delete object by ID', async () => {
const objectStorageWrapper2 = new src_1.ObjectStorageWrapper((0, helpers_1.getContext)(), 'userAgent', 'msgId');
const result = await objectStorageWrapper2.deleteObjectById(id);
(0, chai_1.expect)(result.data).to.be.equal('');
const { firstArg, lastArg } = finalReqCfg.getCall(0);
(0, chai_1.expect)(lastArg).to.be.deep.equal({});
(0, chai_1.expect)(firstArg.getFreshStream).to.be.equal(undefined);
(0, chai_1.expect)(firstArg.axiosReqConfig).to.be.deep.equal({
method: 'delete',
url: '/objects/id123',
params: {},
headers: {
Authorization: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6I',
'User-Agent': 'userAgent axios/^1.8.2',
'x-request-id': 'f:flow_id;s:step_id;m:msgId',
}
});
});
});
describe('Delete object by query parameter', () => {
beforeEach(async () => {
finalReqCfg = sinon_1.default.stub(src_1.StorageClient.prototype, 'requestRetry').callsFake(async () => ({ data: '' }));
});
describe('Different amount of search params', () => {
describe('valid input', () => {
it('Should successfully delete objects (one param)', async () => {
const result = await objectStorageWrapper.deleteObjectsByQueryParameters(genHeaders(2));
(0, chai_1.expect)(result.data).to.be.equal('');
const { firstArg, lastArg } = finalReqCfg.getCall(0);
(0, chai_1.expect)(lastArg).to.be.deep.equal({});
(0, chai_1.expect)(firstArg.getFreshStream).to.be.equal(undefined);
(0, chai_1.expect)(firstArg.axiosReqConfig).to.be.deep.equal({
method: 'delete',
url: '/objects',
params: { 'query[key0]': 'value0', 'query[key1]': 'value1' },
headers: {
Authorization: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6I',
'User-Agent': 'userAgent axios/^1.8.2',
'x-request-id': 'f:flow_id;s:step_id;m:',
}
});
});
});
});
});
});