feat: language in recipes
This commit is contained in:
parent
1c9ffb9d13
commit
74b6f25e24
6 changed files with 86 additions and 12 deletions
|
|
@ -26,6 +26,7 @@ public class DefaultValueFactory {
|
||||||
return new Recipe(
|
return new Recipe(
|
||||||
null,
|
null,
|
||||||
"Untitled recipe",
|
"Untitled recipe",
|
||||||
|
"en",
|
||||||
List.of(),
|
List.of(),
|
||||||
List.of());
|
List.of());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,10 @@ public class Recipe {
|
||||||
@Column(name = "name", nullable = false, unique = true)
|
@Column(name = "name", nullable = false, unique = true)
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
|
// Locale in which the recipe was created.
|
||||||
|
@Column(name = "locale", nullable = false)
|
||||||
|
private String locale = "en";
|
||||||
|
|
||||||
// Creates another table named recipe_ingredients which stores:
|
// Creates another table named recipe_ingredients which stores:
|
||||||
// recipe_ingredients(recipe_id -> recipes(id), ingredient).
|
// recipe_ingredients(recipe_id -> recipes(id), ingredient).
|
||||||
// Example recipe_ingredients table:
|
// Example recipe_ingredients table:
|
||||||
|
|
@ -95,11 +99,15 @@ public class Recipe {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Replace String with Embeddable Ingredient Class for ingredients
|
public Recipe(Long id,
|
||||||
public Recipe(Long id, String name, List<RecipeIngredient> ingredients, List<String> preparationSteps) {
|
String name,
|
||||||
|
String locale,
|
||||||
|
List<RecipeIngredient> ingredients,
|
||||||
|
List<String> preparationSteps) {
|
||||||
// Not used by JPA/Spring
|
// Not used by JPA/Spring
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
this.locale = locale;
|
||||||
this.ingredients = ingredients;
|
this.ingredients = ingredients;
|
||||||
this.preparationSteps = preparationSteps;
|
this.preparationSteps = preparationSteps;
|
||||||
}
|
}
|
||||||
|
|
@ -120,6 +128,14 @@ public class Recipe {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getLocale() {
|
||||||
|
return locale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocale(String locale) {
|
||||||
|
this.locale = locale;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Replace String with Embeddable Ingredient Class
|
// TODO: Replace String with Embeddable Ingredient Class
|
||||||
public List<RecipeIngredient> getIngredients() {
|
public List<RecipeIngredient> getIngredients() {
|
||||||
// Disallow modifying the returned list.
|
// Disallow modifying the returned list.
|
||||||
|
|
@ -159,7 +175,7 @@ public class Recipe {
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Recipe " + id +
|
return "Recipe " + id +
|
||||||
" - " + name +
|
" - " + name + " (" + locale + ")" +
|
||||||
": " + ingredients.size() + " ingredients / " +
|
": " + ingredients.size() + " ingredients / " +
|
||||||
preparationSteps.size() + " steps";
|
preparationSteps.size() + " steps";
|
||||||
}
|
}
|
||||||
|
|
@ -170,6 +186,7 @@ public class Recipe {
|
||||||
return "Recipe{" +
|
return "Recipe{" +
|
||||||
"id=" + id +
|
"id=" + id +
|
||||||
", name='" + name + '\'' +
|
", name='" + name + '\'' +
|
||||||
|
", locale='" + locale + "'" +
|
||||||
", ingredients=" + ingredients +
|
", ingredients=" + ingredients +
|
||||||
", preparationSteps=" + preparationSteps +
|
", preparationSteps=" + preparationSteps +
|
||||||
'}';
|
'}';
|
||||||
|
|
|
||||||
|
|
@ -56,19 +56,35 @@ public class RecipeController {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mapping for <code>GET /recipes(?limit=)</code>
|
* Mapping for <code>GET /recipes(?limit=)(&locales=)</code>
|
||||||
* <p>
|
* <p>
|
||||||
* If the limit parameter is unspecified, return all recipes in the repository.
|
* If the limit parameter is unspecified, return all recipes in the repository.
|
||||||
* @param limit Integer limit of items you want to get
|
* @param limit Integer limit of items you want to get
|
||||||
* @return The list of recipes
|
* @return The list of recipes
|
||||||
*/
|
*/
|
||||||
@GetMapping("/recipes")
|
@GetMapping("/recipes")
|
||||||
public ResponseEntity<List<Recipe>> getRecipes(@RequestParam Optional<Integer> limit) {
|
public ResponseEntity<List<Recipe>> getRecipes(
|
||||||
|
@RequestParam Optional<List<String>> locales,
|
||||||
|
@RequestParam Optional<Integer> limit
|
||||||
|
) {
|
||||||
logger.info("GET /recipes called.");
|
logger.info("GET /recipes called.");
|
||||||
return ResponseEntity.ok(
|
|
||||||
|
// 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.
|
// Choose the right overload. One has a limit, other doesn't.
|
||||||
limit.map(recipeService::findAll).orElseGet(recipeService::findAll)
|
() -> limit.map(recipeService::findAll).orElseGet(recipeService::findAll));
|
||||||
);
|
|
||||||
|
|
||||||
|
return ResponseEntity.ok(recipes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,15 @@ import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
import commons.Recipe;
|
import commons.Recipe;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
|
||||||
public interface RecipeRepository extends JpaRepository<Recipe, Long> {
|
public interface RecipeRepository extends JpaRepository<Recipe, Long> {
|
||||||
boolean existsByName(String name);
|
boolean existsByName(String name);
|
||||||
|
|
||||||
|
List<Recipe> findAllByLocaleIsIn(Collection<String> locales);
|
||||||
|
Page<Recipe> findAllByLocaleIsIn(Collection<String> locales, Pageable pageable);
|
||||||
}
|
}
|
||||||
|
|
@ -7,6 +7,7 @@ import server.database.IngredientRepository;
|
||||||
import server.database.RecipeIngredientRepository;
|
import server.database.RecipeIngredientRepository;
|
||||||
import server.database.RecipeRepository;
|
import server.database.RecipeRepository;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
|
@ -36,6 +37,14 @@ public class RecipeService {
|
||||||
return recipeRepository.findAll(PageRequest.of(0, limit)).toList();
|
return recipeRepository.findAll(PageRequest.of(0, limit)).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Recipe> findAllWithLocales(Collection<String> locales) {
|
||||||
|
return recipeRepository.findAllByLocaleIsIn(locales);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Recipe> findAllWithLocales(Collection<String> locales, int limit) {
|
||||||
|
return recipeRepository.findAllByLocaleIsIn(locales, PageRequest.of(0, limit)).toList();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new recipe. Returns empty if the recipe with the same name already exists.
|
* Creates a new recipe. Returns empty if the recipe with the same name already exists.
|
||||||
* @param recipe Recipe to be saved in the db.
|
* @param recipe Recipe to be saved in the db.
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ public class RecipeControllerTest {
|
||||||
public void setup(TestInfo info) {
|
public void setup(TestInfo info) {
|
||||||
recipes = LongStream
|
recipes = LongStream
|
||||||
.range(0, NUM_RECIPES)
|
.range(0, NUM_RECIPES)
|
||||||
.mapToObj(x -> new Recipe(null, "Recipe " + x, List.of(), List.of()))
|
.mapToObj(x -> new Recipe(null, "Recipe " + x, "en", List.of(), List.of()))
|
||||||
.toList();
|
.toList();
|
||||||
controller = new RecipeController(
|
controller = new RecipeController(
|
||||||
recipeService,
|
recipeService,
|
||||||
|
|
@ -107,7 +107,7 @@ public class RecipeControllerTest {
|
||||||
@Tag("test-from-init-data")
|
@Tag("test-from-init-data")
|
||||||
public void getManyRecipes() {
|
public void getManyRecipes() {
|
||||||
// The number of recipes returned is the same as the entire input list
|
// The number of recipes returned is the same as the entire input list
|
||||||
assertEquals(recipes.size(), controller.getRecipes(Optional.empty()).getBody().size());
|
assertEquals(recipes.size(), controller.getRecipes(Optional.empty(), Optional.empty()).getBody().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -115,7 +115,29 @@ public class RecipeControllerTest {
|
||||||
public void getSomeRecipes() {
|
public void getSomeRecipes() {
|
||||||
final int LIMIT = 5;
|
final int LIMIT = 5;
|
||||||
// The number of recipes returned is the same as the entire input list
|
// The number of recipes returned is the same as the entire input list
|
||||||
assertEquals(LIMIT, controller.getRecipes(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());
|
||||||
|
}
|
||||||
|
|
||||||
|
@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());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Tag("test-from-init-data")
|
||||||
|
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());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue