From d4d1ddf6ae6e12c86792ff9aa1bdb89f4b9edcfb Mon Sep 17 00:00:00 2001 From: Sam Smith Date: Wed, 1 Nov 2017 19:03:19 +0000 Subject: [PATCH] Allow generation of Identifier field in Playground if no regex is required (#2521) As discussed with Simon, removing the code that adds the identifier field name to the auto generated data for relationships in Asset Signed-off-by: Sam Smith --- .../lib/serializer/instancegenerator.js | 7 ++- .../test/serializer/instancegenerator.js | 8 ++-- .../test/resource/resource.component.spec.ts | 45 +++++++++++++++++-- .../app/test/resource/resource.component.ts | 21 +++++++-- 4 files changed, 67 insertions(+), 14 deletions(-) diff --git a/packages/composer-common/lib/serializer/instancegenerator.js b/packages/composer-common/lib/serializer/instancegenerator.js index da05e67ae9..996552f6af 100644 --- a/packages/composer-common/lib/serializer/instancegenerator.js +++ b/packages/composer-common/lib/serializer/instancegenerator.js @@ -217,10 +217,9 @@ class InstanceGenerator { * @return {String} an ID. */ generateRandomId(classDeclaration) { - const prefix = classDeclaration.getIdentifierFieldName(); - let index = Math.round(Math.random() * 9999).toString(); - index = leftPad(index, 4, '0'); - return `${prefix}:${index}`; + let id = Math.round(Math.random() * 9999).toString(); + id = leftPad(id, 4, '0'); + return id; } } diff --git a/packages/composer-common/test/serializer/instancegenerator.js b/packages/composer-common/test/serializer/instancegenerator.js index ad50f2914a..759a141e69 100644 --- a/packages/composer-common/test/serializer/instancegenerator.js +++ b/packages/composer-common/test/serializer/instancegenerator.js @@ -270,7 +270,7 @@ describe('InstanceGenerator', () => { o String assetId --> MyAsset theValue }`); - resource.theValue.getIdentifier().should.match(/^assetId:\d{4}$/); + resource.theValue.getIdentifier().should.match(/^\d{4}$/); }); it('should generate a default value for a relationship array property', () => { @@ -280,7 +280,7 @@ describe('InstanceGenerator', () => { --> MyAsset[] theValues }`); resource.theValues.should.be.a('Array').and.have.lengthOf(1); - resource.theValues[0].getIdentifier().should.match(/^assetId:\d{4}$/); + resource.theValues[0].getIdentifier().should.match(/^\d{4}$/); }); it('should generate a default value for a resource property', () => { @@ -293,7 +293,7 @@ describe('InstanceGenerator', () => { o String assetId o MyInnerAsset theValue }`); - resource.theValue.getIdentifier().should.match(/^innerAssetId:\d{4}$/); + resource.theValue.getIdentifier().should.match(/^\d{4}$/); resource.theValue.theValue.should.be.a('string'); }); @@ -308,7 +308,7 @@ describe('InstanceGenerator', () => { o MyInnerAsset[] theValues }`); resource.theValues.should.be.a('Array').and.have.lengthOf(1); - resource.theValues[0].getIdentifier().should.match(/^innerAssetId:\d{4}$/); + resource.theValues[0].getIdentifier().should.match(/^\d{4}$/); resource.theValues[0].theValue.should.be.a('string'); }); diff --git a/packages/composer-playground/src/app/test/resource/resource.component.spec.ts b/packages/composer-playground/src/app/test/resource/resource.component.spec.ts index 95eff644f5..b41bedfac7 100644 --- a/packages/composer-playground/src/app/test/resource/resource.component.spec.ts +++ b/packages/composer-playground/src/app/test/resource/resource.component.spec.ts @@ -22,6 +22,7 @@ import { ClassDeclaration, Factory, ModelFile + } from 'composer-common'; import { BusinessNetworkConnection, AssetRegistry } from 'composer-client'; @@ -174,7 +175,13 @@ describe('ResourceComponent', () => { describe('#generateResource', () => { let mockClassDeclaration; let mockModelFile; + let mockField; + beforeEach(() => { + mockField = { + getValidator: sinon.stub ().returns(null) + }; + component['updateExistingJSON'] = sandbox.stub(); mockModelFile = sinon.createStubInstance(ModelFile); mockModelFile.getName.returns('model.cto'); @@ -182,11 +189,12 @@ describe('ResourceComponent', () => { mockClassDeclaration.getModelFile.returns(mockModelFile); mockClassDeclaration.getName.returns('class.declaration'); mockClassDeclaration.getIdentifierFieldName.returns('resourceId'); - + mockClassDeclaration.getOwnProperty.returns(mockField); }); - it('should generate a valid resource with undefined', () => { - + it('should generate a valid resource with an empty ID', () => { + mockField.getValidator.returns('/regex/'); + mockClassDeclaration.getOwnProperty.returns(mockField); mockSerializer.toJSON.returns({$class: 'com.org'}); mockSerializer.fromJSON.returns(mockResource); mockResource.validate = sandbox.stub(); @@ -289,6 +297,37 @@ describe('ResourceComponent', () => { }); + it('should generate a valid resource with a random 4-digit ID', () => { + mockSerializer.toJSON.returns({$class: 'com.org'}); + mockSerializer.fromJSON.returns(mockResource); + mockResource.validate = sandbox.stub(); + component['resourceDeclaration'] = mockClassDeclaration; + + // should start clean + should.not.exist(component['definitionError']); + + // run method + component['generateResource'](); + + // should not result in definitionError + should.not.exist(component['definitionError']); + + // resourceDefinition should be set as per serializer.toJSON output + component['resourceDefinition'].should.equal('{\n "$class": "com.org"\n}'); + + // We use the following internal calls + mockFactory.newResource.should.be.calledWith(undefined, + 'class.declaration', + sinon.match(/[0-9]{4}/), + { + generate: 'empty', + includeOptionalFields: false, + disableValidation: true, + allowEmptyId: true + }); + component.onDefinitionChanged.should.be.calledOn; + }); + it('should set definitionError on serializer fail', () => { component['resourceDeclaration'] = mockClassDeclaration; diff --git a/packages/composer-playground/src/app/test/resource/resource.component.ts b/packages/composer-playground/src/app/test/resource/resource.component.ts index c4cfc11409..6753ad30aa 100644 --- a/packages/composer-playground/src/app/test/resource/resource.component.ts +++ b/packages/composer-playground/src/app/test/resource/resource.component.ts @@ -7,7 +7,8 @@ import { ClassDeclaration, AssetDeclaration, ParticipantDeclaration, - TransactionDeclaration + TransactionDeclaration, + Field } from 'composer-common'; import leftPad = require('left-pad'); @@ -103,15 +104,29 @@ export class ResourceComponent implements OnInit { return (this.resource ? true : false); } + /** + * Returns true if the Identifying field of the Class that is being created has + * a validator associated with it ie. its ID field must conform to a regex + */ + private idFieldHasRegex() { + // a non-null validator on an identifying field returns true + let idf: Field = this.resourceDeclaration.getOwnProperty(this.resourceDeclaration.getIdentifierFieldName()); + return idf.getValidator() ? true : false; + } + /** * Generate the json description of a resource */ private generateResource(withSampleData ?: boolean): void { let businessNetworkDefinition = this.clientService.getBusinessNetwork(); let factory = businessNetworkDefinition.getFactory(); - let idx = Math.round(Math.random() * 9999).toString(); - idx = leftPad(idx, 4, '0'); + let id = ''; + if (!this.idFieldHasRegex()) { + let idx = Math.round(Math.random() * 9999).toString(); + id = leftPad(idx, 4, '0'); + } + try { const generateParameters = { generate: withSampleData ? 'sample' : 'empty',