diff --git a/src/main/java/mi/hdm/mealPlan/MealPlan.java b/src/main/java/mi/hdm/mealPlan/MealPlan.java index 2470d1fcca751c967b82eb62b9173f9e434d6dec..d569c8ec3f02e52d6259e631d07e92cb6125ac77 100644 --- a/src/main/java/mi/hdm/mealPlan/MealPlan.java +++ b/src/main/java/mi/hdm/mealPlan/MealPlan.java @@ -3,39 +3,47 @@ package mi.hdm.mealPlan; import mi.hdm.recipes.NutritionCalculator; import mi.hdm.recipes.NutritionTable; import mi.hdm.recipes.Recipe; -import mi.hdm.shoppingList.ShoppingList; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.time.LocalDate; -import java.util.HashMap; import java.util.Map; +import java.util.Optional; /** * Allow the user to create a meal plan for the week. The user can check out his nutrition scores for the week. */ public class MealPlan { - - //TODO: limit MealPlan to seven days (LocalDate + 6 days) private static final Logger log = LogManager.getLogger(MealPlan.class); private final Map<LocalDate, Recipe> plan; - private static final MealPlan mealPlan = new MealPlan(); - - private MealPlan () { - plan = new HashMap<>(); - } - public static MealPlan getInstance() { - return mealPlan; + public MealPlan(Map<LocalDate, Recipe> plan) { + this.plan = plan; } public void addRecipeToMealPlan(Recipe recipe, LocalDate date) { + if (date == null) { + throw new NullPointerException("Date can not be null"); + } + + LocalDate invalid = LocalDate.now().plusDays(7); + + if (date.isBefore(LocalDate.now()) || invalid.isBefore(date)) { + throw new UnsupportedOperationException("You can only add recipes between today and in 7 days from now!"); + } plan.put(date, recipe); } public void clear(LocalDate date) { - log.info("Day {} cleared successfully.", date); - plan.put(date, null); + if (date == null) { + throw new NullPointerException("Date can not be null"); + } + if (plan.containsKey(date)) { + log.info("Day {} cleared successfully.", date); + plan.remove(date); + } else { + throw new NullPointerException("This date does not exist in the meal plan."); + } } public void clear() { @@ -43,19 +51,23 @@ public class MealPlan { plan.clear(); } - public Recipe getRecipeForDay(LocalDate date) { - - - return plan.get(date); + public Optional<Recipe> getRecipeForDay(LocalDate date) { + return Optional.ofNullable(plan.get(date)); } - public Map<LocalDate, Recipe> getAllRecipesFromPlan () { + + public Map<LocalDate, Recipe> getAllRecipesFromPlan() { return plan; } - public NutritionTable getNutritionTable() { - - return NutritionCalculator.calculateNutritionTable(mealPlan); + public void removePastRecipes() { + final LocalDate now = LocalDate.now(); + for (LocalDate d : plan.keySet()) { + if (d.isBefore(now)) plan.remove(d); + } + } + public NutritionTable getNutritionTable() { + return NutritionCalculator.calculateNutritionTable(this); } } diff --git a/src/main/java/mi/hdm/recipes/Recipe.java b/src/main/java/mi/hdm/recipes/Recipe.java index 2e8659f3cfc919f264ff70dad4430870201ba58d..1a181d9910b5521507daa992bf20c570e425e6c1 100644 --- a/src/main/java/mi/hdm/recipes/Recipe.java +++ b/src/main/java/mi/hdm/recipes/Recipe.java @@ -176,4 +176,10 @@ public class Recipe implements RecipeComponent { } return false; } + + @Override + public String toString() { + String desc = description == null ? "No description" : description; + return String.format("Recipe: %s%n--------%n%s%n%nCreated: %s", name, desc, creationTime); + } } diff --git a/src/test/java/mi/hdm/mealPlan/MealPlanTest.java b/src/test/java/mi/hdm/mealPlan/MealPlanTest.java new file mode 100644 index 0000000000000000000000000000000000000000..7f2d37a254046df0f6aa7bc0015e707624e428ca --- /dev/null +++ b/src/test/java/mi/hdm/mealPlan/MealPlanTest.java @@ -0,0 +1,112 @@ +package mi.hdm.mealPlan; + +import mi.hdm.recipes.Recipe; +import mi.hdm.recipes.ValidObjectsPool; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.time.LocalDate; +import java.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +class MealPlanTest { + private MealPlan underTest; + private final static Recipe recipeOne = ValidObjectsPool.getValidRecipeOne(); + private final static Recipe recipeTwo = ValidObjectsPool.getValidRecipeTwo(); + + @BeforeEach + public void setup() { + underTest = new MealPlan(new HashMap<>()); + } + + @Test + public void canAddToMealPlan() { + //given + LocalDate date = LocalDate.now(); + Map<LocalDate, Recipe> expected = Map.of(date, recipeOne); + + //when + underTest.addRecipeToMealPlan(recipeOne, date); + + //expect + assertEquals(expected, underTest.getAllRecipesFromPlan()); + } + + @Test + public void shouldNotAddWhenDateNull() { + assertThrows(NullPointerException.class, () -> underTest.addRecipeToMealPlan(recipeOne, null)); + } + + @Test + public void shouldNotAddWhenOutOfBounds() { + //given + LocalDate future = LocalDate.of(3000, 1, 1); + LocalDate past = LocalDate.of(2000, 1, 1); + + //expect throw + assertThrows(UnsupportedOperationException.class, () -> underTest.addRecipeToMealPlan(recipeOne, future)); + assertThrows(UnsupportedOperationException.class, () -> underTest.addRecipeToMealPlan(recipeOne, past)); + } + + @Test + public void shouldRemoveOldRecipes() { + //given + LocalDate date = LocalDate.of(2022, 1, 1); + Map<LocalDate, Recipe> expected = Map.of(); + HashMap<LocalDate, Recipe> entries = new HashMap<>(); + entries.put(date, recipeOne); + underTest = new MealPlan(entries); + + //when + underTest.removePastRecipes(); + + //expect + assertEquals(expected, underTest.getAllRecipesFromPlan()); + } + + @Test + public void shouldRemoveOldRecipesButKeepUpToDate() { + //given + LocalDate old = LocalDate.of(2022, 1, 1); + LocalDate now = LocalDate.now(); + HashMap<LocalDate, Recipe> entries = new HashMap<>(); + entries.put(old, recipeOne); + entries.put(now, recipeTwo); + underTest = new MealPlan(entries); + + Map<LocalDate, Recipe> expected = Map.of(now, recipeTwo); + + //when + underTest.removePastRecipes(); + + //expect + assertEquals(expected, underTest.getAllRecipesFromPlan()); + } + + @Test + public void shouldClearDayIfPresent() { + //given + Map<LocalDate, Recipe> expected = Map.of(); + LocalDate date = LocalDate.now(); + underTest.addRecipeToMealPlan(recipeOne, date); + + //when + underTest.clear(date); + + //expect + assertEquals(expected, underTest.getAllRecipesFromPlan()); + } + + @Test + public void shouldThrowOnClearInvalidDate() { + //given + LocalDate date = LocalDate.now(); + + //expect + assertThrows(NullPointerException.class, () -> underTest.clear(null)); + assertThrows(NullPointerException.class, () -> underTest.clear(date)); + } +} diff --git a/src/test/java/mi/hdm/recipes/ValidObjectsPool.java b/src/test/java/mi/hdm/recipes/ValidObjectsPool.java index 013cdf977b0be94d1f4f5124911cf524c772d261..cea7fc00a0c59639a93305a5f51b76dcab166962 100644 --- a/src/test/java/mi/hdm/recipes/ValidObjectsPool.java +++ b/src/test/java/mi/hdm/recipes/ValidObjectsPool.java @@ -9,7 +9,7 @@ public class ValidObjectsPool { private final static NutritionTable nutritionTableOne = new NutritionTable(100.0, 17.2, 9.4, 4.3, 2.4, 0.4); private final static NutritionTable nutritionTableTwo = new NutritionTable(263.1, 25.2, 0.2, 0.0, 0.0, 0.8); private final static Ingredient ingredientOne = new Ingredient(Measurement.GRAM, "Zucker", nutritionTableOne); - private final static Ingredient ingredientTwo = new Ingredient(Measurement.PIECE, "Apple", nutritionTableTwo); + private final static Ingredient ingredientTwo = new Ingredient(Measurement.GRAM, "Apple", nutritionTableTwo); private final static Recipe recipeOne = new Recipe("Valid recipe 1", Map.of(ingredientOne, 100, ingredientTwo, 200), "Description for this recipe", List.of("step one", "step two"), List.of(categoryOne), 15); private final static Recipe recipeTwo = new Recipe("Apfelkuchen", Map.of(ingredientOne, 250), "Mein liebster APfelkuchen", List.of("mjam mjam", "ich liebe kochen"), List.of(categoryTwo, categoryOne), 25);