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

✨ save categories of recipe #68

Merged
merged 9 commits into from
Jul 24, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,21 @@
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;

@Entity
@NoArgsConstructor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@NoArgsConstructor에 접근 지정자를 붙여줘도 좋을것 같아요

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그런 기능이 있었군요
좋은 생각입니다
추가하겠습니다~

@AllArgsConstructor
public class Category {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;

private String name;

public Category(String name) {
this(0, name);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여러분 일관성을 위해 앞으로 둘중 하나로 통일하는건 어떤가요??

  • this(0, name);
  • this(0L, name);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

토의 결과대로 0L로 변경하도록 하겠습니다~

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import net.pengcook.recipe.domain.Recipe;

@Entity
@NoArgsConstructor
@AllArgsConstructor
public class CategoryRecipe {

@Id
Expand All @@ -22,4 +26,8 @@ public class CategoryRecipe {
@ManyToOne
@JoinColumn(name = "recipe_id")
private Recipe recipe;

public CategoryRecipe(Category category, Recipe recipe) {
this(0, category, recipe);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package net.pengcook.category.repository;

import net.pengcook.category.domain.CategoryRecipe;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JpaRepository를 상속받고있어서 애너테이션을 제거해도 정상동작할것같은데요, 넣어두신 이유가 궁금합니다!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JpaRepository면 Spring Data JPA가 알아서 구현체를 주입해주는군요!
처음 알았네요.
빈으로 등록이 안될 것이라 생각하고 붙였습니다.
수정하겠습니다~

public interface CategoryRecipeRepository extends JpaRepository<CategoryRecipe, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package net.pengcook.category.repository;

import java.util.Optional;
import net.pengcook.category.domain.Category;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface CategoryRepository extends JpaRepository<Category, Long> {

Optional<Category> findByName(String name);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package net.pengcook.category.service;

import java.util.List;
import lombok.RequiredArgsConstructor;
import net.pengcook.category.domain.Category;
import net.pengcook.category.domain.CategoryRecipe;
import net.pengcook.category.repository.CategoryRecipeRepository;
import net.pengcook.category.repository.CategoryRepository;
import net.pengcook.recipe.domain.Recipe;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class CategoryService {

private final CategoryRepository categoryRepository;
private final CategoryRecipeRepository categoryRecipeRepository;

public void saveCategories(Recipe recipe, List<String> categories) {
categories.forEach(category -> saveCategoryRecipe(recipe, category));
}

private void saveCategoryRecipe(Recipe recipe, String name) {
Category category = categoryRepository.findByName(name)
.orElseGet(() -> categoryRepository.save(new Category(name)));

categoryRecipeRepository.save(new CategoryRecipe(category, recipe));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package net.pengcook.category.service;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertAll;

import java.time.LocalDate;
import java.time.LocalTime;
import java.util.List;
import net.pengcook.category.repository.CategoryRecipeRepository;
import net.pengcook.category.repository.CategoryRepository;
import net.pengcook.recipe.domain.Recipe;
import net.pengcook.user.domain.User;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.jdbc.Sql;

@DataJpaTest
@Import(CategoryService.class)
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
Copy link
Contributor

@geoje geoje Jul 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

혹시 이 부분(23 line)은 무슨 의도 일까용?!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

로키 테스트에서 긁어서 변경 후 사용했는데 저한테는 필요 없는 부분이 딸려왔네요
인메모리 db로도 충분한 테스트인 것 같습니다!

@Sql(scripts = "/data/category.sql")
class CategoryServiceTest {

private final long INITIAL_CATEGORY_COUNT = 5;
private final long INITIAL_CATEGORY_RECIPE_COUNT = 0;

@Autowired
private CategoryService categoryService;
@Autowired
private CategoryRepository categoryRepository;
@Autowired
private CategoryRecipeRepository categoryRecipeRepository;

@Test
@DisplayName("레시피의 카테고리를 저장할 수 있다.")
void saveCategories() {
User author = new User("[email protected]", "ela", "엘라", "ela.jpg", LocalDate.of(2024, 7, 22), "KOREA");
Recipe recipe = new Recipe(1L, "김치볶음밥", author, LocalTime.of(0, 30, 0), "김치볶음밥이미지.jpg", 3, 2, "김치볶음밥 조리법");

categoryService.saveCategories(recipe, List.of("한식", "매운음식"));

assertAll(
() -> assertThat(categoryRepository.count()).isEqualTo(INITIAL_CATEGORY_COUNT + 1),
() -> assertThat(categoryRecipeRepository.count()).isEqualTo(INITIAL_CATEGORY_RECIPE_COUNT + 2)
);
}
}
34 changes: 34 additions & 0 deletions backend/src/test/resources/data/category.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
SET REFERENTIAL_INTEGRITY FALSE;

TRUNCATE TABLE users;
ALTER TABLE users ALTER COLUMN id RESTART;

TRUNCATE TABLE category;
ALTER TABLE category ALTER COLUMN id RESTART;

TRUNCATE TABLE ingredient;
ALTER TABLE ingredient ALTER COLUMN id RESTART;

TRUNCATE TABLE recipe;
ALTER TABLE recipe ALTER COLUMN id RESTART;

TRUNCATE TABLE category_recipe;
ALTER TABLE category_recipe ALTER COLUMN id RESTART;

TRUNCATE TABLE ingredient_recipe;
ALTER TABLE ingredient_recipe ALTER COLUMN id RESTART;

SET REFERENTIAL_INTEGRITY TRUE;

INSERT INTO users (email, username, nickname, image, birth, region)
VALUES ('[email protected]', 'ela', '엘라', 'ela.jpg', '2024-07-22', 'KOREA');

INSERT INTO category (name)
VALUES ('한식'),
('양식'),
('채식'),
('건강식'),
('간편식');

INSERT INTO recipe (title, author_id, cooking_time, thumbnail, difficulty, like_count, description)
VALUES ('김치볶음밥', 1, '00:30:00', '김치볶음밥이미지.jpg', 3, 2, '김치볶음밥 조리법');
Loading