diff --git a/.gitignore b/.gitignore index d5cad4620..2c1abbc58 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ docs/site/ .secret frontend/dist/ +dev/code-generation/generated/* dev/data/backups/* dev/data/debug/* dev/data/img/* diff --git a/.vscode/settings.json b/.vscode/settings.json index 0d5970787..4b8f80bf0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,7 +6,15 @@ "code-generation" ], "cSpell.enableFiletypes": ["!javascript", "!python", "!yaml"], - "cSpell.words": ["compression", "hkotel", "performant", "postgres", "webp"], + "cSpell.words": [ + "chowdown", + "compression", + "hkotel", + "nextcloud", + "performant", + "postgres", + "webp" + ], "editor.codeActionsOnSave": { "source.fixAll.eslint": true, "source.organizeImports": false diff --git a/dev/code-generation/_gen_utils.py b/dev/code-generation/_gen_utils.py index 701c6fff3..ffc5466ff 100644 --- a/dev/code-generation/_gen_utils.py +++ b/dev/code-generation/_gen_utils.py @@ -3,15 +3,15 @@ from dataclasses import dataclass from pathlib import Path from typing import Tuple -from black import FileMode, format_str +import black from jinja2 import Template def render_python_template(template_file: Path, dest: Path, data: dict) -> str: """Render and Format a Jinja2 Template for Python Code""" tplt = Template(template_file.read_text()) - text = tplt.render(data) - text = format_str(text, mode=FileMode()) + text = tplt.render(data=data) + text = black.format_str(text, mode=black.FileMode()) dest.write_text(text) diff --git a/dev/code-generation/gen_test_data_paths.py b/dev/code-generation/gen_test_data_paths.py new file mode 100644 index 000000000..c9e2d641e --- /dev/null +++ b/dev/code-generation/gen_test_data_paths.py @@ -0,0 +1,124 @@ +from dataclasses import dataclass +from pathlib import Path + +from _gen_utils import render_python_template +from slugify import slugify + +CWD = Path(__file__).parent + +TEMPLATE = CWD / "templates" / "test_data.py.j2" + +TEST_DATA = CWD.parent.parent / "tests" / "data" + +GENERATED = CWD / "generated" + + +@dataclass +class TestDataPath: + var: str + path: str + + @classmethod + def from_path(cls, path: Path): + var = str(path) + var = var.replace(str(TEST_DATA), "") + + rel_path = var.removeprefix("/") + + # Remove any file extension + var = var.split(".")[0] + + var = var.replace("'", "") + + var = slugify(var, separator="_") + + return cls(var, rel_path) + + +@dataclass +class DataDir: + name: str + path: Path + children: list[TestDataPath] + + +def get_data_paths(path: Path) -> list[DataDir]: + """ + Recursively walks the given path and returns a list of TestDataPaths + """ + + def recursive_test_paths(p: Path) -> list[TestDataPath]: + test_paths = [] + for child in p.iterdir(): + if child.is_dir(): + test_paths += recursive_test_paths(child) + else: + test_paths.append(TestDataPath.from_path(child)) + return [x for x in test_paths if not None] + + data_paths = [] + + for p in path.iterdir(): + if p.is_dir(): + data_paths.append(DataDir(p.name, p, recursive_test_paths(p))) + + return data_paths + + +def rename_non_compliant_paths(): + """ + Recursively itterates through a directory and renames all files/folders to be + kabab case. + """ + + ignore_files = ["DS_Store", ".gitkeep"] + + ignore_extensions = [".pyc", ".pyo", ".py"] + + def recursive_rename(p: Path): + for child in p.iterdir(): + if str(child).startswith("."): + continue + + if child.suffix in ignore_extensions: + continue + + if child.name in ignore_files: + continue + + if child.is_dir(): + recursive_rename(child) + + else: + new_name = slugify(child.stem) + extension = child.suffix + if new_name != child.name: + child.rename(child.parent / f"{new_name}{extension}") + + recursive_rename(TEST_DATA) + + +def main(): + print("Starting Template Generation") + + rename_non_compliant_paths() + + GENERATED.mkdir(exist_ok=True) + data_dirs = get_data_paths(TEST_DATA) + + all_children = [x.children for x in data_dirs] + + # Flatten list of lists + all_children = [item for sublist in all_children for item in sublist] + + render_python_template( + TEMPLATE, + GENERATED / "__init__.py", + {"children": all_children}, + ) + + print("Finished Template Generation") + + +if __name__ == "__main__": + main() diff --git a/dev/code-generation/templates/test_data.py.j2 b/dev/code-generation/templates/test_data.py.j2 new file mode 100644 index 000000000..e43c93ec8 --- /dev/null +++ b/dev/code-generation/templates/test_data.py.j2 @@ -0,0 +1,7 @@ +from pathlib import Path + +CWD = Path(__file__).parent + +{% for f in data.children %} +{{ f.var }} = CWD / "{{ f.path }}" +{% endfor %} \ No newline at end of file diff --git a/frontend/api/class-interfaces/group-migrations.ts b/frontend/api/class-interfaces/group-migrations.ts index f2081ade8..58e74d439 100644 --- a/frontend/api/class-interfaces/group-migrations.ts +++ b/frontend/api/class-interfaces/group-migrations.ts @@ -3,9 +3,10 @@ import { ReportSummary } from "./group-reports"; const prefix = "/api"; -export type SupportedMigration = "nextcloud" | "chowdown"; +export type SupportedMigration = "nextcloud" | "chowdown" | "mealie_alpha" | "paprika"; export interface MigrationPayload { + addMigrationTag: boolean; migrationType: SupportedMigration; archive: File; } @@ -17,6 +18,7 @@ const routes = { export class GroupMigrationApi extends BaseAPI { async startMigration(payload: MigrationPayload) { const form = new FormData(); + form.append("add_migration_tag", String(payload.addMigrationTag)); form.append("migration_type", payload.migrationType); form.append("archive", payload.archive); diff --git a/frontend/nuxt.config.js b/frontend/nuxt.config.js index 8fe690222..216ffb98d 100644 --- a/frontend/nuxt.config.js +++ b/frontend/nuxt.config.js @@ -1,5 +1,4 @@ export default { - mode: "universal", // Global page headers: https://go.nuxtjs.dev/config-head head: { title: "Home", diff --git a/frontend/pages/recipe/create.vue b/frontend/pages/recipe/create.vue index e028d56b3..789c7b23b 100644 --- a/frontend/pages/recipe/create.vue +++ b/frontend/pages/recipe/create.vue @@ -306,6 +306,10 @@ + + + Looking For Migrations? + diff --git a/frontend/pages/user/group/data/migrations.vue b/frontend/pages/user/group/data/migrations.vue index 3a6a8730b..4e203eeb1 100644 --- a/frontend/pages/user/group/data/migrations.vue +++ b/frontend/pages/user/group/data/migrations.vue @@ -42,6 +42,14 @@ {{ fileObject.name || "No file selected" }} + + + + + + {{ $t("general.submit") }} None: + def __init__(self, name, **_) -> None: self.name = name.strip() self.slug = slugify(self.name) diff --git a/mealie/routes/groups/migrations.py b/mealie/routes/groups/migrations.py index 6ccdb9c0d..89198b4c3 100644 --- a/mealie/routes/groups/migrations.py +++ b/mealie/routes/groups/migrations.py @@ -14,6 +14,7 @@ router = UserAPIRouter() @router.post("", response_model=ReportSummary) def start_data_migration( + add_migration_tag: bool = Form(False), migration_type: SupportedMigrations = Form(...), archive: UploadFile = File(...), temp_path: str = Depends(temporary_zip_path), @@ -23,4 +24,4 @@ def start_data_migration( with temp_path.open("wb") as buffer: shutil.copyfileobj(archive.file, buffer) - return gm_service.migrate(migration_type, temp_path) + return gm_service.migrate(migration_type, add_migration_tag, temp_path) diff --git a/mealie/schema/group/group_migration.py b/mealie/schema/group/group_migration.py index ab7f4c209..a20091612 100644 --- a/mealie/schema/group/group_migration.py +++ b/mealie/schema/group/group_migration.py @@ -6,6 +6,8 @@ from fastapi_camelcase import CamelModel class SupportedMigrations(str, enum.Enum): nextcloud = "nextcloud" chowdown = "chowdown" + paprika = "paprika" + mealie_alpha = "mealie_alpha" class DataMigrationCreate(CamelModel): diff --git a/mealie/services/group_services/migration_service.py b/mealie/services/group_services/migration_service.py index b184a1417..102b3951d 100644 --- a/mealie/services/group_services/migration_service.py +++ b/mealie/services/group_services/migration_service.py @@ -11,6 +11,8 @@ from mealie.schema.reports.reports import ReportOut, ReportSummary from mealie.services._base_http_service.http_services import UserHttpService from mealie.services.events import create_group_event from mealie.services.migrations import ChowdownMigrator, NextcloudMigrator +from mealie.services.migrations.mealie_alpha import MealieAlphaMigrator +from mealie.services.migrations.paprika import PaprikaMigrator logger = get_logger(module=__name__) @@ -24,14 +26,29 @@ class GroupMigrationService(UserHttpService[int, ReportOut]): def dal(self): raise NotImplementedError - def populate_item(self, id: UUID4) -> ReportOut: + def populate_item(self, _: UUID4) -> ReportOut: return None - def migrate(self, migration: SupportedMigrations, archive: Path) -> ReportSummary: + def migrate(self, migration: SupportedMigrations, add_migration_tag: bool, archive: Path) -> ReportSummary: + args = { + "archive": archive, + "db": self.db, + "session": self.session, + "user_id": self.user.id, + "group_id": self.group_id, + "add_migration_tag": add_migration_tag, + } + if migration == SupportedMigrations.nextcloud: - self.migration_type = NextcloudMigrator(archive, self.db, self.session, self.user.id, self.group_id) + self.migration_type = NextcloudMigrator(**args) if migration == SupportedMigrations.chowdown: - self.migration_type = ChowdownMigrator(archive, self.db, self.session, self.user.id, self.group_id) + self.migration_type = ChowdownMigrator(**args) + + if migration == SupportedMigrations.paprika: + self.migration_type = PaprikaMigrator(**args) + + if migration == SupportedMigrations.mealie_alpha: + self.migration_type = MealieAlphaMigrator(**args) return self.migration_type.migrate(f"{migration.value.title()} Migration") diff --git a/mealie/services/migrations/_migration_base.py b/mealie/services/migrations/_migration_base.py index 0ea59894a..1ab6805cc 100644 --- a/mealie/services/migrations/_migration_base.py +++ b/mealie/services/migrations/_migration_base.py @@ -16,6 +16,7 @@ from mealie.schema.reports.reports import ( from mealie.services.scraper import cleaner from .._base_service import BaseService +from .utils.database_helpers import DatabaseMigrationHelpers from .utils.migration_alias import MigrationAlias @@ -26,17 +27,22 @@ class BaseMigrator(BaseService): report_id: int report: ReportOut - def __init__(self, archive: Path, db: Database, session, user_id: int, group_id: UUID): + def __init__(self, archive: Path, db: Database, session, user_id: int, group_id: UUID, add_migration_tag: bool): self.archive = archive self.db = db self.session = session self.user_id = user_id self.group_id = group_id + self.add_migration_tag = add_migration_tag + + self.name = "migration" self.report_entries = [] self.logger = root_logger.get_logger() + self.helpers = DatabaseMigrationHelpers(self.db, self.session, self.group_id, self.user_id) + super().__init__() def _migrate(self) -> None: @@ -94,6 +100,8 @@ class BaseMigrator(BaseService): Args: validated_recipes (list[Recipe]): """ + if self.add_migration_tag: + migration_tag = self.helpers.get_or_set_tags([self.name])[0] return_vars = [] @@ -102,6 +110,9 @@ class BaseMigrator(BaseService): recipe.user_id = self.user_id recipe.group_id = self.group_id + if self.add_migration_tag: + recipe.tags.append(migration_tag) + exception = "" status = False try: @@ -109,7 +120,7 @@ class BaseMigrator(BaseService): status = True except Exception as inst: - exception = inst + exception = str(inst) self.logger.exception(inst) self.session.rollback() @@ -165,6 +176,17 @@ class BaseMigrator(BaseService): dictionary and returns the result unpacked into a Recipe object """ recipe_dict = self.rewrite_alias(recipe_dict) + + # Temporary hold out of recipe_dict + # temp_categories = recipe_dict["recipeCategory"] + # temp_tools = recipe_dict["tools"] + # temp_tasg = recipe_dict["tags"] + recipe_dict = cleaner.clean(recipe_dict, url=recipe_dict.get("org_url", None)) + # Reassign after cleaning + # recipe_dict["recipeCategory"] = temp_categories + # recipe_dict["tools"] = temp_tools + # recipe_dict["tags"] = temp_tasg + return Recipe(**recipe_dict) diff --git a/mealie/services/migrations/chowdown.py b/mealie/services/migrations/chowdown.py index 05855dfe7..82100e4ac 100644 --- a/mealie/services/migrations/chowdown.py +++ b/mealie/services/migrations/chowdown.py @@ -1,9 +1,6 @@ import tempfile import zipfile from pathlib import Path -from uuid import UUID - -from mealie.db.database import Database from ._migration_base import BaseMigrator from .utils.migration_alias import MigrationAlias @@ -11,8 +8,10 @@ from .utils.migration_helpers import MigrationReaders, import_image, split_by_co class ChowdownMigrator(BaseMigrator): - def __init__(self, archive: Path, db: Database, session, user_id: int, group_id: UUID): - super().__init__(archive, db, session, user_id, group_id) + def __init__(self, **kwargs): + super().__init__(**kwargs) + + self.name = "chowdown" self.key_aliases = [ MigrationAlias(key="name", alias="title", func=None), diff --git a/mealie/services/migrations/mealie_alpha.py b/mealie/services/migrations/mealie_alpha.py new file mode 100644 index 000000000..660c56d3f --- /dev/null +++ b/mealie/services/migrations/mealie_alpha.py @@ -0,0 +1,87 @@ +import shutil +import tempfile +import zipfile +from pathlib import Path + +from mealie.schema.recipe.recipe import Recipe + +from ._migration_base import BaseMigrator +from .utils.migration_alias import MigrationAlias +from .utils.migration_helpers import MigrationReaders, split_by_comma + + +class MealieAlphaMigrator(BaseMigrator): + def __init__(self, **kwargs): + super().__init__(**kwargs) + + self.name = "mealie_alpha" + + self.key_aliases = [ + MigrationAlias(key="name", alias="title", func=None), + MigrationAlias(key="recipeIngredient", alias="ingredients", func=None), + MigrationAlias(key="recipeInstructions", alias="directions", func=None), + MigrationAlias(key="tags", alias="tags", func=split_by_comma), + ] + + def _convert_to_new_schema(self, recipe: dict) -> Recipe: + if recipe.get("categories", False): + recipe["recipeCategory"] = recipe.get("categories") + del recipe["categories"] + try: + del recipe["_id"] + del recipe["date_added"] + except Exception: + pass + # Migration from list to Object Type Data + try: + if "" in recipe["tags"]: + recipe["tags"] = [tag for tag in recipe["tags"] if tag != ""] + except Exception: + pass + + try: + if "" in recipe["categories"]: + recipe["categories"] = [cat for cat in recipe["categories"] if cat != ""] + + except Exception: + pass + + if type(recipe["extras"]) == list: + recipe["extras"] = {} + + recipe["comments"] = [] + + return Recipe(**recipe) + + def _migrate(self) -> None: + with tempfile.TemporaryDirectory() as tmpdir: + with zipfile.ZipFile(self.archive) as zip_file: + zip_file.extractall(tmpdir) + + temp_path = Path(tmpdir) + + recipe_lookup: dict[str, Path] = {} + recipes_as_dicts = [] + + for x in temp_path.rglob("**/[!.]*.json"): + if (y := MigrationReaders.json(x)) is not None: + recipes_as_dicts.append(y) + slug = y["slug"] + recipe_lookup[slug] = x.parent + + recipes = [self._convert_to_new_schema(x) for x in recipes_as_dicts] + + results = self.import_recipes_to_database(recipes) + + recipe_model_lookup = {x.slug: x for x in recipes} + + for slug, status in results: + if status: + model = recipe_model_lookup.get(slug) + dest_dir = model.directory + source_dir = recipe_lookup.get(slug) + + if dest_dir.exists(): + shutil.rmtree(dest_dir) + + shutil.copytree(source_dir, dest_dir) diff --git a/mealie/services/migrations/nextcloud.py b/mealie/services/migrations/nextcloud.py index 4000f35cd..08ca2ab69 100644 --- a/mealie/services/migrations/nextcloud.py +++ b/mealie/services/migrations/nextcloud.py @@ -3,12 +3,9 @@ import zipfile from dataclasses import dataclass from pathlib import Path from typing import Optional -from uuid import UUID from slugify import slugify -from mealie.db.database import Database - from ._migration_base import BaseMigrator from .utils.migration_alias import MigrationAlias from .utils.migration_helpers import MigrationReaders, glob_walker, import_image, split_by_comma @@ -40,8 +37,10 @@ class NextcloudDir: class NextcloudMigrator(BaseMigrator): - def __init__(self, archive: Path, db: Database, session, user_id: int, group_id: UUID): - super().__init__(archive, db, session, user_id, group_id) + def __init__(self, **kwargs): + super().__init__(**kwargs) + + self.name = "nextcloud" self.key_aliases = [ MigrationAlias(key="tags", alias="keywords", func=split_by_comma), diff --git a/mealie/services/migrations/paprika.py b/mealie/services/migrations/paprika.py new file mode 100644 index 000000000..d0da688ea --- /dev/null +++ b/mealie/services/migrations/paprika.py @@ -0,0 +1,93 @@ +import base64 +import io +import json +import tempfile +import zipfile +from gzip import GzipFile +from pathlib import Path + +import regex as re +from slugify import slugify + +from mealie.schema.recipe import RecipeNote + +from ._migration_base import BaseMigrator +from .utils.migration_alias import MigrationAlias +from .utils.migration_helpers import import_image + + +def paprika_recipes(file: Path): + """Yields all recipes inside the export file as JSON""" + with tempfile.TemporaryDirectory() as tmpdir: + with zipfile.ZipFile(file) as zip_file: + zip_file.extractall(tmpdir) + + for name in Path(tmpdir).glob("**/[!.]*.paprikarecipe"): + with open(name, "rb") as fd: + with GzipFile("r", fileobj=fd) as recipe_json: + recipe = json.load(recipe_json) + yield recipe + + +class PaprikaMigrator(BaseMigrator): + def __init__(self, **kwargs): + super().__init__(**kwargs) + + self.name = "paprika" + + re_num_list = re.compile(r"^\d+\.\s") + + self.key_aliases = [ + MigrationAlias(key="recipeIngredient", alias="ingredients", func=lambda x: x.split("\n")), + MigrationAlias(key="orgUrl", alias="source_url", func=None), + MigrationAlias(key="performTime", alias="cook_time", func=None), + MigrationAlias(key="recipeYield", alias="servings", func=None), + MigrationAlias(key="image", alias="image_url", func=None), + MigrationAlias(key="dateAdded", alias="created", func=lambda x: x[: x.find(" ")]), + MigrationAlias( + key="notes", + alias="notes", + func=lambda x: [z for z in [RecipeNote(title="", text=x) if x else None] if z], + ), + MigrationAlias( + key="recipeCategory", + alias="categories", + func=self.helpers.get_or_set_category, + ), + MigrationAlias( + key="recipeInstructions", + alias="directions", + func=lambda x: [{"text": re.sub(re_num_list, "", s)} for s in x.split("\n\n")], + ), + ] + + def _migrate(self) -> None: + recipe_image_urls = {} + + recipes = [] + for recipe in paprika_recipes(self.archive): + if "name" not in recipe: + continue + + recipe_model = self.clean_recipe_dictionary(recipe) + + if "photo_data" in recipe: + recipe_image_urls[slugify(recipe["name"])] = recipe["photo_data"] + + recipes.append(recipe_model) + + results = self.import_recipes_to_database(recipes) + + for slug, status in results: + if not status: + continue + + try: + # Images are stored as base64 encoded strings, so we need to decode them before importing. + image = io.BytesIO(base64.b64decode(recipe_image_urls[slug])) + with tempfile.NamedTemporaryFile(suffix=".jpeg") as temp_file: + temp_file.write(image.read()) + path = Path(temp_file.name) + import_image(path, slug) + except Exception as e: + self.logger.error(f"Failed to download image for {slug}: {e}") diff --git a/mealie/services/migrations/utils/database_helpers.py b/mealie/services/migrations/utils/database_helpers.py new file mode 100644 index 000000000..64de2e1eb --- /dev/null +++ b/mealie/services/migrations/utils/database_helpers.py @@ -0,0 +1,51 @@ +from typing import TypeVar + +from pydantic import BaseModel +from slugify import slugify +from sqlalchemy.orm import Session + +from mealie.db.data_access_layer.access_model_factory import AccessModel +from mealie.db.database import Database +from mealie.schema.recipe import RecipeCategory +from mealie.schema.recipe.recipe import RecipeTag + +T = TypeVar("T", bound=BaseModel) + + +class DatabaseMigrationHelpers: + def __init__(self, db: Database, session: Session, group_id: int, user_id: int) -> None: + self.group_id = group_id + self.user_id = user_id + self.session = session + self.db = db + + def _get_or_set_generic(self, accessor: AccessModel, items: list[str], out_model: T) -> list[T]: + """ + Utility model for getting or setting categories or tags. This will only work for those two cases. + + This is probably a bad implementation of this pattern. + """ + items_out = [] + + for item_name in items: + slug_lookup = slugify(item_name) + + item_model = accessor.get_one(slug_lookup, "slug", override_schema=out_model) + + if not item_model: + item_model = accessor.create( + out_model( + name=item_name, + slug=slug_lookup, + ) + ) + + items_out.append(item_model.dict()) + + return items_out + + def get_or_set_category(self, categories: list[str]) -> list[RecipeCategory]: + return self._get_or_set_generic(self.db.categories, categories, RecipeCategory) + + def get_or_set_tags(self, tags: list[str]) -> list[RecipeTag]: + return self._get_or_set_generic(self.db.tags, tags, RecipeTag) diff --git a/mealie/services/scraper/cleaner.py b/mealie/services/scraper/cleaner.py index 449d3a508..6938454c7 100644 --- a/mealie/services/scraper/cleaner.py +++ b/mealie/services/scraper/cleaner.py @@ -56,10 +56,20 @@ def clean_string(text: str) -> str: def category(category: str): + if isinstance(category, list) and len(category) > 0 and isinstance(category[0], dict): + # If the category is a list of dicts, it's probably from a migration + # validate that the required fields are present + valid = [] + for cat in category: + if "name" in cat and "slug" in cat: + valid.append(cat) + + return valid + if isinstance(category, str) and category != "": return [category] - else: - return [] + + return [] def clean_html(raw_html): @@ -201,7 +211,7 @@ def yield_amount(yld) -> str: def clean_time(time_entry): - if time_entry is None: + if time_entry is None or time_entry == "" or time_entry == " ": return None elif isinstance(time_entry, timedelta): return pretty_print_timedelta(time_entry) @@ -214,13 +224,11 @@ def clean_time(time_entry): return pretty_print_timedelta(time_delta_object) except ValueError: logger.error(f"Could not parse time_entry `{time_entry}`") + return str(time_entry) else: return str(time_entry) -# ! TODO: Cleanup Code Below - - def parse_duration(iso_duration): """Parses an ISO 8601 duration string into a datetime.timedelta instance. Args: @@ -253,8 +261,9 @@ def parse_duration(iso_duration): def pretty_print_timedelta(t: timedelta, max_components=None, max_decimal_places=2): """ Print a pretty string for a timedelta. - For example datetime.timedelta(days=2, seconds=17280) will be printed as '2 days 4 Hours 48 Minutes'. Setting max_components to e.g. 1 will change this to '2.2 days', where the - number of decimal points can also be set. + For example datetime.timedelta(days=2, seconds=17280) will be printed as '2 days 4 Hours 48 Minutes'. + Setting max_components to e.g. 1 will change this to '2.2 days', where the number of decimal + points can also be set. """ time_scale_names_dict = { timedelta(days=365): "year", diff --git a/tests/conftest.py b/tests/conftest.py index a596c7b3e..5a1bc757d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -6,8 +6,8 @@ from pytest import fixture from mealie.app import app from mealie.db.db_setup import SessionLocal, generate_session from mealie.db.init_db import main +from tests import data as test_data from tests.fixtures import * # noqa: F403 F401 -from tests.test_config import TEST_DATA main() @@ -35,9 +35,9 @@ def api_client(): @fixture(scope="session") def test_image_jpg(): - return TEST_DATA.joinpath("images", "test_image.jpg") + return test_data.images_test_image_1 @fixture(scope="session") def test_image_png(): - return TEST_DATA.joinpath("images", "test_image.png") + return test_data.images_test_image_2 diff --git a/tests/data/__init__.py b/tests/data/__init__.py new file mode 100644 index 000000000..df8c281b1 --- /dev/null +++ b/tests/data/__init__.py @@ -0,0 +1,60 @@ +from pathlib import Path + +CWD = Path(__file__).parent + + +migrations_paprika = CWD / "migrations/paprika.zip" + +migrations_chowdown = CWD / "migrations/chowdown.zip" + +migrations_mealie = CWD / "migrations/mealie.zip" + +migrations_nextcloud = CWD / "migrations/nextcloud.zip" + +images_test_image_1 = CWD / "images/test-image-1.jpg" + +images_test_image_2 = CWD / "images/test-image-2.png" + +html_sous_vide_smoked_beef_ribs = CWD / "html/sous-vide-smoked-beef-ribs.html" + +html_sous_vide_shrimp = CWD / "html/sous-vide-shrimp.html" + +html_jam_roly_poly_with_custard = CWD / "html/jam-roly-poly-with-custard.html" + +html_taiwanese_three_cup_chicken_san_bei_gi_recipe = CWD / "html/taiwanese-three-cup-chicken-san-bei-gi-recipe.html" + +html_detroit_style_pepperoni_pizza = CWD / "html/detroit-style-pepperoni-pizza.html" + +html_carottes_rapps_with_rice_and_sunflower_seeds = CWD / "html/carottes-rapps-with-rice-and-sunflower-seeds.html" + +html_schinken_kase_waffeln_ohne_viel_schnickschnack = CWD / "html/schinken-kase-waffeln-ohne-viel-schnickschnack.html" + +html_healthy_pasta_bake_60759 = CWD / "html/healthy-pasta-bake-60759.html" + +json_instant_pot_chicken_and_potatoes = CWD / "json/instant-pot-chicken-and-potatoes.json" + +json_jalapeno_popper_dip = CWD / "json/jalapeno-popper-dip.json" + +json_best_homemade_salsa_recipe = CWD / "json/best-homemade-salsa-recipe.json" + +json_how_to_make_instant_pot_spaghetti = CWD / "json/how-to-make-instant-pot-spaghetti.json" + +json_pizza_knoblauch_champignon_paprika_vegan_html = CWD / "json/pizza-knoblauch-champignon-paprika-vegan-html.json" + +json_bon_appetit = CWD / "json/bon-appetit.json" + +json_moroccan_skirt_steak_with_roasted_pepper_couscous = ( + CWD / "json/moroccan-skirt-steak-with-roasted-pepper-couscous.json" +) + +json_microwave_sweet_potatoes_04783 = CWD / "json/microwave-sweet-potatoes-04783.json" + +json_dairy_free_impossible_pumpkin_pie = CWD / "json/dairy-free-impossible-pumpkin-pie.json" + +json_chunky_apple_cake = CWD / "json/chunky-apple-cake.json" + +json_blue_cheese_stuffed_turkey_meatballs_with_raspberry_balsamic_glaze_2 = ( + CWD / "json/blue-cheese-stuffed-turkey-meatballs-with-raspberry-balsamic-glaze-2.json" +) + +json_instant_pot_kerala_vegetable_stew = CWD / "json/instant-pot-kerala-vegetable-stew.json" diff --git a/tests/data/html-raw/carottes-rapps-with-rice-and-sunflower-seeds.html b/tests/data/html/carottes-rapps-with-rice-and-sunflower-seeds.html similarity index 100% rename from tests/data/html-raw/carottes-rapps-with-rice-and-sunflower-seeds.html rename to tests/data/html/carottes-rapps-with-rice-and-sunflower-seeds.html diff --git a/tests/data/html-raw/healthy_pasta_bake_60759.html b/tests/data/html/healthy-pasta-bake-60759.html similarity index 100% rename from tests/data/html-raw/healthy_pasta_bake_60759.html rename to tests/data/html/healthy-pasta-bake-60759.html diff --git a/tests/data/images/test_image.jpg b/tests/data/images/test-image-1.jpg similarity index 100% rename from tests/data/images/test_image.jpg rename to tests/data/images/test-image-1.jpg diff --git a/tests/data/images/test_image.png b/tests/data/images/test-image-2.png similarity index 100% rename from tests/data/images/test_image.png rename to tests/data/images/test-image-2.png diff --git a/tests/data/recipes-raw/best-homemade-salsa-recipe.json b/tests/data/json/best-homemade-salsa-recipe.json similarity index 100% rename from tests/data/recipes-raw/best-homemade-salsa-recipe.json rename to tests/data/json/best-homemade-salsa-recipe.json diff --git a/tests/data/recipes-raw/blue-cheese-stuffed-turkey-meatballs-with-raspberry-balsamic-glaze-2.json b/tests/data/json/blue-cheese-stuffed-turkey-meatballs-with-raspberry-balsamic-glaze-2.json similarity index 100% rename from tests/data/recipes-raw/blue-cheese-stuffed-turkey-meatballs-with-raspberry-balsamic-glaze-2.json rename to tests/data/json/blue-cheese-stuffed-turkey-meatballs-with-raspberry-balsamic-glaze-2.json diff --git a/tests/data/recipes-raw/bon_appetit.json b/tests/data/json/bon-appetit.json similarity index 100% rename from tests/data/recipes-raw/bon_appetit.json rename to tests/data/json/bon-appetit.json diff --git a/tests/data/recipes-raw/chunky-apple-cake.json b/tests/data/json/chunky-apple-cake.json similarity index 100% rename from tests/data/recipes-raw/chunky-apple-cake.json rename to tests/data/json/chunky-apple-cake.json diff --git a/tests/data/recipes-raw/dairy-free-impossible-pumpkin-pie.json b/tests/data/json/dairy-free-impossible-pumpkin-pie.json similarity index 100% rename from tests/data/recipes-raw/dairy-free-impossible-pumpkin-pie.json rename to tests/data/json/dairy-free-impossible-pumpkin-pie.json diff --git a/tests/data/recipes-raw/how-to-make-instant-pot-spaghetti.json b/tests/data/json/how-to-make-instant-pot-spaghetti.json similarity index 100% rename from tests/data/recipes-raw/how-to-make-instant-pot-spaghetti.json rename to tests/data/json/how-to-make-instant-pot-spaghetti.json diff --git a/tests/data/recipes-raw/instant-pot-chicken-and-potatoes.json b/tests/data/json/instant-pot-chicken-and-potatoes.json similarity index 100% rename from tests/data/recipes-raw/instant-pot-chicken-and-potatoes.json rename to tests/data/json/instant-pot-chicken-and-potatoes.json diff --git a/tests/data/recipes-raw/instant-pot-kerala-vegetable-stew.json b/tests/data/json/instant-pot-kerala-vegetable-stew.json similarity index 100% rename from tests/data/recipes-raw/instant-pot-kerala-vegetable-stew.json rename to tests/data/json/instant-pot-kerala-vegetable-stew.json diff --git a/tests/data/recipes-raw/jalapeno-popper-dip.json b/tests/data/json/jalapeno-popper-dip.json similarity index 100% rename from tests/data/recipes-raw/jalapeno-popper-dip.json rename to tests/data/json/jalapeno-popper-dip.json diff --git a/tests/data/recipes-raw/microwave_sweet_potatoes_04783.json b/tests/data/json/microwave-sweet-potatoes-04783.json similarity index 100% rename from tests/data/recipes-raw/microwave_sweet_potatoes_04783.json rename to tests/data/json/microwave-sweet-potatoes-04783.json diff --git a/tests/data/recipes-raw/moroccan-skirt-steak-with-roasted-pepper-couscous.json b/tests/data/json/moroccan-skirt-steak-with-roasted-pepper-couscous.json similarity index 100% rename from tests/data/recipes-raw/moroccan-skirt-steak-with-roasted-pepper-couscous.json rename to tests/data/json/moroccan-skirt-steak-with-roasted-pepper-couscous.json diff --git a/tests/data/recipes-raw/Pizza-Knoblauch-Champignon-Paprika-vegan.html.json b/tests/data/json/pizza-knoblauch-champignon-paprika-vegan-html.json similarity index 100% rename from tests/data/recipes-raw/Pizza-Knoblauch-Champignon-Paprika-vegan.html.json rename to tests/data/json/pizza-knoblauch-champignon-paprika-vegan-html.json diff --git a/tests/data/migrations/chowdown/test_chowdown-gh-pages.zip b/tests/data/migrations/chowdown.zip similarity index 100% rename from tests/data/migrations/chowdown/test_chowdown-gh-pages.zip rename to tests/data/migrations/chowdown.zip diff --git a/tests/data/migrations/mealie.zip b/tests/data/migrations/mealie.zip new file mode 100644 index 000000000..1a208813d Binary files /dev/null and b/tests/data/migrations/mealie.zip differ diff --git a/tests/data/migrations/nextcloud/nextcloud.zip b/tests/data/migrations/nextcloud.zip similarity index 100% rename from tests/data/migrations/nextcloud/nextcloud.zip rename to tests/data/migrations/nextcloud.zip diff --git a/tests/data/migrations/nextcloud/Air Fryer Shrimp/full.jpg b/tests/data/migrations/nextcloud/Air Fryer Shrimp/full.jpg deleted file mode 100644 index 840f88310..000000000 Binary files a/tests/data/migrations/nextcloud/Air Fryer Shrimp/full.jpg and /dev/null differ diff --git a/tests/data/migrations/nextcloud/Air Fryer Shrimp/recipe.json b/tests/data/migrations/nextcloud/Air Fryer Shrimp/recipe.json deleted file mode 100644 index f5bd58f83..000000000 --- a/tests/data/migrations/nextcloud/Air Fryer Shrimp/recipe.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "@context": "http:\/\/schema.org", - "@type": "Recipe", - "name": "Air Fryer Shrimp", - "author": { - "@type": "Person", - "name": "Anna" - }, - "description": "These Air Fryer Shrimp are plump, juicy and perfectly seasoned! This healthy dish is ready in just 8 minutes and requires pantry staples to make it.", - "datePublished": "2020-07-13T16:48:25+00:00", - "image": "https:\/\/www.crunchycreamysweet.com\/wp-content\/uploads\/2020\/07\/air-fryer-shrimp-A-480x270.jpg", - "recipeYield": 4, - "prepTime": "PT0H15M", - "cookTime": "PT0H8M", - "totalTime": "PT0H23M", - "recipeIngredient": [ - "1 lb shrimp", - "2 teaspoons olive oil", - "\u00bd teaspoon garlic powder", - "\u00bc teaspoon paprika", - "\u00bd teaspoon Italian seasoning", - "\u00bd teaspoon salt", - "\u00bc teaspoon black pepper" - ], - "recipeInstructions": [ - "Cleaning the shrimp by removing shells and veins. Run under tap water, then pat dry with paper towel.", - "Mix oil with seasoning in a small bowl.", - "Brush shrimp with seasoning mixture on both sides.", - "Arrange shrimp in air fryer basket or rack, in a single layer.", - "Cook at 400 degrees F for 8 minutes (no need to turn them).", - "Serve." - ], - "aggregateRating": { - "@type": "AggregateRating", - "ratingValue": "5", - "ratingCount": "4" - }, - "recipeCategory": "Main Course", - "recipeCuisine": [ - "American" - ], - "keywords": "air fryer shrimp", - "nutrition": { - "@type": "NutritionInformation", - "calories": "134 kcal", - "carbohydrateContent": "1 g", - "proteinContent": "23 g", - "fatContent": "4 g", - "saturatedFatContent": "1 g", - "cholesterolContent": "286 mg", - "sodiumContent": "1172 mg", - "fiberContent": "1 g", - "sugarContent": "1 g", - "servingSize": "1 serving" - }, - "@id": "https:\/\/www.crunchycreamysweet.com\/air-fryer-shrimp\/#recipe", - "isPartOf": { - "@id": "https:\/\/www.crunchycreamysweet.com\/air-fryer-shrimp\/#article" - }, - "mainEntityOfPage": "https:\/\/www.crunchycreamysweet.com\/air-fryer-shrimp\/#webpage", - "tool": [], - "url": "https:\/\/www.crunchycreamysweet.com\/air-fryer-shrimp\/" -} \ No newline at end of file diff --git a/tests/data/migrations/nextcloud/Air Fryer Shrimp/thumb.jpg b/tests/data/migrations/nextcloud/Air Fryer Shrimp/thumb.jpg deleted file mode 100644 index 2c3d89c00..000000000 Binary files a/tests/data/migrations/nextcloud/Air Fryer Shrimp/thumb.jpg and /dev/null differ diff --git a/tests/data/migrations/nextcloud/Chicken Parmigiana/full.jpg b/tests/data/migrations/nextcloud/Chicken Parmigiana/full.jpg deleted file mode 100644 index 360275989..000000000 Binary files a/tests/data/migrations/nextcloud/Chicken Parmigiana/full.jpg and /dev/null differ diff --git a/tests/data/migrations/nextcloud/Chicken Parmigiana/recipe.json b/tests/data/migrations/nextcloud/Chicken Parmigiana/recipe.json deleted file mode 100644 index fcce8ce64..000000000 --- a/tests/data/migrations/nextcloud/Chicken Parmigiana/recipe.json +++ /dev/null @@ -1,259 +0,0 @@ -{ - "@context": "http:\/\/schema.org", - "@type": "Recipe", - "mainEntityOfPage": "https:\/\/www.allrecipes.com\/recipe\/8975\/chicken-parmigiana\/", - "name": "Chicken Parmigiana", - "image": "https:\/\/imagesvc.meredithcorp.io\/v3\/mm\/image?url=https%3A%2F%2Fimages.media-allrecipes.com%2Fuserphotos%2F10037.jpg", - "datePublished": "1999-04-27T12:40:19.000Z", - "description": "This is a very nice dinner for two. Serve it with your favorite pasta and tossed greens.", - "prepTime": "PT0H30M", - "cookTime": "PT1H0M", - "totalTime": "PT1H30M", - "recipeYield": 2, - "recipeIngredient": [ - "1 egg, beaten", - "2 ounces dry bread crumbs", - "2 skinless, boneless chicken breast halves", - "\u00be (16 ounce) jar spaghetti sauce", - "2 ounces shredded mozzarella cheese", - "\u00bc cup grated Parmesan cheese" - ], - "recipeInstructions": [ - "Preheat oven to 350 degrees F (175 degrees C). Lightly grease a medium baking sheet.\n", - "Pour egg into a small shallow bowl. Place bread crumbs in a separate shallow bowl. Dip chicken into egg, then into the bread crumbs. Place coated chicken on the prepared baking sheet and bake in the preheated oven for 40 minutes, or until no longer pink and juices run clear.\n", - "Pour 1\/2 of the spaghetti sauce into a 7x11 inch baking dish. Place chicken over sauce, and cover with remaining sauce. Sprinkle mozzarella and Parmesan cheeses on top and return to the preheated oven for 20 minutes.\n" - ], - "recipeCategory": "World Cuisine Recipes", - "recipeCuisine": [], - "author": [ - { - "@type": "Person", - "name": "Candy" - } - ], - "aggregateRating": { - "@type": "AggregateRating", - "ratingValue": 4.580034423407917, - "ratingCount": 1743, - "itemReviewed": "Chicken Parmigiana", - "bestRating": "5", - "worstRating": "1" - }, - "nutrition": { - "@type": "NutritionInformation", - "calories": "528.3 calories", - "carbohydrateContent": "44.9 g", - "cholesterolContent": "184.1 mg", - "fatContent": "18.3 g", - "fiberContent": "5.6 g", - "proteinContent": "43.5 g", - "saturatedFatContent": "7.6 g", - "servingSize": null, - "sodiumContent": "1309.5 mg", - "sugarContent": "17.2 g", - "transFatContent": null, - "unsaturatedFatContent": null - }, - "review": [ - { - "@type": "Review", - "datePublished": "2004-02-10T10:18:54.927Z", - "reviewBody": "This is a DELICIOUS basic recipe. I have been doing a similar one for years. I also, prefer adding a few more spices TO THE BREAD CRUMBS,like basil, oregano, garlic powder, salt, fresh cracked pepper and onion powder, and a few TBSP of the parmensan cheese;not only ON IT later. For some reason these spices (added separately) are good, but we don't like with an pre-mix of \"Italian\"spice. It seems to taste a little \"soapy\". Not sure which spice does that to it.? Some suggested to \"double dip\" in bread crumbs;if you do, you should really LIKE a heavy battering. It was too thick for our tastes(esp. since you bake in the sauce; to me,the bottom gets a little mushy, and it just adds extra fat and calories). I also use a cookie cooling \"RACK\" SET ON TOP of a baking sheet, to bake the chicken on instead of just on the cookie sheet pan. It comes out much crisper; letting air get to the BOTTOM of the chicken,also. Also,I wait to spoon the SECOND 1\/2 of the sauce UNTIL SERVING, the chicken will stay crisper,(even with the cheese on top). Obviously, we like the chicken on the crisp side (but we don't want to deep fry).\r\nFor company, put the chicken (with just the cheese baked on top) ON TOP of a small mound of spaghetti and sauce,or any pasta; It makes for a delicious looking presentation. A side salad with some sort of CREAMY dressing seems to compliment the red sauce, and completes the meal wonderfully. We get cravings for this one about 2c a month!", - "reviewRating": { - "@type": "Rating", - "worstRating": "1", - "bestRating": "5", - "ratingValue": 4 - }, - "author": { - "@type": "Person", - "name": "somethingdifferentagain?!", - "image": null, - "sameAs": "https:\/\/www.allrecipes.com\/cook\/342976\/" - } - }, - { - "@type": "Review", - "datePublished": "2004-01-23T16:37:02.013Z", - "reviewBody": "This was an extremely easy, very tasty recipe. As many others suggested, I only put sauce on the bottom of the chicken and then spooned a little over the top when serving. I think the recipe could be improved, though, by (1) pounding the chicken to a uniform thickness and (2) by spicing up the bread crumbs. I used Italian bread crumbs but next time will sprinkle pepper on the chicken before dredging through the crumbs, and I also plan to add more Italian seasoning and maybe a little parmesan to the crumbs. Both these steps, in my opinion, would take this from a really good recipe to an excellent dish!", - "reviewRating": { - "@type": "Rating", - "worstRating": "1", - "bestRating": "5", - "ratingValue": 4 - }, - "author": { - "@type": "Person", - "name": "JBAGNALL", - "image": null, - "sameAs": "https:\/\/www.allrecipes.com\/cook\/642772\/" - } - }, - { - "@type": "Review", - "datePublished": "2005-11-19T20:22:40.53Z", - "reviewBody": "I BRINED my chicken in 4 cups water , 1\/2 cup kosher salt (1\/4 table salt) \u00bd cup sugar for 30 minutes. No need to brine if you are using quick frozen chicken that has been enhanced. Kosher chicken is prebrined. Brining=juicy chicken. Took brined chicken, cut off thin edges, pounded out & shook chicken w\/flour (preflouring allows bread crumbs to stick) in a Ziploc-letting floured chicken sit for 5 min. I heated 6 TBS vegetable oil till it shimmered & then added 2 TBS butter to my pan, reserving half of this mixture for my second batch. Bread crumb mixture: I use \u00bd cup seasoned bread crumbs(same as 2 ounces), \u00bd cup grated parmesan( double what recipe calls for), 1tsp. Mrs. Dash Garlic and Herb, \u00bd tsp. garlic powder, \u00bd tsp, onion powder, \u00bd tsp. Italian seasoning & a pinch of pepper. Took pre-floured chicken, coated it with egg mixture, then dipped in bread crumbs & FRIED the chicken to a medium golden brown. Shook some parmesan on them right away when done frying to absorb any oil. Side-by side I plated plain spaghetti noodles & cutlets, w\/2 TBSP sauce on cutlet & desired amount of sauce on pasta, covered in cheese & baked each individual plate till cheese melted, serving them straight out of the oven. \r\nThe reviews on this were probably the best I have ever gotten, I used to work in an Italian Restaurant owned by NY Italians & have picked up some techniques. My Fettuccine Alfredo used to be my husband favorite dish, after last night he told me he has a new favorite. \r\n", - "reviewRating": { - "@type": "Rating", - "worstRating": "1", - "bestRating": "5", - "ratingValue": 5 - }, - "author": { - "@type": "Person", - "name": "KC MARTEL", - "image": null, - "sameAs": "https:\/\/www.allrecipes.com\/cook\/526291\/" - } - }, - { - "@type": "Review", - "datePublished": "2003-10-22T15:32:26.607Z", - "reviewBody": "After several Chicken Parm recipes THIS is THE ONE:-) I've finally found one that we all love! It's simple and it's darned good:-) I will definately make this recipe again and again; thanks so much:-)", - "reviewRating": { - "@type": "Rating", - "worstRating": "1", - "bestRating": "5", - "ratingValue": 5 - }, - "author": { - "@type": "Person", - "name": "STARCHILD1166", - "image": null, - "sameAs": "https:\/\/www.allrecipes.com\/cook\/736533\/" - } - }, - { - "@type": "Review", - "datePublished": "2003-11-14T16:55:26.39Z", - "reviewBody": "This chicken was so easy to make and turned out excellent! Used Best Marinara Sauce Yet (found here as well)instead of regular spaghetti sauce. This added even more flavor.", - "reviewRating": { - "@type": "Rating", - "worstRating": "1", - "bestRating": "5", - "ratingValue": 5 - }, - "author": { - "@type": "Person", - "name": "Alison", - "image": null, - "sameAs": "https:\/\/www.allrecipes.com\/cook\/516223\/" - } - }, - { - "@type": "Review", - "datePublished": "2003-01-23T04:38:19.873Z", - "reviewBody": "I REALLY liked this recipe. I made my own spaghetti sauce and used parmesan reggiano. I also skipped dipping the breasts in egg as I thought it was unnecessary and it was. Cooking temp. and time are accurate. Even my fussy fiance liked this. I'll definitely make this again.", - "reviewRating": { - "@type": "Rating", - "worstRating": "1", - "bestRating": "5", - "ratingValue": 4 - }, - "author": { - "@type": "Person", - "name": "CSANDST1", - "image": null, - "sameAs": "https:\/\/www.allrecipes.com\/cook\/115553\/" - } - }, - { - "@type": "Review", - "datePublished": "2003-08-05T20:26:00.81Z", - "reviewBody": "Wow! This was really tasty and simple. Something quick to make when you can't spend too much time figuring out what's for dinner. Also great on a toasted roll\/hero as a sandwich. I varied the recipe a little by adding some parmesan cheese (big cheese lover that I am!), garlic powder, onion powder and some salt into the bread crumbs and then mixing it up before breading the chicken with it. Also added a little salt to the beaten egg to make sure the chicken wouldn't end up bland, but that's just my preference. In response to the one reviewer who wanted thicker breading, what I did was double dip the chicken - coat first with the bread crumbs, then dip into the beaten egg and re-coat with breadcrumbs before actually baking (this would require some more breadcrumbs and probably another egg). Excellent recipe! =]", - "reviewRating": { - "@type": "Rating", - "worstRating": "1", - "bestRating": "5", - "ratingValue": 5 - }, - "author": { - "@type": "Person", - "name": "LIZCHAO74", - "image": null, - "sameAs": "https:\/\/www.allrecipes.com\/cook\/511187\/" - } - }, - { - "@type": "Review", - "datePublished": "2003-07-23T07:53:37.18Z", - "reviewBody": "Wonderful chicken recipe! I have made this several times. One night we were craving it and I didn't have any bottled spaghetti sauce. I poured a 14 ounce can of tomato sauce in a microwave bowl added 2t Italian Seasoning and 1t of garlic powder cooked on high for 6 minutes and ended up with a rich thick sauce for the chicken.", - "reviewRating": { - "@type": "Rating", - "worstRating": "1", - "bestRating": "5", - "ratingValue": 4 - }, - "author": { - "@type": "Person", - "name": "MAGGIE MCGUIRE", - "image": null, - "sameAs": "https:\/\/www.allrecipes.com\/cook\/392086\/" - } - }, - { - "@type": "Review", - "datePublished": "2008-06-10T21:54:38.893Z", - "reviewBody": "This is gonna be one of those it\u2019s a good recipe when you completely change it reviews. I did originally follow the recipe and the chicken tasted like it had been in breaded in cardboard. It just was not appetizing. However there is a great breaded chicken recipe on this site, garlic chicken. Made this simple and easy and oh so TASTY. I got great reviews. Here is what I did. Took \u00bc cup olive oil with 3 cloves garlic crushed and heated in microwave for 30 sec. Then coated the chicken in the oil and dipped in a mixture of \u00bd Italian seasoned bread crumbs and \u00bd parmesan cheese (double coat if u like thick breading). Cooked in oven at 325 for 20min (on a foil covered cookie sheet to make clean up easy). Set them in a casserole dish on top of about \u00bd a jar of spaghetti sauce for 3 chicken breast. Covered the breast with slices of mozzarella cheese and baked for another 20-25 minutes. Top with parmesan cheese. This turned out really really yummy and smells sooo good while it\u2019s cooking. ", - "reviewRating": { - "@type": "Rating", - "worstRating": "1", - "bestRating": "5", - "ratingValue": 4 - }, - "author": { - "@type": "Person", - "name": "ANGEL.9", - "image": null, - "sameAs": "https:\/\/www.allrecipes.com\/cook\/218599\/" - } - }, - { - "@type": "Review", - "datePublished": "2006-02-02T19:05:24.607Z", - "reviewBody": "Check out \"Tomato Chicken Parmesan\" on this site for a truly fabulous chicken parm recipe. Every time I make that one people say its the best chicken parm they every had. No matter what kind you make though always pound your chicken breasts it will help immensely keeping the chicken tender and moist.", - "reviewRating": { - "@type": "Rating", - "worstRating": "1", - "bestRating": "5", - "ratingValue": 3 - }, - "author": { - "@type": "Person", - "name": "MomSavedbyGrace", - "image": null, - "sameAs": "https:\/\/www.allrecipes.com\/cook\/1366670\/" - } - } - ], - "video": { - "@context": "http:\/\/schema.org", - "@type": "VideoObject", - "name": "Chicken Parmigiana", - "description": "Make this quick and easy version of chicken Parmigiana.", - "uploadDate": "2012-05-23T22:01:40.476Z", - "duration": "PT2M18.43S", - "thumbnailUrl": "https:\/\/imagesvc.meredithcorp.io\/v3\/mm\/image?url=https%3A%2F%2Fcf-images.us-east-1.prod.boltdns.net%2Fv1%2Fstatic%2F1033249144001%2F15c9e37d-979a-4c2c-a35d-fc3f436b0047%2F6b7f7749-9989-4707-971e-8578e60c0670%2F160x90%2Fmatch%2Fimage.jpg", - "publisher": { - "@type": "Organization", - "name": "Allrecipes", - "url": "https:\/\/www.allrecipes.com", - "logo": { - "@type": "ImageObject", - "url": "https:\/\/www.allrecipes.com\/img\/logo.png", - "width": 209, - "height": 60 - }, - "sameAs": [ - "https:\/\/www.facebook.com\/allrecipes", - "https:\/\/twitter.com\/Allrecipes", - "https:\/\/www.pinterest.com\/allrecipes\/", - "https:\/\/www.instagram.com\/allrecipes\/" - ] - }, - "embedUrl": "https:\/\/players.brightcove.net\/1033249144001\/default_default\/index.html?videoId=1653498713001" - }, - "keywords": "", - "tool": [], - "url": "https:\/\/www.allrecipes.com\/recipe\/8975\/chicken-parmigiana\/" -} \ No newline at end of file diff --git a/tests/data/migrations/nextcloud/Chicken Parmigiana/thumb.jpg b/tests/data/migrations/nextcloud/Chicken Parmigiana/thumb.jpg deleted file mode 100644 index f74eca92e..000000000 Binary files a/tests/data/migrations/nextcloud/Chicken Parmigiana/thumb.jpg and /dev/null differ diff --git a/tests/data/migrations/nextcloud/Skillet Shepherd's Pie/recipe.json b/tests/data/migrations/nextcloud/Skillet Shepherd's Pie/recipe.json deleted file mode 100644 index ff84b9e87..000000000 --- a/tests/data/migrations/nextcloud/Skillet Shepherd's Pie/recipe.json +++ /dev/null @@ -1,89 +0,0 @@ -{ - "@context": "http:\/\/schema.org", - "@type": "Recipe", - "name": "Skillet Shepherd's Pie", - "author": { - "@type": "Person", - "name": "Joanna Cismaru" - }, - "description": "This Skillet Shepherd's Pie recipe, also known as cottage pie, is loaded with flavorful beef and veggies, topped with fluffy and creamy mashed potatoes, then baked to perfection!", - "datePublished": "2019-03-16T20:15:47+00:00", - "image": "https:\/\/www.jocooks.com\/wp-content\/uploads\/2016\/12\/skillet-shepherds-pie-1-2-480x270.jpg", - "video": { - "name": "Skillet Shepherd's Pie", - "description": "This skillet shepherd\u2019s pie is loaded with flavorful beef and veggies then topped with fluffy and creamy mashed potatoes, then baked to perfection!", - "thumbnailUrl": "https:\/\/content.jwplatform.com\/thumbs\/HGr48vds-720.jpg", - "contentUrl": "https:\/\/content.jwplatform.com\/videos\/HGr48vds.mp4", - "uploadDate": "2018-03-08T16:13:05.000Z", - "@type": "VideoObject" - }, - "recipeYield": 1, - "prepTime": "PT0H15M", - "cookTime": "PT1H10M", - "totalTime": "PT1H25M", - "recipeIngredient": [ - "1 tbsp olive oil", - "1 1\/4 lb ground beef (lean)", - "1\/2 tsp salt (or to taste)", - "1\/2 tsp pepper (or to taste)", - "1 large onion (chopped)", - "1 clove garlic (minced)", - "1\/2 tsp red pepper flakes", - "2 tbsp Worcestershire sauce", - "1.9 oz onion soup mix (I used Knorr, 55g pkg)", - "1 cup beef broth (low sodium)", - "2 cups frozen veggies (I used mix of peas, carrots, green beans and corn)", - "6 large potatoes (peeled and cut into cubes)", - "4 tbsp butter (softened)", - "2\/3 cup milk", - "1\/4 cup Parmesan cheese", - "1\/2 tsp salt (or to taste)", - "1\/2 tsp white pepper (or to taste)", - "1 tbsp parsley (fresh, for garnish)" - ], - "recipeInstructions": [ - "Boil the potatoes: Start by first cooking the potatoes in boiling water for about 15 minutes or until fork tender. While the potatoes are cooking, you can prepare the meat mixture.", - "Prepare the meat mixture: Heat the oil in a large skillet over medium heat. Add the ground beef to the skillet, season it with the salt and pepper and cook it for abut 5 minutes or until it's no longer pink, breaking it up as you go along.", - "Add the onion and garlic and cook for 3 more minutes until the onion softens and becomes translucent. Add the pepper flakes, Worcestershire sauce, onion soup mix, beef broth and stir. Stir in the frozen veggies and cook for a couple more minutes. Set aside.", - "Preheat the oven 350 F degrees.", - "Prepare the mashed potatoes: Drain the potatoes then add them to a large bowl. Add in the butter and using a potato masher, mash until smooth. Add the milk, Parmesan cheese, salt pepper and mash a bit a more until smooth.", - "Finish assembling the shepherd's pie: Spread the potatoes over the meat and smooth with a spoon. Take a fork and rough up the top a bit and garnish with a bit of parsley.", - "Bake: Place the skillet on a baking sheet, then place it in the oven and bake for 40 minutes until golden brown on top.", - "Garnish with more parsley and pepper and serve warm." - ], - "aggregateRating": { - "@type": "AggregateRating", - "ratingValue": "4.48", - "ratingCount": "505" - }, - "recipeCategory": "Main Course", - "recipeCuisine": [ - "American" - ], - "keywords": "cottage pie,shepherd's pie,skillet shepherd's pie", - "nutrition": { - "@type": "NutritionInformation", - "calories": "252 kcal", - "carbohydrateContent": "14 g", - "proteinContent": "19 g", - "fatContent": "12 g", - "saturatedFatContent": "6 g", - "cholesterolContent": "63 mg", - "sodiumContent": "1165 mg", - "fiberContent": "2 g", - "sugarContent": "2 g", - "servingSize": "1 serving" - }, - "@id": "https:\/\/www.jocooks.com\/recipes\/skillet-shepherds-pie\/#recipe", - "isPartOf": { - "@id": "https:\/\/www.jocooks.com\/recipes\/skillet-shepherds-pie\/#article" - }, - "mainEntityOfPage": "https:\/\/www.jocooks.com\/recipes\/skillet-shepherds-pie\/#webpage", - "url": "https:\/\/www.jocooks.com\/recipes\/skillet-shepherds-pie\/", - "id": "4485", - "dateCreated": "0", - "dateModified": "1607461134", - "printImage": "false", - "imageUrl": "\/nextcloud\/index.php\/apps\/cookbook\/recipes\/4485\/image?size=full", - "tool": [] -} \ No newline at end of file diff --git a/tests/data/migrations/paprika.zip b/tests/data/migrations/paprika.zip new file mode 100644 index 000000000..cf0548205 Binary files /dev/null and b/tests/data/migrations/paprika.zip differ diff --git a/tests/data/nextcloud_recipes/Air Fryer Shrimp/recipe.json b/tests/data/nextcloud_recipes/Air Fryer Shrimp/recipe.json deleted file mode 100644 index f5bd58f83..000000000 --- a/tests/data/nextcloud_recipes/Air Fryer Shrimp/recipe.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "@context": "http:\/\/schema.org", - "@type": "Recipe", - "name": "Air Fryer Shrimp", - "author": { - "@type": "Person", - "name": "Anna" - }, - "description": "These Air Fryer Shrimp are plump, juicy and perfectly seasoned! This healthy dish is ready in just 8 minutes and requires pantry staples to make it.", - "datePublished": "2020-07-13T16:48:25+00:00", - "image": "https:\/\/www.crunchycreamysweet.com\/wp-content\/uploads\/2020\/07\/air-fryer-shrimp-A-480x270.jpg", - "recipeYield": 4, - "prepTime": "PT0H15M", - "cookTime": "PT0H8M", - "totalTime": "PT0H23M", - "recipeIngredient": [ - "1 lb shrimp", - "2 teaspoons olive oil", - "\u00bd teaspoon garlic powder", - "\u00bc teaspoon paprika", - "\u00bd teaspoon Italian seasoning", - "\u00bd teaspoon salt", - "\u00bc teaspoon black pepper" - ], - "recipeInstructions": [ - "Cleaning the shrimp by removing shells and veins. Run under tap water, then pat dry with paper towel.", - "Mix oil with seasoning in a small bowl.", - "Brush shrimp with seasoning mixture on both sides.", - "Arrange shrimp in air fryer basket or rack, in a single layer.", - "Cook at 400 degrees F for 8 minutes (no need to turn them).", - "Serve." - ], - "aggregateRating": { - "@type": "AggregateRating", - "ratingValue": "5", - "ratingCount": "4" - }, - "recipeCategory": "Main Course", - "recipeCuisine": [ - "American" - ], - "keywords": "air fryer shrimp", - "nutrition": { - "@type": "NutritionInformation", - "calories": "134 kcal", - "carbohydrateContent": "1 g", - "proteinContent": "23 g", - "fatContent": "4 g", - "saturatedFatContent": "1 g", - "cholesterolContent": "286 mg", - "sodiumContent": "1172 mg", - "fiberContent": "1 g", - "sugarContent": "1 g", - "servingSize": "1 serving" - }, - "@id": "https:\/\/www.crunchycreamysweet.com\/air-fryer-shrimp\/#recipe", - "isPartOf": { - "@id": "https:\/\/www.crunchycreamysweet.com\/air-fryer-shrimp\/#article" - }, - "mainEntityOfPage": "https:\/\/www.crunchycreamysweet.com\/air-fryer-shrimp\/#webpage", - "tool": [], - "url": "https:\/\/www.crunchycreamysweet.com\/air-fryer-shrimp\/" -} \ No newline at end of file diff --git a/tests/data/nextcloud_recipes/Air Fryer Shrimp/thumb.jpg b/tests/data/nextcloud_recipes/Air Fryer Shrimp/thumb.jpg deleted file mode 100644 index 2c3d89c00..000000000 Binary files a/tests/data/nextcloud_recipes/Air Fryer Shrimp/thumb.jpg and /dev/null differ diff --git a/tests/data/nextcloud_recipes/Chicken Parmigiana/recipe.json b/tests/data/nextcloud_recipes/Chicken Parmigiana/recipe.json deleted file mode 100644 index fcce8ce64..000000000 --- a/tests/data/nextcloud_recipes/Chicken Parmigiana/recipe.json +++ /dev/null @@ -1,259 +0,0 @@ -{ - "@context": "http:\/\/schema.org", - "@type": "Recipe", - "mainEntityOfPage": "https:\/\/www.allrecipes.com\/recipe\/8975\/chicken-parmigiana\/", - "name": "Chicken Parmigiana", - "image": "https:\/\/imagesvc.meredithcorp.io\/v3\/mm\/image?url=https%3A%2F%2Fimages.media-allrecipes.com%2Fuserphotos%2F10037.jpg", - "datePublished": "1999-04-27T12:40:19.000Z", - "description": "This is a very nice dinner for two. Serve it with your favorite pasta and tossed greens.", - "prepTime": "PT0H30M", - "cookTime": "PT1H0M", - "totalTime": "PT1H30M", - "recipeYield": 2, - "recipeIngredient": [ - "1 egg, beaten", - "2 ounces dry bread crumbs", - "2 skinless, boneless chicken breast halves", - "\u00be (16 ounce) jar spaghetti sauce", - "2 ounces shredded mozzarella cheese", - "\u00bc cup grated Parmesan cheese" - ], - "recipeInstructions": [ - "Preheat oven to 350 degrees F (175 degrees C). Lightly grease a medium baking sheet.\n", - "Pour egg into a small shallow bowl. Place bread crumbs in a separate shallow bowl. Dip chicken into egg, then into the bread crumbs. Place coated chicken on the prepared baking sheet and bake in the preheated oven for 40 minutes, or until no longer pink and juices run clear.\n", - "Pour 1\/2 of the spaghetti sauce into a 7x11 inch baking dish. Place chicken over sauce, and cover with remaining sauce. Sprinkle mozzarella and Parmesan cheeses on top and return to the preheated oven for 20 minutes.\n" - ], - "recipeCategory": "World Cuisine Recipes", - "recipeCuisine": [], - "author": [ - { - "@type": "Person", - "name": "Candy" - } - ], - "aggregateRating": { - "@type": "AggregateRating", - "ratingValue": 4.580034423407917, - "ratingCount": 1743, - "itemReviewed": "Chicken Parmigiana", - "bestRating": "5", - "worstRating": "1" - }, - "nutrition": { - "@type": "NutritionInformation", - "calories": "528.3 calories", - "carbohydrateContent": "44.9 g", - "cholesterolContent": "184.1 mg", - "fatContent": "18.3 g", - "fiberContent": "5.6 g", - "proteinContent": "43.5 g", - "saturatedFatContent": "7.6 g", - "servingSize": null, - "sodiumContent": "1309.5 mg", - "sugarContent": "17.2 g", - "transFatContent": null, - "unsaturatedFatContent": null - }, - "review": [ - { - "@type": "Review", - "datePublished": "2004-02-10T10:18:54.927Z", - "reviewBody": "This is a DELICIOUS basic recipe. I have been doing a similar one for years. I also, prefer adding a few more spices TO THE BREAD CRUMBS,like basil, oregano, garlic powder, salt, fresh cracked pepper and onion powder, and a few TBSP of the parmensan cheese;not only ON IT later. For some reason these spices (added separately) are good, but we don't like with an pre-mix of \"Italian\"spice. It seems to taste a little \"soapy\". Not sure which spice does that to it.? Some suggested to \"double dip\" in bread crumbs;if you do, you should really LIKE a heavy battering. It was too thick for our tastes(esp. since you bake in the sauce; to me,the bottom gets a little mushy, and it just adds extra fat and calories). I also use a cookie cooling \"RACK\" SET ON TOP of a baking sheet, to bake the chicken on instead of just on the cookie sheet pan. It comes out much crisper; letting air get to the BOTTOM of the chicken,also. Also,I wait to spoon the SECOND 1\/2 of the sauce UNTIL SERVING, the chicken will stay crisper,(even with the cheese on top). Obviously, we like the chicken on the crisp side (but we don't want to deep fry).\r\nFor company, put the chicken (with just the cheese baked on top) ON TOP of a small mound of spaghetti and sauce,or any pasta; It makes for a delicious looking presentation. A side salad with some sort of CREAMY dressing seems to compliment the red sauce, and completes the meal wonderfully. We get cravings for this one about 2c a month!", - "reviewRating": { - "@type": "Rating", - "worstRating": "1", - "bestRating": "5", - "ratingValue": 4 - }, - "author": { - "@type": "Person", - "name": "somethingdifferentagain?!", - "image": null, - "sameAs": "https:\/\/www.allrecipes.com\/cook\/342976\/" - } - }, - { - "@type": "Review", - "datePublished": "2004-01-23T16:37:02.013Z", - "reviewBody": "This was an extremely easy, very tasty recipe. As many others suggested, I only put sauce on the bottom of the chicken and then spooned a little over the top when serving. I think the recipe could be improved, though, by (1) pounding the chicken to a uniform thickness and (2) by spicing up the bread crumbs. I used Italian bread crumbs but next time will sprinkle pepper on the chicken before dredging through the crumbs, and I also plan to add more Italian seasoning and maybe a little parmesan to the crumbs. Both these steps, in my opinion, would take this from a really good recipe to an excellent dish!", - "reviewRating": { - "@type": "Rating", - "worstRating": "1", - "bestRating": "5", - "ratingValue": 4 - }, - "author": { - "@type": "Person", - "name": "JBAGNALL", - "image": null, - "sameAs": "https:\/\/www.allrecipes.com\/cook\/642772\/" - } - }, - { - "@type": "Review", - "datePublished": "2005-11-19T20:22:40.53Z", - "reviewBody": "I BRINED my chicken in 4 cups water , 1\/2 cup kosher salt (1\/4 table salt) \u00bd cup sugar for 30 minutes. No need to brine if you are using quick frozen chicken that has been enhanced. Kosher chicken is prebrined. Brining=juicy chicken. Took brined chicken, cut off thin edges, pounded out & shook chicken w\/flour (preflouring allows bread crumbs to stick) in a Ziploc-letting floured chicken sit for 5 min. I heated 6 TBS vegetable oil till it shimmered & then added 2 TBS butter to my pan, reserving half of this mixture for my second batch. Bread crumb mixture: I use \u00bd cup seasoned bread crumbs(same as 2 ounces), \u00bd cup grated parmesan( double what recipe calls for), 1tsp. Mrs. Dash Garlic and Herb, \u00bd tsp. garlic powder, \u00bd tsp, onion powder, \u00bd tsp. Italian seasoning & a pinch of pepper. Took pre-floured chicken, coated it with egg mixture, then dipped in bread crumbs & FRIED the chicken to a medium golden brown. Shook some parmesan on them right away when done frying to absorb any oil. Side-by side I plated plain spaghetti noodles & cutlets, w\/2 TBSP sauce on cutlet & desired amount of sauce on pasta, covered in cheese & baked each individual plate till cheese melted, serving them straight out of the oven. \r\nThe reviews on this were probably the best I have ever gotten, I used to work in an Italian Restaurant owned by NY Italians & have picked up some techniques. My Fettuccine Alfredo used to be my husband favorite dish, after last night he told me he has a new favorite. \r\n", - "reviewRating": { - "@type": "Rating", - "worstRating": "1", - "bestRating": "5", - "ratingValue": 5 - }, - "author": { - "@type": "Person", - "name": "KC MARTEL", - "image": null, - "sameAs": "https:\/\/www.allrecipes.com\/cook\/526291\/" - } - }, - { - "@type": "Review", - "datePublished": "2003-10-22T15:32:26.607Z", - "reviewBody": "After several Chicken Parm recipes THIS is THE ONE:-) I've finally found one that we all love! It's simple and it's darned good:-) I will definately make this recipe again and again; thanks so much:-)", - "reviewRating": { - "@type": "Rating", - "worstRating": "1", - "bestRating": "5", - "ratingValue": 5 - }, - "author": { - "@type": "Person", - "name": "STARCHILD1166", - "image": null, - "sameAs": "https:\/\/www.allrecipes.com\/cook\/736533\/" - } - }, - { - "@type": "Review", - "datePublished": "2003-11-14T16:55:26.39Z", - "reviewBody": "This chicken was so easy to make and turned out excellent! Used Best Marinara Sauce Yet (found here as well)instead of regular spaghetti sauce. This added even more flavor.", - "reviewRating": { - "@type": "Rating", - "worstRating": "1", - "bestRating": "5", - "ratingValue": 5 - }, - "author": { - "@type": "Person", - "name": "Alison", - "image": null, - "sameAs": "https:\/\/www.allrecipes.com\/cook\/516223\/" - } - }, - { - "@type": "Review", - "datePublished": "2003-01-23T04:38:19.873Z", - "reviewBody": "I REALLY liked this recipe. I made my own spaghetti sauce and used parmesan reggiano. I also skipped dipping the breasts in egg as I thought it was unnecessary and it was. Cooking temp. and time are accurate. Even my fussy fiance liked this. I'll definitely make this again.", - "reviewRating": { - "@type": "Rating", - "worstRating": "1", - "bestRating": "5", - "ratingValue": 4 - }, - "author": { - "@type": "Person", - "name": "CSANDST1", - "image": null, - "sameAs": "https:\/\/www.allrecipes.com\/cook\/115553\/" - } - }, - { - "@type": "Review", - "datePublished": "2003-08-05T20:26:00.81Z", - "reviewBody": "Wow! This was really tasty and simple. Something quick to make when you can't spend too much time figuring out what's for dinner. Also great on a toasted roll\/hero as a sandwich. I varied the recipe a little by adding some parmesan cheese (big cheese lover that I am!), garlic powder, onion powder and some salt into the bread crumbs and then mixing it up before breading the chicken with it. Also added a little salt to the beaten egg to make sure the chicken wouldn't end up bland, but that's just my preference. In response to the one reviewer who wanted thicker breading, what I did was double dip the chicken - coat first with the bread crumbs, then dip into the beaten egg and re-coat with breadcrumbs before actually baking (this would require some more breadcrumbs and probably another egg). Excellent recipe! =]", - "reviewRating": { - "@type": "Rating", - "worstRating": "1", - "bestRating": "5", - "ratingValue": 5 - }, - "author": { - "@type": "Person", - "name": "LIZCHAO74", - "image": null, - "sameAs": "https:\/\/www.allrecipes.com\/cook\/511187\/" - } - }, - { - "@type": "Review", - "datePublished": "2003-07-23T07:53:37.18Z", - "reviewBody": "Wonderful chicken recipe! I have made this several times. One night we were craving it and I didn't have any bottled spaghetti sauce. I poured a 14 ounce can of tomato sauce in a microwave bowl added 2t Italian Seasoning and 1t of garlic powder cooked on high for 6 minutes and ended up with a rich thick sauce for the chicken.", - "reviewRating": { - "@type": "Rating", - "worstRating": "1", - "bestRating": "5", - "ratingValue": 4 - }, - "author": { - "@type": "Person", - "name": "MAGGIE MCGUIRE", - "image": null, - "sameAs": "https:\/\/www.allrecipes.com\/cook\/392086\/" - } - }, - { - "@type": "Review", - "datePublished": "2008-06-10T21:54:38.893Z", - "reviewBody": "This is gonna be one of those it\u2019s a good recipe when you completely change it reviews. I did originally follow the recipe and the chicken tasted like it had been in breaded in cardboard. It just was not appetizing. However there is a great breaded chicken recipe on this site, garlic chicken. Made this simple and easy and oh so TASTY. I got great reviews. Here is what I did. Took \u00bc cup olive oil with 3 cloves garlic crushed and heated in microwave for 30 sec. Then coated the chicken in the oil and dipped in a mixture of \u00bd Italian seasoned bread crumbs and \u00bd parmesan cheese (double coat if u like thick breading). Cooked in oven at 325 for 20min (on a foil covered cookie sheet to make clean up easy). Set them in a casserole dish on top of about \u00bd a jar of spaghetti sauce for 3 chicken breast. Covered the breast with slices of mozzarella cheese and baked for another 20-25 minutes. Top with parmesan cheese. This turned out really really yummy and smells sooo good while it\u2019s cooking. ", - "reviewRating": { - "@type": "Rating", - "worstRating": "1", - "bestRating": "5", - "ratingValue": 4 - }, - "author": { - "@type": "Person", - "name": "ANGEL.9", - "image": null, - "sameAs": "https:\/\/www.allrecipes.com\/cook\/218599\/" - } - }, - { - "@type": "Review", - "datePublished": "2006-02-02T19:05:24.607Z", - "reviewBody": "Check out \"Tomato Chicken Parmesan\" on this site for a truly fabulous chicken parm recipe. Every time I make that one people say its the best chicken parm they every had. No matter what kind you make though always pound your chicken breasts it will help immensely keeping the chicken tender and moist.", - "reviewRating": { - "@type": "Rating", - "worstRating": "1", - "bestRating": "5", - "ratingValue": 3 - }, - "author": { - "@type": "Person", - "name": "MomSavedbyGrace", - "image": null, - "sameAs": "https:\/\/www.allrecipes.com\/cook\/1366670\/" - } - } - ], - "video": { - "@context": "http:\/\/schema.org", - "@type": "VideoObject", - "name": "Chicken Parmigiana", - "description": "Make this quick and easy version of chicken Parmigiana.", - "uploadDate": "2012-05-23T22:01:40.476Z", - "duration": "PT2M18.43S", - "thumbnailUrl": "https:\/\/imagesvc.meredithcorp.io\/v3\/mm\/image?url=https%3A%2F%2Fcf-images.us-east-1.prod.boltdns.net%2Fv1%2Fstatic%2F1033249144001%2F15c9e37d-979a-4c2c-a35d-fc3f436b0047%2F6b7f7749-9989-4707-971e-8578e60c0670%2F160x90%2Fmatch%2Fimage.jpg", - "publisher": { - "@type": "Organization", - "name": "Allrecipes", - "url": "https:\/\/www.allrecipes.com", - "logo": { - "@type": "ImageObject", - "url": "https:\/\/www.allrecipes.com\/img\/logo.png", - "width": 209, - "height": 60 - }, - "sameAs": [ - "https:\/\/www.facebook.com\/allrecipes", - "https:\/\/twitter.com\/Allrecipes", - "https:\/\/www.pinterest.com\/allrecipes\/", - "https:\/\/www.instagram.com\/allrecipes\/" - ] - }, - "embedUrl": "https:\/\/players.brightcove.net\/1033249144001\/default_default\/index.html?videoId=1653498713001" - }, - "keywords": "", - "tool": [], - "url": "https:\/\/www.allrecipes.com\/recipe\/8975\/chicken-parmigiana\/" -} \ No newline at end of file diff --git a/tests/data/nextcloud_recipes/Chicken Parmigiana/thumb.jpg b/tests/data/nextcloud_recipes/Chicken Parmigiana/thumb.jpg deleted file mode 100644 index f74eca92e..000000000 Binary files a/tests/data/nextcloud_recipes/Chicken Parmigiana/thumb.jpg and /dev/null differ diff --git a/tests/data/nextcloud_recipes/Skillet Shepherd's Pie/recipe.json b/tests/data/nextcloud_recipes/Skillet Shepherd's Pie/recipe.json deleted file mode 100644 index ff84b9e87..000000000 --- a/tests/data/nextcloud_recipes/Skillet Shepherd's Pie/recipe.json +++ /dev/null @@ -1,89 +0,0 @@ -{ - "@context": "http:\/\/schema.org", - "@type": "Recipe", - "name": "Skillet Shepherd's Pie", - "author": { - "@type": "Person", - "name": "Joanna Cismaru" - }, - "description": "This Skillet Shepherd's Pie recipe, also known as cottage pie, is loaded with flavorful beef and veggies, topped with fluffy and creamy mashed potatoes, then baked to perfection!", - "datePublished": "2019-03-16T20:15:47+00:00", - "image": "https:\/\/www.jocooks.com\/wp-content\/uploads\/2016\/12\/skillet-shepherds-pie-1-2-480x270.jpg", - "video": { - "name": "Skillet Shepherd's Pie", - "description": "This skillet shepherd\u2019s pie is loaded with flavorful beef and veggies then topped with fluffy and creamy mashed potatoes, then baked to perfection!", - "thumbnailUrl": "https:\/\/content.jwplatform.com\/thumbs\/HGr48vds-720.jpg", - "contentUrl": "https:\/\/content.jwplatform.com\/videos\/HGr48vds.mp4", - "uploadDate": "2018-03-08T16:13:05.000Z", - "@type": "VideoObject" - }, - "recipeYield": 1, - "prepTime": "PT0H15M", - "cookTime": "PT1H10M", - "totalTime": "PT1H25M", - "recipeIngredient": [ - "1 tbsp olive oil", - "1 1\/4 lb ground beef (lean)", - "1\/2 tsp salt (or to taste)", - "1\/2 tsp pepper (or to taste)", - "1 large onion (chopped)", - "1 clove garlic (minced)", - "1\/2 tsp red pepper flakes", - "2 tbsp Worcestershire sauce", - "1.9 oz onion soup mix (I used Knorr, 55g pkg)", - "1 cup beef broth (low sodium)", - "2 cups frozen veggies (I used mix of peas, carrots, green beans and corn)", - "6 large potatoes (peeled and cut into cubes)", - "4 tbsp butter (softened)", - "2\/3 cup milk", - "1\/4 cup Parmesan cheese", - "1\/2 tsp salt (or to taste)", - "1\/2 tsp white pepper (or to taste)", - "1 tbsp parsley (fresh, for garnish)" - ], - "recipeInstructions": [ - "Boil the potatoes: Start by first cooking the potatoes in boiling water for about 15 minutes or until fork tender. While the potatoes are cooking, you can prepare the meat mixture.", - "Prepare the meat mixture: Heat the oil in a large skillet over medium heat. Add the ground beef to the skillet, season it with the salt and pepper and cook it for abut 5 minutes or until it's no longer pink, breaking it up as you go along.", - "Add the onion and garlic and cook for 3 more minutes until the onion softens and becomes translucent. Add the pepper flakes, Worcestershire sauce, onion soup mix, beef broth and stir. Stir in the frozen veggies and cook for a couple more minutes. Set aside.", - "Preheat the oven 350 F degrees.", - "Prepare the mashed potatoes: Drain the potatoes then add them to a large bowl. Add in the butter and using a potato masher, mash until smooth. Add the milk, Parmesan cheese, salt pepper and mash a bit a more until smooth.", - "Finish assembling the shepherd's pie: Spread the potatoes over the meat and smooth with a spoon. Take a fork and rough up the top a bit and garnish with a bit of parsley.", - "Bake: Place the skillet on a baking sheet, then place it in the oven and bake for 40 minutes until golden brown on top.", - "Garnish with more parsley and pepper and serve warm." - ], - "aggregateRating": { - "@type": "AggregateRating", - "ratingValue": "4.48", - "ratingCount": "505" - }, - "recipeCategory": "Main Course", - "recipeCuisine": [ - "American" - ], - "keywords": "cottage pie,shepherd's pie,skillet shepherd's pie", - "nutrition": { - "@type": "NutritionInformation", - "calories": "252 kcal", - "carbohydrateContent": "14 g", - "proteinContent": "19 g", - "fatContent": "12 g", - "saturatedFatContent": "6 g", - "cholesterolContent": "63 mg", - "sodiumContent": "1165 mg", - "fiberContent": "2 g", - "sugarContent": "2 g", - "servingSize": "1 serving" - }, - "@id": "https:\/\/www.jocooks.com\/recipes\/skillet-shepherds-pie\/#recipe", - "isPartOf": { - "@id": "https:\/\/www.jocooks.com\/recipes\/skillet-shepherds-pie\/#article" - }, - "mainEntityOfPage": "https:\/\/www.jocooks.com\/recipes\/skillet-shepherds-pie\/#webpage", - "url": "https:\/\/www.jocooks.com\/recipes\/skillet-shepherds-pie\/", - "id": "4485", - "dateCreated": "0", - "dateModified": "1607461134", - "printImage": "false", - "imageUrl": "\/nextcloud\/index.php\/apps\/cookbook\/recipes\/4485\/image?size=full", - "tool": [] -} \ No newline at end of file diff --git a/tests/data/nextcloud_recipes/nextcloud.zip b/tests/data/nextcloud_recipes/nextcloud.zip deleted file mode 100644 index a420370ff..000000000 Binary files a/tests/data/nextcloud_recipes/nextcloud.zip and /dev/null differ diff --git a/tests/data/scraper/html-raw/carottes-rapps-with-rice-and-sunflower-seeds.html b/tests/data/scraper/html-raw/carottes-rapps-with-rice-and-sunflower-seeds.html deleted file mode 100644 index b3fb0b94b..000000000 --- a/tests/data/scraper/html-raw/carottes-rapps-with-rice-and-sunflower-seeds.html +++ /dev/null @@ -1,1318 +0,0 @@ - - - - - - - - -Carottes Rappés with Rice and Sunflower Seeds — FEED THE SWIMMERS - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
- - - - - - - - - - - - -
- - - - -
- - - - - - - -
- -
- - - - - - -
- - -
- - - - - - -

Jill Fergus

I began cooking as a child and feeding family and friends has always been my passion. My kitchen is a busy one. I love to experiment and embrace the kitchen successes along with the accidents. I love to cook and collaborate with friends. I am seasonally driven (I love the farmer's market!), avoid processed foods and focus on whole and organic (mostly plant-based, but not exclusively) choices. In my home, my family has a variety of eating preferences from plant-based, gluten free, refined sugar free to full on omnivore. My goal is to create dishes to please all, either as is or with minor adjustments to the recipe. Where did "Feed the Swimmers" come from? When my kids began swimming competitively and growing into young adults, I realized, even more, how important nutrition is to performance, growth and overall health and emotional well being. Everyone (including the coach during travel meets) would ask "what are you feeding the swimmers?" This has become my mantra whenever I'm in my kitchen cooking for family and the friends I love.

 

 

-
-
-
- -
- -
- - - -
- -
- - - -
- - - -
- -
- -
-
Carottes Rappés with Rice and Sunflower Seeds
-
- - -
- -
- -
- -

Carottes Rappés with Rice and Sunflower Seeds

- -
- - - -
-
- -
- -
-
-
-
-
-
-

 Carottes Râpées with Rice and Sunflower Seeds thanks to @think_rice and @thefeedfeed. Carottes Râpées is a classic French Salad found ready to go (think picnic) at every charcuterie and on most cafe menus. This is one of those insanely simple salads that explode with flavor! The carrots are a fine julienne which allows their juice to meld with the gentle vinaigrette brilliantly. This simple classic gets an update with U.S.-Grown long grain white rice and crunchy sunflower seeds and for me is loaded with the fondest of food memories! When I was a student, I did a semester abroad in Rennes, France, and lived with a family who had three very young children. My eating preferences then were very similar to now- mostly vegetarian with the occasional serving of fish. My French “mom” (who also taught me the art of fresh mayonnaise along with many other wonders) wasn’t quite used to this, but was also looking to add more veggies to their three toddlers diet. I’m not sure if she added rice to make this more child friendly or to stretch their food budget, but it was magical. For protein, I would add hard boiled eggs (from the chickens in the back yard) at lunch and was happy eating this several times per week! Some evenings, my “dad” would cook fresh sardines in the fireplace for me and those dinners were sublime. I didn’t leave with her recipe and we’ve lost touch, but I’ve recreated this based on memory, added the seeds for crunch and used U.S.-Grown rice to support American farmers. I’m delighted to share this with you! With summer looming, this also makes a great picnic salad served with crusty bread😋 for sopping up the dressing and is a great addition to sandwiches. If your prefer vegan, simply omit the egg. #feedfeed #thinkrice #sponsored

RECIPE

Carottes Râpées with Rice and Sunflower Seeds

Notes-

• The finer you’re able to julienne the carrots the better. I recommend using the finest setting of a food processor. If using a spiralizer, or similar, using the finest option works well, too. You’ll simply need to cut your carrots noodles into shorter pieces. I have an old Moulinex grater (not to be confused with their food Mill) I use for these which I love. A box grater is also just fine, as it releases the juice. You’ll simply have a slightly different texture.

• I prefer seasoned rice vinegar for this vinaigrette for its added sweetness.

• Tossing this by hand allows the vinaigrette to blend beautifully with the natural juice of the carrots and coats the grains of rice allowing for even distribution of the flavors.

• The rice should be prepared “al dente” as it will absorb the the vinaigrette.

• If you prefer a vegan option, simply omit the egg

Ingredients-

1/2 lb carrots, finely julienned or grated

1 cup long grain white rice

Large handful flat leaf parsley

1/4 cup seasoned rice vinegar

1/4 cup extra virgin olive oil, plus 1 tsp, separated

1 tsp Dijon mustard

Flaky sea salt

Fresh ground pepper

3 eggs

1/2 cup raw sunflower seeds

Method-

1- Prepare rice per package directions cutting back the water by 1/2 cup. Fluff with a fork and set aside to allow to cool a bit. You don’t want to toss the rice while it’s hot, but slightly warm to the touch best.


2- While the rice is cooking, prepare the vinaigrette, grate the carrots and chop the parsley. Boil the eggs for 10 minutes and add to an ice bath to stop the cooking. You don’t want gray edged yolks. Mash eggs with a fork so you have a course finish. Set aside.


3- Preheat a heavy bottomed pan over medium heat. Add 1 tsp of olive oil and sunflower seeds. Toast until edges just begin to turn golden. Add sea salt to taste and remove from heat to a small bowl.


3- Using your hands, toss carrots with rice to distribute and add vinaigrette, starting with about half (1/4 cup).  Taste and add more to suit your preference being careful not to overdress. Gently incorporate parsley and season with sea salt and fresh ground pepper. Top with chopped egg and sunflower seeds. Serve and enjoy!!!

- - - - - - - - - - - - -
- - - - -
- - - - - - - -
- IMG_0681.JPG -
- - - - - - -
- - -
- - - - - - -

If you happen to own a moulinex, use the finest disc. If you have a spiralizer, also choose the finest noodle option and loosely chop. Serving this as a carrot noodle dish, isn’t a bad idea! 

- - - - - - - - - - - - -
- - - - -
- - - - - - - -
- IMG_0682.JPG -
- - - - - - -
- - -
- - - - - - -

The dressing couldn’t be simpler! I never tire of rice wine.  

- - - - - - - - - - - - -
- - - - -
- - - - - - - -
- IMG_0683.JPG -
- - - - - - -
- - -
- - - - - - -

I would toast way more than you need. These are delicious, especially when warm, and disappear quickly.  

 

- - - - - - - - - - - - -
- - - - -
- - - - - - - -
- IMG_0684.JPG -
- - - - - - -
- - -
- - - - - - -

Enjoy! 

- - - - - -
-
- -
- -
- -
- - -
- -
-
-
-
- - -
-
- - - -
- -
- - - -
- - Spiced Cauliflower, Sweet Potato and Chick Pea Stew with Greens -

Spiced Cauliflower, Sweet Potato and Chick Pea Stew with Greens

-
-
-
- - - -
- - Crispy Sushi Rice with Smoked Salmon and Avocado -

Crispy Sushi Rice with Smoked Salmon and Avocado

-
-
-
- - - - -
- -
- - - -
- -
- - - - - - -
- - - - - - diff --git a/tests/data/scraper/html-raw/healthy_pasta_bake_60759.html b/tests/data/scraper/html-raw/healthy_pasta_bake_60759.html deleted file mode 100644 index fc98bdfa5..000000000 --- a/tests/data/scraper/html-raw/healthy_pasta_bake_60759.html +++ /dev/null @@ -1,500 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Healthy pasta bake recipe - BBC Food - - - - - -
-
- -

Healthy pasta bake

Loading
Healthy pasta bake

A fuss-free and healthy pasta bake that you can make in one dish. It's packed with the flavours and colours of Mediterranean vegetables and topped with pine nuts for crunch.

-Each serving provides 375 kcal, 12g protein, 27g carbohydrates (of which 11g sugars), 22g fat (of which 5g saturates), 8g fibre and 0.95g salt.

Ingredients

  • 2 tbsp olive oil
  • 1 red onion, roughly chopped
  • 1 yellow or red pepper, deseeded and cut into roughly 1.5cm/⅝in chunks
  • 1 courgette (approx. 225g/8oz), quartered lengthways and cut into roughly 1.5cm/⅝in chunks
  • 1 small aubergine (approx. 250g/9oz), cut into roughly 1.5cm/⅝in chunks
  • 2 large garlic cloves, crushed
  • 4 tbsp sun-dried tomato or red pepper pesto
  • 400g tin chopped tomatoes
  • 100g/3½oz wholewheat penne pasta
  • 75g/2¾oz young spinach leaves, tough stalks removed
  • 50g/1¾oz mature cheddar, grated
  • 2 tbsp pine nuts
  • salt and freshly ground black pepper

Method

  1. Preheat the oven to 200C/180 Fan/Gas 6.

  2. Heat the oil in a flameproof casserole. Add the onion, pepper, courgette and aubergine, season with a little salt and lots of pepper and fry over a medium heat for about 8 minutes, or until softened and lightly browned, stirring regularly. Add the garlic and cook for 1 minute, then stir in the pesto and cook for 1 minute more, stirring constantly.

  3. Tip the tomatoes into the casserole, then fill the tomato tin with water and pour into the pan. Add the pasta and bring to a simmer, stirring regularly. Cover with a lid, or if you prefer tip into a baking dish and cover with foil, and bake for 20 minutes.

  4. Take the casserole out of the oven and stir in the spinach, a handful at a time. Once all the spinach has been mixed in, sprinkle the cheese and pine nuts over the top. Return to the oven and cook, uncovered, for a further 10 minutes, until the pasta is tender.

Recipe Tips

If you don’t have wholewheat penne, use another shape, such as fusilli. You can also use traditional pasta, but the overall fibre content won’t be quite as high.

The red pesto adds lots of flavour; green basil pesto also works well.

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tests/data/scraper/recipes-raw/Pizza-Knoblauch-Champignon-Paprika-vegan.html.json b/tests/data/scraper/recipes-raw/Pizza-Knoblauch-Champignon-Paprika-vegan.html.json deleted file mode 100644 index 420f8ac4f..000000000 --- a/tests/data/scraper/recipes-raw/Pizza-Knoblauch-Champignon-Paprika-vegan.html.json +++ /dev/null @@ -1,103 +0,0 @@ -{ - "@context": "http://schema.org", - "@type": "Recipe", - "image": "https://img.chefkoch-cdn.de/rezepte/2235331358009600/bilder/864648/crop-960x540/pizza-knoblauch-champignon-paprika-vegan.jpg", - "recipeCategory": "Gem\u00fcse", - "recipeIngredient": [ - "300 g Weizenmehl (Type 550)", - "1 Pck. Trockenhefe", - "1 TL Salz", - "170 ml Wasser", - "6 EL \u00d6l (Knoblauch\u00f6l oder Oliven\u00f6l)", - "1 EL Tomatenmark", - "n. B. Knoblauch , gew\u00fcrfelt", - "2 Spitzpaprika oder Gem\u00fcsepaprika, rot", - "250 g Champignons", - "1 Zwiebel(n)", - " Salz und Pfeffer", - " Kr\u00e4uter , italienische, frisch oder getrocknet", - " Harissa" - ], - "name": "Pizza Knoblauch Champignon Paprika - vegan", - "description": "Pizza Knoblauch Champignon Paprika - vegan - f\u00fcr Nicht-Veganer nat\u00fcrlich mit K\u00e4se zu belegen. \u00dcber 51 Bewertungen und f\u00fcr raffiniert befunden. Mit \u25ba Portionsrechner \u25ba Kochbuch \u25ba Video-Tipps!", - "recipeInstructions": "Die Zutaten f\u00fcr den Teig verkneten und ca. 40 Minuten an einem warmen Ort gehen lassen. In der Zwischenzeit eine beliebige Anzahl Knoblauchzehen fein w\u00fcrfeln (ich bedecke die Pizza nahezu fl\u00e4chendeckend), die Zwiebel ebenfalls w\u00fcrfeln, Paprika und Champignons klein schneiden. Das \u00d6l mit Tomatenmark, Salz und Pfeffer vermischen. \r\n\r\nDen fertigen Teig ausrollen und auf ein Blech legen (ich benutze eine Pflaumenkuchen-Backform). Die \u00d6lmischung mit einem Backpinsel gleichm\u00e4\u00dfig auf dem Teig verteilen, danach mit dem Knoblauch, den Champignons, der Paprika und den Zwiebeln belegen. \r\n\r\nNun die Pizza mit Salz, Pfeffer, Kr\u00e4utern und Harissa kr\u00e4ftig w\u00fcrzen und bei 250\u00b0C ca. 10 - 15 Minuten backen. Der Teig ist als Grundteig zu betrachten und l\u00e4sst sich nat\u00fcrlich mit allem M\u00f6glichen an Gem\u00fcse belegen.", - "author": { - "@type": "Person", - "name": "healing21" - }, - "publisher": { - "@type": "Organization", - "name": "Chefkoch.de" - }, - "datePublished": "2013-01-14", - "prepTime": "P0DT0H20M", - "cookTime": "P0DT0H15M", - "totalTime": "P0DT1H15M", - "recipeYield": "2 Portion(en)", - "aggregateRating": { - "@type": "AggregateRating", - "ratingCount": 51, - "ratingValue": 4.57, - "reviewCount": 34, - "worstRating": 0, - "bestRating": 5 - }, - "keywords": [ - "Gem\u00fcse", - "Hauptspeise", - "Backen", - "Vegetarisch", - "einfach", - "Vegan", - "Pizza", - "Pilze" - ], - "reviews": [ - { - "@type": "Review", - "reviewBody": " Sehr gutes Basis Rezept!\n\nHab noch Salami, Kochschinken und K\u00e4se dazu gemacht, sonst schmeckt es ja nach nichts. \n\nErgebnis: 1. Klasse! Sehr fein! ", - "datePublished": "2020-04-21", - "author": { - "@type": "Person", - "name": "eierkopp1824" - } - }, - { - "@type": "Review", - "reviewBody": "Hallo,\r\nhabe den Teig gut zwei Stunden gehen lassen und dann wie im Rezept angegeben weiter verarbeitet. Da ich noch einige Schinkenw\u00fcrfel und etwas Fetak\u00e4se im K\u00fchlschrank hatte, wurden diese ebenfalls auf dem Belag verteilt. Ich habe die Pizza auf der untersten Schiene im Backofen gebacken. Der Boden ist nach dem Backen sch\u00f6n knusprig. Es hat mir und meinem Mitesser sehr gut geschmeckt.\r\nLG von Sternek\u00f6chin2011", - "datePublished": "2020-03-10", - "author": { - "@type": "Person", - "name": "Sternek\u00f6chin2011" - } - }, - { - "@type": "Review", - "reviewBody": "Echt f\u00fcr mich die leckerste Pizza auf der Welt! Auch bei meiner Familie kommt sie super an und \u00fcberlebt nicht lange. :)\nDen Belag kann man ja variieren wie man will. ", - "datePublished": "2020-02-20", - "author": { - "@type": "Person", - "name": "Leo090800" - } - }, - { - "@type": "Review", - "reviewBody": "Beste Pizza, die ich je gegessen habe! Sooo lecker! Habe f\u00fcr den Teig Dinkelvollkornmehl genommen und den Belag noch mit ein paar Chiliflocken verfeinert. ", - "datePublished": "2018-04-15", - "author": { - "@type": "Person", - "name": "Sunny_Eyes" - } - }, - { - "@type": "Review", - "reviewBody": "Der Teig ist super, ebenso wie die Sauce! Habe anstelle von normalem Salz Basilikumsalz in den Teig gegeben, das gibt dem ganzen einen besonderen Geschmack.Statt Paprika und Knobi habe ich K\u00e4se und Rucola hinzuef\u00fcgt, den Salat erst nach dem Backen. Die wird sicherlich nochmal gemacht! Da ich nur eine Pizza gemacht habe, habe ich den restlichen Teig eingefroren. Foto ist unterwegs!", - "datePublished": "2018-02-14", - "author": { - "@type": "Person", - "name": "Chiqryn" - } - } - ], - "url": "https://www.chefkoch.de/rezepte/2235331358009600/Pizza-Knoblauch-Champignon-Paprika-vegan.html" -} \ No newline at end of file diff --git a/tests/data/scraper/recipes-raw/best-homemade-salsa-recipe.json b/tests/data/scraper/recipes-raw/best-homemade-salsa-recipe.json deleted file mode 100644 index 0f2671e2c..000000000 --- a/tests/data/scraper/recipes-raw/best-homemade-salsa-recipe.json +++ /dev/null @@ -1,86 +0,0 @@ -{ - "@context": "http://schema.org/", - "@type": "Recipe", - "name": "The Best Homemade Salsa Recipe", - "author": { - "@type": "Person", - "name": "Sommer Collier" - }, - "description": "How To Make Delicious Salsa: Secrets of making the Best Homemade Salsa Recipe! This restaurant style salsa recipe is loaded with flavor, has an amazing texture, and a secret ingredient.", - "datePublished": "2020-02-01T00:00:30+00:00", - "image": [ - "https://www.aspicyperspective.com/wp-content/uploads/2019/02/the-best-homemade-salsa-recipe-100.jpg", - "https://www.aspicyperspective.com/wp-content/uploads/2019/02/the-best-homemade-salsa-recipe-100-500x500.jpg", - "https://www.aspicyperspective.com/wp-content/uploads/2019/02/the-best-homemade-salsa-recipe-100-500x375.jpg", - "https://www.aspicyperspective.com/wp-content/uploads/2019/02/the-best-homemade-salsa-recipe-100-480x270.jpg" - ], - "video": { - "name": "The Best Homemade Salsa Recipe", - "description": "We\u2019re sharing our secrets for making The Best Homemade Salsa Recipe we\u2019ve ever tried. Healthy, fresh, and easy to adjust!", - "thumbnailUrl": "https://content.jwplatform.com/thumbs/rPi8NdK6-720.jpg", - "contentUrl": "https://content.jwplatform.com/videos/rPi8NdK6.mp4", - "uploadDate": "2017-03-22T16:24:09.000Z", - "@type": "VideoObject" - }, - "recipeYield": [ - "20", - "20 (5 cups)" - ], - "prepTime": "PT5M", - "totalTime": "PT5M", - "recipeIngredient": [ - "4 ripe tomatoes, (cored and quartered)", - "1 red onion, (peeled and quartered)", - "3 garlic cloves, (peeled)", - "3 jalapenos, (stemmed and seeded (you can\u00a0substitute 1-2 habanero or serrano peppers.))", - "1/3 cup fresh cilantro", - "3 tablespoons fresh lime juice", - "2-3 teaspoons ground cumin", - "2-3 teaspoons sugar ((optional))", - "1 1/2 teaspoons salt", - "15 ounces crushed San Marzano tomatoes ((1 can))", - "4.5 ounces diced green chiles, (mild, medium, or hot (1 can))" - ], - "recipeInstructions": [ - { - "@type": "HowToStep", - "text": "Place the fresh tomatoes, onion, garlic, peppers, cilantro, lime juice, 2 teaspoons cumin, 2 teaspoons sugar (if using), and salt in a food processor. Pulse until the contents are fine and well blended.", - "name": "Place the fresh tomatoes, onion, garlic, peppers, cilantro, lime juice, 2 teaspoons cumin, 2 teaspoons sugar (if using), and salt in a food processor. Pulse until the contents are fine and well blended.", - "url": "https://www.aspicyperspective.com/best-homemade-salsa-recipe/#wprm-recipe-61842-step-0-0" - }, - { - "@type": "HowToStep", - "text": "Pour in the crushed tomatoes and green chiles. Puree until mostly smooth. Taste, then add more cumin and sugar if desired. Refrigerate until ready to serve.", - "name": "Pour in the crushed tomatoes and green chiles. Puree until mostly smooth. Taste, then add more cumin and sugar if desired. Refrigerate until ready to serve.", - "url": "https://www.aspicyperspective.com/best-homemade-salsa-recipe/#wprm-recipe-61842-step-0-1" - } - ], - "aggregateRating": { - "@type": "AggregateRating", - "ratingValue": "4.98", - "ratingCount": "201" - }, - "recipeCategory": [ - "Appetizer", - "Snack" - ], - "recipeCuisine": [ - "American", - "Mexican" - ], - "keywords": "Homemade Salsa, Salsa, The Best Salsa Recipe", - "nutrition": { - "@type": "NutritionInformation", - "servingSize": "0.25 cup", - "calories": "19 kcal", - "carbohydrateContent": "4 g", - "sodiumContent": "230 mg", - "sugarContent": "2 g" - }, - "@id": "https://www.aspicyperspective.com/best-homemade-salsa-recipe/#recipe", - "isPartOf": { - "@id": "https://www.aspicyperspective.com/best-homemade-salsa-recipe/#article" - }, - "mainEntityOfPage": "https://www.aspicyperspective.com/best-homemade-salsa-recipe/#webpage", - "url": "https://www.aspicyperspective.com/best-homemade-salsa-recipe/" -} \ No newline at end of file diff --git a/tests/data/scraper/recipes-raw/blue-cheese-stuffed-turkey-meatballs-with-raspberry-balsamic-glaze-2.json b/tests/data/scraper/recipes-raw/blue-cheese-stuffed-turkey-meatballs-with-raspberry-balsamic-glaze-2.json deleted file mode 100644 index 32fc65485..000000000 --- a/tests/data/scraper/recipes-raw/blue-cheese-stuffed-turkey-meatballs-with-raspberry-balsamic-glaze-2.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "image": "https://www.cookingforkeeps.com/wp-content/uploads/2013/02/done-1.jpg", - "aggregateRating": { - "properties": { - "ratingValue": "4.0", - "ratingCount": "2" - }, - "@type": "AggregateRating" - }, - "name": "Blue Cheese Stuffed Turkey Meatballs with Raspberry Balsamic Glaze", - "author": "Nicole-Cooking for Keeps", - "recipeYield": "Makes 18-22 meatballs depending on size", - "recipeInstructions": [ - "For the meatballs: Roll the blue cheese in small balls about the diameter of a dime. Freeze for 30 minutes. Preheat oven to 375 degrees. Mix the remaining ingredients together, until just combined. Roll sausage mixture into small balls. Place the blue cheese in the middle, enclosing with meat. Bake on a silt pad until golden brown and cooked through, about 25 min, turning halfway through to ensure even browning.", - "For the Dipping Sauce:", - "Combine all ingredients together in small sauce pan over medium high heat. Bring to a boil and then reduce heat and simmer about five minutes. Coat meatballs in sauce. Serve." - ], - "@context": "http://schema.org", - "@type": "Recipe", - "url": "https://www.cookingforkeeps.com/blue-cheese-stuffed-turkey-meatballs-with-raspberry-balsamic-glaze-2/", - "recipeIngredient": [ - "Sausage Bites", - "3 oz creamy gorgonzola cheese", - "1 lb turkey Italian sausage (schmicas) with fennel seed", - "\u00bd cup Italian style bread crumbs", - "\u00bd onion grated", - "1 egg white", - "Salt to taste", - "Dipping Sauce:", - "\u00bd cup raspberry preserves", - "\u215b cup balsamic vinegar", - "3 teaspoons Dijon mustard", - "Pinch of red pepper", - "Pinch of Salt" - ] -} \ No newline at end of file diff --git a/tests/data/scraper/recipes-raw/bon_appetit.json b/tests/data/scraper/recipes-raw/bon_appetit.json deleted file mode 100644 index 1cdb927c8..000000000 --- a/tests/data/scraper/recipes-raw/bon_appetit.json +++ /dev/null @@ -1,132 +0,0 @@ -{ - "@context": "http://schema.org", - "@type": "Recipe", - "articleBody": "Atlanta pastry chef Claudia Martinez\u2019s family has been making what Martinez describes as meaty Venezuelan tamales around the holidays for generations. In the Martinez household, every family member has a task: Claudia\u2019s dad or grandmother always prepares the guiso, the tender shredded chicken and beef stew that comprises the bulk of the filling. One person slicks scoops of vibrant orange achiote-stained masa dough onto banana leaves, then passes them around the table to get filled. Claudia\u2019s grandma adds a spoonful of guiso; Claudia adds olives and capers; her sister adds a few raisins. Finally, each hallaca gets wrapped up in the fragrant leaves and tied with twine like a tiny present, ready to boil for a late Christmas Eve dinner. The Martinez family usually makes 100 at a time; this scaled-down version of their recipe makes just under 20, enough for a big dinner plus leftovers you can freeze for another day. If you find yourself with leftover masa and stew, do as the Martinezes do: Make arepas with guiso and fried eggs for breakfast on Christmas Day. (If you\u2019re in Atlanta in the days leading up to Christmas Eve, pick up hallacas at Caf\u00e9 Claudia, the pop-up Martinez runs out of the Hotel Clermont.)\nBanana leaves give a floral and grassy flavor to the hallacas, you can buy them either fresh or frozen at Latin and Asian markets. You can use parchment paper instead, but the outcome won\u2019t be as complex.", - "alternativeHeadline": "The Venezuelan holiday dish that Atlanta pastry chef Claudia Martinez\u2019s family has been making for generations.", - "dateModified": "2021-01-02 12:09:30.443000", - "datePublished": "2020-12-01 07:00:00", - "keywords": [ - "recipes", - "holiday 2020", - "new years eve", - "olive oil", - "beef", - "chicken recipes", - "kosher salt", - "tomato", - "garlic", - "tomato paste", - "onion", - "bell pepper", - "green onion scallion", - "cilantro", - "brown sugar", - "cornmeal", - "capers", - "olive", - "raisin", - "web" - ], - "thumbnailUrl": "https://assets.bonappetit.com/photos/5fb4407993a08c9bf97163f7/1:1/w_1125,h_1125,c_limit/1220-Hallacas.jpg", - "publisher": { - "@context": "https://schema.org", - "@type": "Organization", - "name": "Bon App\u00e9tit", - "logo": { - "@type": "ImageObject", - "url": "https://www.bonappetit.com/verso/static/bon-appetit/assets/logo-seo.328de564b950e3d5d1fbe3e42f065290ca1d3844.png", - "width": "479px", - "height": "100px" - }, - "url": "https://www.bonappetit.com" - }, - "isPartOf": { - "@type": [ - "CreativeWork", - "Product" - ], - "name": "Bon App\u00e9tit" - }, - "isAccessibleForFree": true, - "author": [ - { - "@type": "Person", - "name": "Claudia Martinez", - "sameAs": "https://bon-appetit.com/contributor/claudia-martinez/" - } - ], - "aggregateRating": { - "@type": "AggregateRating", - "ratingValue": 5, - "ratingCount": 22 - }, - "description": "The Venezuelan holiday dish that Atlanta pastry chef Claudia Martinez\u2019s family has been making for generations.", - "image": "hallacas.jpg", - "name": "Hallacas", - "recipeIngredient": [ - "1\u00bd cups extra-virgin olive oil", - "3 Tbsp. plus 1\u00bd tsp. achiote (annatto) seeds", - "2\u00bd lb. boneless beef chuck roast", - "2\u00bd lb. skinless, boneless chicken breasts", - "1 Tbsp. Diamond Crystal or 1\u00be tsp. Morton kosher salt, plus more", - "3 medium tomatoes, coarsely chopped", - "3 garlic cloves", - "1 6-oz. can tomato paste", - "1 medium onion, chopped", - "1 large red bell pepper, seeds and ribs removed, coarsely chopped", - "1 large green bell pepper, seeds and ribs removed, coarsely chopped", - "1 bunch scallions, coarsely chopped", - "1 bunch cilantro, coarsely chopped", - "\u00bc cup (packed) light brown sugar", - "1 1-kg package P.A.N. precooked cornmeal", - "2 Tbsp. Diamond Crystal or 1 Tbsp. plus \u00bd tsp. kosher salt", - "3 1-lb. packages fresh or frozen, thawed banana or plantain leaves", - "\u00bc cup extra-virgin olive oil", - "\u00bd cup drained capers", - "\u00bd cup pitted green olives", - "\u00bd cup raisins" - ], - "recipeInstructions": [ - { - "@type": "HowToStep", - "text": "Cook oil and achiote seeds in a small saucepan over medium-low heat until oil turns deep orange, about 10 minutes. Strain into a heatproof jar and let cool. Measure out \u00bd cup achiote oil for making filling; set remaining 1 cup oil aside for making dough." - }, - { - "@type": "HowToStep", - "text": "Bring beef, chicken, 1 Tbsp. Diamond Crystal or 1\u00be tsp. Morton kosher salt, and 12 cups water to a boil in a large pot over medium-high heat. Reduce heat to medium-low and let simmer until cooked through, about 30 minutes. Transfer beef and chicken to a cutting board and let sit until cool enough to handle. Pour 8 cups cooking liquid into a heatproof pitcher or large measuring glass; set aside. Discard any extra liquid." - }, - { - "@type": "HowToStep", - "text": "Cut beef and chicken into \u2153\" cubes; place back into pot (cooking the meat before you chop it means that you can cut the pieces finer and more evenly). Blend tomatoes, garlic, and tomato paste in a blender until smooth; scrape pur\u00e9e into pot with meat. Blend onion, red and green bell peppers, scallions, cilantro, and \u00bd cup reserved cooking liquid in blender until smooth and add to pot. Add brown sugar and \u00bd cup reserved achiote oil. Pour in remaining 7\u00bd cups reserved cooking liquid. Bring to a boil, then reduce heat to medium-low and simmer until meat is tender and liquid is slightly reduced, about 40 minutes. Drain meat in a colander, season lightly with salt, and let cool." - }, - { - "@type": "HowToStep", - "text": "Meanwhile, mix cornmeal, salt, reserved 1 cup achiote oil, and 8 cups water in a large bowl with your hands until dough is smooth, spreadable, and no large lumps remain, 5\u20137 minutes. Press a sheet of plastic wrap or parchment paper directly onto surface of dough; let rest at least 30 minutes or up to 1 hour." - }, - { - "@type": "HowToStep", - "text": "Wash and pat banana leaves dry. Carefully remove any center stems with kitchen shears, avoiding breaking through the leaf, then cut into 14x10\" rectangles. Mix oil and 1 cup water in a medium bowl (it needs to be big enough to dip your hands into). This will help to keep the dough from sticking to your hands. Working one at a time, place a banana leaf on a surface so the veins in the leaves run horizontally. Dipping your hands in oil mixture as you work, place \u00be cup dough in center of leaf and spread out with your fingers into a \u215b\"-thick rectangle, leaving a 1\" border near the vertical edges and a space on both horizontal edges. Place \u00be cup guiso into center of dough. Top with 5 capers, 2 olives, and 8 raisins." - }, - { - "@type": "HowToStep", - "text": "Take top and bottom edges of leaf and bring up toward each other so edges of dough meet and enclose filling. Pull both sides of banana leaf together snugly toward the upper edge of hallaca to seal and fold over toward you to make a tube. Fold remaining 2 side ends toward the center to make a small package." - }, - { - "@type": "HowToStep", - "text": "Place package, fold side down, on another banana leaf and wrap up again. Wrap once more in a third leaf to hold everything together, then tie closed with kitchen twine. (Make sure package is compact, the leaves are not ripped, and hallaca is not leaking.) Repeat with remaining dough, filling, and banana leaves." - }, - { - "@type": "HowToStep", - "text": "Place as many hallacas as will fit into a clean large pot, pour in water to cover, and bring to a boil. Reduce heat and simmer, turning hallacas halfway through, until plumped and firm, about 35 minutes. Repeat with remaining hallacas.\nDo ahead: Hallacas can be made 1 week ahead. Let cool, then cover and chill, or freeze up to 3 months. To reheat, cook in a pot of simmering water (make sure hallacas are submerged), partially covered, until warmed through, 10\u201315 minutes if chilled, 25\u201330 minutes if frozen." - } - ], - "recipeYield": "Makes about 18", - "url": "https://www.bonappetit.com/recipe/hallacas", - "slug": "hallacas", - "orgURL": "https://www.bonappetit.com/recipe/hallacas", - "categories": [], - "tags": [], - "dateAdded": null, - "notes": [], - "extras": [] -} \ No newline at end of file diff --git a/tests/data/scraper/recipes-raw/chunky-apple-cake.json b/tests/data/scraper/recipes-raw/chunky-apple-cake.json deleted file mode 100644 index 7a20a2cab..000000000 --- a/tests/data/scraper/recipes-raw/chunky-apple-cake.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "url": "https://www.deliaonline.com/recipes/seasons/what-should-you-be-cooking-in-november/chunky-apple-cake", - "author": "Delia Smith", - "image": "https://www.deliaonline.com/sites/default/files/quick_media/cakes-chunky-apple-cake.jpg", - "name": "Chunky Apple Cake", - "description": "Apples are superb in cakes, so in the autumn when there are lots of windfalls around, why not make a few of these and freeze them.", - "recipeCuisine": "General", - "recipeCategory": [ - "Apples", - "Afternoon Tea", - "Cake Recipes", - "Autumn", - "Life in the Freezer" - ], - "keywords": "Apples, Afternoon Tea, Cake Recipes, Autumn, Life in the Freezer, Delia, Delia Smith", - "recipeInstructions": "Begin by sifting the flour, baking powder and spices into a roomy mixing bowl, lifting the sieve quite high to give the flour a good airing as it goes down.\n\nNext chop the apples into small dice (with or without peel, just as you like). Then place them in a bowl and toss them with one tablespoon of the sieved flour mixture. Then add the eggs, butter and sugar to the rest of the flour, and using an electric hand whisk, combine them for about 1 minute until you have a smooth creamy consistency. After that fold in the grated orange zest, mixed peel and diced apple. If the mixture seems a little dry, add a tablespoon of milk. Now spoon the cake mix into the prepared tin and level it off with the back of a spoon.\n\nThen bake near the centre of the oven for about one hour or until the cake feels springy in the centre when lightly pressed with a fingertip and just shows signs of shrinking away from the edge of the tin. Cool in the tin for 10 minutes before turning out onto a wire rack. This looks nice dusted with sifted icing sugar just before serving. Store in an airtight tin.\n\nYou can watch more of Delia's cake recipes being made in our Cookery School Videos on the right.", - "recipeIngredient": [ - "225g self-raising flour", - "1 rounded teaspoon baking powder", - "1 level teaspoon mixed spice", - "\u00bd level teaspoon ground cinnamon", - "3 Bramley apples (about 550g)", - "2 large eggs, beaten", - "75g spreadable butter", - "175g light brown soft sugar", - "grated zest of 1 large orange", - "1 tablespoon chopped mixed peel", - "1 tablespoon milk (if needed)", - "little icing sugar" - ], - "@context": "http://schema.org", - "@type": "Recipe" -} \ No newline at end of file diff --git a/tests/data/scraper/recipes-raw/dairy-free-impossible-pumpkin-pie.json b/tests/data/scraper/recipes-raw/dairy-free-impossible-pumpkin-pie.json deleted file mode 100644 index a029bc6e6..000000000 --- a/tests/data/scraper/recipes-raw/dairy-free-impossible-pumpkin-pie.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "@context": "http://schema.org/", - "@type": "Recipe", - "name": "Dairy-Free Impossible Pumpkin Pie", - "author": { - "@type": "Person", - "name": "Kare for Kitchen Treaty" - }, - "description": "This crustless pumpkin pie might just be the\u00a0easiest\u00a0you'll ever make. Simply blend the ingredients together, pour into your pie pan, and bake!", - "datePublished": "2017-11-10T16:12:06+00:00", - "image": [ - "https://www.kitchentreaty.com/wp-content/uploads/2017/11/dairy-free-impossible-pumpkin-pie-8.jpg" - ], - "recipeYield": [ - "8" - ], - "prepTime": "PT10M", - "cookTime": "PT45M", - "totalTime": "PT55M", - "recipeIngredient": [ - "1 (15-ounce) can coconut milk (I recommend full-fat for a richer pie, but lite also works)", - "1 cup pumpkin puree", - "4 large eggs", - "1/2 cup granulated sugar", - "1 tablespoon pure vanilla extract", - "1/2 cup all-purpose flour (or your favorite cup-for-cup gluten-free flour blend*)", - "1 teaspoon baking powder", - "1 tablespoon pumpkin pie spice", - "1/2 teaspoon fine-grain sea salt or table salt", - "Coconut whipped cream (for serving**)" - ], - "recipeInstructions": [ - { - "@type": "HowToStep", - "text": "Preheat oven to 375 degrees Fahrenheit and position rack in the middle of the oven. Spray a 9- or 10-inch pie pan with baking spray or oil the pan with coconut oil or vegan butter.", - "name": "Preheat oven to 375 degrees Fahrenheit and position rack in the middle of the oven. Spray a 9- or 10-inch pie pan with baking spray or oil the pan with coconut oil or vegan butter.", - "url": "https://www.kitchentreaty.com/dairy-free-impossible-pumpkin-pie/#wprm-recipe-32856-step-0-0" - }, - { - "@type": "HowToStep", - "text": "Add the coconut milk, pumpkin, eggs, sugar, and vanilla to the pitcher of a blender. Blend until combined, about 20 seconds. Add the flour, baking powder, pumpkin pie spice, and salt. Blend again until well-combined, another 20\u00a0seconds.", - "name": "Add the coconut milk, pumpkin, eggs, sugar, and vanilla to the pitcher of a blender. Blend until combined, about 20 seconds. Add the flour, baking powder, pumpkin pie spice, and salt. Blend again until well-combined, another 20\u00a0seconds.", - "url": "https://www.kitchentreaty.com/dairy-free-impossible-pumpkin-pie/#wprm-recipe-32856-step-0-1" - }, - { - "@type": "HowToStep", - "text": "Pour filling into the pie plate. The mixture will be fairly runny. Carefully transfer to the preheated oven.", - "name": "Pour filling into the pie plate. The mixture will be fairly runny. Carefully transfer to the preheated oven.", - "url": "https://www.kitchentreaty.com/dairy-free-impossible-pumpkin-pie/#wprm-recipe-32856-step-0-2" - }, - { - "@type": "HowToStep", - "text": "Bake\u00a0until the middle just barely jiggles, 40-50 minutes. I like to check the middle by giving the pie pan a little nudge, and if it seems like it's no longer liquid, I'll pull the pie out and insert a butter knife about halfway between the center and the edge. If the knife comes out relatively clean - no runny pie filling - it's\u00a0done!", - "name": "Bake\u00a0until the middle just barely jiggles, 40-50 minutes. I like to check the middle by giving the pie pan a little nudge, and if it seems like it's no longer liquid, I'll pull the pie out and insert a butter knife about halfway between the center and the edge. If the knife comes out relatively clean - no runny pie filling - it's\u00a0done!", - "url": "https://www.kitchentreaty.com/dairy-free-impossible-pumpkin-pie/#wprm-recipe-32856-step-0-3" - }, - { - "@type": "HowToStep", - "text": "Place on a cooling rack and let cool, about 1 hour. Transfer to refrigerator to completely\u00a0cool, at least one more hour (or up to 3 days in advance).", - "name": "Place on a cooling rack and let cool, about 1 hour. Transfer to refrigerator to completely\u00a0cool, at least one more hour (or up to 3 days in advance).", - "url": "https://www.kitchentreaty.com/dairy-free-impossible-pumpkin-pie/#wprm-recipe-32856-step-0-4" - }, - { - "@type": "HowToStep", - "text": "If desired, top pie with dollops of coconut whipped cream. Or simply cut slices, transfer to a plate, and top\u00a0individual servings with the whipped cream.", - "name": "If desired, top pie with dollops of coconut whipped cream. Or simply cut slices, transfer to a plate, and top\u00a0individual servings with the whipped cream.", - "url": "https://www.kitchentreaty.com/dairy-free-impossible-pumpkin-pie/#wprm-recipe-32856-step-0-5" - }, - { - "@type": "HowToStep", - "text": "Keeps in the refrigerator for 3-4 days. I suggest covering the completely cooled pie with plastic wrap if not serving right away.", - "name": "Keeps in the refrigerator for 3-4 days. I suggest covering the completely cooled pie with plastic wrap if not serving right away.", - "url": "https://www.kitchentreaty.com/dairy-free-impossible-pumpkin-pie/#wprm-recipe-32856-step-0-6" - } - ], - "aggregateRating": { - "@type": "AggregateRating", - "ratingValue": "5", - "ratingCount": "4" - }, - "recipeCategory": [ - "Dessert" - ], - "recipeCuisine": [ - "American" - ], - "keywords": "pie", - "nutrition": { - "@type": "NutritionInformation", - "calories": "231 kcal", - "sugarContent": "14 g", - "sodiumContent": "239 mg", - "fatContent": "14 g", - "saturatedFatContent": "11 g", - "carbohydrateContent": "23 g", - "fiberContent": "1 g", - "proteinContent": "5 g", - "cholesterolContent": "82 mg", - "servingSize": "1 serving" - }, - "url": "https://www.kitchentreaty.com/dairy-free-impossible-pumpkin-pie/" -} \ No newline at end of file diff --git a/tests/data/scraper/recipes-raw/how-to-make-instant-pot-spaghetti.json b/tests/data/scraper/recipes-raw/how-to-make-instant-pot-spaghetti.json deleted file mode 100644 index eb9837a5a..000000000 --- a/tests/data/scraper/recipes-raw/how-to-make-instant-pot-spaghetti.json +++ /dev/null @@ -1,121 +0,0 @@ -{ - "@context": "http://schema.org/", - "@type": "Recipe", - "name": "How to Make Instant Pot Spaghetti", - "author": { - "@type": "Person", - "name": "Karlynn Johnston" - }, - "description": "This Instant Pot Spaghetti recipe is literally the best one out there and it's thanks to one ( or two!) secret ingredients!", - "datePublished": "2020-09-15T13:00:52+00:00", - "image": [ - "https://www.thekitchenmagpie.com/wp-content/uploads/images/2018/02/instantpotspaghetti.jpg", - "https://www.thekitchenmagpie.com/wp-content/uploads/images/2018/02/instantpotspaghetti-500x500.jpg", - "https://www.thekitchenmagpie.com/wp-content/uploads/images/2018/02/instantpotspaghetti-500x375.jpg", - "https://www.thekitchenmagpie.com/wp-content/uploads/images/2018/02/instantpotspaghetti-480x270.jpg" - ], - "recipeYield": [ - "4" - ], - "prepTime": "PT15M", - "cookTime": "PT7M", - "totalTime": "PT22M", - "recipeIngredient": [ - "1 tablespoon olive oil", - "1 cup white onion (diced)", - "1 tablespoon fresh minced garlic", - "1 pound lean ground beef", - "2 teaspoons Italian seasoning mix", - "one 16 ounce package uncooked white flour spaghetti noodles (cooking time for al dente needs to be 9-10 minutes! )", - "one 750 millilitre jar of 4 cheese spaghetti sauce", - "one 15 ounce can diced tomatoes", - "3 cups weak beef broth (divided)", - "1/2 teaspoon salt (( to taste))", - "1/2 teaspoon black pepper", - "1/2 teaspoon white sugar (to cut the acidity of the tomatoes )" - ], - "recipeInstructions": [ - { - "@type": "HowToStep", - "text": "Press the \"saute\" button on your Instant Pot. Add in the olive oil and heat. Once it's heated, add in the white onion. Saute until the onion is soft and translucent. Add in the garlic and fry for 2-3 minutes.", - "name": "Press the \"saute\" button on your Instant Pot. Add in the olive oil and heat. Once it's heated, add in the white onion. Saute until the onion is soft and translucent. Add in the garlic and fry for 2-3 minutes.", - "url": "https://www.thekitchenmagpie.com/how-to-make-instant-pot-spaghetti/#wprm-recipe-44488-step-0-0", - "image": "https://www.thekitchenmagpie.com/wp-content/uploads/images/2018/02/fryinggroundbeefandonionsinaninsantpot.jpg" - }, - { - "@type": "HowToStep", - "text": "Add in the ground beef and fry , stirring constantly, until it's no longer pink. Press the Cancel button to turn off the Instant Pot heating element. Drain the fat (keeping some for flavour if wanted).", - "name": "Add in the ground beef and fry , stirring constantly, until it's no longer pink. Press the Cancel button to turn off the Instant Pot heating element. Drain the fat (keeping some for flavour if wanted).", - "url": "https://www.thekitchenmagpie.com/how-to-make-instant-pot-spaghetti/#wprm-recipe-44488-step-0-1" - }, - { - "@type": "HowToStep", - "text": "Add in 1 cup of the beef broth, mixing it in with the ground beef on the bottom.", - "name": "Add in 1 cup of the beef broth, mixing it in with the ground beef on the bottom.", - "url": "https://www.thekitchenmagpie.com/how-to-make-instant-pot-spaghetti/#wprm-recipe-44488-step-0-2" - }, - { - "@type": "HowToStep", - "text": "Break the spaghetti noodles in half. Place in random, different criss-cross patterns on top of the beef/ beef broth mixture. You are trying to created space between the noodles to try and prevent sticking.", - "name": "Break the spaghetti noodles in half. Place in random, different criss-cross patterns on top of the beef/ beef broth mixture. You are trying to created space between the noodles to try and prevent sticking.", - "url": "https://www.thekitchenmagpie.com/how-to-make-instant-pot-spaghetti/#wprm-recipe-44488-step-0-3", - "image": "https://www.thekitchenmagpie.com/wp-content/uploads/images/2018/02/howtobreakspaghettinoodlesfortheinstantpot.jpg" - }, - { - "@type": "HowToStep", - "text": "In a large bowl or large glass spouted measuring glass, combine the remaining beef broth, tomatoes, 4 cheese sauce, Italian seasoning, salt, pepper and dash of white sugar. ", - "name": "In a large bowl or large glass spouted measuring glass, combine the remaining beef broth, tomatoes, 4 cheese sauce, Italian seasoning, salt, pepper and dash of white sugar. ", - "url": "https://www.thekitchenmagpie.com/how-to-make-instant-pot-spaghetti/#wprm-recipe-44488-step-0-4" - }, - { - "@type": "HowToStep", - "text": "Pout the liquid mixture on top of the pasta, around the sides, making sure you coat everything. Take a wooden spoon and gently push down on the spaghetti noodles, making sure that they are all underneath the liquid.", - "name": "Pout the liquid mixture on top of the pasta, around the sides, making sure you coat everything. Take a wooden spoon and gently push down on the spaghetti noodles, making sure that they are all underneath the liquid.", - "url": "https://www.thekitchenmagpie.com/how-to-make-instant-pot-spaghetti/#wprm-recipe-44488-step-0-5" - }, - { - "@type": "HowToStep", - "text": "Press the Manual Button ( you are going to use high pressure) and set for 7 minutes. Listen to make sure that it seals.", - "name": "Press the Manual Button ( you are going to use high pressure) and set for 7 minutes. Listen to make sure that it seals.", - "url": "https://www.thekitchenmagpie.com/how-to-make-instant-pot-spaghetti/#wprm-recipe-44488-step-0-6" - }, - { - "@type": "HowToStep", - "text": "When it's done, release the valve manually ( see the link in my suggestions in the post above). Stir the spaghetti, breaking up any noodles that stuck together. Let it sit for a few minutes, soaking up the extra liquid.", - "name": "When it's done, release the valve manually ( see the link in my suggestions in the post above). Stir the spaghetti, breaking up any noodles that stuck together. Let it sit for a few minutes, soaking up the extra liquid.", - "url": "https://www.thekitchenmagpie.com/how-to-make-instant-pot-spaghetti/#wprm-recipe-44488-step-0-7", - "image": "https://www.thekitchenmagpie.com/wp-content/uploads/images/2018/02/instantpotspaghetti3.jpg" - } - ], - "aggregateRating": { - "@type": "AggregateRating", - "ratingValue": "5", - "ratingCount": "15" - }, - "recipeCategory": [ - "supper" - ], - "recipeCuisine": [ - "American" - ], - "keywords": "Instant Pot Spaghetti", - "nutrition": { - "@type": "NutritionInformation", - "calories": "222 kcal", - "carbohydrateContent": "5 g", - "proteinContent": "27 g", - "fatContent": "9 g", - "saturatedFatContent": "3 g", - "cholesterolContent": "70 mg", - "sodiumContent": "699 mg", - "fiberContent": "1 g", - "sugarContent": "2 g", - "servingSize": "1 serving" - }, - "@id": "https://www.thekitchenmagpie.com/how-to-make-instant-pot-spaghetti/#recipe", - "isPartOf": { - "@id": "https://www.thekitchenmagpie.com/how-to-make-instant-pot-spaghetti/#article" - }, - "mainEntityOfPage": "https://www.thekitchenmagpie.com/how-to-make-instant-pot-spaghetti/#webpage", - "url": "https://www.thekitchenmagpie.com/how-to-make-instant-pot-spaghetti/" -} \ No newline at end of file diff --git a/tests/data/scraper/recipes-raw/instant-pot-chicken-and-potatoes.json b/tests/data/scraper/recipes-raw/instant-pot-chicken-and-potatoes.json deleted file mode 100644 index 5793e48e7..000000000 --- a/tests/data/scraper/recipes-raw/instant-pot-chicken-and-potatoes.json +++ /dev/null @@ -1,82 +0,0 @@ -{ - "@context": "http://schema.org/", - "@type": "Recipe", - "name": "Instant Pot Chicken and Potatoes", - "author": { - "@type": "Person", - "name": "Tiffany" - }, - "description": "This is hands down the BEST Instant Pot Chicken and Potatoes recipe you'll ever try. Juicy ranch-seasoned chicken breast and parmesan potatoes cooked in 30 minutes in your pressure cooker - it doesn't get easier than this! ", - "datePublished": "2018-10-26T07:00:51+00:00", - "image": [ - "https://www.lecremedelacrumb.com/wp-content/uploads/2018/10/instant-pot-chicken-potatoes-2.jpg", - "https://www.lecremedelacrumb.com/wp-content/uploads/2018/10/instant-pot-chicken-potatoes-2-500x500.jpg", - "https://www.lecremedelacrumb.com/wp-content/uploads/2018/10/instant-pot-chicken-potatoes-2-500x375.jpg", - "https://www.lecremedelacrumb.com/wp-content/uploads/2018/10/instant-pot-chicken-potatoes-2-480x270.jpg" - ], - "recipeYield": [ - "4", - "4 people" - ], - "prepTime": "PT10M", - "cookTime": "PT15M", - "totalTime": "PT40M", - "recipeIngredient": [ - "4 boneless skinless chicken breasts", - "2 pounds baby red or gold potatoes", - "3 tablespoons olive oil", - "1 1/2 teaspoons salt (or to taste)", - "1/2 teaspoon pepper (or to taste)", - "1 teaspoon garlic powder", - "1 teaspoon dried thyme", - "1/2 teaspoon dried basil", - "1/2 teaspoon dried oregano", - "2 tablespoons + 2 teaspoons dry Ranch seasoning (divided)", - "1 cup chicken broth", - "3 tablespoons grated parmesan cheese" - ], - "recipeInstructions": [ - { - "@type": "HowToStep", - "text": "In a large bowl toss chicken and potatoes in the olive oil, then season with salt and pepper. Stir together garlic powder, thyme, basil, oregano, and 2 tablespoons of the Ranch seasoning. Sprinkle over the chicken and potatoes, tossing to distribute the ingredients as evenly as possible. ", - "name": "In a large bowl toss chicken and potatoes in the olive oil, then season with salt and pepper. Stir together garlic powder, thyme, basil, oregano, and 2 tablespoons of the Ranch seasoning. Sprinkle over the chicken and potatoes, tossing to distribute the ingredients as evenly as possible. ", - "url": "https://www.lecremedelacrumb.com/instant-pot-chicken-and-potatoes/#wprm-recipe-22284-step-0-0" - }, - { - "@type": "HowToStep", - "text": "Add chicken broth to the instant pot/pressure cooker, then place chicken in the broth, and top with the potatoes. Place the lid on in the locked position and turn the vent to the sealed position. Set pressure cooker to \"pressure cook\" for 15 minutes.", - "name": "Add chicken broth to the instant pot/pressure cooker, then place chicken in the broth, and top with the potatoes. Place the lid on in the locked position and turn the vent to the sealed position. Set pressure cooker to \"pressure cook\" for 15 minutes.", - "url": "https://www.lecremedelacrumb.com/instant-pot-chicken-and-potatoes/#wprm-recipe-22284-step-0-1" - }, - { - "@type": "HowToStep", - "text": "Once the cook time is finished, do a \"quick release\" by turning the vent to the venting position. Once float valve has dropped, remove the lid. Drain the pressure cooker or use a slotted spoon to transfer chicken and potatoes to a large platter. ", - "name": "Once the cook time is finished, do a \"quick release\" by turning the vent to the venting position. Once float valve has dropped, remove the lid. Drain the pressure cooker or use a slotted spoon to transfer chicken and potatoes to a large platter. ", - "url": "https://www.lecremedelacrumb.com/instant-pot-chicken-and-potatoes/#wprm-recipe-22284-step-0-2" - }, - { - "@type": "HowToStep", - "text": "Sprinkle with Ranch seasoning and parmesan cheese and garnish with chopped thyme or parsley if desired before serving. ", - "name": "Sprinkle with Ranch seasoning and parmesan cheese and garnish with chopped thyme or parsley if desired before serving. ", - "url": "https://www.lecremedelacrumb.com/instant-pot-chicken-and-potatoes/#wprm-recipe-22284-step-0-3" - } - ], - "aggregateRating": { - "@type": "AggregateRating", - "ratingValue": "4.76", - "ratingCount": "225" - }, - "recipeCategory": [ - "Main Course" - ], - "recipeCuisine": [ - "American" - ], - "keywords": "Chicken, healthy, instant pot, mashed potatoes, pressure cooker, ranch", - "@id": "https://www.lecremedelacrumb.com/instant-pot-chicken-and-potatoes/#recipe", - "isPartOf": { - "@id": "https://www.lecremedelacrumb.com/instant-pot-chicken-and-potatoes/#article" - }, - "mainEntityOfPage": "https://www.lecremedelacrumb.com/instant-pot-chicken-and-potatoes/#webpage", - "url": "https://www.lecremedelacrumb.com/instant-pot-chicken-and-potatoes/" -} \ No newline at end of file diff --git a/tests/data/scraper/recipes-raw/instant-pot-kerala-vegetable-stew.json b/tests/data/scraper/recipes-raw/instant-pot-kerala-vegetable-stew.json deleted file mode 100644 index 7cc743510..000000000 --- a/tests/data/scraper/recipes-raw/instant-pot-kerala-vegetable-stew.json +++ /dev/null @@ -1,166 +0,0 @@ -{ - "@context": "http://schema.org/", - "@type": "Recipe", - "name": "How to make Instant Pot Kerala Vegetable Stew", - "author": { - "@type": "Person", - "name": "Dhwani" - }, - "description": "Instant Pot Kerala Vegetable Stew - A complete Comfort and Satisfying food that can be made in a fraction of the time. Veg Stew is Vegetarian / Vegan Instant Pot Recipe with lots of vegetables in coconut milk based hearty sauce that will change your life.", - "datePublished": "2019-01-16T19:25:09+00:00", - "image": [ - "https://cdn.cookingcarnival.com/wp-content/uploads/2019/01/Instant-Pot-Kerala-Vegetable-Stew-2.jpg", - "https://cdn.cookingcarnival.com/wp-content/uploads/2019/01/Instant-Pot-Kerala-Vegetable-Stew-2-500x500.jpg", - "https://cdn.cookingcarnival.com/wp-content/uploads/2019/01/Instant-Pot-Kerala-Vegetable-Stew-2-500x375.jpg", - "https://cdn.cookingcarnival.com/wp-content/uploads/2019/01/Instant-Pot-Kerala-Vegetable-Stew-2-480x270.jpg" - ], - "video": { - "name": "Instant Pot Kerala Vegetable Stew | Vegan stew recipe | vegetable Stew recipe in instant Pot", - "description": "Instant Pot Kerala Vegetable Stew - A complete Comfort and Satisfying food that can be made in a fraction of the time. Veg Stew is Vegetarian / Vegan Instant Pot Recipe with lots of vegetables in coconut milk based hearty sauce that will change your life.\n\nDetailed Recipe of Instant pot Kerela vegetable stew https://www.cookingcarnival.com/instant-pot-kerala-vegetable-stew/\nOfficial Facebook Page: https://www.facebook.com/cookingcarnival\n\nPinterest: https://www.pinterest.com/cookingcarnival/\n\nTwitter: https://twitter.com/carnivalcooking\n\nGoogle Plus: https://plus.google.com/+Cookingcarnival\n\nInstagram: https://www.instagram.com/cookingcarnival", - "uploadDate": "2019-01-17T19:46:14+00:00", - "duration": "PT2M17S", - "thumbnailUrl": "https://i.ytimg.com/vi/pej98AtiBWE/hqdefault.jpg", - "contentUrl": "https://youtu.be/pej98AtiBWE", - "embedUrl": "https://www.youtube.com/embed/pej98AtiBWE?feature=oembed", - "@type": "VideoObject" - }, - "recipeYield": [ - "4", - "4 people" - ], - "prepTime": "PT10M", - "cookTime": "PT10M", - "totalTime": "PT20M", - "recipeIngredient": [ - "2 cups - Cauliflower florets", - "1 cup - Chopped carrots", - "1 1/2 cup - Bell Peppers (chopped)", - "2 cups - Potatoes (Chopped)", - "3/4 cup - Chopped Onions", - "1 cup - Green beans (Chopped)", - "1 tsp - Ginger paste", - "1/2 tsp - Chili ((adust according to your liking) )", - "1 tsp - Garlic paste", - "2 - Cardamom Pods (See Notes)", - "1 inch - Cinnamon stick", - "3 - Cloves", - "20 Pieces - Whole Cashew Nuts", - "1 cup - Coconut milk (See Notes)", - "Salt to taste", - "1/2 tsp - White Pepper Powder (see notes)", - "2 tbsp - Oil (See Notes)", - "2 cups - Water" - ], - "recipeInstructions": [ - { - "@type": "HowToStep", - "text": "Turn on saute button of your IP.", - "name": "Turn on saute button of your IP.", - "url": "https://www.cookingcarnival.com/instant-pot-kerala-vegetable-stew/#wprm-recipe-8126-step-0-0" - }, - { - "@type": "HowToStep", - "text": "Heat oil in a pot, add cardamom pods, cinnamon stick, and cloves.", - "name": "Heat oil in a pot, add cardamom pods, cinnamon stick, and cloves.", - "url": "https://www.cookingcarnival.com/instant-pot-kerala-vegetable-stew/#wprm-recipe-8126-step-0-1" - }, - { - "@type": "HowToStep", - "text": "Now add ginger, garlic, chili and onions. Saute for few seconds.", - "name": "Now add ginger, garlic, chili and onions. Saute for few seconds.", - "url": "https://www.cookingcarnival.com/instant-pot-kerala-vegetable-stew/#wprm-recipe-8126-step-0-2" - }, - { - "@type": "HowToStep", - "text": "Add all the vegetables, salt, white pepper powder and water. Mix well.", - "name": "Add all the vegetables, salt, white pepper powder and water. Mix well.", - "url": "https://www.cookingcarnival.com/instant-pot-kerala-vegetable-stew/#wprm-recipe-8126-step-0-3" - }, - { - "@type": "HowToStep", - "text": "Cover your Instant pot with locking lid.", - "name": "Cover your Instant pot with locking lid.", - "url": "https://www.cookingcarnival.com/instant-pot-kerala-vegetable-stew/#wprm-recipe-8126-step-0-4" - }, - { - "@type": "HowToStep", - "text": "Turn off IP.", - "name": "Turn off IP.", - "url": "https://www.cookingcarnival.com/instant-pot-kerala-vegetable-stew/#wprm-recipe-8126-step-0-5" - }, - { - "@type": "HowToStep", - "text": "Press the manual or pressure cook button. Cook on high pressure for 3 minutes with pressure valve in the sealing position.", - "name": "Press the manual or pressure cook button. Cook on high pressure for 3 minutes with pressure valve in the sealing position.", - "url": "https://www.cookingcarnival.com/instant-pot-kerala-vegetable-stew/#wprm-recipe-8126-step-0-6" - }, - { - "@type": "HowToStep", - "text": "Meanwhile, take whole cashew and coconut milk in a blender jar and blend them well in to a smooth paste. Keep it aside.", - "name": "Meanwhile, take whole cashew and coconut milk in a blender jar and blend them well in to a smooth paste. Keep it aside.", - "url": "https://www.cookingcarnival.com/instant-pot-kerala-vegetable-stew/#wprm-recipe-8126-step-0-7" - }, - { - "@type": "HowToStep", - "text": "Once IP beeps and when you see LO:00, turn off your IP and quick release the pressure.", - "name": "Once IP beeps and when you see LO:00, turn off your IP and quick release the pressure.", - "url": "https://www.cookingcarnival.com/instant-pot-kerala-vegetable-stew/#wprm-recipe-8126-step-0-8" - }, - { - "@type": "HowToStep", - "text": "10. Open the Instant Pot, add prepared cashew-coconut paste. Stir well.", - "name": "10. Open the Instant Pot, add prepared cashew-coconut paste. Stir well.", - "url": "https://www.cookingcarnival.com/instant-pot-kerala-vegetable-stew/#wprm-recipe-8126-step-0-9" - }, - { - "@type": "HowToStep", - "text": "11. Turn on saute button and cook it for 1 to 2 more minutes, until everything well combined.", - "name": "11. Turn on saute button and cook it for 1 to 2 more minutes, until everything well combined.", - "url": "https://www.cookingcarnival.com/instant-pot-kerala-vegetable-stew/#wprm-recipe-8126-step-0-10" - }, - { - "@type": "HowToStep", - "text": "12. Switch off the IP.", - "name": "12. Switch off the IP.", - "url": "https://www.cookingcarnival.com/instant-pot-kerala-vegetable-stew/#wprm-recipe-8126-step-0-11" - }, - { - "@type": "HowToStep", - "text": "13. Instant Pot Kerala Vegetable Stew is ready. Enjoy!!", - "name": "13. Instant Pot Kerala Vegetable Stew is ready. Enjoy!!", - "url": "https://www.cookingcarnival.com/instant-pot-kerala-vegetable-stew/#wprm-recipe-8126-step-0-12" - } - ], - "aggregateRating": { - "@type": "AggregateRating", - "ratingValue": "4.88", - "ratingCount": "8" - }, - "recipeCategory": [ - "Main Course", - "Soups and Stew" - ], - "recipeCuisine": [ - "American", - "Indian" - ], - "keywords": "Easy vegan instant pot recipe, Instant pot, Vegetable Stew", - "nutrition": { - "@type": "NutritionInformation", - "servingSize": "1 person", - "calories": "201 kcal", - "carbohydrateContent": "24 g", - "proteinContent": "4 g", - "fatContent": "10 g", - "saturatedFatContent": "1 g", - "sodiumContent": "56 mg", - "fiberContent": "5 g", - "sugarContent": "9 g" - }, - "@id": "https://www.cookingcarnival.com/instant-pot-kerala-vegetable-stew/#recipe", - "isPartOf": { - "@id": "https://www.cookingcarnival.com/instant-pot-kerala-vegetable-stew/#article" - }, - "mainEntityOfPage": "https://www.cookingcarnival.com/instant-pot-kerala-vegetable-stew/#webpage", - "url": "https://www.cookingcarnival.com/instant-pot-kerala-vegetable-stew/" -} \ No newline at end of file diff --git a/tests/data/scraper/recipes-raw/jalapeno-popper-dip.json b/tests/data/scraper/recipes-raw/jalapeno-popper-dip.json deleted file mode 100644 index 867ab26ac..000000000 --- a/tests/data/scraper/recipes-raw/jalapeno-popper-dip.json +++ /dev/null @@ -1,89 +0,0 @@ -{ - "@context": "http://schema.org/", - "@type": "Recipe", - "name": "Jalape\u00f1o Popper Dip", - "author": { - "@type": "Person", - "name": "Michelle" - }, - "description": "Jalapeno Popper Dip is creamy, cheesy and has just the perfect amount of kick. Great appetizer for your next party or watching the big game!", - "datePublished": "2016-02-22T00:01:37+00:00", - "image": [ - "https://www.browneyedbaker.com/wp-content/uploads/2011/08/jalapeno-popper-dip-6-600.jpg" - ], - "recipeYield": [ - "10", - "10 to 12 servings" - ], - "prepTime": "PT15M", - "cookTime": "PT30M", - "totalTime": "PT45M", - "recipeIngredient": [ - "16 ounces cream cheese (at room temperature)", - "1 cup mayonnaise", - "8 pieces of bacon (cooked and chopped)", - "6 jalape\u00f1os (seeded and minced (if you can't get fresh, substitute a 4-ounce can diced jalape\u00f1o peppers, drained))", - "2 cloves garlic (minced)", - "\u00bd teaspoon cumin", - "6 ounces cheddar cheese (shredded (about 1\u00bd cups))", - "1 cup panko breadcrumbs", - "1 cup grated Parmesan cheese", - "4 tablespoons unsalted butter, melted" - ], - "recipeInstructions": [ - { - "@type": "HowToStep", - "text": "Preheat oven to 375 degrees F.", - "name": "Preheat oven to 375 degrees F.", - "url": "https://www.browneyedbaker.com/jalapeno-popper-dip/#wprm-recipe-44993-step-0-0" - }, - { - "@type": "HowToStep", - "text": "Combine the cream cheese, mayonnaise, bacon, jalapenos, garlic, cumin and cheddar cheese in a mixing bowl. Transfer the mixture into 2-quart baking dish.", - "name": "Combine the cream cheese, mayonnaise, bacon, jalapenos, garlic, cumin and cheddar cheese in a mixing bowl. Transfer the mixture into 2-quart baking dish.", - "url": "https://www.browneyedbaker.com/jalapeno-popper-dip/#wprm-recipe-44993-step-0-1" - }, - { - "@type": "HowToStep", - "text": "Combine the panko breadcrumbs, Parmesan cheese and melted butter in a small bowl, tossing with a fork until the mixture is evenly moistened. Sprinkle evenly over the cream cheese mixture.", - "name": "Combine the panko breadcrumbs, Parmesan cheese and melted butter in a small bowl, tossing with a fork until the mixture is evenly moistened. Sprinkle evenly over the cream cheese mixture.", - "url": "https://www.browneyedbaker.com/jalapeno-popper-dip/#wprm-recipe-44993-step-0-2" - }, - { - "@type": "HowToStep", - "text": "Bake in the preheated oven for 25 to 30 minutes, until the top is golden brown and the dip is bubbling. Let rest for 5 minutes before serving. Serve with your favorite tortilla chips, crackers, vegetables, etc.", - "name": "Bake in the preheated oven for 25 to 30 minutes, until the top is golden brown and the dip is bubbling. Let rest for 5 minutes before serving. Serve with your favorite tortilla chips, crackers, vegetables, etc.", - "url": "https://www.browneyedbaker.com/jalapeno-popper-dip/#wprm-recipe-44993-step-0-3" - } - ], - "aggregateRating": { - "@type": "AggregateRating", - "ratingValue": "4.34", - "ratingCount": "15" - }, - "recipeCategory": [ - "Appetizer" - ], - "recipeCuisine": [ - "American" - ], - "keywords": "cheese dip, game day food, party food", - "nutrition": { - "@type": "NutritionInformation", - "calories": "560 kcal", - "carbohydrateContent": "7 g", - "proteinContent": "14 g", - "fatContent": "52 g", - "saturatedFatContent": "21 g", - "cholesterolContent": "109 mg", - "sodiumContent": "707 mg", - "sugarContent": "2 g", - "servingSize": "1 serving" - }, - "@id": "https://www.browneyedbaker.com/jalapeno-popper-dip/#recipe", - "isPartOf": { - "@id": "https://www.browneyedbaker.com/jalapeno-popper-dip/#article" - }, - "mainEntityOfPage": "https://www.browneyedbaker.com/jalapeno-popper-dip/#webpage", - "url": "https://www.browneyedbaker.com/jalapeno-popper-dip/" -} \ No newline at end of file diff --git a/tests/data/scraper/recipes-raw/microwave_sweet_potatoes_04783.json b/tests/data/scraper/recipes-raw/microwave_sweet_potatoes_04783.json deleted file mode 100644 index 74a07ae91..000000000 --- a/tests/data/scraper/recipes-raw/microwave_sweet_potatoes_04783.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "@context": "https://schema.org", - "@type": "Recipe", - "aggregateRating": { - "ratingCount": 3, - "ratingValue": 4 - }, - "author": { - "@type": "Person", - "name": "Justine Pattison" - }, - "cookTime": "PT10M", - "description": "Microwave jacket sweet potatoes make a wonderfully quick and easy meal. Take your pick of these three delicious fillings, or make all of them! The veggie chilli makes enough for four portions, great for lunch tomorrow. The smoked mackerel and pea fillings each make enough for two portions. \r\n\r\nThis recipe was tested using a 900W microwave oven. If your oven has more or fewer watts, you will need to adjust the cooking time.\r\n", - "image": [ - "https://food-images.files.bbci.co.uk/food/recipes/microwave_sweet_potatoes_04783_16x9.jpg" - ], - "keywords": "quick, jacket potato dinners, microwave recipes , quick and cheap dinners, quick delicious lunches, easy family dinners, lunch, student food, Jacket potato, sweet potato, peas, egg free, gluten free, nut free, pregnancy friendly", - "name": "Microwave jacket sweet potato ", - "prepTime": "PT30M", - "recipeCategory": "Main course", - "recipeIngredient": [ - "2 sweet potatoes, washed and dried", - "75g/2\u00bdoz smoked mackerel, skinned and roughly mashed with a fork", - "3 tbsp half-fat cr\u00e8me fra\u00eeche or soured cream", - "2 spring onions, trimmed and thinly sliced", - "\u00bd unwaxed lemon, finely grated zest only", - "freshly ground black pepper ", - "100g/3\u00bdoz frozen peas", - "100g/3\u00bdoz feta ", - "2 tbsp plain yoghurt", - "1 tbsp finely chopped fresh mint", - "freshly ground black pepper ", - "\u00bd red pepper, deseeded and diced", - "400g tin kidney beans in chilli sauce", - "198g tin sweetcorn in water", - "1 tbsp fresh lime juice", - "50g/1\u00beoz mature Cheddar, coarsely grated", - "4 tbsp soured cream", - "fresh coriander, to garnish", - "1 lime, cut into wedges, to serve" - ], - "recipeInstructions": [ - "Prick the sweet potatoes two or three times with a fork and put on a microwaveable plate. Microwave on high for 5\u20136 minutes for one potato or 7\u20138 minutes for two. Test the potatoes are soft by inserting a skewer through the middle, it should slide in easily. If the potatoes remain a little hard, cook for longer, testing again every 30 seconds. Divide the potatoes between plates, make a cross in the centre and open to fill.", - "To make the smoked mackerel filling, mix all the ingredients together and season with lots of black pepper.", - "To make the pea and feta filling, microwave the peas on high for 2\u20133 minutes, until thawed and just warm. Mash them with a fork, until well broken up, then mix in the feta, yoghurt and mint. Season with lots of black pepper.", - "To make the veggie chilli filling, put the red pepper in a large microwavable bowl and cook on high for 1\u00bd\u20132 minutes, until soft. Add the beans and sweetcorn in its water, stir well and microwave on high for 4\u20135 minutes, until hot. Stir in the lime juice and mix well. Spoon into the cooked sweet potatoes and top with the cheese. Microwave for 1\u20132 minutes, until the cheese melts. Top with the soured cream, coriander and lime wedges. " - ], - "recipeYield": "Serves 2", - "suitableForDiet": [ - "http://schema.org/GlutenFreeDiet" - ], - "url": "https://www.bbc.co.uk/food/recipes/microwave_sweet_potatoes_04783" -} \ No newline at end of file diff --git a/tests/data/scraper/recipes-raw/moroccan-skirt-steak-with-roasted-pepper-couscous.json b/tests/data/scraper/recipes-raw/moroccan-skirt-steak-with-roasted-pepper-couscous.json deleted file mode 100644 index d25ee93d2..000000000 --- a/tests/data/scraper/recipes-raw/moroccan-skirt-steak-with-roasted-pepper-couscous.json +++ /dev/null @@ -1,243 +0,0 @@ -{ - "@context": "http://schema.org", - "@type": "Recipe", - "mainEntityOfPage": "http://www.eatingwell.com/recipe/249961/moroccan-skirt-steak-with-roasted-pepper-couscous/", - "name": "Moroccan Skirt Steak with Roasted Pepper Couscous", - "image": { - "@type": "ImageObject", - "url": "https://imagesvc.meredithcorp.io/v3/mm/image?url=https%3A%2F%2Fstatic.onecms.io%2Fwp-content%2Fuploads%2Fsites%2F44%2F2019%2F08%2F26231251%2F3757257.jpg", - "width": 960, - "height": 960 - }, - "datePublished": "2016-06-03T04:27:31.000Z", - "description": "Thin cuts of beef, such as skirt steak or sirloin steak, cook very quickly when seared in a hot skillet--just right for a busy weeknight. We love how the spicy Moroccan flavors on the steak complement the sweet, roasted pepper-studded couscous. Serve with: Arugula salad and a glass of Pinot Noir.", - "prepTime": null, - "cookTime": null, - "totalTime": "P0DT0H35M", - "recipeIngredient": [ - "2 medium bell peppers", - "1 teaspoon ground cumin", - "1 teaspoon ground coriander", - "\u00be teaspoon salt", - "\u00bd teaspoon ground turmeric", - "\u00bd teaspoon ground cinnamon", - "\u00bd teaspoon freshly ground pepper", - "1 whole lemon, plus more lemon wedges for garnish", - "1 tablespoon 1 teaspoon plus 1 tablespoon extra-virgin olive oil, divided", - "\u2154 cup whole-wheat couscous", - "1 pound 1 pound skirt steak (see Note) or sirloin steak, 3/4 to 1 inch thick, trimmed", - "2 tablespoons chopped green olives" - ], - "recipeInstructions": [ - { - "@type": "HowToStep", - "text": "Position rack in upper third of oven; preheat broiler.\n" - }, - { - "@type": "HowToStep", - "text": "Place bell peppers on a baking sheet and roast under the broiler, turning every 5 minutes, until charred and softened, 10 to 15 minutes. Transfer to a clean cutting board; when cool enough to handle, chop the peppers into bite-size pieces.\n" - }, - { - "@type": "HowToStep", - "text": "Meanwhile, combine cumin, coriander, salt, turmeric, cinnamon and pepper in a small bowl. Grate 1/2 teaspoon zest from the lemon. Juice the lemon into a 1-cup measure and add enough water to make 1 cup. Pour into a small saucepan and add the lemon zest, 1 teaspoon of the spice mixture and 1 teaspoon olive oil. Bring to a boil. Stir in couscous, cover, remove from heat and let stand.\n" - }, - { - "@type": "HowToStep", - "text": "Heat the remaining 1 tablespoon oil in a large skillet (preferably cast-iron) over medium heat until shimmering (but not smoking). Rub the remaining spice mixture on both sides of steak. Cook the steak 2 to 3 minutes per side for medium-rare. Let rest on the cutting board for 5 minutes. Stir olives and the peppers into the couscous. Thinly slice the steak and serve with the couscous and lemon wedges, if desired.\n" - } - ], - "recipeCategory": [ - "Healthy Recipes", - "Healthy Ingredient Recipes", - "Healthy Meat & Poultry Recipes", - "Healthy Beef Recipes", - "Healthy Steak Recipes", - "Healthy New York Strip Steak Recipes" - ], - "recipeCuisine": [], - "author": [ - { - "@type": "Person", - "name": "EatingWell Test Kitchen" - } - ], - "aggregateRating": { - "@type": "AggregateRating", - "ratingValue": 4.538461538461538, - "ratingCount": 13, - "itemReviewed": "Moroccan Skirt Steak with Roasted Pepper Couscous", - "bestRating": "5", - "worstRating": "1" - }, - "nutrition": { - "@type": "NutritionInformation", - "calories": "453.7 calories", - "carbohydrateContent": "36 g", - "cholesterolContent": "96.4 mg", - "fatContent": "18.4 g", - "fiberContent": "6.5 g", - "proteinContent": "36.4 g", - "saturatedFatContent": "5.1 g", - "servingSize": null, - "sodiumContent": "663.3 mg", - "sugarContent": null, - "transFatContent": null, - "unsaturatedFatContent": null - }, - "review": [ - { - "@type": "Review", - "datePublished": "2011-10-30T21:53:57Z", - "reviewBody": "Wow! This steak was fabulous. Full of flavor even my kids liked it. The spices for the steak rub get added to the cous cous. Along with the sweet roasted peppers it was so delicious.", - "reviewRating": { - "@type": "Rating", - "worstRating": "1", - "bestRating": "5", - "ratingValue": 5 - }, - "author": { - "@type": "Person", - "name": "shari_martinez@sbcglobal.net", - "image": null, - "sameAs": "https://www.allrecipes.com/cook/18308949/" - } - }, - { - "@type": "Review", - "datePublished": "2011-10-30T02:40:11Z", - "reviewBody": "Not as well received as I had hoped The leftovers were good as a steak salad with honey-mustard seasoning although Kaja did not like the seasoned meat that way. I ate some couscous on my salad too. Leftover steak is unheard of at our house yet there it was. Offerred the kids a choice of unspiced steak (three takers) and Rice-a-Roni (four takers) Austin & I liked the steak Pros: Easy I liked it Cons: Nobody liked the couscous except me", - "reviewRating": { - "@type": "Rating", - "worstRating": "1", - "bestRating": "5", - "ratingValue": 3 - }, - "author": { - "@type": "Person", - "name": "Ellen", - "image": null, - "sameAs": "https://www.allrecipes.com/cook/19797391/" - } - }, - { - "@type": "Review", - "datePublished": "2011-10-30T03:02:54Z", - "reviewBody": "tasty and easy weeknight meal Initially I was a little leery of using cinnamon to season the meat but it actually turned out very good. The seasoning had a tasty and light flavor. I used sirloin because the skirt steak at the store looked very fatty. The couscous (although I didn't add the olives because I'm not a huge fan) was also very good and I enjoyed the sweetness of the bell pepper. I used the lemon garnish to squeeze over the couscous and meat and think it made it. I would definitely make this again! Pros: Tasty and easy weeknight meal", - "reviewRating": { - "@type": "Rating", - "worstRating": "1", - "bestRating": "5", - "ratingValue": 4 - }, - "author": { - "@type": "Person", - "name": "Kat Y", - "image": null, - "sameAs": "https://www.allrecipes.com/cook/2343563/" - } - }, - { - "@type": "Review", - "datePublished": "2011-10-30T17:25:23Z", - "reviewBody": "This was really good. It was definitely a change from what we're used to but in a good way. I had to use skillet steak because I couldn't find any skirt steak but it worked just fine. I also used the grill for the peppers and steak because my broiler is a bit questionable. Other than that I made it as stated and my husband and I really enjoyed it. A great out of the ordinary quick meal.", - "reviewRating": { - "@type": "Rating", - "worstRating": "1", - "bestRating": "5", - "ratingValue": 5 - }, - "author": { - "@type": "Person", - "name": "EatingWell User", - "image": null, - "sameAs": "https://www.allrecipes.com/cook/eatingwelluser/" - } - }, - { - "@type": "Review", - "datePublished": "2011-10-30T03:41:53Z", - "reviewBody": "I love this recipe so much that I schedule it my meal planning as often as possible. The flavors with this cut of meat are just wonderful. I can't eat grains so I pair it with fennel. Perfect!", - "reviewRating": { - "@type": "Rating", - "worstRating": "1", - "bestRating": "5", - "ratingValue": 5 - }, - "author": { - "@type": "Person", - "name": "EatingWell User", - "image": null, - "sameAs": "https://www.allrecipes.com/cook/eatingwelluser/" - } - }, - { - "@type": "Review", - "datePublished": "2013-02-20T17:33:48Z", - "reviewBody": "Great starting point! I like this one a lot but I would recommend the version of it on funnytummycafe.com. I've not been really adventurous with new flavors but this I will repeat! Pros: Wonderful flavors in the rub Cons: The couscous was TOO lemony", - "reviewRating": { - "@type": "Rating", - "worstRating": "1", - "bestRating": "5", - "ratingValue": 3 - }, - "author": { - "@type": "Person", - "name": "EatingWell User", - "image": null, - "sameAs": "https://www.allrecipes.com/cook/eatingwelluser/" - } - }, - { - "@type": "Review", - "datePublished": "2011-10-30T15:06:11Z", - "reviewBody": "I made this with chicken instead of steak and it was great! My husband has not liked couscous in the past but he really liked this version. Will definitely make again!", - "reviewRating": { - "@type": "Rating", - "worstRating": "1", - "bestRating": "5", - "ratingValue": 5 - }, - "author": { - "@type": "Person", - "name": "EatingWell User", - "image": null, - "sameAs": "https://www.allrecipes.com/cook/eatingwelluser/" - } - }, - { - "@type": "Review", - "datePublished": "2011-10-30T12:15:53Z", - "reviewBody": "WOW! Blew me away this was a great meal! Tons of flavor really quick and very filling! I served brown rice instead of couscous because that's what I had on hand. The husband never knew the difference! I can always tell when something is a real winner with him because he goes back for seconds (we're both on diets). I used one red and one green bell pepper and served a spring mix salad with tomato and feta on the side. Big bravo to the EatingWell kitchen! This will definitely be made again in my house!", - "reviewRating": { - "@type": "Rating", - "worstRating": "1", - "bestRating": "5", - "ratingValue": 5 - }, - "author": { - "@type": "Person", - "name": "EatingWell User", - "image": null, - "sameAs": "https://www.allrecipes.com/cook/eatingwelluser/" - } - }, - { - "@type": "Review", - "datePublished": "2011-10-30T15:12:50Z", - "reviewBody": "Quick & easy to prepare with mild spiced flavor. The rub produces a great crust on the steak. I felt the lemon flavor dominated the cous cous though to be fair I did seem to have a particularly juicy lemon so that may be why. My husband and I both thought that the leftover steak would be superb sliced thinly in a sandwich with a mint/yogurt dressing.", - "reviewRating": { - "@type": "Rating", - "worstRating": "1", - "bestRating": "5", - "ratingValue": 5 - }, - "author": { - "@type": "Person", - "name": "EatingWell User", - "image": null, - "sameAs": "https://www.allrecipes.com/cook/eatingwelluser/" - } - } - ], - "url": "http://www.eatingwell.com/recipe/249961/moroccan-skirt-steak-with-roasted-pepper-couscous/" -} \ No newline at end of file diff --git a/tests/integration_tests/recipe_migration_tests/test_recipe_migrations.py b/tests/integration_tests/recipe_migration_tests/test_recipe_migrations.py new file mode 100644 index 000000000..848114e98 --- /dev/null +++ b/tests/integration_tests/recipe_migration_tests/test_recipe_migrations.py @@ -0,0 +1,55 @@ +from dataclasses import dataclass +from pathlib import Path + +import pytest +from fastapi.testclient import TestClient + +from mealie.schema.group.group_migration import SupportedMigrations +from tests import data as test_data +from tests.utils.fixture_schemas import TestUser + + +class Routes: + base = "/api/groups/migrations" + + def report(item_id: str) -> str: + return f"/api/groups/reports/{item_id}" + + +@dataclass +class MigrationTestData: + typ: SupportedMigrations + archive: Path + + +test_cases = [ + MigrationTestData(typ=SupportedMigrations.nextcloud, archive=test_data.migrations_nextcloud), + MigrationTestData(typ=SupportedMigrations.paprika, archive=test_data.migrations_paprika), + MigrationTestData(typ=SupportedMigrations.chowdown, archive=test_data.migrations_chowdown), + MigrationTestData(typ=SupportedMigrations.mealie_alpha, archive=test_data.migrations_mealie), +] + + +@pytest.mark.parametrize("mig", test_cases) +def test_recipe_migration(api_client: TestClient, unique_user: TestUser, mig: MigrationTestData) -> None: + payload = { + "migration_type": mig.typ.value, + } + + file_payload = { + "archive": mig.archive.read_bytes(), + } + + response = api_client.post(Routes.base, data=payload, files=file_payload, headers=unique_user.token) + + assert response.status_code == 200 + + report_id = response.json()["id"] + + # Validate Results + response = api_client.get(Routes.report(report_id), headers=unique_user.token) + + assert response.status_code == 200 + + for item in response.json()["entries"]: + assert item["success"] diff --git a/tests/integration_tests/test_migration_routes.py b/tests/integration_tests/test_migration_routes.py deleted file mode 100644 index ba3a01fa6..000000000 --- a/tests/integration_tests/test_migration_routes.py +++ /dev/null @@ -1,49 +0,0 @@ -from pathlib import Path - -import pytest -from fastapi.testclient import TestClient - -from tests.test_config import TEST_CHOWDOWN_DIR, TEST_NEXTCLOUD_DIR -from tests.utils.fixture_schemas import TestUser - - -class Routes: - base = "/api/groups/migrations" - - @staticmethod - def report(item_id: str) -> str: - return f"/api/groups/reports/{item_id}" - - -@pytest.mark.parametrize( - "m_type, zip_path", - [ - ("nextcloud", TEST_NEXTCLOUD_DIR.joinpath("nextcloud.zip")), - ("chowdown", TEST_CHOWDOWN_DIR.joinpath("test_chowdown-gh-pages.zip")), - ], -) -def test_migration_nextcloud(api_client: TestClient, zip_path: Path, m_type: str, unique_user: TestUser): - payload = { - "archive": zip_path.read_bytes(), - } - - data = { - "migration_type": m_type, - } - - response = api_client.post(Routes.base, data=data, files=payload, headers=unique_user.token) - - assert response.status_code == 200 - - id = response.json()["id"] - - response = api_client.get(Routes.report(id), headers=unique_user.token) - - assert response.status_code == 200 - - report = response.json() - - assert report.get("status") == "success" - - for entry in report.get("entries"): - assert entry.get("success") is True diff --git a/tests/test_config.py b/tests/test_config.py deleted file mode 100644 index 1f040f1bc..000000000 --- a/tests/test_config.py +++ /dev/null @@ -1,17 +0,0 @@ -from pathlib import Path - -CWD = Path(__file__).parent - - -TEST_DIR = CWD -TEST_DATA = CWD.joinpath("data") - -# Scraper -TEST_RAW_HTML = TEST_DATA.joinpath("scraper", "html-raw") -TEST_RAW_RECIPES = TEST_DATA.joinpath("scraper", "recipes-raw") - -# Migrations -TEST_CHOWDOWN_DIR = TEST_DATA.joinpath("migrations", "chowdown") -TEST_NEXTCLOUD_DIR = TEST_DATA.joinpath("migrations", "nextcloud") - -TEST_HTML_DIR = TEST_DATA.joinpath("html") diff --git a/tests/unit_tests/test_cleaner.py b/tests/unit_tests/test_cleaner.py index dce814396..733aa6f3e 100644 --- a/tests/unit_tests/test_cleaner.py +++ b/tests/unit_tests/test_cleaner.py @@ -1,12 +1,13 @@ import json import re from datetime import timedelta +from pathlib import Path import pytest from mealie.services.scraper import cleaner from mealie.services.scraper.scraper_strategies import RecipeScraperOpenGraph -from tests.test_config import TEST_RAW_HTML, TEST_RAW_RECIPES +from tests import data as test_data # https://github.com/django/django/blob/stable/1.3.x/django/core/validators.py#L45 url_validation_regex = re.compile( @@ -19,29 +20,28 @@ url_validation_regex = re.compile( re.IGNORECASE, ) +test_cleaner_data = [ + (test_data.json_best_homemade_salsa_recipe, 2), + (test_data.json_blue_cheese_stuffed_turkey_meatballs_with_raspberry_balsamic_glaze_2, 3), + (test_data.json_bon_appetit, 8), + (test_data.json_chunky_apple_cake, 4), + (test_data.json_dairy_free_impossible_pumpkin_pie, 7), + (test_data.json_how_to_make_instant_pot_spaghetti, 8), + (test_data.json_instant_pot_chicken_and_potatoes, 4), + (test_data.json_instant_pot_kerala_vegetable_stew, 13), + (test_data.json_jalapeno_popper_dip, 4), + (test_data.json_microwave_sweet_potatoes_04783, 4), + (test_data.json_moroccan_skirt_steak_with_roasted_pepper_couscous, 4), + (test_data.json_pizza_knoblauch_champignon_paprika_vegan_html, 3), +] + @pytest.mark.parametrize( "json_file,num_steps", - [ - ("best-homemade-salsa-recipe.json", 2), - ( - "blue-cheese-stuffed-turkey-meatballs-with-raspberry-balsamic-glaze-2.json", - 3, - ), - ("bon_appetit.json", 8), - ("chunky-apple-cake.json", 4), - ("dairy-free-impossible-pumpkin-pie.json", 7), - ("how-to-make-instant-pot-spaghetti.json", 8), - ("instant-pot-chicken-and-potatoes.json", 4), - ("instant-pot-kerala-vegetable-stew.json", 13), - ("jalapeno-popper-dip.json", 4), - ("microwave_sweet_potatoes_04783.json", 4), - ("moroccan-skirt-steak-with-roasted-pepper-couscous.json", 4), - ("Pizza-Knoblauch-Champignon-Paprika-vegan.html.json", 3), - ], + test_cleaner_data, ) -def test_cleaner_clean(json_file, num_steps): - recipe_data = cleaner.clean(json.load(open(TEST_RAW_RECIPES.joinpath(json_file)))) +def test_cleaner_clean(json_file: Path, num_steps): + recipe_data = cleaner.clean(json.loads(json_file.read_text())) assert len(recipe_data["recipeInstructions"]) == num_steps @@ -98,7 +98,7 @@ def test_cleaner_instructions(instructions): def test_html_with_recipe_data(): - path = TEST_RAW_HTML.joinpath("healthy_pasta_bake_60759.html") + path = test_data.html_healthy_pasta_bake_60759 url = "https://www.bbc.co.uk/food/recipes/healthy_pasta_bake_60759" open_graph_strategy = RecipeScraperOpenGraph(url) @@ -120,7 +120,7 @@ def test_html_with_recipe_data(): ("PT3H", "3 Hours"), ("P1DT1H1M1S", "1 day 1 Hour 1 Minute 1 Second"), ("P1DT1H1M1.53S", "1 day 1 Hour 1 Minute 1 Second"), - ("PT-3H", None), + ("PT-3H", "PT-3H"), ("PT", "none"), ], ) diff --git a/tests/unit_tests/test_nextcloud.py b/tests/unit_tests/test_nextcloud.py deleted file mode 100644 index 8b33ca062..000000000 --- a/tests/unit_tests/test_nextcloud.py +++ /dev/null @@ -1,39 +0,0 @@ -# import shutil -# from pathlib import Path - -# import pytest -# from mealie.core.config import app_dirs -# from mealie.schema.recipe import Recipe -# from tests.test_config import TEST_NEXTCLOUD_DIR - -# CWD = Path(__file__).parent -# TEST_NEXTCLOUD_DIR -# TEMP_NEXTCLOUD = app_dirs.TEMP_DIR.joinpath("nextcloud") - - -# @pytest.mark.parametrize( -# "file_name,final_path", -# [("nextcloud.zip", TEMP_NEXTCLOUD)], -# ) -# def test_zip_extraction(file_name: str, final_path: Path): -# prep() -# zip = TEST_NEXTCLOUD_DIR.joinpath(file_name) -# dir = process_selection(zip) - -# assert dir == final_path -# cleanup() -# assert dir.exists() is False - - -# @pytest.mark.parametrize( -# "recipe_dir", -# [ -# TEST_NEXTCLOUD_DIR.joinpath("Air Fryer Shrimp"), -# TEST_NEXTCLOUD_DIR.joinpath("Chicken Parmigiana"), -# TEST_NEXTCLOUD_DIR.joinpath("Skillet Shepherd's Pie"), -# ], -# ) -# def test_nextcloud_migration(recipe_dir: Path): -# recipe = import_recipes(recipe_dir) -# assert isinstance(recipe, Recipe) -# shutil.rmtree(app_dirs.IMG_DIR.joinpath(recipe.image), ignore_errors=True) diff --git a/tests/utils/recipe_data.py b/tests/utils/recipe_data.py index 43d5f9caa..99919d7a1 100644 --- a/tests/utils/recipe_data.py +++ b/tests/utils/recipe_data.py @@ -1,7 +1,6 @@ from dataclasses import dataclass -from pathlib import Path -from tests.test_config import TEST_HTML_DIR +from tests import data as test_data @dataclass @@ -11,10 +10,7 @@ class RecipeSiteTestCase: expected_slug: str num_ingredients: int num_steps: int - - @property - def html_file(self) -> Path: - return TEST_HTML_DIR / self.html + html_file: str def get_recipe_test_cases(): @@ -22,6 +18,7 @@ def get_recipe_test_cases(): RecipeSiteTestCase( url="https://www.seriouseats.com/taiwanese-three-cup-chicken-san-bei-gi-recipe", html="taiwanese-three-cup-chicken-san-bei-gi-recipe.html", + html_file=test_data.html_taiwanese_three_cup_chicken_san_bei_gi_recipe, expected_slug="taiwanese-three-cup-chicken-san-bei-ji-recipe", num_ingredients=10, num_steps=3, @@ -29,6 +26,7 @@ def get_recipe_test_cases(): RecipeSiteTestCase( url="https://www.rezeptwelt.de/backen-herzhaft-rezepte/schinken-kaese-waffeln-ohne-viel-schnickschnack/4j0bkiig-94d4d-106529-cfcd2-is97x2ml", html="schinken-kase-waffeln-ohne-viel-schnickschnack.html", + html_file=test_data.html_schinken_kase_waffeln_ohne_viel_schnickschnack, expected_slug="schinken-kase-waffeln-ohne-viel-schnickschnack", num_ingredients=7, num_steps=1, # Malformed JSON Data, can't parse steps just get one string @@ -36,6 +34,7 @@ def get_recipe_test_cases(): RecipeSiteTestCase( url="https://cookpad.com/us/recipes/5544853-sous-vide-smoked-beef-ribs", html="sous-vide-smoked-beef-ribs.html", + html_file=test_data.html_sous_vide_smoked_beef_ribs, expected_slug="sous-vide-smoked-beef-ribs", num_ingredients=7, num_steps=12, @@ -43,6 +42,7 @@ def get_recipe_test_cases(): RecipeSiteTestCase( url="https://www.greatbritishchefs.com/recipes/jam-roly-poly-recipe", html="jam-roly-poly-with-custard.html", + html_file=test_data.html_jam_roly_poly_with_custard, expected_slug="jam-roly-poly-with-custard", num_ingredients=13, num_steps=9, @@ -50,6 +50,7 @@ def get_recipe_test_cases(): RecipeSiteTestCase( url="https://recipes.anovaculinary.com/recipe/sous-vide-shrimp", html="sous-vide-shrimp.html", + html_file=test_data.html_sous_vide_shrimp, expected_slug="sous-vide-shrimp", num_ingredients=5, num_steps=0, @@ -57,6 +58,7 @@ def get_recipe_test_cases(): RecipeSiteTestCase( url="https://www.bonappetit.com/recipe/detroit-style-pepperoni-pizza", html="detroit-style-pepperoni-pizza.html", + html_file=test_data.html_detroit_style_pepperoni_pizza, expected_slug="detroit-style-pepperoni-pizza", num_ingredients=8, num_steps=5,