Skip to content

Commit 6e424f0

Browse files
EricGustinclaude
andcommitted
test(auth): cover every OAuth2 provider's construction
Instantiating each provider class exercises its __init__/super().__init__, which codecov patch flags as uncovered when a new provider lands. Walking the provider classes dynamically keeps every current and future provider covered with no per-provider test edit. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 02353a8 commit 6e424f0

1 file changed

Lines changed: 54 additions & 0 deletions

File tree

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
"""Every OAuth2 provider class in ``arcade_core.auth`` must construct and carry its metadata.
2+
3+
This walks the provider classes dynamically rather than naming them, so a newly added
4+
provider is covered the moment it lands -- no per-provider test edit. Each subclass's
5+
``__init__`` (its ``super().__init__`` call) only runs on instantiation, so constructing
6+
every provider here is also what exercises those lines under coverage.
7+
"""
8+
9+
import inspect
10+
11+
import pytest
12+
from arcade_core import auth as auth_module
13+
from arcade_core.auth import AuthProviderType, OAuth2
14+
15+
16+
def _provider_classes() -> list[type[OAuth2]]:
17+
"""Concrete OAuth2 provider classes defined in ``arcade_core.auth`` (OAuth2 itself excluded)."""
18+
return [
19+
obj
20+
for _, obj in inspect.getmembers(auth_module, inspect.isclass)
21+
if issubclass(obj, OAuth2)
22+
and obj is not OAuth2
23+
and obj.__module__ == auth_module.__name__
24+
]
25+
26+
27+
def test_provider_classes_are_discovered():
28+
# Guards the parametrized tests below from silently collecting zero cases.
29+
assert _provider_classes(), "no OAuth2 provider classes found in arcade_core.auth"
30+
31+
32+
@pytest.mark.parametrize("provider_cls", _provider_classes(), ids=lambda c: c.__name__)
33+
def test_provider_constructs_with_default_metadata(provider_cls: type[OAuth2]):
34+
provider = provider_cls()
35+
assert isinstance(provider.provider_id, str)
36+
assert provider.provider_id
37+
assert provider.provider_type == AuthProviderType.oauth2
38+
assert provider.id is None
39+
assert provider.scopes is None
40+
41+
42+
@pytest.mark.parametrize("provider_cls", _provider_classes(), ids=lambda c: c.__name__)
43+
def test_provider_accepts_id_and_scopes(provider_cls: type[OAuth2]):
44+
provider = provider_cls(id="custom-provider-id", scopes=["scope.read", "scope.write"])
45+
assert provider.id == "custom-provider-id"
46+
assert provider.scopes == ["scope.read", "scope.write"]
47+
# provider_id is the fixed well-known key and is not displaced by a custom id.
48+
assert provider.provider_id == provider_cls().provider_id
49+
50+
51+
def test_provider_ids_are_unique():
52+
# A copy-paste codegen slip that reused another provider's id would collide here.
53+
ids = [cls().provider_id for cls in _provider_classes()]
54+
assert len(ids) == len(set(ids)), f"duplicate provider_id values: {sorted(ids)}"

0 commit comments

Comments
 (0)