def test_with_dict_values_as_target(self): nested_container_field_path = 'containerThatWillFailRequestAndRequireFieldsInitialization.{{id}}.nestedContainer' random_first_container_id_one = f"first_container_{uuid4()}" random_first_container_id_two = f"second_container_{uuid4()}" random_nested_container_id_one = f"id_one_{str(uuid4())}" random_nested_container_id_two = f"id_two_{str(uuid4())}" random_container_field_value_one = {'secondNestedValue': f"container_field_value_one_{uuid4()}"} random_container_field_value_two = {'secondNestedValue': f"container_field_value_two_{uuid4()}"} # Initial update that put a single item in the container without risking to override existing fields initial_update_with_empty_value_success = self.users_table.update_field( key_value=TEST_ACCOUNT_ID, field_path=nested_container_field_path + '.{{nestedContainerKey}}', query_kwargs={'id': random_first_container_id_one, 'nestedContainerKey': random_nested_container_id_one}, value_to_set=random_container_field_value_one ) self.assertTrue(initial_update_with_empty_value_success) # Multi update operation, that could cause the update_success = self.users_table.update_field( key_value=TEST_ACCOUNT_ID, field_path=nested_container_field_path + '.{{nestedContainerKey}}', query_kwargs={'id': random_first_container_id_two, 'nestedContainerKey': random_nested_container_id_two}, value_to_set=random_container_field_value_two ) self.assertTrue(update_success) retrieved_containers_data = self.users_table.get_multiple_fields(key_value=TEST_ACCOUNT_ID, getters={ 'one': FieldGetter(field_path=nested_container_field_path, query_kwargs={'id': random_first_container_id_one}), 'two': FieldGetter(field_path=nested_container_field_path, query_kwargs={'id': random_first_container_id_two}) }) self.assertEqual(retrieved_containers_data['one'].get(random_nested_container_id_one, None), random_container_field_value_one) self.assertEqual(retrieved_containers_data['two'].get(random_nested_container_id_two, None), random_container_field_value_two)
def test_set_then_get_multiple_fields(self: unittest.TestCase, users_table: DynamoDBCachingTable or ExternalDynamoDBApiCachingTable): users_table.clear_cached_data_and_pending_operations() random_field_one_value = random.randint(0, 99) random_field_two_value = random.randint(100, 199) update_success = users_table.update_multiple_fields( key_value=TEST_ACCOUNT_ID, setters=[ FieldSetter(field_path='simpleValue', value_to_set=random_field_one_value), FieldSetter(field_path='simpleValue2', value_to_set=random_field_two_value) ]) self.assertTrue(update_success) retrieve_response_data = users_table.get_multiple_fields( key_value=TEST_ACCOUNT_ID, getters={ 'one': FieldGetter(field_path='simpleValue'), 'two': FieldGetter(field_path='simpleValue2') }) self.assertEqual(retrieve_response_data.get('one', None), { 'value': random_field_one_value, 'fromCache': True }) self.assertEqual(retrieve_response_data.get('two', None), { 'value': random_field_two_value, 'fromCache': True })
def test_with_string_value_as_target(self): random_id = str(uuid4()) random_value_one = f"one_{uuid4()}" random_value_two = f"two_{uuid4()}" initial_update_with_empty_value_success = self.users_table.update_field( key_value=TEST_ACCOUNT_ID, field_path='fieldAlreadyInitializedRequiringNewValue', value_to_set="initial" ) self.assertTrue(initial_update_with_empty_value_success) update_success = self.users_table.update_multiple_fields(key_value=TEST_ACCOUNT_ID, setters=[ FieldSetter(field_path='fieldAlreadyInitializedRequiringNewValue', value_to_set=random_value_one), FieldSetter( field_path='containerThatWillFailRequestAndRequireFieldsInitialization.{{id}}.firstNestedValue', query_kwargs={'id': random_id}, value_to_set=random_value_two ) ]) self.assertTrue(update_success) get_response_data = self.users_table.get_multiple_fields(key_value=TEST_ACCOUNT_ID, getters={ 'one': FieldGetter(field_path='fieldAlreadyInitializedRequiringNewValue'), 'two': FieldGetter(field_path='containerThatWillFailRequestAndRequireFieldsInitialization.{{id}}.firstNestedValue', query_kwargs={'id': random_id}) }) self.assertEqual(get_response_data.get('one', None), random_value_one) self.assertEqual(get_response_data.get('two', None), random_value_two)
def test_basic_get_multiple_fields_values_in_single_query(self): response_data: Optional[dict] = self.users_table.get_multiple_fields( key_value=TEST_ACCOUNT_ID, getters={ 'theAccountId': FieldGetter(field_path='accountId'), 'theProjects': FieldGetter(field_path='projects') }) self.assertIsNotNone(response_data) self.assertEqual(response_data.get('theAccountId', None), TEST_ACCOUNT_ID)
def test_basic_get_multiple_fields_items_in_single_query(self): response_data: Optional[dict] = self.users_table.get_multiple_fields_items_from_single_item( key_name="accountId", key_value=self.test_account_id, getters={ "theAccountId": FieldGetter(target_path="accountId"), "theProjects": FieldGetter(target_path="projects") } ) self.assertIsNotNone(response_data) self.assertEqual(response_data.get("theAccountId", None), {"accountId": self.test_account_id})
def test_sophisticated_get_multiple_fields_in_single_query(self): response_data: Optional[dict] = self.users_table.get_multiple_fields( key_value=TEST_ACCOUNT_ID, getters={ 'theAccountId': FieldGetter(field_path='accountId'), 'theProjectName': FieldGetter(field_path='projects.{{projectId}}.projectName', query_kwargs={'projectId': TEST_PROJECT_ID}) }) self.assertIsNotNone(response_data) self.assertEqual(response_data.get('theAccountId', None), TEST_ACCOUNT_ID) self.assertIn("test", response_data.get('theProjectName', ""))
def test_sophisticated_get_multiple_fields_in_single_query(self): response_data: Optional[dict] = self.users_table.get_multiple_fields_values_from_single_item( key_name="accountId", key_value=self.test_account_id, getters={ "theAccountId": FieldGetter(target_path="accountId"), "theProjectName": FieldGetter( target_path="projects.{{projectId}}.projectName", query_kwargs={"projectId": self.test_project_id} ) } ) self.assertIsNotNone(response_data) self.assertEqual(response_data.get("theAccountId", None), self.test_account_id) self.assertIn("test", response_data.get("theProjectName", ""))
def test_set_get_multiple_fields_with_special_inner_keys( self: unittest.TestCase, users_table: DynamoDBBasicTable or DynamoDBCachingTable, is_caching: bool): """ This test the client usage of '__PRIMARY_KEY__' as a getter key in a query_multiple_fields operation on a secondary index. The _inner_query_fields_secondary_index will be triggered to handle the requested, in our test case, we will not request the primary index, which will be added to the existing requested fields, by default with '__PRIMARY_KEY__' as the getter key, but since it is already used by the client, we should normally start to add random letters to '__PRIMARY_KEY__' until a free index key is found. """ field1_random_value: str = f"field1_${uuid4()}" field2_random_value: str = f"field2_${uuid4()}" set_update_success: bool = users_table.update_multiple_fields( key_value=TEST_ACCOUNT_ID, setters=[ FieldSetter(field_path='fieldOne', value_to_set=field1_random_value), FieldSetter(field_path='fieldTwo', value_to_set=field2_random_value) ]) self.assertTrue(set_update_success) if is_caching is True: commit_success: bool = users_table.commit_operations() self.assertTrue(commit_success) retrieved_items_values, query_metadata = users_table.query_multiple_fields( key_value=TEST_ACCOUNT_USERNAME, index_name='username', getters={ '__PRIMARY_KEY__': FieldGetter(field_path='fieldOne'), 'fieldTwo': FieldGetter(field_path='fieldTwo'), }) self.assertEqual( { TEST_ACCOUNT_ID: { '__PRIMARY_KEY__': (field1_random_value if is_caching is not True else { 'fromCache': False, 'value': field1_random_value }), 'fieldTwo': (field2_random_value if is_caching is not True else { 'fromCache': False, 'value': field2_random_value }) } }, retrieved_items_values)
def test_set_get_fields_with_overriding_names(self: unittest.TestCase, users_table: DynamoDBBasicTable or DynamoDBCachingTable, is_caching: bool): item1_field1_random_value: str = f"item1_field1_${uuid4()}" item2_field1_random_value: str = f"item2_field1_${uuid4()}" set_update_success: bool = users_table.update_multiple_fields( key_value=TEST_ACCOUNT_ID, setters=[ FieldSetter(field_path='container.{{containerKey}}', query_kwargs={'containerKey': "item1"}, value_to_set={'fieldOne': item1_field1_random_value}), FieldSetter(field_path='container.{{containerKey}}', query_kwargs={'containerKey': "item2"}, value_to_set={'fieldOne': item2_field1_random_value}) ]) self.assertTrue(set_update_success) if is_caching is True: commit_success: bool = users_table.commit_operations() self.assertTrue(commit_success) retrieved_items_values, query_metadata = users_table.query_multiple_fields( key_value=TEST_ACCOUNT_USERNAME, index_name='username', getters={ 'item1-value': FieldGetter(field_path='container.{{containerKey}}.fieldOne', query_kwargs={'containerKey': "item1"}), 'item2-value': FieldGetter(field_path='container.{{containerKey}}.fieldOne', query_kwargs={'containerKey': "item2"}), }) retrieved_items_values: Dict[str, Any] self.assertEqual( { TEST_ACCOUNT_ID: { 'item1-value': (item1_field1_random_value if is_caching is not True else { 'fromCache': False, 'value': item1_field1_random_value }), 'item2-value': (item2_field1_random_value if is_caching is not True else { 'fromCache': False, 'value': item2_field1_random_value }) } }, retrieved_items_values)
def test_get_value_from_path_target_by_secondary_index(self): account_id: Optional[str] = self.users_table.get_single_field_value_from_single_item( key_name="email", key_value=self.test_account_email, field_to_get="accountId" ) self.assertEqual(account_id, self.test_account_id) account_data: Optional[dict] = self.users_table.get_multiple_fields_values_from_single_item( key_name="email", key_value=self.test_account_email, getters={ "accountId": FieldGetter(target_path="accountId"), "username": FieldGetter(target_path="username") } ) self.assertEqual(account_data.get("accountId", None), self.test_account_id) self.assertEqual(account_data.get("username", None), self.test_account_username)
def test_delete_basic_item_from_path_target(self): random_value = f"fieldToRemove_{uuid4()}" success_field_set: bool = self.users_table.update_field( key_value=TEST_ACCOUNT_ID, field_path='fieldToRemove', value_to_set=random_value) self.assertTrue(success_field_set) retrieved_field, query_metadata = self.users_table.query_field( key_value=TEST_ACCOUNT_ID, field_path='fieldToRemove', ) retrieved_field: Dict[str, dict] self.assertEqual(retrieved_field, {TEST_ACCOUNT_ID: random_value}) retrieved_fields, query_metadata = self.users_table.query_multiple_fields( key_value=TEST_ACCOUNT_ID, getters={'fieldToRemove': FieldGetter(field_path='fieldToRemove')}) retrieved_fields: Dict[str, dict] self.assertEqual(retrieved_fields, {TEST_ACCOUNT_ID: { 'fieldToRemove': random_value }}) """success_field_remove = self.users_table.delete_field(
def test_get_value_from_path_target_by_secondary_index(self): account_id: Optional[str] = self.users_table.get_field( index_name="email", key_value=TEST_ACCOUNT_EMAIL, field_path="accountId") self.assertEqual(account_id, TEST_ACCOUNT_ID) account_data: Optional[dict] = self.users_table.get_multiple_fields( index_name="email", key_value=TEST_ACCOUNT_EMAIL, getters={ "accountId": FieldGetter(field_path="accountId"), "username": FieldGetter(field_path="username") }) self.assertEqual(account_data.get("accountId", None), TEST_ACCOUNT_ID) self.assertEqual(account_data.get("username", None), TEST_ACCOUNT_USERNAME)
def test_initialize_two_items_with_share_parents(self): base_field_path = 'containerForItemsWithSharedParents.{{itemId}}' item_name_field_path = f'{base_field_path}.itemName' potential_old_data_deletion_success = self.users_table.delete_multiple_fields( key_value=TEST_ACCOUNT_ID, removers={ 'one': FieldRemover(field_path=base_field_path, query_kwargs={'itemId': 'itemOne'}), 'two': FieldRemover(field_path=base_field_path, query_kwargs={'itemId': 'itemTwo'}) }) # We do not check the success of the deletion operation, because at the time of writing that, if a delete operation try to delete # a field path that does not exist, the operation will crash and return a success of False, where what we want is just to make sure # the data is fully clean so we can make sure we initialize the items from scratch. We do not really care about removing the data. update_success = self.users_table.update_multiple_fields( key_value=TEST_ACCOUNT_ID, setters=[ FieldSetter(field_path=item_name_field_path, query_kwargs={'itemId': 'itemOne'}, value_to_set="NameItemOne"), FieldSetter(field_path=item_name_field_path, query_kwargs={'itemId': 'itemTwo'}, value_to_set="NameItemTwo"), ]) self.assertTrue(update_success) retrieved_items_data = self.users_table.get_multiple_fields( key_value=TEST_ACCOUNT_ID, getters={ 'one': FieldGetter(field_path=base_field_path, query_kwargs={'itemId': 'itemOne'}), 'two': FieldGetter(field_path=base_field_path, query_kwargs={'itemId': 'itemTwo'}), }) self.assertIsNotNone(retrieved_items_data) self.assertEqual(retrieved_items_data.get('one', None), {'itemName': "NameItemOne"}) self.assertEqual(retrieved_items_data.get('two', None), {'itemName': "NameItemTwo"})
def test_remove_multiple_fields(self): random_id = str(uuid4()) random_value_one = f"one_{uuid4()}" random_value_two = f"two_{uuid4()}" update_success = self.users_table.update_multiple_fields( key_value=TEST_ACCOUNT_ID, setters=[ FieldSetter(field_path='fieldToRemove', value_to_set=random_value_one), FieldSetter( field_path= 'sophisticatedFieldToRemove.{{id}}.firstNestedValue', query_kwargs={'id': random_id}, value_to_set=random_value_two) ]) self.assertTrue(update_success) get_response_data = self.users_table.get_multiple_fields( key_value=TEST_ACCOUNT_ID, getters={ 'one': FieldGetter(field_path='fieldToRemove'), 'two': FieldGetter( field_path= 'sophisticatedFieldToRemove.{{id}}.firstNestedValue', query_kwargs={'id': random_id}) }) self.assertEqual(get_response_data.get('one', None), random_value_one) self.assertEqual(get_response_data.get('two', None), random_value_two) remove_response_data = self.users_table.remove_multiple_fields( key_value=TEST_ACCOUNT_ID, removers={ 'one': FieldRemover(field_path='fieldToRemove'), 'two': FieldRemover( field_path= 'sophisticatedFieldToRemove.{{id}}.firstNestedValue', query_kwargs={'id': random_id}) }) print(remove_response_data)
def test_get_multiple_float_fields( self: unittest.TestCase, table_client: Union[DynamoDBBasicTable, DynamoDBCachingTable, ExternalDynamoDBApiBasicTable, ExternalDynamoDBApiCachingTable], is_caching: bool, primary_key_name: str): container_field_one_random_text_value: float = random.randint(1, 10000) / 100 container_field_two_random_text_value: float = random.randint( 10001, 20000) / 100 first_table_container_fields_update_success: bool = table_client.update_multiple_fields( key_value=TEST_ACCOUNT_ID, setters=[ FieldSetter(field_path='floatsContainer.floatOne', value_to_set=container_field_one_random_text_value), FieldSetter(field_path='floatsContainer.floatTwo', value_to_set=container_field_two_random_text_value) ]) self.assertTrue(first_table_container_fields_update_success) if is_caching is True: self.assertTrue(table_client.commit_operations()) table_client.clear_cached_data() second_table_retrieved_container_fields_without_data_validation: Dict[ str, Optional[Any]] = table_client.get_multiple_fields( key_value=TEST_ACCOUNT_ID, getters={ 'one': FieldGetter(field_path='floatsContainer.floatOne'), 'two': FieldGetter(field_path='floatsContainer.floatTwo'), }) self.assertEqual( { 'one': (container_field_one_random_text_value if is_caching is not True else { 'value': container_field_one_random_text_value, 'fromCache': False }), 'two': (container_field_two_random_text_value if is_caching is not True else { 'value': container_field_two_random_text_value, 'fromCache': False }) }, second_table_retrieved_container_fields_without_data_validation)
def get_attributes(self, user_id: str, attributes_keys: List[str]) -> Dict[str, Any]: retrieved_fields: Optional[Dict[ str, Any]] = self.table_client.get_multiple_fields( key_value=user_id, getters={ key: FieldGetter(field_path=key) for key in attributes_keys }) return retrieved_fields if retrieved_fields is not None else { key: None for key in attributes_keys }
def test_retrieve_multiple_attributes_from_single_object(self): """ Test both the get_field and the get_multiple_fields function """ randomized_item_key = f"key_{uuid4()}" random_name = f"name-{uuid4()}" random_value = f"value-{uuid4()}" timestamp = time() randomized_item = { 'name': random_name, 'value': random_value, 'timestamp': timestamp } query_kwargs = {'itemKey': randomized_item_key} set_success: bool = self.users_table.update_field( key_value=TEST_ACCOUNT_ID, field_path='multiAttributesContainer.{{itemKey}}', query_kwargs=query_kwargs, value_to_set=randomized_item) self.assertTrue(set_success) retrieved_values: dict = self.users_table.get_field( key_value=TEST_ACCOUNT_ID, field_path='multiAttributesContainer.{{itemKey}}.(name, value)', query_kwargs=query_kwargs) self.assertEqual(retrieved_values.get('name'), random_name) self.assertEqual(retrieved_values.get('value'), random_value) retrieved_values: dict = self.users_table.get_multiple_fields( key_value=TEST_ACCOUNT_ID, getters={ 'one': FieldGetter( field_path= 'multiAttributesContainer.{{itemKey}}.(name, value)', query_kwargs=query_kwargs) }) self.assertEqual(retrieved_values['one'].get('name', None), random_name) self.assertEqual(retrieved_values['one'].get('value', None), random_value) deletion_success: bool = self.users_table.delete_field( key_value=TEST_ACCOUNT_ID, field_path='multiAttributesContainer.{{itemKey}}', query_kwargs=query_kwargs) self.assertTrue(deletion_success)
def test_set_get_fields_with_multi_selectors(self: unittest.TestCase, users_table: DynamoDBBasicTable or DynamoDBCachingTable, is_caching: bool): field1_random_value: str = f"field1_${uuid4()}" field2_random_value: str = f"field2_${uuid4()}" set_update_success: bool = users_table.update_multiple_fields( key_value=TEST_ACCOUNT_ID, setters=[ FieldSetter(field_path='fieldOne', value_to_set=field1_random_value), FieldSetter(field_path='fieldTwo', value_to_set=field2_random_value) ]) self.assertTrue(set_update_success) if is_caching is True: commit_success: bool = users_table.commit_operations() self.assertTrue(commit_success) retrieved_items_values, query_metadata = users_table.query_field( key_value=TEST_ACCOUNT_USERNAME, index_name='username', field_path='(fieldOne, fieldTwo)') retrieved_items_values: Dict[str, Any] self.assertEqual( { TEST_ACCOUNT_ID: { 'fieldOne': (field1_random_value if is_caching is not True else { 'fromCache': False, 'value': field1_random_value }), 'fieldTwo': (field2_random_value if is_caching is not True else { 'fromCache': False, 'value': field2_random_value }) } }, retrieved_items_values) retrieved_items_values, query_metadata = users_table.query_multiple_fields( key_value=TEST_ACCOUNT_USERNAME, index_name='username', getters={'item': FieldGetter(field_path='(fieldOne, fieldTwo)')}) retrieved_items_values: Dict[str, Any] print(retrieved_items_values)
def test_query_multiple_fields( self: unittest.TestCase, first_table: Union[DynamoDBBasicTable, DynamoDBCachingTable, ExternalDynamoDBApiBasicTable, ExternalDynamoDBApiCachingTable], second_table: Union[DynamoDBBasicTable, DynamoDBCachingTable, ExternalDynamoDBApiBasicTable, ExternalDynamoDBApiCachingTable], is_caching: bool, primary_key_name: str): container_field_one_random_text_value: str = f"container_fieldOne_randomTextValue_{uuid4()}" container_field_two_random_text_value: str = f"container_fieldTwo_randomTextValue_{uuid4()}" first_table_container_fields_update_success: bool = first_table.update_multiple_fields( key_value=TEST_ACCOUNT_ID, setters=[ FieldSetter(field_path='container.nestedFieldOne', value_to_set=container_field_one_random_text_value), FieldSetter(field_path='container.nestedFieldTwo', value_to_set=container_field_two_random_text_value) ]) self.assertTrue(first_table_container_fields_update_success) if is_caching is True: self.assertTrue(first_table.commit_operations()) first_table.clear_cached_data() second_table_retrieved_container_fields_without_data_validation, query_metadata = second_table.query_multiple_fields( key_value=TEST_ACCOUNT_ID, data_validation=False, getters={ 'one': FieldGetter(field_path='container.nestedFieldOne'), 'two': FieldGetter(field_path='container.nestedFieldTwo'), }) second_table_retrieved_container_fields_without_data_validation: Dict[ str, Optional[Any]] self.assertEqual( { TEST_ACCOUNT_ID: { 'one': (container_field_one_random_text_value if is_caching is not True else { 'value': container_field_one_random_text_value, 'fromCache': False }), 'two': (container_field_two_random_text_value if is_caching is not True else { 'value': container_field_two_random_text_value, 'fromCache': False }) } }, second_table_retrieved_container_fields_without_data_validation) if is_caching is True: second_table.clear_cached_data() second_table_retrieved_container_fields_with_data_validation, query_metadata = second_table.query_multiple_fields( key_value=TEST_ACCOUNT_ID, data_validation=True, getters={ 'one': FieldGetter(field_path='container.nestedFieldOne'), 'two': FieldGetter(field_path='container.nestedFieldTwo'), }) second_table_retrieved_container_fields_with_data_validation: Dict[ str, Optional[int]] self.assertEqual( { TEST_ACCOUNT_ID: { 'one': (None if is_caching is not True else { 'value': None, 'fromCache': False }), 'two': (None if is_caching is not True else { 'value': None, 'fromCache': False }) } }, second_table_retrieved_container_fields_with_data_validation)
def test_set_then_get_pack_values_with_one_of_them_present_in_cache( self: unittest.TestCase, users_table: DynamoDBCachingTable or ExternalDynamoDBApiCachingTable): users_table.clear_cached_data_and_pending_operations() random_field_one_value = random.randint(0, 99) random_field_two_value = random.randint(100, 199) update_success = users_table.update_multiple_fields( key_value=TEST_ACCOUNT_ID, setters=[ FieldSetter(field_path='simpleValue', value_to_set=random_field_one_value), FieldSetter(field_path='simpleValue2', value_to_set=random_field_two_value) ]) self.assertTrue(update_success) users_table.commit_operations() users_table.clear_cached_data_and_pending_operations() # Caching the simpleValue field first_retrieved_first_value = users_table.get_field( key_value=TEST_ACCOUNT_ID, field_path='simpleValue') self.assertEqual({ 'value': random_field_one_value, 'fromCache': False }, first_retrieved_first_value) # With get_field function and multi selector get_field_response_data = users_table.get_field( key_value=TEST_ACCOUNT_ID, field_path='(simpleValue, simpleValue2)') self.assertEqual(get_field_response_data.get('simpleValue', None), { 'value': random_field_one_value, 'fromCache': True }) self.assertEqual(get_field_response_data.get('simpleValue2', None), { 'value': random_field_two_value, 'fromCache': False }) users_table.clear_cached_data_and_pending_operations() # Caching the simpleValue field second_retrieved_first_value = users_table.get_field( key_value=TEST_ACCOUNT_ID, field_path='simpleValue') self.assertEqual(second_retrieved_first_value, { 'fromCache': False, 'value': random_field_one_value }) # With get_multiple_fields function get_multiple_fields_response_data = users_table.get_multiple_fields( key_value=TEST_ACCOUNT_ID, getters={ 'one': FieldGetter(field_path='simpleValue'), 'two': FieldGetter(field_path='simpleValue2') }) self.assertEqual(get_multiple_fields_response_data.get('one', None), { 'value': random_field_one_value, 'fromCache': True }) self.assertEqual(get_multiple_fields_response_data.get('two', None), { 'value': random_field_two_value, 'fromCache': False })