Compare commits

..

1 Commits

Author SHA1 Message Date
Mandlik, Nikhil K. (ARC-TI)[KBR Wyle Services, LLC]
501bdf8f5d [NIRVSS] [Types] Create button to display creatable types dynamically #3273 2020-08-05 12:04:16 -07:00
33 changed files with 186 additions and 579 deletions

View File

@@ -11,12 +11,12 @@ jobs:
name: Update npm
command: 'sudo npm install -g npm@latest'
- restore_cache:
key: dependency-cache-{{ checksum "package.json" }}
key: dependency-cache-13-{{ checksum "package.json" }}
- run:
name: Installing dependencies (npm install)
command: npm install
- save_cache:
key: dependency-cache-{{ checksum "package.json" }}
key: dependency-cache-13-{{ checksum "package.json" }}
paths:
- node_modules
- run:

View File

@@ -1,3 +0,0 @@
const testsContext = require.context('.', true, /\/(src|platform)\/.*Spec.js$/);
testsContext.keys().forEach(testsContext);

View File

@@ -23,7 +23,7 @@
/*global module,process*/
const devMode = process.env.NODE_ENV !== 'production';
const browsers = [process.env.NODE_ENV === 'debug' ? 'ChromeDebugging' : 'ChromeHeadless'];
const browsers = [process.env.NODE_ENV === 'debug' ? 'ChromeDebugging' : 'FirefoxHeadless'];
const coverageEnabled = process.env.COVERAGE === 'true';
const reporters = ['progress', 'html'];
@@ -52,16 +52,12 @@ module.exports = (config) => {
basePath: '',
frameworks: ['jasmine'],
files: [
'indexTest.js'
'platform/**/*Spec.js',
'src/**/*Spec.js'
],
port: 9876,
reporters: reporters,
browsers: browsers,
client: {
jasmine: {
random: false
}
},
customLaunchers: {
ChromeDebugging: {
base: 'Chrome',
@@ -70,7 +66,7 @@ module.exports = (config) => {
}
},
colors: true,
logLevel: config.LOG_DEBUG,
logLevel: config.LOG_INFO,
autoWatch: true,
// HTML test reporting.
htmlReporter: {
@@ -86,20 +82,20 @@ module.exports = (config) => {
reports: ['html', 'lcovonly', 'text-summary'],
thresholds: {
global: {
lines: 64
lines: 62
}
}
},
preprocessors: {
'indexTest.js': ['webpack', 'sourcemap']
'platform/**/*Spec.js': ['webpack', 'sourcemap'],
'src/**/*Spec.js': ['webpack', 'sourcemap']
},
webpack: webpackConfig,
webpackMiddleware: {
stats: 'errors-only',
logLevel: 'warn'
},
concurrency: 1,
singleRun: true,
browserNoActivityTimeout: 90000
});
};
}

View File

@@ -39,16 +39,16 @@
"istanbul-instrumenter-loader": "^3.0.1",
"jasmine-core": "^3.1.0",
"jsdoc": "^3.3.2",
"karma": "5.1.1",
"karma-chrome-launcher": "3.1.0",
"karma-firefox-launcher": "1.3.0",
"karma-cli": "2.0.0",
"karma-coverage": "2.0.3",
"karma-coverage-istanbul-reporter": "3.0.3",
"karma-html-reporter": "0.2.7",
"karma-jasmine": "3.3.1",
"karma-sourcemap-loader": "0.3.7",
"karma-webpack": "4.0.2",
"karma": "^2.0.3",
"karma-chrome-launcher": "^2.2.0",
"karma-firefox-launcher": "^1.3.0",
"karma-cli": "^1.0.1",
"karma-coverage": "^1.1.2",
"karma-coverage-istanbul-reporter": "^2.1.1",
"karma-html-reporter": "^0.2.7",
"karma-jasmine": "^1.1.2",
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "^3.0.0",
"location-bar": "^3.0.1",
"lodash": "^4.17.12",
"markdown-toc": "^0.11.7",

View File

@@ -79,6 +79,12 @@ function (
return this.objectService;
};
function resolveWith(object) {
return function () {
return object;
};
}
/**
* Save changes and conclude editing.
*
@@ -96,6 +102,7 @@ function (
SaveAsAction.prototype.save = function () {
var self = this,
domainObject = this.domainObject,
copyService = this.copyService,
dialog = new SaveInProgressDialog(this.dialogService),
toUndirty = [];
@@ -132,22 +139,19 @@ function (
return fetchObject(object.getModel().location);
}
function saveObject(parent) {
return this.openmct.editor.save().then(() => {
// Force mutation for search indexing
return parent;
});
function allowClone(objectToClone) {
var allowed =
(objectToClone.getId() === domainObject.getId())
|| objectToClone.getCapability('location').isOriginal();
if (allowed) {
toUndirty.push(objectToClone);
}
return allowed;
}
function addSavedObjectToParent(parent) {
return parent.getCapability("composition")
.add(domainObject)
.then(function (addedObject) {
return parent.getCapability("persistence").persist()
.then(function () {
return addedObject;
});
});
function cloneIntoParent(parent) {
return copyService.perform(domainObject, parent, allowClone);
}
function undirty(object) {
@@ -156,17 +160,26 @@ function (
function undirtyOriginals(object) {
return Promise.all(toUndirty.map(undirty))
.then(() => {
return object;
});
.then(resolveWith(object));
}
function indexForSearch(addedObject) {
addedObject.useCapability('mutation', (model) => {
function saveAfterClone(clonedObject) {
return this.openmct.editor.save().then(() => {
// Force mutation for search indexing
return clonedObject;
});
}
function finishEditing(clonedObject) {
return fetchObject(clonedObject.getId());
}
function indexForSearch(savedObject) {
savedObject.useCapability('mutation', (model) => {
return model;
});
return addedObject;
return savedObject;
}
function onSuccess(object) {
@@ -188,12 +201,10 @@ function (
.then(doWizardSave)
.then(showBlockingDialog)
.then(getParent)
.then(saveObject)
.then(addSavedObjectToParent)
.then(cloneIntoParent)
.then(undirtyOriginals)
.then((addedObject) => {
return fetchObject(addedObject.getId());
})
.then(saveAfterClone)
.then(finishEditing)
.then(indexForSearch)
.then(hideBlockingDialog)
.then(onSuccess)

View File

@@ -28,7 +28,6 @@ define(
describe("The Transaction Service", function () {
var mockQ,
mockLog,
mockCacheService,
transactionService;
function fastPromise(val) {
@@ -41,10 +40,9 @@ define(
beforeEach(function () {
mockQ = jasmine.createSpyObj("$q", ["all"]);
mockCacheService = jasmine.createSpyObj("cacheService", ["flush"]);
mockQ.all.and.returnValue(fastPromise());
mockLog = jasmine.createSpyObj("$log", ["error"]);
transactionService = new TransactionService(mockQ, mockLog, mockCacheService);
transactionService = new TransactionService(mockQ, mockLog);
});
it("isActive returns true if a transaction is in progress", function () {
@@ -87,20 +85,17 @@ define(
it("commit calls all queued commit functions", function () {
expect(transactionService.size()).toBe(3);
return transactionService.commit().then(() => {
onCommits.forEach(function (spy) {
expect(spy).toHaveBeenCalled();
});
transactionService.commit();
onCommits.forEach(function (spy) {
expect(spy).toHaveBeenCalled();
});
});
it("commit resets active state and clears queues", function () {
return transactionService.commit().then(() => {
expect(transactionService.isActive()).toBe(false);
expect(transactionService.size()).toBe(0);
expect(transactionService.size()).toBe(0);
});
transactionService.commit();
expect(transactionService.isActive()).toBe(false);
expect(transactionService.size()).toBe(0);
expect(transactionService.size()).toBe(0);
});
});

View File

@@ -46,34 +46,25 @@ define([
spyOn(provider, 'cleanTerm').and.returnValue('cleanedTerm');
spyOn(provider, 'fuzzyMatchUnquotedTerms').and.returnValue('fuzzy');
spyOn(provider, 'parseResponse').and.returnValue('parsedResponse');
$http.and.returnValue(Promise.resolve({
data: {
hits: {
hits: []
}
}
}));
$http.and.returnValue(Promise.resolve({}));
});
it('cleans terms and adds fuzzyness', function () {
return provider.query('hello', 10)
.then(() => {
expect(provider.cleanTerm).toHaveBeenCalledWith('hello');
expect(provider.fuzzyMatchUnquotedTerms)
.toHaveBeenCalledWith('cleanedTerm');
});
provider.query('hello', 10);
expect(provider.cleanTerm).toHaveBeenCalledWith('hello');
expect(provider.fuzzyMatchUnquotedTerms)
.toHaveBeenCalledWith('cleanedTerm');
});
it('calls through to $http', function () {
return provider.query('hello', 10).then(() => {
expect($http).toHaveBeenCalledWith({
method: 'GET',
params: {
q: 'fuzzy',
size: 10
},
url: 'http://localhost:9200/_search/'
});
provider.query('hello', 10);
expect($http).toHaveBeenCalledWith({
method: 'GET',
params: {
q: 'fuzzy',
size: 10
},
url: 'http://localhost:9200/_search/'
});
});

View File

@@ -27,7 +27,7 @@ define([
"../../src/services/SearchAggregator"
], function (SearchAggregator) {
xdescribe("SearchAggregator", function () {
describe("SearchAggregator", function () {
var $q,
objectService,
providers,

View File

@@ -422,10 +422,7 @@ define([
this.router.start();
this.emit('start');
}.bind(this), function () {
console.log('startPromise failed');
this.emit('start');
});
}.bind(this));
};
MCT.prototype.startHeadless = function () {
@@ -447,7 +444,6 @@ define([
MCT.prototype.destroy = function () {
this.emit('destroy');
this.router.destroy();
};
MCT.prototype.plugins = plugins;

View File

@@ -32,6 +32,10 @@ define([
var mockListener;
var oldBundles;
beforeAll(() => {
testUtils.resetApplicationState();
});
beforeEach(function () {
mockPlugin = jasmine.createSpy('plugin');
mockPlugin2 = jasmine.createSpy('plugin2');
@@ -52,8 +56,7 @@ define([
legacyRegistry.delete(bundle);
}
});
return testUtils.resetApplicationState(openmct);
testUtils.resetApplicationState(openmct);
});
it("exposes plugins", function () {

View File

@@ -35,8 +35,7 @@ define([
'./services/LegacyObjectAPIInterceptor',
'./views/installLegacyViews',
'./policies/LegacyCompositionPolicyAdapter',
'./actions/LegacyActionAdapter',
'./services/LegacyPersistenceAdapter'
'./actions/LegacyActionAdapter'
], function (
ActionDialogDecorator,
AdapterCapability,
@@ -52,8 +51,7 @@ define([
LegacyObjectAPIInterceptor,
installLegacyViews,
legacyCompositionPolicyAdapter,
LegacyActionAdapter,
LegacyPersistenceAdapter
LegacyActionAdapter
) {
return {
name: 'src/adapter',
@@ -116,13 +114,6 @@ define([
"instantiate",
"topic"
]
},
{
provides: "persistenceService",
type: "provider",
priority: "fallback",
implementation: LegacyPersistenceAdapter.default,
depends: ["openmct"]
}
],
policies: [

View File

@@ -1,29 +0,0 @@
import objectUtils from 'objectUtils';
function LegacyPersistenceProvider(openmct) {
this.openmct = openmct;
}
LegacyPersistenceProvider.prototype.listObjects = function () {
return Promise.resolve([]);
};
LegacyPersistenceProvider.prototype.listSpaces = function () {
return Promise.resolve(Object.keys(this.openmct.objects.providers));
};
LegacyPersistenceProvider.prototype.updateObject = function (legacyDomainObject) {
return this.openmct.objects.save(legacyDomainObject.useCapability('adapter'));
};
LegacyPersistenceProvider.prototype.updateObject = function (legacyDomainObject) {
return this.openmct.objects.save(legacyDomainObject.useCapability('adapter'));
};
LegacyPersistenceProvider.prototype.readObject = function (keystring) {
let identifier = objectUtils.parseKeyString(keystring);
return this.openmct.legacyObject(this.openmct.objects.get(identifier));
};
export default LegacyPersistenceProvider;

View File

@@ -94,7 +94,7 @@ describe("The LAD Table", () => {
});
afterEach(() => {
return resetApplicationState(openmct);
resetApplicationState(openmct);
});
it("should provide a table view only for lad table objects", () => {
@@ -284,7 +284,7 @@ describe("The LAD Table Set", () => {
});
afterEach(() => {
return resetApplicationState(openmct);
resetApplicationState(openmct);
});
it("should provide a lad table set view only for lad table set objects", () => {

View File

@@ -35,7 +35,7 @@ define(
) {
var defaultAjaxFunction = $.ajax;
describe("The URLIndicator", function () {
xdescribe("The URLIndicator", function () {
var openmct;
var indicatorElement;
var pluginOptions;

View File

@@ -66,7 +66,7 @@ export default class URLTimeSettingsSynchronizer {
TIME_EVENTS.forEach(event => {
this.openmct.time.off(event, this.setUrlFromTimeApi);
});
this.openmct.time.off('bounds', this.updateBounds);
this.openmct.time.on('bounds', this.updateBounds);
}
updateTimeSettings() {

View File

@@ -27,6 +27,7 @@ import {
describe("The URLTimeSettingsSynchronizer", () => {
let openmct;
let testClock;
beforeAll(() => resetApplicationState());
beforeEach((done) => {
openmct = createOpenMct();
@@ -81,17 +82,17 @@ describe("The URLTimeSettingsSynchronizer", () => {
expect(window.location.hash.includes('tc.mode=fixed')).toBe(false);
});
describe("when set in the url", () => {
it("will change from fixed to realtime mode when the mode changes", (done) => {
it("will change from fixed to realtime mode when the mode changes", () => {
expectLocationToBeInFixedMode();
return switchToRealtimeMode().then(() => {
let clock = openmct.time.clock();
expect(clock).toBeDefined();
expect(clock.key).toBe('local');
done();
});
});
it("the clock is correctly set in the API from the URL parameters", (done) => {
it("the clock is correctly set in the API from the URL parameters", () => {
return switchToRealtimeMode().then(() => {
let resolveFunction;
@@ -109,11 +110,10 @@ describe("The URLTimeSettingsSynchronizer", () => {
expect(clock).toBeDefined();
expect(clock.key).toBe('test-clock');
openmct.time.off('clock', resolveFunction);
done();
});
});
});
it("the clock offsets are correctly set in the API from the URL parameters", (done) => {
it("the clock offsets are correctly set in the API from the URL parameters", () => {
return switchToRealtimeMode().then(() => {
let resolveFunction;
@@ -132,11 +132,10 @@ describe("The URLTimeSettingsSynchronizer", () => {
expect(clockOffsets.start).toBe(-2000);
expect(clockOffsets.end).toBe(200);
openmct.time.off('clockOffsets', resolveFunction);
done();
});
});
});
it("the time system is correctly set in the API from the URL parameters", (done) => {
it("the time system is correctly set in the API from the URL parameters", () => {
return switchToRealtimeMode().then(() => {
let resolveFunction;
@@ -154,7 +153,6 @@ describe("The URLTimeSettingsSynchronizer", () => {
expect(timeSystem).toBeDefined();
expect(timeSystem.key).toBe('local');
openmct.time.off('timeSystem', resolveFunction);
done();
});
});
});
@@ -202,7 +200,7 @@ describe("The URLTimeSettingsSynchronizer", () => {
expect(window.location.hash.includes('tc.timeSystem=utc')).toBe(false);
});
describe("when set in the url", () => {
it("time system changes are reflected in the API", (done) => {
it("time system changes are reflected in the API", () => {
let resolveFunction;
return new Promise((resolve) => {
@@ -218,10 +216,9 @@ describe("The URLTimeSettingsSynchronizer", () => {
expect(timeSystem.key).toBe('local');
openmct.time.off('timeSystem', resolveFunction);
done();
});
});
it("mode can be changed from realtime to fixed", (done) => {
it("mode can be changed from realtime to fixed", () => {
return switchToRealtimeMode().then(() => {
expectLocationToBeInRealtimeMode();
@@ -229,10 +226,9 @@ describe("The URLTimeSettingsSynchronizer", () => {
}).then(switchToFixedMode).then(() => {
let clock = openmct.time.clock();
expect(clock).not.toBeDefined();
done();
});
});
it("bounds are correctly set in the API from the URL parameters", (done) => {
it("bounds are correctly set in the API from the URL parameters", () => {
let resolveFunction;
expectLocationToBeInFixedMode();
@@ -250,10 +246,9 @@ describe("The URLTimeSettingsSynchronizer", () => {
expect(bounds).toBeDefined();
expect(bounds.start).toBe(222);
expect(bounds.end).toBe(333);
done();
});
});
it("bounds are correctly set in the API from the URL parameters where only the end bound changes", (done) => {
it("bounds are correctly set in the API from the URL parameters where only the end bound changes", () => {
let resolveFunction;
expectLocationToBeInFixedMode();
@@ -270,7 +265,6 @@ describe("The URLTimeSettingsSynchronizer", () => {
expect(bounds).toBeDefined();
expect(bounds.start).toBe(0);
expect(bounds.end).toBe(333);
done();
});
});
});

View File

@@ -27,7 +27,7 @@ define([
'zepto',
'./dom-observer'
], function (AutoflowTabularPlugin, AutoflowTabularConstants, MCT, $, DOMObserver) {
describe("AutoflowTabularPlugin", function () {
xdescribe("AutoflowTabularPlugin", function () {
var testType;
var testObject;
var mockmct;

View File

@@ -36,6 +36,10 @@ describe('the plugin', function () {
let openmct;
let testTelemetryObject;
beforeAll(() => {
resetApplicationState(openmct);
});
beforeEach((done) => {
testTelemetryObject = {
identifier: {
@@ -94,7 +98,7 @@ describe('the plugin', function () {
});
afterEach(() => {
return resetApplicationState(openmct);
resetApplicationState(openmct);
});
let mockConditionSetObject = {
@@ -458,7 +462,7 @@ describe('the plugin', function () {
};
});
xit('should evaluate as stale when telemetry is not received in the allotted time', (done) => {
it('should evaluate as stale when telemetry is not received in the allotted time', (done) => {
let conditionMgr = new ConditionManager(conditionSetDomainObject, openmct);
conditionMgr.on('conditionSetResultUpdated', mockListener);
@@ -477,10 +481,10 @@ describe('the plugin', function () {
utc: undefined
});
done();
}, 400);
}, 300);
});
xit('should not evaluate as stale when telemetry is received in the allotted time', (done) => {
it('should not evaluate as stale when telemetry is received in the allotted time', (done) => {
const date = Date.now();
conditionSetDomainObject.configuration.conditionCollection[0].configuration.criteria[0].input = ["0.4"];
let conditionMgr = new ConditionManager(conditionSetDomainObject, openmct);

View File

@@ -29,6 +29,10 @@ describe('the plugin', function () {
let openmct;
let displayLayoutDefinition;
beforeAll(() => {
resetApplicationState(openmct);
});
beforeEach((done) => {
openmct = createOpenMct();
openmct.install(new DisplayLayoutPlugin({
@@ -45,7 +49,7 @@ describe('the plugin', function () {
});
afterEach(() => {
return resetApplicationState(openmct);
resetApplicationState(openmct);
});
it('defines a display layout object type with the correct key', () => {

View File

@@ -46,7 +46,7 @@ describe("the plugin", () => {
});
afterEach(() => {
return resetApplicationState(openmct);
resetApplicationState(openmct);
});
it('installs the new folder action', () => {

View File

@@ -35,6 +35,10 @@ describe('the plugin', () => {
parentElement,
mockMessages = ['error', 'test', 'notifications'];
beforeAll(() => {
resetApplicationState();
});
beforeEach((done) => {
openmct = createOpenMct();
@@ -57,7 +61,7 @@ describe('the plugin', () => {
});
afterEach(() => {
return resetApplicationState(openmct);
resetApplicationState(openmct);
});
describe('the indicator plugin element', () => {

View File

@@ -1,53 +0,0 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is 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.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/**
* A CouchDocument describes domain object model in a format
* which is easily read-written to CouchDB. This includes
* Couch's _id and _rev fields, as well as a separate
* metadata field which contains a subset of information found
* in the model itself (to support search optimization with
* CouchDB views.)
* @memberof platform/persistence/couch
* @constructor
* @param {string} id the id under which to store this mode
* @param {object} model the model to store
* @param {string} rev the revision to include (or undefined,
* if no revision should be noted for couch)
* @param {boolean} whether or not to mark this document as
* deleted (see CouchDB docs for _deleted)
*/
export default function CouchDocument(id, model, rev, markDeleted) {
return {
"_id": id,
"_rev": rev,
"_deleted": markDeleted,
"metadata": {
"category": "domain object",
"type": model.type,
"owner": "admin",
"name": model.name,
"created": Date.now()
},
"model": model
};
}

View File

@@ -1,134 +0,0 @@
import CouchDocument from "./CouchDocument";
import CouchObjectQueue from "./CouchObjectQueue";
const REV = "_rev";
const ID = "_id";
export default class CouchObjectProvider {
constructor(openmct, url, namespace) {
this.openmct = openmct;
this.url = url;
this.namespace = namespace;
this.objectQueue = {};
}
request(subPath, method, value) {
return fetch(this.url + '/' + subPath, {
method: method,
body: JSON.stringify(value)
}).then(response => response.json())
.then(function (response) {
return response;
}, function () {
return undefined;
});
}
// Check the response to a create/update/delete request;
// track the rev if it's valid, otherwise return false to
// indicate that the request failed.
// persist any queued objects
checkResponse(response, intermediateResponse) {
let requestSuccess = false;
const id = response.id;
let rev;
if (response && response.ok) {
rev = response.rev;
requestSuccess = true;
}
intermediateResponse.resolve(requestSuccess);
if (id) {
if (!this.objectQueue[id]) {
this.objectQueue[id] = new CouchObjectQueue(undefined, rev);
}
this.objectQueue[id].updateRevision(rev);
this.objectQueue[id].pending = false;
if (this.objectQueue[id].hasNext()) {
this.updateQueued(id);
}
}
}
getModel(response) {
if (response && response.model) {
let key = response[ID];
let object = response.model;
object.identifier = {
namespace: this.namespace,
key: key
};
if (!this.objectQueue[key]) {
this.objectQueue[key] = new CouchObjectQueue(undefined, response[REV]);
}
this.objectQueue[key].updateRevision(response[REV]);
return object;
} else {
return undefined;
}
}
get(identifier) {
return this.request(identifier.key, "GET").then(this.getModel.bind(this));
}
getIntermediateResponse() {
let intermediateResponse = {};
intermediateResponse.promise = new Promise(function (resolve, reject) {
intermediateResponse.resolve = resolve;
intermediateResponse.reject = reject;
});
return intermediateResponse;
}
enqueueObject(key, model, intermediateResponse) {
if (this.objectQueue[key]) {
this.objectQueue[key].enqueue({
model,
intermediateResponse
});
} else {
this.objectQueue[key] = new CouchObjectQueue({
model,
intermediateResponse
});
}
}
create(model) {
let intermediateResponse = this.getIntermediateResponse();
const key = model.identifier.key;
this.enqueueObject(key, model, intermediateResponse);
this.objectQueue[key].pending = true;
const queued = this.objectQueue[key].dequeue();
this.request(key, "PUT", new CouchDocument(key, queued.model)).then((response) => {
this.checkResponse(response, queued.intermediateResponse);
});
return intermediateResponse.promise;
}
updateQueued(key) {
if (!this.objectQueue[key].pending) {
this.objectQueue[key].pending = true;
const queued = this.objectQueue[key].dequeue();
this.request(key, "PUT", new CouchDocument(key, queued.model, this.objectQueue[key].rev)).then((response) => {
this.checkResponse(response, queued.intermediateResponse);
});
}
}
update(model) {
let intermediateResponse = this.getIntermediateResponse();
const key = model.identifier.key;
this.enqueueObject(key, model, intermediateResponse);
this.updateQueued(key);
return intermediateResponse.promise;
}
}

View File

@@ -1,32 +0,0 @@
//TODO: should we limit the queue size?
//const MAX_QUEUE_SIZE = 10;
export default class CouchObjectQueue {
constructor(object, rev) {
this.rev = rev;
this.objects = object ? [object] : [];
this.pending = false;
}
updateRevision(rev) {
this.rev = rev;
}
hasNext() {
return this.objects.length;
}
enqueue(item) {
this.objects.push(item);
}
dequeue() {
return this.objects.shift();
}
clear() {
this.rev = undefined;
this.objects = [];
}
}

View File

@@ -1,8 +0,0 @@
import CouchObjectProvider from './CouchObjectProvider';
const NAMESPACE = '';
export default function CouchPlugin(url) {
return function install(openmct) {
openmct.objects.addProvider(NAMESPACE, new CouchObjectProvider(openmct, url, NAMESPACE));
};
}

View File

@@ -1,102 +0,0 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2020, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is 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.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
import CouchPlugin from './plugin.js';
import {
createOpenMct,
resetApplicationState
} from 'utils/testing';
import CouchObjectProvider from "@/plugins/persistence/couch/CouchObjectProvider";
import CouchObjectQueue from "@/plugins/persistence/couch/CouchObjectQueue";
describe("the plugin", () => {
let openmct;
let element;
let child;
let provider;
let testSpace = "testSpace";
let testPath = "/test/db";
let mockDomainObject = {
identifier: {
namespace: '',
key: "some-value"
}
};
beforeEach((done) => {
openmct = createOpenMct(false);
openmct.install(new CouchPlugin(testSpace, testPath));
element = document.createElement('div');
child = document.createElement('div');
element.appendChild(child);
openmct.on('start', done);
openmct.startHeadless();
provider = openmct.objects.getProvider(mockDomainObject.identifier);
});
it('registers a provider for objects', () => {
expect(provider).toBeDefined();
});
it('gets an object', () => {
openmct.objects.get(mockDomainObject.identifier).then((result) => {
expect(provider.get).toHaveBeenCalled();
expect(result).toBeDefined();
});
});
it('creates an object', () => {
openmct.objects.save(mockDomainObject).then((result) => {
expect(provider.create).toHaveBeenCalled();
expect(result).toBeDefined();
});
});
it('updates an object', () => {
openmct.objects.save(mockDomainObject).then((result) => {
expect(provider.create).toHaveBeenCalled();
openmct.objects.save(mockDomainObject).then((updatedResult) => {
expect(provider.update).toHaveBeenCalled();
expect(updatedResult).toBeDefined();
});
});
});
it('updates queued objects', () => {
let couchProvider = new CouchObjectProvider(openmct, 'http://localhost', '');
let intermediateResponse = couchProvider.getIntermediateResponse();
spyOn(couchProvider, 'updateQueued');
couchProvider.enqueueObject(mockDomainObject.identifier.key, mockDomainObject, intermediateResponse);
couchProvider.objectQueue[mockDomainObject.identifier.key].updateRevision(1);
couchProvider.update(mockDomainObject);
expect(couchProvider.objectQueue[mockDomainObject.identifier.key].hasNext()).toBe(2);
couchProvider.checkResponse({
ok: true,
rev: 2,
id: mockDomainObject.identifier.key
}, intermediateResponse);
expect(couchProvider.updateQueued).toHaveBeenCalledTimes(2);
});
});

View File

@@ -54,8 +54,7 @@ define([
'./themes/snow',
'./URLTimeSettingsSynchronizer/plugin',
'./notificationIndicator/plugin',
'./newFolderAction/plugin',
'./persistence/couch/plugin'
'./newFolderAction/plugin'
], function (
_,
UTCTimeSystem,
@@ -90,12 +89,12 @@ define([
Snow,
URLTimeSettingsSynchronizer,
NotificationIndicator,
NewFolderAction,
CouchDBPlugin
NewFolderAction
) {
var bundleMap = {
LocalStorage: 'platform/persistence/local',
MyItems: 'platform/features/my-items',
CouchDB: 'platform/persistence/couch',
Elasticsearch: 'platform/persistence/elastic'
};
@@ -127,7 +126,27 @@ define([
plugins.Conductor = TimeConductorPlugin.default;
plugins.CouchDB = CouchDBPlugin.default;
plugins.CouchDB = function (url) {
return function (openmct) {
if (url) {
var bundleName = "config/couch";
openmct.legacyRegistry.register(bundleName, {
"extensions": {
"constants": [
{
"key": "COUCHDB_PATH",
"value": url,
"priority": "mandatory"
}
]
}
});
openmct.legacyRegistry.enable(bundleName);
}
openmct.legacyRegistry.enable(bundleMap.CouchDB);
};
};
plugins.Elasticsearch = function (url) {
return function (openmct) {

View File

@@ -28,27 +28,16 @@ import {
resetApplicationState
} from 'utils/testing';
class MockDataTransfer {
constructor() {
this.data = {};
}
get types() {
return Object.keys(this.data);
}
setData(format, data) {
this.data[format] = data;
}
getData(format) {
return this.data[format];
}
}
describe("the plugin", () => {
let openmct;
let tablePlugin;
let element;
let child;
beforeAll(() => {
resetApplicationState();
});
beforeEach((done) => {
openmct = createOpenMct();
@@ -78,7 +67,7 @@ describe("the plugin", () => {
});
afterEach(() => {
return resetApplicationState(openmct);
resetApplicationState(openmct);
});
describe("defines a table object", function () {
@@ -178,7 +167,7 @@ describe("the plugin", () => {
it("Renders a row for every telemetry datum returned", () => {
let rows = element.querySelectorAll('table.c-telemetry-table__body tr');
expect(rows.length).toBe(1);
expect(rows.length).toBe(3);
});
it("Renders a column for every item in telemetry metadata", () => {
@@ -202,7 +191,7 @@ describe("the plugin", () => {
dragStartEvent.dataTransfer =
dragOverEvent.dataTransfer =
dropEvent.dataTransfer = new MockDataTransfer();
dropEvent.dataTransfer = new DataTransfer();
fromColumn.dispatchEvent(dragStartEvent);
toColumn.dispatchEvent(dragOverEvent);

View File

@@ -13,7 +13,7 @@
<div class="c-super-menu__menu">
<ul>
<li
v-for="(item, index) in sortedItems"
v-for="(item, index) in sortedItems()"
:key="index"
:class="item.class"
:title="item.title"
@@ -44,42 +44,11 @@ import objectUtils from 'objectUtils';
export default {
inject: ['openmct'],
data: function () {
let items = [];
this.openmct.types.listKeys().forEach(key => {
let menuItem = this.openmct.types.get(key).definition;
if (menuItem.creatable) {
let menuItemTemplate = {
key: key,
name: menuItem.name,
class: menuItem.cssClass,
title: menuItem.description
};
items.push(menuItemTemplate);
}
});
return {
items: items,
selectedMenuItem: {},
opened: false
};
},
computed: {
sortedItems() {
return this.items.slice().sort((a, b) => {
if (a.name < b.name) {
return -1;
} else if (a.name > b.name) {
return 1;
} else {
return 0;
}
});
}
},
destroyed() {
document.removeEventListener('click', this.close);
},
@@ -132,6 +101,34 @@ export default {
let oldModel = objectUtils.toOldFormat(domainObject);
return this.openmct.$injector.get('instantiate')(oldModel, keyString);
},
sortedItems() {
// TODO: optimize to add event on change 'this.openmct.types'
let items = [];
this.openmct.types.listKeys().forEach(key => {
let menuItem = this.openmct.types.get(key).definition;
if (menuItem.creatable) {
let menuItemTemplate = {
key: key,
name: menuItem.name,
class: menuItem.cssClass,
title: menuItem.description
};
items.push(menuItemTemplate);
}
});
return items.slice().sort((a, b) => {
if (a.name < b.name) {
return -1;
} else if (a.name > b.name) {
return 1;
} else {
return 0;
}
});
}
}
};

View File

@@ -81,12 +81,7 @@ export default {
this.isLoading = true;
this.openmct.objects.get('ROOT')
.then(root => {
let composition = this.openmct.composition.get(root);
if (composition !== undefined) {
return composition.load();
} else {
return [];
}
return this.openmct.composition.get(root).load();
})
.then(children => {
this.isLoading = false;

View File

@@ -45,7 +45,6 @@ class ApplicationRouter extends EventEmitter {
super();
this.routes = [];
this.started = false;
this.locationBar = new LocationBar();
}
/**
@@ -57,17 +56,13 @@ class ApplicationRouter extends EventEmitter {
}
this.started = true;
this.locationBar.onChange(p => this.handleLocationChange(p));
this.locationBar.start({
let locationBar = new LocationBar();
locationBar.onChange(p => this.handleLocationChange(p));
locationBar.start({
root: location.pathname
});
}
destroy() {
this.locationBar.stop();
}
handleLocationChange(pathString) {
if (pathString[0] !== '/') {
pathString = '/' + pathString;

View File

@@ -32,6 +32,7 @@ import {
import {resetApplicationState} from 'utils/testing';
describe('the openmct location utility functions', () => {
beforeAll(() => resetApplicationState());
afterEach(() => resetApplicationState());
it('The setSearchParam function sets an individual search parameters in the window location hash', () => {

View File

@@ -65,29 +65,12 @@ export function clearBuiltinSpies() {
}
export function resetApplicationState(openmct) {
let promise;
clearBuiltinSpies();
window.location.hash = '#';
if (openmct !== undefined) {
openmct.destroy();
}
if (window.location.hash !== '#' && window.location.hash !== '') {
promise = new Promise((resolve, reject) => {
window.addEventListener('hashchange', cleanup);
window.location.hash = '#';
function cleanup() {
window.removeEventListener('hashchange', cleanup);
resolve();
}
});
} else {
promise = Promise.resolve();
}
return promise;
}
function clearBuiltinSpy(funcDefinition) {