1
0
Fork 0
mirror of https://github.com/mealie-recipes/mealie.git synced 2025-08-05 05:25:26 +02:00

Refactor/conver to controllers (#923)

* add dependency injection for get_repositories

* convert events api to controller

* update generic typing

* add abstract controllers

* update test naming

* migrate admin services to controllers

* add additional admin route tests

* remove print

* add public shared dependencies

* add types

* fix typo

* add static variables for recipe json keys

* add coverage gutters config

* update controller routers

* add generic success response

* add category/tag/tool tests

* add token refresh test

* add coverage utilities

* covert comments to controller

* add todo

* add helper properties

* delete old service

* update test notes

* add unit test for pretty_stats

* remove dead code from post_webhooks

* update group routes to use controllers

* add additional group test coverage

* abstract common permission checks

* convert ingredient parser to controller

* update recipe crud to use controller

* remove dead-code

* add class lifespan tracker for debugging

* convert bulk export to controller

* migrate tools router to controller

* update recipe share to controller

* move customer router to _base

* ignore prints in flake8

* convert units and foods to new controllers

* migrate user routes to controllers

* centralize error handling

* fix invalid ref

* reorder fields

* update routers to share common handling

* update tests

* remove prints

* fix cookbooks delete

* fix cookbook get

* add controller for mealplanner

* cover report routes to controller

* remove __future__ imports

* remove dead code

* remove all base_http children and remove dead code
This commit is contained in:
Hayden 2022-01-13 13:06:52 -09:00 committed by GitHub
parent 5823a32daf
commit c4540f1395
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
164 changed files with 3111 additions and 3213 deletions

View file

@ -1,8 +1,14 @@
import random
from dataclasses import dataclass
from uuid import UUID
import pytest
from fastapi.testclient import TestClient
from mealie.repos.repository_factory import AllRepositories
from mealie.schema.cookbook.cookbook import ReadCookBook, SaveCookBook
from tests.utils.assertion_helpers import assert_ignore_keys
from tests.utils.factories import random_string
from tests.utils.fixture_schemas import TestUser
@ -14,27 +20,56 @@ class Routes:
def get_page_data(group_id: UUID):
name_and_slug = random_string(10)
return {
"name": "My New Page",
"slug": "my-new-page",
"name": name_and_slug,
"slug": name_and_slug,
"description": "",
"position": 0,
"categories": [],
"group_id": group_id,
"group_id": str(group_id),
}
@dataclass
class TestCookbook:
id: int
slug: str
name: str
data: dict
@pytest.fixture(scope="function")
def cookbooks(database: AllRepositories, unique_user: TestUser) -> list[TestCookbook]:
data: list[ReadCookBook] = []
yield_data: list[TestCookbook] = []
for _ in range(3):
cb = database.cookbooks.create(SaveCookBook(**get_page_data(unique_user.group_id)))
data.append(cb)
yield_data.append(TestCookbook(id=cb.id, slug=cb.slug, name=cb.name, data=cb.dict()))
yield yield_data
for cb in yield_data:
try:
database.cookbooks.delete(cb.id)
except Exception:
pass
def test_create_cookbook(api_client: TestClient, unique_user: TestUser):
page_data = get_page_data(unique_user.group_id)
response = api_client.post(Routes.base, json=page_data, headers=unique_user.token)
assert response.status_code == 201
def test_read_cookbook(api_client: TestClient, unique_user: TestUser):
page_data = get_page_data(unique_user.group_id)
def test_read_cookbook(api_client: TestClient, unique_user: TestUser, cookbooks: list[TestCookbook]):
sample = random.choice(cookbooks)
response = api_client.get(Routes.item(1), headers=unique_user.token)
assert_ignore_keys(response.json(), page_data)
response = api_client.get(Routes.item(sample.id), headers=unique_user.token)
assert response.status_code == 200
assert_ignore_keys(response.json(), sample.data)
def test_update_cookbook(api_client: TestClient, unique_user: TestUser):
@ -44,14 +79,36 @@ def test_update_cookbook(api_client: TestClient, unique_user: TestUser):
page_data["name"] = "My New Name"
response = api_client.put(Routes.item(1), json=page_data, headers=unique_user.token)
assert response.status_code == 200
def test_delete_cookbook(api_client: TestClient, unique_user: TestUser):
response = api_client.delete(Routes.item(1), headers=unique_user.token)
def test_update_cookbooks_many(api_client: TestClient, unique_user: TestUser, cookbooks: list[TestCookbook]):
pages = [x.data for x in cookbooks]
reverse_order = sorted(pages, key=lambda x: x["position"], reverse=True)
for x, page in enumerate(reverse_order):
page["position"] = x
page["group_id"] = str(unique_user.group_id)
response = api_client.put(Routes.base, json=reverse_order, headers=unique_user.token)
assert response.status_code == 200
response = api_client.get(Routes.base, headers=unique_user.token)
assert response.status_code == 200
known_ids = [x.id for x in cookbooks]
server_ids = [x["id"] for x in response.json()]
for know in known_ids: # Hacky check, because other tests don't cleanup after themselves :(
assert know in server_ids
def test_delete_cookbook(api_client: TestClient, unique_user: TestUser, cookbooks: list[TestCookbook]):
sample = random.choice(cookbooks)
response = api_client.delete(Routes.item(sample.id), headers=unique_user.token)
assert response.status_code == 200
response = api_client.get(Routes.item(1), headers=unique_user.token)
response = api_client.get(Routes.item(sample.slug), headers=unique_user.token)
assert response.status_code == 404

View file

@ -0,0 +1,38 @@
from fastapi.testclient import TestClient
from mealie.repos.all_repositories import AllRepositories
from tests.utils.assertion_helpers import assert_ignore_keys
from tests.utils.fixture_schemas import TestUser
class Routes:
base = "/api/groups/categories"
@staticmethod
def item(item_id: int | str) -> str:
return f"{Routes.base}/{item_id}"
def test_group_mealplan_set_preferences(api_client: TestClient, unique_user: TestUser, database: AllRepositories):
# Create Categories
categories = [{"name": x} for x in ["Breakfast", "Lunch", "Dinner"]]
created = []
for category in categories:
create = database.categories.create(category)
created.append(create.dict())
# Set Category Preferences
response = api_client.put(Routes.base, json=created, headers=unique_user.token)
assert response.status_code == 200
# Get Category Preferences
response = api_client.get(Routes.base, headers=unique_user.token)
assert response.status_code == 200
as_dict = response.json()
assert len(as_dict) == len(categories)
for api_data, expected in zip(as_dict, created):
assert_ignore_keys(api_data, expected, ["id", "recipes"])

View file

@ -0,0 +1,100 @@
from uuid import uuid4
from fastapi.testclient import TestClient
from mealie.repos.repository_factory import AllRepositories
from tests.utils.factories import random_bool
from tests.utils.fixture_schemas import TestUser
class Routes:
self = "/api/groups/self"
memebers = "/api/groups/members"
permissions = "/api/groups/permissions"
def get_permissions_payload(user_id: str, can_manage=None) -> dict:
return {
"user_id": user_id,
"can_manage": random_bool() if can_manage is None else can_manage,
"can_invite": random_bool(),
"can_organize": random_bool(),
}
def test_get_group_members(api_client: TestClient, user_tuple: list[TestUser]):
usr_1, usr_2 = user_tuple
response = api_client.get(Routes.memebers, headers=usr_1.token)
assert response.status_code == 200
members = response.json()
assert len(members) >= 2
all_ids = [x["id"] for x in members]
assert str(usr_1.user_id) in all_ids
assert str(usr_2.user_id) in all_ids
def test_set_memeber_permissions(api_client: TestClient, user_tuple: list[TestUser], database: AllRepositories):
usr_1, usr_2 = user_tuple
# Set Acting User
acting_user = database.users.get_one(usr_1.user_id)
acting_user.can_manage = True
database.users.update(acting_user.id, acting_user)
payload = get_permissions_payload(str(usr_2.user_id))
# Test
response = api_client.put(Routes.permissions, json=payload, headers=usr_1.token)
assert response.status_code == 200
def test_set_memeber_permissions_unauthorized(api_client: TestClient, unique_user: TestUser, database: AllRepositories):
# Setup
user = database.users.get_one(unique_user.user_id)
user.can_manage = False
database.users.update(user.id, user)
payload = get_permissions_payload(str(user.id))
payload = {
"user_id": str(user.id),
"can_manage": True,
"can_invite": True,
"can_organize": True,
}
# Test
response = api_client.put(Routes.permissions, json=payload, headers=unique_user.token)
assert response.status_code == 403
def test_set_memeber_permissions_other_group(
api_client: TestClient,
unique_user: TestUser,
g2_user: TestUser,
database: AllRepositories,
):
user = database.users.get_one(unique_user.user_id)
user.can_manage = True
database.users.update(user.id, user)
payload = get_permissions_payload(str(g2_user.user_id))
response = api_client.put(Routes.permissions, json=payload, headers=unique_user.token)
assert response.status_code == 403
def test_set_memeber_permissions_no_user(
api_client: TestClient,
unique_user: TestUser,
database: AllRepositories,
):
user = database.users.get_one(unique_user.user_id)
user.can_manage = True
database.users.update(user.id, user)
payload = get_permissions_payload(str(uuid4()))
response = api_client.put(Routes.permissions, json=payload, headers=unique_user.token)
assert response.status_code == 404

View file

@ -12,7 +12,6 @@ class Routes:
def test_get_preferences(api_client: TestClient, unique_user: TestUser) -> None:
response = api_client.get(Routes.preferences, headers=unique_user.token)
assert response.status_code == 200
preferences = response.json()

View file

@ -1,15 +0,0 @@
# from fastapi.testclient import TestClient
# from tests.utils.fixture_schemas import TestUser
# class Routes:
# base = "/api/groups/manage/data" # Not sure if this is a good url?!?!?
# def test_recipe_export(api_client: TestClient, unique_user: TestUser) -> None:
# assert False
# def test_recipe_import(api_client: TestClient, unique_user: TestUser) -> None:
# assert False