From bd1c3cb7dac2a1a43f2c6759156875b3dfddfe0a Mon Sep 17 00:00:00 2001 From: Henry Date: Tue, 3 Nov 2015 17:39:05 -0800 Subject: [PATCH] All test cases passing + added test cases for copy --- platform/entanglement/bundle.json | 2 +- .../entanglement/src/services/CopyService.js | 24 ++-- .../test/services/CopyServiceSpec.js | 119 ++++++++---------- 3 files changed, 63 insertions(+), 82 deletions(-) diff --git a/platform/entanglement/bundle.json b/platform/entanglement/bundle.json index 192a132602..702af234bb 100644 --- a/platform/entanglement/bundle.json +++ b/platform/entanglement/bundle.json @@ -77,7 +77,7 @@ "description": "Provides a service for copying objects", "implementation": "services/CopyService.js", "depends": ["$q", "creationService", "policyService", - "persistenceService"] + "persistenceService", "now"] }, { "key": "locationService", diff --git a/platform/entanglement/src/services/CopyService.js b/platform/entanglement/src/services/CopyService.js index da8339e965..220084f7a5 100644 --- a/platform/entanglement/src/services/CopyService.js +++ b/platform/entanglement/src/services/CopyService.js @@ -35,11 +35,12 @@ define( * @memberof platform/entanglement * @implements {platform/entanglement.AbstractComposeService} */ - function CopyService($q, creationService, policyService, persistenceService) { + function CopyService($q, creationService, policyService, persistenceService, now) { this.$q = $q; this.creationService = creationService; this.policyService = policyService; this.persistenceService = persistenceService; + this.now = now; } CopyService.prototype.validate = function (object, parentCandidate) { @@ -95,16 +96,15 @@ define( } delete modelClone.model.composition; delete modelClone.model.location; + delete modelClone.model.persisted; + delete modelClone.model.modified; return $q.when(originalObject.useCapability('composition')).then(function(composees){ - console.log("composees: " + composees); return (composees || []).reduce(function(promise, composee){ - console.log("inside reduce"); //If the object is composed of other // objects, chain a promise.. return promise.then(function(){ // ...to recursively copy it (and its children) return copy(composee, originalObject).then(function(composeeClone){ - console.log("Composing clone"); //Once copied, associate each cloned // composee with its parent clone composeeClone.model.location = modelClone.id; @@ -113,7 +113,6 @@ define( }); });}, $q.when(undefined) ).then(function (){ - console.log("Adding clone to list"); //Add the clone to the list of clones that will //be returned by this function clones.push(modelClone); @@ -122,7 +121,6 @@ define( }); }; return copy(domainObject, parent).then(function(){ - console.log("Done cloning, returning"); return clones; }); } @@ -140,13 +138,13 @@ define( var persisted = 0, self = this; return function(objectClones) { - console.log("Persisting " + objectClones.length + " clones"); return self.$q.all(objectClones.map(function(clone, index){ + clone.model.persisted = self.now(); return self.persistenceService.createObject(clone.persistenceSpace, clone.id, clone.model) .then(function(){ progress && progress("copying", objectClones.length, ++persisted); }); - })).then(function(qall){ + })).then(function(){ return objectClones }); } @@ -170,8 +168,10 @@ define( return self.persistenceService .updateObject(parentClone.persistenceSpace, parentClone.id, parentClone.model) - .then(function(){return parent.getCapability('composition').add(parentClone.id)}) - .then(function(){return parent.getCapability("persistence").persist()}); + .then(function(){return parent.getCapability("composition").add(parentClone.id)}) + .then(function(){return parent.getCapability("persistence").persist()}) + .then(function(){return parentClone}); + // Ensure the clone of the original domainObject is returned } } @@ -181,8 +181,8 @@ define( * @param domainObject * @param parent * @param progress - * @returns a promise that will be completed when the duplication is - * successful, otherwise an error is thrown. + * @returns a promise that will be completed with the clone of + * domainObject when the duplication is successful. */ CopyService.prototype.perform = function (domainObject, parent, progress) { var $q = this.$q; diff --git a/platform/entanglement/test/services/CopyServiceSpec.js b/platform/entanglement/test/services/CopyServiceSpec.js index 121f35663a..7839b78a7d 100644 --- a/platform/entanglement/test/services/CopyServiceSpec.js +++ b/platform/entanglement/test/services/CopyServiceSpec.js @@ -130,12 +130,13 @@ define( createObjectPromise, copyService, mockPersistenceService, + mockNow, object, newParent, copyResult, copyFinished, persistObjectPromise, - persistenceCapability; + parentPersistenceCapability; beforeEach(function () { creationService = jasmine.createSpyObj( @@ -154,13 +155,18 @@ define( mockPersistenceService.createObject.andReturn(persistObjectPromise); mockPersistenceService.updateObject.andReturn(persistObjectPromise); - persistenceCapability = jasmine.createSpyObj( + parentPersistenceCapability = jasmine.createSpyObj( "persistence", [ "persist", "getSpace" ] ); - persistenceCapability.persist.andReturn(persistObjectPromise); - persistenceCapability.getSpace.andReturn("testSpace"); + parentPersistenceCapability.persist.andReturn(persistObjectPromise); + parentPersistenceCapability.getSpace.andReturn("testSpace"); + + mockNow = jasmine.createSpyObj("mockNow", ["now"]); + mockNow.now.andCallFake(function(){ + return 1234; + }) }); @@ -170,7 +176,8 @@ define( name: 'object', id: 'abc', model: { - name: 'some object' + name: 'some object', + persisted: mockNow.now() } }); newParent = domainObjectFactory({ @@ -180,7 +187,7 @@ define( composition: [] }, capabilities: { - persistence: persistenceCapability + persistence: parentPersistenceCapability } }); mockQ = jasmine.createSpyObj('mockQ', ['when', 'all', 'reject']); @@ -193,26 +200,15 @@ define( return synchronousPromise(result); }); - copyService = new CopyService(mockQ, creationService, policyService, mockPersistenceService); + copyService = new CopyService(mockQ, creationService, policyService, mockPersistenceService, mockNow.now); copyResult = copyService.perform(object, newParent); copyFinished = jasmine.createSpy('copyFinished'); copyResult.then(copyFinished); }); - /** - * Test invalidated. Copy service no longer uses creation service. - */ - /*it("uses creation service", function () { - expect(creationService.createObject) - .toHaveBeenCalledWith(jasmine.any(Object), newParent); - - expect(createObjectPromise.then) - .toHaveBeenCalledWith(jasmine.any(Function)); - });*/ - it("uses persistence service", function () { expect(mockPersistenceService.createObject) - .toHaveBeenCalledWith(persistenceCapability, jasmine.any(String), object.getModel()); + .toHaveBeenCalledWith(parentPersistenceCapability, jasmine.any(String), object.getModel()); expect(persistObjectPromise.then) .toHaveBeenCalledWith(jasmine.any(Function)); @@ -301,62 +297,51 @@ define( id: '456', model: { composition: [] + }, + capabilities: { + composition: compositionCapability, + persistence: parentPersistenceCapability } }); createObjectPromise = synchronousPromise(newObject); creationService.createObject.andReturn(createObjectPromise); - copyService = new CopyService(mockQ, creationService, policyService, mockPersistenceService); - console.log("Before perform"); - //compositionPromise.then.andReturn(synchronousPromise([childObject])); - //mockQ.when.andReturn(compositionPromise); - copyResult = copyService.perform(object, newParent); - console.log("After perform"); - //compositionPromise.then.mostRecentCall.args[0]([childObject]); - copyFinished = jasmine.createSpy('copyFinished'); - copyResult.then(copyFinished); + copyService = new CopyService(mockQ, creationService, policyService, mockPersistenceService, mockNow.now); }); - /** - * Test no longer valid due to creation service not - * being used - */ - /*it("uses creation service", function () { - expect(creationService.createObject) - .toHaveBeenCalledWith(jasmine.any(Object), newParent); + describe("the cloning process", function(){ + beforeEach(function() { + copyResult = copyService.perform(object, newParent); + copyFinished = jasmine.createSpy('copyFinished'); + copyResult.then(copyFinished); + }); + /** + * This is testing that the number of calls to the + * backend is kept to a minimum + */ + it("makes only n+2 persistence calls for n copied" + + " objects", function () { + expect(mockPersistenceService.createObject.calls.length).toEqual(2); + expect(mockPersistenceService.updateObject.calls.length).toEqual(1); + expect(parentPersistenceCapability.persist).toHaveBeenCalled(); + }); - expect(createObjectPromise.then) - .toHaveBeenCalledWith(jasmine.any(Function)); - });*/ + it("copies object and children in a bottom-up" + + " fashion", function () { + expect(mockPersistenceService.createObject.calls[0].args[2].name).toEqual(childObject.model.name) + expect(mockPersistenceService.createObject.calls[1].args[2].name).toEqual(object.model.name) + }); - it("uses persistence service", function () { - //Need a better way of testing duplication here. - expect(mockPersistenceService.createObject) - .toHaveBeenCalled(); - }); - /* - //Test is no longer relevant - it("clears model composition", function () { - var newModel = creationService - .createObject - .mostRecentCall - .args[0]; + it("returns a promise", function () { + expect(copyResult.then).toBeDefined(); + expect(copyFinished).toHaveBeenCalled(); + }); - expect(newModel.composition.length).toBe(0); - expect(newModel.name).toBe('some object'); - });*/ + it("clears modified and sets persisted", function () { + expect(copyFinished.mostRecentCall.args[0].model.modified).toBeUndefined(); + expect(copyFinished.mostRecentCall.args[0].model.persisted).toBe(mockNow.now()); + }); - it("recursively clones it's children", function () { - //TODO: This is a valid test, but needs rewritten - /*expect(creationService.createObject.calls.length).toBe(1); - expect(compositionCapability.invoke).toHaveBeenCalled(); - compositionPromise.then.mostRecentCall.args[0]([childObject]); - expect(creationService.createObject.calls.length).toBe(2);*/ - }); - - it("returns a promise", function () { - expect(copyResult.then).toBeDefined(); - expect(copyFinished).toHaveBeenCalled(); }); }); @@ -378,7 +363,7 @@ define( it("throws an error", function () { var copyService = - new CopyService(mockQ, creationService, policyService, mockPersistenceService); + new CopyService(mockQ, creationService, policyService, mockPersistenceService, mockNow.now); function perform() { copyService.perform(object, newParent); @@ -391,10 +376,6 @@ define( expect(perform).toThrow(); }); }); - /** - * Additional tests: - * - Created and persisted dates - */ }); });