From 4b403d91f13001717dea8416638e1bab15b0c0d8 Mon Sep 17 00:00:00 2001 From: Brian Obot Date: Fri, 27 Feb 2026 11:00:55 +0100 Subject: [PATCH] Update Factory for User Model to ensure consistency --- .coverage | Bin 53248 -> 53248 bytes .github/workflows/audit.yml | 2 +- .github/workflows/auto_merge.yml | 17 ++++++++++ .../{run_test.yml => create_pull_request.yml} | 32 +++++++++++++++++- app/middlewares.py | 2 +- app/models/tests/factories.py | 4 +-- app/routers/tests/conftest.py | 2 +- app/routers/tests/test_auth.py | 22 +++++++----- app/services/auth.py | 2 +- conftest.py | 1 + 10 files changed, 69 insertions(+), 15 deletions(-) create mode 100644 .github/workflows/auto_merge.yml rename .github/workflows/{run_test.yml => create_pull_request.yml} (60%) diff --git a/.coverage b/.coverage index c94310c595b1d7a55a56a118af4573fe37d23daf..1114189f42a27132106890d8d188295ee272a886 100644 GIT binary patch delta 89 zcmV-f0H*(dpaX!Q1F!~w0b!E|fF>I@4K58I4Hpa*3=Inl3jqrG3h4^l3d;(@31PDl v5E%)xV2RZO9vl+{0SP)6c0PZ5dt;vgl{Y^>KkuL4e{QqE^Y=cpRE?}cT`3)a delta 90 zcmV-g0HyzcpaX!Q1F!~w0br8{fF>I?4J{2G4HgU(3=9hj3jhlE3g`;j3d#z>31G7k w5Eu!wVTsiP9~~0}0SP=8c0PZ5dt;vgl{Y^>KkuL4f3CIM^ZdOJvs8_&LVYA2WdHyG diff --git a/.github/workflows/audit.yml b/.github/workflows/audit.yml index 80cad71..749cb12 100644 --- a/.github/workflows/audit.yml +++ b/.github/workflows/audit.yml @@ -2,7 +2,7 @@ name: Dependency Security Audit on: push: - branches: [ "master" ] + branches: [ "dev" ] jobs: security-scan: diff --git a/.github/workflows/auto_merge.yml b/.github/workflows/auto_merge.yml new file mode 100644 index 0000000..7b8e389 --- /dev/null +++ b/.github/workflows/auto_merge.yml @@ -0,0 +1,17 @@ +name: Auto Merge PR + +on: + pull_request: + branches: + - master + +jobs: + auto-merge: + runs-on: ubuntu-latest + steps: + - name: Automatically Merge PR + uses: pascalgn/automerge-action@v0.16.4 + env: + GITHUB_TOKEN: ${{ secrets.MY_PERSONAL_TOKEN }} + MERGE_METHOD: merge # or 'squash' or 'rebase' + MERGE_LABELS: "" diff --git a/.github/workflows/run_test.yml b/.github/workflows/create_pull_request.yml similarity index 60% rename from .github/workflows/run_test.yml rename to .github/workflows/create_pull_request.yml index d4d63c1..105cf0c 100644 --- a/.github/workflows/run_test.yml +++ b/.github/workflows/create_pull_request.yml @@ -3,7 +3,7 @@ name: Unit Tests on: push: branches: - - master + - dev jobs: test: @@ -60,3 +60,33 @@ jobs: run: | mkdir logs pytest -s + + create_pull_request: + runs-on: ubuntu-latest + needs: test # This creates the dependency link + if: github.actor == 'brianobot' + permissions: + contents: write + pull-requests: write + env: + GITHUB_TOKEN: ${{ secrets.MY_PERSONAL_TOKEN }} + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Create Pull Request + run: | + # Check if a PR already exists from dev to master + PR_EXISTS=$(gh pr list --head dev --base master --state open --json number -q '.[0].number') + + if [ -z "$PR_EXISTS" ]; then + echo "No open PR found. Creating a new one..." + gh pr create \ + --head dev \ + --base master \ + --title "Auto-PR: Dev to Master" \ + --body "Automated PR triggered by push from ${{ github.actor }}" \ + --assignee "${{ github.actor }}" + else + echo "PR already exists: #$PR_EXISTS. Skipping creation." + fi diff --git a/app/middlewares.py b/app/middlewares.py index 400fc94..a20409b 100644 --- a/app/middlewares.py +++ b/app/middlewares.py @@ -12,8 +12,8 @@ async def log_request_middleware(request: Request, call_next): log_dict = { "url": request.url.path, "method": request.method, - "process_time": f"{(time.time() - start):.2f}s", "status_code": response.status_code, + "process_time": f"{(time.time() - start):.2f}s", } logger.info(log_dict) diff --git a/app/models/tests/factories.py b/app/models/tests/factories.py index ef5fb10..33e3667 100644 --- a/app/models/tests/factories.py +++ b/app/models/tests/factories.py @@ -9,10 +9,10 @@ class UserFactory(factory.alchemy.SQLAlchemyModelFactory): - class Meta: + class Meta: # type: ignore model = UserDB sqlalchemy_session_factory = TestingSessionLocal sqlalchemy_session_persistence = "commit" - email = faker.email().lower() + email = factory.Faker("email") # type: ignore password = get_password_hash("password") diff --git a/app/routers/tests/conftest.py b/app/routers/tests/conftest.py index 5bff8a8..98e1903 100644 --- a/app/routers/tests/conftest.py +++ b/app/routers/tests/conftest.py @@ -8,7 +8,7 @@ @pytest.fixture -async def signup_data() -> dict: +async def signup_data() -> dict[str, str]: return { "email": faker.email(), "password": faker.password(length=8), diff --git a/app/routers/tests/test_auth.py b/app/routers/tests/test_auth.py index f9e2a22..92fba2d 100644 --- a/app/routers/tests/test_auth.py +++ b/app/routers/tests/test_auth.py @@ -3,6 +3,7 @@ from app.main import app from app.models import User as UserDB +from app.redis_manager import redis_manager from app.schemas.auth import UserModel @@ -63,7 +64,6 @@ async def sign_up_user(signup_data: dict): async def mutate_cache_item(key: str, value: dict): # to be used as a side effect to mutate cache item - from app.redis_manager import redis_manager redis_manager.cache_json_item(key, value) @@ -78,15 +78,19 @@ async def test_initiate_password_reset(client: AsyncClient, signup_data: dict): async def test_verify_reset_password_otp(client: AsyncClient, user: UserDB): - await mutate_cache_item(f"reset-code-{user.email}", {"code": "0000"}) - data = {"email": user.email, "code": "0000"} - response: Response = await client.post("/v1/auth/verify_password_reset", json=data) + # Seed the value to be validated against + redis_manager.cache_json_item(f"reset-code-{user.email}", {"code": "0000"}) + verification_data = {"email": user.email, "code": "0000"} + response: Response = await client.post( + "/v1/auth/verify_password_reset", json=verification_data + ) assert response.status_code == 200 - assert response.json().get("detail") == "Code is Correct" + assert response.json().get("detail") == "Verification is Successful" async def test_reset_password(client: AsyncClient, user: UserDB): - await mutate_cache_item(f"reset-code-{user.email}", {"code": "0000"}) + # Seed the value to be validated against + redis_manager.cache_json_item(f"reset-code-{user.email}", {"code": "0000"}) data = {"new_password": "password", "email": user.email, "code": "0000"} response: Response = await client.post("/v1/auth/reset_password", json=data) assert response.status_code == 200 @@ -94,7 +98,8 @@ async def test_reset_password(client: AsyncClient, user: UserDB): async def test_reset_password_fails(client: AsyncClient, user: UserDB): - await mutate_cache_item(f"reset-code-{user.email}", {"code": "0000"}) + # Seed the value to be validated against + redis_manager.cache_json_item(f"reset-code-{user.email}", {"code": "0000"}) data = {"new_password": "password", "email": user.email, "code": "1111"} response: Response = await client.post("/v1/auth/reset_password", json=data) assert response.status_code == 400 @@ -146,7 +151,8 @@ async def test_logout(client: AsyncClient, auth_header: dict[str, str]): async def test_get_user_detail( - client: AsyncClient, user: UserDB, auth_header: dict[str, str] + client: AsyncClient, + auth_header: dict[str, str], ): response: Response = await client.get("/v1/auth/me", headers=auth_header) assert response.status_code == 200 diff --git a/app/services/auth.py b/app/services/auth.py index 7bb41c7..5ae6087 100644 --- a/app/services/auth.py +++ b/app/services/auth.py @@ -159,7 +159,7 @@ async def verify_reset_password_otp(code: str, email: str, session: AsyncSession if not user: raise HTTPException(status_code=400, detail="Invalid Reset Code") - return {"detail": "Code is Correct"} + return {"detail": "Verification is Successful"} async def reset_password( diff --git a/conftest.py b/conftest.py index 8e9e2ff..9d281b6 100644 --- a/conftest.py +++ b/conftest.py @@ -77,6 +77,7 @@ async def user(session: AsyncSession): session.add(user) await session.commit() await session.refresh(user) + await session.flush() return user