Notebook Objects cannot be created with CouchDB enabled (#4425)

* added null check
* added test coverage for exception that caused bug

Co-authored-by: Andrew Henry <akhenry@gmail.com>
This commit is contained in:
Scott Bell 2021-11-15 21:55:04 +01:00 committed by GitHub
parent 53f5fdabe5
commit 8ef3869325
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 52 additions and 65 deletions

View File

@ -370,6 +370,7 @@ class CouchObjectProvider {
} }
return () => { return () => {
if (this.observers[keyString]) {
this.observers[keyString] = this.observers[keyString].filter(observer => observer !== callback); this.observers[keyString] = this.observers[keyString].filter(observer => observer !== callback);
if (this.observers[keyString].length === 0) { if (this.observers[keyString].length === 0) {
delete this.observers[keyString]; delete this.observers[keyString];
@ -377,6 +378,7 @@ class CouchObjectProvider {
this.stopObservingObjectChanges(); this.stopObservingObjectChanges();
} }
} }
}
}; };
} }

View File

@ -41,13 +41,12 @@ describe('the plugin', () => {
namespace: '', namespace: '',
key: 'some-value' key: 'some-value'
}, },
type: 'mock-type', type: 'notebook',
modified: 0 modified: 0
}; };
options = { options = {
url: testPath, url: testPath,
filter: {}, filter: {}
disableObserve: true
}; };
openmct = createOpenMct(); openmct = createOpenMct();
@ -66,7 +65,7 @@ describe('the plugin', () => {
openmct.install(new CouchPlugin(options)); openmct.install(new CouchPlugin(options));
openmct.types.addType('mock-type', {creatable: true}); openmct.types.addType('notebook', {creatable: true});
openmct.on('start', done); openmct.on('start', done);
openmct.startHeadless(); openmct.startHeadless();
@ -98,33 +97,26 @@ describe('the plugin', () => {
fetch.and.returnValue(mockPromise); fetch.and.returnValue(mockPromise);
}); });
it('gets an object', () => { it('gets an object', async () => {
return openmct.objects.get(mockDomainObject.identifier).then((result) => { const result = await openmct.objects.get(mockDomainObject.identifier);
expect(result.identifier.key).toEqual(mockDomainObject.identifier.key); expect(result.identifier.key).toEqual(mockDomainObject.identifier.key);
}); });
});
it('creates an object', () => { it('creates an object', async () => {
return openmct.objects.save(mockDomainObject).then((result) => { const result = await openmct.objects.save(mockDomainObject);
expect(provider.create).toHaveBeenCalled(); expect(provider.create).toHaveBeenCalled();
expect(result).toBeTrue(); expect(result).toBeTrue();
}); });
});
it('updates an object', (done) => { it('updates an object', async () => {
return openmct.objects.save(mockDomainObject).then((result) => { const result = await openmct.objects.save(mockDomainObject);
expect(result).toBeTrue(); expect(result).toBeTrue();
expect(provider.create).toHaveBeenCalled(); expect(provider.create).toHaveBeenCalled();
//Set modified timestamp it detects a change and persists the updated model. //Set modified timestamp it detects a change and persists the updated model.
mockDomainObject.modified = Date.now(); mockDomainObject.modified = Date.now();
const updatedResult = await openmct.objects.save(mockDomainObject);
return openmct.objects.save(mockDomainObject).then((updatedResult) => {
expect(updatedResult).toBeTrue(); expect(updatedResult).toBeTrue();
expect(provider.update).toHaveBeenCalled(); expect(provider.update).toHaveBeenCalled();
done();
});
});
}); });
}); });
describe('batches requests', () => { describe('batches requests', () => {
@ -140,7 +132,7 @@ describe('the plugin', () => {
}); });
fetch.and.returnValue(mockPromise); fetch.and.returnValue(mockPromise);
}); });
it('for multiple simultaneous gets', () => { it('for multiple simultaneous gets', async () => {
const objectIds = [ const objectIds = [
{ {
namespace: '', namespace: '',
@ -154,30 +146,26 @@ describe('the plugin', () => {
} }
]; ];
const getAllObjects = Promise.all( await Promise.all(
objectIds.map((identifier) => objectIds.map((identifier) =>
openmct.objects.get(identifier) openmct.objects.get(identifier)
)); )
);
return getAllObjects.then(() => {
const requestUrl = fetch.calls.mostRecent().args[0]; const requestUrl = fetch.calls.mostRecent().args[0];
const requestMethod = fetch.calls.mostRecent().args[1].method; const requestMethod = fetch.calls.mostRecent().args[1].method;
expect(fetch).toHaveBeenCalledTimes(1); expect(fetch).toHaveBeenCalledTimes(1);
expect(requestUrl.includes('_all_docs')).toBeTrue(); expect(requestUrl.includes('_all_docs')).toBeTrue();
expect(requestMethod).toEqual('POST'); expect(requestMethod).toEqual('POST');
}); });
});
it('but not for single gets', () => { it('but not for single gets', async () => {
const objectId = { const objectId = {
namespace: '', namespace: '',
key: 'object-1' key: 'object-1'
}; };
const getObject = openmct.objects.get(objectId); await openmct.objects.get(objectId);
return getObject.then(() => {
const requestUrl = fetch.calls.mostRecent().args[0]; const requestUrl = fetch.calls.mostRecent().args[0];
const requestMethod = fetch.calls.mostRecent().args[1].method; const requestMethod = fetch.calls.mostRecent().args[1].method;
@ -186,7 +174,6 @@ describe('the plugin', () => {
expect(requestMethod).toEqual('GET'); expect(requestMethod).toEqual('GET');
}); });
}); });
});
describe('implements server-side search', () => { describe('implements server-side search', () => {
let mockPromise; let mockPromise;
beforeEach(() => { beforeEach(() => {
@ -207,23 +194,21 @@ describe('the plugin', () => {
fetch.and.returnValue(mockPromise); fetch.and.returnValue(mockPromise);
}); });
it("using Couch's 'find' endpoint", () => { it("using Couch's 'find' endpoint", async () => {
return Promise.all(openmct.objects.search('test')).then(() => { await Promise.all(openmct.objects.search('test'));
const requestUrl = fetch.calls.mostRecent().args[0]; const requestUrl = fetch.calls.mostRecent().args[0];
expect(fetch).toHaveBeenCalled(); expect(fetch).toHaveBeenCalled();
expect(requestUrl.endsWith('_find')).toBeTrue(); expect(requestUrl.endsWith('_find')).toBeTrue();
}); });
});
it("and supports search by object name", () => { it("and supports search by object name", async () => {
return Promise.all(openmct.objects.search('test')).then(() => { await Promise.all(openmct.objects.search('test'));
const requestPayload = JSON.parse(fetch.calls.mostRecent().args[1].body); const requestPayload = JSON.parse(fetch.calls.mostRecent().args[1].body);
expect(requestPayload).toBeDefined(); expect(requestPayload).toBeDefined();
expect(requestPayload.selector.model.name.$regex).toEqual('(?i)test'); expect(requestPayload.selector.model.name.$regex).toEqual('(?i)test');
}); });
});
}); });
}); });