From ed820cc80e3a1f6e08bf7799e8cb153e6669b6d7 Mon Sep 17 00:00:00 2001 From: Chris Keogh Date: Tue, 12 Sep 2017 09:28:36 +1200 Subject: [PATCH 1/4] return validation error for empty attribute --- moto/dynamodb2/responses.py | 10 +++++++++ tests/test_dynamodb2/test_dynamodb.py | 30 +++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/moto/dynamodb2/responses.py b/moto/dynamodb2/responses.py index 29863d23b..61e976632 100644 --- a/moto/dynamodb2/responses.py +++ b/moto/dynamodb2/responses.py @@ -144,6 +144,16 @@ class DynamoHandler(BaseResponse): def put_item(self): name = self.body['TableName'] item = self.body['Item'] + + res = re.search('\"\"', json.dumps(item)) + if res: + er = 'com.amazonaws.dynamodb.v20111205#ValidationException' + return 400, {'server': 'amazon.com'}, dynamo_json_dump( + {'__type': er, + 'message': ('One or more parameter values were invalid: ' + 'An AttributeValue may not contain an empty string') + }) + overwrite = 'Expected' not in self.body if not overwrite: expected = self.body['Expected'] diff --git a/tests/test_dynamodb2/test_dynamodb.py b/tests/test_dynamodb2/test_dynamodb.py index 7fec5c2bd..4ae753d7b 100644 --- a/tests/test_dynamodb2/test_dynamodb.py +++ b/tests/test_dynamodb2/test_dynamodb.py @@ -149,3 +149,33 @@ def test_list_not_found_table_tags(): conn.list_tags_of_resource(ResourceArn=arn) except ClientError as exception: assert exception.response['Error']['Code'] == "ResourceNotFoundException" + + +@requires_boto_gte("2.9") +@mock_dynamodb2 +def test_item_add_empty_string_exception(): + name = 'TestTable' + conn = boto3.client('dynamodb', + region_name='us-west-2', + aws_access_key_id="ak", + aws_secret_access_key="sk") + conn.create_table(TableName=name, + KeySchema=[{'AttributeName':'forum_name','KeyType':'HASH'}], + AttributeDefinitions=[{'AttributeName':'forum_name','AttributeType':'S'}], + ProvisionedThroughput={'ReadCapacityUnits':5,'WriteCapacityUnits':5}) + session = boto3.Session() + dynamodb = session.resource('dynamodb', + region_name='us-west-2', + aws_access_key_id="ak", + aws_secret_access_key="sk") + table = dynamodb.Table('TestTable') + try: + response = table.put_item(Item={ + 'forum_name': 'LOLCat Forum', + 'subject': 'Check this out!', + 'Body': 'http://url_to_lolcat.gif', + 'SentBy': "", + 'ReceivedTime': '12/9/2011 11:36:03 PM', + }) + except ClientError as exception: + assert exception.response['Error']['Code'] == "ValidationException" From 2a66ae2bfdd9f715e87ef79ca649cff1333fee1c Mon Sep 17 00:00:00 2001 From: Chris Keogh Date: Tue, 12 Sep 2017 11:07:34 +1200 Subject: [PATCH 2/4] fix linting errors --- moto/dynamodb2/responses.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/moto/dynamodb2/responses.py b/moto/dynamodb2/responses.py index acc9dfb5e..d41e4b366 100644 --- a/moto/dynamodb2/responses.py +++ b/moto/dynamodb2/responses.py @@ -148,10 +148,13 @@ class DynamoHandler(BaseResponse): res = re.search('\"\"', json.dumps(item)) if res: er = 'com.amazonaws.dynamodb.v20111205#ValidationException' - return 400, {'server': 'amazon.com'}, dynamo_json_dump( - {'__type': er, - 'message': ('One or more parameter values were invalid: ' - 'An AttributeValue may not contain an empty string')}) + return (400, + {'server': 'amazon.com'}, + dynamo_json_dump({'__type': er, + 'message': ('One or more parameter values were ' + 'invalid:An AttributeValue may not ' + 'contain an empty string')} + )) overwrite = 'Expected' not in self.body if not overwrite: From 6ee204e458d4c696ac3939569e07c2116ce83511 Mon Sep 17 00:00:00 2001 From: Chris Keogh Date: Tue, 12 Sep 2017 12:21:08 +1200 Subject: [PATCH 3/4] fix server mode test --- moto/dynamodb2/responses.py | 2 +- tests/test_dynamodb2/test_dynamodb.py | 26 +++++++++++++------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/moto/dynamodb2/responses.py b/moto/dynamodb2/responses.py index d41e4b366..586a1db7b 100644 --- a/moto/dynamodb2/responses.py +++ b/moto/dynamodb2/responses.py @@ -152,7 +152,7 @@ class DynamoHandler(BaseResponse): {'server': 'amazon.com'}, dynamo_json_dump({'__type': er, 'message': ('One or more parameter values were ' - 'invalid:An AttributeValue may not ' + 'invalid: An AttributeValue may not ' 'contain an empty string')} )) diff --git a/tests/test_dynamodb2/test_dynamodb.py b/tests/test_dynamodb2/test_dynamodb.py index 4ae753d7b..3b50f0b8e 100644 --- a/tests/test_dynamodb2/test_dynamodb.py +++ b/tests/test_dynamodb2/test_dynamodb.py @@ -163,19 +163,19 @@ def test_item_add_empty_string_exception(): KeySchema=[{'AttributeName':'forum_name','KeyType':'HASH'}], AttributeDefinitions=[{'AttributeName':'forum_name','AttributeType':'S'}], ProvisionedThroughput={'ReadCapacityUnits':5,'WriteCapacityUnits':5}) - session = boto3.Session() - dynamodb = session.resource('dynamodb', - region_name='us-west-2', - aws_access_key_id="ak", - aws_secret_access_key="sk") - table = dynamodb.Table('TestTable') + try: - response = table.put_item(Item={ - 'forum_name': 'LOLCat Forum', - 'subject': 'Check this out!', - 'Body': 'http://url_to_lolcat.gif', - 'SentBy': "", - 'ReceivedTime': '12/9/2011 11:36:03 PM', - }) + conn.put_item( + TableName=name, + Item={ + 'forum_name': { 'S': 'LOLCat Forum' }, + 'subject': { 'S': 'Check this out!' }, + 'Body': { 'S': 'http://url_to_lolcat.gif'}, + 'SentBy': { 'S': "" }, + 'ReceivedTime': { 'S': '12/9/2011 11:36:03 PM'}, + } + ) + except ClientError as exception: + exception.response['Error']['Code'] assert exception.response['Error']['Code'] == "ValidationException" From 1472d63c877471996e3798fcdc6144665e57121c Mon Sep 17 00:00:00 2001 From: Chris Keogh Date: Wed, 13 Sep 2017 08:28:42 +1200 Subject: [PATCH 4/4] use assert_raises teat helper pattern --- tests/test_dynamodb2/test_dynamodb.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/test_dynamodb2/test_dynamodb.py b/tests/test_dynamodb2/test_dynamodb.py index 3b50f0b8e..764980fba 100644 --- a/tests/test_dynamodb2/test_dynamodb.py +++ b/tests/test_dynamodb2/test_dynamodb.py @@ -164,7 +164,7 @@ def test_item_add_empty_string_exception(): AttributeDefinitions=[{'AttributeName':'forum_name','AttributeType':'S'}], ProvisionedThroughput={'ReadCapacityUnits':5,'WriteCapacityUnits':5}) - try: + with assert_raises(ClientError) as ex: conn.put_item( TableName=name, Item={ @@ -176,6 +176,8 @@ def test_item_add_empty_string_exception(): } ) - except ClientError as exception: - exception.response['Error']['Code'] - assert exception.response['Error']['Code'] == "ValidationException" + ex.exception.response['Error']['Code'].should.equal('ValidationException') + ex.exception.response['ResponseMetadata']['HTTPStatusCode'].should.equal(400) + ex.exception.response['Error']['Message'].should.equal( + 'One or more parameter values were invalid: An AttributeValue may not contain an empty string' + )