helpers = require('../helpers')
AWS = helpers.AWS
matchXML = helpers.matchXML
describe 'AWS.XML.Builder', ->
xmlns = 'http://mockservice.com/xmlns'
api = null
beforeEach ->
api = new AWS.Model.Api metadata: xmlNamespace: xmlns
toXML = (rules, params) ->
rules.type = 'structure'
shape = AWS.Model.Shape.create(rules, api: api)
builder = new AWS.XML.Builder()
builder.toXML(params, shape, 'Data')
describe 'toXML', ->
it 'wraps simple structures with location of body', ->
rules = members: { Name:{}, State:{} }
params = { Name:'abc', State: 'Enabled' }
xml = """
abc
Enabled
"""
matchXML(toXML(rules, params), xml)
it 'ignores null input', ->
rules = members: { Name:{}, State:{} }
params = { Name:null, State:undefined }
xml = ''
matchXML(toXML(rules, params), xml)
it 'ignores nested null input', ->
rules = members: {Struct:{type: 'structure', members: {State:{}}}}
params = { Struct: { State: null } }
xml = """
"""
matchXML(toXML(rules, params), xml)
it 'orders xml members by the order they appear in the rules', ->
rules = xmlOrder: ['Count', 'State'], members: {Count:{type:'integer'},State:{}}
params = { State: 'Disabled', Count: 123 }
xml = """
123
Disabled
"""
matchXML(toXML(rules, params), xml)
it 'can serializes structures into XML', ->
rules = members:
Name: {}
Details:
type: 'structure'
members:
Abc: {}
Xyz: {}
params =
Details:
Xyz: 'xyz'
Abc: 'abc'
Name: 'john'
xml = """
john
abc
xyz
"""
matchXML(toXML(rules, params), xml)
it 'serializes empty structures as empty element', ->
rules = {members:{Config:{type:'structure',members:{Foo:{},Bar:{}}}}}
params = { Config: {} }
xml = """
"""
matchXML(toXML(rules, params), xml)
it 'does not serialize missing members', ->
rules = {members:{Config:{type:'structure',members:{Foo:{},Bar:{}}}}}
params = { Config: { Foo: 'abc' } }
xml = """
abc
"""
matchXML(toXML(rules, params), xml)
describe 'lists', ->
it 'serializes lists (default member names)', ->
rules = {members:{Aliases:{type:'list',member:{}}}}
params = {Aliases:['abc','mno','xyz']}
xml = """
abc
mno
xyz
"""
matchXML(toXML(rules, params), xml)
it 'serializes lists (custom member names)', ->
rules = {members:{Aliases:{type:'list',member:{locationName:'Alias'}}}}
params = {Aliases:['abc','mno','xyz']}
xml = """
abc
mno
xyz
"""
matchXML(toXML(rules, params), xml)
it 'includes lists elements even if they have no members', ->
rules = {members:{Aliases:{type:'list',member:{locationName:'Alias'}}}}
params = {Aliases:[]}
xml = """
"""
matchXML(toXML(rules, params), xml)
it 'serializes lists of structures', ->
rules = members:
Points:
type: 'list'
member:
type: 'structure'
locationName: 'Point'
members:
X: {type:'float'}
Y: {type:'float'}
params = {Points:[{X:1.2,Y:2.1},{X:3.4,Y:4.3}]}
xml = """
1.2
2.1
3.4
4.3
"""
matchXML(toXML(rules, params), xml)
describe 'flattened lists', ->
it 'serializes lists without a base wrapper', ->
rules = {members:{Aliases:{type:'list',flattened:true,member:{}}}}
params = {Aliases:['abc','mno','xyz']}
xml = """
abc
mno
xyz
"""
matchXML(toXML(rules, params), xml)
it 'serializes lists (custom member names)', ->
rules = members: {Aliases:{type:'list',flattened:true,member:{locationName:'Alias'}}}
params = {Aliases:['abc','mno','xyz']}
xml = """
abc
mno
xyz
"""
matchXML(toXML(rules, params), xml)
it 'omits lists elements when no members are given', ->
rules = {members:{Aliases:{type:'list',flattened:true,member:{locationName:'Alias'}}}}
params = {Aliases:[]}
xml = ''
matchXML(toXML(rules, params), xml)
it 'serializes lists of structures', ->
rules = members:
Points:
type: 'list'
flattened: true
name: 'Point'
member:
type: 'structure'
locationName: 'Point'
members:
X: {type:'float'}
Y: {type:'float'}
params = {Points:[{X:1.2,Y:2.1},{X:3.4,Y:4.3}]}
xml = """
1.2
2.1
3.4
4.3
"""
matchXML(toXML(rules, params), xml)
describe 'maps', ->
rules =
type: 'structure'
members:
Items:
type: 'map'
key: type: 'string'
value: type: 'string'
it 'translates maps', ->
params = { Items: { A: 'a', B: 'b' } }
xml = """
A
a
B
b
"""
matchXML(toXML(rules, params), xml)
it 'allows renamed map keys and values', ->
params = { Items: { A: 'a', B: 'b' } }
otherRules =
type: 'structure'
members:
Items:
type: 'map'
key: type: 'string', locationName: 'MKEY'
value: type: 'string', locationName: 'MVALUE'
xml = """
A
a
B
b
"""
matchXML(toXML(otherRules, params), xml)
it 'ignores null', ->
expect(toXML(rules, Items: null)).toEqual('')
it 'ignores undefined', ->
expect(toXML(rules, Items: undefined)).toEqual('')
describe 'flattened maps', ->
rules =
type: 'structure'
members:
Items:
type: 'map'
locationName: 'Item'
flattened: true
key: type: 'string'
value: type: 'string'
it 'translates flattened maps', ->
params = { Items: { A: 'a', B: 'b' } }
xml = """
-
A
a
-
B
b
"""
matchXML(toXML(rules, params), xml)
it 'allows renamed map keys and values', ->
params = { Items: { A: 'a', B: 'b' } }
otherRules =
type: 'structure'
members:
Items:
locationName: 'Item'
flattened: true
type: 'map'
key: type: 'string', locationName: 'MKEY'
value: type: 'string', locationName: 'MVALUE'
xml = """
-
A
a
-
B
b
"""
matchXML(toXML(otherRules, params), xml)
it 'ignores null', ->
expect(toXML(rules, Items: null)).toEqual('')
it 'ignores undefined', ->
expect(toXML(rules, Items: undefined)).toEqual('')
describe 'numbers', ->
it 'integers', ->
rules = members: {Count:{type:'integer'}}
params = { Count: 123.0 }
xml = """
123
"""
matchXML(toXML(rules, params), xml)
it 'floats', ->
rules = members: {Count:{type:'float'}}
params = { Count: 123.123 }
xml = """
123.123
"""
matchXML(toXML(rules, params), xml)
it 'ints and floats formatted as numbers', ->
rules = members: {CountI:{type:'integer'},CountF:{type:'float'}}
params = { CountI: '123', CountF: '1.23' }
xml = """
123
1.23
"""
matchXML(toXML(rules, params), xml)
describe 'booleans', ->
it 'true', ->
rules = members: {Enabled:{type:'boolean'}}
params = { Enabled: true }
xml = """
true
"""
matchXML(toXML(rules, params), xml)
it 'false', ->
rules = members: {Enabled:{type:'boolean'}}
params = { Enabled: false }
xml = """
false
"""
matchXML(toXML(rules, params), xml)
describe 'timestamps', ->
time = new Date()
time.setMilliseconds(0)
it 'iso8601', ->
api.timestampFormat = 'iso8601'
rules = members: {Expires:{type:'timestamp'}}
params = { Expires: time }
xml = """
#{AWS.util.date.iso8601(time)}
"""
matchXML(toXML(rules, params), xml)
it 'rfc822', ->
api.timestampFormat = 'rfc822'
rules = members: {Expires:{type:'timestamp'}}
params = { Expires: time }
xml = """
#{AWS.util.date.rfc822(time)}
"""
matchXML(toXML(rules, params), xml)
it 'unix timestamp', ->
api.timestampFormat = 'unixTimestamp'
rules = members: {Expires:{type:'timestamp'}}
params = { Expires: time }
xml = """
#{AWS.util.date.unixTimestamp(time)}
"""
matchXML(toXML(rules, params), xml)
it 'follows the forat given on the shape', ->
api.timestampFormat = 'unixTimestamp'
rules = members: {Expires:{type:'timestamp',timestampFormat:'rfc822'}}
params = { Expires: time }
# despite the api configuration will specify unixTimesmap, we expect
# an rfc822 formatted date based on the format attribute
xml = """
#{AWS.util.date.rfc822(time)}
"""
matchXML(toXML(rules, params), xml)
describe 'xml attributes', ->
it 'can serialize xml attributes', ->
rules = members:
Config:
type: 'structure'
members:
Foo:
type: 'string'
Attr:
type: 'string'
xmlAttribute: true
locationName: 'attr:name'
params = { Config: { Foo: 'bar', Attr: 'abc' } }
xml = """
bar
"""
matchXML(toXML(rules, params), xml)
describe 'xml namespaces', ->
it 'can apply xml namespaces on structures', ->
rules = members:
Config:
type: 'structure'
xmlNamespace:
uri: 'URI'
members:
Foo:
type: 'string'
params = { Config: { Foo: 'bar' } }
xml = """
bar
"""
matchXML(toXML(rules, params), xml)
it 'applies namespace prefixes to the xmlns attribute', ->
rules = members:
Config:
type: 'structure'
xmlNamespace:
prefix: 'xsi'
uri: 'URI'
members:
Foo:
type: 'string'
params = { Config: { Foo: 'bar' } }
xml = """
bar
"""
matchXML(toXML(rules, params), xml)
it 'can apply namespaces to elements that have other attributes', ->
rules = members:
Config:
type: 'structure'
xmlNamespace:
prefix: 'xsi'
uri: 'URI'
members:
Foo:
type: 'string'
Bar:
type: 'string'
xmlAttribute: true
locationName: 'xsi:label'
params = { Config: { Foo: 'abc', Bar: 'xyz' } }
xml = """
abc
"""
matchXML(toXML(rules, params), xml)