Skip to content
This repository was archived by the owner on Mar 8, 2020. It is now read-only.

Commit dd714e9

Browse files
author
Simon Stone
authored
Properly parse and validate input based on type (resolves #3878) (#3889)
Signed-off-by: Simon Stone <[email protected]>
1 parent be26624 commit dd714e9

File tree

2 files changed

+190
-115
lines changed

2 files changed

+190
-115
lines changed

packages/composer-cucumber-steps/lib/composer.js

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -645,18 +645,38 @@ class Composer {
645645
* @return {*} correctly typed value.
646646
*/
647647
convertValueToType (value, type) {
648-
switch (type) {
649-
case 'Boolean':
650-
return new Boolean(value).valueOf();
651-
case 'DateTime':
652-
return new Date(value);
653-
case 'Double':
654-
return Number.parseFloat(value);
655-
case 'Integer':
656-
case 'Long':
657-
return Number.parseInt(value);
658-
default:
659-
return value;
648+
try {
649+
switch (type) {
650+
case 'Boolean':
651+
if (value !== 'true' && value !== 'false') {
652+
throw new Error();
653+
}
654+
return value === 'true';
655+
case 'DateTime': {
656+
const result = new Date(value);
657+
result.toISOString();
658+
return result;
659+
}
660+
case 'Double': {
661+
const result = Number.parseFloat(value);
662+
if (isNaN(result)) {
663+
throw new Error();
664+
}
665+
return result;
666+
}
667+
case 'Integer':
668+
case 'Long': {
669+
const result = Number.parseInt(value);
670+
if (isNaN(result)) {
671+
throw new Error();
672+
}
673+
return result;
674+
}
675+
default:
676+
return value;
677+
}
678+
} catch (error) {
679+
throw new Error(`Invalid value "${value}" for type "${type}"`);
660680
}
661681
}
662682

packages/composer-cucumber-steps/test/composer.js

Lines changed: 158 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
'use strict';
1616

17+
const Composer = require('../lib/composer');
1718
const Cucumber = require('cucumber');
1819
const path = require('path');
1920

@@ -64,113 +65,167 @@ function runCucumberTest (featureSource) {
6465

6566
describe('Cucumber', () => {
6667

67-
it('should rethrow any errors if errors are not expected', () => {
68-
const featureSource = `
69-
Feature: test
70-
Background:
71-
Given I have deployed the business network archive basic-sample-network.bna
72-
Scenario: test
73-
Given I have added the following asset of type org.acme.sample.SampleAsset
74-
| assetId | owner | value |
75-
| 1 | [email protected] | 10 |
76-
When I add the following asset of type org.acme.sample.SampleAsset
77-
| assetId | owner | value |
78-
| 1 | [email protected] | 10 |
79-
`;
80-
return runCucumberTest(featureSource)
81-
.should.eventually.be.false;
82-
});
83-
84-
it('should handle any errors if errors are expected', async () => {
85-
const featureSource = `
86-
Feature: test
87-
Background:
88-
Given I have deployed the business network archive basic-sample-network.bna
89-
Scenario: test
90-
Given I have added the following asset of type org.acme.sample.SampleAsset
91-
| assetId | owner | value |
92-
| 1 | [email protected] | 10 |
93-
When I add the following asset of type org.acme.sample.SampleAsset
94-
| assetId | owner | value |
95-
| 1 | [email protected] | 10 |
96-
Then I should get an error
97-
`;
98-
99-
let result = await runCucumberTest(featureSource);
100-
return result.should.be.true;
101-
102-
});
68+
describe('error handling', () => {
69+
70+
it('should rethrow any errors if errors are not expected', () => {
71+
const featureSource = `
72+
Feature: test
73+
Background:
74+
Given I have deployed the business network archive basic-sample-network.bna
75+
Scenario: test
76+
Given I have added the following asset of type org.acme.sample.SampleAsset
77+
| assetId | owner | value |
78+
| 1 | [email protected] | 10 |
79+
When I add the following asset of type org.acme.sample.SampleAsset
80+
| assetId | owner | value |
81+
| 1 | [email protected] | 10 |
82+
`;
83+
return runCucumberTest(featureSource)
84+
.should.eventually.be.false;
85+
});
86+
87+
it('should handle any errors if errors are expected', async () => {
88+
const featureSource = `
89+
Feature: test
90+
Background:
91+
Given I have deployed the business network archive basic-sample-network.bna
92+
Scenario: test
93+
Given I have added the following asset of type org.acme.sample.SampleAsset
94+
| assetId | owner | value |
95+
| 1 | [email protected] | 10 |
96+
When I add the following asset of type org.acme.sample.SampleAsset
97+
| assetId | owner | value |
98+
| 1 | [email protected] | 10 |
99+
Then I should get an error
100+
`;
101+
102+
let result = await runCucumberTest(featureSource);
103+
return result.should.be.true;
104+
105+
});
106+
107+
it('should throw if multiple errors are caught when errors are expected', () => {
108+
const featureSource = `
109+
Feature: test
110+
Background:
111+
Given I have deployed the business network archive basic-sample-network.bna
112+
Scenario: test
113+
Given I have added the following asset of type org.acme.sample.SampleAsset
114+
| assetId | owner | value |
115+
| 1 | [email protected] | 10 |
116+
When I add the following asset of type org.acme.sample.SampleAsset
117+
| assetId | owner | value |
118+
| 1 | [email protected] | 10 |
119+
And I add the following asset of type org.acme.sample.SampleAsset
120+
| assetId | owner | value |
121+
| 1 | [email protected] | 10 |
122+
Then I should get an error
123+
`;
124+
return runCucumberTest(featureSource)
125+
.should.eventually.be.false;
126+
});
127+
128+
it('should throw if errors are expected but none are thrown', () => {
129+
const featureSource = `
130+
Feature: test
131+
Background:
132+
Given I have deployed the business network archive basic-sample-network.bna
133+
Scenario: test
134+
Given I have added the following asset of type org.acme.sample.SampleAsset
135+
| assetId | owner | value |
136+
| 1 | [email protected] | 10 |
137+
Then I should get an error
138+
`;
139+
return runCucumberTest(featureSource)
140+
.should.eventually.be.false;
141+
});
142+
143+
it('should handle any errors that are expected and match the regular expression', () => {
144+
const featureSource = `
145+
Feature: test
146+
Background:
147+
Given I have deployed the business network archive basic-sample-network.bna
148+
Scenario: test
149+
Given I have added the following asset of type org.acme.sample.SampleAsset
150+
| assetId | owner | value |
151+
| 1 | [email protected] | 10 |
152+
When I add the following asset of type org.acme.sample.SampleAsset
153+
| assetId | owner | value |
154+
| 1 | [email protected] | 10 |
155+
Then I should get an error matching /.*/
156+
`;
157+
return runCucumberTest(featureSource)
158+
.should.eventually.be.true;
159+
});
160+
161+
it('should throw if errors are expected but they do not match the regular expression', () => {
162+
const featureSource = `
163+
Feature: test
164+
Background:
165+
Given I have deployed the business network archive basic-sample-network.bna
166+
Scenario: test
167+
Given I have added the following asset of type org.acme.sample.SampleAsset
168+
| assetId | owner | value |
169+
| 1 | [email protected] | 10 |
170+
When I add the following asset of type org.acme.sample.SampleAsset
171+
| assetId | owner | value |
172+
| 1 | [email protected] | 10 |
173+
Then I should get an error matching /blah blah blah/
174+
`;
175+
return runCucumberTest(featureSource)
176+
.should.eventually.be.false;
177+
});
103178

104-
it('should throw if multiple errors are caught when errors are expected', () => {
105-
const featureSource = `
106-
Feature: test
107-
Background:
108-
Given I have deployed the business network archive basic-sample-network.bna
109-
Scenario: test
110-
Given I have added the following asset of type org.acme.sample.SampleAsset
111-
| assetId | owner | value |
112-
| 1 | [email protected] | 10 |
113-
When I add the following asset of type org.acme.sample.SampleAsset
114-
| assetId | owner | value |
115-
| 1 | [email protected] | 10 |
116-
And I add the following asset of type org.acme.sample.SampleAsset
117-
| assetId | owner | value |
118-
| 1 | [email protected] | 10 |
119-
Then I should get an error
120-
`;
121-
return runCucumberTest(featureSource)
122-
.should.eventually.be.false;
123179
});
124180

125-
it('should throw if errors are expected but none are thrown', () => {
126-
const featureSource = `
127-
Feature: test
128-
Background:
129-
Given I have deployed the business network archive basic-sample-network.bna
130-
Scenario: test
131-
Given I have added the following asset of type org.acme.sample.SampleAsset
132-
| assetId | owner | value |
133-
| 1 | [email protected] | 10 |
134-
Then I should get an error
135-
`;
136-
return runCucumberTest(featureSource)
137-
.should.eventually.be.false;
138-
});
139-
140-
it('should handle any errors that are expected and match the regular expression', () => {
141-
const featureSource = `
142-
Feature: test
143-
Background:
144-
Given I have deployed the business network archive basic-sample-network.bna
145-
Scenario: test
146-
Given I have added the following asset of type org.acme.sample.SampleAsset
147-
| assetId | owner | value |
148-
| 1 | [email protected] | 10 |
149-
When I add the following asset of type org.acme.sample.SampleAsset
150-
| assetId | owner | value |
151-
| 1 | [email protected] | 10 |
152-
Then I should get an error matching /.*/
153-
`;
154-
return runCucumberTest(featureSource)
155-
.should.eventually.be.true;
156-
});
181+
describe('#convertValueToType', () => {
182+
183+
it('should handle boolean values', () => {
184+
const composer = new Composer();
185+
composer.convertValueToType('false', 'Boolean').should.be.false;
186+
composer.convertValueToType('true', 'Boolean').should.be.true;
187+
(() => {
188+
composer.convertValueToType('blah', 'Boolean');
189+
}).should.throw(/Invalid value "blah" for type "Boolean"/);
190+
});
191+
192+
it('should handle date values', () => {
193+
const composer = new Composer();
194+
composer.convertValueToType('2018-04-20T15:06:37.919Z', 'DateTime').toISOString().should.equal('2018-04-20T15:06:37.919Z');
195+
(() => {
196+
composer.convertValueToType('blah', 'DateTime');
197+
}).should.throw(/Invalid value "blah" for type "DateTime"/);
198+
});
199+
200+
it('should handle double values', () => {
201+
const composer = new Composer();
202+
composer.convertValueToType('3.142', 'Double').should.equal(3.142);
203+
(() => {
204+
composer.convertValueToType('blah', 'Double');
205+
}).should.throw(/Invalid value "blah" for type "Double"/);
206+
});
207+
208+
it('should handle integer values', () => {
209+
const composer = new Composer();
210+
composer.convertValueToType('1234', 'Integer').should.equal(1234);
211+
(() => {
212+
composer.convertValueToType('blah', 'Integer');
213+
}).should.throw(/Invalid value "blah" for type "Integer"/);
214+
});
215+
216+
it('should handle long values', () => {
217+
const composer = new Composer();
218+
composer.convertValueToType('12345678', 'Long').should.equal(12345678);
219+
(() => {
220+
composer.convertValueToType('blah', 'Long');
221+
}).should.throw(/Invalid value "blah" for type "Long"/);
222+
});
223+
224+
it('should handle string values', () => {
225+
const composer = new Composer();
226+
composer.convertValueToType('12345678', 'String').should.equal('12345678');
227+
});
157228

158-
it('should throw if errors are expected but they do not match the regular expression', () => {
159-
const featureSource = `
160-
Feature: test
161-
Background:
162-
Given I have deployed the business network archive basic-sample-network.bna
163-
Scenario: test
164-
Given I have added the following asset of type org.acme.sample.SampleAsset
165-
| assetId | owner | value |
166-
| 1 | [email protected] | 10 |
167-
When I add the following asset of type org.acme.sample.SampleAsset
168-
| assetId | owner | value |
169-
| 1 | [email protected] | 10 |
170-
Then I should get an error matching /blah blah blah/
171-
`;
172-
return runCucumberTest(featureSource)
173-
.should.eventually.be.false;
174229
});
175230

176231
});

0 commit comments

Comments
 (0)