Merge branch 'feature/custom_filters' into feature/custom_filtersv2

This commit is contained in:
smilerz 2022-02-07 17:47:53 -06:00
commit 286c6344ec
No known key found for this signature in database
GPG Key ID: 39444C7606D47126
5 changed files with 195 additions and 4 deletions

View File

@ -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]):

View 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'),
),
]

View File

@ -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

View 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

View 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)