diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index b94b7dc..1faa95f 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -1,67 +1,80 @@ -#name: Python package -# -#on: -# pull_request: -# -#jobs: -# test: -# name: Unit tests -# runs-on: ubuntu-latest -# steps: -# - name: Checkout -# uses: actions/checkout@v4 -# - name: Set up docker -# uses: docker-practice/actions-setup-docker@master -# - name: Run postgres -# run: | -# docker run -d -p 5432:5432 -e POSTGRES_HOST_AUTH_METHOD=trust --name db-test postgres:15-alpine -# - uses: actions/setup-python@v4 -# with: -# python-version: '3.11' -# - name: Install dependencies -# run: | -# python -m ensurepip -# python -m pip install --upgrade --no-cache-dir pip -# python -m pip install --upgrade --no-cache-dir -r requirements.txt -r requirements.dev.txt -# - name: Migrate DB -# run: | -# DB_DSN=postgresql://postgres@localhost:5432/postgres alembic upgrade head -# - name: Build coverage file -# run: | -# DB_DSN=postgresql://postgres@localhost:5432/postgres pytest --junitxml=pytest.xml --cov-report=term-missing:skip-covered --cov=achievement_api tests/ | tee pytest-coverage.txt -# - name: Print report -# if: always() -# run: | -# cat pytest-coverage.txt -# - name: Pytest coverage comment -# uses: MishaKav/pytest-coverage-comment@main -# with: -# pytest-coverage-path: ./pytest-coverage.txt -# title: Coverage Report -# badge-title: Code Coverage -# hide-badge: false -# hide-report: false -# create-new-comment: false -# hide-comment: false -# report-only-changed-files: false -# remove-link-from-badge: false -# junitxml-path: ./pytest.xml -# junitxml-title: Summary -# linting: -# runs-on: ubuntu-latest -# steps: -# - uses: actions/checkout@v4 -# - uses: actions/setup-python@v2 -# with: -# python-version: 3.11 -# - uses: isort/isort-action@master -# with: -# requirementsFiles: "requirements.txt requirements.dev.txt" -# - uses: psf/black@stable -# - name: Comment if linting failed -# if: ${{ failure() }} -# uses: thollander/actions-comment-pull-request@v2 -# with: -# message: | -# :poop: Code linting failed, use `black` and `isort` to fix it. +name: Python tests +on: + pull_request: + + +jobs: + test: + name: Unit tests + runs-on: ubuntu-latest + services: + postgres: + image: postgres:15 + env: + POSTGRES_HOST_AUTH_METHOD: trust + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + -p 5432:5432 + steps: + - name: Checkout + uses: actions/checkout@v4 + - uses: actions/setup-python@v4 + with: + python-version: "3.11" + - name: Install dependencies + run: | + python -m ensurepip + python -m pip install --upgrade --no-cache-dir pip + python -m pip install --upgrade --no-cache-dir -r requirements.txt -r requirements.dev.txt + - name: Migrate DB + run: | + DB_DSN=postgresql://postgres@localhost:5432/postgres alembic upgrade head + - name: Build coverage file + id: pytest + run: | + DB_DSN=postgresql://postgres@localhost:5432/postgres pytest --junitxml=pytest.xml --cov-report=term-missing:skip-covered --cov=achievement_api tests/ | tee pytest-coverage.txt + exit ${PIPESTATUS[0]} + - name: Print report + if: always() + run: | + cat pytest-coverage.txt + - name: Pytest coverage comment + uses: MishaKav/pytest-coverage-comment@main + if: always() + with: + pytest-coverage-path: ./pytest-coverage.txt + title: Coverage Report + badge-title: Code Coverage + hide-badge: false + hide-report: false + create-new-comment: false + hide-comment: false + report-only-changed-files: false + remove-link-from-badge: false + junitxml-path: ./pytest.xml + junitxml-title: Summary + - name: Fail on pytest errors + if: steps.pytest.outcome == 'failure' + run: exit 1 + + linting: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v2 + with: + python-version: 3.11 + - uses: isort/isort-action@master + with: + requirementsFiles: "requirements.txt requirements.dev.txt" + - uses: psf/black@stable + - name: Comment if linting failed + if: failure() + uses: thollander/actions-comment-pull-request@v2 + with: + message: | + :poop: Code linting failed, use `black` and `isort` to fix it. diff --git a/Makefile b/Makefile index 9e69767..c269d6f 100644 --- a/Makefile +++ b/Makefile @@ -8,9 +8,15 @@ venv: python3.11 -m venv venv format: - autoflake -r --in-place --remove-all-unused-imports ./achievement_api - isort ./achievement_api - black ./achievement_api + source ./venv/bin/activate && autoflake -r --in-place --remove-all-unused-imports ./achievement_api + source ./venv/bin/activate && isort ./achievement_api + source ./venv/bin/activate && black ./achievement_api + source ./venv/bin/activate && autoflake -r --in-place --remove-all-unused-imports ./tests + source ./venv/bin/activate && isort ./tests + source ./venv/bin/activate && black ./tests + source ./venv/bin/activate && autoflake -r --in-place --remove-all-unused-imports ./migrations + source ./venv/bin/activate && isort ./migrations + source ./venv/bin/activate && black ./migrations db: docker run -d -p 5432:5432 -e POSTGRES_HOST_AUTH_METHOD=trust --name db-achievement_api postgres:15 diff --git a/achievement_api/routes/base.py b/achievement_api/routes/base.py index ef5ddd5..37c5836 100644 --- a/achievement_api/routes/base.py +++ b/achievement_api/routes/base.py @@ -17,7 +17,7 @@ description='Программный интерфейс ачивок для Твой ФФ!', version=__version__, # Отключаем нелокальную документацию - root_path=settings.ROOT_PATH if __version__ != 'dev' else '/', + root_path=settings.ROOT_PATH if __version__ != 'dev' else '', docs_url=None if __version__ != 'dev' else '/docs', redoc_url=None, ) diff --git a/achievement_api/routes/user.py b/achievement_api/routes/user.py index b3fdd4c..f694c8c 100644 --- a/achievement_api/routes/user.py +++ b/achievement_api/routes/user.py @@ -1,7 +1,6 @@ import logging -from auth_lib.fastapi import UnionAuth -from fastapi import APIRouter, Depends, HTTPException +from fastapi import APIRouter from fastapi_sqlalchemy import db from pydantic import BaseModel, ConfigDict @@ -33,5 +32,7 @@ class UserGet(BaseModel): @router.get("/{user_id}") def get_all_achievements(user_id: int) -> UserGet: - achievements = db.session.query(Achievement).join(AchievementReciever).where(AchievementReciever.user_id == user_id).all() + achievements = ( + db.session.query(Achievement).join(AchievementReciever).where(AchievementReciever.user_id == user_id).all() + ) return UserGet(user_id=user_id, achievement=achievements) diff --git a/migrations/env.py b/migrations/env.py index 7edd075..79bb606 100644 --- a/migrations/env.py +++ b/migrations/env.py @@ -2,9 +2,11 @@ from alembic import context from sqlalchemy import engine_from_config, pool + from achievement_api.models.base import Base from achievement_api.settings import get_settings + # this is the Alembic Config object, which provides # access to the values within the .ini file in use. config = context.config diff --git a/migrations/versions/c06c1cd9939c_init.py b/migrations/versions/c06c1cd9939c_init.py index 80e6f13..84901fd 100644 --- a/migrations/versions/c06c1cd9939c_init.py +++ b/migrations/versions/c06c1cd9939c_init.py @@ -5,8 +5,9 @@ Create Date: 2023-08-18 03:21:29.803878 """ -from alembic import op + import sqlalchemy as sa +from alembic import op # revision identifiers, used by Alembic. diff --git a/requirements.txt b/requirements.txt index 9fd26f2..429fa9c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,3 +9,4 @@ pydantic[dotenv] pydantic-settings SQLAlchemy uvicorn +python-multipart diff --git a/achievement_api/static/.gitkeep b/static/.gitkeep similarity index 100% rename from achievement_api/static/.gitkeep rename to static/.gitkeep diff --git a/tests/conftest.py b/tests/conftest.py index e69de29..38b1b30 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -0,0 +1,9 @@ +import pytest +from fastapi.testclient import TestClient + +from achievement_api.routes.base import app + + +@pytest.fixture +def client(): + yield TestClient(app) diff --git a/tests/test_routes/test_openapi.py b/tests/test_routes/test_openapi.py new file mode 100644 index 0000000..94e78d6 --- /dev/null +++ b/tests/test_routes/test_openapi.py @@ -0,0 +1,3 @@ +def test_unprocessable_jsons_no_token(client): + response = client.get(f"/openapi.json") + assert response.status_code == 200