From bd88b63e384f83721a82601d25e5659659999ffb Mon Sep 17 00:00:00 2001 From: Ben Southcott Date: Sun, 18 Jun 2023 23:14:37 -0600 Subject: [PATCH 1/3] refactor copy meal plan function and add test for function --- .gitignore | 5 +++ wger/nutrition/tests/test_plan.py | 40 +++++++++++++++++++++++- wger/nutrition/views/plan.py | 52 ++++++++++++++++++------------- 3 files changed, 75 insertions(+), 22 deletions(-) diff --git a/.gitignore b/.gitignore index ec0326d8e..fdeb03458 100644 --- a/.gitignore +++ b/.gitignore @@ -58,6 +58,7 @@ target/ # IDE .idea/ +.vscode/ # External Libraries wger/core/static/yarn @@ -66,6 +67,7 @@ node_modules # Virtual envs venv venv-wger +.python-version # Dummy translation files to copy to react or flutter repo /wger/i18n.tsx @@ -75,3 +77,6 @@ venv-wger /wger/app_en.arb /coverage.lcov /media/ + +# macOS +.DS_Store diff --git a/wger/nutrition/tests/test_plan.py b/wger/nutrition/tests/test_plan.py index bf6abbf9b..04002a37e 100644 --- a/wger/nutrition/tests/test_plan.py +++ b/wger/nutrition/tests/test_plan.py @@ -14,7 +14,7 @@ # along with Workout Manager. If not, see . # Django -from django.urls import reverse +from django.urls import reverse, resolve # wger from wger.core.tests import api_base_test @@ -189,3 +189,41 @@ class PlanApiTestCase(api_base_test.ApiBaseResourceTestCase): private_resource = True special_endpoints = ('nutritional_values', ) data = {'description': 'The description', 'language': 1} + + +class PlanCopyTestCase(WgerTestCase): + + def test_copy_plan(self): + """ + Tests making a copy of a meal plan + """ + self.user_login() + orig_plan = NutritionPlan.objects.get(pk=2) + response = self.client.get(reverse("nutrition:plan:copy", kwargs={"pk": 2})) + copied_plan_pk = int(resolve(response.url).kwargs["id"]) + copied_plan = NutritionPlan.objects.get(pk=copied_plan_pk) + + # fields for each object to test for equality + plan_fields = ("user", "language", "description", "has_goal_calories",) + meal_fields = ("name", "time", "order",) + meal_item_fields = ("ingredient", "weight_unit", "order", "amount",) + + # test each Plan object's fields are equal + for field in plan_fields: + self.assertEqual(getattr(orig_plan, field), getattr(copied_plan, field)) + + orig_plan_meals = orig_plan.meal_set.all() + copied_plan_meals = copied_plan.meal_set.all() + + for meal_cnt, orig_meal in enumerate(orig_plan_meals): + # test that the fields are equal for each Meal object for each Plan + for field in meal_fields: + self.assertEqual(getattr(orig_meal, field), getattr(copied_plan_meals[meal_cnt], field)) + + orig_plan_meal_items = orig_plan_meals[meal_cnt].mealitem_set.all() + copied_plan_meal_items = copied_plan_meals[meal_cnt].mealitem_set.all() + + # test that the fields are equal for each MealItem object for each Meal + for item_cnt, orig_meal_item in enumerate(orig_plan_meal_items): + for field in meal_item_fields: + self.assertEqual(getattr(orig_meal_item, field), getattr(copied_plan_meal_items[item_cnt], field)) diff --git a/wger/nutrition/views/plan.py b/wger/nutrition/views/plan.py index cae8300ca..ed60fc922 100644 --- a/wger/nutrition/views/plan.py +++ b/wger/nutrition/views/plan.py @@ -16,6 +16,7 @@ # Standard Library import logging +from copy import deepcopy # Django from django.contrib.auth.decorators import login_required @@ -42,6 +43,8 @@ UpdateView, ) +from django.db import transaction + # Third Party from reportlab.lib import colors from reportlab.lib.pagesizes import A4 @@ -58,7 +61,7 @@ MEALITEM_WEIGHT_GRAM, MEALITEM_WEIGHT_UNIT, ) -from wger.nutrition.models import NutritionPlan +from wger.nutrition.models import NutritionPlan, Meal, MealItem from wger.utils.generic_views import ( WgerDeleteMixin, WgerFormMixin, @@ -203,33 +206,40 @@ def copy(request, pk): Copy the nutrition plan """ - plan = get_object_or_404(NutritionPlan, pk=pk, user=request.user) - - # Copy plan - meals = plan.meal_set.all() + orig_plan = get_object_or_404(NutritionPlan, pk=pk, user=request.user) - plan_copy = plan - plan_copy.pk = None + # make new Plan, Meal, and MealItem objects using the values for the fields from the original object + plan_copy = NutritionPlan( + user=orig_plan.user, + language=orig_plan.language, + description=orig_plan.description, + has_goal_calories=orig_plan.has_goal_calories + ) plan_copy.save() - # Copy the meals - for meal in meals: - meal_items = meal.mealitem_set.all() - - meal_copy = meal - meal_copy.pk = None - meal_copy.plan = plan_copy + orig_meals = orig_plan.meal_set.all() + for orig_meal in orig_meals: + meal_copy = Meal( + plan=plan_copy, + name=orig_meal.name, + time=orig_meal.time, + order=orig_meal.order + ) meal_copy.save() - # Copy the individual meal entries - for item in meal_items: - item_copy = item - item_copy.pk = None - item_copy.meal = meal_copy - item.save() + orig_meal_items = orig_meal.mealitem_set.all() + for orig_meal_item in orig_meal_items: + meal_item_copy = MealItem( + meal=meal_copy, + ingredient=orig_meal_item.ingredient, + weight_unit=orig_meal_item.weight_unit, + order=orig_meal_item.order, + amount=orig_meal_item.amount + ) + meal_item_copy.save() # Redirect - return HttpResponseRedirect(reverse('nutrition:plan:view', kwargs={'id': plan.id})) + return HttpResponseRedirect(reverse('nutrition:plan:view', kwargs={'id': plan_copy.id})) def export_pdf(request, id, uidb64=None, token=None): From 09d63328b9ba033f8d6c37d6b08ea494eb5741e9 Mon Sep 17 00:00:00 2001 From: Ben Southcott Date: Sun, 18 Jun 2023 23:20:30 -0600 Subject: [PATCH 2/3] remove unused imports, update comments --- wger/nutrition/tests/test_plan.py | 6 +++--- wger/nutrition/views/plan.py | 3 --- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/wger/nutrition/tests/test_plan.py b/wger/nutrition/tests/test_plan.py index 04002a37e..76cc191c5 100644 --- a/wger/nutrition/tests/test_plan.py +++ b/wger/nutrition/tests/test_plan.py @@ -208,7 +208,7 @@ def test_copy_plan(self): meal_fields = ("name", "time", "order",) meal_item_fields = ("ingredient", "weight_unit", "order", "amount",) - # test each Plan object's fields are equal + # test each Plan's fields are equal for field in plan_fields: self.assertEqual(getattr(orig_plan, field), getattr(copied_plan, field)) @@ -216,14 +216,14 @@ def test_copy_plan(self): copied_plan_meals = copied_plan.meal_set.all() for meal_cnt, orig_meal in enumerate(orig_plan_meals): - # test that the fields are equal for each Meal object for each Plan + # test that the fields are equal for each Meal for each Plan for field in meal_fields: self.assertEqual(getattr(orig_meal, field), getattr(copied_plan_meals[meal_cnt], field)) orig_plan_meal_items = orig_plan_meals[meal_cnt].mealitem_set.all() copied_plan_meal_items = copied_plan_meals[meal_cnt].mealitem_set.all() - # test that the fields are equal for each MealItem object for each Meal + # test that the fields are equal for each MealItem for each Meal for item_cnt, orig_meal_item in enumerate(orig_plan_meal_items): for field in meal_item_fields: self.assertEqual(getattr(orig_meal_item, field), getattr(copied_plan_meal_items[item_cnt], field)) diff --git a/wger/nutrition/views/plan.py b/wger/nutrition/views/plan.py index ed60fc922..14369f67b 100644 --- a/wger/nutrition/views/plan.py +++ b/wger/nutrition/views/plan.py @@ -16,7 +16,6 @@ # Standard Library import logging -from copy import deepcopy # Django from django.contrib.auth.decorators import login_required @@ -43,8 +42,6 @@ UpdateView, ) -from django.db import transaction - # Third Party from reportlab.lib import colors from reportlab.lib.pagesizes import A4 From 9b4aabb323fb0ec0bca078e7418f03fa34fd64e5 Mon Sep 17 00:00:00 2001 From: Ben Southcott Date: Mon, 19 Jun 2023 21:38:00 -0600 Subject: [PATCH 3/3] add to authors.rst --- AUTHORS.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS.rst b/AUTHORS.rst index abb43eee3..7a0bb3a90 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -74,6 +74,7 @@ Developers * Bernardo Koen - https://github.com/BernardoKoen * Gabriel Liss - https://github.com/gabeliss * Alexandra Rhodes - https://github.com/arhodes130 +* Ben Southcott - https://github.com/blsouthcott Translators -----------