import pytest from fastapi.testclient import TestClient from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from sqlalchemy.pool import StaticPool from main import app from database import Base, get_db from models import School, ClassAccount, TeacherAccount # Set up an in-memory SQLite database for testing SQLALCHEMY_DATABASE_URL = "sqlite:///:memory:" engine = create_engine( SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}, poolclass=StaticPool ) TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) # Override the database dependency def override_get_db(): db = TestingSessionLocal() try: yield db finally: db.close() app.dependency_overrides[get_db] = override_get_db client = TestClient(app) @pytest.fixture(scope="module", autouse=True) def setup_database(): # Create tables Base.metadata.create_all(bind=engine) db = TestingSessionLocal() # Seed mock data for tests school = School(school_id="test-school", name="Test School", udise_code="123456") db.add(school) cls = ClassAccount(class_id="test-class", grade=3, section="A", year=2024, school_id="test-school") db.add(cls) teacher = TeacherAccount( teacher_id="test-teacher", name="Test Teacher", phone="1234567890", school_id="test-school", is_active=True ) db.add(teacher) db.commit() db.close() yield # Teardown Base.metadata.drop_all(bind=engine) def test_health_check(): response = client.get("/api/health") assert response.status_code == 200 assert response.json() == {"status": "ok"} def test_otp_request(): response = client.post("/api/auth/teacher/otp/request", json={"phone": "1234567890"}) assert response.status_code == 200 assert "OTP sent successfully" in response.json()["message"] def test_otp_verify(): response = client.post("/api/auth/teacher/otp/verify", json={"phone": "1234567890", "otp": "1234"}) assert response.status_code == 200 data = response.json() assert "access_token" in data assert data["role"] == "teacher" assert data["user_id"] == "test-teacher" def test_otp_verify_invalid_phone(): response = client.post("/api/auth/teacher/otp/verify", json={"phone": "0000000000", "otp": "1234"}) assert response.status_code == 404 def test_field_staff_onboard_teacher(): payload = { "name": "New Onboarded Teacher", "phone": "9998887770", "class_ids": ["test-class"] } response = client.post("/api/staff/schools/test-school/teachers/onboard", json=payload) assert response.status_code == 200 data = response.json() assert "teacher_id" in data assert data["message"] == "Teacher successfully onboarded" def test_field_staff_onboard_teacher_invalid_school(): payload = { "name": "Invalid Teacher", "phone": "9998887771", "class_ids": ["test-class"] } response = client.post("/api/staff/schools/invalid-school/teachers/onboard", json=payload) assert response.status_code == 404