33
44from aws_dbesdk_dynamodb .encrypted .client import EncryptedClient
55
6+ from . import sort_dynamodb_json_lists
7+
68from ...constants import (
79 INTEG_TEST_DEFAULT_DYNAMODB_TABLE_NAME ,
810 INTEG_TEST_DEFAULT_TABLE_CONFIGS ,
2123 basic_put_item_request_ddb ,
2224 basic_put_item_request_dict ,
2325 basic_query_paginator_request ,
24- basic_scan_request_ddb ,
25- basic_scan_request_dict ,
26+ basic_scan_paginator_request ,
2627)
2728
28- BOTO3_CLIENT = boto3 .client ("dynamodb" )
29- ENCRYPTED_CLIENT = EncryptedClient (client = BOTO3_CLIENT , encryption_config = INTEG_TEST_DEFAULT_TABLE_CONFIGS )
30- SCAN_PAGINATOR = ENCRYPTED_CLIENT .get_paginator ("scan" )
31- QUERY_PAGINATOR = ENCRYPTED_CLIENT .get_paginator ("query" )
32-
3329
30+ # Creates a matrix of tests for each value in param,
31+ # with a user-friendly string for test output:
32+ # expect_standard_dictionaries = True -> "standard_dicts"
33+ # expect_standard_dictionaries = False -> "ddb_json"
3434@pytest .fixture (params = [True , False ], ids = ["standard_dicts" , "ddb_json" ])
3535def expect_standard_dictionaries (request ):
3636 return request .param
@@ -52,6 +52,10 @@ def plaintext_client(expect_standard_dictionaries):
5252 return client
5353
5454
55+ # Creates a matrix of tests for each value in param,
56+ # with a user-friendly string for test output:
57+ # encrypted = True -> "encrypted"
58+ # encrypted = False -> "plaintext"
5559@pytest .fixture (params = [True , False ], ids = ["encrypted" , "plaintext" ])
5660def encrypted (request ):
5761 return request .param
@@ -74,7 +78,10 @@ def query_paginator(client):
7478def scan_paginator (client ):
7579 return client .get_paginator ("scan" )
7680
77-
81+ # Creates a matrix of tests for each value in param,
82+ # with a user-friendly string for test output:
83+ # use_complex_item = True -> "complex_item"
84+ # use_complex_item = False -> "simple_item"
7885@pytest .fixture (params = [True , False ], ids = ["complex_item" , "simple_item" ])
7986def use_complex_item (request ):
8087 return request .param
@@ -127,23 +134,6 @@ def put_item_request(expect_standard_dictionaries, test_item):
127134 return {** basic_put_item_request_dict (test_item ), "TableName" : INTEG_TEST_DEFAULT_DYNAMODB_TABLE_NAME }
128135 return basic_put_item_request_ddb (test_item )
129136
130-
131- def sort_dynamodb_json_lists (obj ):
132- """
133- Utility that recursively sorts all lists in a DynamoDB JSON-like structure.
134- DynamoDB JSON uses lists to represent sets, so strict equality can fail.
135- Sort lists to ensure consistent ordering when comparing expected and actual items.
136- """
137- if isinstance (obj , dict ):
138- return {k : sort_dynamodb_json_lists (v ) for k , v in obj .items ()}
139- elif isinstance (obj , list ):
140- try :
141- return sorted (obj ) # Sort lists for consistent comparison
142- except TypeError :
143- return obj # Not all lists are sortable; ex. complex_item_ddb's "list" attribute
144- return obj
145-
146-
147137def test_GIVEN_query_paginator_WHEN_paginate_THEN_returns_expected_items (
148138 client , query_paginator , paginate_query_request , put_item_request , test_item
149139):
@@ -168,15 +158,11 @@ def test_GIVEN_query_paginator_WHEN_paginate_THEN_returns_expected_items(
168158
169159
170160@pytest .fixture
171- def paginate_scan_request (expect_standard_dictionaries , encrypted , test_item ):
161+ def paginate_scan_request (expect_standard_dictionaries , test_item ):
172162 if expect_standard_dictionaries :
173- request = {** basic_scan_request_dict (test_item ), "TableName" : INTEG_TEST_DEFAULT_DYNAMODB_TABLE_NAME }
163+ request = {** basic_scan_paginator_request (test_item ), "TableName" : INTEG_TEST_DEFAULT_DYNAMODB_TABLE_NAME }
174164 else :
175- request = basic_scan_request_ddb (test_item )
176- if encrypted :
177- request ["FilterExpression" ] = request ["FilterExpression" ] + " AND attribute_exists (#sig)"
178- request ["ExpressionAttributeNames" ] = {}
179- request ["ExpressionAttributeNames" ]["#sig" ] = "amzn-ddb-map-sig"
165+ request = basic_scan_paginator_request (test_item )
180166 return request
181167
182168
@@ -194,70 +180,10 @@ def test_GIVEN_scan_paginator_WHEN_paginate_THEN_returns_expected_items(
194180 if "Items" in page :
195181 for item in page ["Items" ]:
196182 items .append (item )
197-
198-
199- # TODO: set up scan table and tests
200-
201- # @pytest.fixture
202- # def default_requests(simple_item_ddb):
203- # """Fixture to provide default scan and query requests."""
204- # return {
205- # "scan": get_scan_request(simple_item_ddb["partition_key"]),
206- # "query": get_query_request(simple_item_ddb["partition_key"]),
207- # }
208-
209- # @pytest.fixture(scope="module", autouse=True)
210- # def setup_module_fixture(simple_item_ddb):
211- # # Runs before all tests in this module
212- # for i in range(10):
213- # ENCRYPTED_CLIENT.put_item(
214- # TableName=INTEG_TEST_DEFAULT_DYNAMODB_TABLE_NAME,
215- # Item={
216- # "partition_key": simple_item_ddb["partition_key"],
217- # "sort_key": {"N": str(i)},
218- # "attribute1": {"S": "encrypt and sign me!"},
219- # "attribute2": {"S": "sign me!"},
220- # ":attribute3": {"S": "ignore me!"},
221- # },
222- # )
223- # # Yield to all tests in this module
224- # yield
225- # # TODO: Delete items? not needed but nice
226-
227- # @pytest.mark.parametrize("paginator_name, request_key", [
228- # ("scan", "scan"),
229- # ("query", "query")
230- # ])
231- # def test_GIVEN_incomplete_search_WHEN_build_full_result_THEN_NextToken_completes_search(
232- # paginator_name,
233- # request_key,
234- # default_requests,
235- # ):
236- # # TODO: test
237- # return
238- # # Given: PaginationConfig that will result in an incomplete search.
239- # # There are 10 items, and returning 2 per operation results in multiple uses of NextToken.
240- # pagination_config = {
241- # "MaxItems": 2,
242- # }
243-
244- # paginator = getattr(ENCRYPTED_CLIENT, f"get_paginator")(paginator_name)
245- # incomplete_search_request = default_requests[request_key].copy()
246- # incomplete_search_request["PaginationConfig"] = pagination_config
247-
248- # # When: Build full result from paginator
249- # full_result = paginator.paginate(**incomplete_search_request)
250-
251- # print(f"{full_result=}")
252-
253- # collected_items = []
254-
255- # print(f'{full_result=}')
256-
257- # for item in full_result:
258- # # assert item["attribute1"]["S"] == "encrypt and sign me!"
259- # collected_items.append(item)
260-
261- # # Then: NextToken should be present
262- # # assert "NextToken" in full_result
263- # # Then: NextToken is able to complete the search
183+ assert len (items ) == 1
184+ # DynamoDB JSON uses lists to represent sets, so strict equality can fail.
185+ # Sort lists to ensure consistent ordering when comparing expected and actual items.
186+ expected_item = sort_dynamodb_json_lists (test_item )
187+ actual_item = sort_dynamodb_json_lists (items [0 ])
188+ # Then: Items are equal
189+ assert expected_item == actual_item
0 commit comments