mss-sdk
Version:
MSS SDK for JavaScript
457 lines (352 loc) • 13.5 kB
text/coffeescript
helpers = require('./helpers')
AWS = helpers.AWS
Buffer = AWS.util.Buffer
describe 'AWS.ParamValidator', ->
[members, input] = [{}, {}]
validate = (params) ->
r = input
if r && !r.xml && !r.payload
r = AWS.Model.Shape.create(input, {api: {}})
new AWS.ParamValidator().validate(r, params)
expectValid = (params) ->
expect(validate(params)).to.equal(true)
expectError = (message, params) ->
if params == undefined
[message, params] = [undefined, message]
expect(-> validate(params)).to.throw(message)
# empty input (nil or {}) means no arguments are accepted
describe 'empty input', ->
beforeEach ->
input = type: 'structure'
it 'accepts an empty hash when the input are an empty hash', ->
expectValid {}
it 'does not accept params in the given hash', ->
expectError foo: 'bar'
# Param (hash) keys can be given as strings or symbols, but
# are case sensitive.
describe 'param keys', ->
beforeEach ->
input =
members:
foo: {}, bar: type: 'string'
it 'accepts string keys', ->
expectValid foo: 'foo'
expectValid bar: 'bar'
it 'rejects keys that do not match case', ->
expectError Bar: 'bar'
expectError Foo: 'foo'
# Params not described in the input are not accepted.
describe 'unexpected params', ->
beforeEach ->
input =
members:
string1: {}
string2: {}
hash:
type: 'structure'
members:
good: {}
it 'throws an ArgumentError for un-described params', ->
expectError string3: 'xyz'
it 'rejects nested params that are not described in the input', ->
expectValid hash: good: 'abc'
expectError hash: bad: 'abc'
# Params that are hashes (structures) can specify that some or all
# of their nested params are required. When the parent param is
# present, the required nested params must also be present or an
# ArgumentError is raised. If the parent param is optional and not
# provided, then missing nested required params will not raise an error.
describe 'required params', ->
beforeEach ->
input =
required: ['req']
members:
req: type: 'string'
opt:
type: 'structure'
required: ['req']
members: req: type: 'string'
it 'throws an error if a top-level required param is omitted', ->
expectError {}
it 'throws an error if a top-level required param is null', ->
expectError req: null
it 'optional params can be omitted, even if they have required params', ->
expectValid req: 'abc'
it 'requires nested required params when the parent is present', ->
expectError req: 'abc', opt: {}
it 'accepts nested required params', ->
expectValid req: 'abc', opt: req: 'xyz'
it 'accepts empty strings in required params', ->
expectValid req: ''
it 'accepts 0 in required params', ->
input.members.req.type = 'integer'
expectValid req: 0
it 'accepts false in required params', ->
input.members.req.type = 'boolean'
expectValid req: false
# The root params is always a structure (hash) by default, but
# you can also nest structures.
describe 'structure', ->
beforeEach ->
input =
members:
hash1:
type: 'structure'
members:
param1: {}
param2: {}
hash2:
type: 'structure'
required: ['param4']
members:
param3: type: 'boolean'
param4: type: 'integer'
it 'accepts hashes', ->
expectValid hash1: {}
it 'accepts hashes with params', ->
expectValid hash1: param1: 'a', param2: 'b'
it 'throws an error for non hashes', ->
expectError hash1: 'oops'
it 'throws an error for unknown hash members', ->
expectError hash1: param3: 'c'
it 'allows nesting structures', ->
expectValid hash1: hash2: param3: true, param4: 123
it 'rejects unknown members', ->
expectError hash1: oops: 'abc'
it 'does not check inherited properties on parameters', ->
cls = -> this
cls.prototype.otherKey = 'value'
obj = new cls
obj.hash1 = {}
expectValid obj
describe 'list', ->
beforeEach ->
members = {}
input =
members:
array: type: 'list', member: members
it 'accepts an array for list params', ->
expectValid array: []
it 'throws an error if list params are not arrays', ->
expectError array: {}
it 'supports nested structures', ->
members.type = 'structure'
members.members = name: {}
expectValid array: [{name: 'abc'}, {name: 'mno'}, {name: 'xyz'}]
expectError array: [{badKey: 'abc'}]
describe 'map', ->
beforeEach ->
members = {}
input =
members:
hash: type: 'map', value: members
it 'accepts maps', ->
expectValid hash: {}
it 'accepts null', ->
expectValid hash: null
it 'rejects non-maps', ->
expectError hash: 'oops'
it 'accepts user-supplied maps keys', ->
expectValid hash: a: '1', b: '2', c: '3'
it 'supports nested params', ->
members.type = 'structure'
members.members =
param1: type: 'list', member: type: 'string'
param2: type: 'integer'
param3: type: 'structure', members: param4: {}
expectValid hash:
foo: param1: ['a', 'b', 'c']
bar: param2: 123
yuck: param3: param4: 'xyz'
expectError hash: foo: param4: 'abc'
describe 'boolean', ->
beforeEach ->
input = members: param: type: 'boolean'
it 'accepts true', ->
expectValid param: true
it 'accpets false', ->
expectValid param: false
it 'accepts null', ->
expectValid param: null
it 'rejects other values', ->
expectError param: 'true'
describe 'timestamp', ->
beforeEach ->
input = members: param: type: 'timestamp'
it 'accepts Date objects', ->
expectValid param: new Date()
it 'accepts strings formatted like datetimes', ->
expectValid param: '2012-01-02T10:11:12Z'
expectValid param: '2012-01-02T10:11:12.0001Z'
it 'accepts UNIX timestamps as number values', ->
expectValid param: 12345
it 'accepts null', ->
expectValid param: null
it 'rejects other param values', ->
expectError param: 'abc'
describe 'string', ->
beforeEach ->
input = members: param: type: 'string'
it 'accepts strings', ->
expectValid param: 'abc'
it 'accepts empty string', ->
expectValid param: ''
it 'accepts null', ->
expectValid param: null
it 'rejects other objects', ->
expectError param: 123
expectError param: {}
expectError param: []
describe 'float', ->
beforeEach ->
input = members: param: type: 'float'
it 'accepts floats', ->
expectValid param: 1.23
it 'accepts integers', ->
expectValid param: 123
it 'accepts floats formatted as strings', ->
expectValid param: '1.23'
it 'accepts null', ->
expectValid param: null
it 'rejects other objects', ->
expectError param: 'NOTFLOAT'
describe 'integer', ->
beforeEach ->
input = members: param: type: 'integer'
it 'accepts integers', ->
expectValid param: 123
it 'accepts integers formatted as strings', ->
expectValid param: '123'
it 'accepts null', ->
expectValid param: null
it 'rejects other objects', ->
expectError param: 'NOTINT'
describe 'base64', ->
beforeEach ->
input = members: param: type: 'base64'
it 'accepts strings', ->
expectValid param: 'abc'
it 'accepts Buffers', ->
expectValid param: new Buffer(100)
it 'accepts typed arrays', ->
expectValid param: new Uint8Array(1, 2, 3)
expectValid param: new Uint32Array(1, 2, 3)
it 'accepts null', ->
expectValid param: null
it 'rejects other objects', ->
expectError param: {}
if AWS.util.isBrowser()
it 'accepts Blob objects', ->
try blob = new Blob
if blob then expectValid param: blob
it 'accepts ArrayBuffer objects', ->
expectValid param: new ArrayBuffer
it 'accepts DataView objects', ->
expectValid param: new DataView(new ArrayBuffer)
describe 'binary', ->
beforeEach ->
input = members: param: type: 'binary'
it 'accepts strings', ->
expectValid param: 'abc'
it 'accepts Buffers', ->
expectValid param: new Buffer(100)
it 'accepts Streams', ->
Stream = require('stream').Stream
expectValid param: new Stream()
it 'accepts null', ->
expectValid param: null
it 'rejects other objects', ->
expectError param: {}
describe 'payloads', ->
it 'validates from payload key if input include an xml element', ->
input =
type: 'structure'
required: ['body']
payload: 'body'
members:
notbody: type: 'string'
body:
type: 'structure'
members: enabled: type: 'boolean'
expectValid body: { enabled: true }, notbody: 'true'
describe 'error messages', ->
beforeEach ->
input =
members:
config:
type: 'structure'
members:
settings:
type: 'structure'
members:
enabled: type: 'boolean'
it 'throws helpful messages for unknown params', ->
msg = 'Unexpected key \'fake\' found in params'
expectError msg, fake: 'value'
it 'throws helpful messages for nested unknown params', ->
msg = 'Unexpected key \'fake\' found in params.config.settings'
expectError msg, config: settings: fake: 'value'
it 'throws helpful messages for missing required params', ->
msg = 'Missing required key \'needed\' in params.config.settings'
input.members.config.members.settings.required = ['needed']
expectError msg, config: settings: {}
it 'throws helpul messages for invalid structures', ->
msg = 'Expected params.config.settings to be a structure'
expectError msg, config: settings: 'abc'
it 'throws helpul messages for invalid lists', ->
msg = 'Expected params.config.settings.tags to be an Array'
input.members.config.members.settings.members.tags = type: 'list', member: {}
expectError msg, config: settings: tags: 123
it 'throws helpful messages for invalid list members', ->
msg = 'Expected params.config.items[1].value to be a number'
input.members.config.members.items =
type: 'list',
member:
type: 'structure',
members:
value: type: 'integer'
expectError msg, config: items:
[{value: 123}, {value: 'abc'}, {value: 321}]
it 'throws helpful messages for invalid maps', ->
msg = 'Expected params.config.settings.tags to be a map'
input.members.config.members.settings.members.tags =
type: 'map',
key: {}
value: {}
expectError msg, config: settings: tags: '123'
it 'throws helpful messages for invalid map members', ->
msg = 'Expected params.config.counts[\'red\'] to be a number'
input.members.config.members.counts =
type: 'map',
value: type: 'integer'
expectError msg, config: counts: red: true
it 'throws helpful messages for invalid strings', ->
msg = "Expected params.config.settings.name to be a string"
input.members.config.members.settings.members.name = type: 'string'
expectError msg, config: settings: name: 123
it 'throws helpful messages for invalid integers', ->
msg = "Expected params.config.settings.count to be a number"
input.members.config.members.settings.members.count = type: 'integer'
expectError msg, config: settings: count: 'invalid-integer'
it 'throws helpful messages for invalid timestamps', ->
msg = "Expected params.config.settings.when to be a " +
"Date object, ISO-8601 string, or a UNIX timestamp"
input.members.config.members.settings.members.when = type: 'timestamp'
expectError msg, config: settings: when: 'invalid-date'
it 'throws helpful messages for invalid booleans', ->
msg = "Expected params.config.settings.enabled to be a boolean"
expectError msg, config: settings: enabled: 'invalid-boolean'
it 'throws helpful messages for invalid floats', ->
msg = "Expected params.config.settings.value to be a number"
input.members.config.members.settings.members.value = type: 'float'
expectError msg, config: settings: value: 'invalid-float'
it 'throws helpful messages for invalid base64 params', ->
msg = "Expected params.config.settings.data to be a " +
"string, Buffer, Stream, Blob, or typed array object"
input.members.config.members.settings.members.data = type: 'base64'
expectError msg, config: settings: data: 123
it 'throws helpful messages for invalid binary params', ->
msg = "Expected params.config.settings.data to be a " +
"string, Buffer, Stream, Blob, or typed array object"
input.members.config.members.settings.members.data = type: 'binary'
expectError msg, config: settings: data: 123