예제 #1
0
    def ready(self):
        # post_save signal is only necessary if using full-text search on postgres
        if settings.DATABASES['default']['ENGINE'] in ['django.db.backends.postgresql_psycopg2',
                                                       'django.db.backends.postgresql']:
            import cookbook.signals  # noqa

        if not settings.DISABLE_TREE_FIX_STARTUP:
            # when starting up run fix_tree to:
            #   a) make sure that nodes are sorted when switching between sort modes
            #   b) fix problems, if any, with tree consistency
            with scopes_disabled():
                try:
                    from cookbook.models import Keyword, Food
                    Keyword.fix_tree(fix_paths=True)
                    Food.fix_tree(fix_paths=True)
                except OperationalError:
                    if DEBUG:
                        traceback.print_exc()
                    pass  # if model does not exist there is no need to fix it
                except ProgrammingError:
                    if DEBUG:
                        traceback.print_exc()
                    pass  # if migration has not been run database cannot be fixed yet
                except Exception:
                    if DEBUG:
                        traceback.print_exc()
                    pass  # dont break startup just because fix could not run, need to investigate cases when this happens
예제 #2
0
def test_move(u1_s1, obj_tree_1, obj_2, obj_3, space_1):
    with scope(space=space_1):
        parent = obj_tree_1.get_parent()
        child = obj_tree_1.get_descendants()[0]
        assert parent.get_num_children() == 1
        assert parent.get_descendant_count() == 2
        assert Food.get_root_nodes().filter(space=space_1).count() == 2

    url = reverse(MOVE_URL, args=[obj_tree_1.id, obj_2.id])

    # move child to new parent, only HTTP put method should work
    r = u1_s1.get(url)
    assert r.status_code == 405
    r = u1_s1.post(url)
    assert r.status_code == 405
    r = u1_s1.delete(url)
    assert r.status_code == 405
    r = u1_s1.put(url)
    assert r.status_code == 200
    with scopes_disabled():
        # django-treebeard bypasses django ORM so object needs retrieved again
        parent = Food.objects.get(pk=parent.id)
        obj_2 = Food.objects.get(pk=obj_2.id)
        assert parent.get_num_children() == 0
        assert parent.get_descendant_count() == 0
        assert obj_2.get_num_children() == 1
        assert obj_2.get_descendant_count() == 2

    # run diagnostic to find problems - none should be found
    with scopes_disabled():
        assert Food.find_problems() == ([], [], [], [], [])
예제 #3
0
def test_merge(
    u1_s1,
    obj_1, obj_2, obj_3,
    ing_1_s1, ing_2_s1, ing_3_s2,
    sle_1_s1, sle_2_s1, sle_3_s2,
    space_1
):
    with scopes_disabled():
        assert Unit.objects.filter(space=space_1).count() == 2
        assert obj_1.ingredient_set.count() == 1
        assert obj_2.ingredient_set.count() == 1
        assert obj_3.ingredient_set.count() == 1
        assert obj_1.shoppinglistentry_set.count() == 1
        assert obj_2.shoppinglistentry_set.count() == 1
        assert obj_3.shoppinglistentry_set.count() == 1

    # merge Unit with ingredient/shopping list entry with another Unit, only HTTP put method should work
    url = reverse(MERGE_URL, args=[obj_1.id, obj_2.id])
    r = u1_s1.get(url)
    assert r.status_code == 405
    r = u1_s1.post(url)
    assert r.status_code == 405
    r = u1_s1.delete(url)
    assert r.status_code == 405
    r = u1_s1.put(url)
    assert r.status_code == 200
    with scopes_disabled():
        assert Unit.objects.filter(pk=obj_1.id).count() == 0
        assert obj_2.ingredient_set.count() == 2
        assert obj_3.ingredient_set.count() == 1

        assert obj_2.shoppinglistentry_set.count() == 2
        assert obj_3.shoppinglistentry_set.count() == 1

    # attempt to merge with non-existent parent
    r = u1_s1.put(
        reverse(MERGE_URL, args=[obj_2.id, 9999])
    )
    assert r.status_code == 404

    # attempt to move to wrong space
    r = u1_s1.put(
        reverse(MERGE_URL, args=[obj_2.id, obj_3.id])
    )
    assert r.status_code == 404

    # attempt to merge with self
    r = u1_s1.put(
        reverse(MERGE_URL, args=[obj_2.id, obj_2.id])
    )
    assert r.status_code == 403

    # run diagnostic to find problems - none should be found
    with scopes_disabled():
        assert Food.find_problems() == ([], [], [], [], [])
예제 #4
0
def test_move(u1_s1, obj_1, obj_1_1, obj_1_1_1, obj_2, obj_3, space_1):
    url = reverse(MOVE_URL, args=[obj_1_1.id, obj_2.id])
    with scopes_disabled():
        assert obj_1.get_num_children() == 1
        assert obj_1.get_descendant_count() == 2
        assert Food.get_root_nodes().filter(space=space_1).count() == 2

    # move child to new parent, only HTTP put method should work
    r = u1_s1.get(url)
    assert r.status_code == 405
    r = u1_s1.post(url)
    assert r.status_code == 405
    r = u1_s1.delete(url)
    assert r.status_code == 405
    r = u1_s1.put(url)
    assert r.status_code == 200
    with scopes_disabled():
        # django-treebeard bypasses django ORM so object needs retrieved again
        obj_1 = Food.objects.get(pk=obj_1.id)
        obj_2 = Food.objects.get(pk=obj_2.id)
        assert obj_1.get_num_children() == 0
        assert obj_1.get_descendant_count() == 0
        assert obj_2.get_num_children() == 1
        assert obj_2.get_descendant_count() == 2

    # move child to root
    r = u1_s1.put(reverse(MOVE_URL, args=[obj_1_1.id, 0]))
    assert r.status_code == 200
    with scopes_disabled():
        assert Food.get_root_nodes().filter(space=space_1).count() == 3

    # attempt to move to non-existent parent
    r = u1_s1.put(reverse(MOVE_URL, args=[obj_1.id, 9999]))
    assert r.status_code == 404

    # attempt to move to wrong space
    r = u1_s1.put(reverse(MOVE_URL, args=[obj_1_1.id, obj_3.id]))
    assert r.status_code == 404

    # run diagnostic to find problems - none should be found
    with scopes_disabled():
        assert Food.find_problems() == ([], [], [], [], [])
예제 #5
0
def test_merge(u1_s1, obj_tree_1, obj_1, obj_3, space_1):
    with scope(space=space_1):
        parent = obj_tree_1.get_parent()
        child = obj_tree_1.get_descendants()[0]
        assert parent.get_num_children() == 1
        assert parent.get_descendant_count() == 2
        assert Food.get_root_nodes().filter(space=space_1).count() == 2
        assert Food.objects.count() == 4

    # merge food with no children with another food, only HTTP put method should work
    url = reverse(MERGE_URL, args=[child.id, obj_tree_1.id])
    r = u1_s1.get(url)
    assert r.status_code == 405
    r = u1_s1.post(url)
    assert r.status_code == 405
    r = u1_s1.delete(url)
    assert r.status_code == 405
    r = u1_s1.put(url)
    assert r.status_code == 200
    with scope(space=space_1):
        # django-treebeard bypasses django ORM so object needs retrieved again
        with pytest.raises(Food.DoesNotExist):
            Food.objects.get(pk=child.id)
        obj_tree_1 = Food.objects.get(pk=obj_tree_1.id)
        assert parent.get_num_children() == 1
        assert parent.get_descendant_count() == 1

    # merge food with children with another food
    r = u1_s1.put(reverse(MERGE_URL, args=[parent.id, obj_1.id]))
    assert r.status_code == 200
    with scope(space=space_1):
        # django-treebeard bypasses django ORM so object needs retrieved again
        with pytest.raises(Food.DoesNotExist):
            Food.objects.get(pk=parent.id)
        obj_1 = Food.objects.get(pk=obj_1.id)
        assert obj_1.get_num_children() == 1
        assert obj_1.get_descendant_count() == 1

    # run diagnostic to find problems - none should be found
    with scopes_disabled():
        assert Food.find_problems() == ([], [], [], [], [])
예제 #6
0
파일: views.py 프로젝트: cschoeni/recipes
def space(request):
    space_users = UserPreference.objects.filter(space=request.space).all()

    counts = Object()
    counts.recipes = Recipe.objects.filter(space=request.space).count()
    counts.keywords = Keyword.objects.filter(space=request.space).count()
    counts.recipe_import = RecipeImport.objects.filter(space=request.space).count()
    counts.units = Unit.objects.filter(space=request.space).count()
    counts.ingredients = Food.objects.filter(space=request.space).count()
    counts.comments = Comment.objects.filter(recipe__space=request.space).count()

    counts.recipes_internal = Recipe.objects.filter(internal=True, space=request.space).count()
    counts.recipes_external = counts.recipes - counts.recipes_internal

    counts.recipes_no_keyword = Recipe.objects.filter(keywords=None, space=request.space).count()

    invite_links = InviteLinkTable(
        InviteLink.objects.filter(valid_until__gte=datetime.today(), used_by=None, space=request.space).all())
    RequestConfig(request, paginate={'per_page': 25}).configure(invite_links)

    space_form = SpacePreferenceForm(instance=request.space)

    space_form.base_fields['food_inherit'].queryset = Food.inheritable_fields
    if request.method == "POST" and 'space_form' in request.POST:
        form = SpacePreferenceForm(request.POST, prefix='space')
        if form.is_valid():
            request.space.food_inherit.set(form.cleaned_data['food_inherit'])
            request.space.show_facet_count = form.cleaned_data['show_facet_count']
            request.space.save()
            if form.cleaned_data['reset_food_inherit']:
                Food.reset_inheritance(space=request.space)

    return render(request, 'space.html', {
        'space_users': space_users,
        'counts': counts,
        'invite_links': invite_links,
        'space_form': space_form
    })
예제 #7
0
def test_delete(u1_s1, u1_s2, obj_1, obj_1_1, obj_1_1_1):
    with scopes_disabled():
        assert Food.objects.count() == 3

    r = u1_s2.delete(reverse(DETAIL_URL, args={obj_1.id}))
    assert r.status_code == 404
    with scopes_disabled():
        assert Food.objects.count() == 3

    r = u1_s1.delete(reverse(DETAIL_URL, args={obj_1_1.id}))

    assert r.status_code == 204
    with scopes_disabled():
        assert Food.objects.count() == 1
        assert Food.find_problems() == ([], [], [], [], [])
예제 #8
0
def test_delete(u1_s1, u1_s2, obj_1, obj_tree_1):
    with scopes_disabled():
        assert Food.objects.count() == 4

    r = u1_s2.delete(reverse(DETAIL_URL, args={obj_1.id}))
    assert r.status_code == 404
    with scopes_disabled():
        assert Food.objects.count() == 4

    # should delete self and child, leaving parent
    r = u1_s1.delete(reverse(DETAIL_URL, args={obj_tree_1.id}))

    assert r.status_code == 204
    with scopes_disabled():
        assert Food.objects.count() == 2
        assert Food.find_problems() == ([], [], [], [], [])
예제 #9
0
def test_move_errors(u1_s1, obj_tree_1, obj_3, space_1):
    with scope(space=space_1):
        parent = obj_tree_1.get_parent()
        child = obj_tree_1.get_descendants()[0]
    # move child to root
    r = u1_s1.put(reverse(MOVE_URL, args=[obj_tree_1.id, 0]))
    assert r.status_code == 200
    with scopes_disabled():
        assert Food.get_root_nodes().filter(space=space_1).count() == 2

    # attempt to move to non-existent parent
    r = u1_s1.put(reverse(MOVE_URL, args=[parent.id, 9999]))
    assert r.status_code == 404

    # attempt to move non-existent mode to parent
    r = u1_s1.put(reverse(MOVE_URL, args=[9999, parent.id]))
    assert r.status_code == 404

    # attempt to move to wrong space
    r = u1_s1.put(reverse(MOVE_URL, args=[obj_tree_1.id, obj_3.id]))
    assert r.status_code == 404
예제 #10
0
        reset_inherit = self.initial_data.get('reset_inherit', False)
        if not onhand is None:
            shared_users = [user := self.context['request'].user] + list(
                user.userpreference.shopping_share.all())
            if onhand:
                validated_data['onhand_users'] = list(
                    self.instance.onhand_users.all()) + shared_users
            else:
                validated_data['onhand_users'] = list(
                    set(self.instance.onhand_users.all()) - set(shared_users))

        # update before resetting inheritance
        saved_instance = super(FoodSerializer,
                               self).update(instance, validated_data)
        if reset_inherit and (r := self.context.get('request', None)):
            Food.reset_inheritance(food=saved_instance, space=r.space)
        return saved_instance

    class Meta:
        model = Food
        fields = ('id', 'name', 'description', 'shopping', 'recipe',
                  'food_onhand', 'supermarket_category', 'image', 'parent',
                  'numchild', 'numrecipe', 'inherit_fields', 'full_name',
                  'ignore_shopping', 'substitute', 'substitute_siblings',
                  'substitute_children', 'substitute_onhand',
                  'child_inherit_fields')
        read_only_fields = ('id', 'numchild', 'parent', 'image', 'numrecipe')


class IngredientSimpleSerializer(WritableNestedModelSerializer):
    food = FoodSimpleSerializer(allow_null=True)
예제 #11
0
def test_merge(u1_s1, obj_1, obj_1_1, obj_1_1_1, obj_2, obj_3, ing_1_s1,
               ing_2_s1, ing_3_s2, ing_1_1_s1, sle_1_s1, sle_2_s1, sle_3_s2,
               sle_1_1_s1, space_1):
    with scopes_disabled():
        assert obj_1.get_num_children() == 1
        assert obj_1.get_descendant_count() == 2
        assert Food.get_root_nodes().filter(space=space_1).count() == 2
        assert Food.objects.filter(space=space_1).count() == 4
        assert obj_1.ingredient_set.count() == 1
        assert obj_2.ingredient_set.count() == 1
        assert obj_3.ingredient_set.count() == 1
        assert obj_1_1.ingredient_set.count() == 1
        assert obj_1_1_1.ingredient_set.count() == 0
        assert obj_1.shoppinglistentry_set.count() == 1
        assert obj_2.shoppinglistentry_set.count() == 1
        assert obj_3.shoppinglistentry_set.count() == 1
        assert obj_1_1.shoppinglistentry_set.count() == 1
        assert obj_1_1_1.shoppinglistentry_set.count() == 0

    # merge food with no children and no ingredient/shopping list entry with another food, only HTTP put method should work
    url = reverse(MERGE_URL, args=[obj_1_1_1.id, obj_2.id])
    r = u1_s1.get(url)
    assert r.status_code == 405
    r = u1_s1.post(url)
    assert r.status_code == 405
    r = u1_s1.delete(url)
    assert r.status_code == 405
    r = u1_s1.put(url)
    assert r.status_code == 200
    with scopes_disabled():
        # django-treebeard bypasses django ORM so object needs retrieved again
        obj_1 = Food.objects.get(pk=obj_1.id)
        obj_2 = Food.objects.get(pk=obj_2.id)
        assert Food.objects.filter(pk=obj_1_1_1.id).count() == 0
        assert obj_1.get_num_children() == 1
        assert obj_1.get_descendant_count() == 1
        assert obj_2.get_num_children() == 0
        assert obj_2.get_descendant_count() == 0
        assert obj_1.ingredient_set.count() == 1
        assert obj_2.ingredient_set.count() == 1
        assert obj_3.ingredient_set.count() == 1
        assert obj_1_1.ingredient_set.count() == 1
        assert obj_1.shoppinglistentry_set.count() == 1
        assert obj_2.shoppinglistentry_set.count() == 1
        assert obj_3.shoppinglistentry_set.count() == 1
        assert obj_1_1.shoppinglistentry_set.count() == 1

    # merge food (with connected ingredient/shoppinglistentry) with children to another food
    r = u1_s1.put(reverse(MERGE_URL, args=[obj_1.id, obj_2.id]))
    assert r.status_code == 200
    with scopes_disabled():
        # django-treebeard bypasses django ORM so object needs retrieved again
        obj_2 = Food.objects.get(pk=obj_2.id)
        assert Food.objects.filter(pk=obj_1.id).count() == 0
        assert obj_2.get_num_children() == 1
        assert obj_2.get_descendant_count() == 1
        assert obj_2.ingredient_set.count() == 2
        assert obj_3.ingredient_set.count() == 1
        assert obj_1_1.ingredient_set.count() == 1
        assert obj_2.shoppinglistentry_set.count() == 2
        assert obj_3.shoppinglistentry_set.count() == 1
        assert obj_1_1.shoppinglistentry_set.count() == 1

    # attempt to merge with non-existent parent
    r = u1_s1.put(reverse(MERGE_URL, args=[obj_1_1.id, 9999]))
    assert r.status_code == 404

    # attempt to move to wrong space
    r = u1_s1.put(reverse(MERGE_URL, args=[obj_2.id, obj_3.id]))
    assert r.status_code == 404

    # attempt to merge with child
    r = u1_s1.put(reverse(MERGE_URL, args=[obj_2.id, obj_1_1.id]))
    assert r.status_code == 403

    # attempt to merge with self
    r = u1_s1.put(reverse(MERGE_URL, args=[obj_2.id, obj_2.id]))
    assert r.status_code == 403

    # run diagnostic to find problems - none should be found
    with scopes_disabled():
        assert Food.find_problems() == ([], [], [], [], [])