diff --git a/.github/workflows/black.yml b/.github/workflows/black.yml new file mode 100644 index 0000000..ff72390 --- /dev/null +++ b/.github/workflows/black.yml @@ -0,0 +1,9 @@ +name: black-action +on: [push, pull_request] +jobs: + linter_name: + name: runner / black formatter + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: rickstaa/action-black@v1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 1fa0751..01953ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,28 @@ # Changelog +## [v1.0.0](https://github.com/SebRut/pygrocy/tree/v1.0.0) (2021-09-10) + +[Full Changelog](https://github.com/SebRut/pygrocy/compare/v0.30.0...v1.0.0) + +**Implemented enhancements:** + +- Add assigned\_to\_user to task [\#188](https://github.com/SebRut/pygrocy/issues/188) +- Add support for meal plan sections in grocy v3.1.0 [\#172](https://github.com/SebRut/pygrocy/issues/172) + +**Closed issues:** + +- add category field to task [\#189](https://github.com/SebRut/pygrocy/issues/189) +- support consuming decimal amounts [\#187](https://github.com/SebRut/pygrocy/issues/187) + +**Merged pull requests:** + +- add assigned\_to\_user field to Task [\#190](https://github.com/SebRut/pygrocy/pull/190) ([SebRut](https://github.com/SebRut)) +- apply black to everything [\#185](https://github.com/SebRut/pygrocy/pull/185) ([SebRut](https://github.com/SebRut)) +- migrate to pydantic [\#184](https://github.com/SebRut/pygrocy/pull/184) ([SebRut](https://github.com/SebRut)) +- add basic support for product and note type [\#183](https://github.com/SebRut/pygrocy/pull/183) ([SebRut](https://github.com/SebRut)) +- add meal plan section support [\#182](https://github.com/SebRut/pygrocy/pull/182) ([SebRut](https://github.com/SebRut)) +- add users getter [\#170](https://github.com/SebRut/pygrocy/pull/170) ([SebRut](https://github.com/SebRut)) + ## [v0.30.0](https://github.com/SebRut/pygrocy/tree/v0.30.0) (2021-08-23) [Full Changelog](https://github.com/SebRut/pygrocy/compare/v0.29.0...v0.30.0) diff --git a/pygrocy/data_models/chore.py b/pygrocy/data_models/chore.py index 6e57df5..2dd71d1 100644 --- a/pygrocy/data_models/chore.py +++ b/pygrocy/data_models/chore.py @@ -1,9 +1,14 @@ from datetime import datetime from enum import Enum -from typing import List, Dict +from typing import Dict + from pygrocy.base import DataModel from pygrocy.data_models.user import User -from pygrocy.grocy_api_client import CurrentChoreResponse, ChoreDetailsResponse, GrocyApiClient +from pygrocy.grocy_api_client import ( + ChoreDetailsResponse, + CurrentChoreResponse, + GrocyApiClient, +) class PeriodType(str, Enum): diff --git a/pygrocy/data_models/generic.py b/pygrocy/data_models/generic.py index d85af48..f14c157 100644 --- a/pygrocy/data_models/generic.py +++ b/pygrocy/data_models/generic.py @@ -23,3 +23,4 @@ class EntityType(str, Enum): USER_ENTITIES = "userentities" USER_OBJECTS = "userobjects" MEAL_PLAN = "meal_plan" + MEAL_PLAN_SECTIONS = "meal_plan_sections" diff --git a/pygrocy/data_models/meal_items.py b/pygrocy/data_models/meal_items.py index 7d2126b..0fe9ecb 100644 --- a/pygrocy/data_models/meal_items.py +++ b/pygrocy/data_models/meal_items.py @@ -1,10 +1,12 @@ import base64 from datetime import datetime +from enum import Enum from pygrocy.base import DataModel from pygrocy.grocy_api_client import ( GrocyApiClient, MealPlanResponse, + MealPlanSectionResponse, RecipeDetailsResponse, ) @@ -50,6 +52,36 @@ def get_picture_url_path(self, width: int = 400): return f"{path}?force_serve_as=picture&best_fit_width={width}" +class MealPlanSection(DataModel): + def __init__(self, response: MealPlanSectionResponse): + self._id = response.id + self._name = response.name + self._sort_number = response.sort_number + self._row_created_timestamp = response.row_created_timestamp + + @property + def id(self) -> int: + return self._id + + @property + def name(self) -> str: + return self._name + + @property + def sort_number(self) -> int: + return self._sort_number + + @property + def row_created_timestamp(self) -> datetime: + return self._row_created_timestamp + + +class MealPlanItemType(str, Enum): + NOTE = "note" + PRODUCT = "product" + RECIPE = "recipe" + + class MealPlanItem(DataModel): def __init__(self, response: MealPlanResponse): self._id = response.id @@ -58,13 +90,16 @@ def __init__(self, response: MealPlanResponse): self._recipe_id = response.recipe_id self._recipe_servings = response.recipe_servings self._note = response.note + self._section_id = response.section_id + self._type = MealPlanItemType(response.type) + self._product_id = response.product_id @property def id(self) -> int: return self._id @property - def day(self) -> datetime: + def day(self) -> datetime.date: return self._day @property @@ -83,8 +118,28 @@ def note(self) -> str: def recipe(self) -> RecipeItem: return self._recipe + @property + def section_id(self) -> int: + return self._section_id + + @property + def section(self) -> MealPlanSection: + return self._section + + @property + def type(self) -> MealPlanItemType: + return self._type + + @property + def product_id(self) -> int: + return self._product_id + def get_details(self, api_client: GrocyApiClient): if self.recipe_id: recipe = api_client.get_recipe(self.recipe_id) if recipe: self._recipe = RecipeItem(recipe) + if self.section_id: + section = api_client.get_meal_plan_section(self.section_id) + if section: + self._section = MealPlanSection(section) diff --git a/pygrocy/data_models/product.py b/pygrocy/data_models/product.py index bb98038..8f6ede0 100644 --- a/pygrocy/data_models/product.py +++ b/pygrocy/data_models/product.py @@ -56,7 +56,7 @@ def _init_from_CurrentStockResponse(self, response: CurrentStockResponse): self._init_from_ProductData(response.product) def _init_from_MissingProductResponse(self, response: MissingProductResponse): - self._id = response.product_id + self._id = response.id self._name = response.name self._amount_missing = response.amount_missing self._is_partly_in_stock = response.is_partly_in_stock @@ -78,7 +78,7 @@ def get_details(self, api_client: GrocyApiClient): details = api_client.get_product(self.id) if details: self._name = details.product.name - self._barcodes = details.barcodes + self._barcodes = [ProductBarcode(barcode) for barcode in details.barcodes] self._product_group_id = details.product.product_group_id @property @@ -98,7 +98,7 @@ def available_amount(self) -> float: return self._available_amount @property - def best_before_date(self) -> datetime: + def best_before_date(self) -> datetime.date: return self._best_before_date @property diff --git a/pygrocy/data_models/task.py b/pygrocy/data_models/task.py index 466ec54..851d2a1 100644 --- a/pygrocy/data_models/task.py +++ b/pygrocy/data_models/task.py @@ -1,7 +1,33 @@ from datetime import datetime from typing import Dict + from pygrocy.base import DataModel -from pygrocy.grocy_api_client import TaskResponse +from pygrocy.data_models.user import User +from pygrocy.grocy_api_client import TaskCategoryDto, TaskResponse + + +class TaskCategory(DataModel): + def __init__(self, data: TaskCategoryDto): + self._id = data.id + self._name = data.name + self._description = data.description + self._row_created_timestamp = data.row_created_timestamp + + @property + def id(self) -> int: + return self._id + + @property + def name(self) -> str: + return self._name + + @property + def description(self) -> str: + return self._description + + @property + def row_created_timestamp(self) -> datetime: + return self._row_created_timestamp class Task(DataModel): @@ -14,11 +40,15 @@ def __init__(self, response: TaskResponse): self._done = response.done self._done_timestamp = response.done_timestamp self._category_id = response.category_id + if response.category: + self._category = TaskCategory(response.category) self._assigned_to_user_id = response.assigned_to_user_id + if response.assigned_to_user: + self._assigned_to_user = User(response.assigned_to_user) self._userfields = response.userfields @property - def id(self) -> str: + def id(self) -> int: return self._id @property @@ -30,7 +60,7 @@ def description(self) -> str: return self._description @property - def due_date(self) -> datetime: + def due_date(self) -> datetime.date: return self._due_date @property @@ -45,10 +75,18 @@ def done_timestamp(self) -> datetime: def category_id(self) -> int: return self._category_id + @property + def category(self) -> TaskCategory: + return self._category + @property def assigned_to_user_id(self) -> int: return self._assigned_to_user_id + @property + def assigned_to_user(self) -> User: + return self._assigned_to_user + @property def userfields(self) -> Dict[str, str]: - return self._userfields \ No newline at end of file + return self._userfields diff --git a/pygrocy/data_models/user.py b/pygrocy/data_models/user.py index 40953ed..9bf256e 100644 --- a/pygrocy/data_models/user.py +++ b/pygrocy/data_models/user.py @@ -28,4 +28,4 @@ def last_name(self) -> str: @property def display_name(self) -> str: - return self._display_name \ No newline at end of file + return self._display_name diff --git a/pygrocy/grocy.py b/pygrocy/grocy.py index adc79e6..ed5a5f9 100644 --- a/pygrocy/grocy.py +++ b/pygrocy/grocy.py @@ -8,7 +8,7 @@ from .data_models.battery import Battery from .data_models.chore import Chore from .data_models.generic import EntityType -from .data_models.meal_items import MealPlanItem, RecipeItem +from .data_models.meal_items import MealPlanItem, MealPlanSection, RecipeItem from .data_models.product import Group, Product, ShoppingListProduct from .data_models.task import Task from .data_models.user import User # noqa: F401 @@ -98,7 +98,7 @@ def all_products(self) -> List[Product]: raw_products = self.get_generic_objects_for_type(EntityType.PRODUCTS) from pygrocy.grocy_api_client import ProductData - product_datas = [ProductData(product) for product in raw_products] + product_datas = [ProductData(**product) for product in raw_products] return [Product(product) for product in product_datas] def chores(self, get_details: bool = False) -> List[Chore]: @@ -237,3 +237,22 @@ def delete_generic(self, entity_type: EntityType, object_id: int): def get_generic_objects_for_type(self, entity_type: EntityType): return self._api_client.get_generic_objects_for_type(entity_type.value) + + def meal_plan_sections(self) -> List[MealPlanSection]: + raw_sections = self._api_client.get_meal_plan_sections() + return [MealPlanSection(section) for section in raw_sections] + + def meal_plan_section(self, meal_plan_section_id: int) -> MealPlanSection: + section = self._api_client.get_meal_plan_section(meal_plan_section_id) + + if section: + return MealPlanSection(section) + + def users(self) -> List[User]: + user_dtos = self._api_client.get_users() + return [User(user) for user in user_dtos] + + def user(self, user_id: int = None) -> User: + user = self._api_client.get_user(user_id=user_id) + if user: + return User(user) diff --git a/pygrocy/grocy_api_client.py b/pygrocy/grocy_api_client.py index 4cb183b..ddf4ddb 100644 --- a/pygrocy/grocy_api_client.py +++ b/pygrocy/grocy_api_client.py @@ -3,18 +3,15 @@ import logging from datetime import datetime from enum import Enum -from typing import List +from typing import Dict, List, Optional from urllib.parse import urljoin import requests +from pydantic import BaseModel, Field +from pydantic.schema import date -from pygrocy.utils import ( - localize_datetime, - parse_bool_int, - parse_date, - parse_float, - parse_int, -) +from pygrocy import EntityType +from pygrocy.utils import localize_datetime, parse_date from .errors import GrocyError @@ -24,519 +21,206 @@ _LOGGER.setLevel(logging.INFO) -class ShoppingListItem(object): - def __init__(self, parsed_json): - self._id = parse_int(parsed_json.get("id")) - self._product_id = parse_int(parsed_json.get("product_id", None)) - self._note = parsed_json.get("note", None) - self._amount = parse_float(parsed_json.get("amount"), 0) - self._row_created_timestamp = parse_date( - parsed_json.get("row_created_timestamp", None) - ) - self._shopping_list_id = parse_int(parsed_json.get("shopping_list_id")) - self._done = parse_int(parsed_json.get("done")) - - @property - def id(self) -> int: - return self._id - - @property - def product_id(self) -> int: - return self._product_id - - @property - def note(self) -> str: - return self._note - - @property - def amount(self) -> float: - return self._amount - - -class MealPlanResponse(object): - def __init__(self, parsed_json): - self._id = parse_int(parsed_json.get("id")) - self._day = parse_date(parsed_json.get("day")) - self._type = parsed_json.get("type") - self._recipe_id = parse_int(parsed_json.get("recipe_id")) - self._recipe_servings = parse_int(parsed_json.get("recipe_servings")) - self._note = parsed_json.get("note", None) - self._product_id = parsed_json.get("product_id") - self._product_amount = parse_float(parsed_json.get("product_amount"), 0) - self._product_qu_id = parsed_json.get("product_qu_id") - self._row_created_timestamp = parse_date( - parsed_json.get("row_created_timestamp") - ) - self._userfields = parsed_json.get("userfields") - - @property - def id(self) -> int: - return self._id - - @property - def day(self) -> datetime: - return self._day - - @property - def recipe_id(self) -> int: - return self._recipe_id - - @property - def recipe_servings(self) -> int: - return self._recipe_servings - - @property - def note(self) -> str: - return self._note - - -class RecipeDetailsResponse(object): - def __init__(self, parsed_json): - self._id = parse_int(parsed_json.get("id")) - self._name = parsed_json.get("name") - self._description = parsed_json.get("description") - self._base_servings = parse_int(parsed_json.get("base_servings")) - self._desired_servings = parse_int(parsed_json.get("desired_servings")) - self._picture_file_name = parsed_json.get("picture_file_name") - self._row_created_timestamp = parse_date( - parsed_json.get("row_created_timestamp") - ) - self._userfields = parsed_json.get("userfields") - - @property - def id(self) -> int: - return self._id - - @property - def name(self) -> str: - return self._name - - @property - def description(self) -> str: - return self._description - - @property - def base_servings(self) -> int: - return self._base_servings - - @property - def desired_servings(self) -> int: - return self._desired_servings - - @property - def picture_file_name(self) -> str: - return self._picture_file_name - - -class QuantityUnitData(object): - def __init__(self, parsed_json): - self._id = parse_int(parsed_json.get("id")) - self._name = parsed_json.get("name") - self._name_plural = parsed_json.get("name_plural") - self._description = parsed_json.get("description") - self._row_created_timestamp = parse_date( - parsed_json.get("row_created_timestamp") - ) - - -class LocationData(object): - def __init__(self, parsed_json): - self._id = parse_int(parsed_json.get("id")) - self._name = parsed_json.get("name") - self._description = parsed_json.get("description") - self._row_created_timestamp = parse_date( - parsed_json.get("row_created_timestamp") - ) - - @property - def id(self) -> int: - return self._id - - @property - def name(self) -> str: - return self._name - - @property - def description(self) -> str: - return self._description - - -class ProductData(object): - def __init__(self, parsed_json): - self._id = parse_int(parsed_json.get("id")) - self._name = parsed_json.get("name") - self._description = parsed_json.get("description", None) - self._location_id = parse_int(parsed_json.get("location_id", None)) - self._product_group_id = parse_int(parsed_json.get("product_group_id", None)) - self._qu_id_stock = parse_int(parsed_json.get("qu_id_stock", None)) - self._qu_id_purchase = parse_int(parsed_json.get("qu_id_purchsase", None)) - self._qu_factor_purchase_to_stock = parse_float( - parsed_json.get("qu_factor_purchase_to_stock", None) - ) - self._picture_file_name = parsed_json.get("picture_file_name", None) - self._allow_partial_units_in_stock = bool( - parsed_json.get("allow_partial_units_in_stock", None) == "true" - ) - self._row_created_timestamp = parse_date( - parsed_json.get("row_created_timestamp", None) - ) - self._min_stock_amount = parse_int(parsed_json.get("min_stock_amount", None), 0) - self._default_best_before_days = parse_int( - parsed_json.get("default_best_before_days", None) - ) - - @property - def id(self) -> int: - return self._id - - @property - def product_group_id(self) -> int: - return self._product_group_id - - @property - def name(self) -> str: - return self._name - - -class ChoreData(object): - def __init__(self, parsed_json): - self.id = parse_int(parsed_json.get("id")) - self.name = parsed_json.get("name") - self.description = parsed_json.get("description") - self.period_type = parsed_json.get("period_type") - self.period_config = parsed_json.get("period_config") - self.period_days = parse_int(parsed_json.get("period_days")) - self.track_date_only = parse_bool_int(parsed_json.get("track_date_only")) - self.rollover = parse_bool_int(parsed_json.get("rollover")) - self.assignment_type = parsed_json.get("assignment_type") - self.assignment_config = parsed_json.get("assignment_config") - self.next_execution_assigned_to_user_id = parse_int( - parsed_json.get("next_execution_assigned_to_user_id") - ) - self.userfields = parsed_json.get("userfields") - +class ShoppingListItem(BaseModel): + id: int + product_id: Optional[int] = None + note: Optional[str] = None + amount: float + row_created_timestamp: datetime + shopping_list_id: int + done: int + + +class MealPlanResponse(BaseModel): + id: int + day: date + type: str + recipe_id: Optional[int] = None + recipe_servings: Optional[int] = None + note: Optional[str] = None + product_id: Optional[int] = None + product_amount: Optional[float] = None + product_qu_id: Optional[str] = None + row_created_timestamp: datetime + userfields: Optional[Dict] = None + section_id: Optional[int] = None + + +class RecipeDetailsResponse(BaseModel): + id: Optional[int] = None + name: str + description: Optional[str] = None + base_servings: int + desired_servings: int + picture_file_name: Optional[str] + row_created_timestamp: datetime + userfields: Optional[Dict] = None + + +class QuantityUnitData(BaseModel): + id: int + name: str + name_plural: str + description: Optional[str] = None + row_created_timestamp: datetime + + +class LocationData(BaseModel): + id: int + name: str + description: Optional[str] = None + row_created_timestamp: datetime + + +class ProductData(BaseModel): + id: int + name: str + description: Optional[str] = None + location_id: int + product_group_id: Optional[int] = None + qu_id_stock: int + qu_id_purchase: int + qu_factor_purchase_to_stock: float + picture_file_name: Optional[str] = None + allow_partial_units_in_stock: Optional[bool] = False + row_created_timestamp: datetime + min_stock_amount: Optional[int] + default_best_before_days: int + + +class ChoreData(BaseModel): + id: int + name: str + description: Optional[str] = None + period_type: str + period_config: Optional[str] = None + period_days: Optional[int] = 0 + track_date_only: bool + rollover: bool + assignment_type: Optional[str] = None + assignment_config: Optional[str] = None + next_execution_assigned_to_user_id: Optional[int] = None + userfields: Optional[Dict] + + +class UserDto(BaseModel): + id: int + username: str + first_name: Optional[str] = None + last_name: Optional[str] = None + display_name: Optional[str] = None + + +class CurrentChoreResponse(BaseModel): + chore_id: int + last_tracked_time: Optional[datetime] + next_estimated_execution_time: datetime + + +class CurrentStockResponse(BaseModel): + product_id: int + amount: float + best_before_date: date + amount_opened: float + product: ProductData + + +class MissingProductResponse(BaseModel): + id: int + name: str + amount_missing: float + is_partly_in_stock: bool + + +class CurrentVolatilStockResponse(BaseModel): + due_products: Optional[List[CurrentStockResponse]] = None + overdue_products: Optional[List[CurrentStockResponse]] = None + expired_products: Optional[List[CurrentStockResponse]] = None + missing_products: Optional[List[MissingProductResponse]] = None + + +class ProductBarcodeData(BaseModel): + barcode: str + + +class ProductDetailsResponse(BaseModel): + last_purchased: Optional[date] = None + last_used: Optional[datetime] = None + stock_amount: int + stock_amount_opened: int + next_best_before_date: Optional[date] = None + last_price: Optional[float] = None + product: ProductData + quantity_unit_stock: QuantityUnitData + barcodes: Optional[List[ProductBarcodeData]] = Field(alias="product_barcodes") + location: Optional[LocationData] = None + + +class ChoreDetailsResponse(BaseModel): + chore: ChoreData + last_tracked: Optional[datetime] = None + next_estimated_execution_time: datetime + track_count: int = 0 + next_execution_assigned_user: Optional[UserDto] = None + last_done_by: Optional[UserDto] = None -class UserDto(object): - def __init__(self, parsed_json): - self._id = parse_int(parsed_json.get("id")) - - self._username = parsed_json.get("username") - self._first_name = parsed_json.get("first_name") - self._last_name = parsed_json.get("last_name") - self._display_name = parsed_json.get("display_name") - - @property - def id(self) -> int: - return self._id - - @property - def username(self) -> str: - return self._username - - @property - def first_name(self) -> str: - return self._first_name - - @property - def last_name(self) -> str: - return self._last_name - - @property - def display_name(self) -> str: - return self._display_name - - -class CurrentChoreResponse(object): - def __init__(self, parsed_json): - self._chore_id = parse_int(parsed_json.get("chore_id"), None) - self._last_tracked_time = parse_date(parsed_json.get("last_tracked_time")) - self._next_estimated_execution_time = parse_date( - parsed_json.get("next_estimated_execution_time") - ) - - @property - def chore_id(self) -> int: - return self._chore_id - - @property - def last_tracked_time(self) -> datetime: - return self._last_tracked_time - - @property - def next_estimated_execution_time(self) -> datetime: - return self._next_estimated_execution_time - - -class CurrentStockResponse(object): - def __init__(self, parsed_json): - self._product_id = parse_int(parsed_json.get("product_id")) - self._amount = parse_float(parsed_json.get("amount")) - self._best_before_date = parse_date(parsed_json.get("best_before_date")) - self._amount_opened = parse_float(parsed_json.get("amount_opened")) - self._product = ProductData(parsed_json.get("product")) - - @property - def product_id(self) -> int: - return self._product_id - - @property - def amount(self) -> float: - return self._amount - - @property - def best_before_date(self) -> datetime: - return self._best_before_date - - @property - def amount_opened(self) -> float: - return self._amount_opened - - @property - def product(self) -> ProductData: - return self._product - - -class MissingProductResponse(object): - def __init__(self, parsed_json): - self._product_id = parse_int(parsed_json.get("id")) - self._name = parsed_json.get("name") - self._amount_missing = parse_float(parsed_json.get("amount_missing")) - self._is_partly_in_stock = bool( - parse_int(parsed_json.get("is_partly_in_stock")) - ) - @property - def product_id(self) -> int: - return self._product_id - - @property - def name(self) -> str: - return self._name - - @property - def amount_missing(self) -> float: - return self._amount_missing - - @property - def is_partly_in_stock(self) -> bool: - return self._is_partly_in_stock - - -class CurrentVolatilStockResponse(object): - def __init__(self, parsed_json): - self._due_products = [] - if "due_products" in parsed_json: - self._due_products = [ - CurrentStockResponse(product) - for product in parsed_json.get("due_products") - ] - - self._overdue_products = [] - if "overdue_products" in parsed_json: - self._overdue_products = [ - CurrentStockResponse(product) - for product in parsed_json.get("overdue_products") - ] - - self._expired_products = [] - if "expired_products" in parsed_json: - self._expired_products = [ - CurrentStockResponse(product) - for product in parsed_json.get("expired_products") - ] - - self._missing_products = [] - if "missing_products" in parsed_json: - self._missing_products = [ - MissingProductResponse(product) - for product in parsed_json.get("missing_products") - ] - - @property - def due_products(self) -> List[CurrentStockResponse]: - return self._due_products - - @property - def overdue_products(self) -> List[CurrentStockResponse]: - return self._overdue_products - - @property - def expired_products(self) -> List[CurrentStockResponse]: - return self._expired_products - - @property - def missing_products(self) -> List[MissingProductResponse]: - return self._missing_products - - -class ProductBarcodeData(object): - def __init__(self, parsed_json): - self._barcode = str(parsed_json.get("barcode")) - - @property - def barcode(self) -> str: - return self._barcode - - -class ProductDetailsResponse(object): - def __init__(self, parsed_json): - self._last_purchased = parse_date(parsed_json.get("last_purchased")) - self._last_used = parse_date(parsed_json.get("last_used")) - self._stock_amount = parse_int(parsed_json.get("stock_amount")) - self._stock_amount_opened = parse_int(parsed_json.get("stock_amount_opened")) - self._next_best_before_date = parse_date( - parsed_json.get("next_best_before_date") - ) - self._last_price = parse_float(parsed_json.get("last_price")) - - self._product = ProductData(parsed_json.get("product")) - - self._quantity_unit_stock = QuantityUnitData( - parsed_json.get("quantity_unit_stock") - ) - - self._parse_location(parsed_json) - - self._parse_barcodes(parsed_json) - - def _parse_barcodes(self, parsed_json): - barcodes_raw = parsed_json.get("product_barcodes", "") - if barcodes_raw is not None: - self._barcodes = [ProductBarcodeData(barcode) for barcode in barcodes_raw] - - def _parse_location(self, parsed_json): - raw_location = parsed_json.get("location") - if raw_location is None: - self._location = None - else: - self._location = LocationData(raw_location) - - @property - def last_purchased(self) -> datetime: - return self._last_purchased - - @property - def last_used(self) -> datetime: - return self._last_used - - @property - def stock_amount(self) -> int: - return self._stock_amount - - @property - def stock_amount_opened(self) -> int: - return self._stock_amount_opened - - @property - def next_best_before_date(self) -> datetime: - return self._next_best_before_date - - @property - def last_price(self) -> float: - return self._last_price - - @property - def barcodes(self) -> List[ProductBarcodeData]: - return self._barcodes - - @property - def product(self) -> ProductData: - return self._product - - -class ChoreDetailsResponse(object): - def __init__(self, parsed_json): - self._chore = ChoreData(parsed_json.get("chore")) - self._last_tracked = parse_date(parsed_json.get("last_tracked")) - self._next_estimated_execution_time = parse_date( - parsed_json.get("next_estimated_execution_time") - ) - self._track_count = parse_int(parsed_json.get("track_count")) - - next_user = parsed_json.get("next_execution_assigned_user") - if next_user is not None: - self._next_execution_assigned_user = UserDto(next_user) - else: - self._next_execution_assigned_user = None - - if self._last_tracked is None: - self._last_done_by = None - else: - self._last_done_by = UserDto(parsed_json.get("last_done_by")) +class TransactionType(Enum): + PURCHASE = "purchase" + CONSUME = "consume" + INVENTORY_CORRECTION = "inventory-correction" + PRODUCT_OPENED = "product-opened" - @property - def chore(self) -> ChoreData: - return self._chore - @property - def last_done_by(self) -> UserDto: - return self._last_done_by +class TaskCategoryDto(BaseModel): + id: int + name: str + description: Optional[str] = None + row_created_timestamp: datetime - @property - def last_tracked(self) -> datetime: - return self._last_tracked - @property - def next_estimated_execution_time(self) -> datetime: - return self._next_estimated_execution_time +class TaskResponse(BaseModel): + id: int + name: str + description: Optional[str] = None + due_date: date + done: int + done_timestamp: Optional[datetime] = None + category_id: Optional[int] = None + category: Optional[TaskCategoryDto] = None + assigned_to_user_id: Optional[int] = None + assigned_to_user: Optional[UserDto] = None + userfields: Optional[Dict] = None - @property - def track_count(self) -> int: - return self._track_count - @property - def next_execution_assigned_user(self) -> UserDto: - return self._next_execution_assigned_user +class CurrentBatteryResponse(BaseModel): + id: int + last_tracked_time: Optional[datetime] = None + next_estimated_charge_time: datetime -class TransactionType(Enum): - PURCHASE = "purchase" - CONSUME = "consume" - INVENTORY_CORRECTION = "inventory-correction" - PRODUCT_OPENED = "product-opened" +class BatteryData(BaseModel): + id: int + name: str + description: str + used_in: str + charge_interval_days: int + created_timestamp: datetime = Field(alias="row_created_timestamp") + userfields: Optional[Dict] = None -class TaskResponse(object): - def __init__(self, parsed_json): - self.id = parse_int(parsed_json.get("id")) - self.name = parsed_json.get("name") - self.description = parsed_json.get("description") - self.due_date = parse_date(parsed_json.get("due_date")) - self.done = parse_int(parsed_json.get("done")) - self.done_timestamp = parse_date(parsed_json.get("done_timestamp")) - self.category_id = parse_int(parsed_json.get("category_id")) - self.assigned_to_user_id = parse_int(parsed_json.get("assigned_to_user_id")) - self.userfields = parsed_json.get("userfields") - - -class CurrentBatteryResponse(object): - def __init__(self, parsed_json): - self.id = parse_int(parsed_json.get("battery_id")) - self.last_tracked_time = parse_date(parsed_json.get("last_tracked_time")) - self.next_estimated_charge_time = parse_date( - parsed_json.get("'next_estimated_charge_time") - ) +class BatteryDetailsResponse(BaseModel): + battery: BatteryData + charge_cycles_count: int + last_charged: Optional[datetime] = None + next_estimated_charge_time: datetime -class BatteryData(object): - def __init__(self, parsed_json): - self.id = parse_int(parsed_json.get("id")) - self.name = parsed_json.get("name") - self.description = parsed_json.get("description") - self.used_in = parsed_json.get("used_in") - self.charge_interval_days = parse_int(parsed_json.get("charge_interval_days")) - self.created_timestamp = parse_date(parsed_json.get("row_created_timestamp")) - self.userfields = parsed_json.get("userfields") - - -class BatteryDetailsResponse(object): - def __init__(self, parsed_json): - self.battery = BatteryData(parsed_json.get("battery")) - self.charge_cycles_count = parse_int(parsed_json.get("charge_cycles_count")) - self.last_charged = parse_date(parsed_json.get("last_charged")) - self.next_estimated_charge_time = parse_date( - parsed_json.get("'next_estimated_charge_time") - ) +class MealPlanSectionResponse(BaseModel): + id: Optional[int] = None + name: str + sort_number: Optional[int] = None + row_created_timestamp: datetime def _enable_debug_mode(): @@ -635,27 +319,27 @@ def _do_delete_request(self, end_url: str): def get_stock(self) -> List[CurrentStockResponse]: parsed_json = self._do_get_request("stock") - return [CurrentStockResponse(response) for response in parsed_json] + return [CurrentStockResponse(**response) for response in parsed_json] def get_volatile_stock(self) -> CurrentVolatilStockResponse: parsed_json = self._do_get_request("stock/volatile") - return CurrentVolatilStockResponse(parsed_json) + return CurrentVolatilStockResponse(**parsed_json) def get_product(self, product_id) -> ProductDetailsResponse: url = f"stock/products/{product_id}" parsed_json = self._do_get_request(url) if parsed_json: - return ProductDetailsResponse(parsed_json) + return ProductDetailsResponse(**parsed_json) def get_chores(self) -> List[CurrentChoreResponse]: parsed_json = self._do_get_request("chores") - return [CurrentChoreResponse(chore) for chore in parsed_json] + return [CurrentChoreResponse(**chore) for chore in parsed_json] def get_chore(self, chore_id: int) -> ChoreDetailsResponse: url = f"chores/{chore_id}" parsed_json = self._do_get_request(url) if parsed_json: - return ChoreDetailsResponse(parsed_json) + return ChoreDetailsResponse(**parsed_json) def execute_chore( self, @@ -708,7 +392,7 @@ def consume_product( def get_shopping_list(self) -> List[ShoppingListItem]: parsed_json = self._do_get_request("objects/shopping_list") - return [ShoppingListItem(response) for response in parsed_json] + return [ShoppingListItem(**response) for response in parsed_json] def add_missing_product_to_shopping_list(self, shopping_list_id: int = None): data = None @@ -744,7 +428,7 @@ def remove_product_in_shopping_list( def get_product_groups(self) -> List[LocationData]: parsed_json = self._do_get_request("objects/product_groups") - return [LocationData(response) for response in parsed_json] + return [LocationData(**response) for response in parsed_json] def upload_product_picture(self, product_id: int, pic_path: str): b64fn = base64.b64encode("{}.jpg".format(product_id).encode("ascii")) @@ -772,7 +456,7 @@ def get_last_db_changed(self): def get_tasks(self) -> List[TaskResponse]: parsed_json = self._do_get_request("tasks") - return [TaskResponse(data) for data in parsed_json] + return [TaskResponse(**data) for data in parsed_json] def complete_task(self, task_id: int, done_time: datetime = datetime.now()): url = f"tasks/{task_id}/complete" @@ -784,22 +468,22 @@ def complete_task(self, task_id: int, done_time: datetime = datetime.now()): def get_meal_plan(self) -> List[MealPlanResponse]: parsed_json = self._do_get_request("objects/meal_plan") - return [MealPlanResponse(data) for data in parsed_json] + return [MealPlanResponse(**data) for data in parsed_json] def get_recipe(self, object_id: int) -> RecipeDetailsResponse: parsed_json = self._do_get_request(f"objects/recipes/{object_id}") if parsed_json: - return RecipeDetailsResponse(parsed_json) + return RecipeDetailsResponse(**parsed_json) def get_batteries(self) -> List[CurrentBatteryResponse]: parsed_json = self._do_get_request(f"batteries") if parsed_json: - return [CurrentBatteryResponse(data) for data in parsed_json] + return [CurrentBatteryResponse(**data) for data in parsed_json] def get_battery(self, battery_id: int) -> BatteryDetailsResponse: parsed_json = self._do_get_request(f"batteries/{battery_id}") if parsed_json: - return BatteryDetailsResponse(parsed_json) + return BatteryDetailsResponse(**parsed_json) def charge_battery(self, battery_id: int, tracked_time: datetime = datetime.now()): localized_tracked_time = localize_datetime(tracked_time) @@ -818,3 +502,28 @@ def delete_generic(self, entity_type: str, object_id: int): def get_generic_objects_for_type(self, entity_type: str): return self._do_get_request(f"objects/{entity_type}") + + def get_meal_plan_sections(self) -> List[MealPlanSectionResponse]: + parsed_json = self.get_generic_objects_for_type(EntityType.MEAL_PLAN_SECTIONS) + if parsed_json: + return [MealPlanSectionResponse(**resp) for resp in parsed_json] + + def get_meal_plan_section(self, meal_plan_section_id) -> MealPlanSectionResponse: + parsed_json = self._do_get_request( + f"objects/meal_plan_sections?query%5B%5D=id%3D{meal_plan_section_id}" + ) + if parsed_json and len(parsed_json) == 1: + return MealPlanSectionResponse(**parsed_json[0]) + + def get_users(self) -> List[UserDto]: + parsed_json = self._do_get_request("users") + if parsed_json: + return [UserDto(**user) for user in parsed_json] + + def get_user(self, user_id: int) -> UserDto: + query_params = [] + if user_id: + query_params.append(f"id={user_id}") + parsed_json = self._do_get_request("users") + if parsed_json: + return UserDto(**parsed_json[0]) diff --git a/setup.py b/setup.py index 2ab2e97..c0efc1e 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setuptools.setup( name="pygrocy", - version="0.30.0", + version="1.0.0", author="Sebastian Rutofski", author_email="kontakt@sebastian-rutofski.de", description="", @@ -20,6 +20,7 @@ "pytz~=2021.1", "tzlocal>=2.1,<3.0", "deprecation~=2.1.0", + "pydantic~=1.8.2", ], classifiers=[ "Programming Language :: Python :: 3", diff --git a/test/cassettes/test_meal_plan/TestMealPlan.test_get_meal_plan_with_details_valid.yaml b/test/cassettes/test_meal_plan/TestMealPlan.test_get_meal_plan_with_details_valid.yaml index 13001ee..38aeb65 100644 --- a/test/cassettes/test_meal_plan/TestMealPlan.test_get_meal_plan_with_details_valid.yaml +++ b/test/cassettes/test_meal_plan/TestMealPlan.test_get_meal_plan_with_details_valid.yaml @@ -15,11 +15,12 @@ interactions: response: body: string: !!binary | - H4sIAAAAAAAEA83U3QqCMBQH8FeRcz1hm2a25+guQoaOGvjVnIVE795SKXO0yxh4MQ7nP/zB2Tnc - QRbACIKCD8CAYkpCTEOcAgI9tMLUlMilOaD5kM2BqZx1Ql1lferGS+pGm0TdlyWCVjVFn+ux/bvC - q6avNTD8abr0iz7V3LJcCa5FkWlZiU7zql38HIkCsmMxYVECDzQJqCXYuQUm4JcgWgsIdgtMwC9B - bAmIW2ACfgk2loC6Bebh+CVILEHkFnj3DraWIHYLvJuidC3Ai100rsj31Lx26bQcf48R7M+yC8zH - gzn8p9V6fALTAMx5HgYAAA== + H4sIAAAAAAAEA9WVzWrDMAzHXyX47IDlpF3i59htlGBisxkaO3OclTL67lOTsKXN5h03gw9C6C/r + B/p4eidGEQGUKHkmgnDGIWc8ZxWhJJx7jT6vW4MGXYxmEczuZtD+zdjnYUpiXUCFHY9HSnrv1NiG + KfzWIzs32kAE+wp6HVdx3p2a1msZtGqC6fQQZNevioMig1qUIIo9VqWcxT8x16DbYJydEuVwoTMa + 36DVcTQUJIJW3KMBi6OhIBG0coMGcTQUJIK226DxOBoOZyJo+w1aEUdLZ9YeNmhlHC2dhqzu0dhq + Q04b/bMBr6t/3uU/dyR5fDFDhk9mi/ifXIL6lrPK+S+D94fdicWVGVSCgdhdZ+jbIweXwweKUAJF + wAcAAA== headers: Access-Control-Allow-Headers: - '*' @@ -34,7 +35,7 @@ interactions: Content-Type: - application/json Date: - - Sat, 21 Aug 2021 19:42:50 GMT + - Tue, 24 Aug 2021 18:09:33 GMT Server: - nginx/1.20.1 Transfer-Encoding: @@ -84,7 +85,49 @@ interactions: Content-Type: - application/json Date: - - Sat, 21 Aug 2021 19:42:50 GMT + - Tue, 24 Aug 2021 18:09:33 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/meal_plan_sections?query%5B%5D=id%3D-1 + response: + body: + string: !!binary | + H4sIAAAAAAAEAyXKwQqAIAwA0F+JnRWcXWS/EiGWO3hQYy46RP9e0Pm95YaSgSwaaKkyEICB0UVj + O+vG8pP0K+7CSTlHLZWHpnp81zuP1gXr58kFwpkwwLO+Gg7z9FQAAAA= + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Tue, 24 Aug 2021 18:09:33 GMT Server: - nginx/1.20.1 Transfer-Encoding: @@ -134,7 +177,49 @@ interactions: Content-Type: - application/json Date: - - Sat, 21 Aug 2021 19:42:50 GMT + - Tue, 24 Aug 2021 18:09:33 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/meal_plan_sections?query%5B%5D=id%3D-1 + response: + body: + string: !!binary | + H4sIAAAAAAAEAyXKwQqAIAwA0F+JnRWcXWS/EiGWO3hQYy46RP9e0Pm95YaSgSwaaKkyEICB0UVj + O+vG8pP0K+7CSTlHLZWHpnp81zuP1gXr58kFwpkwwLO+Gg7z9FQAAAA= + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Tue, 24 Aug 2021 18:09:34 GMT Server: - nginx/1.20.1 Transfer-Encoding: @@ -184,7 +269,49 @@ interactions: Content-Type: - application/json Date: - - Sat, 21 Aug 2021 19:42:50 GMT + - Tue, 24 Aug 2021 18:09:34 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/meal_plan_sections?query%5B%5D=id%3D-1 + response: + body: + string: !!binary | + H4sIAAAAAAAEAyXKwQqAIAwA0F+JnRWcXWS/EiGWO3hQYy46RP9e0Pm95YaSgSwaaKkyEICB0UVj + O+vG8pP0K+7CSTlHLZWHpnp81zuP1gXr58kFwpkwwLO+Gg7z9FQAAAA= + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Tue, 24 Aug 2021 18:09:34 GMT Server: - nginx/1.20.1 Transfer-Encoding: @@ -234,7 +361,49 @@ interactions: Content-Type: - application/json Date: - - Sat, 21 Aug 2021 19:42:50 GMT + - Tue, 24 Aug 2021 18:09:34 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/meal_plan_sections?query%5B%5D=id%3D-1 + response: + body: + string: !!binary | + H4sIAAAAAAAEAyXKwQqAIAwA0F+JnRWcXWS/EiGWO3hQYy46RP9e0Pm95YaSgSwaaKkyEICB0UVj + O+vG8pP0K+7CSTlHLZWHpnp81zuP1gXr58kFwpkwwLO+Gg7z9FQAAAA= + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Tue, 24 Aug 2021 18:09:34 GMT Server: - nginx/1.20.1 Transfer-Encoding: @@ -284,7 +453,49 @@ interactions: Content-Type: - application/json Date: - - Sat, 21 Aug 2021 19:42:51 GMT + - Tue, 24 Aug 2021 18:09:34 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/meal_plan_sections?query%5B%5D=id%3D-1 + response: + body: + string: !!binary | + H4sIAAAAAAAEAyXKwQqAIAwA0F+JnRWcXWS/EiGWO3hQYy46RP9e0Pm95YaSgSwaaKkyEICB0UVj + O+vG8pP0K+7CSTlHLZWHpnp81zuP1gXr58kFwpkwwLO+Gg7z9FQAAAA= + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Tue, 24 Aug 2021 18:09:34 GMT Server: - nginx/1.20.1 Transfer-Encoding: @@ -334,7 +545,49 @@ interactions: Content-Type: - application/json Date: - - Sat, 21 Aug 2021 19:42:51 GMT + - Tue, 24 Aug 2021 18:09:34 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/meal_plan_sections?query%5B%5D=id%3D-1 + response: + body: + string: !!binary | + H4sIAAAAAAAEAyXKwQqAIAwA0F+JnRWcXWS/EiGWO3hQYy46RP9e0Pm95YaSgSwaaKkyEICB0UVj + O+vG8pP0K+7CSTlHLZWHpnp81zuP1gXr58kFwpkwwLO+Gg7z9FQAAAA= + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Tue, 24 Aug 2021 18:09:34 GMT Server: - nginx/1.20.1 Transfer-Encoding: @@ -384,7 +637,183 @@ interactions: Content-Type: - application/json Date: - - Sat, 21 Aug 2021 19:42:51 GMT + - Tue, 24 Aug 2021 18:09:34 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/meal_plan_sections?query%5B%5D=id%3D-1 + response: + body: + string: !!binary | + H4sIAAAAAAAEAyXKwQqAIAwA0F+JnRWcXWS/EiGWO3hQYy46RP9e0Pm95YaSgSwaaKkyEICB0UVj + O+vG8pP0K+7CSTlHLZWHpnp81zuP1gXr58kFwpkwwLO+Gg7z9FQAAAA= + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Tue, 24 Aug 2021 18:09:35 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/meal_plan_sections?query%5B%5D=id%3D-1 + response: + body: + string: !!binary | + H4sIAAAAAAAEAyXKwQqAIAwA0F+JnRWcXWS/EiGWO3hQYy46RP9e0Pm95YaSgSwaaKkyEICB0UVj + O+vG8pP0K+7CSTlHLZWHpnp81zuP1gXr58kFwpkwwLO+Gg7z9FQAAAA= + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Tue, 24 Aug 2021 18:09:35 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/recipes/2 + response: + body: + string: !!binary | + H4sIAAAAAAAEA7WVTW/bMAyG/wqh0wY4aZKuA+Z5BnbfrdcAhiyxjhp9TaIyBMP++yi3KNIOWIHO + OzgHiXzIvKZf/hRGi3bXCC8dilbcRjkdkMjAGGyYPGYUjdCYVTKRTPAc0x22/beQ0IGJubhuf8UH + Xbw8g27sNQMSZEMcMPbAfGpABZ+RkArfSM35yvgJ0BpKDWTUoI104IMv7gxokgsaCF1kkvEno4sn + KARWjtwAIMFcBcHJyUuQ1nwvZwZgklzsiXcKtkQqcg1fCU6YAmDINVsqVXKNJ7gvmQLowk9tHOd7 + lJBwLG4Nt9w0KO5TwlFmDVMZMU0JfcPdciUJJI/GSb7P0isqnJ8JLnR64FZBZi3Wf7l7plOXo/SQ + 6Wzxy16MUh2nFIrXK1X7bCFN47vdzU0D88/m/ee96F9qy6+gUvoLTf6bxlwr9l2xfWdN/1a9GcLZ + lbC88I/s/VXtcZlZ3qe9f6n527SupKVmurL+fa4rZaHZrqg/fGDR+Z7/8tN3/9YZn/tcxEsqaSk/ + qaxXPGX+9tiwU/gxqISSUA9kHGdJF9m6d5vddrXZrbbXsP3Ufti21x85Ohr2q4TDnbE4PC4CtouH + RbC+jxPHjDLjkDGd2K+zaLfzUjCJ+c8OfaBBHVAdh3wIMXKwNZlEu2kEnWPdMD4kJ22tmoIuioa6 + gHyxthGFUXcGreYC9eTXb5+DW9eeBgAA + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Tue, 24 Aug 2021 18:09:35 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/meal_plan_sections?query%5B%5D=id%3D1 + response: + body: + string: !!binary | + H4sIAAAAAAAEAw3LwQpAQBAG4FfRf15lh8IcvYa0LUZJi3ZHDvLunL++/sE6g63B7oOA0UXx2+KT + wiAdUd1+hVEiuDSIx+2m31Vmp2uQpD6c/6GCbF40OVWZrblqmQjv8AEGfHFxWwAAAA== + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Tue, 24 Aug 2021 18:09:35 GMT Server: - nginx/1.20.1 Transfer-Encoding: diff --git a/test/cassettes/test_meal_plan/TestMealPlan.test_get_meal_plan_with_note.yaml b/test/cassettes/test_meal_plan/TestMealPlan.test_get_meal_plan_with_note.yaml new file mode 100644 index 0000000..c2c9d19 --- /dev/null +++ b/test/cassettes/test_meal_plan/TestMealPlan.test_get_meal_plan_with_note.yaml @@ -0,0 +1,48 @@ +interactions: +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/meal_plan + response: + body: + string: !!binary | + H4sIAAAAAAAEA9WW22qEMBCGX0VyrZCJutU8R+9KEdG0DayJ1bjLUvruHQ9ss5ttCoXSBrwIw/yT + +cgcfHgjsiUcYtLWJ8IJowwSyhJakJiYUy/QNohG4iHeDtUmWM3VKIaDVM/jEkRpgwo17fcx6Qfd + To1Z3C8tdacnZQinn06vk+U36GPVDKI2oq2M7MRo6q63koM0gpJnwNMdZtVqhXdirFE0Rmq1BErg + PV7RmINW+tFQEAhaeo0G1I+GgkDQMgcN/GgoCAQtd9CYHw2bMxC0nYOW+tHC6bU7By3zo4VTkMU1 + GrUm5DLRzwU4j/51ln9dkeT+RY4RfnW0if/JJigvOYuEfdN4f1idmFwWQcEp8HzuoZtL7rzjALef + vb9RbTXeD57Q6KcJb/2th8P88ghmNL78aNykwxX++AEo0x9inwgAAA== + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 11:53:54 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +version: 1 diff --git a/test/cassettes/test_meal_plan/TestMealPlan.test_get_meal_plan_with_note_and_details.yaml b/test/cassettes/test_meal_plan/TestMealPlan.test_get_meal_plan_with_note_and_details.yaml new file mode 100644 index 0000000..6f05396 --- /dev/null +++ b/test/cassettes/test_meal_plan/TestMealPlan.test_get_meal_plan_with_note_and_details.yaml @@ -0,0 +1,868 @@ +interactions: +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/meal_plan + response: + body: + string: !!binary | + H4sIAAAAAAAEA9WW22qEMBCGX0VyrZCJutU8R+9KEdG0DayJ1bjLUvruHQ9ss5ttCoXSBrwIw/yT + +cgcfHgjsiUcYtLWJ8IJowwSyhJakJiYUy/QNohG4iHeDtUmWM3VKIaDVM/jEkRpgwo17fcx6Qfd + To1Z3C8tdacnZQinn06vk+U36GPVDKI2oq2M7MRo6q63koM0gpJnwNMdZtVqhXdirFE0Rmq1BErg + PV7RmINW+tFQEAhaeo0G1I+GgkDQMgcN/GgoCAQtd9CYHw2bMxC0nYOW+tHC6bU7By3zo4VTkMU1 + GrUm5DLRzwU4j/51ln9dkeT+RY4RfnW0if/JJigvOYuEfdN4f1idmFwWQcEp8HzuoZtL7rzjALef + vb9RbTXeD57Q6KcJb/2th8P88ghmNL78aNykwxX++AEo0x9inwgAAA== + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 11:55:40 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/recipes/1 + response: + body: + string: !!binary | + H4sIAAAAAAAEA7WVTW/TQBCG/8rIJ5CcNE4pEsZY4s4Biasla7w7dbbZL/YjKEX8d2ZNVbVFAimY + g3OY2Xlm8nr87vdKyapt6sqioaqtPqv7e6zqSlIUQfmknOVod2j6Ty6QAeVjNt1wxYHOP41BN/XS + aRcgqsQHph6YmGoQzkZKlDJnUHK9UHYG0iqFGiJJkAoNWGezOQOpYJyERMYzSdmTktkmyAk0TjwA + UIKlC4HB2SKgVl/zmQEUkJs98k5OZ58ybuFjghMFB+RiqUYhciznE9zlmBzIzE8ZnJY8IQSastnC + Fx4aBM+JcMQoYc4ThTmQrXla7oSQ8KgMcj6iFSlzfUzwRKdf3CLIosX2D7lnOnXRo4WYzpo+DNWE + 4jgHl63ciDJnC2GeXu1vbmpYfnav3w9V/1JbfgWF0j/R5L9pzL1832Xdd1r1l+rNEK4uhPWFf2AP + V2XGdXZ5CIN9qfllWhfSWjtdWP++14Wy0m4X1G8+sOp+L3/58bu/dMeXOVfxkkJay08K6y+esnx7 + bNjBfRtFIEwkx6QMV6HxbN373b7Z7Pab5hqad+2bpr1+y6e9Yr8KNN4qTeOD9fti/ds7P3N+wkhj + pHBir47L/cAXggrMfha0Lo3iQOI4xoPzng9rFVPV7uoqnX25T6wLBnXpGJzMIo3lurFZ67rKjLpV + pCU3KJEfPwFRig1KjAYAAA== + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 11:55:40 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/meal_plan_sections?query%5B%5D=id%3D-1 + response: + body: + string: !!binary | + H4sIAAAAAAAEAyXKwQqAIAwA0F+JnRWcXWS/EiGWO3hQYy46RP9e0Pm95YaSgSwaaKkyEICB0UVj + O+vG8pP0K+7CSTlHLZWHpnp81zuP1gXr58kFwpkwwLO+Gg7z9FQAAAA= + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 11:55:40 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/recipes/2 + response: + body: + string: !!binary | + H4sIAAAAAAAEA7WVTW/bMAyG/wqh0wY4aZKuA+Z5BnbfrdcAhiyxjhp9TaIyBMP++yi3KNIOWIHO + OzgHiXzIvKZf/hRGi3bXCC8dilbcRjkdkMjAGGyYPGYUjdCYVTKRTPAc0x22/beQ0IGJubhuf8UH + Xbw8g27sNQMSZEMcMPbAfGpABZ+RkArfSM35yvgJ0BpKDWTUoI104IMv7gxokgsaCF1kkvEno4sn + KARWjtwAIMFcBcHJyUuQ1nwvZwZgklzsiXcKtkQqcg1fCU6YAmDINVsqVXKNJ7gvmQLowk9tHOd7 + lJBwLG4Nt9w0KO5TwlFmDVMZMU0JfcPdciUJJI/GSb7P0isqnJ8JLnR64FZBZi3Wf7l7plOXo/SQ + 6Wzxy16MUh2nFIrXK1X7bCFN47vdzU0D88/m/ee96F9qy6+gUvoLTf6bxlwr9l2xfWdN/1a9GcLZ + lbC88I/s/VXtcZlZ3qe9f6n527SupKVmurL+fa4rZaHZrqg/fGDR+Z7/8tN3/9YZn/tcxEsqaSk/ + qaxXPGX+9tiwU/gxqISSUA9kHGdJF9m6d5vddrXZrbbXsP3Ufti21x85Ohr2q4TDnbE4PC4CtouH + RbC+jxPHjDLjkDGd2K+zaLfzUjCJ+c8OfaBBHVAdh3wIMXKwNZlEu2kEnWPdMD4kJ22tmoIuioa6 + gHyxthGFUXcGreYC9eTXb5+DW9eeBgAA + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 11:55:40 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/meal_plan_sections?query%5B%5D=id%3D-1 + response: + body: + string: !!binary | + H4sIAAAAAAAEAyXKwQqAIAwA0F+JnRWcXWS/EiGWO3hQYy46RP9e0Pm95YaSgSwaaKkyEICB0UVj + O+vG8pP0K+7CSTlHLZWHpnp81zuP1gXr58kFwpkwwLO+Gg7z9FQAAAA= + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 11:55:40 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/recipes/3 + response: + body: + string: !!binary | + H4sIAAAAAAAEA7VVTWvcQAz9K2JOLXg3+9EU6rqG3nvLdcHIM4p3svPV+diwlP73atwQkhQaSN2D + fRhJT8/PmqcfQivR7hvh0JJoxQ06da/lkZJohKIkow5Ze8eh7rjtv/lIFnRIxXaHKz7owtMz6MZe + eeMjJJ05YeyBYXMD0rtEmXLhCCqul9pNQEbn2EAiBUqjBeddsRcgHa1XkMkGRtLurFVxGUoGgyMT + AMowdyGwODkENPp7uTAAReRmj3hnb0rIBdfwNcOZogfyqVajlCXV/Ax3JWUPqvBTidMcJ4RIY7Fr + uGHSIJknwgmTgqmMFKdIrmG23Akh40lb5HhCJ3Ph+pThiU6/casgsxbrv8Se6dSlgA5Svhj6chAj + ytMUfXFqJSvPFuI0vttdXzcwvzbvPx9E/1Jb/gUVpX+iyX/TmHuFvium74zu36o3g3B1RVhe+Afs + w1XluMwsH+LBvdT8bVpXpKVmumL9+1xXlIVmu0L94QOLzvf8yY/3/q0zPvNcxEsq0lJ+UrFe8ZT5 + 7rFhR38/yEiYSQ1ZW65CG9i6d5vddrXZrbZ72H5qP2zb/UfODpr9KtJwqw0ND/7PJvbg/+u7MHHS + iImGRPHMhp1Eu523go7c4Nmh83ngrSFPQzr6EDjZ6JRFu2lEvoS6WZyPFk1tG70qMg918bhiTCMK + Q91qMoob1JOfvwBbCM5klgYAAA== + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 11:55:40 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/meal_plan_sections?query%5B%5D=id%3D-1 + response: + body: + string: !!binary | + H4sIAAAAAAAEAyXKwQqAIAwA0F+JnRWcXWS/EiGWO3hQYy46RP9e0Pm95YaSgSwaaKkyEICB0UVj + O+vG8pP0K+7CSTlHLZWHpnp81zuP1gXr58kFwpkwwLO+Gg7z9FQAAAA= + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 11:55:40 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/recipes/4 + response: + body: + string: !!binary | + H4sIAAAAAAAEA7WVTW/bMAyG/wqh0wY4aZK2A+Z5BnbfYcCuAQxZYh01+ppEZQiG/fdRXlGkHdAB + nXdwDiL5kHlNv/ohjBbtTSO8dCha8UV6JY+YRSM0ZpVMJBM8B7rDtv8cEjowMRfX7a/4oIuXZ9CN + vQ42JMiGOGHsgaHUgAo+IyEVjkjN9cr4CdAaSg1k1KCNdOCDL+4MaJILGghdZJLxJ6OLJygEVo48 + ACDB3AXByclLkNZ8K2cGYJLc7JF3CrZEKnINnwhOmAJgyLVaKlVyzSe4L5kC6MJPHRznOEpIOBa3 + hq88NCieU8JRZg1TGTFNCX3D03InCSSPxkmOZxaOCtdnggudfnOrILMW6xdiT3TqcpQeMp0tftyL + UarjlELxeqXqnC2kaXyzu71tYP7ZvP2wF/1zbfkVVEp/ocl/05h7xb4rtu+s6V+rN0O4uhKWF/6B + vb+qMy6zy/u09881f53WlbTUTlfWv+91pSy02xX1hw8sut/zX3787l+74/Oci3hJJS3lJ5X1F0+Z + vz027BS+DyqhJNQDGcdV0kW27t1mt11tdqvtNWzftzfb9vodZ0fDfpVwuDMWhwf3Z7eY3X99HydO + GWXGIWM6sV1n0W7nO8Ekxj859IEGdUB1HPIhxMjJ1mQS7aYRdI71VvEhOWlr0xR0UTTUS8cXaxtR + GHVn0GpuUE9+/gJlZaYokgYAAA== + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 11:55:41 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/meal_plan_sections?query%5B%5D=id%3D-1 + response: + body: + string: !!binary | + H4sIAAAAAAAEAyXKwQqAIAwA0F+JnRWcXWS/EiGWO3hQYy46RP9e0Pm95YaSgSwaaKkyEICB0UVj + O+vG8pP0K+7CSTlHLZWHpnp81zuP1gXr58kFwpkwwLO+Gg7z9FQAAAA= + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 11:55:41 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/recipes/1 + response: + body: + string: !!binary | + H4sIAAAAAAAEA7WVTW/TQBCG/8rIJ5CcNE4pEsZY4s4Biasla7w7dbbZL/YjKEX8d2ZNVbVFAimY + g3OY2Xlm8nr87vdKyapt6sqioaqtPqv7e6zqSlIUQfmknOVod2j6Ty6QAeVjNt1wxYHOP41BN/XS + aRcgqsQHph6YmGoQzkZKlDJnUHK9UHYG0iqFGiJJkAoNWGezOQOpYJyERMYzSdmTktkmyAk0TjwA + UIKlC4HB2SKgVl/zmQEUkJs98k5OZ58ybuFjghMFB+RiqUYhciznE9zlmBzIzE8ZnJY8IQSastnC + Fx4aBM+JcMQoYc4ThTmQrXla7oSQ8KgMcj6iFSlzfUzwRKdf3CLIosX2D7lnOnXRo4WYzpo+DNWE + 4jgHl63ciDJnC2GeXu1vbmpYfnav3w9V/1JbfgWF0j/R5L9pzL1832Xdd1r1l+rNEK4uhPWFf2AP + V2XGdXZ5CIN9qfllWhfSWjtdWP++14Wy0m4X1G8+sOp+L3/58bu/dMeXOVfxkkJay08K6y+esnx7 + bNjBfRtFIEwkx6QMV6HxbN373b7Z7Pab5hqad+2bpr1+y6e9Yr8KNN4qTeOD9fti/ds7P3N+wkhj + pHBir47L/cAXggrMfha0Lo3iQOI4xoPzng9rFVPV7uoqnX25T6wLBnXpGJzMIo3lurFZ67rKjLpV + pCU3KJEfPwFRig1KjAYAAA== + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 11:55:41 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/meal_plan_sections?query%5B%5D=id%3D-1 + response: + body: + string: !!binary | + H4sIAAAAAAAEAyXKwQqAIAwA0F+JnRWcXWS/EiGWO3hQYy46RP9e0Pm95YaSgSwaaKkyEICB0UVj + O+vG8pP0K+7CSTlHLZWHpnp81zuP1gXr58kFwpkwwLO+Gg7z9FQAAAA= + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 11:55:41 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/recipes/2 + response: + body: + string: !!binary | + H4sIAAAAAAAEA7WVTW/bMAyG/wqh0wY4aZKuA+Z5BnbfrdcAhiyxjhp9TaIyBMP++yi3KNIOWIHO + OzgHiXzIvKZf/hRGi3bXCC8dilbcRjkdkMjAGGyYPGYUjdCYVTKRTPAc0x22/beQ0IGJubhuf8UH + Xbw8g27sNQMSZEMcMPbAfGpABZ+RkArfSM35yvgJ0BpKDWTUoI104IMv7gxokgsaCF1kkvEno4sn + KARWjtwAIMFcBcHJyUuQ1nwvZwZgklzsiXcKtkQqcg1fCU6YAmDINVsqVXKNJ7gvmQLowk9tHOd7 + lJBwLG4Nt9w0KO5TwlFmDVMZMU0JfcPdciUJJI/GSb7P0isqnJ8JLnR64FZBZi3Wf7l7plOXo/SQ + 6Wzxy16MUh2nFIrXK1X7bCFN47vdzU0D88/m/ee96F9qy6+gUvoLTf6bxlwr9l2xfWdN/1a9GcLZ + lbC88I/s/VXtcZlZ3qe9f6n527SupKVmurL+fa4rZaHZrqg/fGDR+Z7/8tN3/9YZn/tcxEsqaSk/ + qaxXPGX+9tiwU/gxqISSUA9kHGdJF9m6d5vddrXZrbbXsP3Ufti21x85Ohr2q4TDnbE4PC4CtouH + RbC+jxPHjDLjkDGd2K+zaLfzUjCJ+c8OfaBBHVAdh3wIMXKwNZlEu2kEnWPdMD4kJ22tmoIuioa6 + gHyxthGFUXcGreYC9eTXb5+DW9eeBgAA + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 11:55:41 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/meal_plan_sections?query%5B%5D=id%3D-1 + response: + body: + string: !!binary | + H4sIAAAAAAAEAyXKwQqAIAwA0F+JnRWcXWS/EiGWO3hQYy46RP9e0Pm95YaSgSwaaKkyEICB0UVj + O+vG8pP0K+7CSTlHLZWHpnp81zuP1gXr58kFwpkwwLO+Gg7z9FQAAAA= + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 11:55:41 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/recipes/4 + response: + body: + string: !!binary | + H4sIAAAAAAAEA7WVTW/bMAyG/wqh0wY4aZK2A+Z5BnbfYcCuAQxZYh01+ppEZQiG/fdRXlGkHdAB + nXdwDiL5kHlNv/ohjBbtTSO8dCha8UV6JY+YRSM0ZpVMJBM8B7rDtv8cEjowMRfX7a/4oIuXZ9CN + vQ42JMiGOGHsgaHUgAo+IyEVjkjN9cr4CdAaSg1k1KCNdOCDL+4MaJILGghdZJLxJ6OLJygEVo48 + ACDB3AXByclLkNZ8K2cGYJLc7JF3CrZEKnINnwhOmAJgyLVaKlVyzSe4L5kC6MJPHRznOEpIOBa3 + hq88NCieU8JRZg1TGTFNCX3D03InCSSPxkmOZxaOCtdnggudfnOrILMW6xdiT3TqcpQeMp0tftyL + UarjlELxeqXqnC2kaXyzu71tYP7ZvP2wF/1zbfkVVEp/ocl/05h7xb4rtu+s6V+rN0O4uhKWF/6B + vb+qMy6zy/u09881f53WlbTUTlfWv+91pSy02xX1hw8sut/zX3787l+74/Oci3hJJS3lJ5X1F0+Z + vz027BS+DyqhJNQDGcdV0kW27t1mt11tdqvtNWzftzfb9vodZ0fDfpVwuDMWhwf3Z7eY3X99HydO + GWXGIWM6sV1n0W7nO8Ekxj859IEGdUB1HPIhxMjJ1mQS7aYRdI71VvEhOWlr0xR0UTTUS8cXaxtR + GHVn0GpuUE9+/gJlZaYokgYAAA== + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 11:55:41 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/meal_plan_sections?query%5B%5D=id%3D-1 + response: + body: + string: !!binary | + H4sIAAAAAAAEAyXKwQqAIAwA0F+JnRWcXWS/EiGWO3hQYy46RP9e0Pm95YaSgSwaaKkyEICB0UVj + O+vG8pP0K+7CSTlHLZWHpnp81zuP1gXr58kFwpkwwLO+Gg7z9FQAAAA= + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 11:55:41 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/meal_plan_sections?query%5B%5D=id%3D-1 + response: + body: + string: !!binary | + H4sIAAAAAAAEAyXKwQqAIAwA0F+JnRWcXWS/EiGWO3hQYy46RP9e0Pm95YaSgSwaaKkyEICB0UVj + O+vG8pP0K+7CSTlHLZWHpnp81zuP1gXr58kFwpkwwLO+Gg7z9FQAAAA= + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 11:55:41 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/recipes/2 + response: + body: + string: !!binary | + H4sIAAAAAAAEA7WVTW/bMAyG/wqh0wY4aZKuA+Z5BnbfrdcAhiyxjhp9TaIyBMP++yi3KNIOWIHO + OzgHiXzIvKZf/hRGi3bXCC8dilbcRjkdkMjAGGyYPGYUjdCYVTKRTPAc0x22/beQ0IGJubhuf8UH + Xbw8g27sNQMSZEMcMPbAfGpABZ+RkArfSM35yvgJ0BpKDWTUoI104IMv7gxokgsaCF1kkvEno4sn + KARWjtwAIMFcBcHJyUuQ1nwvZwZgklzsiXcKtkQqcg1fCU6YAmDINVsqVXKNJ7gvmQLowk9tHOd7 + lJBwLG4Nt9w0KO5TwlFmDVMZMU0JfcPdciUJJI/GSb7P0isqnJ8JLnR64FZBZi3Wf7l7plOXo/SQ + 6Wzxy16MUh2nFIrXK1X7bCFN47vdzU0D88/m/ee96F9qy6+gUvoLTf6bxlwr9l2xfWdN/1a9GcLZ + lbC88I/s/VXtcZlZ3qe9f6n527SupKVmurL+fa4rZaHZrqg/fGDR+Z7/8tN3/9YZn/tcxEsqaSk/ + qaxXPGX+9tiwU/gxqISSUA9kHGdJF9m6d5vddrXZrbbXsP3Ufti21x85Ohr2q4TDnbE4PC4CtouH + RbC+jxPHjDLjkDGd2K+zaLfzUjCJ+c8OfaBBHVAdh3wIMXKwNZlEu2kEnWPdMD4kJ22tmoIuioa6 + gHyxthGFUXcGreYC9eTXb5+DW9eeBgAA + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 11:55:41 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/meal_plan_sections?query%5B%5D=id%3D1 + response: + body: + string: !!binary | + H4sIAAAAAAAEAw3LwQpAQBAG4FfRf15lh8IcvYa0LUZJi3ZHDvLunL++/sE6g63B7oOA0UXx2+KT + wiAdUd1+hVEiuDSIx+2m31Vmp2uQpD6c/6GCbF40OVWZrblqmQjv8AEGfHFxWwAAAA== + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 11:55:42 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/meal_plan_sections?query%5B%5D=id%3D-1 + response: + body: + string: !!binary | + H4sIAAAAAAAEAyXKwQqAIAwA0F+JnRWcXWS/EiGWO3hQYy46RP9e0Pm95YaSgSwaaKkyEICB0UVj + O+vG8pP0K+7CSTlHLZWHpnp81zuP1gXr58kFwpkwwLO+Gg7z9FQAAAA= + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 11:55:42 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +version: 1 diff --git a/test/cassettes/test_meal_plan/TestMealPlan.test_get_meal_plan_with_product.yaml b/test/cassettes/test_meal_plan/TestMealPlan.test_get_meal_plan_with_product.yaml new file mode 100644 index 0000000..7101807 --- /dev/null +++ b/test/cassettes/test_meal_plan/TestMealPlan.test_get_meal_plan_with_product.yaml @@ -0,0 +1,911 @@ +interactions: +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/meal_plan + response: + body: + string: !!binary | + H4sIAAAAAAAEA9WW22qEMBCGX0VyrZDxVM1z9K4UEU1bYTVWY8tS9t078XzYpqVQugEvwpBJ5jMz + 88/DBylywsAmeXomjLjUBYe6Do2ITeS55mhreFbgwh4XyegwmJOWN29F9dz2h1RCokfVnU42qRuR + d5nst28taSm6ShJGl02v3WpfI96TrOGp5Hkii5K3Mi3rVXDgWRAzH5gXYlS5qPBOPKvlmSxE1R/k + wMUe0NwDWqxHQwdD0Lw9GlA9GjoYguYf0ECPhg6GoAUHNFePhsVpCFp4QPP0aObU2t0BzdejmZOQ + 0R6Nrjpk39HnBFStf+jlX2ckuX8pWgu/1Bqdb0QJ4i1n5LjfFN4/ZicG51sQMQosUDV0VeRmjQNU + v7V+o/eq8H7xhFI8dXjrXz0cxhdYoNBYP2hcpVskHHbjifo5S/GNQaJhzMmfJOl2IFEeWK8T7jSf + 4LWTaZxPlIBqh5OZLGSgFOsqGVwePwG8geHkeAkAAA== + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 12:05:21 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/recipes/1 + response: + body: + string: !!binary | + H4sIAAAAAAAEA7WVTW/TQBCG/8rIJ5CcNE4pEsZY4s4Biasla7w7dbbZL/YjKEX8d2ZNVbVFAimY + g3OY2Xlm8nr87vdKyapt6sqioaqtPqv7e6zqSlIUQfmknOVod2j6Ty6QAeVjNt1wxYHOP41BN/XS + aRcgqsQHph6YmGoQzkZKlDJnUHK9UHYG0iqFGiJJkAoNWGezOQOpYJyERMYzSdmTktkmyAk0TjwA + UIKlC4HB2SKgVl/zmQEUkJs98k5OZ58ybuFjghMFB+RiqUYhciznE9zlmBzIzE8ZnJY8IQSastnC + Fx4aBM+JcMQoYc4ThTmQrXla7oSQ8KgMcj6iFSlzfUzwRKdf3CLIosX2D7lnOnXRo4WYzpo+DNWE + 4jgHl63ciDJnC2GeXu1vbmpYfnav3w9V/1JbfgWF0j/R5L9pzL1832Xdd1r1l+rNEK4uhPWFf2AP + V2XGdXZ5CIN9qfllWhfSWjtdWP++14Wy0m4X1G8+sOp+L3/58bu/dMeXOVfxkkJay08K6y+esnx7 + bNjBfRtFIEwkx6QMV6HxbN373b7Z7Pab5hqad+2bpr1+y6e9Yr8KNN4qTeOD9fti/ds7P3N+wkhj + pHBir47L/cAXggrMfha0Lo3iQOI4xoPzng9rFVPV7uoqnX25T6wLBnXpGJzMIo3lurFZ67rKjLpV + pCU3KJEfPwFRig1KjAYAAA== + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 12:05:21 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/meal_plan_sections?query%5B%5D=id%3D-1 + response: + body: + string: !!binary | + H4sIAAAAAAAEAyXKwQqAIAwA0F+JnRWcXWS/EiGWO3hQYy46RP9e0Pm95YaSgSwaaKkyEICB0UVj + O+vG8pP0K+7CSTlHLZWHpnp81zuP1gXr58kFwpkwwLO+Gg7z9FQAAAA= + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 12:05:21 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/recipes/2 + response: + body: + string: !!binary | + H4sIAAAAAAAEA7WVTW/bMAyG/wqh0wY4aZKuA+Z5BnbfrdcAhiyxjhp9TaIyBMP++yi3KNIOWIHO + OzgHiXzIvKZf/hRGi3bXCC8dilbcRjkdkMjAGGyYPGYUjdCYVTKRTPAc0x22/beQ0IGJubhuf8UH + Xbw8g27sNQMSZEMcMPbAfGpABZ+RkArfSM35yvgJ0BpKDWTUoI104IMv7gxokgsaCF1kkvEno4sn + KARWjtwAIMFcBcHJyUuQ1nwvZwZgklzsiXcKtkQqcg1fCU6YAmDINVsqVXKNJ7gvmQLowk9tHOd7 + lJBwLG4Nt9w0KO5TwlFmDVMZMU0JfcPdciUJJI/GSb7P0isqnJ8JLnR64FZBZi3Wf7l7plOXo/SQ + 6Wzxy16MUh2nFIrXK1X7bCFN47vdzU0D88/m/ee96F9qy6+gUvoLTf6bxlwr9l2xfWdN/1a9GcLZ + lbC88I/s/VXtcZlZ3qe9f6n527SupKVmurL+fa4rZaHZrqg/fGDR+Z7/8tN3/9YZn/tcxEsqaSk/ + qaxXPGX+9tiwU/gxqISSUA9kHGdJF9m6d5vddrXZrbbXsP3Ufti21x85Ohr2q4TDnbE4PC4CtouH + RbC+jxPHjDLjkDGd2K+zaLfzUjCJ+c8OfaBBHVAdh3wIMXKwNZlEu2kEnWPdMD4kJ22tmoIuioa6 + gHyxthGFUXcGreYC9eTXb5+DW9eeBgAA + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 12:05:21 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/meal_plan_sections?query%5B%5D=id%3D-1 + response: + body: + string: !!binary | + H4sIAAAAAAAEAyXKwQqAIAwA0F+JnRWcXWS/EiGWO3hQYy46RP9e0Pm95YaSgSwaaKkyEICB0UVj + O+vG8pP0K+7CSTlHLZWHpnp81zuP1gXr58kFwpkwwLO+Gg7z9FQAAAA= + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 12:05:21 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/recipes/3 + response: + body: + string: !!binary | + H4sIAAAAAAAEA7VVTWvcQAz9K2JOLXg3+9EU6rqG3nvLdcHIM4p3svPV+diwlP73atwQkhQaSN2D + fRhJT8/PmqcfQivR7hvh0JJoxQ06da/lkZJohKIkow5Ze8eh7rjtv/lIFnRIxXaHKz7owtMz6MZe + eeMjJJ05YeyBYXMD0rtEmXLhCCqul9pNQEbn2EAiBUqjBeddsRcgHa1XkMkGRtLurFVxGUoGgyMT + AMowdyGwODkENPp7uTAAReRmj3hnb0rIBdfwNcOZogfyqVajlCXV/Ax3JWUPqvBTidMcJ4RIY7Fr + uGHSIJknwgmTgqmMFKdIrmG23Akh40lb5HhCJ3Ph+pThiU6/casgsxbrv8Se6dSlgA5Svhj6chAj + ytMUfXFqJSvPFuI0vttdXzcwvzbvPx9E/1Jb/gUVpX+iyX/TmHuFvium74zu36o3g3B1RVhe+Afs + w1XluMwsH+LBvdT8bVpXpKVmumL9+1xXlIVmu0L94QOLzvf8yY/3/q0zPvNcxEsq0lJ+UrFe8ZT5 + 7rFhR38/yEiYSQ1ZW65CG9i6d5vddrXZrbZ72H5qP2zb/UfODpr9KtJwqw0ND/7PJvbg/+u7MHHS + iImGRPHMhp1Eu523go7c4Nmh83ngrSFPQzr6EDjZ6JRFu2lEvoS6WZyPFk1tG70qMg918bhiTCMK + Q91qMoob1JOfvwBbCM5klgYAAA== + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 12:05:21 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/meal_plan_sections?query%5B%5D=id%3D-1 + response: + body: + string: !!binary | + H4sIAAAAAAAEAyXKwQqAIAwA0F+JnRWcXWS/EiGWO3hQYy46RP9e0Pm95YaSgSwaaKkyEICB0UVj + O+vG8pP0K+7CSTlHLZWHpnp81zuP1gXr58kFwpkwwLO+Gg7z9FQAAAA= + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 12:05:22 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/recipes/4 + response: + body: + string: !!binary | + H4sIAAAAAAAEA7WVTW/bMAyG/wqh0wY4aZK2A+Z5BnbfYcCuAQxZYh01+ppEZQiG/fdRXlGkHdAB + nXdwDiL5kHlNv/ohjBbtTSO8dCha8UV6JY+YRSM0ZpVMJBM8B7rDtv8cEjowMRfX7a/4oIuXZ9CN + vQ42JMiGOGHsgaHUgAo+IyEVjkjN9cr4CdAaSg1k1KCNdOCDL+4MaJILGghdZJLxJ6OLJygEVo48 + ACDB3AXByclLkNZ8K2cGYJLc7JF3CrZEKnINnwhOmAJgyLVaKlVyzSe4L5kC6MJPHRznOEpIOBa3 + hq88NCieU8JRZg1TGTFNCX3D03InCSSPxkmOZxaOCtdnggudfnOrILMW6xdiT3TqcpQeMp0tftyL + UarjlELxeqXqnC2kaXyzu71tYP7ZvP2wF/1zbfkVVEp/ocl/05h7xb4rtu+s6V+rN0O4uhKWF/6B + vb+qMy6zy/u09881f53WlbTUTlfWv+91pSy02xX1hw8sut/zX3787l+74/Oci3hJJS3lJ5X1F0+Z + vz027BS+DyqhJNQDGcdV0kW27t1mt11tdqvtNWzftzfb9vodZ0fDfpVwuDMWhwf3Z7eY3X99HydO + GWXGIWM6sV1n0W7nO8Ekxj859IEGdUB1HPIhxMjJ1mQS7aYRdI71VvEhOWlr0xR0UTTUS8cXaxtR + GHVn0GpuUE9+/gJlZaYokgYAAA== + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 12:05:22 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/meal_plan_sections?query%5B%5D=id%3D-1 + response: + body: + string: !!binary | + H4sIAAAAAAAEAyXKwQqAIAwA0F+JnRWcXWS/EiGWO3hQYy46RP9e0Pm95YaSgSwaaKkyEICB0UVj + O+vG8pP0K+7CSTlHLZWHpnp81zuP1gXr58kFwpkwwLO+Gg7z9FQAAAA= + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 12:05:22 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/recipes/1 + response: + body: + string: !!binary | + H4sIAAAAAAAEA7WVTW/TQBCG/8rIJ5CcNE4pEsZY4s4Biasla7w7dbbZL/YjKEX8d2ZNVbVFAimY + g3OY2Xlm8nr87vdKyapt6sqioaqtPqv7e6zqSlIUQfmknOVod2j6Ty6QAeVjNt1wxYHOP41BN/XS + aRcgqsQHph6YmGoQzkZKlDJnUHK9UHYG0iqFGiJJkAoNWGezOQOpYJyERMYzSdmTktkmyAk0TjwA + UIKlC4HB2SKgVl/zmQEUkJs98k5OZ58ybuFjghMFB+RiqUYhciznE9zlmBzIzE8ZnJY8IQSastnC + Fx4aBM+JcMQoYc4ThTmQrXla7oSQ8KgMcj6iFSlzfUzwRKdf3CLIosX2D7lnOnXRo4WYzpo+DNWE + 4jgHl63ciDJnC2GeXu1vbmpYfnav3w9V/1JbfgWF0j/R5L9pzL1832Xdd1r1l+rNEK4uhPWFf2AP + V2XGdXZ5CIN9qfllWhfSWjtdWP++14Wy0m4X1G8+sOp+L3/58bu/dMeXOVfxkkJay08K6y+esnx7 + bNjBfRtFIEwkx6QMV6HxbN373b7Z7Pab5hqad+2bpr1+y6e9Yr8KNN4qTeOD9fti/ds7P3N+wkhj + pHBir47L/cAXggrMfha0Lo3iQOI4xoPzng9rFVPV7uoqnX25T6wLBnXpGJzMIo3lurFZ67rKjLpV + pCU3KJEfPwFRig1KjAYAAA== + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 12:05:22 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/meal_plan_sections?query%5B%5D=id%3D-1 + response: + body: + string: !!binary | + H4sIAAAAAAAEAyXKwQqAIAwA0F+JnRWcXWS/EiGWO3hQYy46RP9e0Pm95YaSgSwaaKkyEICB0UVj + O+vG8pP0K+7CSTlHLZWHpnp81zuP1gXr58kFwpkwwLO+Gg7z9FQAAAA= + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 12:05:22 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/recipes/2 + response: + body: + string: !!binary | + H4sIAAAAAAAEA7WVTW/bMAyG/wqh0wY4aZKuA+Z5BnbfrdcAhiyxjhp9TaIyBMP++yi3KNIOWIHO + OzgHiXzIvKZf/hRGi3bXCC8dilbcRjkdkMjAGGyYPGYUjdCYVTKRTPAc0x22/beQ0IGJubhuf8UH + Xbw8g27sNQMSZEMcMPbAfGpABZ+RkArfSM35yvgJ0BpKDWTUoI104IMv7gxokgsaCF1kkvEno4sn + KARWjtwAIMFcBcHJyUuQ1nwvZwZgklzsiXcKtkQqcg1fCU6YAmDINVsqVXKNJ7gvmQLowk9tHOd7 + lJBwLG4Nt9w0KO5TwlFmDVMZMU0JfcPdciUJJI/GSb7P0isqnJ8JLnR64FZBZi3Wf7l7plOXo/SQ + 6Wzxy16MUh2nFIrXK1X7bCFN47vdzU0D88/m/ee96F9qy6+gUvoLTf6bxlwr9l2xfWdN/1a9GcLZ + lbC88I/s/VXtcZlZ3qe9f6n527SupKVmurL+fa4rZaHZrqg/fGDR+Z7/8tN3/9YZn/tcxEsqaSk/ + qaxXPGX+9tiwU/gxqISSUA9kHGdJF9m6d5vddrXZrbbXsP3Ufti21x85Ohr2q4TDnbE4PC4CtouH + RbC+jxPHjDLjkDGd2K+zaLfzUjCJ+c8OfaBBHVAdh3wIMXKwNZlEu2kEnWPdMD4kJ22tmoIuioa6 + gHyxthGFUXcGreYC9eTXb5+DW9eeBgAA + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 12:05:22 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/meal_plan_sections?query%5B%5D=id%3D-1 + response: + body: + string: !!binary | + H4sIAAAAAAAEAyXKwQqAIAwA0F+JnRWcXWS/EiGWO3hQYy46RP9e0Pm95YaSgSwaaKkyEICB0UVj + O+vG8pP0K+7CSTlHLZWHpnp81zuP1gXr58kFwpkwwLO+Gg7z9FQAAAA= + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 12:05:22 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/recipes/4 + response: + body: + string: !!binary | + H4sIAAAAAAAEA7WVTW/bMAyG/wqh0wY4aZK2A+Z5BnbfYcCuAQxZYh01+ppEZQiG/fdRXlGkHdAB + nXdwDiL5kHlNv/ohjBbtTSO8dCha8UV6JY+YRSM0ZpVMJBM8B7rDtv8cEjowMRfX7a/4oIuXZ9CN + vQ42JMiGOGHsgaHUgAo+IyEVjkjN9cr4CdAaSg1k1KCNdOCDL+4MaJILGghdZJLxJ6OLJygEVo48 + ACDB3AXByclLkNZ8K2cGYJLc7JF3CrZEKnINnwhOmAJgyLVaKlVyzSe4L5kC6MJPHRznOEpIOBa3 + hq88NCieU8JRZg1TGTFNCX3D03InCSSPxkmOZxaOCtdnggudfnOrILMW6xdiT3TqcpQeMp0tftyL + UarjlELxeqXqnC2kaXyzu71tYP7ZvP2wF/1zbfkVVEp/ocl/05h7xb4rtu+s6V+rN0O4uhKWF/6B + vb+qMy6zy/u09881f53WlbTUTlfWv+91pSy02xX1hw8sut/zX3787l+74/Oci3hJJS3lJ5X1F0+Z + vz027BS+DyqhJNQDGcdV0kW27t1mt11tdqvtNWzftzfb9vodZ0fDfpVwuDMWhwf3Z7eY3X99HydO + GWXGIWM6sV1n0W7nO8Ekxj859IEGdUB1HPIhxMjJ1mQS7aYRdI71VvEhOWlr0xR0UTTUS8cXaxtR + GHVn0GpuUE9+/gJlZaYokgYAAA== + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 12:05:22 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/meal_plan_sections?query%5B%5D=id%3D-1 + response: + body: + string: !!binary | + H4sIAAAAAAAEAyXKwQqAIAwA0F+JnRWcXWS/EiGWO3hQYy46RP9e0Pm95YaSgSwaaKkyEICB0UVj + O+vG8pP0K+7CSTlHLZWHpnp81zuP1gXr58kFwpkwwLO+Gg7z9FQAAAA= + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 12:05:22 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/meal_plan_sections?query%5B%5D=id%3D-1 + response: + body: + string: !!binary | + H4sIAAAAAAAEAyXKwQqAIAwA0F+JnRWcXWS/EiGWO3hQYy46RP9e0Pm95YaSgSwaaKkyEICB0UVj + O+vG8pP0K+7CSTlHLZWHpnp81zuP1gXr58kFwpkwwLO+Gg7z9FQAAAA= + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 12:05:22 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/recipes/2 + response: + body: + string: !!binary | + H4sIAAAAAAAEA7WVTW/bMAyG/wqh0wY4aZKuA+Z5BnbfrdcAhiyxjhp9TaIyBMP++yi3KNIOWIHO + OzgHiXzIvKZf/hRGi3bXCC8dilbcRjkdkMjAGGyYPGYUjdCYVTKRTPAc0x22/beQ0IGJubhuf8UH + Xbw8g27sNQMSZEMcMPbAfGpABZ+RkArfSM35yvgJ0BpKDWTUoI104IMv7gxokgsaCF1kkvEno4sn + KARWjtwAIMFcBcHJyUuQ1nwvZwZgklzsiXcKtkQqcg1fCU6YAmDINVsqVXKNJ7gvmQLowk9tHOd7 + lJBwLG4Nt9w0KO5TwlFmDVMZMU0JfcPdciUJJI/GSb7P0isqnJ8JLnR64FZBZi3Wf7l7plOXo/SQ + 6Wzxy16MUh2nFIrXK1X7bCFN47vdzU0D88/m/ee96F9qy6+gUvoLTf6bxlwr9l2xfWdN/1a9GcLZ + lbC88I/s/VXtcZlZ3qe9f6n527SupKVmurL+fa4rZaHZrqg/fGDR+Z7/8tN3/9YZn/tcxEsqaSk/ + qaxXPGX+9tiwU/gxqISSUA9kHGdJF9m6d5vddrXZrbbXsP3Ufti21x85Ohr2q4TDnbE4PC4CtouH + RbC+jxPHjDLjkDGd2K+zaLfzUjCJ+c8OfaBBHVAdh3wIMXKwNZlEu2kEnWPdMD4kJ22tmoIuioa6 + gHyxthGFUXcGreYC9eTXb5+DW9eeBgAA + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 12:05:22 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/meal_plan_sections?query%5B%5D=id%3D1 + response: + body: + string: !!binary | + H4sIAAAAAAAEAw3LwQpAQBAG4FfRf15lh8IcvYa0LUZJi3ZHDvLunL++/sE6g63B7oOA0UXx2+KT + wiAdUd1+hVEiuDSIx+2m31Vmp2uQpD6c/6GCbF40OVWZrblqmQjv8AEGfHFxWwAAAA== + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 12:05:22 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/meal_plan_sections?query%5B%5D=id%3D-1 + response: + body: + string: !!binary | + H4sIAAAAAAAEAyXKwQqAIAwA0F+JnRWcXWS/EiGWO3hQYy46RP9e0Pm95YaSgSwaaKkyEICB0UVj + O+vG8pP0K+7CSTlHLZWHpnp81zuP1gXr58kFwpkwwLO+Gg7z9FQAAAA= + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 12:05:22 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/meal_plan_sections?query%5B%5D=id%3D1 + response: + body: + string: !!binary | + H4sIAAAAAAAEAw3LwQpAQBAG4FfRf15lh8IcvYa0LUZJi3ZHDvLunL++/sE6g63B7oOA0UXx2+KT + wiAdUd1+hVEiuDSIx+2m31Vmp2uQpD6c/6GCbF40OVWZrblqmQjv8AEGfHFxWwAAAA== + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 25 Aug 2021 12:05:23 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +version: 1 diff --git a/test/cassettes/test_meal_plan_sections/TestMealPlanSections.test_get_section_by_id_invalid.yaml b/test/cassettes/test_meal_plan_sections/TestMealPlanSections.test_get_section_by_id_invalid.yaml new file mode 100644 index 0000000..edf76ff --- /dev/null +++ b/test/cassettes/test_meal_plan_sections/TestMealPlanSections.test_get_section_by_id_invalid.yaml @@ -0,0 +1,43 @@ +interactions: +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/meal_plan_sections?query%5B%5D=id%3D1000 + response: + body: + string: !!binary | + H4sIAAAAAAAEA4uOBQApu0wNAgAAAA== + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Tue, 24 Aug 2021 17:57:24 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +version: 1 diff --git a/test/cassettes/test_meal_plan_sections/TestMealPlanSections.test_get_section_by_id_valid.yaml b/test/cassettes/test_meal_plan_sections/TestMealPlanSections.test_get_section_by_id_valid.yaml new file mode 100644 index 0000000..9287794 --- /dev/null +++ b/test/cassettes/test_meal_plan_sections/TestMealPlanSections.test_get_section_by_id_valid.yaml @@ -0,0 +1,44 @@ +interactions: +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/meal_plan_sections?query%5B%5D=id%3D1 + response: + body: + string: !!binary | + H4sIAAAAAAAEAw3LwQpAQBAG4FfRf15lh8IcvYa0LUZJi3ZHDvLunL++/sE6g63B7oOA0UXx2+KT + wiAdUd1+hVEiuDSIx+2m31Vmp2uQpD6c/6GCbF40OVWZrblqmQjv8AEGfHFxWwAAAA== + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Tue, 24 Aug 2021 17:57:00 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +version: 1 diff --git a/test/cassettes/test_meal_plan_sections/TestMealPlanSections.test_get_sections_valid.yaml b/test/cassettes/test_meal_plan_sections/TestMealPlanSections.test_get_sections_valid.yaml new file mode 100644 index 0000000..904c0e7 --- /dev/null +++ b/test/cassettes/test_meal_plan_sections/TestMealPlanSections.test_get_sections_valid.yaml @@ -0,0 +1,45 @@ +interactions: +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + accept: + - application/json + method: GET + uri: https://localhost/api/objects/meal_plan_sections + response: + body: + string: !!binary | + H4sIAAAAAAAEA4uuVspMUbLSNdRRykvMTVWyUlLSUSrOLyqJzyvNTUotgkgV5ZfHJxelJpakpsSX + ZOamFpck5hYA1RoZGBnqGljoGhkrGFhYGRpbGVoo1epAjESY6ATUmZ2WWFyCbrSxjhJBk00UDM2t + TCytjIyUamMBqqo+Xq4AAAA= + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Tue, 24 Aug 2021 17:49:32 GMT + Server: + - nginx/1.20.1 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/8.0.9 + status: + code: 200 + message: OK +version: 1 diff --git a/test/cassettes/test_stock/TestStock.test_get_expired_products_empty.yaml b/test/cassettes/test_stock/TestStock.test_get_expired_products_empty.yaml new file mode 100644 index 0000000..7092d22 --- /dev/null +++ b/test/cassettes/test_stock/TestStock.test_get_expired_products_empty.yaml @@ -0,0 +1,250 @@ +interactions: +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.25.1 + accept: + - application/json + method: GET + uri: https://localhost/api/stock/volatile + response: + body: + string: !!binary | + H4sIAAAAAAAEA+1aS2/jNhD+K4TOjhDZSTbxrVgUvbRA0fZSFAuClsYy15Ko8OE0DfLfO0NRtuRX + vQvHSQEdfOAMNaTJ+fjNDPkSZQ54rVXmUmui6V9fRpFagd6SvkSiVK6y0TS6jUahwUWea8iFhYzk + 8TVqVqJwgK0kicfYnIGxfAZzpYFn2BE14+txcnU9ubruGFI1VN4ImWhG4o2sPwappenI+HpapKJJ + 2+faj4/N8K+49NPbCKLpS7SWVaKk/j/muSELYFItaytVFU0rVxQbK7lWrt7YEqmVq3akQqWCvmnU + 9MfNQtW1rHLeUzUWHx3247XT6UIYMjHBDxqhsSpd0iI1kjmOovS6K7eKtz2Sa7/epawa0dZKwFy4 + gpa+u/7PuMGRX6gDai7mFrRf+tN6zjXAP/g3T+ttF+Jp07mWqXXoF3NZAG+2oVkfqMQMRVag8glk + vrB8Iaqs2HzaUdHIfiUqZXm6gHQZ1mPuCrRclFBZjv7HNaSyhnYFajSOiq6LNIOnolBa+n7JmDYm + daUr0HX59lJzNefGzVobreUtJ3x0EqeUqsq4EjablPg5L2QGHN3Gbyon3K0kPIXF1OqJpxoIXtzK + EndSlDXqGgCNr5IJSx6mN8l0che9vo6+GaLju3iS4B/s+0gHo+Or8SfU9/AY5taTdfC43o3vROkD + jhf2ZI1SkgWU/qlypy22T8PpHc3+jDgle32cBskxnA4wJQSvHWOA6ZqyOgR4jElv44R6HoQpUql3 + dE/QgTbfGKYJkcg2Tr0wAPXzAgCp7b2AukuoQTIAdeDTb+fTG3TkwHg9oN74s70Nee/jhKjqIE6R + TskLe9T51jglft/BKQlbnKoiY6nDyH8LqtHPGLKXTNYYtrBMYUzEjLQMg2U7YhTNgAWM3pgRGfZJ + MTRjUEirR8xAxjIpSlapypXPDKQuVcYslDUakdVKZphIMGdZIWY4CAPbDACsFHklmCjko3tGA6AF + Dra2t1KFq60TMfvBMgyVFANl6GuRps5Qf8u+OgylWObwR3MGrwfBNMxcGbPfcdIsxXkKthQmY7mb + gcYcphrhbHEkwaxYylKg3ogKw1P83lh2eC3iI7phnTY+E2/8kHcSqXMHaMO5P+RRy0vnUclD/Ikc + +cjB7wO4ix78VEDYOfhJGA7+X0Wt5VKg4LRUyseqZ0ylQoED6yBtQeOEksd3plKUxGYftOIR1c1G + xF/rHKc5lD58ferNSx9JfH80p8LqCkVJF4UskdcOZEnYxmoOS1EYr6BkwOx7VimxJNjsxADaS9Yr + k9v4/sPxLKWGO6AlYQDtb5gfmcW7QZaor1+xDJI3KIR8ZJodLhYueLGAQL0j3joWEF+cXYnud4BK + wgDUPxSm/QrbA7e+K7davw8Ds56HWSmp2le5HPcql3dxco8dj+HV538XvGHwpdJtvHphwOsvslie + jNZz15n8VUefV1vRGxDrcGPvr5tOubFHj/if3NfjOxv4u5YaL/eDm4fXN6U0BsvpXWl4rtKr26sl + PVJYozt8hfcJhGS8fccHDrZ45u3zEH/RQI8E/MMXOhbarHKhUkXvG/bZmvhjYq+1JFpb6+SoP7kS + S/4zEHrv3Cgw/i9rneD5s5am3muIjqNDhr68/gsqXCVT1SQAAA== + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Thu, 27 May 2021 09:45:47 GMT + Server: + - nginx/1.18.0 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/7.4.14 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.25.1 + accept: + - application/json + method: GET + uri: https://localhost/api/stock/volatile + response: + body: + string: !!binary | + H4sIAAAAAAAEA+1aS2/jNhD+K4TOjhDZSTbxrVgUvbRA0fZSFAuClsYy15Ko8OE0DfLfO0NRtuRX + vQvHSQEdfOAMNaTJ+fjNDPkSZQ54rVXmUmui6V9fRpFagd6SvkSiVK6y0TS6jUahwUWea8iFhYzk + 8TVqVqJwgK0kicfYnIGxfAZzpYFn2BE14+txcnU9ubruGFI1VN4ImWhG4o2sPwappenI+HpapKJJ + 2+faj4/N8K+49NPbCKLpS7SWVaKk/j/muSELYFItaytVFU0rVxQbK7lWrt7YEqmVq3akQqWCvmnU + 9MfNQtW1rHLeUzUWHx3247XT6UIYMjHBDxqhsSpd0iI1kjmOovS6K7eKtz2Sa7/epawa0dZKwFy4 + gpa+u/7PuMGRX6gDai7mFrRf+tN6zjXAP/g3T+ttF+Jp07mWqXXoF3NZAG+2oVkfqMQMRVag8glk + vrB8Iaqs2HzaUdHIfiUqZXm6gHQZ1mPuCrRclFBZjv7HNaSyhnYFajSOiq6LNIOnolBa+n7JmDYm + daUr0HX59lJzNefGzVobreUtJ3x0EqeUqsq4EjablPg5L2QGHN3Gbyon3K0kPIXF1OqJpxoIXtzK + EndSlDXqGgCNr5IJSx6mN8l0che9vo6+GaLju3iS4B/s+0gHo+Or8SfU9/AY5taTdfC43o3vROkD + jhf2ZI1SkgWU/qlypy22T8PpHc3+jDgle32cBskxnA4wJQSvHWOA6ZqyOgR4jElv44R6HoQpUql3 + dE/QgTbfGKYJkcg2Tr0wAPXzAgCp7b2AukuoQTIAdeDTb+fTG3TkwHg9oN74s70Nee/jhKjqIE6R + TskLe9T51jglft/BKQlbnKoiY6nDyH8LqtHPGLKXTNYYtrBMYUzEjLQMg2U7YhTNgAWM3pgRGfZJ + MTRjUEirR8xAxjIpSlapypXPDKQuVcYslDUakdVKZphIMGdZIWY4CAPbDACsFHklmCjko3tGA6AF + Dra2t1KFq60TMfvBMgyVFANl6GuRps5Qf8u+OgylWObwR3MGrwfBNMxcGbPfcdIsxXkKthQmY7mb + gcYcphrhbHEkwaxYylKg3ogKw1P83lh2eC3iI7phnTY+E2/8kHcSqXMHaMO5P+RRy0vnUclD/Ikc + +cjB7wO4ix78VEDYOfhJGA7+X0Wt5VKg4LRUyseqZ0ylQoED6yBtQeOEksd3plKUxGYftOIR1c1G + xF/rHKc5lD58ferNSx9JfH80p8LqCkVJF4UskdcOZEnYxmoOS1EYr6BkwOx7VimxJNjsxADaS9Yr + k9v4/sPxLKWGO6AlYQDtb5gfmcW7QZaor1+xDJI3KIR8ZJodLhYueLGAQL0j3joWEF+cXYnud4BK + wgDUPxSm/QrbA7e+K7davw8Ds56HWSmp2le5HPcql3dxco8dj+HV538XvGHwpdJtvHphwOsvslie + jNZz15n8VUefV1vRGxDrcGPvr5tOubFHj/if3NfjOxv4u5YaL/eDm4fXN6U0BsvpXWl4rtKr26sl + PVJYozt8hfcJhGS8fccHDrZ45u3zEH/RQI8E/MMXOhbarHKhUkXvG/bZmvhjYq+1JFpb6+SoP7kS + S/4zEHrv3Cgw/i9rneD5s5am3muIjqNDhr68/gsqXCVT1SQAAA== + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Thu, 27 May 2021 09:46:01 GMT + Server: + - nginx/1.18.0 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/7.4.14 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.25.1 + accept: + - application/json + method: GET + uri: https://localhost/api/stock/volatile + response: + body: + string: !!binary | + H4sIAAAAAAAEA+1aS2/jNhD+K4TOjhDZSTbxrVgUvbRA0fZSFAuClsYy15Ko8OE0DfLfO0NRtuRX + vQvHSQEdfOAMNaTJ+fjNDPkSZQ54rVXmUmui6V9fRpFagd6SvkSiVK6y0TS6jUahwUWea8iFhYzk + 8TVqVqJwgK0kicfYnIGxfAZzpYFn2BE14+txcnU9ubruGFI1VN4ImWhG4o2sPwappenI+HpapKJJ + 2+faj4/N8K+49NPbCKLpS7SWVaKk/j/muSELYFItaytVFU0rVxQbK7lWrt7YEqmVq3akQqWCvmnU + 9MfNQtW1rHLeUzUWHx3247XT6UIYMjHBDxqhsSpd0iI1kjmOovS6K7eKtz2Sa7/epawa0dZKwFy4 + gpa+u/7PuMGRX6gDai7mFrRf+tN6zjXAP/g3T+ttF+Jp07mWqXXoF3NZAG+2oVkfqMQMRVag8glk + vrB8Iaqs2HzaUdHIfiUqZXm6gHQZ1mPuCrRclFBZjv7HNaSyhnYFajSOiq6LNIOnolBa+n7JmDYm + daUr0HX59lJzNefGzVobreUtJ3x0EqeUqsq4EjablPg5L2QGHN3Gbyon3K0kPIXF1OqJpxoIXtzK + EndSlDXqGgCNr5IJSx6mN8l0che9vo6+GaLju3iS4B/s+0gHo+Or8SfU9/AY5taTdfC43o3vROkD + jhf2ZI1SkgWU/qlypy22T8PpHc3+jDgle32cBskxnA4wJQSvHWOA6ZqyOgR4jElv44R6HoQpUql3 + dE/QgTbfGKYJkcg2Tr0wAPXzAgCp7b2AukuoQTIAdeDTb+fTG3TkwHg9oN74s70Nee/jhKjqIE6R + TskLe9T51jglft/BKQlbnKoiY6nDyH8LqtHPGLKXTNYYtrBMYUzEjLQMg2U7YhTNgAWM3pgRGfZJ + MTRjUEirR8xAxjIpSlapypXPDKQuVcYslDUakdVKZphIMGdZIWY4CAPbDACsFHklmCjko3tGA6AF + Dra2t1KFq60TMfvBMgyVFANl6GuRps5Qf8u+OgylWObwR3MGrwfBNMxcGbPfcdIsxXkKthQmY7mb + gcYcphrhbHEkwaxYylKg3ogKw1P83lh2eC3iI7phnTY+E2/8kHcSqXMHaMO5P+RRy0vnUclD/Ikc + +cjB7wO4ix78VEDYOfhJGA7+X0Wt5VKg4LRUyseqZ0ylQoED6yBtQeOEksd3plKUxGYftOIR1c1G + xF/rHKc5lD58ferNSx9JfH80p8LqCkVJF4UskdcOZEnYxmoOS1EYr6BkwOx7VimxJNjsxADaS9Yr + k9v4/sPxLKWGO6AlYQDtb5gfmcW7QZaor1+xDJI3KIR8ZJodLhYueLGAQL0j3joWEF+cXYnud4BK + wgDUPxSm/QrbA7e+K7davw8Ds56HWSmp2le5HPcql3dxco8dj+HV538XvGHwpdJtvHphwOsvslie + jNZz15n8VUefV1vRGxDrcGPvr5tOubFHj/if3NfjOxv4u5YaL/eDm4fXN6U0BsvpXWl4rtKr26sl + PVJYozt8hfcJhGS8fccHDrZ45u3zEH/RQI8E/MMXOhbarHKhUkXvG/bZmvhjYq+1JFpb6+SoP7kS + S/4zEHrv3Cgw/i9rneD5s5am3muIjqNDhr68/gsqXCVT1SQAAA== + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Thu, 27 May 2021 10:31:49 GMT + Server: + - nginx/1.18.0 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/7.4.14 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.25.1 + accept: + - application/json + method: GET + uri: https://localhost/api/stock/volatile + response: + body: + string: !!binary | + H4sIAAAAAAAEA+1aS2/jNhD+K4TOjhDZSTbxrVgUvbRA0fZSFAuClsYy15Ko8OE0DfLfO0NRtuRX + vQvHSQEdfOAMNaTJ+fjNDPkSZQ54rVXmUmui6V9fRpFagd6SvkSiVK6y0TS6jUahwUWea8iFhYzk + 8TVqVqJwgK0kicfYnIGxfAZzpYFn2BE14+txcnU9ubruGFI1VN4ImWhG4o2sPwappenI+HpapKJJ + 2+faj4/N8K+49NPbCKLpS7SWVaKk/j/muSELYFItaytVFU0rVxQbK7lWrt7YEqmVq3akQqWCvmnU + 9MfNQtW1rHLeUzUWHx3247XT6UIYMjHBDxqhsSpd0iI1kjmOovS6K7eKtz2Sa7/epawa0dZKwFy4 + gpa+u/7PuMGRX6gDai7mFrRf+tN6zjXAP/g3T+ttF+Jp07mWqXXoF3NZAG+2oVkfqMQMRVag8glk + vrB8Iaqs2HzaUdHIfiUqZXm6gHQZ1mPuCrRclFBZjv7HNaSyhnYFajSOiq6LNIOnolBa+n7JmDYm + daUr0HX59lJzNefGzVobreUtJ3x0EqeUqsq4EjablPg5L2QGHN3Gbyon3K0kPIXF1OqJpxoIXtzK + EndSlDXqGgCNr5IJSx6mN8l0che9vo6+GaLju3iS4B/s+0gHo+Or8SfU9/AY5taTdfC43o3vROkD + jhf2ZI1SkgWU/qlypy22T8PpHc3+jDgle32cBskxnA4wJQSvHWOA6ZqyOgR4jElv44R6HoQpUql3 + dE/QgTbfGKYJkcg2Tr0wAPXzAgCp7b2AukuoQTIAdeDTb+fTG3TkwHg9oN74s70Nee/jhKjqIE6R + TskLe9T51jglft/BKQlbnKoiY6nDyH8LqtHPGLKXTNYYtrBMYUzEjLQMg2U7YhTNgAWM3pgRGfZJ + MTRjUEirR8xAxjIpSlapypXPDKQuVcYslDUakdVKZphIMGdZIWY4CAPbDACsFHklmCjko3tGA6AF + Dra2t1KFq60TMfvBMgyVFANl6GuRps5Qf8u+OgylWObwR3MGrwfBNMxcGbPfcdIsxXkKthQmY7mb + gcYcphrhbHEkwaxYylKg3ogKw1P83lh2eC3iI7phnTY+E2/8kHcSqXMHaMO5P+RRy0vnUclD/Ikc + +cjB7wO4ix78VEDYOfhJGA7+X0Wt5VKg4LRUyseqZ0ylQoED6yBtQeOEksd3plKUxGYftOIR1c1G + xF/rHKc5lD58ferNSx9JfH80p8LqCkVJF4UskdcOZEnYxmoOS1EYr6BkwOx7VimxJNjsxADaS9Yr + k9v4/sPxLKWGO6AlYQDtb5gfmcW7QZaor1+xDJI3KIR8ZJodLhYueLGAQL0j3joWEF+cXYnud4BK + wgDUPxSm/QrbA7e+K7davw8Ds56HWSmp2le5HPcql3dxco8dj+HV538XvGHwpdJtvHphwOsvslie + jNZz15n8VUefV1vRGxDrcGPvr5tOubFHj/if3NfjOxv4u5YaL/eDm4fXN6U0BsvpXWl4rtKr26sl + PVJYozt8hfcJhGS8fccHDrZ45u3zEH/RQI8E/MMXOhbarHKhUkXvG/bZmvhjYq+1JFpb6+SoP7kS + S/4zEHrv3Cgw/i9rneD5s5am3muIjqNDhr68/gsqXCVT1SQAAA== + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Thu, 27 May 2021 10:32:04 GMT + Server: + - nginx/1.18.0 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/7.4.14 + status: + code: 200 + message: OK +version: 1 diff --git a/test/cassettes/test_users/TestUsers.test_get_user_by_id_valid.yaml b/test/cassettes/test_users/TestUsers.test_get_user_by_id_valid.yaml new file mode 100644 index 0000000..cae2453 --- /dev/null +++ b/test/cassettes/test_users/TestUsers.test_get_user_by_id_valid.yaml @@ -0,0 +1,46 @@ +interactions: +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.25.1 + accept: + - application/json + method: GET + uri: https://localhost/api/users + response: + body: + string: !!binary | + H4sIAAAAAAAEA72RywrCMBBFfyVknUKT1oVd+wuuREJopzCQtCEPioj/bqJdqFi7kS7nXrjnwJyu + FDvaUE4ZjR7coAyk8wBmJMd0p7hH54N8FkPUmlGtPgI3TrJ1oAJ0MqABH5SxaUaUghelKHhF+L6p + eVPVabBDb7W6zJNvLIttiA5kjxpekDc2a4oFTZKLv4rufog+aGuq1ZJqLrZTzbQ11fyUb88nudhO + NdOWVM932fjmdqkCAAA= + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Wed, 28 Jul 2021 13:11:50 GMT + Server: + - nginx/1.18.0 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/7.4.14 + status: + code: 200 + message: OK +version: 1 diff --git a/test/cassettes/test_users/TestUsers.test_get_users_valid.yaml b/test/cassettes/test_users/TestUsers.test_get_users_valid.yaml new file mode 100644 index 0000000..d005af2 --- /dev/null +++ b/test/cassettes/test_users/TestUsers.test_get_users_valid.yaml @@ -0,0 +1,46 @@ +interactions: +- request: + body: null + headers: + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.25.1 + accept: + - application/json + method: GET + uri: https://localhost/api/users + response: + body: + string: !!binary | + H4sIAAAAAAAEA72RywrCMBBFfyVknUKT1oVd+wuuREJopzCQtCEPioj/bqJdqFi7kS7nXrjnwJyu + FDvaUE4ZjR7coAyk8wBmJMd0p7hH54N8FkPUmlGtPgI3TrJ1oAJ0MqABH5SxaUaUghelKHhF+L6p + eVPVabBDb7W6zJNvLIttiA5kjxpekDc2a4oFTZKLv4rufog+aGuq1ZJqLrZTzbQ11fyUb88nudhO + NdOWVM932fjmdqkCAAA= + headers: + Access-Control-Allow-Headers: + - '*' + Access-Control-Allow-Methods: + - GET, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Fri, 28 May 2021 08:58:31 GMT + Server: + - nginx/1.18.0 + Transfer-Encoding: + - chunked + X-Powered-By: + - PHP/7.4.14 + status: + code: 200 + message: OK +version: 1 diff --git a/test/test_LocationData.py b/test/test_LocationData.py deleted file mode 100644 index 07a5f8d..0000000 --- a/test/test_LocationData.py +++ /dev/null @@ -1,21 +0,0 @@ -import json -from unittest import TestCase - -from pygrocy.grocy_api_client import LocationData - - -class TestLocationData(TestCase): - def test_parse(self): - input_json = """{ - "id": "1", - "name": "string", - "description": "string", - "row_created_timestamp": "2019-04-17 10:30:00" - }""" - - response = LocationData(json.loads(input_json)) - - assert response.id == 1 - assert response.name == "string" - assert response.description == "string" - \ No newline at end of file diff --git a/test/test_MealPlanResponse.py b/test/test_MealPlanResponse.py deleted file mode 100644 index 0743045..0000000 --- a/test/test_MealPlanResponse.py +++ /dev/null @@ -1,29 +0,0 @@ -import json -from datetime import datetime -from unittest import TestCase - -from pygrocy.grocy_api_client import MealPlanResponse - - -class TestMealPlanResponse(TestCase): - def test_parse(self): - input_json = """{ - "id": "7", - "day": "2020-08-16", - "type": "recipe", - "recipe_id": "4", - "recipe_servings": "3", - "note": null, - "product_id": null, - "product_amount": "0.0", - "product_qu_id": null, - "row_created_timestamp": "2020-08-12 14:37:06", - "userfields": null - }""" - - response = MealPlanResponse(json.loads(input_json)) - - assert response.id == 7 - assert response.recipe_id == 4 - assert response.recipe_servings == 3 - self.assertIsInstance(response.day, datetime) diff --git a/test/test_ShoppingListItem.py b/test/test_ShoppingListItem.py deleted file mode 100644 index 60e1650..0000000 --- a/test/test_ShoppingListItem.py +++ /dev/null @@ -1,25 +0,0 @@ -import json -from unittest import TestCase - -from pygrocy.grocy_api_client import ShoppingListItem - - -class TestShoppingListItem(TestCase): - def test_parse(self): - input_json = """{ - "id": "1", - "product_id": "6", - "note": "string", - "amount": "2", - "row_created_timestamp": "2019-04-17 10:30:00", - "shopping_list_id": "1", - "done": "0" - }""" - - response = ShoppingListItem(json.loads(input_json)) - - assert response.product_id == 6 - assert response.id == 1 - assert response.note == "string" - assert response.amount == 2 - \ No newline at end of file diff --git a/test/test_UserDto.py b/test/test_UserDto.py deleted file mode 100644 index 64529d3..0000000 --- a/test/test_UserDto.py +++ /dev/null @@ -1,24 +0,0 @@ -import json -from unittest import TestCase - -from pygrocy.grocy_api_client import UserDto - - -class TestUserDto(TestCase): - def test_parse(self): - input_json = """{ - "id": "1", - "username": "user", - "first_name": "Guz", - "last_name": "Userman", - "row_created_timestamp": "2019-04-17 10:30:00", - "display_name": "Guzzboy" - }""" - - response = UserDto(json.loads(input_json)) - - assert response.display_name == "Guzzboy" - assert response.id == 1 - assert response.first_name == "Guz" - assert response.last_name == "Userman" - assert response.username == "user" diff --git a/test/test_battery.py b/test/test_battery.py index 7dad178..0b9c2d9 100644 --- a/test/test_battery.py +++ b/test/test_battery.py @@ -22,7 +22,7 @@ def test_get_battery_details_valid(self, grocy): assert battery.charge_interval_days == 0 assert isinstance(battery.created_timestamp, datetime) assert isinstance(battery.last_charged, datetime) - assert battery.next_estimated_charge_time is None + assert isinstance(battery.next_estimated_charge_time, datetime) assert battery.userfields is None assert battery.charge_cycles_count == 6 diff --git a/test/test_choreDetailsResponse.py b/test/test_choreDetailsResponse.py deleted file mode 100644 index 61e4aa0..0000000 --- a/test/test_choreDetailsResponse.py +++ /dev/null @@ -1,68 +0,0 @@ -import json -from unittest import TestCase - -from pygrocy.grocy_api_client import ChoreDetailsResponse - - -class TestChoreDetailsResponse(TestCase): - def test_parse(self): - input_json = """{ - "chore": { - "id": 0, - "name": "string", - "description": "string", - "period_type": "manually", - "period_days": 0, - "row_created_timestamp": "2019-05-04T11:31:04.563Z" - }, - "last_tracked": "2019-05-04T11:31:04.563Z", - "track_count": 0, - "last_done_by": { - "id": 0, - "username": "string", - "first_name": "string", - "last_name": "string", - "display_name": "string", - "row_created_timestamp": "2019-05-04T11:31:04.564Z" - }, - "next_estimated_execution_time": "2019-05-04T11:31:04.564Z", - "next_execution_assigned_user": { - "id": 42, - "username": "string", - "first_name": "string", - "last_name": "string", - "display_name": "string", - "row_created_timestamp": "2019-05-04T11:31:04.564Z" - } - }""" - - response = ChoreDetailsResponse(json.loads(input_json)) - - assert response.chore.id == 0 - assert response.chore.name == "string" - - assert response.last_done_by.display_name == "string" - - assert response.next_execution_assigned_user.id == 42 - assert response.next_execution_assigned_user.display_name == "string" - - def test_no_last_tracked_data(self): - input_json = """{ - "chore": { - "id": 0, - "name": "string", - "description": "string", - "period_type": "manually", - "period_days": 0, - "row_created_timestamp": "2019-05-04T11:31:04.563Z" - }, - "last_tracked": null, - "track_count": 0, - "last_done_by": null, - "next_estimated_execution_time": "2019-05-04T11:31:04.564Z" - }""" - - response = ChoreDetailsResponse(json.loads(input_json)) - - assert response.last_tracked is None - assert response.last_done_by is None diff --git a/test/test_currentChoreResponse.py b/test/test_currentChoreResponse.py deleted file mode 100644 index 9df8c4a..0000000 --- a/test/test_currentChoreResponse.py +++ /dev/null @@ -1,14 +0,0 @@ -import json -from unittest import TestCase - -from pygrocy.grocy_api_client import CurrentChoreResponse - - -class TestCurrentChoreResponse(TestCase): - def test_parse(self): - input_json = """{ "chore_id": "4", "last_tracked_time": null, "next_estimated_execution_time": "2999-12-31 23:59:59", "track_date_only": "0", "next_execution_assigned_to_user_id": null }""" - - response = CurrentChoreResponse(json.loads(input_json)) - - assert response.chore_id == 4 - diff --git a/test/test_currentStockResponse.py b/test/test_currentStockResponse.py deleted file mode 100644 index 4f25020..0000000 --- a/test/test_currentStockResponse.py +++ /dev/null @@ -1,20 +0,0 @@ -import json -from unittest import TestCase - -from pygrocy.grocy_api_client import CurrentStockResponse - - -class TestCurrentStockResponse(TestCase): - def test_parse(self): - input_json = """{"product_id": 0,"amount": "12.53","best_before_date": "2019-04-22","amount_opened": 0, "product": { "id": 0, "name": "test product"}}""" - response = CurrentStockResponse(json.loads(input_json)) - - assert response.product_id == 0 - assert response.amount == 12.53 - assert response.amount_opened == 0 - - assert response.best_before_date.year == 2019 - assert response.best_before_date.month == 4 - assert response.best_before_date.day == 22 - assert response.product.id == 0 - assert response.product.name == "test product" diff --git a/test/test_meal_plan.py b/test/test_meal_plan.py index 1afee8b..0a809cf 100644 --- a/test/test_meal_plan.py +++ b/test/test_meal_plan.py @@ -1,6 +1,6 @@ import pytest -from pygrocy.data_models.meal_items import RecipeItem +from pygrocy.data_models.meal_items import MealPlanItemType, MealPlanSection, RecipeItem class TestMealPlan: @@ -20,7 +20,7 @@ def test_get_meal_plan_valid(self, grocy): def test_get_meal_plan_with_details_valid(self, grocy): meal_plan = grocy.meal_plan(get_details=True) - assert len(meal_plan) == 8 + assert len(meal_plan) == 9 item = next(item for item in meal_plan if item.id == 1) assert item.day.day == 8 assert item.recipe_id == 1 @@ -35,3 +35,24 @@ def test_get_meal_plan_with_details_valid(self, grocy): assert recipe.base_servings == 1 assert recipe.description[:4] == "