Skip to content

Commit

Permalink
Update tests for empty string and binary values
Browse files Browse the repository at this point in the history
  • Loading branch information
mhart committed May 24, 2020
1 parent 7932a5b commit 8a4a8d1
Show file tree
Hide file tree
Showing 10 changed files with 146 additions and 84 deletions.
32 changes: 26 additions & 6 deletions test/batchGetItem.js
Expand Up @@ -240,14 +240,10 @@ describe('batchGetItem', function() {

it('should return ValidationException for invalid values in Key', function(done) {
async.forEach([
[{N: '', S: ''}, 'An AttributeValue may not contain an empty string'],
[{B: ''}, 'An AttributeValue may not contain a null or empty binary type.'],
[{NULL: 'no'}, 'Null attribute value types must have the value of true'],
[{SS: []}, 'An string set may not be empty'],
[{NS: []}, 'An number set may not be empty'],
[{BS: []}, 'Binary sets should not be empty'],
[{SS: ['a', '']}, 'An string set may not have a empty string as a member'],
[{BS: ['aaaa', '']}, 'Binary sets may not contain null or empty values'],
[{SS: ['a', 'a']}, 'Input collection [a, a] contains duplicates.'],
[{BS: ['Yg==', 'Yg==']}, 'Input collection [Yg==, Yg==]of type BS contains duplicates.'],
], function(expr, cb) {
Expand All @@ -258,6 +254,7 @@ describe('batchGetItem', function() {

it('should return ValidationException for empty/invalid numbers in Key', function(done) {
async.forEach([
[{S: '', N: ''}, 'The parameter cannot be converted to a numeric value'],
[{S: 'a', N: ''}, 'The parameter cannot be converted to a numeric value'],
[{S: 'a', N: 'b'}, 'The parameter cannot be converted to a numeric value: b'],
[{NS: ['1', '']}, 'The parameter cannot be converted to a numeric value'],
Expand All @@ -279,7 +276,7 @@ describe('batchGetItem', function() {
'Supplied AttributeValue has more than one datatypes set, must contain exactly one of the supported datatypes', done)
})

it('should return ValidationException for duplicated keys', function(done) {
it('should return ValidationException for empty ExpressionAttributeNames', function(done) {
var key = {a: {S: helpers.randomString()}, b: {N: helpers.randomNumber()}}
assertValidation({
RequestItems: {
Expand All @@ -289,6 +286,29 @@ describe('batchGetItem', function() {
ProjectionExpression: '',
},
},
}, 'ExpressionAttributeNames must not be empty', done)
})

it('should return ValidationException for empty ProjectionExpression', function(done) {
var key = {a: {S: helpers.randomString()}, b: {N: helpers.randomNumber()}}
assertValidation({
RequestItems: {
abc: {
Keys: [key, {b: key.b, a: key.a}, key],
ProjectionExpression: '',
},
},
}, 'Invalid ProjectionExpression: The expression can not be empty;', done)
})

it('should return ValidationException for duplicated keys', function(done) {
var key = {a: {S: helpers.randomString()}, b: {N: helpers.randomNumber()}}
assertValidation({
RequestItems: {
abc: {
Keys: [key, {b: key.b, a: key.a}, key],
},
},
}, 'Provided list of item keys contains duplicates', done)
})

Expand All @@ -302,7 +322,7 @@ describe('batchGetItem', function() {
AttributesToGet: ['a', 'a'],
},
},
}, 'Provided list of item keys contains duplicates', done)
}, 'One or more parameter values were invalid: Duplicate value in attribute name: a', done)
})

it('should return ValidationException duplicate values in AttributesToGet', function(done) {
Expand Down
5 changes: 1 addition & 4 deletions test/batchWriteItem.js
Expand Up @@ -214,14 +214,10 @@ describe('batchWriteItem', function() {

it('should return ValidationException for invalid values in Item', function(done) {
async.forEach([
[{N: '', S: ''}, 'An AttributeValue may not contain an empty string'],
[{B: ''}, 'An AttributeValue may not contain a null or empty binary type.'],
[{NULL: 'no'}, 'Null attribute value types must have the value of true'],
[{SS: []}, 'An string set may not be empty'],
[{NS: []}, 'An number set may not be empty'],
[{BS: []}, 'Binary sets should not be empty'],
[{SS: ['a', '']}, 'An string set may not have a empty string as a member'],
[{BS: ['aaaa', '']}, 'Binary sets may not contain null or empty values'],
[{SS: ['a', 'a']}, 'Input collection [a, a] contains duplicates.'],
[{BS: ['Yg==', 'Yg==']}, 'Input collection [Yg==, Yg==]of type BS contains duplicates.'],
], function(expr, cb) {
Expand All @@ -232,6 +228,7 @@ describe('batchWriteItem', function() {

it('should return ValidationException for empty/invalid numbers in Item', function(done) {
async.forEach([
[{S: '', N: ''}, 'The parameter cannot be converted to a numeric value'],
[{S: 'a', N: ''}, 'The parameter cannot be converted to a numeric value'],
[{S: 'a', N: 'b'}, 'The parameter cannot be converted to a numeric value: b'],
[{NS: ['1', '']}, 'The parameter cannot be converted to a numeric value'],
Expand Down
12 changes: 6 additions & 6 deletions test/createTable.js
Expand Up @@ -421,25 +421,25 @@ describe('createTable', function() {
KeySchema: [{KeyType: 'HASH', AttributeName: 'a'}, {KeyType: 'RANGE', AttributeName: 'b'}],
LocalSecondaryIndexes: [{}, {}, {}, {}, {}, {}, {}, {}, {}],
ProvisionedThroughput: {ReadCapacityUnits: 1, WriteCapacityUnits: 1}}, [
'Value null at \'localSecondaryIndexes.1.member.indexName\' failed to satisfy constraint: ' +
'Member must not be null',
'Value null at \'localSecondaryIndexes.1.member.keySchema\' failed to satisfy constraint: ' +
'Member must not be null',
'Value null at \'localSecondaryIndexes.1.member.projection\' failed to satisfy constraint: ' +
'Member must not be null',
'Value null at \'localSecondaryIndexes.1.member.indexName\' failed to satisfy constraint: ' +
'Value null at \'localSecondaryIndexes.2.member.indexName\' failed to satisfy constraint: ' +
'Member must not be null',
'Value null at \'localSecondaryIndexes.2.member.keySchema\' failed to satisfy constraint: ' +
'Member must not be null',
'Value null at \'localSecondaryIndexes.2.member.projection\' failed to satisfy constraint: ' +
'Member must not be null',
'Value null at \'localSecondaryIndexes.2.member.indexName\' failed to satisfy constraint: ' +
'Value null at \'localSecondaryIndexes.3.member.indexName\' failed to satisfy constraint: ' +
'Member must not be null',
'Value null at \'localSecondaryIndexes.3.member.keySchema\' failed to satisfy constraint: ' +
'Member must not be null',
'Value null at \'localSecondaryIndexes.3.member.projection\' failed to satisfy constraint: ' +
'Member must not be null',
'Value null at \'localSecondaryIndexes.3.member.indexName\' failed to satisfy constraint: ' +
'Member must not be null',
'Value null at \'localSecondaryIndexes.4.member.keySchema\' failed to satisfy constraint: ' +
'Value null at \'localSecondaryIndexes.4.member.indexName\' failed to satisfy constraint: ' +
'Member must not be null',
], done)
})
Expand Down Expand Up @@ -756,7 +756,7 @@ describe('createTable', function() {
'Member must not be null',
'Value null at \'globalSecondaryIndexes.3.member.indexName\' failed to satisfy constraint: ' +
'Member must not be null',
'Value null at \'globalSecondaryIndexes.4.member.keySchema\' failed to satisfy constraint: ' +
'Value null at \'globalSecondaryIndexes.4.member.indexName\' failed to satisfy constraint: ' +
'Member must not be null',
], done)
})
Expand Down
10 changes: 2 additions & 8 deletions test/deleteItem.js
Expand Up @@ -225,14 +225,10 @@ describe('deleteItem', function() {

it('should return ValidationException for invalid values in ExpressionAttributeValues', function(done) {
async.forEach([
[{N: '', S: ''}, 'An AttributeValue may not contain an empty string'],
[{B: ''}, 'An AttributeValue may not contain a null or empty binary type.'],
[{NULL: 'no'}, 'Null attribute value types must have the value of true'],
[{SS: []}, 'An string set may not be empty'],
[{NS: []}, 'An number set may not be empty'],
[{BS: []}, 'Binary sets should not be empty'],
[{SS: ['a', '']}, 'An string set may not have a empty string as a member'],
[{BS: ['aaaa', '']}, 'Binary sets may not contain null or empty values'],
[{SS: ['a', 'a']}, 'Input collection [a, a] contains duplicates.'],
[{BS: ['Yg==', 'Yg==']}, 'Input collection [Yg==, Yg==]of type BS contains duplicates.'],
], function(expr, cb) {
Expand All @@ -248,6 +244,7 @@ describe('deleteItem', function() {

it('should return ValidationException for empty/invalid numbers in ExpressionAttributeValues', function(done) {
async.forEach([
[{S: '', N: ''}, 'The parameter cannot be converted to a numeric value'],
[{S: 'a', N: ''}, 'The parameter cannot be converted to a numeric value'],
[{S: 'a', N: 'b'}, 'The parameter cannot be converted to a numeric value: b'],
[{NS: ['1', '']}, 'The parameter cannot be converted to a numeric value'],
Expand Down Expand Up @@ -310,14 +307,10 @@ describe('deleteItem', function() {

it('should return ValidationException for invalid values in Key', function(done) {
async.forEach([
[{N: '', S: ''}, 'An AttributeValue may not contain an empty string'],
[{B: ''}, 'An AttributeValue may not contain a null or empty binary type.'],
[{NULL: 'no'}, 'Null attribute value types must have the value of true'],
[{SS: []}, 'An string set may not be empty'],
[{NS: []}, 'An number set may not be empty'],
[{BS: []}, 'Binary sets should not be empty'],
[{SS: ['a', '']}, 'An string set may not have a empty string as a member'],
[{BS: ['aaaa', '']}, 'Binary sets may not contain null or empty values'],
[{SS: ['a', 'a']}, 'Input collection [a, a] contains duplicates.'],
[{BS: ['Yg==', 'Yg==']}, 'Input collection [Yg==, Yg==]of type BS contains duplicates.'],
], function(expr, cb) {
Expand All @@ -328,6 +321,7 @@ describe('deleteItem', function() {

it('should return ValidationException for empty/invalid numbers in Key', function(done) {
async.forEach([
[{S: '', N: ''}, 'The parameter cannot be converted to a numeric value'],
[{S: 'a', N: ''}, 'The parameter cannot be converted to a numeric value'],
[{S: 'a', N: 'b'}, 'The parameter cannot be converted to a numeric value: b'],
[{NS: ['1', '']}, 'The parameter cannot be converted to a numeric value'],
Expand Down
17 changes: 13 additions & 4 deletions test/getItem.js
Expand Up @@ -143,14 +143,10 @@ describe('getItem', function() {

it('should return ValidationException for invalid values in Key', function(done) {
async.forEach([
[{N: '', S: ''}, 'An AttributeValue may not contain an empty string'],
[{B: ''}, 'An AttributeValue may not contain a null or empty binary type.'],
[{NULL: 'no'}, 'Null attribute value types must have the value of true'],
[{SS: []}, 'An string set may not be empty'],
[{NS: []}, 'An number set may not be empty'],
[{BS: []}, 'Binary sets should not be empty'],
[{SS: ['a', '']}, 'An string set may not have a empty string as a member'],
[{BS: ['aaaa', '']}, 'Binary sets may not contain null or empty values'],
[{SS: ['a', 'a']}, 'Input collection [a, a] contains duplicates.'],
[{BS: ['Yg==', 'Yg==']}, 'Input collection [Yg==, Yg==]of type BS contains duplicates.'],
], function(expr, cb) {
Expand All @@ -161,6 +157,7 @@ describe('getItem', function() {

it('should return ValidationException for empty/invalid numbers in Key', function(done) {
async.forEach([
[{S: '', N: ''}, 'The parameter cannot be converted to a numeric value'],
[{S: 'a', N: ''}, 'The parameter cannot be converted to a numeric value'],
[{S: 'a', N: 'b'}, 'The parameter cannot be converted to a numeric value: b'],
[{NS: ['1', '']}, 'The parameter cannot be converted to a numeric value'],
Expand Down Expand Up @@ -337,6 +334,18 @@ describe('getItem', function() {
'The provided key element does not match the schema', done)
})

it('should return ValidationException if string key has empty string', function(done) {
assertValidation({TableName: helpers.testHashTable, Key: {a: {S: ''}}},
'One or more parameter values were invalid: ' +
'The AttributeValue for a key attribute cannot contain an empty string value. Key: a', done)
})

it('should return ValidationException if binary key has empty string', function(done) {
assertValidation({TableName: helpers.testRangeBTable, Key: {a: {S: 'a'}, b: {B: ''}}},
'One or more parameter values were invalid: ' +
'The AttributeValue for a key attribute cannot contain an empty binary value. Key: b', done)
})

it('should return ValidationException if hash key is too big', function(done) {
var keyStr = (helpers.randomString() + new Array(2048).join('a')).slice(0, 2049)
assertValidation({TableName: helpers.testHashTable, Key: {a: {S: keyStr}}},
Expand Down
27 changes: 14 additions & 13 deletions test/helpers.js
Expand Up @@ -375,6 +375,7 @@ function assertType(target, property, type, done) {
type = subtypeMatch[1]
subtype = subtypeMatch[2]
}
var castMsg = "class sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to class java.lang.Class (sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl and java.lang.Class are in module java.base of loader 'bootstrap')"
switch (type) {
case 'Boolean':
msgs = [
Expand Down Expand Up @@ -444,12 +445,12 @@ function assertType(target, property, type, done) {
break
case 'ParameterizedList':
msgs = [
['23', 'sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to java.lang.Class'],
[true, 'sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to java.lang.Class'],
[23, 'sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to java.lang.Class'],
[-2147483648, 'sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to java.lang.Class'],
[2147483648, 'sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to java.lang.Class'],
[34.56, 'sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to java.lang.Class'],
['23', castMsg],
[true, castMsg],
[23, castMsg],
[-2147483648, castMsg],
[2147483648, castMsg],
[34.56, castMsg],
[{}, 'Start of structure or map found where not expected'],
]
break
Expand All @@ -466,12 +467,12 @@ function assertType(target, property, type, done) {
break
case 'ParameterizedMap':
msgs = [
['23', 'sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to java.lang.Class'],
[true, 'sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to java.lang.Class'],
[23, 'sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to java.lang.Class'],
[-2147483648, 'sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to java.lang.Class'],
[2147483648, 'sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to java.lang.Class'],
[34.56, 'sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to java.lang.Class'],
['23', castMsg],
[true, castMsg],
[23, castMsg],
[-2147483648, castMsg],
[2147483648, castMsg],
[34.56, castMsg],
[[], 'Unrecognized collection type java.util.Map<java.lang.String, com.amazonaws.dynamodb.v20120810.AttributeValue>'],
]
break
Expand Down Expand Up @@ -556,7 +557,6 @@ function assertAccessDenied(target, data, msg, done) {
function assertValidation(target, data, msg, done) {
request(opts(target, data), function(err, res) {
if (err) return done(err)
res.statusCode.should.equal(400)
if (typeof res.body !== 'object') {
return done(new Error('Not JSON: ' + res.body))
}
Expand All @@ -573,6 +573,7 @@ function assertValidation(target, data, msg, done) {
} else {
res.body.message.should.equal(msg)
}
res.statusCode.should.equal(400)
done()
})
}
Expand Down
40 changes: 36 additions & 4 deletions test/putItem.js
Expand Up @@ -184,14 +184,10 @@ describe('putItem', function() {

it('should return ValidationException for invalid values in Item', function(done) {
async.forEach([
[{N: '', S: ''}, 'An AttributeValue may not contain an empty string'],
[{B: ''}, 'An AttributeValue may not contain a null or empty binary type.'],
[{NULL: 'no'}, 'Null attribute value types must have the value of true'],
[{SS: []}, 'An string set may not be empty'],
[{NS: []}, 'An number set may not be empty'],
[{BS: []}, 'Binary sets should not be empty'],
[{SS: ['a', '']}, 'An string set may not have a empty string as a member'],
[{BS: ['aaaa', '']}, 'Binary sets may not contain null or empty values'],
[{SS: ['a', 'a']}, 'Input collection [a, a] contains duplicates.'],
[{BS: ['Yg==', 'Yg==']}, 'Input collection [Yg==, Yg==]of type BS contains duplicates.'],
], function(expr, cb) {
Expand All @@ -207,6 +203,7 @@ describe('putItem', function() {

it('should return ValidationException for empty/invalid numbers in Item', function(done) {
async.forEach([
[{S: '', N: ''}, 'The parameter cannot be converted to a numeric value'],
[{S: 'a', N: ''}, 'The parameter cannot be converted to a numeric value'],
[{S: 'a', N: 'b'}, 'The parameter cannot be converted to a numeric value: b'],
[{NS: ['1', '']}, 'The parameter cannot be converted to a numeric value'],
Expand Down Expand Up @@ -504,6 +501,16 @@ describe('putItem', function() {
}, done)
})

it('should return ValidationException if empty string key', function(done) {
assertValidation({TableName: helpers.testHashTable, Item: {a: {S: ''}}},
'One or more parameter values are not valid. The AttributeValue for a key attribute cannot contain an empty string value. Key: a', done)
})

it('should return ValidationException if empty binary key', function(done) {
assertValidation({TableName: helpers.testRangeBTable, Item: {a: {S: 'a'}, b: {B: ''}}},
'One or more parameter values are not valid. The AttributeValue for a key attribute cannot contain an empty binary value. Key: b', done)
})

it('should return ValidationException if missing range key', function(done) {
assertValidation({TableName: helpers.testRangeTable, Item: {a: {S: 'a'}}},
'One or more parameter values were invalid: Missing the key b in the item', done)
Expand Down Expand Up @@ -565,6 +572,31 @@ describe('putItem', function() {
})
})

it('should put empty values', function(done) {
var item = {
a: {S: helpers.randomString()},
b: {S: ''},
c: {B: ''},
d: {SS: ['']},
e: {BS: ['']},
}
request(opts({TableName: helpers.testHashTable, Item: item}), function(err, res) {
if (err) return done(err)
res.body.should.eql({})
res.statusCode.should.equal(200)
request(helpers.opts('GetItem', {TableName: helpers.testHashTable, Key: {a: item.a}, ConsistentRead: true}), function(err, res) {
if (err) return done(err)
res.statusCode.should.equal(200)
item.b = {S: ''}
item.c = {B: ''}
item.d = {SS: ['']}
item.e = {BS: ['']}
res.body.should.eql({Item: item})
done()
})
})
})

it('should put really long numbers', function(done) {
var item = {
a: {S: helpers.randomString()},
Expand Down

0 comments on commit 8a4a8d1

Please sign in to comment.