async def test_alter_traits_on_enti_attr_proj(self): """Test AlterTraits on an entity attribute""" test_name = 'test_alter_traits_on_enti_attr_proj' entity_name = 'NewPerson' corpus = ProjectionTestUtils.get_local_corpus( self.tests_subpath, test_name) # type: CdmCorpusDefinition corpus.storage.mount('traitGroup', LocalAdapter(self.trait_group_file_path)) for res_opt in self.res_opts_combinations: await ProjectionTestUtils.load_entity_for_resolution_option_and_save( self, corpus, test_name, self.tests_subpath, entity_name, res_opt) entity = await corpus.fetch_object_async( 'local:/{0}.cdm.json/{0}'.format(entity_name) ) # type: CdmEntityDefinition resolved_entity = await ProjectionTestUtils.get_resolved_entity( corpus, entity, ['structured']) self.assertEqual(5, len(resolved_entity.attributes)) self.validate_trait(resolved_entity.attributes[0], 'name', True) self.validate_trait(resolved_entity.attributes[1], 'age') self.validate_trait(resolved_entity.attributes[2], 'address') self.validate_trait(resolved_entity.attributes[3], 'phoneNumber') self.validate_trait(resolved_entity.attributes[4], 'email')
async def test_extends_entity_proj(self): """addSupportingAttribute on an entity definition""" test_name = 'test_extends_entity_proj' entity_name = 'NewPerson' corpus = ProjectionTestUtils.get_local_corpus( self.tests_subpath, test_name) # type: CdmCorpusDefinition for res_opt in self.res_opts_combinations: await ProjectionTestUtils.load_entity_for_resolution_option_and_save( self, corpus, test_name, self.tests_subpath, entity_name, res_opt) entity = await corpus.fetch_object_async( 'local:/{0}.cdm.json/{0}'.format(entity_name) ) # type: CdmEntityDefinition resolved_entity = await ProjectionTestUtils.get_resolved_entity( corpus, entity, []) # type: CdmEntityDefinition # Original set of attributes: ['name', 'age', 'address', 'phoneNumber', 'email'] # Supporting attribute: 'PersonInfo_display' (using extendsEntityResolutionGuidance) self.assertEqual(6, len(resolved_entity.attributes)) self.assertEqual('name', resolved_entity.attributes[0].name) self.assertEqual('age', resolved_entity.attributes[1].name) self.assertEqual('address', resolved_entity.attributes[2].name) self.assertEqual('phoneNumber', resolved_entity.attributes[3].name) self.assertEqual('email', resolved_entity.attributes[4].name) self.assertEqual('PersonInfo_display', resolved_entity.attributes[5].name) self.validate_in_support_of_attribute(resolved_entity.attributes[5], 'email')
async def test_type_attribute_proj(self): """Test resolving a type attribute with an add supporting attribute operation""" test_name = 'test_type_attribute_proj' entity_name = 'NewPerson' corpus = ProjectionTestUtils.get_local_corpus( self.tests_subpath, test_name) # type: CdmCorpusDefinition for res_opt in self.res_opts_combinations: await ProjectionTestUtils.load_entity_for_resolution_option_and_save( self, corpus, test_name, self.tests_subpath, entity_name, res_opt) entity = await corpus.fetch_object_async( 'local:/{0}.cdm.json/{0}'.format(entity_name) ) # type: CdmEntityDefinition resolved_entity = await ProjectionTestUtils.get_resolved_entity( corpus, entity, ['referenceOnly']) # type: CdmEntityDefinition # Original set of attributes: ["PersonInfo"] self.assertEqual(2, len(resolved_entity.attributes)) self.assertEqual('PersonInfo', resolved_entity.attributes[0].name) supporting_attribute = resolved_entity.attributes[ 1] # type: CdmTypeAttributeDefinition self.assertEqual('PersonInfo_display', supporting_attribute.name) self.validate_in_support_of_attribute(supporting_attribute, 'PersonInfo', False)
async def test_add_type_with_combine_proj(self): """AddTypeAttribute on an entity attribute (after a CombineAttributes)""" test_name = 'test_add_type_with_combine_proj' entity_name = 'Customer' corpus = ProjectionTestUtils.get_local_corpus(self.tests_subpath, test_name) for res_opt in self.res_opts_combinations: await ProjectionTestUtils.load_entity_for_resolution_option_and_save( self, corpus, test_name, self.tests_subpath, entity_name, res_opt) entity = await corpus.fetch_object_async( 'local:/{}.cdm.json/{}'.format(entity_name, entity_name)) resolved_entity = await ProjectionTestUtils.get_resolved_entity( corpus, entity, []) # Original set of attributes: ["emailId", "address", "isPrimary", "phoneId", "number", "socialId", "account"] # Merge ["emailId, "phoneId, "socialId"] into "contactId", type attribute: "contactType" self.assertEqual(6, len(resolved_entity.attributes)) self.assertEqual('address', resolved_entity.attributes[0].name) self.assertEqual('isPrimary', resolved_entity.attributes[1].name) self.assertEqual('number', resolved_entity.attributes[2].name) self.assertEqual('account', resolved_entity.attributes[3].name) self.assertEqual('contactId', resolved_entity.attributes[4].name) self.assertEqual('contactType', resolved_entity.attributes[5].name) self.assertEqual( 'is.linkedEntity.name', resolved_entity.attributes[5].applied_traits[4].named_reference)
async def test_combine_ops_nested_proj(self): """Nested projections with AddTypeAttribute and other operations""" test_name = 'test_combine_ops_nested_proj' entity_name = 'Customer' corpus = ProjectionTestUtils.get_local_corpus(self.tests_subpath, test_name) for res_opt in self.res_opts_combinations: await ProjectionTestUtils.load_entity_for_resolution_option_and_save( self, corpus, test_name, self.tests_subpath, entity_name, res_opt) entity = await corpus.fetch_object_async( 'local:/{}.cdm.json/{}'.format(entity_name, entity_name)) resolved_entity = await ProjectionTestUtils.get_resolved_entity( corpus, entity, []) # Original set of attributes: ["emailId", "address", "isPrimary", "phoneId", "number", "socialId", "account"] # Merge ["emailId, "phoneId, "socialId"] into "contactId", type attribute: "contactType", # rename ["contactId", "isPrimary"] as "new_{m}", include ["contactId", "new_isPrimary", "contactType"] self.assertEqual(3, len(resolved_entity.attributes)) self.assertEqual('new_contactId', resolved_entity.attributes[0].name) self.assertEqual('new_isPrimary', resolved_entity.attributes[1].name) self.assertEqual('contactType', resolved_entity.attributes[2].name) self.assertEqual( 'is.linkedEntity.name', resolved_entity.attributes[2].applied_traits[4].named_reference)
async def test_conditional_proj(self): """AddCountAttribute with a conditionn""" test_name = 'test_conditional_proj' entity_name = 'NewPerson' corpus = ProjectionTestUtils.get_local_corpus(self.tests_subpath, test_name) for res_opt in self.res_opts_combinations: await ProjectionTestUtils.load_entity_for_resolution_option_and_save( self, corpus, test_name, self.tests_subpath, entity_name, res_opt) entity = await corpus.fetch_object_async( 'local:/{}.cdm.json/{}'.format(entity_name, entity_name)) resolved_entity = await ProjectionTestUtils.get_resolved_entity( corpus, entity, []) # Original set of attributes: ["name", "age", "address", "phoneNumber", "email"] # Count attribute: "someCount" # Condition is false, so no Count attribute added self.assertEqual(5, len(resolved_entity.attributes)) self.assertEqual('name', resolved_entity.attributes[0].name) self.assertEqual('age', resolved_entity.attributes[1].name) self.assertEqual('address', resolved_entity.attributes[2].name) self.assertEqual('phoneNumber', resolved_entity.attributes[3].name) self.assertEqual('email', resolved_entity.attributes[4].name)
async def test_duplicate(self): """Two AddCountAttribute operations in a single projection using the same Count attribute""" test_name = 'test_duplicate' entity_name = 'NewPerson' corpus = ProjectionTestUtils.get_local_corpus(self.tests_subpath, test_name) for res_opt in self.res_opts_combinations: await ProjectionTestUtils.load_entity_for_resolution_option_and_save( self, corpus, test_name, self.tests_subpath, entity_name, res_opt) entity = await corpus.fetch_object_async( 'local:/{}.cdm.json/{}'.format(entity_name, entity_name)) resolved_entity = await ProjectionTestUtils.get_resolved_entity( corpus, entity, []) # Original set of attributes: ["name", "age", "address", "phoneNumber", "email"] # Count attribute: "someCount", count attribute: "someCount" # "someCount" should get merged into one self.assertEqual(6, len(resolved_entity.attributes)) self.assertEqual('name', resolved_entity.attributes[0].name) self.assertEqual('age', resolved_entity.attributes[1].name) self.assertEqual('address', resolved_entity.attributes[2].name) self.assertEqual('phoneNumber', resolved_entity.attributes[3].name) self.assertEqual('email', resolved_entity.attributes[4].name) self.assertEqual('someCount', resolved_entity.attributes[5].name) self.assertEqual( 'is.linkedEntity.array.count', resolved_entity.attributes[5].applied_traits[1].named_reference)
async def test_array_source_proj(self): """ArrayExpansion on an array source""" test_name = 'test_array_source_proj' entity_name = 'FriendGroup' corpus = ProjectionTestUtils.get_local_corpus(self.tests_subpath, test_name) for res_opt in self.res_opts_combinations: await ProjectionTestUtils.load_entity_for_resolution_option_and_save(self, corpus, test_name, self.tests_subpath, entity_name, res_opt) entity = await corpus.fetch_object_async('local:/{}.cdm.json/{}'.format(entity_name, entity_name)) resolved_entity = await ProjectionTestUtils.get_resolved_entity(corpus, entity, []) # Original set of attributes: ["personCount", "name1", "age1", "address1", "name2", "age2", "address2"] # Expand 1...2, renameFormat = {m}_{o} self.assertEqual(14, len(resolved_entity.attributes)) self.assertEqual('personCount_1', resolved_entity.attributes[0].name) self.assertEqual('name1_1', resolved_entity.attributes[1].name) self.assertEqual('age1_1', resolved_entity.attributes[2].name) self.assertEqual('address1_1', resolved_entity.attributes[3].name) self.assertEqual('name2_1', resolved_entity.attributes[4].name) self.assertEqual('age2_1', resolved_entity.attributes[5].name) self.assertEqual('address2_1', resolved_entity.attributes[6].name) self.assertEqual('personCount_2', resolved_entity.attributes[7].name) self.assertEqual('name1_2', resolved_entity.attributes[8].name) self.assertEqual('age1_2', resolved_entity.attributes[9].name) self.assertEqual('address1_2', resolved_entity.attributes[10].name) self.assertEqual('name2_2', resolved_entity.attributes[11].name) self.assertEqual('age2_2', resolved_entity.attributes[12].name) self.assertEqual('address2_2', resolved_entity.attributes[13].name)
async def test_group(self): """Expansion on an entity with an attribute group""" test_name = 'test_group' entity_name = 'ThreeMusketeers' corpus = ProjectionTestUtils.get_local_corpus(self.tests_subpath, test_name) for res_opt in self.res_opts_combinations: await ProjectionTestUtils.load_entity_for_resolution_option_and_save(self, corpus, test_name, self.tests_subpath, entity_name, res_opt) entity = await corpus.fetch_object_async('local:/{}.cdm.json/{}'.format(entity_name, entity_name)) resolved_entity = await ProjectionTestUtils.get_resolved_entity(corpus, entity, []) # Original set of attributes: ["name", "age", "address"] # Expand 1...3, renameFormat = {m}{o} self.assertEqual(10, len(resolved_entity.attributes)) self.assertEqual('count', resolved_entity.attributes[0].name) self.assertEqual('name1', resolved_entity.attributes[1].name) self.assertEqual('age1', resolved_entity.attributes[2].name) self.assertEqual('address1', resolved_entity.attributes[3].name) self.assertEqual('name2', resolved_entity.attributes[4].name) self.assertEqual('age2', resolved_entity.attributes[5].name) self.assertEqual('address2', resolved_entity.attributes[6].name) self.assertEqual('name3', resolved_entity.attributes[7].name) self.assertEqual('age3', resolved_entity.attributes[8].name) self.assertEqual('address3', resolved_entity.attributes[9].name)
async def test_polymorphic_proj(self): """ArrayExpansion on a polymorphic source""" test_name = 'test_polymorphic_proj' entity_name = 'BusinessPerson' corpus = ProjectionTestUtils.get_local_corpus(self.tests_subpath, test_name) for res_opt in self.res_opts_combinations: if 'structured' in res_opt: # Array expansion is not supported on an attribute group yet. continue await ProjectionTestUtils.load_entity_for_resolution_option_and_save(self, corpus, test_name, self.tests_subpath, entity_name, res_opt) entity = await corpus.fetch_object_async('local:/{}.cdm.json/{}'.format(entity_name, entity_name)) resolved_entity = await ProjectionTestUtils.get_resolved_entity(corpus, entity, []) # Original set of attributes: ["emailId", "address", "isPrimary", "phoneId", "number"] # Expand 1...2, renameFormat = {m}{o} self.assertEqual(10, len(resolved_entity.attributes)) self.assertEqual('emailId1', resolved_entity.attributes[0].name) self.assertEqual('address1', resolved_entity.attributes[1].name) self.assertEqual('isPrimary1', resolved_entity.attributes[2].name) self.assertEqual('phoneId1', resolved_entity.attributes[3].name) self.assertEqual('number1', resolved_entity.attributes[4].name) self.assertEqual('emailId2', resolved_entity.attributes[5].name) self.assertEqual('address2', resolved_entity.attributes[6].name) self.assertEqual('isPrimary2', resolved_entity.attributes[7].name) self.assertEqual('phoneId2', resolved_entity.attributes[8].name) self.assertEqual('number2', resolved_entity.attributes[9].name)
async def test_array_source(self): """ Expansion on an array source NOTE: This is not supported in resolution guidance due to ordinals from a previous resolution guidance not being removed for the next resolution guidance, resulting in ordinals being skipped over in the new resolution guidance as it thinks it has already done that round """ test_name = 'test_array_source' entity_name = 'FriendGroup' corpus = ProjectionTestUtils.get_local_corpus(self.tests_subpath, test_name) for res_opt in self.res_opts_combinations: await ProjectionTestUtils.load_entity_for_resolution_option_and_save(self, corpus, test_name, self.tests_subpath, entity_name, res_opt) entity = await corpus.fetch_object_async('local:/{}.cdm.json/{}'.format(entity_name, entity_name)) resolved_entity = await ProjectionTestUtils.get_resolved_entity(corpus, entity, []) # Original set of attributes: ["personCount", "name1", "age1", "address1", "name2", "age2", "address2"] # Expand 1...2, renameFormat = {m}_{o} # Since resolution guidance doesn't support doing an expansion on an array source, we end up with the # following result where it skips expanding attributes with the same ordinal (ex. name1_1, name2_2) self.assertEqual(9, len(resolved_entity.attributes)) self.assertEqual('count_', resolved_entity.attributes[0].name) self.assertEqual('personCount_1', resolved_entity.attributes[1].name) self.assertEqual('name2_1', resolved_entity.attributes[2].name) self.assertEqual('age2_1', resolved_entity.attributes[3].name) self.assertEqual('address2_1', resolved_entity.attributes[4].name) self.assertEqual('personCount_2', resolved_entity.attributes[5].name) self.assertEqual('name1_2', resolved_entity.attributes[6].name) self.assertEqual('age1_2', resolved_entity.attributes[7].name) self.assertEqual('address1_2', resolved_entity.attributes[8].name)
async def test_start_GT_end_ordinal(self): """Start ordinal greater than end ordinal""" test_name = 'test_start_GT_end_ordinal' entity_name = 'ThreeMusketeers' corpus = ProjectionTestUtils.get_local_corpus(self.tests_subpath, test_name) # A warning should be logged when startOrdinal > endOrdinal def callback(level: 'CdmStatusLevel', message: str): if message.find('startOrdinal 2 should not be greater than endOrdinal 0') == -1: self.fail('Some unexpected failure - {}!'.format(message)) corpus.set_event_callback(callback, CdmStatusLevel.WARNING) for res_opt in self.res_opts_combinations: await ProjectionTestUtils.load_entity_for_resolution_option_and_save(self, corpus, test_name, self.tests_subpath, entity_name, res_opt) entity = await corpus.fetch_object_async('local:/{}.cdm.json/{}'.format(entity_name, entity_name)) resolved_entity = await ProjectionTestUtils.get_resolved_entity(corpus, entity, []) # Original set of attributes: ["name", "age", "address"] # Expand 2...0, renameFormat = {m}{o} # No array expansion happens here so the input just passes through self.assertEqual(3, len(resolved_entity.attributes)) self.assertEqual('name', resolved_entity.attributes[0].name) self.assertEqual('age', resolved_entity.attributes[1].name) self.assertEqual('address', resolved_entity.attributes[2].name)
async def test_negative_start_ordinal(self): """Start and end ordinals of -2...2""" test_name = 'test_negative_start_ordinal' entity_name = 'ThreeMusketeers' corpus = ProjectionTestUtils.get_local_corpus(self.tests_subpath, test_name) for res_opt in self.res_opts_combinations: await ProjectionTestUtils.load_entity_for_resolution_option_and_save(self, corpus, test_name, self.tests_subpath, entity_name, res_opt) entity = await corpus.fetch_object_async('local:/{}.cdm.json/{}'.format(entity_name, entity_name)) resolved_entity = await ProjectionTestUtils.get_resolved_entity(corpus, entity, []) # Original set of attributes: ["name", "age", "address"] # Expand -2...2, renameFormat = {m}{o} # Since we don't allow negative ordinals, output should be 0...2 self.assertEqual(9, len(resolved_entity.attributes)) self.assertEqual('name0', resolved_entity.attributes[0].name) self.assertEqual('age0', resolved_entity.attributes[1].name) self.assertEqual('address0', resolved_entity.attributes[2].name) self.assertEqual('name1', resolved_entity.attributes[3].name) self.assertEqual('age1', resolved_entity.attributes[4].name) self.assertEqual('address1', resolved_entity.attributes[5].name) self.assertEqual('name2', resolved_entity.attributes[6].name) self.assertEqual('age2', resolved_entity.attributes[7].name) self.assertEqual('address2', resolved_entity.attributes[8].name)
async def test_nested_proj(self): """Nested projections with ArrayExpansion""" test_name = 'test_nested_proj' entity_name = 'ThreeMusketeers' corpus = ProjectionTestUtils.get_local_corpus(self.tests_subpath, test_name) for res_opt in self.res_opts_combinations: await ProjectionTestUtils.load_entity_for_resolution_option_and_save(self, corpus, test_name, self.tests_subpath, entity_name, res_opt) entity = await corpus.fetch_object_async('local:/{}.cdm.json/{}'.format(entity_name, entity_name)) resolved_entity = await ProjectionTestUtils.get_resolved_entity(corpus, entity, []) # Original set of attributes: ["name", "age", "address"] # Expand 1...3 and then 1...2, renameFormat = {m}_{o} self.assertEqual(18, len(resolved_entity.attributes)) self.assertEqual('name_1_1', resolved_entity.attributes[0].name) self.assertEqual('age_1_1', resolved_entity.attributes[1].name) self.assertEqual('address_1_1', resolved_entity.attributes[2].name) self.assertEqual('name_2_1', resolved_entity.attributes[3].name) self.assertEqual('age_2_1', resolved_entity.attributes[4].name) self.assertEqual('address_2_1', resolved_entity.attributes[5].name) self.assertEqual('name_3_1', resolved_entity.attributes[6].name) self.assertEqual('age_3_1', resolved_entity.attributes[7].name) self.assertEqual('address_3_1', resolved_entity.attributes[8].name) self.assertEqual('name_1_2', resolved_entity.attributes[9].name) self.assertEqual('age_1_2', resolved_entity.attributes[10].name) self.assertEqual('address_1_2', resolved_entity.attributes[11].name) self.assertEqual('name_2_2', resolved_entity.attributes[12].name) self.assertEqual('age_2_2', resolved_entity.attributes[13].name) self.assertEqual('address_2_2', resolved_entity.attributes[14].name) self.assertEqual('name_3_2', resolved_entity.attributes[15].name) self.assertEqual('age_3_2', resolved_entity.attributes[16].name) self.assertEqual('address_3_2', resolved_entity.attributes[17].name)
async def test_combine_ops(self): """AddCountAttribute with other operations in the same projection""" test_name = 'test_combine_ops' entity_name = 'NewPerson' corpus = ProjectionTestUtils.get_local_corpus(self.tests_subpath, test_name) for res_opt in self.res_opts_combinations: await ProjectionTestUtils.load_entity_for_resolution_option_and_save( self, corpus, test_name, self.tests_subpath, entity_name, res_opt) entity = await corpus.fetch_object_async( 'local:/{}.cdm.json/{}'.format(entity_name, entity_name)) resolved_entity = await ProjectionTestUtils.get_resolved_entity( corpus, entity, []) # Original set of attributes: ["name", "age", "address", "phoneNumber", "email"] # Count attribute: "someCount", count attribute: "anotherCount", rename "name" to "firstName" self.assertEqual(8, len(resolved_entity.attributes)) self.assertEqual('name', resolved_entity.attributes[0].name) self.assertEqual('age', resolved_entity.attributes[1].name) self.assertEqual('address', resolved_entity.attributes[2].name) self.assertEqual('phoneNumber', resolved_entity.attributes[3].name) self.assertEqual('email', resolved_entity.attributes[4].name) self.assertEqual('someCount', resolved_entity.attributes[5].name) self.assertEqual( 'is.linkedEntity.array.count', resolved_entity.attributes[5].applied_traits[1].named_reference) self.assertEqual('anotherCount', resolved_entity.attributes[6].name) self.assertEqual( 'is.linkedEntity.array.count', resolved_entity.attributes[6].applied_traits[1].named_reference) self.assertEqual('firstName', resolved_entity.attributes[7].name)
async def test_with_nested_array_expansion(self): """Nested projections with ArrayExpansion, then AddCountAttribute, and then RenameAttributes""" test_name = 'test_with_nested_array_expansion' entity_name = 'NewPerson' corpus = ProjectionTestUtils.get_local_corpus(self.tests_subpath, test_name) for res_opt in self.res_opts_combinations: await ProjectionTestUtils.load_entity_for_resolution_option_and_save( self, corpus, test_name, self.tests_subpath, entity_name, res_opt) entity = await corpus.fetch_object_async( 'local:/{}.cdm.json/{}'.format(entity_name, entity_name)) resolved_entity = await ProjectionTestUtils.get_resolved_entity( corpus, entity, []) # Original set of attributes: ["name", "age", "address", "phoneNumber", "email"] # Count attribute: "personCount", expand 1...2, renameFormat = {m}{o} self.assertEqual(11, len(resolved_entity.attributes)) self.assertEqual('name1', resolved_entity.attributes[0].name) self.assertEqual('age1', resolved_entity.attributes[1].name) self.assertEqual('address1', resolved_entity.attributes[2].name) self.assertEqual('phoneNumber1', resolved_entity.attributes[3].name) self.assertEqual('email1', resolved_entity.attributes[4].name) self.assertEqual('name2', resolved_entity.attributes[5].name) self.assertEqual('age2', resolved_entity.attributes[6].name) self.assertEqual('address2', resolved_entity.attributes[7].name) self.assertEqual('phoneNumber2', resolved_entity.attributes[8].name) self.assertEqual('email2', resolved_entity.attributes[9].name) self.assertEqual('personCount', resolved_entity.attributes[10].name) self.assertEqual( 'is.linkedEntity.array.count', resolved_entity.attributes[10].applied_traits[1].named_reference)
async def test_combine_ops_nested_proj(self): """Nested projections with AddCountAttribute and other operations""" test_name = 'test_combine_ops_nested_proj' entity_name = 'NewPerson' corpus = ProjectionTestUtils.get_local_corpus(self.tests_subpath, test_name) for res_opt in self.res_opts_combinations: await ProjectionTestUtils.load_entity_for_resolution_option_and_save( self, corpus, test_name, self.tests_subpath, entity_name, res_opt) entity = await corpus.fetch_object_async( 'local:/{}.cdm.json/{}'.format(entity_name, entity_name)) resolved_entity = await ProjectionTestUtils.get_resolved_entity( corpus, entity, []) # Original set of attributes: ["name", "age", "address", "phoneNumber", "email"] # Count attribute: "someCount", renameFormat = new_{m}, include ["new_name", "age", "new_someCount"] self.assertEqual(3, len(resolved_entity.attributes)) self.assertEqual('new_name', resolved_entity.attributes[0].name) self.assertEqual('new_age', resolved_entity.attributes[1].name) self.assertEqual('new_someCount', resolved_entity.attributes[2].name) self.assertEqual( 'is.linkedEntity.array.count', resolved_entity.attributes[2].applied_traits[1].named_reference)
async def test_nested_proj_using_object_model(self): """Test for creating nested projections with ExcludeAttributes operations using the object model""" corpus = ProjectionTestUtils.get_local_corpus( self.tests_subpath, 'test_nested_proj_using_object_model') corpus.storage.mount( 'local', LocalAdapter( TestHelper.get_actual_output_folder_path( self.tests_subpath, 'test_nested_proj_using_object_model'))) local_root = corpus.storage.fetch_root_folder('local') # Create an entity entity = ProjectionTestUtils.create_entity(corpus, local_root) # Create a projection projection = ProjectionTestUtils.create_projection(corpus, local_root) # Create an ExcludeAttributes operation exclude_attrs_op = corpus.make_object( CdmObjectType.OPERATION_EXCLUDE_ATTRIBUTES_DEF) exclude_attrs_op.exclude_attributes = ['id', 'date'] projection.operations.append(exclude_attrs_op) # Create an entity reference to hold this projection projection_entity_ref = corpus.make_object(CdmObjectType.ENTITY_REF, None) projection_entity_ref.explicit_reference = projection # Create another projection that uses the previous projection as its source projection2 = corpus.make_object(CdmObjectType.PROJECTION_DEF) projection2.source = projection_entity_ref # Create an ExcludeAttributes operation exclude_attrs_op2 = corpus.make_object( CdmObjectType.OPERATION_EXCLUDE_ATTRIBUTES_DEF) exclude_attrs_op2.exclude_attributes = ['value'] projection2.operations.append(exclude_attrs_op2) # Create an entity reference to hold this projection projection_entity_ref2 = corpus.make_object(CdmObjectType.ENTITY_REF, None) projection_entity_ref2.explicit_reference = projection2 # Create an entity attribute that contains this projection and add this to the entity entity_attribute = corpus.make_object( CdmObjectType.ENTITY_ATTRIBUTE_DEF, 'TestEntityAttribute') entity_attribute.entity = projection_entity_ref2 entity.attributes.append(entity_attribute) # Resolve the entity resolved_entity = await entity.create_resolved_entity_async( 'Resolved_{}.cdm.json'.format(entity.entity_name), None, local_root) # Verify correctness of the resolved attributes after running the ExcludeAttributes operations # Original set of attributes: ['id', 'name', 'value', 'date'] # Excluded attributes: ['id', 'date'], ['value'] self.assertEqual(1, len(resolved_entity.attributes)) self.assertEqual('name', resolved_entity.attributes[0].name)
async def test_group(self): """CountAttribute on an entity with an attribute group""" test_name = 'test_group' entity_name = 'NewPerson' corpus = ProjectionTestUtils.get_local_corpus(self.tests_subpath, test_name) for res_opt in self.res_opts_combinations: await ProjectionTestUtils.load_entity_for_resolution_option_and_save( self, corpus, test_name, self.tests_subpath, entity_name, res_opt) entity = await corpus.fetch_object_async( 'local:/{}.cdm.json/{}'.format(entity_name, entity_name)) resolved_entity = await ProjectionTestUtils.get_resolved_entity( corpus, entity, []) # Original set of attributes: ["name", "age", "address", "phoneNumber", "email"] # Count attribute: "someCount" # For resolution guidance, CountAttribute has to be used with Expansion so we do an Expansion of 1...1 here self.assertEqual(6, len(resolved_entity.attributes)) self.assertEqual('someCount', resolved_entity.attributes[0].name) self.assertEqual( 'is.linkedEntity.array.count', resolved_entity.attributes[0].applied_traits[1].named_reference) self.assertEqual('name1', resolved_entity.attributes[1].name) self.assertEqual('age1', resolved_entity.attributes[2].name) self.assertEqual('address1', resolved_entity.attributes[3].name) self.assertEqual('phoneNumber1', resolved_entity.attributes[4].name) self.assertEqual('email1', resolved_entity.attributes[5].name)
async def test_polymorphic(self): """SelectsSomeAvoidNames on a polymorphic source""" test_name = 'test_polymorphic' entity_name = 'BusinessPerson' corpus = ProjectionTestUtils.get_local_corpus(self.tests_subpath, test_name) for res_opt in self.res_opts_combinations: await ProjectionTestUtils.load_entity_for_resolution_option_and_save( self, corpus, test_name, self.tests_subpath, entity_name, res_opt) entity = await corpus.fetch_object_async( 'local:/{}.cdm.json/{}'.format(entity_name, entity_name)) resolved_entity = await ProjectionTestUtils.get_resolved_entity( corpus, entity, []) # Original set of attributes: ['emailId', 'address', 'isPrimary', 'phoneId', 'number', 'socialId', 'account'] # Excluded attributes: ['socialId', 'account'] self.assertEqual(5, len(resolved_entity.attributes)) self.assertEqual('emailId', resolved_entity.attributes[0].name) self.assertEqual('address', resolved_entity.attributes[1].name) self.assertEqual('isPrimary', resolved_entity.attributes[2].name) self.assertEqual('phoneId', resolved_entity.attributes[3].name) self.assertEqual('number', resolved_entity.attributes[4].name)
async def test_extends_entity(self): """SelectedTypeAttribute on an entity definition""" test_name = 'test_extends_entity' entity_name = 'Customer' corpus = ProjectionTestUtils.get_local_corpus(self.tests_subpath, test_name) for res_opt in self.res_opts_combinations: await ProjectionTestUtils.load_entity_for_resolution_option_and_save( self, corpus, test_name, self.tests_subpath, entity_name, res_opt) entity = await corpus.fetch_object_async( 'local:/{}.cdm.json/{}'.format(entity_name, entity_name)) resolved_entity = await ProjectionTestUtils.get_resolved_entity( corpus, entity, []) # Original set of attributes: ["emailId", "address", "isPrimary", "phoneId", "number", "socialId", "account"] # Type attribute: "someType" (using extendsEntityResolutionGuidance) self.assertEqual(8, len(resolved_entity.attributes)) self.assertEqual('emailId', resolved_entity.attributes[0].name) self.assertEqual('address', resolved_entity.attributes[1].name) self.assertEqual('isPrimary', resolved_entity.attributes[2].name) self.assertEqual('phoneId', resolved_entity.attributes[3].name) self.assertEqual('number', resolved_entity.attributes[4].name) self.assertEqual('socialId', resolved_entity.attributes[5].name) self.assertEqual('account', resolved_entity.attributes[6].name) self.assertEqual('someType', resolved_entity.attributes[7].name) self.assertEqual( 'is.linkedEntity.name', resolved_entity.attributes[7].applied_traits[4].named_reference)
async def test_array_source_rename(self): """SelectsSomeAvoidNames on an array source that has renameFormat = '{m}'""" test_name = 'test_array_source_rename' entity_name = 'FriendGroup' corpus = ProjectionTestUtils.get_local_corpus(self.tests_subpath, test_name) for res_opt in self.res_opts_combinations: await ProjectionTestUtils.load_entity_for_resolution_option_and_save( self, corpus, test_name, self.tests_subpath, entity_name, res_opt) entity = await corpus.fetch_object_async( 'local:/{}.cdm.json/{}'.format(entity_name, entity_name)) resolved_entity = await ProjectionTestUtils.get_resolved_entity( corpus, entity, []) # Original set of attributes: ['personCount', 'name1', 'age1', 'address1', 'phoneNumber1', 'email1', ..., 'email3'] (16 total) # Excluded attributes: ['age1', 'age2', 'age3'] self.assertEqual(13, len(resolved_entity.attributes)) self.assertEqual('personCount', resolved_entity.attributes[0].name) self.assertEqual('name1', resolved_entity.attributes[1].name) self.assertEqual('address1', resolved_entity.attributes[2].name) self.assertEqual('phoneNumber1', resolved_entity.attributes[3].name) self.assertEqual('email1', resolved_entity.attributes[4].name) self.assertEqual('name2', resolved_entity.attributes[5].name) self.assertEqual('address2', resolved_entity.attributes[6].name) self.assertEqual('phoneNumber2', resolved_entity.attributes[7].name) self.assertEqual('email2', resolved_entity.attributes[8].name) self.assertEqual('name3', resolved_entity.attributes[9].name) self.assertEqual('address3', resolved_entity.attributes[10].name) self.assertEqual('phoneNumber3', resolved_entity.attributes[11].name) self.assertEqual('email3', resolved_entity.attributes[12].name)
async def test_combine_ops_proj(self): """AddTypeAttribute with other operations in the same projection""" test_name = 'test_combine_ops_proj' entity_name = 'Customer' corpus = ProjectionTestUtils.get_local_corpus(self.tests_subpath, test_name) for res_opt in self.res_opts_combinations: await ProjectionTestUtils.load_entity_for_resolution_option_and_save( self, corpus, test_name, self.tests_subpath, entity_name, res_opt) entity = await corpus.fetch_object_async( 'local:/{}.cdm.json/{}'.format(entity_name, entity_name)) resolved_entity = await ProjectionTestUtils.get_resolved_entity( corpus, entity, []) # Original set of attributes: ["emailId", "address", "isPrimary", "phoneId", "number", "socialId", "account"] # Type attribute: "someType", rename "address" to "homeAddress" self.assertEqual(9, len(resolved_entity.attributes)) self.assertEqual('emailId', resolved_entity.attributes[0].name) self.assertEqual('address', resolved_entity.attributes[1].name) self.assertEqual('isPrimary', resolved_entity.attributes[2].name) self.assertEqual('phoneId', resolved_entity.attributes[3].name) self.assertEqual('number', resolved_entity.attributes[4].name) self.assertEqual('socialId', resolved_entity.attributes[5].name) self.assertEqual('account', resolved_entity.attributes[6].name) self.assertEqual('someType', resolved_entity.attributes[7].name) self.assertEqual( 'is.linkedEntity.name', resolved_entity.attributes[7].applied_traits[4].named_reference) self.assertEqual('homeAddress', resolved_entity.attributes[8].name)
async def test_empty_exclude(self): """ExcludeAttributes with an empty exclude attributes list""" test_name = 'test_empty_exclude' entity_name = 'NewPerson' corpus = ProjectionTestUtils.get_local_corpus(self.tests_subpath, test_name) for res_opt in self.res_opts_combinations: await ProjectionTestUtils.load_entity_for_resolution_option_and_save( self, corpus, test_name, self.tests_subpath, entity_name, res_opt) entity = await corpus.fetch_object_async( 'local:/{}.cdm.json/{}'.format(entity_name, entity_name)) resolved_entity = await ProjectionTestUtils.get_resolved_entity( corpus, entity, []) # Original set of attributes: ['name', 'age', 'address', 'phoneNumber', 'email'] # Excluded attributes: [] self.assertEqual(5, len(resolved_entity.attributes)) self.assertEqual('name', resolved_entity.attributes[0].name) self.assertEqual('age', resolved_entity.attributes[1].name) self.assertEqual('address', resolved_entity.attributes[2].name) self.assertEqual('phoneNumber', resolved_entity.attributes[3].name) self.assertEqual('email', resolved_entity.attributes[4].name)
async def test_conditional_proj(self): """AddTypeAttribute with a condition""" test_name = 'test_conditional_proj' entity_name = 'Customer' corpus = ProjectionTestUtils.get_local_corpus(self.tests_subpath, test_name) for res_opt in self.res_opts_combinations: await ProjectionTestUtils.load_entity_for_resolution_option_and_save( self, corpus, test_name, self.tests_subpath, entity_name, res_opt) entity = await corpus.fetch_object_async( 'local:/{}.cdm.json/{}'.format(entity_name, entity_name)) resolved_entity = await ProjectionTestUtils.get_resolved_entity( corpus, entity, []) # Original set of attributes: ["emailId", "address", "isPrimary", "phoneId", "number", "socialId", "account"] # Merge ["emailId, "phoneId, "socialId"] into "contactId", type attribute: "contactType" # Condition for projection containing AddTypeAttribute is false, so no Type attribute is created self.assertEqual(5, len(resolved_entity.attributes)) self.assertEqual('address', resolved_entity.attributes[0].name) self.assertEqual('isPrimary', resolved_entity.attributes[1].name) self.assertEqual('number', resolved_entity.attributes[2].name) self.assertEqual('account', resolved_entity.attributes[3].name) self.assertEqual('contactId', resolved_entity.attributes[4].name)
async def test_EA_name_proj(self): """ ExcludeAttributes with an entity attribute name on an inline entity reference that contains entity attributes This is testing that, for the case of the structured directive, we can filter using the name of an entity attribute in the inline entity reference to exclude the entire entity attribute group """ test_name = 'test_EA_name_proj' entity_name = 'NewPerson' corpus = ProjectionTestUtils.get_local_corpus(self.tests_subpath, test_name) for res_opt in self.res_opts_combinations: await ProjectionTestUtils.load_entity_for_resolution_option_and_save( self, corpus, test_name, self.tests_subpath, entity_name, res_opt) entity = await corpus.fetch_object_async( 'local:/{}.cdm.json/{}'.format(entity_name, entity_name)) resolved_entity = await ProjectionTestUtils.get_resolved_entity( corpus, entity, ['structured']) # Original set of attributes: ['name', 'age', 'address', 'phoneNumber', 'email', 'title', 'company', 'tenure'] # Excluded attributes: ['OccupationInfo'] (name of entity attribute that contains 'title', 'company', 'tenure') self.assertEqual( 1, len(resolved_entity.attributes) ) # attribute group created because of structured directive att_group = resolved_entity.attributes[0].explicit_reference self.assertEqual(5, len(att_group.members)) self.assertEqual('name', att_group.members[0].name) self.assertEqual('age', att_group.members[1].name) self.assertEqual('address', att_group.members[2].name) self.assertEqual('phoneNumber', att_group.members[3].name) self.assertEqual('email', att_group.members[4].name)
async def test_nested_proj(self): """Nested replaceAsForeignKey with addSupporingAttribute""" test_name = 'test_nested_proj' entity_name = 'NewPerson' corpus = ProjectionTestUtils.get_local_corpus( self.tests_subpath, test_name) # type: CdmCorpusDefinition for res_opt in self.res_opts_combinations: await ProjectionTestUtils.load_entity_for_resolution_option_and_save( self, corpus, test_name, self.tests_subpath, entity_name, res_opt) entity = await corpus.fetch_object_async( 'local:/{0}.cdm.json/{0}'.format(entity_name) ) # type: CdmEntityDefinition resolved_entity = await ProjectionTestUtils.get_resolved_entity( corpus, entity, ['referenceOnly']) # type: CdmEntityDefinition # Original set of attributes: ['name', 'age', 'address', 'phoneNumber', 'email'] self.assertEqual(2, len(resolved_entity.attributes)) self.assertEqual('personId', resolved_entity.attributes[0].name) self.assertEqual('PersonInfo_display', resolved_entity.attributes[1].name) self.validate_in_support_of_attribute(resolved_entity.attributes[1], 'personId')
async def test_extends_entity(self): """CountAttribute on an entity definition""" test_name = 'test_extends_entity' entity_name = 'NewPerson' corpus = ProjectionTestUtils.get_local_corpus(self.tests_subpath, test_name) for res_opt in self.res_opts_combinations: await ProjectionTestUtils.load_entity_for_resolution_option_and_save( self, corpus, test_name, self.tests_subpath, entity_name, res_opt) entity = await corpus.fetch_object_async( 'local:/{}.cdm.json/{}'.format(entity_name, entity_name)) resolved_entity = await ProjectionTestUtils.get_resolved_entity( corpus, entity, []) # Original set of attributes: ["name", "age", "address", "phoneNumber", "email"] # Count attribute: "someCount" # For resolution guidance, CountAttribute has to be used with Expansion so we do an Expansion of 1...1 here # ExtendsEntityResolutionGuidance doesn't support doing expansions, so we only get the Count attribute self.assertEqual(1, len(resolved_entity.attributes)) self.assertEqual('someCount', resolved_entity.attributes[0].name) self.assertEqual( 'is.linkedEntity.array.count', resolved_entity.attributes[0].applied_traits[1].named_reference)
async def test_combine_ops_proj(self): """AddSupportingAttribute with replaceAsForeignKey operation in the same projection""" test_name = 'test_combine_ops_proj' entity_name = 'NewPerson' corpus = ProjectionTestUtils.get_local_corpus( self.tests_subpath, test_name) # type: CdmCorpusDefinition for res_opt in self.res_opts_combinations: await ProjectionTestUtils.load_entity_for_resolution_option_and_save( self, corpus, test_name, self.tests_subpath, entity_name, res_opt) entity = await corpus.fetch_object_async( 'local:/{0}.cdm.json/{0}'.format(entity_name) ) # type: CdmEntityDefinition resolved_entity = await ProjectionTestUtils.get_resolved_entity( corpus, entity, []) # type: CdmEntityDefinition # Original set of attributes: ['name', 'age', 'address', 'phoneNumber', 'email'] # Supporting attribute: 'PersonInfo_display', rename 'address' to 'homeAddress' self.assertEqual(7, len(resolved_entity.attributes)) self.assertEqual('name', resolved_entity.attributes[0].name) self.assertEqual('age', resolved_entity.attributes[1].name) self.assertEqual('homeAddress', resolved_entity.attributes[2].name) self.assertEqual('phoneNumber', resolved_entity.attributes[3].name) self.assertEqual('email', resolved_entity.attributes[4].name) self.assertEqual('address', resolved_entity.attributes[5].name) self.assertEqual('PersonInfo_display', resolved_entity.attributes[6].name) self.validate_in_support_of_attribute(resolved_entity.attributes[6], 'email')
async def test_combine_ops_nested_proj(self): """Test AlterTraits operation nested with IncludeAttributes and RenameAttribute""" test_name = 'test_combine_ops_nested_proj' entity_name = 'NewPerson' corpus = ProjectionTestUtils.get_local_corpus( self.tests_subpath, test_name) # type: CdmCorpusDefinition corpus.storage.mount('traitGroup', LocalAdapter(self.trait_group_file_path)) for res_opt in self.res_opts_combinations: await ProjectionTestUtils.load_entity_for_resolution_option_and_save( self, corpus, test_name, self.tests_subpath, entity_name, res_opt) entity = await corpus.fetch_object_async( 'local:/{0}.cdm.json/{0}'.format(entity_name) ) # type: CdmEntityDefinition resolved_entity = await ProjectionTestUtils.get_resolved_entity( corpus, entity, []) # Original set of attributes: ["name", "age", "address", "phoneNumber", "email"] # Include attributes: ["age", "phoneNumber", "name"] # Add attribute: ["newName"] # alter traits on ["newName", "name", + { "means.TraitG100" , "JobTitleBase" } - { "means.TraitG300" } ] # Rename attribute ["newName" -> "renaming-{m}" ] # alter traits on ["renaming-newName", + { "means.TraitG4(precision:5, scale:15)" } ] self.assertEqual(4, len(resolved_entity.attributes)) self.validate_trait(resolved_entity.attributes[0], 'age', False, True) self.validate_trait(resolved_entity.attributes[1], 'phoneNumber', False, True) self.validate_trait(resolved_entity.attributes[2], 'name') self.validate_trait(resolved_entity.attributes[3], 'renaming-newName', True)