Mealplan CRUD Tests (#95)

* dev-bug: fixed vscode freezes

* test: refactor database init to support tests

* mealplan CRUD testing

Co-authored-by: Hayden <hay-kot@pm.me>
This commit is contained in:
Hayden 2021-01-18 19:54:46 -09:00 committed by GitHub
commit 2ffaecb7b7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 232 additions and 37 deletions

1
.gitignore vendored
View file

@ -152,3 +152,4 @@ ENV/
node_modules/ node_modules/
mealie/data/debug/last_recipe.json mealie/data/debug/last_recipe.json
*.sqlite *.sqlite
app_data/db/test.db

View file

@ -16,6 +16,7 @@ const mealPlanURLs = {
export default { export default {
async create(postBody) { async create(postBody) {
let response = await apiReq.post(mealPlanURLs.create, postBody); let response = await apiReq.post(mealPlanURLs.create, postBody);
console.log(JSON.stringify(postBody));
return response; return response;
}, },

View file

@ -19,7 +19,7 @@ def get_all_meals(db: Session = Depends(generate_session)):
@router.post("/api/meal-plan/create/") @router.post("/api/meal-plan/create/")
def set_meal_plan(data: MealPlan, db: Session = Depends(generate_session)): def set_meal_plan(data: MealPlan, db: Session = Depends(generate_session)):
""" Creates a meal plan database entry """ """ Creates a meal plan database entry """
data.process_meals() data.process_meals(db)
data.save_to_db(db) data.save_to_db(db)
# raise HTTPException( # raise HTTPException(
@ -35,7 +35,7 @@ def update_meal_plan(
plan_id: str, meal_plan: MealPlan, db: Session = Depends(generate_session) plan_id: str, meal_plan: MealPlan, db: Session = Depends(generate_session)
): ):
""" Updates a meal plan based off ID """ """ Updates a meal plan based off ID """
meal_plan.process_meals() meal_plan.process_meals(db)
meal_plan.update(db, plan_id) meal_plan.update(db, plan_id)
# try: # try:
# meal_plan.process_meals() # meal_plan.process_meals()

View file

@ -89,9 +89,9 @@ def parse_recipe_url(url: RecipeURLIn, db: Session = Depends(generate_session)):
@router.post("/api/recipe/create/") @router.post("/api/recipe/create/")
def create_from_json(data: Recipe, db: Session = Depends(generate_session)) -> str: def create_from_json(data: Recipe, db: Session = Depends(generate_session)) -> str:
""" Takes in a JSON string and loads data into the database as a new entry""" """ Takes in a JSON string and loads data into the database as a new entry"""
created_recipe = data.save_to_db(db) new_recipe_slug = data.save_to_db(db)
return created_recipe return new_recipe_slug
@router.post("/api/recipe/{recipe_slug}/update/image/") @router.post("/api/recipe/{recipe_slug}/update/image/")

View file

@ -54,12 +54,12 @@ class MealPlan(BaseModel):
} }
} }
def process_meals(self): def process_meals(self, session: Session):
meals = [] meals = []
for x, meal in enumerate(self.meals): for x, meal in enumerate(self.meals):
try: try:
recipe = Recipe.get_by_slug(meal.slug) recipe = Recipe.get_by_slug(session, meal.slug)
meal_data = { meal_data = {
"slug": recipe.slug, "slug": recipe.slug,

View file

@ -19,7 +19,10 @@ def override_get_db():
db.close() db.close()
@fixture @fixture(scope="session")
def api_client(): def api_client():
app.dependency_overrides[generate_session] = override_get_db app.dependency_overrides[generate_session] = override_get_db
return TestClient(app) yield TestClient(app)
SQLITE_FILE.unlink()

View file

View file

@ -0,0 +1,100 @@
import json
from tests.test_routes.utils.routes_data import recipe_test_data
def cleanup(api_client):
api_client.delete(f"/api/recipe/{recipe_test_data[0].expected_slug}/delete/")
api_client.delete(f"/api/recipe/{recipe_test_data[1].expected_slug}/delete/")
meal_plan = {
"startDate": "2021-01-18",
"endDate": "2021-01-19",
"meals": [
{
"slug": None,
"date": "2021-1-17",
"dateText": "Monday, January 18, 2021",
},
{
"slug": None,
"date": "2021-1-18",
"dateText": "Tueday, January 19, 2021",
},
],
}
def test_create_mealplan(api_client):
slug_1 = api_client.post(
"/api/recipe/create-url/", json={"url": recipe_test_data[0].url}
)
slug_2 = api_client.post(
"/api/recipe/create-url/", json={"url": recipe_test_data[1].url}
)
meal_plan["meals"][0]["slug"] = json.loads(slug_1.content)
meal_plan["meals"][1]["slug"] = json.loads(slug_2.content)
response = api_client.post("/api/meal-plan/create/", json=meal_plan)
assert response.status_code == 200
def test_read_mealplan(api_client):
response = api_client.get("/api/meal-plan/all/")
assert response.status_code == 200
new_meal_plan = json.loads(response.text)
meals = new_meal_plan[0]["meals"]
assert meals[0]["slug"] == meal_plan["meals"][0]["slug"]
assert meals[1]["slug"] == meal_plan["meals"][1]["slug"]
cleanup(api_client)
def test_update_mealplan(api_client):
slug_1 = api_client.post(
"/api/recipe/create-url/", json={"url": recipe_test_data[0].url}
)
slug_2 = api_client.post(
"/api/recipe/create-url/", json={"url": recipe_test_data[1].url}
)
response = api_client.get("/api/meal-plan/all/")
existing_mealplan = json.loads(response.text)
existing_mealplan = existing_mealplan[0]
## Swap
plan_uid = existing_mealplan.get("uid")
existing_mealplan["meals"][0]["slug"] = json.loads(slug_2.content)
existing_mealplan["meals"][1]["slug"] = json.loads(slug_1.content)
response = api_client.post(
f"/api/meal-plan/{plan_uid}/update/", json=existing_mealplan
)
assert response.status_code == 200
response = api_client.get("/api/meal-plan/all/")
existing_mealplan = json.loads(response.text)
existing_mealplan = existing_mealplan[0]
assert existing_mealplan["meals"][0]["slug"] == json.loads(slug_2.content)
assert existing_mealplan["meals"][1]["slug"] == json.loads(slug_1.content)
cleanup(api_client)
def test_delete_mealplan(api_client):
response = api_client.get("/api/meal-plan/all/")
existing_mealplan = json.loads(response.text)
existing_mealplan = existing_mealplan[0]
plan_uid = existing_mealplan.get("uid")
response = api_client.delete(f"/api/meal-plan/{plan_uid}/delete/")
assert response.status_code == 200

View file

@ -1,59 +1,85 @@
import json import json
import pytest import pytest
from slugify import slugify
from tests.test_routes.utils.routes_data import (RecipeTestData,
raw_recipe_dict,
recipe_test_data)
class RecipeTestData: @pytest.mark.parametrize("recipe_data", recipe_test_data)
def __init__(self, url, expected_slug) -> None: def test_create_by_url(api_client, recipe_data: RecipeTestData):
self.url: str = url response = api_client.post("/api/recipe/create-url/", json={"url": recipe_data.url})
self.expected_slug: str = expected_slug
test_data = [
RecipeTestData(
url="https://www.bonappetit.com/recipe/rustic-shrimp-toasts",
expected_slug="rustic-shrimp-toasts",
),
RecipeTestData(
url="https://www.allrecipes.com/recipe/282905/honey-garlic-shrimp/",
expected_slug="honey-garlic-shrimp",
),
]
@pytest.mark.parametrize("recipe_data", test_data)
def test_create(api_client, recipe_data: RecipeTestData):
payload = json.dumps({"url": recipe_data.url})
response = api_client.post("/api/recipe/create-url/", payload)
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
@pytest.mark.parametrize("recipe_data", test_data) def test_create_by_json(api_client):
response = api_client.post("/api/recipe/create/", json=raw_recipe_dict)
assert response.status_code == 200
assert json.loads(response.text) == "banana-bread"
def test_read_all_post(api_client):
response = api_client.post(
"/api/all-recipes/", json={"properties": ["slug", "description", "rating"]}
)
assert response.status_code == 200
@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"/api/recipe/{recipe_data.expected_slug}/")
assert response.status_code == 200 assert response.status_code == 200
recipe = json.loads(response.content) recipe = json.loads(response.content)
recipe["notes"] = [ test_notes = [
{"title": "My Test Title1", "text": "My Test Text1"}, {"title": "My Test Title1", "text": "My Test Text1"},
{"title": "My Test Title2", "text": "My Test Text2"}, {"title": "My Test Title2", "text": "My Test Text2"},
] ]
recipe["notes"] = test_notes
recipe["categories"] = ["one", "two", "three"] test_categories = ["one", "two", "three"]
recipe["categories"] = test_categories
payload = json.dumps(recipe)
response = api_client.post( response = api_client.post(
f"/api/recipe/{recipe_data.expected_slug}/update/", payload f"/api/recipe/{recipe_data.expected_slug}/update/", 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}/")
@pytest.mark.parametrize("recipe_data", test_data) recipe = json.loads(response.content)
assert recipe["notes"] == test_notes
assert recipe["categories"] == test_categories
@pytest.mark.parametrize("recipe_data", recipe_test_data)
def test_rename(api_client, recipe_data):
response = api_client.get(f"/api/recipe/{recipe_data.expected_slug}/")
assert response.status_code == 200
recipe = json.loads(response.content)
new_name = recipe.get("name") + "-rename"
new_slug = slugify(new_name)
recipe["name"] = new_name
response = api_client.post(
f"/api/recipe/{recipe_data.expected_slug}/update/", json=recipe
)
assert response.status_code == 200
assert json.loads(response.text) == new_slug
recipe_data.expected_slug = new_slug
@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"/api/recipe/{recipe_data.expected_slug}/delete/")
assert response.status_code == 200 assert response.status_code == 200

View file

@ -0,0 +1,64 @@
class RecipeTestData:
def __init__(self, url, expected_slug) -> None:
self.url: str = url
self.expected_slug: str = expected_slug
recipe_test_data = [
RecipeTestData(
url="https://www.bonappetit.com/recipe/rustic-shrimp-toasts",
expected_slug="rustic-shrimp-toasts",
),
RecipeTestData(
url="https://www.allrecipes.com/recipe/282905/honey-garlic-shrimp/",
expected_slug="honey-garlic-shrimp",
),
]
raw_recipe_dict = {
"name": "Banana Bread",
"description": "From Angie's mom",
"image": "banana-bread.jpg",
"recipeYield": "",
"recipeIngredient": [
"4 bananas",
"1/2 cup butter",
"1/2 cup sugar",
"2 eggs",
"2 cups flour",
"1/2 tsp baking soda",
"1 tsp baking powder",
"pinch salt",
"1/4 cup nuts (we like pecans)",
],
"recipeInstructions": [
{
"@type": "Beat the eggs, then cream with the butter and sugar",
"text": "Beat the eggs, then cream with the butter and sugar",
},
{
"@type": "Mix in bananas, then flour, baking soda/powder, salt, and nuts",
"text": "Mix in bananas, then flour, baking soda/powder, salt, and nuts",
},
{
"@type": "Add to greased and floured pan",
"text": "Add to greased and floured pan",
},
{
"@type": "Bake until brown/cracked, toothpick comes out clean",
"text": "Bake until brown/cracked, toothpick comes out clean",
},
],
"totalTime": "None",
"prepTime": None,
"performTime": None,
"slug": "",
"categories": [],
"tags": ["breakfast", " baking"],
"dateAdded": "2021-01-12",
"notes": [],
"rating": 0,
"orgURL": None,
"extras": {},
}