diff --git a/server/src/main/java/server/api/RecipeController.java b/server/src/main/java/server/api/RecipeController.java index 2a56310..37a2a78 100644 --- a/server/src/main/java/server/api/RecipeController.java +++ b/server/src/main/java/server/api/RecipeController.java @@ -7,8 +7,6 @@ import commons.ws.Topics; import commons.ws.messages.CreateRecipeMessage; import commons.ws.messages.DeleteRecipeMessage; import commons.ws.messages.UpdateRecipeMessage; -import org.springframework.data.domain.Example; -import org.springframework.data.domain.PageRequest; import org.springframework.http.ResponseEntity; import org.springframework.messaging.simp.SimpMessagingTemplate; @@ -22,9 +20,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import server.database.IngredientRepository; -import server.database.RecipeIngredientRepository; -import server.database.RecipeRepository; +import server.service.RecipeService; import java.util.List; import java.util.Optional; @@ -32,19 +28,12 @@ import java.util.Optional; @RestController @RequestMapping("/api") public class RecipeController { - private final RecipeRepository recipeRepository; // JPA repository used in this controller private final SimpMessagingTemplate messagingTemplate; - private final RecipeIngredientRepository recipeIngredientRepository; - private final IngredientRepository ingredientRepository; + private final RecipeService recipeService; - public RecipeController(RecipeRepository recipeRepository, - SimpMessagingTemplate messagingTemplate, - IngredientRepository ingredientRepository, - RecipeIngredientRepository recipeIngredientRepository) { - this.recipeRepository = recipeRepository; + public RecipeController(RecipeService recipeService, SimpMessagingTemplate messagingTemplate) { + this.recipeService = recipeService; this.messagingTemplate = messagingTemplate; - this.recipeIngredientRepository = recipeIngredientRepository; - this.ingredientRepository = ingredientRepository; } /** @@ -57,10 +46,9 @@ public class RecipeController { */ @GetMapping("/recipe/{id}") public ResponseEntity getRecipe(@PathVariable Long id) { - if (!recipeRepository.existsById(id)) { - return ResponseEntity.notFound().build(); - } - return ResponseEntity.ok(recipeRepository.findById(id).get()); + return recipeService.findById(id) + .map(ResponseEntity::ok) + .orElseGet(() -> ResponseEntity.notFound().build()); } /** @@ -72,28 +60,12 @@ public class RecipeController { */ @GetMapping("/recipes") public ResponseEntity> getRecipes(@RequestParam Optional limit) { - if (limit.isPresent()) { - return ResponseEntity.ok( - recipeRepository.findAll( - PageRequest.of(0, limit.get()) - ).toList()); - } + return ResponseEntity.ok( + // Choose the right overload. One has a limit, other doesn't. + limit.map(recipeService::findAll).orElseGet(recipeService::findAll) + ); + } - return ResponseEntity.ok(recipeRepository.findAll()); - } - private Recipe saveRecipeAndDependencies(Recipe recipe) { - recipe.getIngredients() - .forEach(recipeIngredient -> - recipeIngredient.setIngredient( - ingredientRepository - .findByName(recipeIngredient.getIngredient().name) - .orElseGet(() -> ingredientRepository.save(recipeIngredient.getIngredient()) - )) - ); - recipeIngredientRepository.saveAll(recipe.getIngredients()); - Recipe saved = recipeRepository.save(recipe); - return saved; - } /** * Mapping for POST /recipe/{id}. * Also creates the ingredient elements if they do not exist. @@ -104,13 +76,12 @@ public class RecipeController { */ @PostMapping("/recipe/{id}") public ResponseEntity updateRecipe(@PathVariable Long id, @RequestBody Recipe recipe) { - if (!recipeRepository.existsById(id)) { - return ResponseEntity.badRequest().build(); - } - Recipe saved = saveRecipeAndDependencies(recipe); - messagingTemplate.convertAndSend(Topics.RECIPES, new UpdateRecipeMessage(saved)); - - return ResponseEntity.ok(saved); + return recipeService.update(id, recipe) + .map(saved -> { + messagingTemplate.convertAndSend(Topics.RECIPES, new UpdateRecipeMessage(saved)); // Send to WS. + return ResponseEntity.ok(saved); + }) + .orElseGet(() -> ResponseEntity.notFound().build()); // Recipe with that id not found. } /** @@ -125,22 +96,12 @@ public class RecipeController { */ @PutMapping("/recipe/new") public ResponseEntity createRecipe(@RequestBody Recipe recipe) { - - // We initialize a new example recipe with the name of input recipe - // This is the only attribute we are concerned about making sure it's unique - Recipe example = new Recipe(); - example.setName(recipe.getName()); - - /* Here we use very funny JPA magic repository.exists(Example) - We check if any recipe in the repository has the same name as the input - */ - if (recipeRepository.exists(Example.of(example))) { - return ResponseEntity.badRequest().build(); - } - Recipe saved = saveRecipeAndDependencies(recipe); - messagingTemplate.convertAndSend(Topics.RECIPES, new CreateRecipeMessage(saved)); - - return ResponseEntity.ok(saved); + return recipeService.create(recipe) + .map(saved -> { + messagingTemplate.convertAndSend(Topics.RECIPES, new CreateRecipeMessage(saved)); // Send to WS. + return ResponseEntity.ok(saved); + }) + .orElseGet(() -> ResponseEntity.badRequest().build()); // That recipe already exists. } /** @@ -153,13 +114,10 @@ public class RecipeController { */ @DeleteMapping("/recipe/{id}") public ResponseEntity deleteRecipe(@PathVariable Long id) { - if (!recipeRepository.existsById(id)) { + if (!recipeService.delete(id)) { return ResponseEntity.badRequest().build(); } - recipeRepository.deleteById(id); - - messagingTemplate.convertAndSend(Topics.RECIPES, new DeleteRecipeMessage(id)); - + messagingTemplate.convertAndSend(Topics.RECIPES, new DeleteRecipeMessage(id)); // Send to WS. return ResponseEntity.ok(true); } } diff --git a/server/src/test/java/server/api/RecipeControllerTest.java b/server/src/test/java/server/api/RecipeControllerTest.java index c16490c..c052688 100644 --- a/server/src/test/java/server/api/RecipeControllerTest.java +++ b/server/src/test/java/server/api/RecipeControllerTest.java @@ -13,9 +13,8 @@ import org.springframework.http.HttpStatus; import org.springframework.messaging.simp.SimpMessagingTemplate; import org.springframework.test.context.ActiveProfiles; import server.WebSocketConfig; -import server.database.IngredientRepository; -import server.database.RecipeIngredientRepository; import server.database.RecipeRepository; +import server.service.RecipeService; import java.util.ArrayList; import java.util.List; @@ -38,30 +37,27 @@ import static org.junit.jupiter.api.Assertions.assertEquals; // This is required to enable WebSocket messaging in tests // // Without this line, Spring screams about missing SimpMessagingTemplate bean -@Import(WebSocketConfig.class) +@Import({WebSocketConfig.class, RecipeService.class}) public class RecipeControllerTest { - + private final RecipeService recipeService; + private final RecipeRepository recipeRepository; private final SimpMessagingTemplate template; private RecipeController controller; + private List recipes; - private final RecipeRepository recipeRepository; private List recipeIds; public static final int NUM_RECIPES = 10; - private final IngredientRepository ingredientRepository; - private final RecipeIngredientRepository recipeIngredientRepository; // Injects a test repository into the test class @Autowired public RecipeControllerTest( + RecipeService recipeService, RecipeRepository recipeRepository, - SimpMessagingTemplate template, - IngredientRepository ingredientRepository, - RecipeIngredientRepository recipeIngredientRepository + SimpMessagingTemplate template ) { + this.recipeService = recipeService; this.recipeRepository = recipeRepository; this.template = template; - this.ingredientRepository = ingredientRepository; - this.recipeIngredientRepository = recipeIngredientRepository; } @BeforeEach @@ -71,10 +67,8 @@ public class RecipeControllerTest { .mapToObj(x -> new Recipe(null, "Recipe " + x, List.of(), List.of())) .toList(); controller = new RecipeController( - recipeRepository, - template, - ingredientRepository, - recipeIngredientRepository + recipeService, + template ); Set tags = info.getTags(); List ids = new ArrayList<>();