import itertools import random from datetime import date from atlas_um.pgdb import ( pgdb, DNAAccount, DNAAccountActivity, ClaimName, ClaimValue, ResourceGroup, ) from atlas_um.pgdb.associations import dna_account_claim_table from atlas_um.pgdb.dna_account import DNAAccountStatuses from tests.atlas_um.factories import ( DNAAccountFactory, ResourceGroupFactory, ClaimNameFactory, ClaimValueFactory, ) class TestDNAAccount: def test_insert_minimum(self, pgdb_session, faker): fake_sub = faker.pystr() dna_account = DNAAccount(sub=fake_sub) pgdb_session.add(dna_account) pgdb_session.commit() def test_search_given_name_complete_match(self, faker, pgdb_session): given_name = faker.first_name() for account in DNAAccountFactory.build_batch(faker.pyint(max_value=5)): pgdb_session.add(account) account1 = DNAAccountFactory.build(given_name=given_name) pgdb_session.add(account1) for account in DNAAccountFactory.build_batch(faker.pyint(max_value=5)): pgdb_session.add(account) account2 = DNAAccountFactory.build(given_name=given_name) pgdb_session.add(account2) for account in DNAAccountFactory.build_batch(faker.pyint(max_value=5)): pgdb_session.add(account) results = DNAAccount.query.search(given_name) assert account1 in results assert account2 in results def test_search_given_name_infix_match(self, faker, pgdb_session): given_name_infix = faker.first_name() for account in DNAAccountFactory.build_batch(faker.pyint(max_value=5)): pgdb_session.add(account) given_name1 = faker.pystr() + given_name_infix + faker.pystr() account1 = DNAAccountFactory.build(given_name=given_name1) pgdb_session.add(account1) for account in DNAAccountFactory.build_batch(faker.pyint(max_value=5)): pgdb_session.add(account) given_name2 = faker.pystr() + given_name_infix + faker.pystr() account2 = DNAAccountFactory.build(given_name=given_name2) pgdb_session.add(account2) for account in DNAAccountFactory.build_batch(faker.pyint(max_value=5)): pgdb_session.add(account) results = DNAAccount.query.search(given_name_infix) assert account1 in results assert account2 in results def test_search_family_name_complete_match(self, faker, pgdb_session): family_name = faker.last_name() for account in DNAAccountFactory.build_batch(faker.pyint(max_value=5)): pgdb_session.add(account) account1 = DNAAccountFactory.build(family_name=family_name) pgdb_session.add(account1) for account in DNAAccountFactory.build_batch(faker.pyint(max_value=5)): pgdb_session.add(account) account2 = DNAAccountFactory.build(family_name=family_name) pgdb_session.add(account2) for account in DNAAccountFactory.build_batch(faker.pyint(max_value=5)): pgdb_session.add(account) results = DNAAccount.query.search(family_name) assert account1 in results assert account2 in results def test_search_family_name_infix_match(self, faker, pgdb_session): family_name_infix = faker.last_name() for account in DNAAccountFactory.build_batch(faker.pyint(max_value=5)): pgdb_session.add(account) family_name1 = faker.pystr() + family_name_infix + faker.pystr() account1 = DNAAccountFactory.build(family_name=family_name1) pgdb_session.add(account1) for account in DNAAccountFactory.build_batch(faker.pyint(max_value=5)): pgdb_session.add(account) family_name2 = faker.pystr() + family_name_infix + faker.pystr() account2 = DNAAccountFactory.build(family_name=family_name2) pgdb_session.add(account2) for account in DNAAccountFactory.build_batch(faker.pyint(max_value=5)): pgdb_session.add(account) results = DNAAccount.query.search(family_name_infix) assert account1 in results assert account2 in results def test_search_full_name_match(self, faker, pgdb_session): for account in DNAAccountFactory.build_batch(faker.pyint(max_value=5)): pgdb_session.add(account) given_name = faker.pystr() family_name = faker.pystr() account = DNAAccountFactory.build( given_name=given_name, family_name=family_name ) pgdb_session.add(account) results = DNAAccount.query.search(f"{given_name} {family_name}") assert account in results def test_search_email_complete_match(self, faker, pgdb_session): base_email = faker.email() for account in DNAAccountFactory.build_batch(faker.pyint(max_value=5)): pgdb_session.add(account) account1 = DNAAccountFactory.build(email=f"case_1{base_email}") pgdb_session.add(account1) for account in DNAAccountFactory.build_batch(faker.pyint(max_value=5)): pgdb_session.add(account) account2 = DNAAccountFactory.build(email=f"case_2{base_email}") pgdb_session.add(account2) for account in DNAAccountFactory.build_batch(faker.pyint(max_value=5)): pgdb_session.add(account) results = DNAAccount.query.search(base_email) assert account1 in results assert account2 in results def test_search_email_infix_match(self, faker, pgdb_session): email_infix = faker.email() for account in DNAAccountFactory.build_batch(faker.pyint(max_value=5)): pgdb_session.add(account) email1 = faker.pystr() + email_infix + faker.pystr() account1 = DNAAccountFactory.build(email=email1) pgdb_session.add(account1) for account in DNAAccountFactory.build_batch(faker.pyint(max_value=5)): pgdb_session.add(account) email2 = faker.pystr() + email_infix + faker.pystr() account2 = DNAAccountFactory.build(email=email2) pgdb_session.add(account2) for account in DNAAccountFactory.build_batch(faker.pyint(max_value=5)): pgdb_session.add(account) results = DNAAccount.query.search(email_infix) assert account1 in results assert account2 in results def test_resource_groups_with_status(self, faker, pgdb_session): rand_factor = 5 dna_account = DNAAccountFactory.build() groups = ResourceGroupFactory.create_batch(faker.pyint(1, rand_factor)) names = { g: ClaimNameFactory.create_batch( faker.pyint(1, rand_factor), resource_group=g ) for g in groups } for claim_name in itertools.chain(*names.values()): dna_account.claim_values.extend( ClaimValueFactory.create_batch( faker.pyint(1, rand_factor), claim_name=claim_name ) ) pgdb_session.add(dna_account) pgdb_session.commit() assert all( not is_disabled for group, is_disabled in dna_account.resource_groups_with_status.all() # noqa ) disabled_groups = random.choices(groups, k=faker.pyint(1, len(groups))) pgdb_session.execute( pgdb.update(dna_account_claim_table) .where( dna_account_claim_table.c.dna_account_id == dna_account.id, dna_account_claim_table.c.claim_value_id == ClaimValue.id, ClaimValue.claim_name_id == ClaimName.id, ClaimName.resource_group_id.in_(g.id for g in disabled_groups), ) .values(is_disabled=True) ) pgdb.session.commit() assert all( not is_disabled for group, is_disabled in dna_account.resource_groups_with_status.all() # noqa if group not in disabled_groups ) assert all( is_disabled for group, is_disabled in dna_account.resource_groups_with_status.all() # noqa if group in disabled_groups ) def test_serialize_claims(self, pgdb_session, faker): dna_account = DNAAccountFactory.build() resource_group = ResourceGroupFactory.build() claim_name = ClaimNameFactory.build( resource_group=resource_group, claim_values_serializer="ListAppend" ) claim_value = ClaimValueFactory.build( claim_name=claim_name, ) dna_account.claim_values.append(claim_value) pgdb_session.add(dna_account) pgdb_session.add(resource_group) pgdb_session.add(claim_name) pgdb_session.add(claim_value) pgdb_session.commit() assert claim_name.url in dna_account.serialize_claims() pgdb_session.execute( pgdb.update(dna_account_claim_table).values(is_disabled=True) ) pgdb.session.commit() assert claim_name.url not in dna_account.serialize_claims() def test_status_hybrid_property_match(self, pgdb_session): account = DNAAccountFactory.build() expected_status = account.status pgdb_session.add(account) pgdb_session.commit() actual_status = ( pgdb_session.query(DNAAccount.status, DNAAccount) .where(DNAAccount.id == account.id) .scalar() ) assert expected_status == actual_status def test_status_active_future_expired_date(self, pgdb_session, faker): expected_status = DNAAccountStatuses.ACTIVE account = DNAAccountFactory.build() pgdb_session.add(account) pgdb_session.commit() actual_status = account.status assert account.expiration_date >= date.today() assert expected_status == actual_status actual_status = ( pgdb_session.query(DNAAccount.status, DNAAccount) .where(DNAAccount.id == account.id) .scalar() ) assert expected_status == actual_status def test_status_active_future_expiration_date(self, pgdb_session, faker): expected_status = DNAAccountStatuses.ACTIVE account = DNAAccountFactory.build() pgdb_session.add(account) pgdb_session.commit() actual_status = account.status assert account.expiration_date >= date.today() assert expected_status == actual_status actual_status = ( pgdb_session.query(DNAAccount.status, DNAAccount) .where(DNAAccount.id == account.id) .scalar() ) assert expected_status == actual_status def test_status_active_no_expiration_date(self, pgdb_session, faker): expected_status = DNAAccountStatuses.ACTIVE account = DNAAccountFactory.build(expiration_date=None) pgdb_session.add(account) pgdb_session.commit() actual_status = account.status assert account.expiration_date is None assert expected_status == actual_status actual_status = ( pgdb_session.query(DNAAccount.status, DNAAccount) .where(DNAAccount.id == account.id) .scalar() ) assert expected_status == actual_status def test_status_suspended_today_expiration_date(self, pgdb_session, faker): expected_status = DNAAccountStatuses.SUSPENDED expiration_date = date.today() account = DNAAccountFactory.build(expiration_date=expiration_date) pgdb_session.add(account) pgdb_session.commit() actual_status = account.status assert account.expiration_date == expiration_date assert expected_status == actual_status actual_status = ( pgdb_session.query(DNAAccount.status, DNAAccount) .where(DNAAccount.id == account.id) .scalar() ) assert expected_status == actual_status def test_status_suspended_past_expiration_date(self, pgdb_session, faker): expected_status = DNAAccountStatuses.SUSPENDED expiration_date = faker.past_date() account = DNAAccountFactory.build(expiration_date=expiration_date) pgdb_session.add(account) pgdb_session.commit() actual_status = account.status assert account.expiration_date == expiration_date assert expected_status == actual_status actual_status = ( pgdb_session.query(DNAAccount.status, DNAAccount) .where(DNAAccount.id == account.id) .scalar() ) assert expected_status == actual_status def test_selsert_from_usm_claimset_without_account( self, faker, mocker, pgdb_session ): email = faker.email() assert DNAAccount.query.count() == 0 dna_account = DNAAccount.selsert_from_usm_claimset( {"sub": "test_sub", "email": email} ) assert dna_account.is_null assert DNAAccount.query.count() == 0 def test_selsert_from_usm_claimset_with_account( self, faker, mocker, pgdb_session ): email = faker.email() dna_account = DNAAccountFactory.build(email=email) pgdb_session.add(dna_account) pgdb_session.commit() actual_account = DNAAccount.selsert_from_usm_claimset( {"sub": "test_sub", "email": email} ) assert dna_account == actual_account assert ( DNAAccount.query.filter(DNAAccount.email == email).first() == dna_account ) def test_selsert_from_usm_claimset_with_account_alt_email( self, faker, mocker, pgdb_session ): email = faker.email() alt_email = faker.email() dna_account = DNAAccountFactory.build(email=alt_email) pgdb_session.add(dna_account) pgdb_session.commit() actual_account = DNAAccount.selsert_from_usm_claimset( { "sub": "test_sub", "email": email, "verified_primary_email": [alt_email], } ) assert dna_account == actual_account assert ( DNAAccount.query.filter(DNAAccount.email == alt_email).first() == dna_account ) def test_register_for_resource_group_with_account_and_domain( self, faker, pgdb_session ): domain = "product.test" resource_group = ResourceGroupFactory.build( service_url=f"https://{domain}" ) dna_account = DNAAccountFactory.build() pgdb_session.add(resource_group) pgdb_session.add(dna_account) pgdb_session.commit() instance = DNAAccountActivity.register_for_resource_group( dna_account, ResourceGroup.query.by_domain(domain).first() ) assert instance.dna_account == dna_account assert instance.resource_group == resource_group assert instance.last_login assert instance in dna_account.account_activities def test_register_for_resource_group_with_account_and_domain_update( self, faker, pgdb_session ): domain = "product.test" resource_group = ResourceGroupFactory.build( service_url=f"https://{domain}" ) dna_account = DNAAccountFactory.build() last_login = faker.past_datetime() instance = DNAAccountActivity( dna_account=dna_account, resource_group=resource_group, last_login=last_login, ) pgdb_session.add(resource_group) pgdb_session.add(dna_account) pgdb_session.add(instance) pgdb_session.commit() instance = DNAAccountActivity.register_for_resource_group( dna_account, ResourceGroup.query.by_domain(domain).first() ) assert instance.dna_account == dna_account assert instance.resource_group == resource_group assert instance.last_login > last_login assert instance in dna_account.account_activities def test_register_for_resource_group_with_account_unknown_domain( self, faker, pgdb_session ): domain = "product.test" resource_group = ResourceGroupFactory.build( service_url="https://other-domain.test" ) dna_account = DNAAccountFactory.build() pgdb_session.add(resource_group) pgdb_session.add(dna_account) pgdb_session.commit() instance = DNAAccountActivity.register_for_resource_group( dna_account, ResourceGroup.query.by_domain(domain).first() ) assert instance.dna_account == dna_account assert instance.resource_group is None assert instance.last_login assert instance in dna_account.account_activities def test_register_for_resource_group_set_first_login( self, faker, pgdb_session ): domain = "product.test" resource_group = ResourceGroupFactory.build( service_url=f"https://{domain}" ) dna_account = DNAAccountFactory.build() instance = DNAAccountActivity( dna_account=dna_account, resource_group=resource_group, ) pgdb_session.add(resource_group) pgdb_session.add(dna_account) pgdb_session.add(instance) pgdb_session.commit() assert not instance.first_login instance = DNAAccountActivity.register_for_resource_group( dna_account, ResourceGroup.query.by_domain(domain).first() ) assert instance.dna_account == dna_account assert instance.resource_group == resource_group assert instance.first_login first_login = instance.first_login # check that first_login doesn't change instance = DNAAccountActivity.register_for_resource_group( dna_account, ResourceGroup.query.by_domain(domain).first() ) assert first_login == instance.first_login