Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
36 changes: 33 additions & 3 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ plugins {
java
id("org.springframework.boot") version "3.5.9"
id("io.spring.dependency-management") version "1.1.7"
id("org.asciidoctor.jvm.convert") version "4.0.5"
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

org.asciidoctor.jvm.convert gradle plugin latest version 2025

💡 Result:

The latest release in 2025 is version 4.0.4 (released January 13, 2025). [1][2]

Sources:

  • Maven Repository listing for org.asciidoctor.jvm.convert.gradle.plugin 4.0.4. [1]
  • Gradle Plugin Portal (plugin page; shows earlier 4.0.2 example). [2]

🌐 Web query:

org.asciidoctor.jvm.convert 4.0.5 gradle plugin

💡 Result:

Short answer: There is no org.asciidoctor.jvm.convert plugin version 4.0.5 on the Gradle Plugin Portal — the latest published for that plugin id is 4.0.3 (published 20 Jul 2024). Other Asciidoctor JVM plugins (org.asciidoctor.jvm.base, .pdf, .gems, .js.convert, etc.) do have 4.0.5 releases. [1][2][3]

  • org.asciidoctor.jvm.convert — latest listed: 4.0.3. [1]
  • Example other plugin with 4.0.5: org.asciidoctor.jvm.base (4.0.5). [2]
  • Asciidoctor Gradle plugin compatibility / docs. [3]

If you want, I can watch the Gradle Plugin Portal for a 4.0.5 release of org.asciidoctor.jvm.convert or suggest a migration path (use 4.x suite or the 1.5.x "org.asciidoctor.convert" legacy plugin).


플러그인 버전을 4.0.3으로 수정하세요.

org.asciidoctor.jvm.convert 버전 4.0.5는 존재하지 않습니다. Gradle Plugin Portal의 최신 버전은 4.0.3(2024년 7월 20일 발표)입니다. 현재 버전은 플러그인 해석 실패를 야기할 것입니다.

id("org.asciidoctor.jvm.convert") version "4.0.3"
🤖 Prompt for AI Agents
In build.gradle.kts around line 5, the plugin declaration uses a non-existent
version "4.0.5"; change that version to "4.0.3" so the
id("org.asciidoctor.jvm.convert") line reads the supported plugin version and
the Gradle plugin resolution succeeds.

}

group = "com.umc"
Expand All @@ -19,6 +20,7 @@ configurations {
compileOnly {
extendsFrom(configurations.annotationProcessor.get())
}
create("asciidoctorExt")
}

repositories {
Expand Down Expand Up @@ -54,9 +56,6 @@ dependencies {
annotationProcessor("com.querydsl:querydsl-apt:${queryDslVersion}:jakarta")
annotationProcessor("jakarta.annotation:jakarta.annotation-api")

// APT가 jakarta 클래스를 로딩할 수 있게 명시
annotationProcessor("jakarta.persistence:jakarta.persistence-api")

// --- Database ---
implementation("org.flywaydb:flyway-core")
implementation("org.flywaydb:flyway-database-postgresql")
Expand Down Expand Up @@ -95,8 +94,39 @@ dependencies {
testImplementation("org.testcontainers:testcontainers")
testImplementation("org.testcontainers:junit-jupiter")
testImplementation("org.testcontainers:postgresql")

// --- Spring REST Docs ---
"asciidoctorExt"("org.springframework.restdocs:spring-restdocs-asciidoctor")
testImplementation("org.springframework.restdocs:spring-restdocs-mockmvc")
}

tasks.withType<Test> {
useJUnitPlatform()
}


val snippetsDir = file("build/generated-snippets")

tasks.test {
outputs.dir(snippetsDir)

}
Comment on lines +110 to +113
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Issue #16의 테스트 실패 로그 요구사항이 누락되었습니다.

Issue #16에서는 "테스트 실패 시 상세 로그 출력 구성"을 명시적으로 요구하고 있습니다. 현재 코드는 outputs.dir(snippetsDir)만 설정되어 있어 기본 로그 레벨만 출력됩니다.

커밋 메시지("test task 간략화")를 보면 의도적인 간소화로 보이나, 이는 Issue 요구사항과 불일치합니다. 다음 중 하나를 선택하시기 바랍니다:

  1. Issue #16의 요구사항이 변경되었다면 이슈를 업데이트
  2. 테스트 실패 시 상세 로그 출력 기능을 다시 추가
🔎 테스트 실패 로그 출력 예시

이전 리뷰 댓글에서 언급된 것처럼 상세 로그 출력을 위해 다음과 같이 구성할 수 있습니다:

 tasks.test {
     outputs.dir(snippetsDir)
-    
+    
+    testLogging {
+        events("passed", "skipped", "failed")
+        showExceptions = true
+        showCauses = true
+        showStackTraces = true
+        exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
+    }
 }
📝 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.

Suggested change
tasks.test {
outputs.dir(snippetsDir)
}
tasks.test {
outputs.dir(snippetsDir)
testLogging {
events("passed", "skipped", "failed")
showExceptions = true
showCauses = true
showStackTraces = true
exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
}
}
🤖 Prompt for AI Agents
In build.gradle.kts around lines 110-113 the test task only sets
outputs.dir(snippetsDir) but omits the detailed test-failure logging required by
Issue #16; restore explicit testLogging configuration on the tasks.test block to
emit detailed failure output (e.g., enable events for failed/skipped, set
exceptionFormat to FULL, and enable showing standard streams) while keeping
outputs.dir(snippetsDir), and update the commit message or Issue #16 if
requirements have changed.


tasks.asciidoctor {
inputs.dir(snippetsDir)
configurations("asciidoctorExt")

sources {
include("**/index.adoc")
}

baseDirFollowsSourceDir()
dependsOn(tasks.test)
}

tasks.bootJar {
dependsOn(tasks.asciidoctor)
from(tasks.asciidoctor.get().outputDir) {
into("static/docs")
}
}
11 changes: 11 additions & 0 deletions src/docs/asciidoc/index.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
ifndef::snippets[]
:snippets: ../../build/generated-snippets
endif::[]
= UMC Product REST API 문서
:doctype: book
:icons: font
:source-highlighter: highlightjs
:toc: left
:toclevels: 2
:sectlinks:

31 changes: 31 additions & 0 deletions src/test/java/com/umc/product/support/DocumentationTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.umc.product.support;


import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.context.annotation.Import;
import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler;
import org.springframework.test.web.servlet.MockMvc;

@WebMvcTest(
)
@Import({
RestDocsConfig.class,
})
@AutoConfigureMockMvc(addFilters = false)
@AutoConfigureRestDocs
Comment on lines +13 to +19
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# DocumentationTest를 extends하는 클래스들과 그들의 @WebMvcTest 설정 확인
rg -n "extends DocumentationTest" --type java -A 15 -B 2

Repository: UMC-PRODUCT/umc-product-server

Length of output: 56


🏁 Script executed:

#!/bin/bash
# 1. DocumentationTest.java 파일 확인
echo "=== DocumentationTest.java 내용 ==="
find . -name "DocumentationTest.java" -type f | head -5

# 2. DocumentationTest를 import하거나 참조하는 파일들 검색
echo -e "\n=== DocumentationTest를 참조하는 파일들 ==="
rg "DocumentationTest" --type java

# 3. REST Docs 관련 @WebMvcTest 사용 패턴 확인
echo -e "\n=== @WebMvcTest 사용 패턴 ==="
rg "@WebMvcTest" --type java -A 3

Repository: UMC-PRODUCT/umc-product-server

Length of output: 627


🏁 Script executed:

#!/bin/bash
# DocumentationTest.java 전체 내용 읽기
cat -n src/test/java/com/umc/product/support/DocumentationTest.java

Repository: UMC-PRODUCT/umc-product-server

Length of output: 1208


🏁 Script executed:

#!/bin/bash
# 1. RestDocsConfig 검색
echo "=== RestDocsConfig 파일 확인 ==="
find . -name "RestDocsConfig.java" -type java | head -5

# 2. RestDocumentationResultHandler 사용하는 클래스 찾기
echo -e "\n=== RestDocumentationResultHandler 참조 ==="
rg "RestDocumentationResultHandler" --type java -B 3 -A 3

# 3. REST Docs 관련 테스트 클래스들
echo -e "\n=== Test 클래스들 현황 ==="
fd ".*Test\.java$" src/test/java --type f | head -20

Repository: UMC-PRODUCT/umc-product-server

Length of output: 3095


🏁 Script executed:

#!/bin/bash
# 1. 모든 Test 클래스 찾기 (고정된 find 명령)
echo "=== 모든 Test 클래스 ==="
find src/test/java -name "*Test.java" -type f

# 2. 더 광범위한 extends DocumentationTest 검색
echo -e "\n=== DocumentationTest 상속 여부 ==="
rg "extends\s+DocumentationTest|DocumentationTest\s*{" --type java -B 2 -A 8

# 3. @WebMvcTest 사용하는 모든 클래스
echo -e "\n=== @WebMvcTest 사용 클래스 ==="
rg "@WebMvcTest" --type java -B 5

Repository: UMC-PRODUCT/umc-product-server

Length of output: 1032


🏁 Script executed:

#!/bin/bash
# @WebMvcTest()의 빈 controllers 파라미터 동작 확인
cat > /tmp/check_webmvctest.py << 'EOF'
# @WebMvcTest() with empty controllers parameter behavior
# According to Spring Boot documentation:
# - @WebMvcTest() with no controllers specified will load ALL controllers
# - This can cause issues because the context becomes too large
# - For a base class meant to be extended, this is suboptimal design

print("Spring Boot @WebMvcTest() behavior:")
print("1. @WebMvcTest() - loads ALL controllers in the application context")
print("2. @WebMvcTest(controllers = SpecificController.class) - loads ONLY specified controller")
print("\nFor a base class meant to be inherited:")
print("- Having @WebMvcTest() (all controllers) is problematic")
print("- Subclasses cannot override/narrow the controller scope")
print("- Better approach: Keep base class minimal, let subclasses specify controllers")
EOF
python /tmp/check_webmvctest.py

# 2. 실제 Spring Boot 권장사항 확인
echo -e "\n=== 결론 ==="
echo "DocumentationTest.java의 현재 상태:"
echo "- @WebMvcTest() 빈 파라미터 사용: 모든 컨트롤러 로드 (불필요)"
echo "- 아직 상속하는 클래스 없음: 현재 사용되지 않는 상태"

Repository: UMC-PRODUCT/umc-product-server

Length of output: 160


REST Docs 테스트 기반 클래스 설정이 잘 구성되었습니다.

@WebMvcTest, @AutoConfigureRestDocs, addFilters = false 설정을 활용하여 문서화 테스트 기반 클래스를 효과적으로 구성했습니다. 다만, @WebMvcTest()에 컨트롤러를 지정하지 않으면 애플리케이션의 모든 컨트롤러를 로드하게 되어 문맥이 불필요하게 커집니다. 이 클래스를 상속하는 실제 테스트 클래스에서는 @WebMvcTest(controllers = YourController.class) 형태로 테스트할 컨트롤러를 명시하여 불필요한 빈 로드를 방지해야 합니다.

🤖 Prompt for AI Agents
In src/test/java/com/umc/product/support/DocumentationTest.java around lines 13
to 19, the base test class uses @WebMvcTest without specifying controllers which
causes all controllers to be loaded; update usage by ensuring subclasses that
extend this base test annotate themselves with @WebMvcTest(controllers =
YourController.class) (or controllers = {AController.class, BController.class})
to limit loaded beans and avoid unnecessary context size; keep the shared
annotations (@AutoConfigureMockMvc(addFilters = false), @AutoConfigureRestDocs,
@Import(RestDocsConfig.class)) in the base and only add the controllers
attribute on concrete test classes.

public class DocumentationTest {

@Autowired
protected MockMvc mockMvc;

@Autowired
protected RestDocumentationResultHandler restDocsHandler;

@Autowired
protected ObjectMapper objectMapper;

}
22 changes: 22 additions & 0 deletions src/test/java/com/umc/product/support/RestDocsConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.umc.product.support;

import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation;
import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler;

import static org.springframework.restdocs.operation.preprocess.Preprocessors.*;
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

와일드카드 static import 사용 검토 (선택적)

와일드카드 static import(import static ... Preprocessors.*;)를 사용하고 있습니다. REST Docs에서는 관례적으로 사용되는 패턴이지만, 명시적으로 필요한 메서드만 import하는 것이 더 명확할 수 있습니다.

🔎 명시적 import로 변경하는 제안
-import static org.springframework.restdocs.operation.preprocess.Preprocessors.*;
+import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest;
+import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse;
+import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint;
🤖 Prompt for AI Agents
In src/test/java/com/umc/product/support/RestDocsConfig.java around line 8,
replace the wildcard static import "import static
org.springframework.restdocs.operation.preprocess.Preprocessors.*;" with
explicit static imports for only the Preprocessors methods actually used in this
file (e.g., import static
org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint;
import static
org.springframework.restdocs.operation.preprocess.Preprocessors.removeHeaders;
etc.). Inspect the rest of the file to determine which static methods are
referenced, add explicit imports for those methods, and remove the wildcard
import to avoid importing unused members.


@TestConfiguration
public class RestDocsConfig {

@Bean
public RestDocumentationResultHandler restDocsMockMvcConfigurationCustomizer() {
return MockMvcRestDocumentation.document(
"{class-name}/{method-name}",
preprocessRequest(prettyPrint()),
preprocessResponse(prettyPrint())
);
}
Comment on lines +13 to +20
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

메서드명이 반환 타입과 불일치

메서드명 restDocsMockMvcConfigurationCustomizer()는 "Customizer"를 포함하지만, 실제로는 RestDocumentationResultHandler를 반환합니다. Spring REST Docs에서 "Customizer"는 일반적으로 RestDocsMockMvcConfigurationCustomizer 인터페이스를 구현하는 경우에 사용하는 용어입니다.

현재 코드는 Result Handler를 반환하므로 메서드명이 혼란을 야기할 수 있습니다. 메서드명을 반환 타입과 용도에 맞게 변경하는 것을 권장합니다.

🔎 메서드명 개선 제안
 @Bean
-public RestDocumentationResultHandler restDocsMockMvcConfigurationCustomizer() {
+public RestDocumentationResultHandler restDocsHandler() {
     return MockMvcRestDocumentation.document(
             "{class-name}/{method-name}",
             preprocessRequest(prettyPrint()),
             preprocessResponse(prettyPrint())
     );
 }

참고: 설정 내용 자체(문서 경로 패턴, pretty-print 전처리)는 REST Docs 표준 패턴을 잘 따르고 있으며 적절합니다.

📝 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.

Suggested change
@Bean
public RestDocumentationResultHandler restDocsMockMvcConfigurationCustomizer() {
return MockMvcRestDocumentation.document(
"{class-name}/{method-name}",
preprocessRequest(prettyPrint()),
preprocessResponse(prettyPrint())
);
}
@Bean
public RestDocumentationResultHandler restDocsHandler() {
return MockMvcRestDocumentation.document(
"{class-name}/{method-name}",
preprocessRequest(prettyPrint()),
preprocessResponse(prettyPrint())
);
}
🤖 Prompt for AI Agents
In src/test/java/com/umc/product/support/RestDocsConfig.java around lines 13 to
20, the bean method is named restDocsMockMvcConfigurationCustomizer() but
returns a RestDocumentationResultHandler which is misleading; rename the method
to reflect the return type and purpose (e.g., restDocumentationResultHandler or
restDocsResultHandler) and update any references/usages or @Autowired/bean
lookups that rely on the old method name so the bean name remains correct and
consistent with its role as a ResultHandler.

}

10 changes: 10 additions & 0 deletions src/test/java/com/umc/product/support/UseCaseTestSupport.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.umc.product.support;


import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public abstract class UseCaseTestSupport {
Comment on lines +6 to +7
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find all test classes extending UseCaseTestSupport
rg -n "extends UseCaseTestSupport" --type java -C 10

Repository: UMC-PRODUCT/umc-product-server

Length of output: 56


🏁 Script executed:

#!/bin/bash
# First, check if the file exists and read its contents
echo "=== Checking UseCaseTestSupport.java ==="
find . -name "UseCaseTestSupport.java" -type f

echo -e "\n=== Searching for test files that might extend it ==="
find ./src/test -name "*.java" -type f | head -20

echo -e "\n=== Looking for any references to UseCaseTestSupport ==="
rg "UseCaseTestSupport" --type java

Repository: UMC-PRODUCT/umc-product-server

Length of output: 647


🏁 Script executed:

#!/bin/bash
cat -n ./src/test/java/com/umc/product/support/UseCaseTestSupport.java

Repository: UMC-PRODUCT/umc-product-server

Length of output: 303


🏁 Script executed:

#!/bin/bash
echo "=== UmcProductApplicationTests.java ==="
cat -n ./src/test/java/com/umc/product/UmcProductApplicationTests.java

echo -e "\n=== DocumentationTest.java ==="
cat -n ./src/test/java/com/umc/product/support/DocumentationTest.java

echo -e "\n=== Checking for UseCase classes in src ==="
find ./src/main -name "*UseCase.java" -type f | head -10

Repository: UMC-PRODUCT/umc-product-server

Length of output: 1628


🏁 Script executed:

#!/bin/bash
echo "=== Checking for any service/use case patterns in the project ==="
find ./src/main -name "*.java" -type f | grep -E "(Service|UseCase)" | head -10

echo -e "\n=== Checking application.yml or application.properties for context hints ==="
find ./src -name "application*.yml" -o -name "application*.properties"

Repository: UMC-PRODUCT/umc-product-server

Length of output: 254


UseCaseTestSupport에서 @SpringBootTest 제거 필요

현재 이 클래스는 공유할 테스트 설정이나 유틸리티가 없는 빈 추상 클래스입니다. @SpringBootTest는 전체 애플리케이션 컨텍스트를 로드하므로 불필요합니다.

UseCase는 단일 책임 원칙을 따르는 단위 테스트 대상이므로, 다음 중 하나를 권장합니다:

  • @SpringBootTest 제거 (상속 클래스에서 필요한 경우 개별 적용)
  • 또는 실제 공유 테스트 설정(예: 공통 Mock 설정, 테스트 데이터 초기화)을 추가한 후에만 @SpringBootTest 사용

프로젝트의 DocumentationTest@WebMvcTest 같은 경량 슬라이스 테스트를 사용하고 있으므로, 이 기준에 맞추기를 권장합니다.

🤖 Prompt for AI Agents
In src/test/java/com/umc/product/support/UseCaseTestSupport.java around lines 6
to 7, the abstract test support class is annotated with @SpringBootTest but
provides no shared test configuration, causing unnecessary full application
context startup; remove the @SpringBootTest annotation from this base class so
subclasses can opt-in individually, or alternatively replace it by adding
meaningful shared test configuration (e.g., common @TestConfiguration, mocks, or
test data setup) and document that subclasses will inherit the slice only when
intended.



}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//==== Request Fields
|===
|Path|Type|Optional|Description

{{#fields}}

|{{#tableCellContent}}`+{{path}}+`{{/tableCellContent}}
|{{#tableCellContent}}`+{{type}}+`{{/tableCellContent}}
|{{#tableCellContent}}{{#optional}}O{{/optional}}{{/tableCellContent}}
|{{#tableCellContent}}{{description}}{{/tableCellContent}}

{{/fields}}

|===
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//==== Response Fields
|===
|Path|Type|Optional|Description

{{#fields}}

|{{#tableCellContent}}`+{{path}}+`{{/tableCellContent}}
|{{#tableCellContent}}`+{{type}}+`{{/tableCellContent}}
|{{#tableCellContent}}{{#optional}}O{{/optional}}{{/tableCellContent}}
|{{#tableCellContent}}{{description}}{{/tableCellContent}}

{{/fields}}

|===