django-ninja
django-ninja copied to clipboard
[BUG] Cannot use Django's Test Client when Ninja TestClient is used in a pytest suite
Describe the bug
I have the following pytest tests, running in the same order as below. The first one uses the NinjaTestClient. Once this client1.get("/whoami", user=simple_user)
is executed, the next test using Django Test Client fails with the exception Router@'/access-control/' has already been attached to API NinjaAPI:1.0.0
. The stack trace is also pasted below.
from ninja.testing import TestClient as NinjaTestClient
...
@pytest.mark.django_db
def test_api_whoami_happy_path(simple_user):
assert True
client1 = NinjaTestClient(router)
response_happy: NinjaResponse = client1.get("/whoami", user=simple_user)
assert response_happy.status_code == 200
user: AppUserResponseSchema = AppUserResponseSchema.model_validate(
response_happy.json()
)
assert user.id == simple_user.id
response_sad: NinjaResponse = client1.get("/whoami")
assert response_sad.status_code == 401
@pytest.mark.django_db
def test_authenticated_tenanted_request(
client: DjangoTestClient,
simple_user: AppUser,
simple_tenant: AppTenant,
fake_token_generator: FakeAuth0TokenGenerator,
):
simple_tenant.app_users.add(simple_user)
access_token = fake_token_generator.get_fake_token_for_user(simple_user)
response: HttpResponse = client.get(
"/api/v1/access-control/tenant/access-check",
HTTP_AUTHORIZATION=f"Bearer {access_token}",
HTTP_TENANT_ID=f"{simple_tenant.id}",
)
assert response.status_code == 200
response_data = response.json()
parsed_data = TenantedAccessCheckResponseSchema.model_validate(response_data)
assert parsed_data.app_tenant.id == simple_tenant.id
assert parsed_data.app_user.id == simple_user.id
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <ninja.router.Router object at 0x109b1a490>, prefix = '/access-control/'
def build_routers(self, prefix: str) -> List[Tuple[str, "Router"]]:
if self.api is not None:
from ninja.main import debug_server_url_reimport
if not debug_server_url_reimport():
> raise ConfigError(
f"Router@'{prefix}' has already been attached to API"
f" {self.api.title}:{self.api.version} "
)
E ninja.errors.ConfigError: Router@'/access-control/' has already been attached to API NinjaAPI:1.0.0
../../../Library/Caches/pypoetry/virtualenvs/some-backend-adgzL-V0-py3.11/lib/python3.11/site-packages/ninja/router.py:367: ConfigError
Versions (please complete the following information):
- Python version: 3.11
- Django version: '4.2.13'
- Django-Ninja version: '1.1.0'
- Pydantic version: '2.7.4'