"""Opt-in fixtures for the live-Gitea integration tests. Tests in this directory are marked ``integration`` and skipped unless ``AEGIS_INTEGRATION=1``. The default test run never touches Docker. """ from __future__ import annotations import os import re from collections.abc import Iterator from dataclasses import dataclass, field from pathlib import Path import pytest from tests.integration.harness import ( GiteaInstance, HarnessError, start_gitea, stop_gitea, unique, ) _HERE = Path(__file__).parent.resolve() ENABLE_ENV = "AEGIS_INTEGRATION" def integration_enabled() -> bool: """Return True when the opt-in env var is set.""" return os.environ.get(ENABLE_ENV) == "1" def pytest_configure(config: pytest.Config) -> None: """Register the ``integration`` marker (idempotent with pyproject).""" config.addinivalue_line( "markers", "integration: live Gitea in Docker, opt-in via AEGIS_INTEGRATION=1" ) def _is_integration(item: pytest.Item) -> bool: try: return _HERE in Path(str(item.path)).resolve().parents except (OSError, ValueError): # pragma: no cover - defensive return False def pytest_collection_modifyitems(config: pytest.Config, items: list[pytest.Item]) -> None: """Mark and (unless opted in) skip every test under tests/integration.""" selected = [item for item in items if _is_integration(item)] skip = pytest.mark.skip(reason=f"live Gitea tests need {ENABLE_ENV}=1 and Docker") for item in selected: item.add_marker(pytest.mark.integration) if not integration_enabled(): item.add_marker(skip) if selected and len(selected) == len(items): # An integration-only run covers almost none of src/, so the unit-test # coverage gate does not apply to it. # pytest-cov reads its options from the early-config namespace. for namespace in (config.option, config.known_args_namespace): if getattr(namespace, "cov_fail_under", None) is not None: namespace.cov_fail_under = 0 @pytest.fixture(scope="session") def gitea() -> Iterator[GiteaInstance]: """A throwaway Gitea in Docker, shared by the whole session.""" try: instance = start_gitea() except HarnessError as exc: pytest.fail(f"integration harness could not start Gitea: {exc}", pytrace=False) try: yield instance finally: stop_gitea(instance) @pytest.fixture def unique_name(request: pytest.FixtureRequest) -> str: """A unique, Gitea-safe name derived from the test name.""" slug = re.sub(r"[^a-z0-9]+", "-", request.node.name.lower()).strip("-")[:16].strip("-") return unique(slug or "t") @dataclass class RegularUser: """A non-admin user with its own full-scope token.""" login: str password: str = field(repr=False) token: str = field(repr=False) @pytest.fixture(scope="session") def regular_user(gitea: GiteaInstance) -> RegularUser: """A non-admin user plus a full-scope token minted for that user.""" login, password = gitea.create_user(gitea.unique("it-user")) token = gitea.mint_token(login, password, ["all"]) return RegularUser(login=login, password=password, token=token)