mirror of
https://github.com/nasa/openmct.git
synced 2024-12-20 21:53:08 +00:00
Handle empty namespaces in import (#7619)
* handle blank namespaces in import --------- Co-authored-by: Andrew Henry <akhenry@gmail.com>
This commit is contained in:
parent
e305b46d88
commit
b2b0837592
@ -150,16 +150,15 @@ export default class ImportAsJSONAction {
|
|||||||
* @param {string} namespace
|
* @param {string} namespace
|
||||||
* @returns {object}
|
* @returns {object}
|
||||||
*/
|
*/
|
||||||
_generateNewIdentifiers(tree, namespace) {
|
_generateNewIdentifiers(tree, newNamespace) {
|
||||||
// For each domain object in the file, generate new ID, replace in tree
|
// For each domain object in the file, generate new ID, replace in tree
|
||||||
Object.keys(tree.openmct).forEach((domainObjectId) => {
|
Object.keys(tree.openmct).forEach((domainObjectId) => {
|
||||||
const newId = {
|
|
||||||
namespace,
|
|
||||||
key: uuid()
|
|
||||||
};
|
|
||||||
|
|
||||||
const oldId = parseKeyString(domainObjectId);
|
const oldId = parseKeyString(domainObjectId);
|
||||||
|
|
||||||
|
const newId = {
|
||||||
|
namespace: newNamespace,
|
||||||
|
key: uuid()
|
||||||
|
};
|
||||||
tree = this._rewriteId(oldId, newId, tree);
|
tree = this._rewriteId(oldId, newId, tree);
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
@ -228,22 +227,32 @@ export default class ImportAsJSONAction {
|
|||||||
_rewriteId(oldId, newId, tree) {
|
_rewriteId(oldId, newId, tree) {
|
||||||
let newIdKeyString = this.openmct.objects.makeKeyString(newId);
|
let newIdKeyString = this.openmct.objects.makeKeyString(newId);
|
||||||
let oldIdKeyString = this.openmct.objects.makeKeyString(oldId);
|
let oldIdKeyString = this.openmct.objects.makeKeyString(oldId);
|
||||||
tree = JSON.stringify(tree).replace(new RegExp(oldIdKeyString, 'g'), newIdKeyString);
|
const newTreeString = JSON.stringify(tree).replace(
|
||||||
|
new RegExp(oldIdKeyString, 'g'),
|
||||||
return JSON.parse(tree, (key, value) => {
|
newIdKeyString
|
||||||
|
);
|
||||||
|
const newTree = JSON.parse(newTreeString, (key, value) => {
|
||||||
if (
|
if (
|
||||||
value !== undefined &&
|
value !== undefined &&
|
||||||
value !== null &&
|
value !== null &&
|
||||||
Object.prototype.hasOwnProperty.call(value, 'key') &&
|
Object.prototype.hasOwnProperty.call(value, 'key') &&
|
||||||
Object.prototype.hasOwnProperty.call(value, 'namespace') &&
|
Object.prototype.hasOwnProperty.call(value, 'namespace')
|
||||||
value.key === oldId.key &&
|
|
||||||
value.namespace === oldId.namespace
|
|
||||||
) {
|
) {
|
||||||
return newId;
|
// first check if key is messed up from regex and contains a colon
|
||||||
} else {
|
// if it does, repair it
|
||||||
return value;
|
if (value.key.includes(':')) {
|
||||||
|
const splitKey = value.key.split(':');
|
||||||
|
value.key = splitKey[1];
|
||||||
|
value.namespace = splitKey[0];
|
||||||
}
|
}
|
||||||
|
// now check if we need to replace the id
|
||||||
|
if (value.key === oldId.key && value.namespace === oldId.namespace) {
|
||||||
|
return newId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
});
|
});
|
||||||
|
return newTree;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
|
@ -135,11 +135,75 @@ describe('The import JSON action', function () {
|
|||||||
selectFile: {
|
selectFile: {
|
||||||
name: 'imported object',
|
name: 'imported object',
|
||||||
// eslint-disable-next-line prettier/prettier
|
// eslint-disable-next-line prettier/prettier
|
||||||
body: "{\"openmct\":{\"c28d230d-e909-4a3e-9840-d9ef469dda70\":{\"identifier\":{\"key\":\"c28d230d-e909-4a3e-9840-d9ef469dda70\",\"namespace\":\"\"},\"name\":\"Unnamed Overlay Plot\",\"type\":\"telemetry.plot.overlay\",\"composition\":[],\"configuration\":{\"series\":[]},\"modified\":1695837546833,\"location\":\"mine\",\"created\":1695837546833,\"persisted\":1695837546833,\"__proto__\":{\"toString\":\"foobar\"}}},\"rootId\":\"c28d230d-e909-4a3e-9840-d9ef469dda70\"}"
|
body: '{"openmct":{"c28d230d-e909-4a3e-9840-d9ef469dda70":{"identifier":{"key":"c28d230d-e909-4a3e-9840-d9ef469dda70","namespace":""},"name":"Unnamed Overlay Plot","type":"telemetry.plot.overlay","composition":[],"configuration":{"series":[]},"modified":1695837546833,"location":"mine","created":1695837546833,"persisted":1695837546833,"__proto__":{"toString":"foobar"}}},"rootId":"c28d230d-e909-4a3e-9840-d9ef469dda70"}'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return Promise.resolve(pollutedResponse);
|
return Promise.resolve(pollutedResponse);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
it('preserves the integrity of the namespace and key during import', async () => {
|
||||||
|
const incomingObject = {
|
||||||
|
openmct: {
|
||||||
|
'7323f02a-06ac-438d-bd58-6d6e33b8741e': {
|
||||||
|
name: 'Some Folder',
|
||||||
|
type: 'folder',
|
||||||
|
composition: [
|
||||||
|
{
|
||||||
|
key: '9f6c2d21-5ec8-434c-9fe8-31614ae6d7e6',
|
||||||
|
namespace: ''
|
||||||
|
}
|
||||||
|
],
|
||||||
|
modified: 1710843256162,
|
||||||
|
location: 'mine',
|
||||||
|
created: 1710843243471,
|
||||||
|
persisted: 1710843256162,
|
||||||
|
identifier: {
|
||||||
|
namespace: '',
|
||||||
|
key: '7323f02a-06ac-438d-bd58-6d6e33b8741e'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'9f6c2d21-5ec8-434c-9fe8-31614ae6d7e6': {
|
||||||
|
name: 'Some Clock',
|
||||||
|
type: 'clock',
|
||||||
|
configuration: {
|
||||||
|
baseFormat: 'YYYY/MM/DD hh:mm:ss',
|
||||||
|
use24: 'clock12',
|
||||||
|
timezone: 'UTC'
|
||||||
|
},
|
||||||
|
modified: 1710843256152,
|
||||||
|
location: '7323f02a-06ac-438d-bd58-6d6e33b8741e',
|
||||||
|
created: 1710843256152,
|
||||||
|
persisted: 1710843256152,
|
||||||
|
identifier: {
|
||||||
|
namespace: '',
|
||||||
|
key: '9f6c2d21-5ec8-434c-9fe8-31614ae6d7e6'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rootId: '7323f02a-06ac-438d-bd58-6d6e33b8741e'
|
||||||
|
};
|
||||||
|
|
||||||
|
const targetDomainObject = {
|
||||||
|
identifier: {
|
||||||
|
namespace: 'starJones',
|
||||||
|
key: '84438cda-a071-48d1-b9bf-d77bd53e59ba'
|
||||||
|
},
|
||||||
|
type: 'folder'
|
||||||
|
};
|
||||||
|
spyOn(openmct.objects, 'save').and.callFake((model) => Promise.resolve(model));
|
||||||
|
try {
|
||||||
|
await importFromJSONAction.onSave(targetDomainObject, {
|
||||||
|
selectFile: { body: JSON.stringify(incomingObject) }
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const callArgs of openmct.objects.save.calls.allArgs()) {
|
||||||
|
const savedObject = callArgs[0]; // Assuming the first argument is the object being saved.
|
||||||
|
expect(savedObject.identifier.key.includes(':')).toBeFalse(); // Ensure no colon in the key.
|
||||||
|
expect(savedObject.identifier.namespace).toBe(targetDomainObject.identifier.namespace);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
fail(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user