Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add ACH to stripe payment emails #1020

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft

Conversation

suejung-sentry
Copy link
Contributor

@suejung-sentry suejung-sentry commented Jan 21, 2025

Note that the auto-refund email has a template but is never invoked per @spalmurray-codecov .

Copy link

codecov bot commented Jan 21, 2025

Codecov Report

Attention: Patch coverage is 66.66667% with 1 line in your changes missing coverage. Please review.

Project coverage is 97.49%. Comparing base (ce786b3) to head (6609712).
Report is 35 commits behind head on main.

✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
services/yaml/tests/test_yaml_parsing.py 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1020      +/-   ##
==========================================
- Coverage   97.73%   97.49%   -0.24%     
==========================================
  Files         451      463      +12     
  Lines       36922    38083    +1161     
==========================================
+ Hits        36086    37130    +1044     
- Misses        836      953     +117     
Flag Coverage Δ
integration 42.85% <66.66%> (+0.45%) ⬆️
unit 90.18% <0.00%> (-0.10%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

⚠️ Impact Analysis from Codecov is deprecated and will be sunset on Jan 31 2025. See more

@codecov-notifications
Copy link

codecov-notifications bot commented Jan 21, 2025

❌ 2 Tests Failed:

Tests completed Failed Passed Skipped
1796 2 1794 9
View the top 2 failed tests by shortest run time
services/yaml/tests/test_yaml_parsing.py::TestYamlSavingService::test_parse_big_yaml_file
Stack Traces | 0.045s run time
self = <test_yaml_parsing.TestYamlSavingService object at 0x7f8aaf9e7890>

    def test_parse_big_yaml_file(self):
        with open(here.parent / "samples" / "big.yaml") as f:
            contents = f.read()
>       res = parse_yaml_file(
            contents, show_secrets_for=("github", 44376991, 156617777)
        )

.../yaml/tests/test_yaml_parsing.py:59: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
services/yaml/parser.py:16: in parse_yaml_file
    return validate_yaml(yaml_dict, show_secrets_for=show_secrets_for)
.../local/lib/python3.13.../shared/yaml/validation.py:43: in validate_yaml
    return do_actual_validation(inputted_yaml_dict, show_secrets_for)
.../local/lib/python3.13.../shared/yaml/validation.py:162: in do_actual_validation
    is_valid = validator.validate(yaml_dict, full_schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:1033: in validate
    self.__normalize_mapping(self.document, self.schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:708: in __normalize_mapping
    self.__normalize_containers(mapping, schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:787: in __normalize_containers
    self.__normalize_mapping_per_schema(field, mapping, schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:851: in __normalize_mapping_per_schema
    result_value = validator.normalized(mapping[field], always_return_document=True)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:683: in normalized
    self.__normalize_mapping(self.document, self.schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:708: in __normalize_mapping
    self.__normalize_containers(mapping, schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:796: in __normalize_containers
    self.__normalize_sequence_per_schema(field, mapping, schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:865: in __normalize_sequence_per_schema
    result = validator.normalized(document, always_return_document=True)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:683: in normalized
    self.__normalize_mapping(self.document, self.schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:708: in __normalize_mapping
    self.__normalize_containers(mapping, schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:787: in __normalize_containers
    self.__normalize_mapping_per_schema(field, mapping, schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:851: in __normalize_mapping_per_schema
    result_value = validator.normalized(mapping[field], always_return_document=True)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:683: in normalized
    self.__normalize_mapping(self.document, self.schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:708: in __normalize_mapping
    self.__normalize_containers(mapping, schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:787: in __normalize_containers
    self.__normalize_mapping_per_schema(field, mapping, schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:851: in __normalize_mapping_per_schema
    result_value = validator.normalized(mapping[field], always_return_document=True)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:683: in normalized
    self.__normalize_mapping(self.document, self.schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:697: in __normalize_mapping
    self.__normalize_rename_fields(mapping, schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:903: in __normalize_rename_fields
    self._normalize_rename(mapping, schema, field)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <shared.yaml.validation.CodecovUserYamlValidator object at 0x7f8aa4085b50>
mapping = {'target': 'auto', 'type': 'patch'}
schema = {'schema': {'base': {'allowed': ('parent', 'pr', 'auto'), 'type': 'string'}, 'branches': {'nullable': True, 'schema': ... 'string'}, 'type': 'list'}, 'disable_approx': {'type': 'boolean'}, 'enabled': {'type': 'boolean'}, ...}, 'type': None}
field = 'type'

    def _normalize_rename(self, mapping, schema, field):
        """{'type': 'hashable'}"""
>       if 'rename' in schema[field]:
E       TypeError: argument of type 'NoneType' is not iterable

.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:916: TypeError
tasks/tests/unit/test_sync_teams_task.py::TestSyncTeamsTaskUnit::test_team_removed
Stack Traces | 0.054s run time
self = <worker.tasks.tests.unit.test_sync_teams_task.TestSyncTeamsTaskUnit object at 0x7f3a1b5b49d0>
mocker = <pytest_mock.plugin.MockFixture object at 0x7f3a061aeb10>
mock_configuration = <shared.config.ConfigHelper object at 0x7f3a0423fe90>
dbsession = <sqlalchemy.orm.session.Session object at 0x7f3a05f57e30>
codecov_vcr = <vcr.cassette.Cassette object at 0x7f3a061af7d0>

    def test_team_removed(self, mocker, mock_configuration, dbsession, codecov_vcr):
        token = "testv2ztxs03zwys22v36ama292esl13swroe6dj"
        prev_team = OwnerFactory.create(service="github", username="Evil_Corp")
        dbsession.add(prev_team)
        user = OwnerFactory.create(
            organizations=[prev_team.ownerid],
            service="github",
            unencrypted_oauth_token=token,
        )
        dbsession.add(user)
        dbsession.flush()
>       SyncTeamsTask().run_impl(dbsession, user.ownerid, using_integration=False)

.../tests/unit/test_sync_teams_task.py:42: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <@task: app.tasks.sync_teams.SyncTeams of tasks at 0x7f3a17c5bb60>
db_session = <sqlalchemy.orm.session.Session object at 0x7f3a05f57e30>
ownerid = 312, username = None, kwargs = {'using_integration': False}
owner = Owner<312@service<github>>, service = 'github'
git = <github slug=None ownerid=312 repoid=None>, teams = [], updated_teams = []

    def run_impl(self, db_session, ownerid, *, username=None, **kwargs):
        log.info("Sync teams", extra=dict(ownerid=ownerid, username=username))
        owner = db_session.query(Owner).filter(Owner.ownerid == ownerid).first()
    
        assert owner, "Owner not found"
        service = owner.service
    
        git = get_owner_provider_service(owner, ignore_installation=True)
    
        # get list of teams with username, name, email, id (service_id), etc
        teams = async_to_sync(git.list_teams)()
    
        updated_teams = []
    
        for team in teams:
            team_data = dict(
                username=team["username"],
                name=team["name"],
                email=team.get("email"),
                avatar_url=team.get("avatar_url"),
                parent_service_id=team.get("parent_id"),
            )
            team_ownerid = self.upsert_team(
                db_session, service, str(team["id"]), team_data
            )
            team_data["ownerid"] = team_ownerid
            updated_teams.append(team_data)
    
        team_ids = [team["ownerid"] for team in updated_teams]
    
        removed_orgs = set(owner.organizations or []) - set(team_ids)
        if removed_orgs:
            log.warning(
                "Owner had access to organization that are being removed",
                extra=dict(
                    old_orgs=owner.organizations,
                    new_orgs=team_ids,
                    removed_orgs=sorted(removed_orgs),
                    ownerid=ownerid,
                ),
            )
        # The org has members in plan_activated_users
            # The member has the org in organizations
            # Ownerid is the member's ownerid
            for org in removed_orgs:
>               org.plan_activated_users.remove(ownerid)
E               AttributeError: 'NoneType' object has no attribute 'plan_activated_users'

tasks/sync_teams.py:65: AttributeError

To view more test analytics, go to the Test Analytics Dashboard
📢 Thoughts on this report? Let us know!

Copy link

github-actions bot commented Jan 21, 2025

❌ 2 Tests Failed:

Tests completed Failed Passed Skipped
1805 2 1794 9
View the top 2 failed tests by shortest run time
test_parse_big_yaml_file
Stack Traces | 0.045s run time
self = &lt;test_yaml_parsing.TestYamlSavingService object at 0x7f8aaf9e7890&gt;

    def test_parse_big_yaml_file(self):
        with open(here.parent / "samples" / "big.yaml") as f:
            contents = f.read()
&gt;       res = parse_yaml_file(
            contents, show_secrets_for=("github", 44376991, 156617777)
        )

services/yaml/tests/test_yaml_parsing.py:59: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
services/yaml/parser.py:16: in parse_yaml_file
    return validate_yaml(yaml_dict, show_secrets_for=show_secrets_for)
/usr/local/lib/python3.13/site-packages/shared/yaml/validation.py:43: in validate_yaml
    return do_actual_validation(inputted_yaml_dict, show_secrets_for)
/usr/local/lib/python3.13/site-packages/shared/yaml/validation.py:162: in do_actual_validation
    is_valid = validator.validate(yaml_dict, full_schema)
/usr/local/lib/python3.13/site-packages/cerberus/validator.py:1033: in validate
    self.__normalize_mapping(self.document, self.schema)
/usr/local/lib/python3.13/site-packages/cerberus/validator.py:708: in __normalize_mapping
    self.__normalize_containers(mapping, schema)
/usr/local/lib/python3.13/site-packages/cerberus/validator.py:787: in __normalize_containers
    self.__normalize_mapping_per_schema(field, mapping, schema)
/usr/local/lib/python3.13/site-packages/cerberus/validator.py:851: in __normalize_mapping_per_schema
    result_value = validator.normalized(mapping[field], always_return_document=True)
/usr/local/lib/python3.13/site-packages/cerberus/validator.py:683: in normalized
    self.__normalize_mapping(self.document, self.schema)
/usr/local/lib/python3.13/site-packages/cerberus/validator.py:708: in __normalize_mapping
    self.__normalize_containers(mapping, schema)
/usr/local/lib/python3.13/site-packages/cerberus/validator.py:796: in __normalize_containers
    self.__normalize_sequence_per_schema(field, mapping, schema)
/usr/local/lib/python3.13/site-packages/cerberus/validator.py:865: in __normalize_sequence_per_schema
    result = validator.normalized(document, always_return_document=True)
/usr/local/lib/python3.13/site-packages/cerberus/validator.py:683: in normalized
    self.__normalize_mapping(self.document, self.schema)
/usr/local/lib/python3.13/site-packages/cerberus/validator.py:708: in __normalize_mapping
    self.__normalize_containers(mapping, schema)
/usr/local/lib/python3.13/site-packages/cerberus/validator.py:787: in __normalize_containers
    self.__normalize_mapping_per_schema(field, mapping, schema)
/usr/local/lib/python3.13/site-packages/cerberus/validator.py:851: in __normalize_mapping_per_schema
    result_value = validator.normalized(mapping[field], always_return_document=True)
/usr/local/lib/python3.13/site-packages/cerberus/validator.py:683: in normalized
    self.__normalize_mapping(self.document, self.schema)
/usr/local/lib/python3.13/site-packages/cerberus/validator.py:708: in __normalize_mapping
    self.__normalize_containers(mapping, schema)
/usr/local/lib/python3.13/site-packages/cerberus/validator.py:787: in __normalize_containers
    self.__normalize_mapping_per_schema(field, mapping, schema)
/usr/local/lib/python3.13/site-packages/cerberus/validator.py:851: in __normalize_mapping_per_schema
    result_value = validator.normalized(mapping[field], always_return_document=True)
/usr/local/lib/python3.13/site-packages/cerberus/validator.py:683: in normalized
    self.__normalize_mapping(self.document, self.schema)
/usr/local/lib/python3.13/site-packages/cerberus/validator.py:697: in __normalize_mapping
    self.__normalize_rename_fields(mapping, schema)
/usr/local/lib/python3.13/site-packages/cerberus/validator.py:903: in __normalize_rename_fields
    self._normalize_rename(mapping, schema, field)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = &lt;shared.yaml.validation.CodecovUserYamlValidator object at 0x7f8aa4085b50&gt;
mapping = {'target': 'auto', 'type': 'patch'}
schema = {'schema': {'base': {'allowed': ('parent', 'pr', 'auto'), 'type': 'string'}, 'branches': {'nullable': True, 'schema': ... 'string'}, 'type': 'list'}, 'disable_approx': {'type': 'boolean'}, 'enabled': {'type': 'boolean'}, ...}, 'type': None}
field = 'type'

    def _normalize_rename(self, mapping, schema, field):
        """{'type': 'hashable'}"""
&gt;       if 'rename' in schema[field]:
E       TypeError: argument of type 'NoneType' is not iterable

/usr/local/lib/python3.13/site-packages/cerberus/validator.py:916: TypeError
test_team_removed
Stack Traces | 0.054s run time
self = &lt;worker.tasks.tests.unit.test_sync_teams_task.TestSyncTeamsTaskUnit object at 0x7f3a1b5b49d0&gt;
mocker = &lt;pytest_mock.plugin.MockFixture object at 0x7f3a061aeb10&gt;
mock_configuration = &lt;shared.config.ConfigHelper object at 0x7f3a0423fe90&gt;
dbsession = &lt;sqlalchemy.orm.session.Session object at 0x7f3a05f57e30&gt;
codecov_vcr = &lt;vcr.cassette.Cassette object at 0x7f3a061af7d0&gt;

    def test_team_removed(self, mocker, mock_configuration, dbsession, codecov_vcr):
        token = "testv2ztxs03zwys22v36ama292esl13swroe6dj"
        prev_team = OwnerFactory.create(service="github", username="Evil_Corp")
        dbsession.add(prev_team)
        user = OwnerFactory.create(
            organizations=[prev_team.ownerid],
            service="github",
            unencrypted_oauth_token=token,
        )
        dbsession.add(user)
        dbsession.flush()
&gt;       SyncTeamsTask().run_impl(dbsession, user.ownerid, using_integration=False)

tasks/tests/unit/test_sync_teams_task.py:42: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = &lt;@task: app.tasks.sync_teams.SyncTeams of tasks at 0x7f3a17c5bb60&gt;
db_session = &lt;sqlalchemy.orm.session.Session object at 0x7f3a05f57e30&gt;
ownerid = 312, username = None, kwargs = {'using_integration': False}
owner = Owner&lt;312@service&lt;github&gt;&gt;, service = 'github'
git = &lt;github slug=None ownerid=312 repoid=None&gt;, teams = [], updated_teams = []

    def run_impl(self, db_session, ownerid, *, username=None, **kwargs):
        log.info("Sync teams", extra=dict(ownerid=ownerid, username=username))
        owner = db_session.query(Owner).filter(Owner.ownerid == ownerid).first()
    
        assert owner, "Owner not found"
        service = owner.service
    
        git = get_owner_provider_service(owner, ignore_installation=True)
    
        # get list of teams with username, name, email, id (service_id), etc
        teams = async_to_sync(git.list_teams)()
    
        updated_teams = []
    
        for team in teams:
            team_data = dict(
                username=team["username"],
                name=team["name"],
                email=team.get("email"),
                avatar_url=team.get("avatar_url"),
                parent_service_id=team.get("parent_id"),
            )
            team_ownerid = self.upsert_team(
                db_session, service, str(team["id"]), team_data
            )
            team_data["ownerid"] = team_ownerid
            updated_teams.append(team_data)
    
        team_ids = [team["ownerid"] for team in updated_teams]
    
        removed_orgs = set(owner.organizations or []) - set(team_ids)
        if removed_orgs:
            log.warning(
                "Owner had access to organization that are being removed",
                extra=dict(
                    old_orgs=owner.organizations,
                    new_orgs=team_ids,
                    removed_orgs=sorted(removed_orgs),
                    ownerid=ownerid,
                ),
            )
        # The org has members in plan_activated_users
            # The member has the org in organizations
            # Ownerid is the member's ownerid
            for org in removed_orgs:
&gt;               org.plan_activated_users.remove(ownerid)
E               AttributeError: 'NoneType' object has no attribute 'plan_activated_users'

tasks/sync_teams.py:65: AttributeError

📣 Thoughts on this report? Let Codecov know! | Powered by Codecov

@codecov-qa
Copy link

codecov-qa bot commented Jan 29, 2025

❌ 2 Tests Failed:

Tests completed Failed Passed Skipped
1796 2 1794 9
View the top 2 failed tests by shortest run time
services/yaml/tests/test_yaml_parsing.py::TestYamlSavingService::test_parse_big_yaml_file
Stack Traces | 0.045s run time
self = <test_yaml_parsing.TestYamlSavingService object at 0x7f8aaf9e7890>

    def test_parse_big_yaml_file(self):
        with open(here.parent / "samples" / "big.yaml") as f:
            contents = f.read()
>       res = parse_yaml_file(
            contents, show_secrets_for=("github", 44376991, 156617777)
        )

.../yaml/tests/test_yaml_parsing.py:59: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
services/yaml/parser.py:16: in parse_yaml_file
    return validate_yaml(yaml_dict, show_secrets_for=show_secrets_for)
.../local/lib/python3.13.../shared/yaml/validation.py:43: in validate_yaml
    return do_actual_validation(inputted_yaml_dict, show_secrets_for)
.../local/lib/python3.13.../shared/yaml/validation.py:162: in do_actual_validation
    is_valid = validator.validate(yaml_dict, full_schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:1033: in validate
    self.__normalize_mapping(self.document, self.schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:708: in __normalize_mapping
    self.__normalize_containers(mapping, schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:787: in __normalize_containers
    self.__normalize_mapping_per_schema(field, mapping, schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:851: in __normalize_mapping_per_schema
    result_value = validator.normalized(mapping[field], always_return_document=True)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:683: in normalized
    self.__normalize_mapping(self.document, self.schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:708: in __normalize_mapping
    self.__normalize_containers(mapping, schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:796: in __normalize_containers
    self.__normalize_sequence_per_schema(field, mapping, schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:865: in __normalize_sequence_per_schema
    result = validator.normalized(document, always_return_document=True)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:683: in normalized
    self.__normalize_mapping(self.document, self.schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:708: in __normalize_mapping
    self.__normalize_containers(mapping, schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:787: in __normalize_containers
    self.__normalize_mapping_per_schema(field, mapping, schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:851: in __normalize_mapping_per_schema
    result_value = validator.normalized(mapping[field], always_return_document=True)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:683: in normalized
    self.__normalize_mapping(self.document, self.schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:708: in __normalize_mapping
    self.__normalize_containers(mapping, schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:787: in __normalize_containers
    self.__normalize_mapping_per_schema(field, mapping, schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:851: in __normalize_mapping_per_schema
    result_value = validator.normalized(mapping[field], always_return_document=True)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:683: in normalized
    self.__normalize_mapping(self.document, self.schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:697: in __normalize_mapping
    self.__normalize_rename_fields(mapping, schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:903: in __normalize_rename_fields
    self._normalize_rename(mapping, schema, field)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <shared.yaml.validation.CodecovUserYamlValidator object at 0x7f8aa4085b50>
mapping = {'target': 'auto', 'type': 'patch'}
schema = {'schema': {'base': {'allowed': ('parent', 'pr', 'auto'), 'type': 'string'}, 'branches': {'nullable': True, 'schema': ... 'string'}, 'type': 'list'}, 'disable_approx': {'type': 'boolean'}, 'enabled': {'type': 'boolean'}, ...}, 'type': None}
field = 'type'

    def _normalize_rename(self, mapping, schema, field):
        """{'type': 'hashable'}"""
>       if 'rename' in schema[field]:
E       TypeError: argument of type 'NoneType' is not iterable

.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:916: TypeError
tasks/tests/unit/test_sync_teams_task.py::TestSyncTeamsTaskUnit::test_team_removed
Stack Traces | 0.054s run time
self = <worker.tasks.tests.unit.test_sync_teams_task.TestSyncTeamsTaskUnit object at 0x7f3a1b5b49d0>
mocker = <pytest_mock.plugin.MockFixture object at 0x7f3a061aeb10>
mock_configuration = <shared.config.ConfigHelper object at 0x7f3a0423fe90>
dbsession = <sqlalchemy.orm.session.Session object at 0x7f3a05f57e30>
codecov_vcr = <vcr.cassette.Cassette object at 0x7f3a061af7d0>

    def test_team_removed(self, mocker, mock_configuration, dbsession, codecov_vcr):
        token = "testv2ztxs03zwys22v36ama292esl13swroe6dj"
        prev_team = OwnerFactory.create(service="github", username="Evil_Corp")
        dbsession.add(prev_team)
        user = OwnerFactory.create(
            organizations=[prev_team.ownerid],
            service="github",
            unencrypted_oauth_token=token,
        )
        dbsession.add(user)
        dbsession.flush()
>       SyncTeamsTask().run_impl(dbsession, user.ownerid, using_integration=False)

.../tests/unit/test_sync_teams_task.py:42: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <@task: app.tasks.sync_teams.SyncTeams of tasks at 0x7f3a17c5bb60>
db_session = <sqlalchemy.orm.session.Session object at 0x7f3a05f57e30>
ownerid = 312, username = None, kwargs = {'using_integration': False}
owner = Owner<312@service<github>>, service = 'github'
git = <github slug=None ownerid=312 repoid=None>, teams = [], updated_teams = []

    def run_impl(self, db_session, ownerid, *, username=None, **kwargs):
        log.info("Sync teams", extra=dict(ownerid=ownerid, username=username))
        owner = db_session.query(Owner).filter(Owner.ownerid == ownerid).first()
    
        assert owner, "Owner not found"
        service = owner.service
    
        git = get_owner_provider_service(owner, ignore_installation=True)
    
        # get list of teams with username, name, email, id (service_id), etc
        teams = async_to_sync(git.list_teams)()
    
        updated_teams = []
    
        for team in teams:
            team_data = dict(
                username=team["username"],
                name=team["name"],
                email=team.get("email"),
                avatar_url=team.get("avatar_url"),
                parent_service_id=team.get("parent_id"),
            )
            team_ownerid = self.upsert_team(
                db_session, service, str(team["id"]), team_data
            )
            team_data["ownerid"] = team_ownerid
            updated_teams.append(team_data)
    
        team_ids = [team["ownerid"] for team in updated_teams]
    
        removed_orgs = set(owner.organizations or []) - set(team_ids)
        if removed_orgs:
            log.warning(
                "Owner had access to organization that are being removed",
                extra=dict(
                    old_orgs=owner.organizations,
                    new_orgs=team_ids,
                    removed_orgs=sorted(removed_orgs),
                    ownerid=ownerid,
                ),
            )
        # The org has members in plan_activated_users
            # The member has the org in organizations
            # Ownerid is the member's ownerid
            for org in removed_orgs:
>               org.plan_activated_users.remove(ownerid)
E               AttributeError: 'NoneType' object has no attribute 'plan_activated_users'

tasks/sync_teams.py:65: AttributeError

To view more test analytics, go to the Test Analytics Dashboard
📢 Thoughts on this report? Let us know!

Copy link

codecov-public-qa bot commented Jan 29, 2025

❌ 2 Tests Failed:

Tests completed Failed Passed Skipped
1796 2 1794 9
View the top 2 failed tests by shortest run time
services/yaml/tests/test_yaml_parsing.py::TestYamlSavingService::test_parse_big_yaml_file
Stack Traces | 0.045s run time
self = <test_yaml_parsing.TestYamlSavingService object at 0x7f8aaf9e7890>

    def test_parse_big_yaml_file(self):
        with open(here.parent / "samples" / "big.yaml") as f:
            contents = f.read()
>       res = parse_yaml_file(
            contents, show_secrets_for=("github", 44376991, 156617777)
        )

.../yaml/tests/test_yaml_parsing.py:59: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
services/yaml/parser.py:16: in parse_yaml_file
    return validate_yaml(yaml_dict, show_secrets_for=show_secrets_for)
.../local/lib/python3.13.../shared/yaml/validation.py:43: in validate_yaml
    return do_actual_validation(inputted_yaml_dict, show_secrets_for)
.../local/lib/python3.13.../shared/yaml/validation.py:162: in do_actual_validation
    is_valid = validator.validate(yaml_dict, full_schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:1033: in validate
    self.__normalize_mapping(self.document, self.schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:708: in __normalize_mapping
    self.__normalize_containers(mapping, schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:787: in __normalize_containers
    self.__normalize_mapping_per_schema(field, mapping, schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:851: in __normalize_mapping_per_schema
    result_value = validator.normalized(mapping[field], always_return_document=True)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:683: in normalized
    self.__normalize_mapping(self.document, self.schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:708: in __normalize_mapping
    self.__normalize_containers(mapping, schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:796: in __normalize_containers
    self.__normalize_sequence_per_schema(field, mapping, schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:865: in __normalize_sequence_per_schema
    result = validator.normalized(document, always_return_document=True)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:683: in normalized
    self.__normalize_mapping(self.document, self.schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:708: in __normalize_mapping
    self.__normalize_containers(mapping, schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:787: in __normalize_containers
    self.__normalize_mapping_per_schema(field, mapping, schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:851: in __normalize_mapping_per_schema
    result_value = validator.normalized(mapping[field], always_return_document=True)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:683: in normalized
    self.__normalize_mapping(self.document, self.schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:708: in __normalize_mapping
    self.__normalize_containers(mapping, schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:787: in __normalize_containers
    self.__normalize_mapping_per_schema(field, mapping, schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:851: in __normalize_mapping_per_schema
    result_value = validator.normalized(mapping[field], always_return_document=True)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:683: in normalized
    self.__normalize_mapping(self.document, self.schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:697: in __normalize_mapping
    self.__normalize_rename_fields(mapping, schema)
.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:903: in __normalize_rename_fields
    self._normalize_rename(mapping, schema, field)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <shared.yaml.validation.CodecovUserYamlValidator object at 0x7f8aa4085b50>
mapping = {'target': 'auto', 'type': 'patch'}
schema = {'schema': {'base': {'allowed': ('parent', 'pr', 'auto'), 'type': 'string'}, 'branches': {'nullable': True, 'schema': ... 'string'}, 'type': 'list'}, 'disable_approx': {'type': 'boolean'}, 'enabled': {'type': 'boolean'}, ...}, 'type': None}
field = 'type'

    def _normalize_rename(self, mapping, schema, field):
        """{'type': 'hashable'}"""
>       if 'rename' in schema[field]:
E       TypeError: argument of type 'NoneType' is not iterable

.../local/lib/python3.13............................................................/site-packages/cerberus/validator.py:916: TypeError
tasks/tests/unit/test_sync_teams_task.py::TestSyncTeamsTaskUnit::test_team_removed
Stack Traces | 0.054s run time
self = <worker.tasks.tests.unit.test_sync_teams_task.TestSyncTeamsTaskUnit object at 0x7f3a1b5b49d0>
mocker = <pytest_mock.plugin.MockFixture object at 0x7f3a061aeb10>
mock_configuration = <shared.config.ConfigHelper object at 0x7f3a0423fe90>
dbsession = <sqlalchemy.orm.session.Session object at 0x7f3a05f57e30>
codecov_vcr = <vcr.cassette.Cassette object at 0x7f3a061af7d0>

    def test_team_removed(self, mocker, mock_configuration, dbsession, codecov_vcr):
        token = "testv2ztxs03zwys22v36ama292esl13swroe6dj"
        prev_team = OwnerFactory.create(service="github", username="Evil_Corp")
        dbsession.add(prev_team)
        user = OwnerFactory.create(
            organizations=[prev_team.ownerid],
            service="github",
            unencrypted_oauth_token=token,
        )
        dbsession.add(user)
        dbsession.flush()
>       SyncTeamsTask().run_impl(dbsession, user.ownerid, using_integration=False)

.../tests/unit/test_sync_teams_task.py:42: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <@task: app.tasks.sync_teams.SyncTeams of tasks at 0x7f3a17c5bb60>
db_session = <sqlalchemy.orm.session.Session object at 0x7f3a05f57e30>
ownerid = 312, username = None, kwargs = {'using_integration': False}
owner = Owner<312@service<github>>, service = 'github'
git = <github slug=None ownerid=312 repoid=None>, teams = [], updated_teams = []

    def run_impl(self, db_session, ownerid, *, username=None, **kwargs):
        log.info("Sync teams", extra=dict(ownerid=ownerid, username=username))
        owner = db_session.query(Owner).filter(Owner.ownerid == ownerid).first()
    
        assert owner, "Owner not found"
        service = owner.service
    
        git = get_owner_provider_service(owner, ignore_installation=True)
    
        # get list of teams with username, name, email, id (service_id), etc
        teams = async_to_sync(git.list_teams)()
    
        updated_teams = []
    
        for team in teams:
            team_data = dict(
                username=team["username"],
                name=team["name"],
                email=team.get("email"),
                avatar_url=team.get("avatar_url"),
                parent_service_id=team.get("parent_id"),
            )
            team_ownerid = self.upsert_team(
                db_session, service, str(team["id"]), team_data
            )
            team_data["ownerid"] = team_ownerid
            updated_teams.append(team_data)
    
        team_ids = [team["ownerid"] for team in updated_teams]
    
        removed_orgs = set(owner.organizations or []) - set(team_ids)
        if removed_orgs:
            log.warning(
                "Owner had access to organization that are being removed",
                extra=dict(
                    old_orgs=owner.organizations,
                    new_orgs=team_ids,
                    removed_orgs=sorted(removed_orgs),
                    ownerid=ownerid,
                ),
            )
        # The org has members in plan_activated_users
            # The member has the org in organizations
            # Ownerid is the member's ownerid
            for org in removed_orgs:
>               org.plan_activated_users.remove(ownerid)
E               AttributeError: 'NoneType' object has no attribute 'plan_activated_users'

tasks/sync_teams.py:65: AttributeError

To view more test analytics, go to the Test Analytics Dashboard
📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants