diff --git a/.github/workflows/build_and_publish.yml b/.github/workflows/build_and_publish.yml index a236b7c..660c80e 100644 --- a/.github/workflows/build_and_publish.yml +++ b/.github/workflows/build_and_publish.yml @@ -9,9 +9,9 @@ jobs: name: Build and publish Python 🐍 distributions 📦 to PyPI and TestPyPI runs-on: ubuntu-latest steps: - - uses: actions/checkout@master + - uses: actions/checkout@v3 - name: Set up Python 3.11 - uses: actions/setup-python@v3 + uses: actions/setup-python@v4 with: python-version: "3.11" - name: Install dependencies diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 7ddb096..c2ee22c 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -8,8 +8,8 @@ jobs: linting: runs-on: ubuntu-latest steps: - - uses: actions/checkout@master - - uses: actions/setup-python@v3 + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 with: python-version: 3.11 - uses: isort/isort-action@master diff --git a/README.md b/README.md index c653a19..b5ca884 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,8 @@ ## Примеры использования ```python from auth_lib.fastapi import UnionAuth +from fastapi import APIRouter, Depends +router = APIRouter(prefix="/...") ## Чтобы дернуть ручку нужен один скоуп, авторизация обязательна ## Юзкейс https://github.com/profcomff/timetable-api/blob/a374c74cd960941100f6c923ff9c3ff706a1ed09/calendar_backend/routes/room/room.py#L45 @@ -48,3 +50,47 @@ AUTH_AUTO_ERROR: bool = True AUTH_ALLOW_NONE: bool = False ``` + +Пример мока библиотеки: + +Установите нужные завивсимости +```shell +pip install 'auth-lib-profcomff[testing]' +``` + +```python +import pytest +from fastapi.testclient import TestClient +from fastapi import FastAPI + +@pytest.fixture +def client(auth_mock): + yield TestClient(FastAPI()) + +@pytest.mark.authenticated("scope1", "scope2", ...) +def test1(client): + """ + В этом тесте будут выданы скоупы scope1, scope2, + библиотека не будет проверять токен через АПИ, будет просто возвращать + нужный словарь, как будто пользователь авторизован с нужными скоупами + """ + assert 2*2 == 4 + + +@pytest.mark.authenticated() +def test2(client): + """ + В этом тесте скоупов выдано не будет, + но библиотека не будет проверять токен через АПИ, будет просто возвращать + нужный словарь, как будто пользователь авторизован с нужными скоупами + """ + assert 2*2 == 4 + + +def test3(client): + """ + В этом тесте скоупов выдано не будет, библиотека будет проверять + токен через АПИ + """ + assert 2*2 == 4 +``` diff --git a/auth_lib/testing/__init__.py b/auth_lib/testing/__init__.py new file mode 100644 index 0000000..565e213 --- /dev/null +++ b/auth_lib/testing/__init__.py @@ -0,0 +1,5 @@ +try: + from auth_lib.testing.testutils import auth_mock, pytest_configure +except ImportError: + print("You have to install testing requirements") + print("pip install 'auth-lib-profcomff[testing]'") diff --git a/auth_lib/testing/testutils.py b/auth_lib/testing/testutils.py new file mode 100644 index 0000000..d193d9c --- /dev/null +++ b/auth_lib/testing/testutils.py @@ -0,0 +1,33 @@ +from unittest.mock import MagicMock, patch + +import pytest + + +def pytest_configure(config): + config.addinivalue_line( + "markers", "authenticated(*scopes): mark test to mock auth_lib" + ) + + +@pytest.fixture(autouse=True) +def auth_mock(request): + marker: pytest.mark = request.node.get_closest_marker("authenticated") + if not marker: + return (yield) + scopes: tuple[str] = marker.args + session_scopes = [] + for cnt, scope in enumerate(scopes): + session_scopes.append({"id": cnt, "name": scope, "comment": ""}) + _return_val: dict[str, int | list[dict[str, str | int]]] = { + "user_id": 0, + "id": 0, + "session_scopes": session_scopes, + "user_scopes": session_scopes, + } + patcher = patch( + "auth_lib.fastapi.UnionAuth.__call__", + new=MagicMock(return_value=_return_val), + ) + patcher.start() + yield + patcher.stop() diff --git a/setup.py b/setup.py index 76f8b84..df839be 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setup( name="auth_lib_profcomff", - version="2023.03.16.2", + version="2023.04.19", author="Semyon Grigoriev", long_description=readme, long_description_content_type="text/markdown", @@ -14,7 +14,9 @@ install_requires=["requests", "aiohttp", "setuptools"], extras_require={ "fastapi": ["fastapi", "starlette", "pydantic"], + "testing": ["pytest"], }, + entry_points={"pytest11": ["pytest_auth_lib = auth_lib.testing"]}, classifiers=[ "Programming Language :: Python :: 3.11", ],