2
2
import pytest
3
3
4
4
from aws_dbesdk_dynamodb .encrypted .table import EncryptedTable
5
+ from aws_dbesdk_dynamodb .smithygenerated .aws_cryptography_dbencryptionsdk_dynamodb_transforms .errors import (
6
+ DynamoDbEncryptionTransformsException ,
7
+ )
5
8
6
9
from ...constants import (
7
10
INTEG_TEST_DEFAULT_DYNAMODB_TABLE_NAME ,
8
11
INTEG_TEST_DEFAULT_TABLE_CONFIGS ,
9
12
)
10
13
from ...items import complex_item_dict , simple_item_dict
11
14
from ...requests import (
15
+ basic_delete_item_request_dict ,
12
16
basic_get_item_request_dict ,
13
17
basic_put_item_request_dict ,
14
18
basic_query_request_dict ,
15
19
basic_scan_request_dict ,
20
+ basic_update_item_request_dict_signed_attribute ,
21
+ basic_update_item_request_dict_unsigned_attribute ,
16
22
)
17
23
18
24
@@ -61,21 +67,37 @@ def test_item(request):
61
67
return request .param
62
68
63
69
64
- def test_GIVEN_item_WHEN_basic_put_and_basic_get_THEN_round_trip_passes (table , test_item ):
65
- """Test put_item and get_item operations."""
66
- # Given: Simple and complex items in appropriate format for client
70
+ def test_GIVEN_item_WHEN_basic_put_AND_basic_get_AND_basic_delete_THEN_round_trip_passes (table , test_item ):
71
+ """Test put_item, get_item, and delete_item operations."""
72
+ # Given: Valid put_item request
67
73
put_item_request_dict = basic_put_item_request_dict (test_item )
68
-
69
- # When: Putting and getting item
74
+ # When: put_item
70
75
put_response = table .put_item (** put_item_request_dict )
76
+ # Then: put_item succeeds
71
77
assert put_response ["ResponseMetadata" ]["HTTPStatusCode" ] == 200
72
78
79
+ # Given: Valid get_item request for the same item
73
80
get_item_request_dict = basic_get_item_request_dict (test_item )
81
+ # When: get_item
74
82
get_response = table .get_item (** get_item_request_dict )
75
83
# Then: Simple item is encrypted and decrypted correctly
76
84
assert get_response ["ResponseMetadata" ]["HTTPStatusCode" ] == 200
77
85
assert get_response ["Item" ] == put_item_request_dict ["Item" ]
78
86
87
+ # Given: Valid delete_item request for the same item
88
+ delete_item_request_dict = basic_delete_item_request_dict (test_item )
89
+ # When: delete_item
90
+ delete_response = table .delete_item (** delete_item_request_dict )
91
+ # Then: delete_item succeeds
92
+ assert delete_response ["ResponseMetadata" ]["HTTPStatusCode" ] == 200
93
+
94
+ # Given: Valid get_item request for the same item
95
+ get_item_request_dict = basic_get_item_request_dict (test_item )
96
+ # When: get_item
97
+ get_response = table .get_item (** get_item_request_dict )
98
+ # Then: get_item is empty (i.e. the item was deleted)
99
+ assert "Item" not in get_response
100
+
79
101
80
102
def test_GIVEN_items_WHEN_batch_write_and_get_THEN_round_trip_passes (
81
103
table ,
@@ -154,7 +176,6 @@ def scan_request(encrypted, test_item):
154
176
155
177
156
178
def test_GIVEN_valid_put_and_scan_requests_WHEN_put_and_scan_THEN_round_trip_passes (table , test_item , scan_request ):
157
- """Test put_item and scan operations."""
158
179
# Given: Simple and complex items in appropriate format for client
159
180
put_item_request_dict = basic_put_item_request_dict (test_item )
160
181
table .put_item (** put_item_request_dict )
@@ -166,24 +187,44 @@ def test_GIVEN_valid_put_and_scan_requests_WHEN_put_and_scan_THEN_round_trip_pas
166
187
assert scan_response ["ResponseMetadata" ]["HTTPStatusCode" ] == 200
167
188
168
189
169
- def test_WHEN_update_item_THEN_raises_not_implemented_error ():
170
- # Given: Encrypted client and update item parameters
190
+ def test_GIVEN_update_for_unsigned_attribute_WHEN_update_item_THEN_passes (table , test_item ):
191
+ # Given: some item is already in the table
192
+ put_response = table .put_item (** basic_put_item_request_dict (test_item ))
193
+ assert put_response ["ResponseMetadata" ]["HTTPStatusCode" ] == 200
194
+
195
+ # Given: Valid update item request for unsigned attribute
196
+ update_item_request = basic_update_item_request_dict_unsigned_attribute (test_item )
197
+
171
198
# When: Calling update_item
172
- with pytest .raises (NotImplementedError ):
173
- encrypted_table ().update_item (
174
- TableName = INTEG_TEST_DEFAULT_DYNAMODB_TABLE_NAME ,
175
- Key = {"partition_key" : "test-key" , "sort_key" : 1 },
176
- UpdateExpression = "SET attribute1 = :val" ,
177
- ExpressionAttributeValues = {":val" : {"S" : "new value" }},
178
- )
179
- # Then: NotImplementedError is raised
199
+ update_response = table .update_item (** update_item_request )
200
+ # Then: update_item succeeds
201
+ assert update_response ["ResponseMetadata" ]["HTTPStatusCode" ] == 200
202
+
203
+
204
+ def test_GIVEN_update_for_signed_attribute_WHEN_update_item_THEN_raises_DynamoDbEncryptionTransformsException (
205
+ table , test_item , encrypted
206
+ ):
207
+ if not encrypted :
208
+ pytest .skip ("Skipping negative test for plaintext client" )
209
+
210
+ # Given: some item is already in the table
211
+ put_response = table .put_item (** basic_put_item_request_dict (test_item ))
212
+ assert put_response ["ResponseMetadata" ]["HTTPStatusCode" ] == 200
213
+
214
+ # Given: Valid update item request for signed attribute
215
+ update_item_request = basic_update_item_request_dict_signed_attribute (test_item )
216
+
217
+ # Then: raises DynamoDbEncryptionTransformsException
218
+ with pytest .raises (DynamoDbEncryptionTransformsException ):
219
+ # When: Calling update_item
220
+ table .update_item (** update_item_request )
180
221
181
222
182
223
def test_WHEN_call_passthrough_method_THEN_correct_response_is_returned ():
183
224
"""Test that calling a passthrough method returns the correct response."""
184
- # Given: Encrypted client
185
- # When: Calling some passthrough method that does not explicitly exist on EncryptedClient ,
186
- # but exists on the underlying boto3 client
187
- response = encrypted_table ().meta . client . list_backups ()
188
- # Then: Correct response is returned, i.e. EncryptedClient forwards the call to the underlying boto3 client
189
- assert response [ "ResponseMetadata" ][ "HTTPStatusCode" ] == 200
225
+ # Given: Encrypted or plaintext table
226
+ # When: Calling some passthrough method that does not explicitly exist on EncryptedTable ,
227
+ # but exists on the underlying boto3 table
228
+ response = encrypted_table ().table_name
229
+ # Then: Correct response is returned, i.e. EncryptedTable forwards the call to the underlying boto3 table
230
+ assert response == INTEG_TEST_DEFAULT_DYNAMODB_TABLE_NAME
0 commit comments