Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
name: CI Pipeline

# Trigger this workflow on Push to specific branches OR on Pull Requests to main
on:
push:
branches: [ "dev" ]
pull_request:
branches: [ "main" ]

jobs:
# --- JOB 1: Test the Frontend ---
frontend-build:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./client

steps:
- name: Check out code
uses: actions/checkout@v4

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '24'
cache: 'npm'
cache-dependency-path: client/package-lock.json

- name: Install Dependencies
run: npm ci

- name: Build (Checks for Type Errors)
run: npm run build
env:
# We add dummy vars because the build needs them,
# we don't need real secrets just to check syntax.
NEXT_PUBLIC_API_URL: "http://localhost:8000"
NEXT_PUBLIC_FIREBASE_API_KEY: "dummy"
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN: "dummy"
NEXT_PUBLIC_FIREBASE_PROJECT_ID: "dummy"
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET: "dummy"
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID: "dummy"
NEXT_PUBLIC_FIREBASE_APP_ID: "dummy"

# --- JOB 2: Test the Backend ---
backend-test:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./server

steps:
- name: Check out code
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.13'
cache: 'pip'

- name: Install Dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install httpx pytest # Ensure test tools are installed

- name: Run Tests
# We skip tests that require real Gemini credentials for now
# using the '-m "not integration"' marker if we had one,
# or just basic unit tests.
run: |
pytest
env:
# Dummy keys so the app creates the 'client' object without crashing
GEMINI_API_KEY: "dummy_key"
GOOGLE_APPLICATION_CREDENTIALS: "dummy_creds.json"
File renamed without changes.
26 changes: 15 additions & 11 deletions server/tests/test_main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import pytest
from fastapi.testclient import TestClient
from server.main import app
from main import app


@pytest.fixture(autouse=True)
Expand All @@ -10,30 +10,35 @@ def mock_firebase(mocker):
The autouse=True means this runs automatically for all tests.
"""

# Create our mock Firestore client
# Create the Mock DB Client
class MockDocRef:
id = "fake_doc_id_123"

mock_db_client = mocker.Mock()
# Ensure nested calls like db.collection().add() return valid mocks
mock_db_client.collection.return_value.add.return_value = (None, MockDocRef())
mock_db_client.collection.return_value.document.return_value = mocker.Mock()

# Mock the components in the correct order (before client creation)
# Patch the External Firebase Calls (so they don't hit the network)
mocker.patch("firebase_admin.credentials.Certificate")
mocker.patch("firebase_admin.initialize_app")
mock_fs_client = mocker.patch("firebase_admin.firestore.client")
mock_fs_client.return_value = mock_db_client

# IMPORTANT: Set the global db variable in main.py
import server.main
# PATCH THE GLOBAL DB VARIABLE
import main

server.main.db = mock_db_client
# We overwrite the 'db' variable inside the 'main' module
main.db = mock_db_client

# Clean up after the test
yield
server.main.db = None

# 4. Clean up
main.db = None

# Now create the client (after Firebase is mocked)

# It is safer to use a fixture for the client to ensure fresh state,
# but global is okay for simple tests if the app is stateless.
client = TestClient(app)


Expand Down Expand Up @@ -126,8 +131,7 @@ class MockGeminiResponse:
)

assert response.status_code == 200

assert response.json() == {"tailored_resume": "This is a fake tailored resume."}
assert response.json().get("tailored_resume") == "This is a fake tailored resume."


def test_fixture_is_working(sample_job_data):
Expand Down