feat: add working tests
This commit is contained in:
		
							parent
							
								
									cd7a5431e9
								
							
						
					
					
						commit
						3d7217ec69
					
				
					 10 changed files with 80 additions and 21 deletions
				
			
		|  | @ -6,7 +6,7 @@ from sqlalchemy import pool | |||
| from alembic import context | ||||
| 
 | ||||
| from foxnouns.db import Base | ||||
| from foxnouns.settings import SYNC_DATABASE_URL | ||||
| from foxnouns.db.sync import SYNC_DATABASE_URL | ||||
| 
 | ||||
| # this is the Alembic Config object, which provides | ||||
| # access to the values within the .ini file in use. | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| from quart import Quart, make_response, jsonify, request, g | ||||
| from quart import Quart, request, g | ||||
| from quart_schema import QuartSchema, RequestSchemaValidationError | ||||
| 
 | ||||
| from .blueprints import users_blueprint | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| from pydantic import BaseModel, Field, field_validator | ||||
| from quart import Blueprint, request | ||||
| from quart import Blueprint | ||||
| from quart_schema import validate_response, validate_request | ||||
| 
 | ||||
| from foxnouns.db.aio import async_session | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| from sqlalchemy import URL | ||||
| from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker | ||||
| 
 | ||||
| from foxnouns.settings import DATABASE | ||||
| from foxnouns.settings import DATABASE, ECHO_SQL | ||||
| 
 | ||||
| ASYNC_DATABASE_URL = URL.create( | ||||
|     "postgresql+asyncpg", | ||||
|  | @ -11,5 +11,5 @@ ASYNC_DATABASE_URL = URL.create( | |||
|     database=DATABASE["NAME"], | ||||
| ) | ||||
| 
 | ||||
| engine = create_async_engine(ASYNC_DATABASE_URL) | ||||
| engine = create_async_engine(ASYNC_DATABASE_URL, echo=ECHO_SQL) | ||||
| async_session = async_sessionmaker(engine, expire_on_commit=False) | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| from sqlalchemy import URL, create_engine | ||||
| 
 | ||||
| from foxnouns.settings import DATABASE | ||||
| from foxnouns.settings import DATABASE, ECHO_SQL | ||||
| 
 | ||||
| SYNC_DATABASE_URL = URL.create( | ||||
|     "postgresql+psycopg", | ||||
|  | @ -10,4 +10,4 @@ SYNC_DATABASE_URL = URL.create( | |||
|     database=DATABASE["NAME"], | ||||
| ) | ||||
| 
 | ||||
| engine = create_engine(SYNC_DATABASE_URL) | ||||
| engine = create_engine(SYNC_DATABASE_URL, echo=ECHO_SQL) | ||||
|  |  | |||
|  | @ -1,5 +1,3 @@ | |||
| import re | ||||
| 
 | ||||
| from pydantic import Field | ||||
| 
 | ||||
| from . import BaseSnowflakeModel | ||||
|  |  | |||
|  | @ -20,3 +20,6 @@ SHORT_DOMAIN = env("SHORT_DOMAIN", "prns.localhost") | |||
| 
 | ||||
| # Secret key for signing tokens, generate with (for example) `openssl rand -base64 32` | ||||
| SECRET_KEY = env("SECRET_KEY") | ||||
| 
 | ||||
| # Whether to echo SQL statements to the logs. | ||||
| ECHO_SQL = env.bool("ECHO_SQL", False) | ||||
|  |  | |||
|  | @ -1,8 +1,61 @@ | |||
| import pytest | ||||
| import pytest_asyncio | ||||
| from sqlalchemy import text, delete | ||||
| 
 | ||||
| from foxnouns.db import Base | ||||
| from foxnouns.settings import DATABASE | ||||
| 
 | ||||
| 
 | ||||
| # Override the database name to the testing database | ||||
| DATABASE["NAME"] = f"{DATABASE['NAME']}_test" | ||||
| 
 | ||||
| 
 | ||||
| def pytest_collection_modifyitems(items): | ||||
|     """Ensure that all async tests use the same event loop.""" | ||||
| 
 | ||||
|     pytest_asyncio_tests = ( | ||||
|         item for item in items if pytest_asyncio.is_async_test(item) | ||||
|     ) | ||||
|     session_scope_marker = pytest.mark.asyncio(scope="session") | ||||
|     for async_test in pytest_asyncio_tests: | ||||
|         async_test.add_marker(session_scope_marker, append=False) | ||||
| 
 | ||||
| 
 | ||||
| @pytest.fixture(scope="session", autouse=True) | ||||
| def setup(): | ||||
|     """Migrate the testing database to the latest migration, and once the tests complete, clear the database again.""" | ||||
| 
 | ||||
|     from foxnouns.db.sync import engine | ||||
|     from alembic import command, config | ||||
| 
 | ||||
|     cfg = config.Config("alembic.ini") | ||||
|     cfg.attributes["connection"] = engine.connect() | ||||
|     command.upgrade(cfg, "head") | ||||
| 
 | ||||
|     yield | ||||
| 
 | ||||
|     with engine.begin() as session: | ||||
|         Base.metadata.drop_all(session) | ||||
|         session.execute(text("DROP TABLE alembic_version")) | ||||
|         session.commit() | ||||
| 
 | ||||
| 
 | ||||
| @pytest.fixture(scope="function", autouse=True) | ||||
| def clean_tables_after_tests(): | ||||
|     """Clean tables after every test.""" | ||||
| 
 | ||||
|     yield | ||||
| 
 | ||||
|     from foxnouns.db.sync import engine | ||||
| 
 | ||||
|     with engine.begin() as session: | ||||
|         for table in reversed(Base.metadata.sorted_tables): | ||||
|             session.execute(delete(table)) | ||||
|         session.commit() | ||||
| 
 | ||||
| 
 | ||||
| @pytest_asyncio.fixture(scope="session", autouse=True) | ||||
| async def setup(): | ||||
|     print("hello from setup!") | ||||
|     yield | ||||
|     print("bye from setup!") | ||||
| async def app(): | ||||
|     from foxnouns.app import app | ||||
| 
 | ||||
|     return app | ||||
|  |  | |||
|  | @ -1,8 +0,0 @@ | |||
| import pytest | ||||
| 
 | ||||
| from foxnouns import hello | ||||
| 
 | ||||
| 
 | ||||
| @pytest.mark.asyncio | ||||
| async def test_hello(): | ||||
|     assert (await hello()) == "Hello world!" | ||||
							
								
								
									
										13
									
								
								tests/test_users.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								tests/test_users.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | |||
| import pytest | ||||
| from quart import Quart | ||||
| 
 | ||||
| 
 | ||||
| @pytest.mark.asyncio | ||||
| class TestUsers: | ||||
|     async def test_get_me_returns_403_if_unauthenticated(self, app: Quart): | ||||
|         resp = await app.test_client().get("/api/v2/users/@me") | ||||
|         assert resp.status_code == 403 | ||||
| 
 | ||||
|     async def test_get_users_returns_404_if_user_not_found(self, app: Quart): | ||||
|         resp = await app.test_client().get("/api/v2/users/unknown_user") | ||||
|         assert resp.status_code == 404 | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue