route refactoring

This commit is contained in:
hayden 2021-02-03 19:06:51 -09:00
commit d0cc0a089a
15 changed files with 116 additions and 66 deletions

View file

@ -90,8 +90,8 @@ app.include_router(static_routes.router)
# Generate API Documentation # Generate API Documentation
if not PRODUCTION: # if not PRODUCTION:
generate_api_docs(app) # generate_api_docs(app)
start_scheduler() start_scheduler()

View file

@ -25,7 +25,7 @@ class BaseDocument:
def get_all_limit_columns( def get_all_limit_columns(
self, session: Session, fields: List[str], limit: int = None self, session: Session, fields: List[str], limit: int = None
) -> list[SqlAlchemyBase]: ) -> List[SqlAlchemyBase]:
"""Queries the database for the selected model. Restricts return responses to the """Queries the database for the selected model. Restricts return responses to the
keys specified under "fields" keys specified under "fields"

View file

@ -11,7 +11,7 @@ from sqlalchemy.orm.session import Session
from starlette.responses import FileResponse from starlette.responses import FileResponse
from utils.snackbar import SnackResponse from utils.snackbar import SnackResponse
router = APIRouter(prefix="/api/backups", tags=["Import / Export"]) router = APIRouter(prefix="/api/backups", tags=["Backups"])
@router.get("/available", response_model=Imports) @router.get("/available", response_model=Imports)

View file

@ -65,7 +65,7 @@ def delete_meal_plan(plan_id, db: Session = Depends(generate_session)):
return SnackResponse.success("Mealplan Deleted") return SnackResponse.success("Mealplan Deleted")
@router.get("/today/", tags=["Meal Plan"]) @router.get("/today", tags=["Meal Plan"])
def get_today(db: Session = Depends(generate_session)): def get_today(db: Session = Depends(generate_session)):
""" """
Returns the recipe slug for the meal scheduled for today. Returns the recipe slug for the meal scheduled for today.

View file

@ -88,7 +88,7 @@ def normalize_time(time_entry) -> str:
def normalize_data(recipe_data: dict) -> dict: def normalize_data(recipe_data: dict) -> dict:
recipe_data["totalTime"] = normalize_time(recipe_data.get("totalTime")) recipe_data["totalTime"] = normalize_time(recipe_data.get("totalTime"))
recipe_data["description"] = cleanhtml(recipe_data.get("description")) recipe_data["description"] = cleanhtml(recipe_data.get("description", ""))
recipe_data["prepTime"] = normalize_time(recipe_data.get("prepTime")) recipe_data["prepTime"] = normalize_time(recipe_data.get("prepTime"))
recipe_data["performTime"] = normalize_time(recipe_data.get("performTime")) recipe_data["performTime"] = normalize_time(recipe_data.get("performTime"))
recipe_data["recipeYield"] = normalize_yield(recipe_data.get("recipeYield")) recipe_data["recipeYield"] = normalize_yield(recipe_data.get("recipeYield"))

View file

@ -141,6 +141,8 @@ def default_settings_init():
default_entry = SiteSettings(name="main", webhooks=webhooks) default_entry = SiteSettings(name="main", webhooks=webhooks)
document = db.settings.save_new(session, default_entry.dict(), webhooks.dict()) document = db.settings.save_new(session, default_entry.dict(), webhooks.dict())
session.close()
if not sql_exists: if not sql_exists:
default_settings_init() default_settings_init()

View file

@ -23,6 +23,8 @@ def override_get_db():
db.close() db.close()
@fixture(scope="session") @fixture(scope="session")
def api_client(): def api_client():

View file

@ -2,6 +2,13 @@ import json
import pytest import pytest
from tests.test_routes.utils.routes_data import recipe_test_data from tests.test_routes.utils.routes_data import recipe_test_data
from tests.utils.routes import (
MEALPLAN_ALL,
MEALPLAN_CREATE,
MEALPLAN_PREFIX,
RECIPES_CREATE_URL,
RECIPES_PREFIX,
)
def get_meal_plan_template(first=None, second=None): def get_meal_plan_template(first=None, second=None):
@ -23,30 +30,30 @@ def get_meal_plan_template(first=None, second=None):
} }
## Meal Routes
@pytest.fixture @pytest.fixture
def slug_1(api_client): def slug_1(api_client):
# Slug 1 # Slug 1
slug_1 = api_client.post(
"/api/recipe/create-url/", json={"url": recipe_test_data[0].url} slug_1 = api_client.post(RECIPES_CREATE_URL, json={"url": recipe_test_data[0].url})
)
slug_1 = json.loads(slug_1.content) slug_1 = json.loads(slug_1.content)
yield slug_1 yield slug_1
api_client.delete(f"/api/recipe/{recipe_test_data[1].expected_slug}/delete/") api_client.delete(RECIPES_PREFIX + "/" + slug_1)
@pytest.fixture @pytest.fixture
def slug_2(api_client): def slug_2(api_client):
# Slug 2 # Slug 2
slug_2 = api_client.post( slug_2 = api_client.post(RECIPES_CREATE_URL, json={"url": recipe_test_data[1].url})
"/api/recipe/create-url/", json={"url": recipe_test_data[1].url}
)
slug_2 = json.loads(slug_2.content) slug_2 = json.loads(slug_2.content)
yield slug_2 yield slug_2
api_client.delete(f"/api/recipe/{recipe_test_data[0].expected_slug}/delete/") api_client.delete(RECIPES_PREFIX + "/" + slug_2)
def test_create_mealplan(api_client, slug_1, slug_2): def test_create_mealplan(api_client, slug_1, slug_2):
@ -54,12 +61,12 @@ def test_create_mealplan(api_client, slug_1, slug_2):
meal_plan["meals"][0]["slug"] = slug_1 meal_plan["meals"][0]["slug"] = slug_1
meal_plan["meals"][1]["slug"] = slug_2 meal_plan["meals"][1]["slug"] = slug_2
response = api_client.post("/api/meal-plan/create/", json=meal_plan) response = api_client.post(MEALPLAN_CREATE, json=meal_plan)
assert response.status_code == 200 assert response.status_code == 200
def test_read_mealplan(api_client, slug_1, slug_2): def test_read_mealplan(api_client, slug_1, slug_2):
response = api_client.get("/api/meal-plan/all/") response = api_client.get(MEALPLAN_ALL)
assert response.status_code == 200 assert response.status_code == 200
@ -74,7 +81,7 @@ def test_read_mealplan(api_client, slug_1, slug_2):
def test_update_mealplan(api_client, slug_1, slug_2): def test_update_mealplan(api_client, slug_1, slug_2):
response = api_client.get("/api/meal-plan/all/") response = api_client.get(MEALPLAN_ALL)
existing_mealplan = json.loads(response.text) existing_mealplan = json.loads(response.text)
existing_mealplan = existing_mealplan[0] existing_mealplan = existing_mealplan[0]
@ -84,13 +91,11 @@ def test_update_mealplan(api_client, slug_1, slug_2):
existing_mealplan["meals"][0]["slug"] = slug_2 existing_mealplan["meals"][0]["slug"] = slug_2
existing_mealplan["meals"][1]["slug"] = slug_1 existing_mealplan["meals"][1]["slug"] = slug_1
response = api_client.post( response = api_client.put(f"{MEALPLAN_PREFIX}/{plan_uid}", json=existing_mealplan)
f"/api/meal-plan/{plan_uid}/update/", json=existing_mealplan
)
assert response.status_code == 200 assert response.status_code == 200
response = api_client.get("/api/meal-plan/all/") response = api_client.get(MEALPLAN_ALL)
existing_mealplan = json.loads(response.text) existing_mealplan = json.loads(response.text)
existing_mealplan = existing_mealplan[0] existing_mealplan = existing_mealplan[0]
@ -99,11 +104,13 @@ def test_update_mealplan(api_client, slug_1, slug_2):
def test_delete_mealplan(api_client): def test_delete_mealplan(api_client):
response = api_client.get("/api/meal-plan/all/") response = api_client.get(MEALPLAN_ALL)
assert response.status_code == 200
existing_mealplan = json.loads(response.text) existing_mealplan = json.loads(response.text)
existing_mealplan = existing_mealplan[0] existing_mealplan = existing_mealplan[0]
plan_uid = existing_mealplan.get("uid") plan_uid = existing_mealplan.get("uid")
response = api_client.delete(f"/api/meal-plan/{plan_uid}/delete/") response = api_client.delete(f"{MEALPLAN_PREFIX}/{plan_uid}")
assert response.status_code == 200 assert response.status_code == 200

View file

@ -4,6 +4,7 @@ import shutil
import pytest import pytest
from app_config import MIGRATION_DIR from app_config import MIGRATION_DIR
from tests.test_config import TEST_CHOWDOWN_DIR, TEST_NEXTCLOUD_DIR from tests.test_config import TEST_CHOWDOWN_DIR, TEST_NEXTCLOUD_DIR
from tests.utils.routes import MIGRATIONS_PREFIX, RECIPES_PREFIX
### Chowdown ### Chowdown
@ -23,7 +24,8 @@ def chowdown_zip():
def test_upload_chowdown_zip(api_client, chowdown_zip): def test_upload_chowdown_zip(api_client, chowdown_zip):
response = api_client.post( response = api_client.post(
"/api/migrations/chowdown/upload/", files={"archive": chowdown_zip.open("rb")} f"{MIGRATIONS_PREFIX}/chowdown/upload",
files={"archive": chowdown_zip.open("rb")},
) )
assert response.status_code == 200 assert response.status_code == 200
@ -33,7 +35,7 @@ def test_upload_chowdown_zip(api_client, chowdown_zip):
def test_import_chowdown_directory(api_client, chowdown_zip): def test_import_chowdown_directory(api_client, chowdown_zip):
selection = chowdown_zip.name selection = chowdown_zip.name
response = api_client.post(f"/api/migrations/chowdown/{selection}/import/") response = api_client.post(f"{MIGRATIONS_PREFIX}/chowdown/{selection}/import")
assert response.status_code == 200 assert response.status_code == 200
@ -41,13 +43,13 @@ def test_import_chowdown_directory(api_client, chowdown_zip):
assert report["failed"] == [] assert report["failed"] == []
expected_slug = "roasted-okra" expected_slug = "roasted-okra"
response = api_client.get(f"/api/recipe/{expected_slug}/") response = api_client.get(f"{RECIPES_PREFIX}/{expected_slug}")
assert response.status_code == 200 assert response.status_code == 200
def test_delete_chowdown_migration_data(api_client, chowdown_zip): def test_delete_chowdown_migration_data(api_client, chowdown_zip):
selection = chowdown_zip.name selection = chowdown_zip.name
response = api_client.delete(f"/api/migrations/chowdown/{selection}/delete/") response = api_client.delete(f"{MIGRATIONS_PREFIX}/chowdown/{selection}/delete")
assert response.status_code == 200 assert response.status_code == 200
assert not MIGRATION_DIR.joinpath(chowdown_zip.name).is_file() assert not MIGRATION_DIR.joinpath(chowdown_zip.name).is_file()
@ -70,7 +72,8 @@ def nextcloud_zip():
def test_upload_nextcloud_zip(api_client, nextcloud_zip): def test_upload_nextcloud_zip(api_client, nextcloud_zip):
response = api_client.post( response = api_client.post(
"/api/migrations/nextcloud/upload/", files={"archive": nextcloud_zip.open("rb")} f"{MIGRATIONS_PREFIX}/nextcloud/upload",
files={"archive": nextcloud_zip.open("rb")},
) )
assert response.status_code == 200 assert response.status_code == 200
@ -80,7 +83,7 @@ def test_upload_nextcloud_zip(api_client, nextcloud_zip):
def test_import_nextcloud_directory(api_client, nextcloud_zip): def test_import_nextcloud_directory(api_client, nextcloud_zip):
selection = nextcloud_zip.name selection = nextcloud_zip.name
response = api_client.post(f"/api/migrations/nextcloud/{selection}/import/") response = api_client.post(f"{MIGRATIONS_PREFIX}/nextcloud/{selection}/import")
assert response.status_code == 200 assert response.status_code == 200
@ -88,13 +91,13 @@ def test_import_nextcloud_directory(api_client, nextcloud_zip):
assert report["failed"] == [] assert report["failed"] == []
expected_slug = "air-fryer-shrimp" expected_slug = "air-fryer-shrimp"
response = api_client.get(f"/api/recipe/{expected_slug}/") response = api_client.get(f"{RECIPES_PREFIX}/{expected_slug}")
assert response.status_code == 200 assert response.status_code == 200
def test_delete__nextcloud_migration_data(api_client, nextcloud_zip): def test_delete__nextcloud_migration_data(api_client, nextcloud_zip):
selection = nextcloud_zip.name selection = nextcloud_zip.name
response = api_client.delete(f"/api/migrations/nextcloud/{selection}/delete/") response = api_client.delete(f"{MIGRATIONS_PREFIX}/nextcloud/{selection}/delete")
assert response.status_code == 200 assert response.status_code == 200
assert not MIGRATION_DIR.joinpath(nextcloud_zip.name).is_file() assert not MIGRATION_DIR.joinpath(nextcloud_zip.name).is_file()

View file

@ -2,32 +2,31 @@ import json
import pytest import pytest
from slugify import slugify from slugify import slugify
from tests.test_routes.utils.routes_data import ( from tests.test_routes.utils.routes_data import (RecipeTestData, raw_recipe,
RecipeTestData, raw_recipe_no_image,
raw_recipe, recipe_test_data)
raw_recipe_no_image, from tests.utils.routes import (RECIPES_ALL, RECIPES_CREATE,
recipe_test_data, RECIPES_CREATE_URL, RECIPES_PREFIX)
)
@pytest.mark.parametrize("recipe_data", recipe_test_data) @pytest.mark.parametrize("recipe_data", recipe_test_data)
def test_create_by_url(api_client, recipe_data: RecipeTestData): def test_create_by_url(api_client, recipe_data: RecipeTestData):
response = api_client.post("/api/recipe/create-url/", json={"url": recipe_data.url}) response = api_client.post(RECIPES_CREATE_URL, json={"url": recipe_data.url})
assert response.status_code == 201 assert response.status_code == 201
assert json.loads(response.text) == recipe_data.expected_slug assert json.loads(response.text) == recipe_data.expected_slug
def test_create_by_json(api_client): def test_create_by_json(api_client):
response = api_client.post("/api/recipe/create/", json=raw_recipe) response = api_client.post(RECIPES_CREATE, json=raw_recipe)
assert response.status_code == 200 assert response.status_code == 201
assert json.loads(response.text) == "banana-bread" assert json.loads(response.text) == "banana-bread"
def test_create_no_image(api_client): def test_create_no_image(api_client):
response = api_client.post("/api/recipe/create/", json=raw_recipe_no_image) response = api_client.post(RECIPES_CREATE, json=raw_recipe_no_image)
assert response.status_code == 200 assert response.status_code == 201
assert json.loads(response.text) == "banana-bread-no-image" assert json.loads(response.text) == "banana-bread-no-image"
@ -35,24 +34,24 @@ def test_create_no_image(api_client):
# data = {"image": test_image.open("rb").read(), "extension": "jpg"} # data = {"image": test_image.open("rb").read(), "extension": "jpg"}
# response = api_client.post( # response = api_client.post(
# "/api/recipe/banana-bread-no-image/update/image/", files=data # "{RECIPES_PREFIX}banana-bread-no-image/update/image/", files=data
# ) # )
# assert response.status_code == 200 # assert response.status_code == 200
# response = api_client.get("/api/recipe/banana-bread-no-image/update/image/") # response = api_client.get("{RECIPES_PREFIX}banana-bread-no-image/update/image/")
def test_read_all_post(api_client): def test_read_all_post(api_client):
response = api_client.post( response = api_client.post(
"/api/all-recipes/", json={"properties": ["slug", "description", "rating"]} RECIPES_ALL, json={"properties": ["slug", "description", "rating"]}
) )
assert response.status_code == 200 assert response.status_code == 200
@pytest.mark.parametrize("recipe_data", recipe_test_data) @pytest.mark.parametrize("recipe_data", recipe_test_data)
def test_read_update(api_client, recipe_data): def test_read_update(api_client, recipe_data):
response = api_client.get(f"/api/recipe/{recipe_data.expected_slug}/") response = api_client.get(f"{RECIPES_PREFIX}/{recipe_data.expected_slug}")
assert response.status_code == 200 assert response.status_code == 200
recipe = json.loads(response.content) recipe = json.loads(response.content)
@ -66,14 +65,14 @@ def test_read_update(api_client, recipe_data):
test_categories = ["one", "two", "three"] test_categories = ["one", "two", "three"]
recipe["categories"] = test_categories recipe["categories"] = test_categories
response = api_client.post( response = api_client.put(
f"/api/recipe/{recipe_data.expected_slug}/update/", json=recipe f"{RECIPES_PREFIX}/{recipe_data.expected_slug}", json=recipe
) )
assert response.status_code == 200 assert response.status_code == 200
assert json.loads(response.text) == recipe_data.expected_slug assert json.loads(response.text) == recipe_data.expected_slug
response = api_client.get(f"/api/recipe/{recipe_data.expected_slug}/") response = api_client.get(f"{RECIPES_PREFIX}/{recipe_data.expected_slug}")
recipe = json.loads(response.content) recipe = json.loads(response.content)
@ -83,7 +82,7 @@ def test_read_update(api_client, recipe_data):
@pytest.mark.parametrize("recipe_data", recipe_test_data) @pytest.mark.parametrize("recipe_data", recipe_test_data)
def test_rename(api_client, recipe_data): def test_rename(api_client, recipe_data):
response = api_client.get(f"/api/recipe/{recipe_data.expected_slug}/") response = api_client.get(f"{RECIPES_PREFIX}/{recipe_data.expected_slug}")
assert response.status_code == 200 assert response.status_code == 200
recipe = json.loads(response.content) recipe = json.loads(response.content)
@ -91,8 +90,8 @@ def test_rename(api_client, recipe_data):
new_slug = slugify(new_name) new_slug = slugify(new_name)
recipe["name"] = new_name recipe["name"] = new_name
response = api_client.post( response = api_client.put(
f"/api/recipe/{recipe_data.expected_slug}/update/", json=recipe f"{RECIPES_PREFIX}/{recipe_data.expected_slug}", json=recipe
) )
assert response.status_code == 200 assert response.status_code == 200
@ -103,5 +102,5 @@ def test_rename(api_client, recipe_data):
@pytest.mark.parametrize("recipe_data", recipe_test_data) @pytest.mark.parametrize("recipe_data", recipe_test_data)
def test_delete(api_client, recipe_data): def test_delete(api_client, recipe_data):
response = api_client.delete(f"/api/recipe/{recipe_data.expected_slug}/delete/") response = api_client.delete(f"{RECIPES_PREFIX}/{recipe_data.expected_slug}")
assert response.status_code == 200 assert response.status_code == 200

View file

@ -1,6 +1,12 @@
import json import json
import pytest import pytest
from tests.utils.routes import (
SETTINGS_PREFIX,
SETTINGS_UPDATE,
THEMES_CREATE,
THEMES_PREFIX,
)
@pytest.fixture(scope="function") @pytest.fixture(scope="function")
@ -26,7 +32,7 @@ def default_theme(api_client):
"error": "#EF5350", "error": "#EF5350",
}, },
} }
api_client.post("/api/site-settings/themes/create/", json=default_theme) api_client.post(THEMES_CREATE, json=default_theme)
return default_theme return default_theme
@ -48,7 +54,7 @@ def new_theme():
def test_default_settings(api_client, default_settings): def test_default_settings(api_client, default_settings):
response = api_client.get("/api/site-settings/") response = api_client.get(SETTINGS_PREFIX)
assert response.status_code == 200 assert response.status_code == 200
@ -62,47 +68,45 @@ def test_update_settings(api_client, default_settings):
"https://test3.url.com", "https://test3.url.com",
] ]
response = api_client.post("/api/site-settings/update/", json=default_settings) response = api_client.put(SETTINGS_UPDATE, json=default_settings)
assert response.status_code == 200 assert response.status_code == 200
response = api_client.get("/api/site-settings/") response = api_client.get(SETTINGS_PREFIX)
assert json.loads(response.content) == default_settings assert json.loads(response.content) == default_settings
def test_default_theme(api_client, default_theme): def test_default_theme(api_client, default_theme):
response = api_client.get("/api/site-settings/themes/default/") response = api_client.get(f"{THEMES_PREFIX}/default")
assert response.status_code == 200 assert response.status_code == 200
assert json.loads(response.content) == default_theme assert json.loads(response.content) == default_theme
def test_create_theme(api_client, new_theme): def test_create_theme(api_client, new_theme):
response = api_client.post("/api/site-settings/themes/create/", json=new_theme) response = api_client.post(THEMES_CREATE, json=new_theme)
assert response.status_code == 200 assert response.status_code == 200
response = api_client.get(f"/api/site-settings/themes/{new_theme.get('name')}/") response = api_client.get(f"{THEMES_PREFIX}/{new_theme.get('name')}")
assert response.status_code == 200 assert response.status_code == 200
assert json.loads(response.content) == new_theme assert json.loads(response.content) == new_theme
def test_read_all_themes(api_client, default_theme, new_theme): def test_read_all_themes(api_client, default_theme, new_theme):
response = api_client.get("/api/site-settings/themes/") response = api_client.get(THEMES_PREFIX)
assert response.status_code == 200 assert response.status_code == 200
assert json.loads(response.content) == [default_theme, new_theme] assert json.loads(response.content) == [default_theme, new_theme]
def test_read_theme(api_client, default_theme, new_theme): def test_read_theme(api_client, default_theme, new_theme):
for theme in [default_theme, new_theme]: for theme in [default_theme, new_theme]:
response = api_client.get(f"/api/site-settings/themes/{theme.get('name')}/") response = api_client.get(f"{THEMES_PREFIX}/{theme.get('name')}")
assert response.status_code == 200 assert response.status_code == 200
assert json.loads(response.content) == theme assert json.loads(response.content) == theme
def test_delete_theme(api_client, default_theme, new_theme): def test_delete_theme(api_client, default_theme, new_theme):
for theme in [default_theme, new_theme]: for theme in [default_theme, new_theme]:
response = api_client.delete( response = api_client.delete(f"{THEMES_PREFIX}/{theme.get('name')}")
f"/api/site-settings/themes/{theme.get('name')}/delete/"
)
assert response.status_code == 200 assert response.status_code == 200

View file

@ -0,0 +1,3 @@

View file

@ -1 +0,0 @@
test_

View file

View file

@ -0,0 +1,31 @@
BASE = "/api"
ALL_RECIPES = BASE + "/recipes"
RECIPES_PREFIX = BASE + "/recipes"
RECIPES_ALL = RECIPES_PREFIX
RECIPES_CREATE = RECIPES_PREFIX + "/create"
RECIPES_CREATE_URL = RECIPES_PREFIX + "/create-url"
CATEGORIES_PREFIX = BASE + "/categories"
TAGS_PREFIX = BASE + "/tags"
MEALPLAN_PREFIX = BASE + "/meal-plans"
MEALPLAN_ALL = MEALPLAN_PREFIX + "/all"
MEALPLAN_CREATE = MEALPLAN_PREFIX + "/create"
MEALPLAN_THIS_WEEK = MEALPLAN_PREFIX + "/this-week"
MEALPLAN_TODAY = MEALPLAN_PREFIX + "/today"
SETTINGS_PREFIX = BASE + "/site-settings"
SETTINGS_UPDATE = SETTINGS_PREFIX
TEST_WEBHOOKS = SETTINGS_PREFIX + "/webhooks/test"
THEMES_PREFIX = BASE + "/themes"
THEMES_CREATE = THEMES_PREFIX + "/create"
BACKUPS_PREFIX = BASE + "/backups"
BACKUPS_AVAILABLE = BACKUPS_PREFIX + "/available"
BACKUPS_EXPORT = BACKUPS_PREFIX + "/export/database"
BACKUPS_UPLOAD = BACKUPS_PREFIX + "/upload"
MIGRATIONS_PREFIX = BASE + "/migrations"