diff --git a/server/src/main/java/server/api/RecipeController.java b/server/src/main/java/server/api/RecipeController.java index bf8fc52..fe64067 100644 --- a/server/src/main/java/server/api/RecipeController.java +++ b/server/src/main/java/server/api/RecipeController.java @@ -31,12 +31,14 @@ import java.util.logging.Logger; @RequestMapping("/api") public class RecipeController { - private static final Logger logger = Logger.getLogger(RecipeController.class.getName()); + private static final Logger logger = Logger.getLogger( + RecipeController.class.getName()); private SimpMessagingTemplate messagingTemplate; private RecipeService recipeService; private RecipeRepository recipeRepository; - public RecipeController(RecipeService recipeService, SimpMessagingTemplate messagingTemplate) { + public RecipeController(RecipeService recipeService, + SimpMessagingTemplate messagingTemplate) { this.recipeService = recipeService; this.messagingTemplate = messagingTemplate; logger.info("Initialized controller."); @@ -72,24 +74,26 @@ public class RecipeController { ) { logger.info("GET /recipes called."); - // TODO: maybe refactor this. this is horrid and evil and nightmare - var recipes = locales - .map(loc -> { - return limit.map(lim -> { - return recipeService.findAllWithLocales(loc, lim); - }) - .orElseGet(() -> { - return recipeService.findAllWithLocales(loc); - }); - }) - .orElseGet( - // Choose the right overload. One has a limit, other doesn't. - () -> limit.map(recipeService::findAll).orElseGet(recipeService::findAll)); - + List recipes = locales + .map(loc -> findWithLocales(loc, limit)) + .orElseGet(() -> findAll(limit)); return ResponseEntity.ok(recipes); } + private List findWithLocales(List locales, Optional limit) { + return limit + .map(lim -> recipeService.findAllWithLocales(locales, lim)) + .orElseGet(() -> recipeService.findAllWithLocales(locales)); + } + + private List findAll(Optional limit) { + return limit + .map(recipeService::findAll) + .orElseGet(recipeService::findAll); + } + + /** * Mapping for POST /recipe/{id}. * Also creates the ingredient elements if they do not exist. diff --git a/server/src/test/java/server/api/IngredientControllerTest.java b/server/src/test/java/server/api/IngredientControllerTest.java index 849269a..1728ea7 100644 --- a/server/src/test/java/server/api/IngredientControllerTest.java +++ b/server/src/test/java/server/api/IngredientControllerTest.java @@ -6,6 +6,7 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.context.annotation.Import; +import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatusCode; import org.springframework.messaging.simp.SimpMessagingTemplate; import org.springframework.test.context.ActiveProfiles; @@ -70,18 +71,24 @@ public class IngredientControllerTest { @Test public void testGetAllIngredients() { - List ingredients = controller.getIngredients(Optional.empty(), Optional.empty()).getBody(); + List ingredients = controller.getIngredients( + Optional.empty(), + Optional.empty()).getBody(); assertNotNull(ingredients); final int expectedCount = 5; - assertEquals(expectedCount, ingredients.size()); - assertEquals("Eggs", ingredients.getFirst().name); + assertEquals(expectedCount, + ingredients.size()); + assertEquals("Eggs", + ingredients.getFirst().name); } @Test public void testGetPaginatedIngredients() { final int limit = 2; - List ingredients = controller.getIngredients(Optional.of(0), Optional.of(limit)).getBody(); + List ingredients = + controller.getIngredients(Optional.of(0), + Optional.of(limit)).getBody(); assertNotNull(ingredients); final int expectedCount = 2; @@ -105,14 +112,17 @@ public class IngredientControllerTest { public void testGetIngredientByInvalidId() { var response = controller.getIngredientById(INVALID_ID); - assertEquals(HttpStatusCode.valueOf(NOT_FOUND_STATUS), response.getStatusCode()); + assertEquals(HttpStatusCode.valueOf(NOT_FOUND_STATUS), + response.getStatusCode()); } @Test public void testCreateIngredient() { - Ingredient newIngredient = new Ingredient("Butter", PROTEIN_ALT, FAT_ALT, CARBS_ALT); + Ingredient newIngredient = new Ingredient("Butter", + PROTEIN_ALT, FAT_ALT, CARBS_ALT); - Ingredient createdIngredient = controller.createIngredient(newIngredient).getBody(); + Ingredient createdIngredient = + controller.createIngredient(newIngredient).getBody(); final int expectedCount = 6; @@ -123,11 +133,13 @@ public class IngredientControllerTest { @Test public void testCreateIngredientMissingName() { - Ingredient newIngredient = new Ingredient(null, PROTEIN_ALT, FAT_ALT, CARBS_ALT); + Ingredient newIngredient = new Ingredient(null, + PROTEIN_ALT, FAT_ALT, CARBS_ALT); var response = controller.createIngredient(newIngredient); - assertEquals(HttpStatusCode.valueOf(BAD_REQUEST_STATUS), response.getStatusCode()); + assertEquals(HttpStatusCode.valueOf(BAD_REQUEST_STATUS), + response.getStatusCode()); } @Test @@ -140,22 +152,30 @@ public class IngredientControllerTest { Long id = ingredient.id; - Ingredient updatedData = new Ingredient("Sea Salt", PROTEIN_ALT, FAT_ALT, CARBS_ALT); + Ingredient updatedData = new Ingredient("Sea Salt", + PROTEIN_ALT, FAT_ALT, CARBS_ALT); - Ingredient updatedIngredient = controller.updateIngredient(id, updatedData).getBody(); + Ingredient updatedIngredient = + controller.updateIngredient(id, updatedData).getBody(); assertNotNull(updatedIngredient); - assertEquals("Sea Salt", updatedIngredient.name); - assertEquals(PROTEIN_ALT, updatedIngredient.proteinPer100g); + assertEquals("Sea Salt", + updatedIngredient.name); + assertEquals(PROTEIN_ALT, + updatedIngredient.proteinPer100g); } @Test public void testUpdateMissingIngredient() { - Ingredient updatedData = new Ingredient("Sea Salt", PROTEIN_ALT, FAT_ALT, CARBS_ALT); + Ingredient updatedData = new Ingredient( + "Sea Salt", + PROTEIN_ALT, FAT_ALT, CARBS_ALT); - var response = controller.updateIngredient(INVALID_ID, updatedData); + var response = controller.updateIngredient(INVALID_ID, + updatedData); - assertEquals(HttpStatusCode.valueOf(NOT_FOUND_STATUS), response.getStatusCode()); + assertEquals(HttpStatusCode.valueOf(NOT_FOUND_STATUS), + response.getStatusCode()); } @Test @@ -171,14 +191,56 @@ public class IngredientControllerTest { var response = controller.deleteIngredient(id); final int expectedCount = 4; - assertEquals(HttpStatusCode.valueOf(OK_STATUS), response.getStatusCode()); - assertEquals(expectedCount, ingredientRepository.count()); + assertEquals(HttpStatusCode.valueOf(OK_STATUS), + response.getStatusCode()); + assertEquals(expectedCount, + ingredientRepository.count()); } @Test public void testDeleteMissingIngredient() { var response = controller.deleteIngredient(INVALID_ID); - assertEquals(HttpStatusCode.valueOf(NOT_FOUND_STATUS), response.getStatusCode()); + assertEquals(HttpStatusCode.valueOf(NOT_FOUND_STATUS), + response.getStatusCode()); + } + + @Test + public void testCreateIngredientNullIngredientReturnsBadRequest() { + var response = controller.createIngredient(null); + + assertEquals(HttpStatusCode.valueOf(BAD_REQUEST_STATUS), + response.getStatusCode()); + assertEquals(5, + ingredientRepository.count()); // unchanged + } + + @Test + public void testCreateIngredientBlankNameReturnsBadRequest() { + Ingredient blankName = new Ingredient( + " ", + PROTEIN_ALT, FAT_ALT, CARBS_ALT); + + var response = + controller.createIngredient(blankName); + + assertEquals(HttpStatusCode.valueOf(BAD_REQUEST_STATUS), + response.getStatusCode()); + assertEquals(5, + ingredientRepository.count()); + } + + @Test + public void testCreateIngredientDuplicateNameReturnsConflict() { + Ingredient duplicate = new Ingredient("Salt", + PROTEIN_ALT, FAT_ALT, CARBS_ALT); + + var response = + controller.createIngredient(duplicate); + + assertEquals(HttpStatus.CONFLICT, + response.getStatusCode()); + assertEquals(5, + ingredientRepository.count()); // unchanged } } diff --git a/server/src/test/java/server/api/RecipeControllerTest.java b/server/src/test/java/server/api/RecipeControllerTest.java index bede814..563d9ec 100644 --- a/server/src/test/java/server/api/RecipeControllerTest.java +++ b/server/src/test/java/server/api/RecipeControllerTest.java @@ -64,7 +64,10 @@ public class RecipeControllerTest { public void setup(TestInfo info) { recipes = LongStream .range(0, NUM_RECIPES) - .mapToObj(x -> new Recipe(null, "Recipe " + x, "en", List.of(), List.of())) + .mapToObj(x -> new Recipe( + null, + "Recipe " + x, + "en", List.of(), List.of())) .toList(); controller = new RecipeController( recipeService, @@ -94,20 +97,26 @@ public class RecipeControllerTest { controller.createRecipe(recipes.getFirst()); // There is 1 recipe in the repository - assertEquals(1, recipeRepository.count()); + assertEquals(1, + recipeRepository.count()); } @Test public void createManyRecipes() { - recipes.forEach(recipe -> controller.createRecipe(recipe)); + recipes.forEach(recipe -> + controller.createRecipe(recipe)); // There are the same number of recipes in the repository as the input list - assertEquals(recipes.size(), recipeRepository.count()); + assertEquals(recipes.size(), + recipeRepository.count()); } @Test @Tag("test-from-init-data") public void getManyRecipes() { // The number of recipes returned is the same as the entire input list - assertEquals(recipes.size(), controller.getRecipes(Optional.empty(), Optional.empty()).getBody().size()); + assertEquals(recipes.size(), + controller.getRecipes( + Optional.empty(), + Optional.empty()).getBody().size()); } @Test @@ -115,21 +124,28 @@ public class RecipeControllerTest { public void getSomeRecipes() { final int LIMIT = 5; // The number of recipes returned is the same as the entire input list - assertEquals(LIMIT, controller.getRecipes(Optional.empty(), Optional.of(LIMIT)).getBody().size()); + assertEquals(LIMIT, + controller.getRecipes( + Optional.empty(), + Optional.of(LIMIT)).getBody().size()); } @Test @Tag("test-from-init-data") public void getManyRecipesWithLocale() { // The number of recipes returned is the same as the entire input list - assertEquals(recipes.size(), controller.getRecipes(Optional.of(List.of("en", "nl")), Optional.empty()).getBody().size()); + assertEquals(recipes.size(), + controller.getRecipes(Optional.of(List.of("en", "nl")), + Optional.empty()).getBody().size()); } @Test @Tag("test-from-init-data") public void getNoRecipesWithLocale() { // should have NO Dutch recipes (thank god) - assertEquals(0, controller.getRecipes(Optional.of(List.of("nl")), Optional.empty()).getBody().size()); + assertEquals(0, + controller.getRecipes(Optional.of(List.of("nl")), + Optional.empty()).getBody().size()); } @Test @@ -137,7 +153,9 @@ public class RecipeControllerTest { public void getSomeRecipesWithLocale() { final int LIMIT = 5; // The number of recipes returned is the same as the entire input list - assertEquals(LIMIT, controller.getRecipes(Optional.of(List.of("en", "nl")), Optional.of(LIMIT)).getBody().size()); + assertEquals(LIMIT, + controller.getRecipes(Optional.of(List.of("en", "nl")), + Optional.of(LIMIT)).getBody().size()); } @Test @@ -167,7 +185,8 @@ public class RecipeControllerTest { final int DELETE_INDEX = 5; // The object has been successfully deleted - assertEquals(HttpStatus.OK, controller.deleteRecipe(recipeIds.get(DELETE_INDEX)).getStatusCode()); + assertEquals(HttpStatus.OK, + controller.deleteRecipe(recipeIds.get(DELETE_INDEX)).getStatusCode()); } @Test @@ -178,13 +197,15 @@ public class RecipeControllerTest { controller.deleteRecipe(recipeIds.get(DELETE_INDEX)); // The count of items decreased by 1 after the 5th item has been removed. - assertEquals(recipeIds.size() - 1, recipeRepository.count()); + assertEquals(recipeIds.size() - 1, + recipeRepository.count()); } @Test public void deleteOneRecipeFail() { final Long DELETE_INDEX = 5L; - assertEquals(HttpStatus.BAD_REQUEST, controller.deleteRecipe(DELETE_INDEX).getStatusCode()); + assertEquals(HttpStatus.BAD_REQUEST, + controller.deleteRecipe(DELETE_INDEX).getStatusCode()); } @Test @@ -195,6 +216,7 @@ public class RecipeControllerTest { Recipe newRecipe = controller.getRecipe(recipeIds.get(UPDATE_INDEX)).getBody(); newRecipe.setName("New recipe"); controller.updateRecipe(newRecipe.getId(), newRecipe); - assertEquals("New recipe", recipeRepository.getReferenceById(recipeIds.get(UPDATE_INDEX)).getName()); + assertEquals("New recipe", + recipeRepository.getReferenceById(recipeIds.get(UPDATE_INDEX)).getName()); } }