Merge branch 'feature/custom_filters' into feature/custom_filtersv2
This commit is contained in:
commit
286c6344ec
@ -62,7 +62,7 @@ class RecipeSearch():
|
||||
# TODO add created by
|
||||
# TODO image exists
|
||||
self._sort_order = self._params.get('sort_order', None)
|
||||
self._internal = str2bool(self._params.get('internal', False))
|
||||
self._internal = str2bool(self._params.get('internal', None))
|
||||
self._random = str2bool(self._params.get('random', False))
|
||||
self._new = str2bool(self._params.get('new', False))
|
||||
self._last_viewed = int(self._params.get('last_viewed', 0))
|
||||
@ -112,7 +112,7 @@ class RecipeSearch():
|
||||
self.food_filters(**self._foods)
|
||||
self.book_filters(**self._books)
|
||||
self.rating_filter(rating=self._rating)
|
||||
self.internal_filter()
|
||||
self.internal_filter(internal=self._internal)
|
||||
self.step_filters(steps=self._steps)
|
||||
self.unit_filters(units=self._units)
|
||||
self._makenow_filter()
|
||||
@ -335,8 +335,10 @@ class RecipeSearch():
|
||||
else:
|
||||
self._queryset = self._queryset.filter(rating__gte=int(rating))
|
||||
|
||||
def internal_filter(self):
|
||||
self._queryset = self._queryset.filter(internal=True)
|
||||
def internal_filter(self, internal=None):
|
||||
if not internal:
|
||||
return
|
||||
self._queryset = self._queryset.filter(internal=internal)
|
||||
|
||||
def book_filters(self, **kwargs):
|
||||
if all([kwargs[x] is None for x in kwargs]):
|
||||
|
18
cookbook/migrations/0172_food_child_inherit_fields.py
Normal file
18
cookbook/migrations/0172_food_child_inherit_fields.py
Normal file
@ -0,0 +1,18 @@
|
||||
# Generated by Django 3.2.11 on 2022-02-04 17:11
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cookbook', '0171_auto_20220202_1340'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='food',
|
||||
name='child_inherit_fields',
|
||||
field=models.ManyToManyField(blank=True, related_name='child_inherit', to='cookbook.FoodInheritField'),
|
||||
),
|
||||
]
|
@ -111,6 +111,15 @@ class FoodFactory(factory.django.DjangoModelFactory):
|
||||
)
|
||||
space = factory.SubFactory(SpaceFactory)
|
||||
|
||||
@factory.post_generation
|
||||
def users_onhand(self, create, extracted, **kwargs):
|
||||
if not create:
|
||||
return
|
||||
|
||||
if extracted:
|
||||
for user in extracted:
|
||||
self.onhand_users.add(user)
|
||||
|
||||
class Params:
|
||||
has_category = False
|
||||
has_recipe = False
|
||||
|
135
cookbook/tests/other/test_makenow_filter.py
Normal file
135
cookbook/tests/other/test_makenow_filter.py
Normal file
@ -0,0 +1,135 @@
|
||||
import json
|
||||
|
||||
import pytest
|
||||
from django.contrib import auth
|
||||
from django.urls import reverse
|
||||
from django_scopes import scope
|
||||
from pytest_factoryboy import LazyFixture, register
|
||||
|
||||
from cookbook.helper.recipe_search import RecipeSearch
|
||||
from cookbook.models import Food, Recipe
|
||||
from cookbook.tests.factories import FoodFactory, RecipeFactory
|
||||
|
||||
# TODO returns recipes with all ingredients via child substitute
|
||||
# TODO returns recipes with all ingredients via sibling substitute
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def recipes(space_1):
|
||||
return RecipeFactory.create_batch(10, space=space_1)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def makenow_recipe(request, space_1):
|
||||
onhand_user = auth.get_user(request.getfixturevalue(request.param.get('onhand_users', 'u1_s1')))
|
||||
|
||||
recipe = RecipeFactory.create(space=space_1)
|
||||
for food in Food.objects.filter(ingredient__step__recipe=recipe.id):
|
||||
food.onhand_users.add(onhand_user)
|
||||
return recipe
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def user1(u1_s1, u2_s1, space_1):
|
||||
user1 = auth.get_user(u1_s1)
|
||||
user2 = auth.get_user(u2_s1)
|
||||
user1.userpreference.shopping_share.add(user2)
|
||||
user2.userpreference.shopping_share.add(user1)
|
||||
return user1
|
||||
|
||||
|
||||
@pytest.mark.parametrize("makenow_recipe", [
|
||||
({'onhand_users': 'u1_s1'}), ({'onhand_users': 'u2_s1'}),
|
||||
], indirect=['makenow_recipe'])
|
||||
def test_makenow_onhand(recipes, makenow_recipe, user1, space_1):
|
||||
request = type('', (object,), {'space': space_1, 'user': user1})()
|
||||
search = RecipeSearch(request, makenow='true')
|
||||
with scope(space=space_1):
|
||||
search = search.get_queryset(Recipe.objects.all())
|
||||
assert search.count() == 1
|
||||
assert search.first().id == makenow_recipe.id
|
||||
|
||||
|
||||
@pytest.mark.parametrize("makenow_recipe", [
|
||||
({'onhand_users': 'u1_s1'}), ({'onhand_users': 'u2_s1'}),
|
||||
], indirect=['makenow_recipe'])
|
||||
def test_makenow_ignoreshopping(recipes, makenow_recipe, user1, space_1):
|
||||
request = type('', (object,), {'space': space_1, 'user': user1})()
|
||||
search = RecipeSearch(request, makenow='true')
|
||||
with scope(space=space_1):
|
||||
food = Food.objects.filter(ingredient__step__recipe=makenow_recipe.id).first()
|
||||
food.onhand_users.clear()
|
||||
assert search.get_queryset(Recipe.objects.all()) == 0
|
||||
food.ignore_shopping = True
|
||||
food.save()
|
||||
assert Food.objects.filter(ingredient__step__recipe=makenow_recipe.id, onhand_users__isnull=False).count() == 9
|
||||
assert Food.objects.filter(ingredient__step__recipe=makenow_recipe.id, ignore_shopping=True).count() == 1
|
||||
search = search.get_queryset(Recipe.objects.all())
|
||||
assert search.count() == 1
|
||||
assert search.first().id == makenow_recipe.id
|
||||
|
||||
|
||||
@pytest.mark.parametrize("makenow_recipe", [
|
||||
({'onhand_users': 'u1_s1'}), ({'onhand_users': 'u2_s1'}),
|
||||
], indirect=['makenow_recipe'])
|
||||
def test_makenow_substitute(recipes, makenow_recipe, user1, space_1):
|
||||
request = type('', (object,), {'space': space_1, 'user': user1})()
|
||||
search = RecipeSearch(request, makenow='true')
|
||||
with scope(space=space_1):
|
||||
food = Food.objects.filter(ingredient__step__recipe=makenow_recipe.id).first()
|
||||
onhand_user = food.onhand_users.first()
|
||||
food.onhand_users.clear()
|
||||
assert search.get_queryset(Recipe.objects.all()).count() == 0
|
||||
food.substitute.add(FoodFactory.create(space=space_1, onhand_users=[onhand_user]))
|
||||
assert Food.objects.filter(ingredient__step__recipe=makenow_recipe.id, onhand_users__isnull=False).count() == 9
|
||||
assert Food.objects.filter(ingredient__step__recipe=makenow_recipe.id, substitute__isnull=False).count() == 1
|
||||
|
||||
search = search.get_queryset(Recipe.objects.all())
|
||||
assert search.count() == 1
|
||||
assert search.first().id == makenow_recipe.id
|
||||
|
||||
|
||||
@pytest.mark.parametrize("makenow_recipe", [
|
||||
({'onhand_users': 'u1_s1'}), ({'onhand_users': 'u2_s1'}),
|
||||
], indirect=['makenow_recipe'])
|
||||
def test_makenow_child_substitute(recipes, makenow_recipe, user1, space_1):
|
||||
request = type('', (object,), {'space': space_1, 'user': user1})()
|
||||
search = RecipeSearch(request, makenow='true')
|
||||
with scope(space=space_1):
|
||||
food = Food.objects.filter(ingredient__step__recipe=makenow_recipe.id).first()
|
||||
onhand_user = food.onhand_users.first()
|
||||
food.onhand_users.clear()
|
||||
food.substitute_children = True
|
||||
food.save()
|
||||
assert search.get_queryset(Recipe.objects.all()).count() == 0
|
||||
new_food = FoodFactory.create(space=space_1, onhand_users=[onhand_user])
|
||||
new_food.move(food, 'first-child')
|
||||
assert Food.objects.filter(ingredient__step__recipe=makenow_recipe.id, onhand_users__isnull=False).count() == 9
|
||||
assert Food.objects.filter(ingredient__step__recipe=makenow_recipe.id, numchild__gt=0).count() == 1
|
||||
search = search.get_queryset(Recipe.objects.all())
|
||||
assert search.count() == 1
|
||||
assert search.first().id == makenow_recipe.id
|
||||
|
||||
|
||||
@pytest.mark.parametrize("makenow_recipe", [
|
||||
({'onhand_users': 'u1_s1'}), ({'onhand_users': 'u2_s1'}),
|
||||
], indirect=['makenow_recipe'])
|
||||
def test_makenow_sibling_substitute(recipes, makenow_recipe, user1, space_1):
|
||||
request = type('', (object,), {'space': space_1, 'user': user1})()
|
||||
search = RecipeSearch(request, makenow='true')
|
||||
with scope(space=space_1):
|
||||
food = Food.objects.filter(ingredient__step__recipe=makenow_recipe.id).first()
|
||||
onhand_user = food.onhand_users.first()
|
||||
food.onhand_users.clear()
|
||||
food.substitute_siblings = True
|
||||
food.save()
|
||||
assert search.get_queryset(Recipe.objects.all()).count() == 0
|
||||
new_parent = FoodFactory.create(space=space_1)
|
||||
new_sibling = FoodFactory.create(space=space_1, onhand_users=[onhand_user])
|
||||
new_sibling.move(new_parent, 'first-child')
|
||||
food.move(new_parent, 'first-child')
|
||||
assert Food.objects.filter(ingredient__step__recipe=makenow_recipe.id, onhand_users__isnull=False).count() == 9
|
||||
assert Food.objects.filter(ingredient__step__recipe=makenow_recipe.id, depth=2).count() == 1
|
||||
search = search.get_queryset(Recipe.objects.all())
|
||||
assert search.count() == 1
|
||||
assert search.first().id == makenow_recipe.id
|
27
cookbook/tests/other/test_recipe_full_text_search.py
Normal file
27
cookbook/tests/other/test_recipe_full_text_search.py
Normal file
@ -0,0 +1,27 @@
|
||||
import json
|
||||
|
||||
import pytest
|
||||
from django.contrib import auth
|
||||
from django.urls import reverse
|
||||
from django_scopes import scope, scopes_disabled
|
||||
from pytest_factoryboy import LazyFixture, register
|
||||
|
||||
from cookbook.models import Food, FoodInheritField, Ingredient, ShoppingList, ShoppingListEntry
|
||||
from cookbook.tests.factories import (FoodFactory, IngredientFactory, ShoppingListEntryFactory,
|
||||
SupermarketCategoryFactory)
|
||||
|
||||
# TODO food/keyword/book test or, and, or_not, and_not search
|
||||
# TODO recipe name/description/instructions/keyword/book/food test search with icontains, istarts with/ full text(?? probably when word changes based on conjugation??), trigram, unaccent
|
||||
|
||||
# TODO fuzzy lookup on units, keywords, food when not configured in main search settings
|
||||
|
||||
# TODO test combining any/all of the above
|
||||
# TODO search rating as user or when another user rated
|
||||
# TODO search last cooked
|
||||
# TODO changing lsat_viewed ## to return on search
|
||||
# TODO test sort_by
|
||||
# TODO test sort_by new X number of recipes are new within last Y days
|
||||
# TODO test loading custom filter
|
||||
# TODO test loading custom filter with overrided params
|
||||
# TODO makenow with above filters
|
||||
# TODO test search for number of times cooked (self vs others)
|
Loading…
Reference in New Issue
Block a user