[tests] migrate to tests without docker containers
This commit is contained in:
parent
c41620a02f
commit
98fa2187d4
13 changed files with 146 additions and 189 deletions
|
@ -1,30 +0,0 @@
|
||||||
version: '3'
|
|
||||||
|
|
||||||
networks:
|
|
||||||
fooder_test:
|
|
||||||
driver: bridge
|
|
||||||
|
|
||||||
services:
|
|
||||||
database:
|
|
||||||
restart: unless-stopped
|
|
||||||
image: postgres
|
|
||||||
networks:
|
|
||||||
- fooder_test
|
|
||||||
env_file:
|
|
||||||
- .env.test
|
|
||||||
|
|
||||||
api:
|
|
||||||
restart: unless-stopped
|
|
||||||
image: registry.domandoman.xyz/fooder/api
|
|
||||||
build:
|
|
||||||
dockerfile: Dockerfile
|
|
||||||
context: .
|
|
||||||
networks:
|
|
||||||
- fooder_test
|
|
||||||
env_file:
|
|
||||||
- .env.test
|
|
||||||
volumes:
|
|
||||||
- ./fooder:/opt/fooder/fooder
|
|
||||||
ports:
|
|
||||||
- "8000:8000"
|
|
||||||
command: "uvicorn fooder.app:app --host 0.0.0.0 --port 8000 --reload"
|
|
|
@ -7,7 +7,7 @@ DB_URI="postgresql+asyncpg://${POSTGRES_USER}:${POSTGRES_PASSWORD}@database/${PO
|
||||||
ECHO_SQL=0
|
ECHO_SQL=0
|
||||||
|
|
||||||
SECRET_KEY="${SECRET_KEY}" # generate with $ openssl rand -hex 32
|
SECRET_KEY="${SECRET_KEY}" # generate with $ openssl rand -hex 32
|
||||||
REFRESH_SECRET_KEY="${REFRESH_SECRET}" # generate with $ openssl rand -hex 32
|
REFRESH_SECRET_KEY="${REFRESH_SECRET_KEY}" # generate with $ openssl rand -hex 32
|
||||||
ALGORITHM="HS256"
|
ALGORITHM="HS256"
|
||||||
ACCESS_TOKEN_EXPIRE_MINUTES=30
|
ACCESS_TOKEN_EXPIRE_MINUTES=30
|
||||||
REFRESH_TOKEN_EXPIRE_DAYS=30
|
REFRESH_TOKEN_EXPIRE_DAYS=30
|
||||||
|
|
|
@ -16,7 +16,9 @@ if __name__ == "__main__":
|
||||||
from .settings import Settings
|
from .settings import Settings
|
||||||
|
|
||||||
settings = Settings()
|
settings = Settings()
|
||||||
engine = sqlalchemy.create_engine(settings.DB_URI.replace("+asyncpg", ""))
|
engine = sqlalchemy.create_engine(
|
||||||
|
settings.DB_URI.replace("+asyncpg", "").replace("+aiosqlite", "")
|
||||||
|
)
|
||||||
|
|
||||||
if args.create_tables:
|
if args.create_tables:
|
||||||
Base.metadata.create_all(engine)
|
Base.metadata.create_all(engine)
|
||||||
|
|
|
@ -9,10 +9,19 @@ from .settings import Settings
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
settings = Settings.parse_obj({})
|
settings = Settings.parse_obj({})
|
||||||
|
|
||||||
|
if settings.DB_URI.startswith("sqlite"):
|
||||||
|
settings.DB_URI = settings.DB_URI + "?check_same_thread=False"
|
||||||
|
|
||||||
|
"""
|
||||||
|
Asynchronous PostgreSQL database engine.
|
||||||
|
"""
|
||||||
async_engine = create_async_engine(
|
async_engine = create_async_engine(
|
||||||
settings.DB_URI,
|
settings.DB_URI,
|
||||||
pool_pre_ping=True,
|
pool_pre_ping=True,
|
||||||
echo=settings.ECHO_SQL,
|
echo=settings.ECHO_SQL,
|
||||||
|
connect_args=(
|
||||||
|
{"check_same_thread": False} if settings.DB_URI.startswith("sqlite") else {}
|
||||||
|
),
|
||||||
)
|
)
|
||||||
AsyncSessionLocal = async_sessionmaker(
|
AsyncSessionLocal = async_sessionmaker(
|
||||||
bind=async_engine,
|
bind=async_engine,
|
||||||
|
|
6
fooder/test/fixtures/__init__.py
vendored
6
fooder/test/fixtures/__init__.py
vendored
|
@ -3,3 +3,9 @@ from .user import * # noqa
|
||||||
from .product import * # noqa
|
from .product import * # noqa
|
||||||
from .meal import * # noqa
|
from .meal import * # noqa
|
||||||
from .entry import * # noqa
|
from .entry import * # noqa
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def anyio_backend():
|
||||||
|
return "asyncio"
|
||||||
|
|
70
fooder/test/fixtures/client.py
vendored
70
fooder/test/fixtures/client.py
vendored
|
@ -1,31 +1,17 @@
|
||||||
import requests
|
from fooder.app import app
|
||||||
|
from httpx import AsyncClient
|
||||||
import pytest
|
import pytest
|
||||||
import os
|
import httpx
|
||||||
import yaml
|
|
||||||
|
|
||||||
|
|
||||||
def get_api_url(service_name) -> str:
|
|
||||||
with open("docker-compose.test.yml") as f:
|
|
||||||
config = yaml.safe_load(f)
|
|
||||||
|
|
||||||
port = config["services"][service_name]["ports"][0].split(":")[0]
|
|
||||||
|
|
||||||
return f"http://localhost:{port}/"
|
|
||||||
|
|
||||||
|
|
||||||
class Client:
|
class Client:
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
base_url: str,
|
|
||||||
username: str | None = None,
|
username: str | None = None,
|
||||||
password: str | None = None,
|
password: str | None = None,
|
||||||
):
|
):
|
||||||
self.base_url = os.path.join(base_url, "api")
|
self.client = AsyncClient(app=app, base_url="http://testserver/api")
|
||||||
self.session = requests.Session()
|
self.client.headers["Accept"] = "application/json"
|
||||||
self.session.headers["Accept"] = "application/json"
|
|
||||||
|
|
||||||
if username and password:
|
|
||||||
self.login(username, password, True)
|
|
||||||
|
|
||||||
def set_token(self, token: str) -> None:
|
def set_token(self, token: str) -> None:
|
||||||
"""set_token.
|
"""set_token.
|
||||||
|
@ -34,14 +20,14 @@ class Client:
|
||||||
:type token: str
|
:type token: str
|
||||||
:rtype: None
|
:rtype: None
|
||||||
"""
|
"""
|
||||||
self.session.headers["Authorization"] = "Bearer " + token
|
self.client.headers["Authorization"] = "Bearer " + token
|
||||||
|
|
||||||
def create_user(self, username: str, password: str) -> None:
|
async def create_user(self, username: str, password: str) -> None:
|
||||||
data = {"username": username, "password": password}
|
data = {"username": username, "password": password}
|
||||||
response = self.post("user", json=data)
|
response = await self.post("user", json=data)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
|
|
||||||
def login(self, username: str, password: str, force_login: bool) -> None:
|
async def login(self, username: str, password: str, force_login: bool) -> None:
|
||||||
"""login.
|
"""login.
|
||||||
|
|
||||||
:param username:
|
:param username:
|
||||||
|
@ -54,40 +40,40 @@ class Client:
|
||||||
"""
|
"""
|
||||||
data = {"username": username, "password": password}
|
data = {"username": username, "password": password}
|
||||||
|
|
||||||
response = self.post("token", data=data)
|
response = await self.post("token", data=data)
|
||||||
|
|
||||||
if response.status_code != 200:
|
if response.status_code != 200:
|
||||||
if force_login:
|
if force_login:
|
||||||
self.create_user(username, password)
|
await self.create_user(username, password)
|
||||||
return self.login(username, password, False)
|
return await self.login(username, password, False)
|
||||||
else:
|
else:
|
||||||
raise Exception(f"Could not login as {username}")
|
raise Exception(
|
||||||
|
f"Could not login as {username}! Detail: {response.text}"
|
||||||
|
)
|
||||||
|
|
||||||
result = response.json()
|
result = response.json()
|
||||||
self.set_token(result["access_token"])
|
self.set_token(result["access_token"])
|
||||||
|
|
||||||
def get(self, path: str, **kwargs) -> requests.Response:
|
async def get(self, path: str, **kwargs) -> httpx.Response:
|
||||||
return self.session.get(os.path.join(self.base_url, path), **kwargs)
|
return await self.client.get(path, **kwargs)
|
||||||
|
|
||||||
def delete(self, path: str, **kwargs) -> requests.Response:
|
async def delete(self, path: str, **kwargs) -> httpx.Response:
|
||||||
return self.session.delete(os.path.join(self.base_url, path), **kwargs)
|
return await self.client.delete(path, **kwargs)
|
||||||
|
|
||||||
def post(self, path: str, **kwargs) -> requests.Response:
|
async def post(self, path: str, **kwargs) -> httpx.Response:
|
||||||
return self.session.post(os.path.join(self.base_url, path), **kwargs)
|
return await self.client.post(path, **kwargs)
|
||||||
|
|
||||||
def patch(self, path: str, **kwargs) -> requests.Response:
|
async def patch(self, path: str, **kwargs) -> httpx.Response:
|
||||||
return self.session.patch(os.path.join(self.base_url, path), **kwargs)
|
return await self.client.patch(path, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def unauthorized_client() -> Client:
|
def unauthorized_client() -> Client:
|
||||||
return Client(get_api_url("api"))
|
return Client()
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def client(user_payload) -> Client:
|
async def client(user_payload) -> Client:
|
||||||
return Client(
|
client = Client()
|
||||||
get_api_url("api"),
|
await client.login(user_payload["username"], user_payload["password"], True)
|
||||||
username=user_payload["username"],
|
return client
|
||||||
password=user_payload["password"],
|
|
||||||
)
|
|
||||||
|
|
|
@ -2,10 +2,10 @@ import datetime
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.dependency()
|
@pytest.mark.anyio
|
||||||
def test_get_diary(client):
|
async def test_get_diary(client):
|
||||||
today = datetime.date.today().isoformat()
|
today = datetime.date.today().isoformat()
|
||||||
response = client.get("diary", params={"date": today})
|
response = await client.get("diary", params={"date": today})
|
||||||
assert response.status_code == 200, response.json()
|
assert response.status_code == 200, response.json()
|
||||||
|
|
||||||
assert response.json()["date"] == today
|
assert response.json()["date"] == today
|
||||||
|
@ -13,52 +13,56 @@ def test_get_diary(client):
|
||||||
assert len(response.json()["meals"]) == 1
|
assert len(response.json()["meals"]) == 1
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.dependency(depends=["test_get_diary"])
|
@pytest.mark.anyio
|
||||||
def test_diary_add_meal(client, meal_payload_factory):
|
async def test_diary_add_meal(client, meal_payload_factory):
|
||||||
today = datetime.date.today().isoformat()
|
today = datetime.date.today().isoformat()
|
||||||
response = client.get("diary", params={"date": today})
|
response = await client.get("diary", params={"date": today})
|
||||||
|
|
||||||
diary_id = response.json()["id"]
|
diary_id = response.json()["id"]
|
||||||
meal_order = len(response.json()["meals"]) + 1
|
meal_order = len(response.json()["meals"]) + 1
|
||||||
|
|
||||||
response = client.post("meal", json=meal_payload_factory(diary_id, meal_order))
|
response = await client.post(
|
||||||
|
"meal", json=meal_payload_factory(diary_id, meal_order)
|
||||||
|
)
|
||||||
assert response.status_code == 200, response.json()
|
assert response.status_code == 200, response.json()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.dependency(depends=["test_diary_add_meal"])
|
@pytest.mark.anyio
|
||||||
def test_diary_delete_meal(client):
|
async def test_diary_delete_meal(client):
|
||||||
today = datetime.date.today().isoformat()
|
today = datetime.date.today().isoformat()
|
||||||
response = client.get("diary", params={"date": today})
|
response = await client.get("diary", params={"date": today})
|
||||||
|
|
||||||
meals_amount = len(response.json()["meals"])
|
meals_amount = len(response.json()["meals"])
|
||||||
meal_id = response.json()["meals"][0]["id"]
|
meal_id = response.json()["meals"][0]["id"]
|
||||||
|
|
||||||
response = client.delete(f"meal/{meal_id}")
|
response = await client.delete(f"meal/{meal_id}")
|
||||||
assert response.status_code == 200, response.json()
|
assert response.status_code == 200, response.json()
|
||||||
|
|
||||||
response = client.get("diary", params={"date": today})
|
response = await client.get("diary", params={"date": today})
|
||||||
assert response.status_code == 200, response.json()
|
assert response.status_code == 200, response.json()
|
||||||
assert len(response.json()["meals"]) == meals_amount - 1
|
assert len(response.json()["meals"]) == meals_amount - 1
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.dependency(depends=["test_get_diary"])
|
@pytest.mark.anyio
|
||||||
def test_diary_add_entry(client, product_payload_factory, entry_payload_factory):
|
async def test_diary_add_entry(client, product_payload_factory, entry_payload_factory):
|
||||||
today = datetime.date.today().isoformat()
|
today = datetime.date.today().isoformat()
|
||||||
response = client.get("diary", params={"date": today})
|
response = await client.get("diary", params={"date": today})
|
||||||
|
|
||||||
meal_id = response.json()["meals"][0]["id"]
|
meal_id = response.json()["meals"][0]["id"]
|
||||||
|
|
||||||
product_id = client.post("product", json=product_payload_factory()).json()["id"]
|
product_id = (await client.post("product", json=product_payload_factory())).json()[
|
||||||
|
"id"
|
||||||
|
]
|
||||||
|
|
||||||
entry_payload = entry_payload_factory(meal_id, product_id, 100.0)
|
entry_payload = entry_payload_factory(meal_id, product_id, 100.0)
|
||||||
response = client.post("entry", json=entry_payload)
|
response = await client.post("entry", json=entry_payload)
|
||||||
assert response.status_code == 200, response.json()
|
assert response.status_code == 200, response.json()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.dependency(depends=["test_diary_add_entry"])
|
@pytest.mark.anyio
|
||||||
def test_diary_edit_entry(client, entry_payload_factory):
|
async def test_diary_edit_entry(client, entry_payload_factory):
|
||||||
today = datetime.date.today().isoformat()
|
today = datetime.date.today().isoformat()
|
||||||
response = client.get("diary", params={"date": today})
|
response = await client.get("diary", params={"date": today})
|
||||||
|
|
||||||
entry = response.json()["meals"][0]["entries"][0]
|
entry = response.json()["meals"][0]["entries"][0]
|
||||||
id_ = entry["id"]
|
id_ = entry["id"]
|
||||||
|
@ -66,21 +70,21 @@ def test_diary_edit_entry(client, entry_payload_factory):
|
||||||
entry["meal_id"], entry["product"]["id"], entry["grams"] + 100.0
|
entry["meal_id"], entry["product"]["id"], entry["grams"] + 100.0
|
||||||
)
|
)
|
||||||
|
|
||||||
response = client.patch(f"entry/{id_}", json=entry_payload)
|
response = await client.patch(f"entry/{id_}", json=entry_payload)
|
||||||
assert response.status_code == 200, response.json()
|
assert response.status_code == 200, response.json()
|
||||||
assert response.json()["grams"] == entry_payload["grams"]
|
assert response.json()["grams"] == entry_payload["grams"]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.dependency(depends=["test_diary_add_entry"])
|
@pytest.mark.anyio
|
||||||
def test_diary_delete_entry(client):
|
async def test_diary_delete_entry(client):
|
||||||
today = datetime.date.today().isoformat()
|
today = datetime.date.today().isoformat()
|
||||||
response = client.get("diary", params={"date": today})
|
response = await client.get("diary", params={"date": today})
|
||||||
|
|
||||||
entry_id = response.json()["meals"][0]["entries"][0]["id"]
|
entry_id = response.json()["meals"][0]["entries"][0]["id"]
|
||||||
response = client.delete(f"entry/{entry_id}")
|
response = await client.delete(f"entry/{entry_id}")
|
||||||
assert response.status_code == 200, response.json()
|
assert response.status_code == 200, response.json()
|
||||||
|
|
||||||
response = client.get("diary", params={"date": today})
|
response = await client.get("diary", params={"date": today})
|
||||||
assert response.status_code == 200, response.json()
|
assert response.status_code == 200, response.json()
|
||||||
deleted_entries = [
|
deleted_entries = [
|
||||||
entry
|
entry
|
||||||
|
|
|
@ -2,38 +2,42 @@ import datetime
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.dependency()
|
@pytest.mark.anyio
|
||||||
def test_create_meal(
|
async def test_create_meal(
|
||||||
client, meal_payload_factory, product_payload_factory, entry_payload_factory
|
client, meal_payload_factory, product_payload_factory, entry_payload_factory
|
||||||
):
|
):
|
||||||
today = datetime.date.today().isoformat()
|
today = datetime.date.today().isoformat()
|
||||||
response = client.get("diary", params={"date": today})
|
response = await client.get("diary", params={"date": today})
|
||||||
|
|
||||||
diary_id = response.json()["id"]
|
diary_id = response.json()["id"]
|
||||||
meal_order = len(response.json()["meals"]) + 1
|
meal_order = len(response.json()["meals"]) + 1
|
||||||
|
|
||||||
response = client.post("meal", json=meal_payload_factory(diary_id, meal_order))
|
response = await client.post(
|
||||||
|
"meal", json=meal_payload_factory(diary_id, meal_order)
|
||||||
|
)
|
||||||
assert response.status_code == 200, response.json()
|
assert response.status_code == 200, response.json()
|
||||||
|
|
||||||
meal_id = response.json()["id"]
|
meal_id = response.json()["id"]
|
||||||
|
|
||||||
product_id = client.post("product", json=product_payload_factory()).json()["id"]
|
product_id = (await client.post("product", json=product_payload_factory())).json()[
|
||||||
|
"id"
|
||||||
|
]
|
||||||
|
|
||||||
entry_payload = entry_payload_factory(meal_id, product_id, 100.0)
|
entry_payload = entry_payload_factory(meal_id, product_id, 100.0)
|
||||||
response = client.post("entry", json=entry_payload)
|
response = await client.post("entry", json=entry_payload)
|
||||||
assert response.status_code == 200, response.json()
|
assert response.status_code == 200, response.json()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.dependency(depends=["test_create_meal"])
|
@pytest.mark.anyio
|
||||||
def test_save_meal(client, meal_save_payload):
|
async def test_save_meal(client, meal_save_payload):
|
||||||
today = datetime.date.today().isoformat()
|
today = datetime.date.today().isoformat()
|
||||||
response = client.get("diary", params={"date": today})
|
response = await client.get("diary", params={"date": today})
|
||||||
|
|
||||||
meal = response.json()["meals"][0]
|
meal = response.json()["meals"][0]
|
||||||
meal_id = meal["id"]
|
meal_id = meal["id"]
|
||||||
save_payload = meal_save_payload(meal_id)
|
save_payload = meal_save_payload(meal_id)
|
||||||
|
|
||||||
response = client.post(f"meal/{meal_id}/save", json=save_payload)
|
response = await client.post(f"meal/{meal_id}/save", json=save_payload)
|
||||||
assert response.status_code == 200, response.json()
|
assert response.status_code == 200, response.json()
|
||||||
|
|
||||||
preset = response.json()
|
preset = response.json()
|
||||||
|
@ -45,27 +49,27 @@ def test_save_meal(client, meal_save_payload):
|
||||||
assert meal[k] == v, f"{k} != {v}"
|
assert meal[k] == v, f"{k} != {v}"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.dependency(depends=["test_create_meal"])
|
@pytest.mark.anyio
|
||||||
def test_list_presets(client, meal_save_payload):
|
async def test_list_presets(client, meal_save_payload):
|
||||||
response = client.get("preset")
|
response = await client.get("preset")
|
||||||
assert response.status_code == 200, response.json()
|
assert response.status_code == 200, response.json()
|
||||||
assert len(response.json()["presets"]) > 0, response.json()
|
assert len(response.json()["presets"]) > 0, response.json()
|
||||||
|
|
||||||
name = meal_save_payload(0)["name"]
|
name = meal_save_payload(0)["name"]
|
||||||
response = client.get(f"preset?q={name}")
|
response = await client.get(f"preset?q={name}")
|
||||||
assert response.status_code == 200, response.json()
|
assert response.status_code == 200, response.json()
|
||||||
assert len(response.json()["presets"]) > 0, response.json()
|
assert len(response.json()["presets"]) > 0, response.json()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.dependency(depends=["test_list_presets"])
|
@pytest.mark.anyio
|
||||||
def test_create_meal_from_preset(client, meal_from_preset):
|
async def test_create_meal_from_preset(client, meal_from_preset):
|
||||||
today = datetime.date.today().isoformat()
|
today = datetime.date.today().isoformat()
|
||||||
response = client.get("diary", params={"date": today})
|
response = await client.get("diary", params={"date": today})
|
||||||
|
|
||||||
diary_id = response.json()["id"]
|
diary_id = response.json()["id"]
|
||||||
meal_order = len(response.json()["meals"]) + 1
|
meal_order = len(response.json()["meals"]) + 1
|
||||||
|
|
||||||
response = client.get("preset")
|
response = await client.get("preset")
|
||||||
assert response.status_code == 200, response.json()
|
assert response.status_code == 200, response.json()
|
||||||
assert len(response.json()["presets"]) > 0, response.json()
|
assert len(response.json()["presets"]) > 0, response.json()
|
||||||
|
|
||||||
|
@ -77,7 +81,7 @@ def test_create_meal_from_preset(client, meal_from_preset):
|
||||||
preset["id"],
|
preset["id"],
|
||||||
)
|
)
|
||||||
|
|
||||||
response = client.post("meal/from_preset", json=payload)
|
response = await client.post("meal/from_preset", json=payload)
|
||||||
assert response.status_code == 200, response.json()
|
assert response.status_code == 200, response.json()
|
||||||
meal = response.json()
|
meal = response.json()
|
||||||
|
|
||||||
|
@ -88,16 +92,16 @@ def test_create_meal_from_preset(client, meal_from_preset):
|
||||||
assert meal[k] == v, f"{k} != {v}"
|
assert meal[k] == v, f"{k} != {v}"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.dependency(depends=["test_list_presets"])
|
@pytest.mark.anyio
|
||||||
def test_delete_preset(client):
|
async def test_delete_preset(client):
|
||||||
presets = client.get("preset").json()["presets"]
|
presets = (await client.get("preset")).json()["presets"]
|
||||||
preset_id = presets[0]["id"]
|
preset_id = presets[0]["id"]
|
||||||
|
|
||||||
response = client.get(f"preset/{preset_id}")
|
response = await client.get(f"preset/{preset_id}")
|
||||||
assert response.status_code == 200, response.json()
|
assert response.status_code == 200, response.json()
|
||||||
|
|
||||||
response = client.delete(f"preset/{preset_id}")
|
response = await client.delete(f"preset/{preset_id}")
|
||||||
assert response.status_code == 200, response.json()
|
assert response.status_code == 200, response.json()
|
||||||
|
|
||||||
response = client.get(f"preset/{preset_id}")
|
response = await client.get(f"preset/{preset_id}")
|
||||||
assert response.status_code == 404, response.json()
|
assert response.status_code == 404, response.json()
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.dependency()
|
@pytest.mark.anyio
|
||||||
def test_create_product(client, product_payload):
|
async def test_create_product(client, product_payload):
|
||||||
response = client.post("product", json=product_payload)
|
response = await client.post("product", json=product_payload)
|
||||||
assert response.status_code == 200, response.json()
|
assert response.status_code == 200, response.json()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.dependency(depends=["test_create_product"])
|
@pytest.mark.anyio
|
||||||
def test_list_product(client):
|
async def test_list_product(client):
|
||||||
response = client.get("product")
|
response = await client.get("product")
|
||||||
assert response.status_code == 200, response.json()
|
assert response.status_code == 200, response.json()
|
||||||
|
|
||||||
data = response.json()["products"]
|
data = response.json()["products"]
|
||||||
|
@ -21,13 +21,15 @@ def test_list_product(client):
|
||||||
product_ids.add(product["id"])
|
product_ids.add(product["id"])
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.dependency(depends=["test_create_product"])
|
@pytest.mark.anyio
|
||||||
def test_get_product_by_barcode(client):
|
async def test_get_product_by_barcode(client):
|
||||||
response = client.get("product/by_barcode", params={"barcode": "4056489666028"})
|
response = await client.get(
|
||||||
|
"product/by_barcode", params={"barcode": "4056489666028"}
|
||||||
|
)
|
||||||
assert response.status_code == 200, response.json()
|
assert response.status_code == 200, response.json()
|
||||||
|
|
||||||
name = response.json()["name"]
|
name = response.json()["name"]
|
||||||
|
|
||||||
response = client.get("product", params={"q": name})
|
response = await client.get("product", params={"q": name})
|
||||||
assert response.status_code == 200, response.json()
|
assert response.status_code == 200, response.json()
|
||||||
assert len(response.json()["products"]) == 1
|
assert len(response.json()["products"]) == 1
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.dependency()
|
@pytest.mark.anyio
|
||||||
def test_user_creation(unauthorized_client, user_payload_factory):
|
async def test_user_creation(unauthorized_client, user_payload_factory):
|
||||||
response = unauthorized_client.post("user", json=user_payload_factory())
|
response = await unauthorized_client.post("user", json=user_payload_factory())
|
||||||
assert response.status_code == 200, response.json()
|
assert response.status_code == 200, response.json()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.dependency(depends=["test_user_creation"])
|
@pytest.mark.anyio
|
||||||
def test_user_login(client, user_payload):
|
async def test_user_login(client, user_payload):
|
||||||
response = client.post("token", data=user_payload)
|
response = await client.post("token", data=user_payload)
|
||||||
assert response.status_code == 200, response.json()
|
assert response.status_code == 200, response.json()
|
||||||
|
|
||||||
data = response.json()
|
data = response.json()
|
||||||
|
@ -17,13 +17,13 @@ def test_user_login(client, user_payload):
|
||||||
assert data["refresh_token"] is not None
|
assert data["refresh_token"] is not None
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.dependency(depends=["test_user_login"])
|
@pytest.mark.anyio
|
||||||
def test_user_refresh_token(client, user_payload):
|
async def test_user_refresh_token(client, user_payload):
|
||||||
response = client.post("token", data=user_payload)
|
response = await client.post("token", data=user_payload)
|
||||||
assert response.status_code == 200, response.json()
|
assert response.status_code == 200, response.json()
|
||||||
|
|
||||||
token = response.json()["refresh_token"]
|
token = response.json()["refresh_token"]
|
||||||
payload = {"refresh_token": token}
|
payload = {"refresh_token": token}
|
||||||
|
|
||||||
response = client.post("token/refresh", json=payload)
|
response = await client.post("token/refresh", json=payload)
|
||||||
assert response.status_code == 200, response.json()
|
assert response.status_code == 200, response.json()
|
||||||
|
|
|
@ -48,5 +48,6 @@ def find(bar_code: str) -> Product:
|
||||||
fiber=data["product"]["nutriments"].get("fiber_100g", 0.0),
|
fiber=data["product"]["nutriments"].get("fiber_100g", 0.0),
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
raise e
|
||||||
logger.error(e)
|
logger.error(e)
|
||||||
raise ParseError()
|
raise ParseError()
|
||||||
|
|
|
@ -11,3 +11,4 @@ requests
|
||||||
black
|
black
|
||||||
flake8
|
flake8
|
||||||
flake8-bugbear
|
flake8-bugbear
|
||||||
|
httpx
|
||||||
|
|
60
test.sh
60
test.sh
|
@ -3,60 +3,32 @@
|
||||||
# Run fooder api tests
|
# Run fooder api tests
|
||||||
#
|
#
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
TESTS='test'
|
|
||||||
[[ $# -eq 1 ]] && TESTS=${1}
|
|
||||||
|
|
||||||
echo "Running fooder api tests"
|
echo "Running fooder api tests"
|
||||||
|
|
||||||
# up containers
|
# if exists, remove test.db
|
||||||
DC='docker-compose -f docker-compose.test.yml'
|
[ -f test.db ] && rm test.db
|
||||||
|
|
||||||
if [ "$(${DC} ps | grep -E 'running|Up' | wc -l)" -gt 0 ]; then
|
|
||||||
# down containers to assure a clean database
|
|
||||||
echo "stopping containers..."
|
|
||||||
${DC} down --remove-orphans
|
|
||||||
fi
|
|
||||||
|
|
||||||
# create test env values
|
# create test env values
|
||||||
export POSTGRES_USER=fooder_test
|
export DB_URI="sqlite+aiosqlite:///test.db"
|
||||||
export POSTGRES_DATABASE=fooder_test
|
export ECHO_SQL=0
|
||||||
export POSTGRES_PASSWORD=$(pwgen 13 1)
|
|
||||||
export SECRET_KEY=$(openssl rand -hex 32)
|
export SECRET_KEY=$(openssl rand -hex 32)
|
||||||
export REFRESH_SECRET=$(openssl rand -hex 32)
|
export REFRESH_SECRET_KEY=$(openssl rand -hex 32)
|
||||||
|
|
||||||
rm -f .env.test
|
python -m fooder --create-tables
|
||||||
envsubst < env.template > .env.test
|
|
||||||
|
|
||||||
|
# finally run tests
|
||||||
|
if [[ $# -eq 1 ]]; then
|
||||||
|
python -m pytest fooder --disable-warnings -sv -k "${1}"
|
||||||
|
else
|
||||||
|
python -m pytest fooder --disable-warnings -sv
|
||||||
|
fi
|
||||||
|
|
||||||
|
# unset test env values
|
||||||
unset POSTGRES_USER
|
unset POSTGRES_USER
|
||||||
unset POSTGRES_DATABASE
|
unset POSTGRES_DATABASE
|
||||||
unset POSTGRES_PASSWORD
|
unset POSTGRES_PASSWORD
|
||||||
unset SECRET_KEY
|
unset SECRET_KEY
|
||||||
unset REFRESH_SECRET
|
unset REFRESH_SECRET
|
||||||
|
|
||||||
echo "starting containers..."
|
# if exists, remove test.db
|
||||||
${DC} up -d
|
[ -f test.db ] && rm test.db
|
||||||
|
|
||||||
# Wait for the containers to start
|
|
||||||
echo "waiting for containers to start..."
|
|
||||||
while [ "$(${DC} ps | grep -E 'running|Up' | wc -l)" -lt 2 ]; do
|
|
||||||
sleep 1
|
|
||||||
done
|
|
||||||
|
|
||||||
while [ "$(${DC} logs database | grep -E 'database system is ready to accept connections' | wc -l)" -lt 2 ]; do
|
|
||||||
sleep 1
|
|
||||||
done
|
|
||||||
|
|
||||||
# create tables
|
|
||||||
echo "creating tables..."
|
|
||||||
${DC} exec api bash -c "python -m fooder --create-tables"
|
|
||||||
|
|
||||||
# finally run tests
|
|
||||||
set -xe
|
|
||||||
python -m pytest fooder -sv -k "${TESTS}"
|
|
||||||
|
|
||||||
# clean up after tests
|
|
||||||
echo "cleaning up..."
|
|
||||||
${DC} down --remove-orphans
|
|
||||||
rm -f .env.test
|
|
||||||
|
|
Loading…
Reference in a new issue