Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Back to master #225

Open
wants to merge 36 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
ec6b226
completing assignment
bbqboneless Jul 7, 2023
c336b97
Adding repos
bbqboneless Jul 7, 2023
860c1cc
Adding startup page with bootstrap
bbqboneless Jul 13, 2023
efd3775
Refactoring convenient methods: Ingredients, Recipes and bootstrap
bbqboneless Jul 13, 2023
2368bfb
Committed Lombok stuff
bbqboneless Sep 22, 2023
f9cfb5e
Commit Panel Interface
bbqboneless Sep 25, 2023
ffd67cc
Unit Test using Mockito
bbqboneless Sep 25, 2023
7960185
Assignment: Unit Testing the Index Controller
bbqboneless Sep 25, 2023
f5233ea
Just adding Tests
bbqboneless Sep 25, 2023
c95346e
Updating the Recipe Repo and Recipe Service Impl, added the Recipe Co…
bbqboneless Sep 28, 2023
02e561d
Setting up recipe data with Thymeleaf
bbqboneless Sep 28, 2023
4761ee6
Creating a bunch of command, converter and test files that will help …
bbqboneless Oct 3, 2023
b9b2d00
Adding a New Recipe
bbqboneless Oct 4, 2023
c2e4f3d
Updating a Recipe
bbqboneless Oct 4, 2023
bb8aedf
Deleting a Recipe
bbqboneless Oct 4, 2023
dbf224e
View Ingredients
bbqboneless Oct 4, 2023
1e31fae
View and Update Ingredients
bbqboneless Dec 1, 2023
b02774b
New Ingredients
bbqboneless Dec 1, 2023
d615007
Delete Ingredients
bbqboneless Dec 1, 2023
f492815
Refactor some controllers
bbqboneless Dec 5, 2023
86f86af
Image Controller
bbqboneless Dec 5, 2023
bd09741
Images into database
bbqboneless Dec 6, 2023
8531f01
Display images
bbqboneless Dec 6, 2023
2d41da0
Display images - solved
bbqboneless Dec 6, 2023
cd315e9
Recipe Not Found Exception Handling
bbqboneless Dec 14, 2023
82b7c1c
Recipe Not Found Exception Handling with 404 Not Found legend added
bbqboneless Dec 14, 2023
0d9c09b
Add not found id to error handler
bbqboneless Dec 14, 2023
52b24aa
Add not found input string to error handler
bbqboneless Dec 14, 2023
a5cb96f
Make Bad Request error global
bbqboneless Dec 14, 2023
e25cb3d
Adding Constraints into the Recipe Command
bbqboneless Dec 14, 2023
7c1afdc
Updated form to visualize constraint errors
bbqboneless Dec 14, 2023
ac55b14
Added customized messages for constraints
bbqboneless Dec 14, 2023
c2cf1c8
Internationalization
bbqboneless Dec 14, 2023
72cd6bc
Configuration of MySQL
bbqboneless Dec 22, 2023
0a1c73d
Database schema for use
bbqboneless Dec 22, 2023
08b356d
Database schema for use 2
bbqboneless Dec 22, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,41 @@
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>5.2.3</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.6.4</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.0.32</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand All @@ -61,6 +91,28 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.20</version>
<configuration>
<includes>
<include>**/*.IT.java</include>
</includes>
<additionalClasspathElements>
<additionalClasspathElement>${basedir}/target/classes</additionalClasspathElement>
</additionalClasspathElements>
<parallel>none</parallel>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

Expand Down
91 changes: 91 additions & 0 deletions src/main/java/guru/springframework/bootstrap/BootStrapMySQL.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package guru.springframework.bootstrap;

import guru.springframework.domain.Category;
import guru.springframework.domain.UnitOfMeasure;
import guru.springframework.repositories.CategoryRepository;
import guru.springframework.repositories.UnitOfMeasureRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Profile;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

@Slf4j
@Component
@Profile({"dev","prod"})
public class BootStrapMySQL implements ApplicationListener<ContextRefreshedEvent> {
private final CategoryRepository categoryRepository;
private final UnitOfMeasureRepository unitOfMeasureRepository;

public BootStrapMySQL(CategoryRepository categoryRepository,
UnitOfMeasureRepository unitOfMeasureRepository) {
this.categoryRepository = categoryRepository;
this.unitOfMeasureRepository = unitOfMeasureRepository;
}

@Override
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {

if (categoryRepository.count() == 0L){
log.debug("Loading Categories");
loadCategories();
}

if (unitOfMeasureRepository.count() == 0L){
log.debug("Loading UOMs");
loadUom();
}
}

private void loadCategories(){
Category cat1 = new Category();
cat1.setDescription("American");
categoryRepository.save(cat1);

Category cat2 = new Category();
cat2.setDescription("Italian");
categoryRepository.save(cat2);

Category cat3 = new Category();
cat3.setDescription("Mexican");
categoryRepository.save(cat3);

Category cat4 = new Category();
cat4.setDescription("Fast Food");
categoryRepository.save(cat4);
}

private void loadUom(){
UnitOfMeasure uom1 = new UnitOfMeasure();
uom1.setDescription("Teaspoon");
unitOfMeasureRepository.save(uom1);

UnitOfMeasure uom2 = new UnitOfMeasure();
uom2.setDescription("Tablespoon");
unitOfMeasureRepository.save(uom2);

UnitOfMeasure uom3 = new UnitOfMeasure();
uom3.setDescription("Cup");
unitOfMeasureRepository.save(uom3);

UnitOfMeasure uom4 = new UnitOfMeasure();
uom4.setDescription("Pinch");
unitOfMeasureRepository.save(uom4);

UnitOfMeasure uom5 = new UnitOfMeasure();
uom5.setDescription("Ounce");
unitOfMeasureRepository.save(uom5);

UnitOfMeasure uom6 = new UnitOfMeasure();
uom6.setDescription("Each");
unitOfMeasureRepository.save(uom6);

UnitOfMeasure uom7 = new UnitOfMeasure();
uom7.setDescription("Pint");
unitOfMeasureRepository.save(uom7);

UnitOfMeasure uom8 = new UnitOfMeasure();
uom8.setDescription("Dash");
unitOfMeasureRepository.save(uom8);
}
}
162 changes: 162 additions & 0 deletions src/main/java/guru/springframework/bootstrap/RecipeBootstrap.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
package guru.springframework.bootstrap;

import guru.springframework.domain.*;
import guru.springframework.repositories.CategoryRepository;
import guru.springframework.repositories.RecipeRepository;
import guru.springframework.repositories.UnitOfMeasureRepository;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.weaver.ast.Not;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Profile;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

import javax.transaction.Transactional;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@Slf4j
@Component
@Profile("default")
public class RecipeBootstrap implements ApplicationListener<ContextRefreshedEvent> {
private final CategoryRepository categoryRepository;
private final RecipeRepository recipeRepository;
private final UnitOfMeasureRepository unitOfMeasureRepository;

public RecipeBootstrap(CategoryRepository categoryRepository, RecipeRepository recipeRepository, UnitOfMeasureRepository unitOfMeasureRepository) {
this.categoryRepository = categoryRepository;
this.recipeRepository = recipeRepository;
this.unitOfMeasureRepository = unitOfMeasureRepository;
}
//guardar lo que viene de los repositorios
@Override
@Transactional
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
recipeRepository.saveAll(getRecipes());
log.debug("Loading bootstrap data...");
}

private List<Recipe> getRecipes(){
List<Recipe> recipes = new ArrayList<>(2);

//get Units Of Measure
Optional<UnitOfMeasure> eachUomOptional = unitOfMeasureRepository.findByDescription("Each");
if(!eachUomOptional.isPresent()){
throw new RuntimeException("Expected Each UOM not found");
}
Optional<UnitOfMeasure> tableSpoonUomOptional = unitOfMeasureRepository.findByDescription("Tablespoon");
if(!tableSpoonUomOptional.isPresent()){
throw new RuntimeException("Expected Tablespoon UOM not found");
}
Optional<UnitOfMeasure> teaSpoonUomOptional = unitOfMeasureRepository.findByDescription("Teaspoon");
if(!teaSpoonUomOptional.isPresent()){
throw new RuntimeException("Expected Teaspoon UOM not found");
}
Optional<UnitOfMeasure> dashUOMOptional = unitOfMeasureRepository.findByDescription("Dash");
if(!dashUOMOptional.isPresent()){
throw new RuntimeException("Expected Dash UOM not found");
}
Optional<UnitOfMeasure> pintUOMOptional = unitOfMeasureRepository.findByDescription("Pint");
if(!pintUOMOptional.isPresent()){
throw new RuntimeException("Expected Pint UOM not found");
}
Optional<UnitOfMeasure> cupsUOMOptional = unitOfMeasureRepository.findByDescription("Cup");
if(!cupsUOMOptional.isPresent()){
throw new RuntimeException("Expected Cup UOM not found");
}

//get optionals
UnitOfMeasure eachUom = eachUomOptional.get();
UnitOfMeasure tableSpoonUOM = tableSpoonUomOptional.get();
UnitOfMeasure teaspoonUOM = teaSpoonUomOptional.get();
UnitOfMeasure dashUom = dashUOMOptional.get();
UnitOfMeasure pintUom = pintUOMOptional.get();
UnitOfMeasure cupsUom = cupsUOMOptional.get();

//Categorias
Optional<Category> americanCategoryOptional = categoryRepository.findByDescription("American");
if(!americanCategoryOptional.isPresent()){
throw new RuntimeException("Expected Category not found");
}
Optional<Category> mexicanCategoryOptional = categoryRepository.findByDescription("Mexican");
if(!mexicanCategoryOptional.isPresent()){
throw new RuntimeException("Expected Category not found");
}

Category americanCategory = americanCategoryOptional.get();
Category mexicanCategory = mexicanCategoryOptional.get();

//Creamos la receta
Recipe guacRecipe = new Recipe();
guacRecipe.setDescription("Perfect Guacamole");
guacRecipe.setPrepTime(10);
guacRecipe.setCookTime(0);
guacRecipe.setDifficulty(Difficulty.EASY);
guacRecipe.setDirections("1. Cut the avocados: Cut the avocados in half. Remove the pit. Score the inside of the avocado with a blunt knife and scoop out the flesh with a spoon. Place in a bowl\n" +
"2. Mash the avocado flesh: Using a fork, roughly mash the avocado. \n" +
"3. Add the remaining ingredients to taste: Sprinkle with salt and lime (or lemon) juice. Add the chopped onion, cilantro, black pepper, and chilis.\n" +
"4. Serve immediately\n");
Notes guacNotes = new Notes();
guacNotes.setRecipeNotes("Chilling tomatoes hurts their flavor.\n" +
"So, if you want to add chopped tomato to your guacamole, add it just before serving.\n" +
"Read more: https://www.simplyrecipes.com/recipes/perfect_guacamole/");
guacRecipe.setNotes(guacNotes);
guacRecipe.addIngredient(new Ingredient("Ripe Avocados",new BigDecimal(2), eachUom));
guacRecipe.addIngredient(new Ingredient("Kosher salt",new BigDecimal(0.5), teaspoonUOM));
guacRecipe.addIngredient(new Ingredient("Fresh lime/lemon juice",new BigDecimal(2), tableSpoonUOM));
guacRecipe.addIngredient(new Ingredient("Minced Red/green onion ",new BigDecimal(2), tableSpoonUOM));
guacRecipe.addIngredient(new Ingredient("Serrano chiles, stems and seeds removed",new BigDecimal(2), eachUom));
guacRecipe.addIngredient(new Ingredient("Cilantro",new BigDecimal(2),tableSpoonUOM));
guacRecipe.addIngredient(new Ingredient("Freshly grated black pepper",new BigDecimal(2), dashUom));
guacRecipe.addIngredient(new Ingredient("Ripe tomato, seeds and pulp removed",new BigDecimal(0.5), eachUom));

guacRecipe.getCategories().add(americanCategory);
guacRecipe.getCategories().add(mexicanCategory);
guacRecipe.setUrl("https://www.simplyrecipes.com/recipes/perfect_guacamole/");
guacRecipe.setServings(4);
guacRecipe.setSource("Simply Recipes");

recipes.add(guacRecipe);

//Tacos
Recipe tacosRecipe = new Recipe();
tacosRecipe.setDescription("Spicy Grilled Chicken Taco");
tacosRecipe.setCookTime(15);
tacosRecipe.setPrepTime(20);
tacosRecipe.setDifficulty(Difficulty.MODERATE);

tacosRecipe.setDirections("1. Prepare the grill: Prepare either a gas or charcoal grill for medium-high, direct heat.\n" +
"2. Make the marinade and coat the chicken: In a large bowl, stir together the chili powder, oregano, cumin, sugar, salt, garlic and orange zest. Stir in the orange juice and olive oil to make a loose paste. Add the chicken to the bowl and toss to coat all over. Set aside.\n" +
"3. Grill the chicken: Grill the chicken for 3 to 4 minutes per side, or until a thermometer inserted into the thickest part of the meat registers 165°F. Transfer to a plate and rest for 5 minutes.\n" +
"4. Thin the sour cream with milk: Stir together the sour cream and milk to thin out the sour cream to make it easy to drizzle.\n" +
"5. Assemble the tacos: Slice the chicken into strips. On each tortilla, place a small handful of arugula. Top with chicken slices, sliced avocado, radishes, tomatoes, and onion slices. Drizzle with the thinned sour cream. Serve with lime wedges.\n" +
"6. Warm the tortillas: Place each tortilla on the grill or on a hot, dry skillet over medium-high heat. As soon as you see pockets of the air start to puff up in the tortilla, turn it with tongs and heat for a few seconds on the other side. Wrap warmed tortillas in a tea towel to keep them warm until serving.\n");

Notes tacoNotes = new Notes();
tacoNotes.setRecipeNotes("Look for ancho chile powder with the Mexican ingredients at your grocery store, on buy it online. (If you can't find ancho chili powder, you replace the ancho chili, the oregano, and the cumin with 2 1/2 tablespoons regular chili powder, though the flavor won't be quite the same.)\n" +
"Read more: https://www.simplyrecipes.com/recipes/spicy_grilled_chicken_tacos/\n");
tacosRecipe.setNotes(tacoNotes);

tacosRecipe.addIngredient(new Ingredient("Ancho chilli powder", new BigDecimal(2), tableSpoonUOM));
tacosRecipe.addIngredient(new Ingredient("Dried oregano", new BigDecimal(1), teaspoonUOM));
tacosRecipe.addIngredient(new Ingredient("Dried Cumin", new BigDecimal(1), teaspoonUOM));
tacosRecipe.addIngredient(new Ingredient("Salt", new BigDecimal(0.5), teaspoonUOM));
tacosRecipe.addIngredient(new Ingredient("Corn tortillas", new BigDecimal(8), eachUom));
tacosRecipe.addIngredient(new Ingredient("Avocado, sliced", new BigDecimal(2), eachUom));
tacosRecipe.addIngredient(new Ingredient("Boneless Chicken thighs", new BigDecimal(6), eachUom));
tacosRecipe.addIngredient(new Ingredient("Onion, sliced", new BigDecimal(0.25), eachUom));
tacosRecipe.addIngredient(new Ingredient("Sour cream", new BigDecimal(0.5), cupsUom));
tacosRecipe.addIngredient(new Ingredient("Lime/lemon", new BigDecimal(1), eachUom));

tacosRecipe.getCategories().add(americanCategory);
tacosRecipe.getCategories().add(mexicanCategory);

tacosRecipe.setUrl("https://www.simplyrecipes.com/recipes/spicy_grilled_chicken_tacos/");
tacosRecipe.setServings(6);
tacosRecipe.setSource("Simply Recipes");

recipes.add(tacosRecipe);
return recipes;
}
}
13 changes: 13 additions & 0 deletions src/main/java/guru/springframework/commands/CategoryCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package guru.springframework.commands;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Setter
@Getter
@NoArgsConstructor
public class CategoryCommand {
private Long id;
private String description;
}
18 changes: 18 additions & 0 deletions src/main/java/guru/springframework/commands/IngredientCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package guru.springframework.commands;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.math.BigDecimal;

@Getter
@Setter
@NoArgsConstructor
public class IngredientCommand {
private Long id;
private Long recipeId;
private String description;
private BigDecimal amount;
private UnitOfMeasureCommand uom;
}
13 changes: 13 additions & 0 deletions src/main/java/guru/springframework/commands/NotesCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package guru.springframework.commands;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@NoArgsConstructor
public class NotesCommand {
private Long id;
private String recipeNotes;
}
Loading