mirror of
https://github.com/nasa/openmct.git
synced 2025-06-27 11:32:13 +00:00
Compare commits
8 Commits
operator-s
...
trasaction
Author | SHA1 | Date | |
---|---|---|---|
ed1c79b449 | |||
e05d14c374 | |||
2e600317b2 | |||
db76d9ec4f | |||
bf19c4754f | |||
386348b658 | |||
641bc2f9fd | |||
1da329c092 |
@ -186,7 +186,7 @@ ObjectAPI.prototype.get = function (identifier, abortSignal) {
|
|||||||
identifier = utils.parseKeyString(identifier);
|
identifier = utils.parseKeyString(identifier);
|
||||||
let dirtyObject;
|
let dirtyObject;
|
||||||
if (this.isTransactionActive()) {
|
if (this.isTransactionActive()) {
|
||||||
dirtyObject = this.transaction.getDirtyObject(keystring);
|
dirtyObject = this.transaction.getDirtyObject(identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dirtyObject) {
|
if (dirtyObject) {
|
||||||
|
@ -39,6 +39,7 @@ describe("The Object API", () => {
|
|||||||
type: "test-type"
|
type: "test-type"
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("The save function", () => {
|
describe("The save function", () => {
|
||||||
it("Rejects if no provider available", () => {
|
it("Rejects if no provider available", () => {
|
||||||
let rejected = false;
|
let rejected = false;
|
||||||
@ -332,6 +333,48 @@ describe("The Object API", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("transactions", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
spyOn(openmct.editor, 'isEditing').and.returnValue(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('there is no active transaction', () => {
|
||||||
|
expect(objectAPI.isTransactionActive()).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('start a transaction', () => {
|
||||||
|
objectAPI.startTransaction();
|
||||||
|
expect(objectAPI.isTransactionActive()).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('has active transaction', () => {
|
||||||
|
objectAPI.startTransaction();
|
||||||
|
const activeTransaction = objectAPI.getActiveTransaction();
|
||||||
|
expect(activeTransaction).not.toBe(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('end a transaction', () => {
|
||||||
|
objectAPI.endTransaction();
|
||||||
|
expect(objectAPI.isTransactionActive()).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns dirty object on get', (done) => {
|
||||||
|
spyOn(objectAPI, 'supportsMutation').and.returnValue(true);
|
||||||
|
|
||||||
|
objectAPI.startTransaction();
|
||||||
|
objectAPI.mutate(mockDomainObject, 'name', 'dirty object');
|
||||||
|
|
||||||
|
const dirtyObject = objectAPI.transaction.getDirtyObject(mockDomainObject.identifier);
|
||||||
|
|
||||||
|
objectAPI.get(mockDomainObject.identifier)
|
||||||
|
.then(object => {
|
||||||
|
const areEqual = JSON.stringify(object) === JSON.stringify(dirtyObject);
|
||||||
|
expect(areEqual).toBe(true);
|
||||||
|
})
|
||||||
|
.finally(done);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function hasOwnProperty(object, property) {
|
function hasOwnProperty(object, property) {
|
||||||
|
@ -47,18 +47,19 @@ export default class Transaction {
|
|||||||
createDirtyObjectPromise(object, action) {
|
createDirtyObjectPromise(object, action) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
action(object)
|
action(object)
|
||||||
.then(resolve)
|
.then((success) => {
|
||||||
.catch(reject)
|
|
||||||
.finally(() => {
|
|
||||||
this.dirtyObjects.delete(object);
|
this.dirtyObjects.delete(object);
|
||||||
});
|
resolve(success);
|
||||||
|
})
|
||||||
|
.catch(reject);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getDirtyObject(keystring) {
|
getDirtyObject(identifier) {
|
||||||
let dirtyObject;
|
let dirtyObject;
|
||||||
this.dirtyObjects.forEach(object => {
|
this.dirtyObjects.forEach(object => {
|
||||||
if (this.objectAPI.makeKeyString(object.identifier) === keystring) {
|
const areIdsEqual = this.objectAPI.areIdsEqual(object.identifier, identifier);
|
||||||
|
if (areIdsEqual) {
|
||||||
dirtyObject = object;
|
dirtyObject = object;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
110
src/api/objects/TransactionSpec.js
Normal file
110
src/api/objects/TransactionSpec.js
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
import Transaction from "./Transaction";
|
||||||
|
import utils from 'objectUtils';
|
||||||
|
|
||||||
|
let openmct = {};
|
||||||
|
let objectAPI;
|
||||||
|
let transaction;
|
||||||
|
|
||||||
|
describe("Transaction Class", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
objectAPI = {
|
||||||
|
makeKeyString: (identifier) => utils.makeKeyString(identifier),
|
||||||
|
save: (object) => object,
|
||||||
|
mutate: (object, prop, value) => {
|
||||||
|
object[prop] = value;
|
||||||
|
|
||||||
|
return object;
|
||||||
|
},
|
||||||
|
refresh: (object) => Promise.resolve(object),
|
||||||
|
areIdsEqual: (...identifiers) => {
|
||||||
|
return identifiers.map(utils.parseKeyString)
|
||||||
|
.every(identifier => {
|
||||||
|
return identifier === identifiers[0]
|
||||||
|
|| (identifier.namespace === identifiers[0].namespace
|
||||||
|
&& identifier.key === identifiers[0].key);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
transaction = new Transaction(objectAPI);
|
||||||
|
|
||||||
|
openmct.editor = {
|
||||||
|
isEditing: () => true
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
it('has no dirty objects', () => {
|
||||||
|
expect(transaction.dirtyObjects.size).toEqual(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('add(), adds object to dirtyObjects', () => {
|
||||||
|
const mockDomainObjects = createMockDomainObjects();
|
||||||
|
transaction.add(mockDomainObjects[0]);
|
||||||
|
expect(transaction.dirtyObjects.size).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('cancel(), clears all dirtyObjects', (done) => {
|
||||||
|
const mockDomainObjects = createMockDomainObjects(3);
|
||||||
|
mockDomainObjects.forEach(transaction.add.bind(transaction));
|
||||||
|
|
||||||
|
expect(transaction.dirtyObjects.size).toEqual(3);
|
||||||
|
|
||||||
|
transaction.cancel()
|
||||||
|
.then(success => {
|
||||||
|
expect(transaction.dirtyObjects.size).toEqual(0);
|
||||||
|
}).finally(done);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('commit(), saves all dirtyObjects', (done) => {
|
||||||
|
const mockDomainObjects = createMockDomainObjects(3);
|
||||||
|
mockDomainObjects.forEach(transaction.add.bind(transaction));
|
||||||
|
|
||||||
|
expect(transaction.dirtyObjects.size).toEqual(3);
|
||||||
|
spyOn(objectAPI, 'save');
|
||||||
|
transaction.commit()
|
||||||
|
.then(success => {
|
||||||
|
expect(transaction.dirtyObjects.size).toEqual(0);
|
||||||
|
expect(objectAPI.save.calls.count()).toEqual(3);
|
||||||
|
}).finally(done);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('getDirtyObject(), returns correct dirtyObject', () => {
|
||||||
|
const mockDomainObjects = createMockDomainObjects();
|
||||||
|
transaction.add(mockDomainObjects[0]);
|
||||||
|
|
||||||
|
expect(transaction.dirtyObjects.size).toEqual(1);
|
||||||
|
const dirtyObject = transaction.getDirtyObject(mockDomainObjects[0].identifier);
|
||||||
|
|
||||||
|
expect(dirtyObject).toEqual(mockDomainObjects[0]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('getDirtyObject(), returns empty dirtyObject for no active transaction', () => {
|
||||||
|
const mockDomainObjects = createMockDomainObjects();
|
||||||
|
|
||||||
|
expect(transaction.dirtyObjects.size).toEqual(0);
|
||||||
|
const dirtyObject = transaction.getDirtyObject(mockDomainObjects[0].identifier);
|
||||||
|
|
||||||
|
expect(dirtyObject).toEqual(undefined);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function createMockDomainObjects(size = 1) {
|
||||||
|
const objects = [];
|
||||||
|
|
||||||
|
while (size > 0) {
|
||||||
|
const mockDomainObject = {
|
||||||
|
identifier: {
|
||||||
|
namespace: 'test-namespace',
|
||||||
|
key: `test-key-${size}`
|
||||||
|
},
|
||||||
|
name: `test object ${size}`,
|
||||||
|
type: 'test-type'
|
||||||
|
};
|
||||||
|
|
||||||
|
objects.push(mockDomainObject);
|
||||||
|
|
||||||
|
size--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return objects;
|
||||||
|
}
|
@ -49,9 +49,10 @@ describe('Application router utility functions', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('The setSearchParam function sets an individual search parameter in the window location hash', () => {
|
it('The setSearchParam function sets an individual search parameter in the window location hash', () => {
|
||||||
openmct.router.setSearchParam('testParam', 'testValue');
|
openmct.router.setSearchParam('testParam1', 'testValue1');
|
||||||
|
|
||||||
const searchParams = openmct.router.getAllSearchParams();
|
const searchParams = openmct.router.getAllSearchParams();
|
||||||
expect(searchParams.get('testParam')).toBe('testValue');
|
expect(searchParams.get('testParam1')).toBe('testValue1');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('The deleteSearchParam function deletes an individual search paramater in the window location hash', () => {
|
it('The deleteSearchParam function deletes an individual search paramater in the window location hash', () => {
|
||||||
|
Reference in New Issue
Block a user