Skip to content

Commit

Permalink
Sync latest version of protocol tests (#1407)
Browse files Browse the repository at this point in the history
* Sync latest version of protocol tests

* Add a changelog note

* Ensure param validator does not reject valid JSONValue inputs
  • Loading branch information
jeskew committed Mar 17, 2017
1 parent e695c27 commit e516ed8
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 12 deletions.
5 changes: 5 additions & 0 deletions .changes/next-release/feature-protocol-2bb8b66f.json
@@ -0,0 +1,5 @@
{
"type": "feature",
"category": "protocol",
"description": "The SDK can now support JSON-value string shapes in headers"
}
23 changes: 13 additions & 10 deletions lib/model/shape.js
Expand Up @@ -30,9 +30,10 @@ function Shape(shape, options, memberName) {
property(this, 'isStreaming', shape.streaming || this.isStreaming || false);
property(this, 'isComposite', shape.isComposite || false);
property(this, 'isShape', true, false);
property(this, 'isQueryName', shape.queryName ? true : false, false);
property(this, 'isLocationName', shape.locationName ? true : false, false);
property(this, 'isQueryName', Boolean(shape.queryName), false);
property(this, 'isLocationName', Boolean(shape.locationName), false);
property(this, 'isIdempotent', shape.idempotencyToken === true);
property(this, 'isJsonValue', shape.jsonvalue === true);

if (options.documentation) {
property(this, 'documentation', shape.documentation);
Expand Down Expand Up @@ -282,14 +283,16 @@ function TimestampShape(shape) {
function StringShape() {
Shape.apply(this, arguments);

if (this.api) {
switch (this.api.protocol) {
case 'rest-xml':
case 'query':
case 'ec2':
this.toType = function(value) { return value || ''; };
}
}
var nullLessProtocols = ['rest-xml', 'query', 'ec2'];
this.toType = function(value) {
value = this.api && nullLessProtocols.indexOf(this.api.protocol) > -1 ?
value || '' : value;
return this.isJsonValue ? JSON.parse(value) : value;
};

this.toWireFormat = function(value) {
return this.isJsonValue ? JSON.stringify(value) : value;
};
}

function FloatShape() {
Expand Down
6 changes: 5 additions & 1 deletion lib/param_validator.js
Expand Up @@ -147,7 +147,11 @@ AWS.ParamValidator = AWS.util.inherit({
},

validateString: function validateString(shape, value, context) {
if (this.validateType(value, context, ['string'])) {
var validTypes = ['string'];
if (shape.isJsonValue) {
validTypes = validTypes.concat(['number', 'object', 'boolean']);
}
if (value !== null && this.validateType(value, context, validTypes)) {
this.validateEnum(shape, value, context);
this.validateRange(shape, value.length, context, 'string length');
this.validatePattern(shape, value, context);
Expand Down
8 changes: 7 additions & 1 deletion lib/protocol/rest.js
Expand Up @@ -78,6 +78,9 @@ function populateHeaders(req) {
});
} else if (member.location === 'header') {
value = member.toWireFormat(value).toString();
if (member.isJsonValue) {
value = util.base64.encode(value);
}
req.httpRequest.headers[member.name] = value;
}
});
Expand Down Expand Up @@ -119,7 +122,10 @@ function extractData(resp) {
});
} else if (member.location === 'header') {
if (headers[header] !== undefined) {
data[name] = headers[header];
var value = member.isJsonValue ?
util.base64.decode(headers[header]) :
headers[header];
data[name] = member.toType(value);
}
} else if (member.location === 'statusCode') {
data[name] = parseInt(r.statusCode, 10);
Expand Down
62 changes: 62 additions & 0 deletions test/fixtures/protocol/input/rest-json.json
Expand Up @@ -1300,5 +1300,67 @@
}
}
]
},
{
"description": "JSON value trait",
"metadata": {
"protocol": "rest-json",
"apiVersion": "2014-01-01"
},
"shapes": {
"InputShape": {
"type": "structure",
"members": {
"Attr": {
"shape": "StringType",
"jsonvalue": true,
"location": "header",
"locationName": "X-Amz-Foo"
}
}
},
"StringType": {
"type": "string"
}
},
"cases": [
{
"given": {
"input": {
"shape": "InputShape"
},
"http": {
"method": "POST"
},
"name": "OperationName"
},
"params": {
"Attr": {"Foo":"Bar"}
},
"serialized": {
"uri": "/",
"headers": {"X-Amz-Foo": "eyJGb28iOiJCYXIifQ=="},
"body": ""
}
},
{
"given": {
"input": {
"shape": "InputShape"
},
"http": {
"method": "POST"
},
"name": "OperationName"
},
"params": {
},
"serialized": {
"uri": "/",
"headers": {},
"body": ""
}
}
]
}
]
40 changes: 40 additions & 0 deletions test/fixtures/protocol/output/rest-json.json
Expand Up @@ -624,5 +624,45 @@
}
}
]
},
{
"description": "JSON value trait",
"metadata": {
"protocol": "rest-json"
},
"shapes": {
"OutputShape": {
"type": "structure",
"members": {
"Attr": {
"shape": "StringType",
"jsonvalue": true,
"location": "header",
"locationName": "X-Amz-Foo"
}
}
},
"StringType": {
"type": "string"
}
},
"cases": [
{
"given": {
"output": {
"shape": "OutputShape"
},
"name": "OperationName"
},
"result": {
"Attr": {"Foo":"Bar"}
},
"response": {
"status_code": 200,
"headers": {"X-Amz-Foo": "eyJGb28iOiJCYXIifQ=="},
"body": ""
}
}
]
}
]
9 changes: 9 additions & 0 deletions test/param_validator.spec.coffee
Expand Up @@ -255,6 +255,15 @@ describe 'AWS.ParamValidator', ->
expectError param: {}
expectError param: []

it 'accepts anything JSON-encodable if the member is a JSONValue', ->
input = members: param: {type: 'string', jsonvalue: true}
expectValid param: '{"foo":"bar"}'
expectValid param: 123
expectValid param: {}
expectValid param: []
expectValid param: true
expectValid param: null

describe 'float', ->
beforeEach ->
input = members: param: type: 'float'
Expand Down

0 comments on commit e516ed8

Please sign in to comment.