@microfocus/alm-octane-js-rest-sdk
Version:
NodeJS wrapper for the Open Text ALM Octane API
278 lines (277 loc) • 14.1 kB
JavaScript
;
/*
* Copyright 2020-2023 Open Text.
*
* The only warranties for products and services of Open Text and
* its affiliates and licensors (“Open Text”) are as may be set forth
* in the express warranty statements accompanying such products and services.
* Nothing herein should be construed as constituting an additional warranty.
* Open Text shall not be liable for technical or editorial errors or
* omissions contained herein. The information contained herein is subject
* to change without notice.
*
* Except as specifically indicated otherwise, this document contains
* confidential information and a valid license is required for possession,
* use or copying. If this work is provided to the U.S. Government,
* consistent with FAR 12.211 and 12.212, Commercial Computer Software,
* Computer Software Documentation, and Technical Data for Commercial Items are
* licensed to the U.S. Government under vendor's standard commercial license.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
/* eslint-env mocha */
const assert_1 = __importDefault(require("assert"));
const octane_1 = __importDefault(require("../../../lib/root/octane"));
const defectEntityName = octane_1.default.entityTypes.defects;
const query_1 = __importDefault(require("../../../lib/query"));
const convertToRootConfig = require('./octaneConfigConverter').convertToRootConfig;
describe('octane', function () {
// @ts-ignore
this.slow(350);
let octane;
let configObject;
before(function adaptGenerateRoutesConfigFileToRootConfigFile() {
configObject = convertToRootConfig();
octane = new octane_1.default(configObject);
});
describe('makes successful CRUD operations', () => {
const numberOfCreatedDefects = 10;
function assertIdListsMatch(receivedIds, expectedIds) {
for (let i = 0; i < expectedIds.length; i++) {
assert_1.default.strictEqual(receivedIds[i], expectedIds[i]);
}
}
async function deleteDefectsWithIds(idsToDelete) {
if (idsToDelete !== undefined && idsToDelete.length > 0) {
const deletedDefects = await octane
.delete(defectEntityName)
.query(query_1.default.field('id').inComparison(idsToDelete).build())
.execute();
assert_1.default.strictEqual(deletedDefects.total_count, idsToDelete.length);
const deletedIds = deletedDefects.data.map((deletedEntity) => deletedEntity.id);
deletedIds.sort();
assertIdListsMatch(deletedIds, idsToDelete);
}
}
async function createDefects(numberOfDefects) {
const defects = [];
for (let i = 1; i <= numberOfDefects; i++) {
// noinspection HtmlRequiredLangAttribute
defects.push({
name: 'My Test Defect ' + Math.random(),
description: `<html><body>\n This is the test ${i} ${Math.random()} \n</body></html>`,
});
}
const createdDefects = await octane
.create(defectEntityName, defects)
.execute();
assert_1.default.strictEqual(createdDefects.total_count, numberOfDefects);
for (let i = 0; i < numberOfDefects; i++) {
defects[i].id = createdDefects.data[i].id;
}
return defects;
}
describe('create operations', function () {
const createdIds = [];
it('creates single defects', async () => {
const createdSingleDefect = await octane
.create(defectEntityName, { name: 'My Test Defect 0' })
.execute();
assert_1.default.strictEqual(createdSingleDefect.total_count, 1);
createdIds.push(createdSingleDefect.data[0].id);
});
it('creates multiple defects', async function () {
// @ts-ignore
this.timeout(3000).slow(750);
const newDefects = await createDefects(numberOfCreatedDefects);
newDefects.map((defect) => createdIds.push(defect.id));
});
after(async function () {
this.timeout(30000).slow(4000);
await deleteDefectsWithIds(createdIds);
});
});
describe('operations requiring setup and cleanup', () => {
const defectIds = [];
let defectSingleId;
let defects;
before(async function () {
defects = await createDefects(numberOfCreatedDefects);
defects.map((defect) => defectIds.push(defect.id));
defectSingleId = defectIds[0];
});
describe('read operations', () => {
it('get single defects', async () => {
const gotSingleDefect = await octane
.get(defectEntityName)
.at(defectSingleId)
.execute();
assert_1.default.strictEqual(gotSingleDefect.id, defectSingleId);
});
describe('on multiple defects', () => {
it('gets all created defects', async () => {
const gotDefects = await octane
.get(defectEntityName)
.orderBy('id')
.query(query_1.default.field('id').inComparison(defectIds).build())
.execute();
assert_1.default.strictEqual(gotDefects.total_count, numberOfCreatedDefects);
const receivedIds = gotDefects.data.map((data) => data.id);
assertIdListsMatch(receivedIds, defectIds);
});
it('gets the defect when using all possible get all request parameters', async () => {
const limit = Math.floor(defectIds.length / 2);
const offset = 1;
const expectedIds = [];
const expectedDefects = [];
defects.sort((d1, d2) => (d1.name > d2.name ? 1 : -1));
for (let i = offset; i < offset + limit; i++) {
expectedIds.push(defects[i].id);
expectedDefects.push(defects[i]);
}
const gotDefects = await octane
.get(defectEntityName)
.query(query_1.default.field('id').inComparison(defectIds).build())
.limit(limit)
.offset(offset)
.fields('name', 'description')
.orderBy('name')
.execute();
assert_1.default.strictEqual(gotDefects.total_count, defectIds.length);
assert_1.default.strictEqual(gotDefects.data.length, limit); // assert that the limit worked
const receivedIds = gotDefects.data.map((data) => data.id);
for (let i = 0; i < gotDefects.data.length; i++) {
assert_1.default.strictEqual(gotDefects.data[i].name, expectedDefects[i].name);
assert_1.default.strictEqual(gotDefects.data[i].description, expectedDefects[i].description);
}
receivedIds.sort();
expectedIds.sort();
assertIdListsMatch(receivedIds, expectedIds);
});
});
});
describe('update operations', () => {
it('updates single defect without id', async () => {
const defectUpdate = { name: 'Update 0 No Id' };
const updatedDefect = await octane
.update(defectEntityName, defectUpdate)
.at(defectSingleId)
.execute();
(0, assert_1.default)(updatedDefect.id, defectSingleId);
const gotUpdatedDefect = await octane
.get(defectEntityName)
.at(updatedDefect.id)
.fields('name')
.execute();
(0, assert_1.default)(gotUpdatedDefect.name, defectUpdate.name);
});
it('updates single defect with id', async () => {
const defectUpdate = { id: defectSingleId, name: 'Update 0 With Id' };
const updateSingleDefect = await octane
.update(defectEntityName, defectUpdate)
.execute();
(0, assert_1.default)(updateSingleDefect.id, defectSingleId);
const gotUpdatedDefect = await octane
.get(defectEntityName)
.at(updateSingleDefect.id)
.fields('name')
.execute();
(0, assert_1.default)(gotUpdatedDefect.name, defectUpdate.name);
});
it('updates multiple defects', async () => {
const defectsToUpdate = [];
defectIds.sort();
defectIds.map((id) => {
defectsToUpdate.push({
name: 'Update ' + Math.random(),
id: id,
});
});
const updateDefects = await octane
.updateBulk(defectEntityName, defectsToUpdate)
.execute();
const receivedIds = updateDefects.data.map((data) => data.id);
assertIdListsMatch(receivedIds, defectIds);
const gotUpdatedDefect = await octane
.get(defectEntityName)
.fields('name')
.query(query_1.default.field('id').inComparison(receivedIds).build())
.orderBy('id')
.execute();
for (let i = 0; i < receivedIds.length; i++) {
(0, assert_1.default)(gotUpdatedDefect.data[i].name, defectsToUpdate[i].name);
}
});
});
after(async function () {
this.timeout(10000).slow(4000);
await deleteDefectsWithIds(defectIds);
});
});
describe('delete operations', () => {
const defectIds = [];
let defectSingleId;
before(async function () {
const newDefects = await createDefects(numberOfCreatedDefects + 1);
newDefects.map((defect) => defectIds.push(defect.id));
defectSingleId = defectIds.pop();
});
it('deletes single defects', async () => {
const deleteSingleDefect = await octane
.delete(defectEntityName)
.at(defectSingleId)
.execute();
assert_1.default.strictEqual(deleteSingleDefect, undefined);
});
it('deletes multiple defects', async function () {
// @ts-ignore
this.timeout(10000).slow(4000);
await deleteDefectsWithIds(defectIds);
});
});
describe('custom operation', () => {
const defectIds = [];
let defectSingleId;
let defects;
before(async () => {
defects = await createDefects(numberOfCreatedDefects);
defects.map((defect) => defectIds.push(defect.id));
defectSingleId = defectIds[0];
});
it('sends request for defect with custom header', async () => {
const url = '/api/shared_spaces/' +
configObject.sharedSpace +
'/workspaces/' +
configObject.workspace +
'/defects/' +
defectSingleId;
await assert_1.default.doesNotReject(octane.executeCustomRequest(url, octane_1.default.operationTypes.get, undefined, { 'ALM-OCTANE-TECH-PREVIEW': true }));
const gotSingleDefect = await octane.executeCustomRequest(url, octane_1.default.operationTypes.get, undefined, { 'ALM-OCTANE-TECH-PREVIEW': true });
assert_1.default.strictEqual(gotSingleDefect.id, defectSingleId);
});
it('fails on not supported operation', async () => {
const url = '/api/shared_spaces/' +
configObject.sharedSpace +
'/workspaces/' +
configObject.workspace +
'/defects/' +
defectSingleId;
await assert_1.default.rejects(octane.executeCustomRequest(url, 'someRandomOp', undefined, {
'ALM-OCTANE-TECH-PREVIEW': true,
}), new Error('Operation is not supported'));
});
});
});
});