Conversation
WalkthroughThis update introduces a complete article creation feature, including REST API endpoint, service and domain logic, exception handling, validation, and related tests. It also adds supporting infrastructure for category validation and test fixture management, enforces unique constraints on articles, and updates global exception codes for precise error reporting. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Controller as ArticleController
participant Usecase as ArticleManagementUsecase
participant ArticleGet as ArticleGetService
participant CategoryGet as CategoryGetService
participant ArticleSave as ArticleSaveService
Client->>Controller: POST /article (ArticleCreateRequest)
Controller->>Usecase: createArticle(user, command)
Usecase->>ArticleGet: checkExistsByUserAndUrl(user, url)
ArticleGet-->>Usecase: exists? (bool)
alt Article already exists
Usecase-->>Controller: throw ArticleAlreadyExistException
else Article does not exist
Usecase->>CategoryGet: getCategoryAndUser(categoryId, user)
CategoryGet-->>Usecase: Category
Usecase->>ArticleSave: save(new Article)
ArticleSave-->>Usecase: (void)
Usecase-->>Controller: (void)
end
Controller-->>Client: ResponseDto<Void> (201 CREATED)
Suggested reviewers
Poem
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (11)
src/main/java/com/pinback/pinback_server/domain/article/exception/ArticleAlreadyExistException.java (1)
6-10: Consider adding context parameters for better error reporting.The exception implementation is correct and follows the established pattern. However, consider adding optional parameters to provide more context about which URL and user caused the duplicate.
Here's an enhanced version that maintains backward compatibility:
public class ArticleAlreadyExistException extends ApplicationException { public ArticleAlreadyExistException() { super(ExceptionCode.ARTICLE_ALREADY_EXIST); } + + public ArticleAlreadyExistException(String url, String username) { + super(ExceptionCode.ARTICLE_ALREADY_EXIST, + String.format("Article with URL '%s' already exists for user '%s'", url, username)); + } }src/test/java/com/pinback/pinback_server/domain/ApplicationTest.java (1)
12-12: Consider renaming the class for better clarity.The class name
ApplicationTestis misleading since it doesn't contain actual tests. Consider renaming it toBaseIntegrationTestorApplicationTestBaseto better reflect its purpose as a test base class.-public class ApplicationTest { +public abstract class BaseIntegrationTest {src/test/java/com/pinback/pinback_server/domain/fixture/CustomRepository.java (1)
20-21: Ensure consistent ID reset and database portability.Two observations:
- Consider resetting the
userstable ID counter for consistency- The
ALTER TABLE ... RESTART WITHsyntax is H2-specificentityManager.createNativeQuery("ALTER TABLE article ALTER COLUMN article_id RESTART WITH 1").executeUpdate(); entityManager.createNativeQuery("ALTER TABLE category ALTER COLUMN category_id RESTART WITH 1").executeUpdate(); + entityManager.createNativeQuery("ALTER TABLE users ALTER COLUMN user_id RESTART WITH 1").executeUpdate();src/main/java/com/pinback/pinback_server/domain/category/domain/service/CategoryGetService.java (1)
19-21: Consider renaming method for clarity.The method name
getCategoryAndUseris slightly misleading as it retrieves a category for a user, not both entities. Consider renaming to better reflect the operation:- public Category getCategoryAndUser(long categoryId, User user) { + public Category getCategoryByIdAndUser(long categoryId, User user) {Otherwise, the implementation is clean and follows good practices with proper exception handling.
src/test/java/com/pinback/pinback_server/domain/category/domain/service/CategoryGetServiceTest.java (1)
34-44: Consider adding positive test case for completeness.The test covers the exception scenario well, but consider adding a positive test case to verify successful category retrieval when the user owns the category:
@DisplayName("카테고리 소유자일 경우 정상적으로 조회된다.") @Test void getCategoryWhenOwner() { // given User user = userRepository.save(user()); Category category = categoryRepository.save(category(user)); // when Category result = categoryGetService.getCategoryAndUser(category.getId(), user); // then assertThat(result).isNotNull(); assertThat(result.getId()).isEqualTo(category.getId()); }The existing test implementation is solid and follows good practices.
src/test/java/com/pinback/pinback_server/domain/fixture/TestFixture.java (1)
19-21: Consider i18n implications for test data.The hard-coded Korean text "테스트카테고리" in the category name might cause issues in international development environments or CI/CD pipelines that don't support Korean characters. Consider using English for test fixtures:
- public static Category category(User user) { - return Category.create("테스트카테고리", user); - } + public static Category category(User user) { + return Category.create("Test Category", user); + }Otherwise, the fixture design is excellent with good separation of concerns and consistent factory methods.
src/main/java/com/pinback/pinback_server/domain/article/presentation/dto/request/ArticleCreateRequest.java (2)
11-11: Consider more precise validation message.The message "url을 비어있을 수 없습니다" (URL cannot be empty) is accurate for
@NotEmptyvalidation. However, consider externalizing validation messages to a properties file for better maintainability and internationalization support.
14-14: Improve validation message precision.The message "카테고리 ID는 비어있을 수 없습니다" (Category ID cannot be empty) is slightly imprecise since
Longvalues are null rather than empty. Consider using "카테고리 ID는 필수입니다" (Category ID is required) for better clarity.src/main/java/com/pinback/pinback_server/domain/article/application/ArticleManagementUsecase.java (1)
28-35: Consider returning the created article.The method returns
voidbut could return the createdArticleentity, which would be useful for getting the generated ID and other computed fields.-public void createArticle(User user, ArticleCreateCommand command) { +public Article createArticle(User user, ArticleCreateCommand command) { if (articleGetService.checkExistsByUserAndUrl(user, command.url())) { throw new ArticleAlreadyExistException(); } Category category = categoryGetService.getCategoryAndUser(command.categoryId(), user); Article article = Article.create(command.url(), command.memo(), user, category); - articleSaveService.save(article); + return articleSaveService.save(article);src/test/java/com/pinback/pinback_server/domain/article/application/ArticleManagementUsecaseTest.java (2)
44-46: Consider using relative dates in tests.The hard-coded future date
LocalDateTime.of(2025, 8, 6, 0, 0, 0)makes the test brittle and may cause issues over time.-LocalDateTime.of(2025, 8, 6, 0, 0, 0) +LocalDateTime.now().plusDays(1)
58-71: Consider adding CategoryNotFoundException test.The test coverage is good for duplicate handling, but missing a test case for when the category doesn't exist or doesn't belong to the user.
Add a test method:
@DisplayName("존재하지 않는 카테고리로 아티클을 생성하면 예외가 발생한다.") @Test void createArticle_CategoryNotFound() { User user = userRepository.save(user()); ArticleCreateCommand command = new ArticleCreateCommand("testUrl", 999L, "테스트메모", LocalDateTime.now().plusDays(1)); assertThatThrownBy(() -> articleManagementUsecase.createArticle(user, command)) .isInstanceOf(CategoryNotFoundException.class); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (18)
src/main/java/com/pinback/pinback_server/domain/article/application/ArticleManagementUsecase.java(1 hunks)src/main/java/com/pinback/pinback_server/domain/article/application/command/ArticleCreateCommand.java(1 hunks)src/main/java/com/pinback/pinback_server/domain/article/domain/entity/Article.java(2 hunks)src/main/java/com/pinback/pinback_server/domain/article/domain/repository/ArticleRepository.java(1 hunks)src/main/java/com/pinback/pinback_server/domain/article/domain/service/ArticleGetService.java(1 hunks)src/main/java/com/pinback/pinback_server/domain/article/domain/service/ArticleSaveService.java(1 hunks)src/main/java/com/pinback/pinback_server/domain/article/exception/ArticleAlreadyExistException.java(1 hunks)src/main/java/com/pinback/pinback_server/domain/article/presentation/ArticleController.java(1 hunks)src/main/java/com/pinback/pinback_server/domain/article/presentation/dto/request/ArticleCreateRequest.java(1 hunks)src/main/java/com/pinback/pinback_server/domain/category/domain/repository/CategoryRepository.java(1 hunks)src/main/java/com/pinback/pinback_server/domain/category/domain/service/CategoryGetService.java(1 hunks)src/main/java/com/pinback/pinback_server/domain/category/exception/CategoryNotFoundException.java(1 hunks)src/main/java/com/pinback/pinback_server/global/exception/constant/ExceptionCode.java(1 hunks)src/test/java/com/pinback/pinback_server/domain/ApplicationTest.java(1 hunks)src/test/java/com/pinback/pinback_server/domain/article/application/ArticleManagementUsecaseTest.java(1 hunks)src/test/java/com/pinback/pinback_server/domain/category/domain/service/CategoryGetServiceTest.java(1 hunks)src/test/java/com/pinback/pinback_server/domain/fixture/CustomRepository.java(1 hunks)src/test/java/com/pinback/pinback_server/domain/fixture/TestFixture.java(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (5)
src/main/java/com/pinback/pinback_server/domain/category/domain/repository/CategoryRepository.java (1)
src/test/java/com/pinback/pinback_server/domain/fixture/CustomRepository.java (1)
Repository(9-23)
src/main/java/com/pinback/pinback_server/domain/article/domain/repository/ArticleRepository.java (1)
src/test/java/com/pinback/pinback_server/domain/fixture/CustomRepository.java (1)
Repository(9-23)
src/test/java/com/pinback/pinback_server/domain/category/domain/service/CategoryGetServiceTest.java (2)
src/test/java/com/pinback/pinback_server/domain/fixture/TestFixture.java (1)
TestFixture(9-31)src/main/java/com/pinback/pinback_server/domain/category/exception/CategoryNotFoundException.java (1)
CategoryNotFoundException(6-10)
src/main/java/com/pinback/pinback_server/domain/article/application/ArticleManagementUsecase.java (2)
src/main/java/com/pinback/pinback_server/domain/category/domain/service/CategoryGetService.java (1)
Service(13-22)src/main/java/com/pinback/pinback_server/domain/article/exception/ArticleAlreadyExistException.java (1)
ArticleAlreadyExistException(6-10)
src/test/java/com/pinback/pinback_server/domain/article/application/ArticleManagementUsecaseTest.java (3)
src/test/java/com/pinback/pinback_server/domain/fixture/TestFixture.java (1)
TestFixture(9-31)src/test/java/com/pinback/pinback_server/domain/ApplicationTest.java (1)
SpringBootTest(10-21)src/main/java/com/pinback/pinback_server/domain/article/exception/ArticleAlreadyExistException.java (1)
ArticleAlreadyExistException(6-10)
🔇 Additional comments (21)
src/main/java/com/pinback/pinback_server/domain/category/domain/repository/CategoryRepository.java (2)
3-4: LGTM - Clean imports added.The Optional and User imports are correctly added to support the new repository method.
13-13: LGTM - Repository method follows Spring Data JPA conventions.The
findByIdAndUsermethod signature correctly follows Spring Data JPA naming conventions and will automatically generate the appropriate query to find a category by both ID and user ownership.src/main/java/com/pinback/pinback_server/domain/category/exception/CategoryNotFoundException.java (1)
1-11: LGTM - Exception class follows established patterns.The
CategoryNotFoundExceptioncorrectly extendsApplicationExceptionand uses the predefinedExceptionCode.CATEGORY_NOT_FOUND. The implementation is clean and consistent with the codebase's exception handling approach.src/main/java/com/pinback/pinback_server/domain/article/domain/entity/Article.java (2)
16-16: LGTM - UniqueConstraint import added.The import is correctly added to support the unique constraint annotation.
25-28: LGTM - Unique constraint properly enforces business rule.The unique constraint on
user_idandurlcolumns correctly implements the business requirement that each user can have only one article with the same URL. The column names match the entity's field mappings.src/main/java/com/pinback/pinback_server/domain/article/application/command/ArticleCreateCommand.java (1)
1-12: Verify remindTime field aligns with PR objectives.The command record structure is well-designed, but the inclusion of
remindTimeseems inconsistent with the PR description stating "pure article creation logic without any reminder creation." Please confirm if reminder functionality should be included in this implementation.src/main/java/com/pinback/pinback_server/domain/article/domain/service/ArticleSaveService.java (1)
11-20: LGTM - Service follows established patterns.The
ArticleSaveServicecorrectly follows the established service layer pattern with proper transaction management. While it's a thin wrapper around the repository, it maintains architectural consistency and provides a clear abstraction layer.src/main/java/com/pinback/pinback_server/domain/article/domain/repository/ArticleRepository.java (2)
7-7: Import addition is correct.The User entity import is properly added to support the new method signature.
12-12: Repository method follows JPA conventions correctly.The
existsByUserAndUrlmethod signature follows Spring Data JPA naming conventions and will automatically generate the appropriate query. The boolean return type is suitable for existence checks.src/test/java/com/pinback/pinback_server/domain/ApplicationTest.java (1)
17-20: Database cleanup strategy is appropriate.The
@AfterEachcleanup approach ensures test isolation by resetting the database state after each test. This is a good practice for integration tests.src/main/java/com/pinback/pinback_server/global/exception/constant/ExceptionCode.java (3)
13-13: HTTP status code comment correction is accurate.The comment correction from 403 to 401 is appropriate for token-related exceptions (unauthorized vs forbidden).
20-21: New exception codes follow established patterns.The new exception codes
CATEGORY_NOT_FOUND("c40402") and the updatedUSER_NOT_FOUND("c40401") maintain the logical sequence within the 404 category.
29-29: Article duplicate exception code is well-defined.The
ARTICLE_ALREADY_EXISTexception code ("c40902") is appropriately placed under the 409 Conflict category with a clear Korean message.src/main/java/com/pinback/pinback_server/domain/article/domain/service/ArticleGetService.java (2)
11-13: Service annotations are correctly applied.The combination of
@Service,@RequiredArgsConstructor, and@Transactional(readOnly = true)is appropriate for a read-only service class.
17-19: Method implementation is clean and focused.The
checkExistsByUserAndUrlmethod has a clear, descriptive name and appropriately delegates to the repository. The implementation follows the single responsibility principle.src/test/java/com/pinback/pinback_server/domain/fixture/CustomRepository.java (1)
16-18: Consider deletion order for foreign key constraints.The current deletion order may cause foreign key constraint violations if referential integrity is enforced. Since
articlelikely referencescategoryandusers, consider deleting in reverse dependency order:- entityManager.createNativeQuery("DELETE FROM article").executeUpdate(); - entityManager.createNativeQuery("DELETE FROM category").executeUpdate(); - entityManager.createNativeQuery("DELETE FROM users").executeUpdate(); + entityManager.createNativeQuery("DELETE FROM article").executeUpdate(); + entityManager.createNativeQuery("DELETE FROM category").executeUpdate(); + entityManager.createNativeQuery("DELETE FROM users").executeUpdate();Actually, the current order appears correct (delete child tables first), but verify this matches your actual foreign key relationships.
src/main/java/com/pinback/pinback_server/domain/article/presentation/ArticleController.java (1)
23-27: Excellent controller implementation following best practices.The controller demonstrates:
- Clean separation of concerns with delegation to the use case layer
- Proper validation with
@Validannotation- Appropriate use of
@CurrentUserfor authentication- Correct HTTP status response with
ResponseDto.created()The implementation follows Spring Boot conventions and REST best practices effectively.
src/test/java/com/pinback/pinback_server/domain/fixture/TestFixture.java (1)
23-30: Well-designed factory methods for flexible test scenarios.The article factory methods provide good flexibility:
article(User user)creates a complete article with a new categoryarticleWithCategory(User user, Category category)allows reusing existing categoriesThis design supports various testing scenarios effectively while maintaining clean, readable test code.
src/main/java/com/pinback/pinback_server/domain/article/presentation/dto/request/ArticleCreateRequest.java (1)
22-29: LGTM! Clean conversion method.The
toCommand()method provides a clean conversion from request DTO to command object, maintaining clear separation of concerns between presentation and application layers.src/main/java/com/pinback/pinback_server/domain/article/application/ArticleManagementUsecase.java (1)
17-25: LGTM! Proper service structure and dependencies.The service follows Spring best practices with appropriate annotations and dependency injection. The default
@Transactional(readOnly = true)is a good defensive approach.src/test/java/com/pinback/pinback_server/domain/article/application/ArticleManagementUsecaseTest.java (1)
25-28: LGTM! Proper test class structure.The test class correctly extends
ApplicationTestand uses appropriate Spring Boot test annotations with transactional support.
| //TODO: 리마인드 로직 추가 필요 | ||
| @Transactional | ||
| public void createArticle(User user, ArticleCreateCommand command) { | ||
| if (articleGetService.checkExistsByUserAndUrl(user, command.url())) { | ||
| throw new ArticleAlreadyExistException(); | ||
| } | ||
| Category category = categoryGetService.getCategoryAndUser(command.categoryId(), user); | ||
| Article article = Article.create(command.url(), command.memo(), user, category); | ||
| articleSaveService.save(article); | ||
| } |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Critical: RemindTime parameter is completely ignored.
The method accepts remindTime through the command but doesn't use it anywhere. This creates a significant disconnect between the API contract and the actual implementation.
Consider one of these approaches:
// Option 1: Use remindTime in Article creation
-Article article = Article.create(command.url(), command.memo(), user, category);
+Article article = Article.create(command.url(), command.memo(), user, category, command.remindTime());
// Option 2: If reminder logic is not ready, document the limitation
+// TODO: remindTime is currently ignored until reminder logic is implementedVerify if the Article.create() method supports remindTime parameter:
🏁 Script executed:
#!/bin/bash
# Search for Article.create method signatures
ast-grep --pattern 'class Article {
$$$
static $_ create($$$) {
$$$
}
$$$
}'Length of output: 90
I couldn’t locate the Article.create signature with AST grep. Let’s fall back to a file search and regex:
🏁 Script executed:
#!/bin/bash
# Locate Article.java
file=$(fd Article.java)
echo "Located file: $file"
# Show the class declaration
rg -n 'class Article' "$file"
# Show all static create method signatures
rg -n 'static .*\bcreate\b' "$file"Length of output: 666
Include remindTime in article creation or document its omission
The remindTime value provided in ArticleCreateCommand is never used because the Article.create(...) factory method only accepts (url, memo, user, category) and doesn’t support a reminder timestamp. You need to either wire it through the domain model or explicitly note that it’s pending implementation.
• In src/main/java/com/pinback/pinback_server/domain/article/application/ArticleManagementUsecase.java:createArticle you call:
Article.create(command.url(), command.memo(), user, category);but never use command.remindTime().
• In src/main/java/com/pinback/pinback_server/domain/article/domain/entity/Article.java:55 the signature is:
public static Article create(String url, String memo, User user, Category category) { … }Consider one of these fixes:
Option 1: Extend the create signature and pass remindTime through:
// ArticleManagementUsecase.java
- Article article = Article.create(command.url(), command.memo(), user, category);
+ Article article = Article.create(
+ command.url(),
+ command.memo(),
+ user,
+ category,
+ command.remindTime()
+ );
// Article.java
- public static Article create(String url, String memo, User user, Category category) {
+ public static Article create(
+ String url,
+ String memo,
+ User user,
+ Category category,
+ LocalDateTime remindTime
+ ) {
Article article = new Article(…);
+ article.setRemindTime(remindTime);
return article;
}Option 2: Leave remindTime unhandled for now but document it:
// TODO: `remindTime` is ignored until reminder scheduling logic is implemented
@Transactional
public void createArticle(User user, ArticleCreateCommand command) {
…
}🤖 Prompt for AI Agents
In
src/main/java/com/pinback/pinback_server/domain/article/application/ArticleManagementUsecase.java
around lines 26 to 35, the remindTime from ArticleCreateCommand is not used in
the Article.create call because the factory method does not accept it. To fix
this, either extend the Article.create method signature in the domain entity to
include remindTime and pass it through here, or add a clear TODO comment in
createArticle noting that remindTime is currently ignored until reminder
scheduling is implemented.
| @DisplayName("사용자는 아티클을 생성할 수 있다.") | ||
| @Test | ||
| void articleSaveService() { |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Fix misleading test method name.
The method name articleSaveService() is misleading as it tests the use case, not the save service specifically.
-@DisplayName("사용자는 아티클을 생성할 수 있다.")
-@Test
-void articleSaveService() {
+@DisplayName("사용자는 아티클을 생성할 수 있다.")
+@Test
+void createArticle_Success() {🤖 Prompt for AI Agents
In
src/test/java/com/pinback/pinback_server/domain/article/application/ArticleManagementUsecaseTest.java
around lines 39 to 41, rename the test method from articleSaveService() to a
name that clearly reflects it is testing the article management use case, such
as articleManagementUsecaseTest() or testArticleCreationUsecase(), to avoid
confusion with a specific save service.
| assertThat(article.getUrl()).isEqualTo(command.url()); | ||
| assertThat(article.getMemo()).isEqualTo(command.memo()); | ||
| assertThat(article.getCategory()).isEqualTo(category); | ||
| assertThat(article.getIsRead()).isFalse(); |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Add validation for ignored remindTime parameter.
The test doesn't verify that remindTime is properly stored, which would catch the issue where this parameter is currently ignored in the implementation.
assertThat(article.getUrl()).isEqualTo(command.url());
assertThat(article.getMemo()).isEqualTo(command.memo());
assertThat(article.getCategory()).isEqualTo(category);
assertThat(article.getIsRead()).isFalse();
+assertThat(article.getRemindTime()).isEqualTo(command.remindTime());📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| assertThat(article.getUrl()).isEqualTo(command.url()); | |
| assertThat(article.getMemo()).isEqualTo(command.memo()); | |
| assertThat(article.getCategory()).isEqualTo(category); | |
| assertThat(article.getIsRead()).isFalse(); | |
| assertThat(article.getUrl()).isEqualTo(command.url()); | |
| assertThat(article.getMemo()).isEqualTo(command.memo()); | |
| assertThat(article.getCategory()).isEqualTo(category); | |
| assertThat(article.getIsRead()).isFalse(); | |
| assertThat(article.getRemindTime()).isEqualTo(command.remindTime()); |
🤖 Prompt for AI Agents
In
src/test/java/com/pinback/pinback_server/domain/article/application/ArticleManagementUsecaseTest.java
around lines 52 to 55, the test is missing validation for the remindTime
parameter. Add an assertion to verify that the article's remindTime matches the
command's remindTime to ensure this parameter is correctly stored and handled in
the implementation.
| //then | ||
| Article article = articleRepository.findById(1L).get(); | ||
| assertThat(article.getUrl()).isEqualTo(command.url()); | ||
| assertThat(article.getMemo()).isEqualTo(command.memo()); | ||
| assertThat(article.getCategory()).isEqualTo(category); | ||
| assertThat(article.getIsRead()).isFalse(); | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Avoid hard-coded ID assumptions.
Using findById(1L) assumes specific ID generation behavior, making the test brittle. Consider using repository queries or storing the created article's ID.
-//then
-Article article = articleRepository.findById(1L).get();
+//then
+List<Article> articles = articleRepository.findByUser(user);
+assertThat(articles).hasSize(1);
+Article article = articles.get(0);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| //then | |
| Article article = articleRepository.findById(1L).get(); | |
| assertThat(article.getUrl()).isEqualTo(command.url()); | |
| assertThat(article.getMemo()).isEqualTo(command.memo()); | |
| assertThat(article.getCategory()).isEqualTo(category); | |
| assertThat(article.getIsRead()).isFalse(); | |
| } | |
| //then | |
| List<Article> articles = articleRepository.findByUser(user); | |
| assertThat(articles).hasSize(1); | |
| Article article = articles.get(0); | |
| assertThat(article.getUrl()).isEqualTo(command.url()); | |
| assertThat(article.getMemo()).isEqualTo(command.memo()); | |
| assertThat(article.getCategory()).isEqualTo(category); | |
| assertThat(article.getIsRead()).isFalse(); | |
| } |
🤖 Prompt for AI Agents
In
src/test/java/com/pinback/pinback_server/domain/article/application/ArticleManagementUsecaseTest.java
around lines 50 to 56, avoid using a hard-coded ID (1L) in findById as it
assumes specific ID generation and makes the test brittle. Instead, capture the
ID of the article when it is created or saved, then use that stored ID to
retrieve the article for assertions. Alternatively, use repository queries that
do not rely on fixed IDs to fetch the article.
🚀 PR 요약
아티클 생성 로직을 구현했습니다
✨ PR 상세 내용
🚨 주의 사항
주의할 부분이 무엇인가요? - 지우고 작성
✅ 체크 리스트
close #15
Summary by CodeRabbit
New Features
Bug Fixes
Tests