From f45d00b3451ad0cd68934140939f0d2e07ac6750 Mon Sep 17 00:00:00 2001 From: can019 Date: Wed, 10 Sep 2025 12:32:07 +0900 Subject: [PATCH 01/12] chore: rename UserServiceApplicationE2eTest Changes to be committed: renamed: src/test/java/com/gltkorea/icebang/e2e/scenario/UserServiceApplicationE2eTests.java -> src/test/java/com/gltkorea/icebang/e2e/scenario/ContextLoadE2eTests.java --- ...ServiceApplicationE2eTests.java => ContextLoadE2eTests.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename apps/user-service/src/test/java/com/gltkorea/icebang/e2e/scenario/{UserServiceApplicationE2eTests.java => ContextLoadE2eTests.java} (73%) diff --git a/apps/user-service/src/test/java/com/gltkorea/icebang/e2e/scenario/UserServiceApplicationE2eTests.java b/apps/user-service/src/test/java/com/gltkorea/icebang/e2e/scenario/ContextLoadE2eTests.java similarity index 73% rename from apps/user-service/src/test/java/com/gltkorea/icebang/e2e/scenario/UserServiceApplicationE2eTests.java rename to apps/user-service/src/test/java/com/gltkorea/icebang/e2e/scenario/ContextLoadE2eTests.java index 2379e450..be0bb785 100644 --- a/apps/user-service/src/test/java/com/gltkorea/icebang/e2e/scenario/UserServiceApplicationE2eTests.java +++ b/apps/user-service/src/test/java/com/gltkorea/icebang/e2e/scenario/ContextLoadE2eTests.java @@ -4,7 +4,7 @@ import com.gltkorea.icebang.e2e.support.E2eTestSupport; -class UserServiceApplicationE2eTests extends E2eTestSupport { +class ContextLoadE2eTests extends E2eTestSupport { @Test void contextLoads() {} From 144c99221f8f8b4cf4e6aafd3e3810430aac2ad9 Mon Sep 17 00:00:00 2001 From: can019 Date: Wed, 10 Sep 2025 13:04:31 +0900 Subject: [PATCH 02/12] test: User login rest docs --- .../email/service/MockEmailService.java | 2 +- .../application-test-integration.yml | 13 +- .../main/resources/application-test-unit.yml | 9 - .../auth/AuthApiIntegrationTest.java | 81 +++++ .../icebang/integration/auth/testa.java | 287 ------------------ .../support/IntegrationTestSupport.java | 30 +- 6 files changed, 110 insertions(+), 312 deletions(-) create mode 100644 apps/user-service/src/test/java/com/gltkorea/icebang/integration/auth/AuthApiIntegrationTest.java delete mode 100644 apps/user-service/src/test/java/com/gltkorea/icebang/integration/auth/testa.java diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/domain/email/service/MockEmailService.java b/apps/user-service/src/main/java/com/gltkorea/icebang/domain/email/service/MockEmailService.java index 6ccaffc9..527bb752 100644 --- a/apps/user-service/src/main/java/com/gltkorea/icebang/domain/email/service/MockEmailService.java +++ b/apps/user-service/src/main/java/com/gltkorea/icebang/domain/email/service/MockEmailService.java @@ -8,7 +8,7 @@ import lombok.extern.slf4j.Slf4j; @Service -@Profile({"test-unit", "test-e2e", "local", "develop"}) +@Profile({"test-unit", "test-e2e", "test-integration", "local", "develop"}) @Slf4j public class MockEmailService implements EmailService { diff --git a/apps/user-service/src/main/resources/application-test-integration.yml b/apps/user-service/src/main/resources/application-test-integration.yml index 95faf0f3..6625974a 100644 --- a/apps/user-service/src/main/resources/application-test-integration.yml +++ b/apps/user-service/src/main/resources/application-test-integration.yml @@ -10,7 +10,7 @@ spring: password: driver-class-name: org.h2.Driver hikari: - connection-init-sql: "SET MODE MariaDB" + connection-init-sql: "SET MODE MariaDB; SET NON_KEYWORDS USER;" connection-timeout: 30000 idle-timeout: 600000 max-lifetime: 1800000 @@ -23,15 +23,6 @@ spring: console: enabled: true - # JPA 설정 (H2용) - jpa: - hibernate: - ddl-auto: create-drop - show-sql: true - properties: - hibernate: - dialect: org.hibernate.dialect.H2Dialect - # SQL 스크립트 초기화 설정 sql: init: @@ -48,4 +39,4 @@ mybatis: map-underscore-to-camel-case: true logging: - config: classpath:log4j2-test-unit.yml \ No newline at end of file + config: classpath:log4j2-develop.yml \ No newline at end of file diff --git a/apps/user-service/src/main/resources/application-test-unit.yml b/apps/user-service/src/main/resources/application-test-unit.yml index 4b36c77f..cd4e018f 100644 --- a/apps/user-service/src/main/resources/application-test-unit.yml +++ b/apps/user-service/src/main/resources/application-test-unit.yml @@ -24,15 +24,6 @@ spring: console: enabled: true - # JPA 설정 (H2용) - jpa: - hibernate: - ddl-auto: create-drop - show-sql: true - properties: - hibernate: - dialect: org.hibernate.dialect.H2Dialect - # SQL 스크립트 초기화 설정 sql: init: diff --git a/apps/user-service/src/test/java/com/gltkorea/icebang/integration/auth/AuthApiIntegrationTest.java b/apps/user-service/src/test/java/com/gltkorea/icebang/integration/auth/AuthApiIntegrationTest.java new file mode 100644 index 00000000..23a24550 --- /dev/null +++ b/apps/user-service/src/test/java/com/gltkorea/icebang/integration/auth/AuthApiIntegrationTest.java @@ -0,0 +1,81 @@ +package com.gltkorea.icebang.integration.auth; + +import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.document; +import static com.epages.restdocs.apispec.ResourceDocumentation.*; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; +import static org.springframework.restdocs.payload.PayloadDocumentation.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.http.*; +import org.springframework.restdocs.payload.JsonFieldType; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.jdbc.Sql; + +import com.epages.restdocs.apispec.ResourceSnippetParameters; +import com.gltkorea.icebang.integration.support.IntegrationTestSupport; + +@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) +@Sql( + value = "classpath:sql/01-insert-internal-users.sql", + executionPhase = Sql.ExecutionPhase.BEFORE_TEST_CLASS) +class AuthApiIntegrationTest extends IntegrationTestSupport { + @Test + @DisplayName("사용자 로그인 성공") + void login_success() throws Exception { + // given + Map loginRequest = new HashMap<>(); + loginRequest.put("email", "admin@icebang.site"); + loginRequest.put("password", "qwer1234!A"); + + // MockMvc로 REST Docs + OpenAPI 생성 + mockMvc + .perform( + post(getApiUrlForDocs("/v0/auth/login")) + .contentType(MediaType.APPLICATION_JSON) + .header("Origin", "https://admin.icebang.site") + .header("Referer", "https://admin.icebang.site/") + .content(objectMapper.writeValueAsString(loginRequest))) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.success").value(true)) + .andExpect(jsonPath("$.status").value("OK")) + .andExpect(jsonPath("$.message").value("OK")) + .andExpect(jsonPath("$.data").isEmpty()) + .andDo( + document( + "auth-login", + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint()), + resource( + ResourceSnippetParameters.builder() + .tag("Authentication") + .summary("사용자 로그인") + .description("이메일과 비밀번호로 사용자 인증을 수행합니다") + .requestFields( + fieldWithPath("email") + .type(JsonFieldType.STRING) + .description("사용자 이메일 주소"), + fieldWithPath("password") + .type(JsonFieldType.STRING) + .description("사용자 비밀번호")) + .responseFields( + fieldWithPath("success") + .type(JsonFieldType.BOOLEAN) + .description("요청 성공 여부"), + fieldWithPath("data") + .type(JsonFieldType.NULL) + .description("응답 데이터 (로그인 성공 시 null)"), + fieldWithPath("message") + .type(JsonFieldType.STRING) + .description("응답 메시지"), + fieldWithPath("status") + .type(JsonFieldType.STRING) + .description("HTTP 상태")) + .build()))); + } +} diff --git a/apps/user-service/src/test/java/com/gltkorea/icebang/integration/auth/testa.java b/apps/user-service/src/test/java/com/gltkorea/icebang/integration/auth/testa.java deleted file mode 100644 index 9f273f56..00000000 --- a/apps/user-service/src/test/java/com/gltkorea/icebang/integration/auth/testa.java +++ /dev/null @@ -1,287 +0,0 @@ -// package com.gltkorea.icebang.e2e.scenario; -// -// import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.document; -// import static com.epages.restdocs.apispec.ResourceDocumentation.*; -// import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; -// import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post; -// import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; -// import static org.springframework.restdocs.payload.PayloadDocumentation.*; -// import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; -// -// import java.util.Arrays; -// import java.util.HashMap; -// import java.util.Map; -// -// import org.junit.jupiter.api.DisplayName; -// import org.junit.jupiter.api.Test; -// import org.springframework.http.*; -// import org.springframework.restdocs.payload.JsonFieldType; -// import org.springframework.test.annotation.DirtiesContext; -// import org.springframework.test.context.jdbc.Sql; -// -// import com.epages.restdocs.apispec.ResourceSnippetParameters; -// import com.gltkorea.icebang.e2e.support.E2eTestSupport; -// -// @Sql("classpath:sql/01-insert-internal-users.sql") -// @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) -// class UserRegistrationFlowE2eTest extends E2eTestSupport { -// -// @Test -// @DisplayName("조직 목록 조회 성공") -// void getOrganizations_success() throws Exception { -// mockMvc -// .perform( -// get(getApiUrlForDocs("/v0/organizations")) -// .contentType(MediaType.APPLICATION_JSON) -// .header("Origin", "https://admin.icebang.site") -// .header("Referer", "https://admin.icebang.site/")) -// .andExpect(status().isOk()) -// .andExpect(jsonPath("$.success").value(true)) -// .andExpect(jsonPath("$.status").value("OK")) -// .andExpect(jsonPath("$.message").value("OK")) -// .andExpect(jsonPath("$.data").isArray()) -// .andDo( -// document( -// "organizations-list", -// preprocessRequest(prettyPrint()), -// preprocessResponse(prettyPrint()), -// resource( -// ResourceSnippetParameters.builder() -// .tag("Organization") -// .summary("조직 목록 조회") -// .description("시스템에 등록된 모든 조직의 목록을 조회합니다") -// .responseFields( -// fieldWithPath("success") -// .type(JsonFieldType.BOOLEAN) -// .description("요청 성공 여부"), -// -// fieldWithPath("data[]").type(JsonFieldType.ARRAY).description("조직 목록"), -// fieldWithPath("data[].id") -// .type(JsonFieldType.NUMBER) -// .description("조직 ID"), -// fieldWithPath("data[].organizationName") -// .type(JsonFieldType.STRING) -// .description("조직명"), -// fieldWithPath("message") -// .type(JsonFieldType.STRING) -// .description("응답 메시지"), -// fieldWithPath("status") -// .type(JsonFieldType.STRING) -// .description("HTTP 상태")) -// .build()))); -// } -// -// @Test -// @DisplayName("조직별 옵션 조회 성공") -// void getOrganizationOptions_success() throws Exception { -// mockMvc -// .perform( -// get(getApiUrlForDocs("/v0/organizations/{orgId}/options"), 1) -// .contentType(MediaType.APPLICATION_JSON) -// .header("Origin", "https://admin.icebang.site") -// .header("Referer", "https://admin.icebang.site/")) -// .andExpect(status().isOk()) -// .andExpect(jsonPath("$.success").value(true)) -// .andExpect(jsonPath("$.status").value("OK")) -// .andExpect(jsonPath("$.message").value("OK")) -// .andExpect(jsonPath("$.data.departments").isArray()) -// .andExpect(jsonPath("$.data.positions").isArray()) -// .andExpect(jsonPath("$.data.roles").isArray()) -// .andDo( -// document( -// "organization-options", -// preprocessRequest(prettyPrint()), -// preprocessResponse(prettyPrint()), -// resource( -// ResourceSnippetParameters.builder() -// .tag("Organization") -// .summary("조직별 옵션 조회") -// .description("특정 조직의 부서, 직급, 역할 정보를 조회합니다") -// .responseFields( -// fieldWithPath("success") -// .type(JsonFieldType.BOOLEAN) -// .description("요청 성공 여부"), -// fieldWithPath("data") -// .type(JsonFieldType.OBJECT) -// .description("조직 옵션 데이터"), -// fieldWithPath("data.departments[]") -// .type(JsonFieldType.ARRAY) -// .description("부서 목록"), -// fieldWithPath("data.departments[].id") -// .type(JsonFieldType.NUMBER) -// .description("부서 ID"), -// fieldWithPath("data.departments[].name") -// .type(JsonFieldType.STRING) -// .description("부서명"), -// fieldWithPath("data.positions[]") -// .type(JsonFieldType.ARRAY) -// .description("직급 목록"), -// fieldWithPath("data.positions[].id") -// .type(JsonFieldType.NUMBER) -// .description("직급 ID"), -// fieldWithPath("data.positions[].title") -// .type(JsonFieldType.STRING) -// .description("직급명"), -// fieldWithPath("data.roles[]") -// .type(JsonFieldType.ARRAY) -// .description("역할 목록"), -// fieldWithPath("data.roles[].id") -// .type(JsonFieldType.NUMBER) -// .description("역할 ID"), -// fieldWithPath("data.roles[].name") -// .type(JsonFieldType.STRING) -// .description("역할 코드명"), -// fieldWithPath("data.roles[].description") -// .type(JsonFieldType.STRING) -// .description("역할 설명"), -// fieldWithPath("message") -// .type(JsonFieldType.STRING) -// .description("응답 메시지"), -// fieldWithPath("status") -// .type(JsonFieldType.STRING) -// .description("HTTP 상태")) -// .build()))); -// } -// -// @Test -// @DisplayName("사용자 로그인 성공") -// void login_success() throws Exception { -// // given -// Map loginRequest = new HashMap<>(); -// loginRequest.put("email", "admin@icebang.site"); -// loginRequest.put("password", "qwer1234!A"); -// -// // MockMvc로 REST Docs + OpenAPI 생성 -// mockMvc -// .perform( -// post(getApiUrlForDocs("/v0/auth/login")) -// .contentType(MediaType.APPLICATION_JSON) -// .header("Origin", "https://admin.icebang.site") -// .header("Referer", "https://admin.icebang.site/") -// .content(objectMapper.writeValueAsString(loginRequest))) -// .andExpect(status().isOk()) -// .andExpect(jsonPath("$.success").value(true)) -// .andExpect(jsonPath("$.status").value("OK")) -// .andExpect(jsonPath("$.message").value("OK")) -// .andExpect(jsonPath("$.data").isEmpty()) -// .andDo( -// document( -// "auth-login", -// preprocessRequest(prettyPrint()), -// preprocessResponse(prettyPrint()), -// resource( -// ResourceSnippetParameters.builder() -// .tag("Authentication") -// .summary("사용자 로그인") -// .description("이메일과 비밀번호로 사용자 인증을 수행합니다") -// .requestFields( -// fieldWithPath("email") -// .type(JsonFieldType.STRING) -// .description("사용자 이메일 주소"), -// fieldWithPath("password") -// .type(JsonFieldType.STRING) -// .description("사용자 비밀번호")) -// .responseFields( -// fieldWithPath("success") -// .type(JsonFieldType.BOOLEAN) -// .description("요청 성공 여부"), -// fieldWithPath("data") -// .type(JsonFieldType.NULL) -// .description("응답 데이터 (로그인 성공 시 -// null)"), -// fieldWithPath("message") -// .type(JsonFieldType.STRING) -// .description("응답 메시지"), -// fieldWithPath("status") -// .type(JsonFieldType.STRING) -// .description("HTTP 상태")) -// .build()))); -// } -// -// @Test -// @DisplayName("사용자 회원가입 성공") -// void register_success() throws Exception { -// // given - 먼저 로그인하여 인증 토큰 획득 -// Map loginRequest = new HashMap<>(); -// loginRequest.put("email", "admin@icebang.site"); -// loginRequest.put("password", "qwer1234!A"); -// -// // 로그인 수행 (실제 환경에서는 토큰을 헤더에 추가해야 할 수 있음) -// mockMvc -// .perform( -// post("/v0/auth/login") -// .contentType(MediaType.APPLICATION_JSON) -// .content(objectMapper.writeValueAsString(loginRequest))) -// .andExpect(status().isOk()); -// -// // 회원가입 요청 데이터 -// Map registerRequest = new HashMap<>(); -// registerRequest.put("name", "김철수"); -// registerRequest.put("email", "kim.chulsoo@example.com"); -// registerRequest.put("orgId", 1); -// registerRequest.put("deptId", 2); -// registerRequest.put("positionId", 5); -// registerRequest.put("roleIds", Arrays.asList(6, 7, 8)); -// registerRequest.put("password", null); -// -// // when & then -// mockMvc -// .perform( -// post(getApiUrlForDocs("/v0/auth/register")) -// .contentType(MediaType.APPLICATION_JSON) -// .header("Origin", "https://admin.icebang.site") -// .header("Referer", "https://admin.icebang.site/") -// .content(objectMapper.writeValueAsString(registerRequest))) -// .andExpect(status().isOk()) -// .andExpect(jsonPath("$.success").value(true)) -// .andExpect(jsonPath("$.status").value("OK")) -// .andExpect(jsonPath("$.message").value("OK")) -// .andDo( -// document( -// "auth-register", -// preprocessRequest(prettyPrint()), -// preprocessResponse(prettyPrint()), -// resource( -// ResourceSnippetParameters.builder() -// .tag("Authentication") -// .summary("사용자 회원가입") -// .description("새로운 사용자를 등록합니다. 관리자 로그인 후에만 사용 -// 가능합니다.") -// .requestFields( -// -// fieldWithPath("name").type(JsonFieldType.STRING).description("사용자 이름"), -// fieldWithPath("email") -// .type(JsonFieldType.STRING) -// .description("사용자 이메일 주소"), -// -// fieldWithPath("orgId").type(JsonFieldType.NUMBER).description("조직 ID"), -// -// fieldWithPath("deptId").type(JsonFieldType.NUMBER).description("부서 ID"), -// fieldWithPath("positionId") -// .type(JsonFieldType.NUMBER) -// .description("직급 ID"), -// fieldWithPath("roleIds[]") -// .type(JsonFieldType.ARRAY) -// .description("역할 ID 목록"), -// fieldWithPath("password") -// .type(JsonFieldType.NULL) -// .description("비밀번호 (null인 경우 시스템에서 -// 자동 생성)") -// .optional()) -// .responseFields( -// fieldWithPath("success") -// .type(JsonFieldType.BOOLEAN) -// .description("요청 성공 여부"), -// fieldWithPath("data") -// .type(JsonFieldType.VARIES) -// .description("응답 데이터 (회원가입 결과 -// 정보)"), -// fieldWithPath("message") -// .type(JsonFieldType.STRING) -// .description("응답 메시지"), -// fieldWithPath("status") -// .type(JsonFieldType.STRING) -// .description("HTTP 상태")) -// .build()))); -// } -// } diff --git a/apps/user-service/src/test/java/com/gltkorea/icebang/integration/support/IntegrationTestSupport.java b/apps/user-service/src/test/java/com/gltkorea/icebang/integration/support/IntegrationTestSupport.java index 9eb0b356..0c8991c9 100644 --- a/apps/user-service/src/test/java/com/gltkorea/icebang/integration/support/IntegrationTestSupport.java +++ b/apps/user-service/src/test/java/com/gltkorea/icebang/integration/support/IntegrationTestSupport.java @@ -1,13 +1,35 @@ package com.gltkorea.icebang.integration.support; -import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.restdocs.RestDocumentationExtension; +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.context.SpringBootTest; +import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.context.annotation.Import; import org.springframework.test.web.servlet.MockMvc; +import com.fasterxml.jackson.databind.ObjectMapper; import com.gltkorea.icebang.integration.annotation.IntegrationTest; +import com.gltkorea.icebang.integration.config.RestDocsConfiguration; @IntegrationTest -@ExtendWith(RestDocumentationExtension.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@AutoConfigureMockMvc +@AutoConfigureRestDocs +@Import(RestDocsConfiguration.class) public abstract class IntegrationTestSupport { - protected MockMvc mockMvc; + + @Autowired protected MockMvc mockMvc; + + @Autowired protected ObjectMapper objectMapper; + + @LocalServerPort protected int port; + + /** RestDocs에서 실제 API 호출 주소를 표기할 때 사용 */ + protected String getApiUrlForDocs(String path) { + if (path.startsWith("/")) { + return "http://localhost:" + port + path; + } + return "http://localhost:" + port + "/" + path; + } } From ae9ace4ac393d07d39e99345938b53f783be352c Mon Sep 17 00:00:00 2001 From: can019 Date: Wed, 10 Sep 2025 13:13:00 +0900 Subject: [PATCH 03/12] =?UTF-8?q?chore:=20Test=20dir=20=EA=B5=AC=EC=A1=B0?= =?UTF-8?q?=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gltkorea/icebang/e2e/scenario/ContextLoadE2eTests.java | 2 +- .../icebang/e2e/scenario/UserRegistrationFlowE2eTest.java | 2 +- .../icebang/e2e/{ => setup}/annotation/E2eTest.java | 2 +- .../e2e/{ => setup}/config/E2eTestConfiguration.java | 2 +- .../icebang/e2e/{ => setup}/support/E2eTestSupport.java | 6 +++--- .../icebang/e2e/{ => setup}/support/E2eTestSupportTest.java | 2 +- .../integration/{ => setup}/annotation/IntegrationTest.java | 2 +- .../{ => setup}/config/RestDocsConfiguration.java | 2 +- .../{ => setup}/support/IntegrationTestSupport.java | 6 +++--- .../{ => tests}/auth/AuthApiIntegrationTest.java | 4 ++-- .../icebang/unit/{ => setup}/annotation/UnitTest.java | 2 +- .../icebang/unit/{ => setup}/support/UnitTestSupport.java | 4 ++-- 12 files changed, 18 insertions(+), 18 deletions(-) rename apps/user-service/src/test/java/com/gltkorea/icebang/e2e/{ => setup}/annotation/E2eTest.java (88%) rename apps/user-service/src/test/java/com/gltkorea/icebang/e2e/{ => setup}/config/E2eTestConfiguration.java (97%) rename apps/user-service/src/test/java/com/gltkorea/icebang/e2e/{ => setup}/support/E2eTestSupport.java (91%) rename apps/user-service/src/test/java/com/gltkorea/icebang/e2e/{ => setup}/support/E2eTestSupportTest.java (90%) rename apps/user-service/src/test/java/com/gltkorea/icebang/integration/{ => setup}/annotation/IntegrationTest.java (87%) rename apps/user-service/src/test/java/com/gltkorea/icebang/integration/{ => setup}/config/RestDocsConfiguration.java (94%) rename apps/user-service/src/test/java/com/gltkorea/icebang/integration/{ => setup}/support/IntegrationTestSupport.java (84%) rename apps/user-service/src/test/java/com/gltkorea/icebang/integration/{ => tests}/auth/AuthApiIntegrationTest.java (96%) rename apps/user-service/src/test/java/com/gltkorea/icebang/unit/{ => setup}/annotation/UnitTest.java (88%) rename apps/user-service/src/test/java/com/gltkorea/icebang/unit/{ => setup}/support/UnitTestSupport.java (60%) diff --git a/apps/user-service/src/test/java/com/gltkorea/icebang/e2e/scenario/ContextLoadE2eTests.java b/apps/user-service/src/test/java/com/gltkorea/icebang/e2e/scenario/ContextLoadE2eTests.java index be0bb785..ad6bfbf0 100644 --- a/apps/user-service/src/test/java/com/gltkorea/icebang/e2e/scenario/ContextLoadE2eTests.java +++ b/apps/user-service/src/test/java/com/gltkorea/icebang/e2e/scenario/ContextLoadE2eTests.java @@ -2,7 +2,7 @@ import org.junit.jupiter.api.Test; -import com.gltkorea.icebang.e2e.support.E2eTestSupport; +import com.gltkorea.icebang.e2e.setup.support.E2eTestSupport; class ContextLoadE2eTests extends E2eTestSupport { diff --git a/apps/user-service/src/test/java/com/gltkorea/icebang/e2e/scenario/UserRegistrationFlowE2eTest.java b/apps/user-service/src/test/java/com/gltkorea/icebang/e2e/scenario/UserRegistrationFlowE2eTest.java index f0fd3244..762d5ca4 100644 --- a/apps/user-service/src/test/java/com/gltkorea/icebang/e2e/scenario/UserRegistrationFlowE2eTest.java +++ b/apps/user-service/src/test/java/com/gltkorea/icebang/e2e/scenario/UserRegistrationFlowE2eTest.java @@ -13,7 +13,7 @@ import org.springframework.http.*; import org.springframework.test.context.jdbc.Sql; -import com.gltkorea.icebang.e2e.support.E2eTestSupport; +import com.gltkorea.icebang.e2e.setup.support.E2eTestSupport; @Sql( value = "classpath:sql/01-insert-internal-users.sql", diff --git a/apps/user-service/src/test/java/com/gltkorea/icebang/e2e/annotation/E2eTest.java b/apps/user-service/src/test/java/com/gltkorea/icebang/e2e/setup/annotation/E2eTest.java similarity index 88% rename from apps/user-service/src/test/java/com/gltkorea/icebang/e2e/annotation/E2eTest.java rename to apps/user-service/src/test/java/com/gltkorea/icebang/e2e/setup/annotation/E2eTest.java index 0840a996..0f087064 100644 --- a/apps/user-service/src/test/java/com/gltkorea/icebang/e2e/annotation/E2eTest.java +++ b/apps/user-service/src/test/java/com/gltkorea/icebang/e2e/setup/annotation/E2eTest.java @@ -1,4 +1,4 @@ -package com.gltkorea.icebang.e2e.annotation; +package com.gltkorea.icebang.e2e.setup.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/apps/user-service/src/test/java/com/gltkorea/icebang/e2e/config/E2eTestConfiguration.java b/apps/user-service/src/test/java/com/gltkorea/icebang/e2e/setup/config/E2eTestConfiguration.java similarity index 97% rename from apps/user-service/src/test/java/com/gltkorea/icebang/e2e/config/E2eTestConfiguration.java rename to apps/user-service/src/test/java/com/gltkorea/icebang/e2e/setup/config/E2eTestConfiguration.java index 7ebe181d..4ee26803 100644 --- a/apps/user-service/src/test/java/com/gltkorea/icebang/e2e/config/E2eTestConfiguration.java +++ b/apps/user-service/src/test/java/com/gltkorea/icebang/e2e/setup/config/E2eTestConfiguration.java @@ -1,4 +1,4 @@ -package com.gltkorea.icebang.e2e.config; +package com.gltkorea.icebang.e2e.setup.config; import org.springframework.boot.test.context.TestConfiguration; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; diff --git a/apps/user-service/src/test/java/com/gltkorea/icebang/e2e/support/E2eTestSupport.java b/apps/user-service/src/test/java/com/gltkorea/icebang/e2e/setup/support/E2eTestSupport.java similarity index 91% rename from apps/user-service/src/test/java/com/gltkorea/icebang/e2e/support/E2eTestSupport.java rename to apps/user-service/src/test/java/com/gltkorea/icebang/e2e/setup/support/E2eTestSupport.java index 12a44848..b72ac031 100644 --- a/apps/user-service/src/test/java/com/gltkorea/icebang/e2e/support/E2eTestSupport.java +++ b/apps/user-service/src/test/java/com/gltkorea/icebang/e2e/setup/support/E2eTestSupport.java @@ -1,4 +1,4 @@ -package com.gltkorea.icebang.e2e.support; +package com.gltkorea.icebang.e2e.setup.support; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -9,8 +9,8 @@ import org.springframework.web.context.WebApplicationContext; import org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper; -import com.gltkorea.icebang.e2e.annotation.E2eTest; -import com.gltkorea.icebang.e2e.config.E2eTestConfiguration; +import com.gltkorea.icebang.e2e.setup.annotation.E2eTest; +import com.gltkorea.icebang.e2e.setup.config.E2eTestConfiguration; @Import(E2eTestConfiguration.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) diff --git a/apps/user-service/src/test/java/com/gltkorea/icebang/e2e/support/E2eTestSupportTest.java b/apps/user-service/src/test/java/com/gltkorea/icebang/e2e/setup/support/E2eTestSupportTest.java similarity index 90% rename from apps/user-service/src/test/java/com/gltkorea/icebang/e2e/support/E2eTestSupportTest.java rename to apps/user-service/src/test/java/com/gltkorea/icebang/e2e/setup/support/E2eTestSupportTest.java index 7eccdd4e..33bfd4dc 100644 --- a/apps/user-service/src/test/java/com/gltkorea/icebang/e2e/support/E2eTestSupportTest.java +++ b/apps/user-service/src/test/java/com/gltkorea/icebang/e2e/setup/support/E2eTestSupportTest.java @@ -1,4 +1,4 @@ -package com.gltkorea.icebang.e2e.support; +package com.gltkorea.icebang.e2e.setup.support; import static org.assertj.core.api.Assertions.assertThat; diff --git a/apps/user-service/src/test/java/com/gltkorea/icebang/integration/annotation/IntegrationTest.java b/apps/user-service/src/test/java/com/gltkorea/icebang/integration/setup/annotation/IntegrationTest.java similarity index 87% rename from apps/user-service/src/test/java/com/gltkorea/icebang/integration/annotation/IntegrationTest.java rename to apps/user-service/src/test/java/com/gltkorea/icebang/integration/setup/annotation/IntegrationTest.java index ca4e4046..ec111866 100644 --- a/apps/user-service/src/test/java/com/gltkorea/icebang/integration/annotation/IntegrationTest.java +++ b/apps/user-service/src/test/java/com/gltkorea/icebang/integration/setup/annotation/IntegrationTest.java @@ -1,4 +1,4 @@ -package com.gltkorea.icebang.integration.annotation; +package com.gltkorea.icebang.integration.setup.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/apps/user-service/src/test/java/com/gltkorea/icebang/integration/config/RestDocsConfiguration.java b/apps/user-service/src/test/java/com/gltkorea/icebang/integration/setup/config/RestDocsConfiguration.java similarity index 94% rename from apps/user-service/src/test/java/com/gltkorea/icebang/integration/config/RestDocsConfiguration.java rename to apps/user-service/src/test/java/com/gltkorea/icebang/integration/setup/config/RestDocsConfiguration.java index 319860ad..eeb97ffc 100644 --- a/apps/user-service/src/test/java/com/gltkorea/icebang/integration/config/RestDocsConfiguration.java +++ b/apps/user-service/src/test/java/com/gltkorea/icebang/integration/setup/config/RestDocsConfiguration.java @@ -1,4 +1,4 @@ -package com.gltkorea.icebang.integration.config; +package com.gltkorea.icebang.integration.setup.config; import org.springframework.boot.test.context.TestConfiguration; import org.springframework.context.annotation.Bean; diff --git a/apps/user-service/src/test/java/com/gltkorea/icebang/integration/support/IntegrationTestSupport.java b/apps/user-service/src/test/java/com/gltkorea/icebang/integration/setup/support/IntegrationTestSupport.java similarity index 84% rename from apps/user-service/src/test/java/com/gltkorea/icebang/integration/support/IntegrationTestSupport.java rename to apps/user-service/src/test/java/com/gltkorea/icebang/integration/setup/support/IntegrationTestSupport.java index 0c8991c9..037f37e5 100644 --- a/apps/user-service/src/test/java/com/gltkorea/icebang/integration/support/IntegrationTestSupport.java +++ b/apps/user-service/src/test/java/com/gltkorea/icebang/integration/setup/support/IntegrationTestSupport.java @@ -1,4 +1,4 @@ -package com.gltkorea.icebang.integration.support; +package com.gltkorea.icebang.integration.setup.support; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; @@ -9,8 +9,8 @@ import org.springframework.test.web.servlet.MockMvc; import com.fasterxml.jackson.databind.ObjectMapper; -import com.gltkorea.icebang.integration.annotation.IntegrationTest; -import com.gltkorea.icebang.integration.config.RestDocsConfiguration; +import com.gltkorea.icebang.integration.setup.annotation.IntegrationTest; +import com.gltkorea.icebang.integration.setup.config.RestDocsConfiguration; @IntegrationTest @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) diff --git a/apps/user-service/src/test/java/com/gltkorea/icebang/integration/auth/AuthApiIntegrationTest.java b/apps/user-service/src/test/java/com/gltkorea/icebang/integration/tests/auth/AuthApiIntegrationTest.java similarity index 96% rename from apps/user-service/src/test/java/com/gltkorea/icebang/integration/auth/AuthApiIntegrationTest.java rename to apps/user-service/src/test/java/com/gltkorea/icebang/integration/tests/auth/AuthApiIntegrationTest.java index 23a24550..676cc688 100644 --- a/apps/user-service/src/test/java/com/gltkorea/icebang/integration/auth/AuthApiIntegrationTest.java +++ b/apps/user-service/src/test/java/com/gltkorea/icebang/integration/tests/auth/AuthApiIntegrationTest.java @@ -1,4 +1,4 @@ -package com.gltkorea.icebang.integration.auth; +package com.gltkorea.icebang.integration.tests.auth; import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.document; import static com.epages.restdocs.apispec.ResourceDocumentation.*; @@ -18,7 +18,7 @@ import org.springframework.test.context.jdbc.Sql; import com.epages.restdocs.apispec.ResourceSnippetParameters; -import com.gltkorea.icebang.integration.support.IntegrationTestSupport; +import com.gltkorea.icebang.integration.setup.support.IntegrationTestSupport; @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) @Sql( diff --git a/apps/user-service/src/test/java/com/gltkorea/icebang/unit/annotation/UnitTest.java b/apps/user-service/src/test/java/com/gltkorea/icebang/unit/setup/annotation/UnitTest.java similarity index 88% rename from apps/user-service/src/test/java/com/gltkorea/icebang/unit/annotation/UnitTest.java rename to apps/user-service/src/test/java/com/gltkorea/icebang/unit/setup/annotation/UnitTest.java index 117a5cb2..cb2f975c 100644 --- a/apps/user-service/src/test/java/com/gltkorea/icebang/unit/annotation/UnitTest.java +++ b/apps/user-service/src/test/java/com/gltkorea/icebang/unit/setup/annotation/UnitTest.java @@ -1,4 +1,4 @@ -package com.gltkorea.icebang.unit.annotation; +package com.gltkorea.icebang.unit.setup.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/apps/user-service/src/test/java/com/gltkorea/icebang/unit/support/UnitTestSupport.java b/apps/user-service/src/test/java/com/gltkorea/icebang/unit/setup/support/UnitTestSupport.java similarity index 60% rename from apps/user-service/src/test/java/com/gltkorea/icebang/unit/support/UnitTestSupport.java rename to apps/user-service/src/test/java/com/gltkorea/icebang/unit/setup/support/UnitTestSupport.java index be4c8660..9bc71657 100644 --- a/apps/user-service/src/test/java/com/gltkorea/icebang/unit/support/UnitTestSupport.java +++ b/apps/user-service/src/test/java/com/gltkorea/icebang/unit/setup/support/UnitTestSupport.java @@ -1,6 +1,6 @@ -package com.gltkorea.icebang.unit.support; +package com.gltkorea.icebang.unit.setup.support; -import com.gltkorea.icebang.unit.annotation.UnitTest; +import com.gltkorea.icebang.unit.setup.annotation.UnitTest; @UnitTest public abstract class UnitTestSupport { From c3d96ef7795bb08e624b686c24826fb5bce1001e Mon Sep 17 00:00:00 2001 From: can019 Date: Wed, 10 Sep 2025 13:22:07 +0900 Subject: [PATCH 04/12] test: oranization api test --- .../OrganizationApiIntegrationTest.java | 157 ++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 apps/user-service/src/test/java/com/gltkorea/icebang/integration/tests/organization/OrganizationApiIntegrationTest.java diff --git a/apps/user-service/src/test/java/com/gltkorea/icebang/integration/tests/organization/OrganizationApiIntegrationTest.java b/apps/user-service/src/test/java/com/gltkorea/icebang/integration/tests/organization/OrganizationApiIntegrationTest.java new file mode 100644 index 00000000..d7306ec2 --- /dev/null +++ b/apps/user-service/src/test/java/com/gltkorea/icebang/integration/tests/organization/OrganizationApiIntegrationTest.java @@ -0,0 +1,157 @@ +package com.gltkorea.icebang.integration.tests.organization; + +import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.document; +import static com.epages.restdocs.apispec.ResourceDocumentation.*; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; +import static org.springframework.restdocs.payload.PayloadDocumentation.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.http.*; +import org.springframework.restdocs.payload.JsonFieldType; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.jdbc.Sql; + +import com.epages.restdocs.apispec.ResourceSnippetParameters; +import com.gltkorea.icebang.integration.setup.support.IntegrationTestSupport; + +@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) +@Sql( + value = { + "classpath:sql/01-insert-internal-users.sql", + "classpath:sql/02-insert-external-users.sql" + }, + executionPhase = Sql.ExecutionPhase.BEFORE_TEST_CLASS) +class OrganizationApiIntegrationTest extends IntegrationTestSupport { + + @Test + @DisplayName("조직 목록 조회 성공") + void getOrganizations_success() throws Exception { + // when & then + mockMvc + .perform( + get(getApiUrlForDocs("/v0/organizations")) + .contentType(MediaType.APPLICATION_JSON) + .header("Origin", "https://admin.icebang.site") + .header("Referer", "https://admin.icebang.site/")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.success").value(true)) + .andExpect(jsonPath("$.status").value("OK")) + .andExpect(jsonPath("$.message").value("OK")) + .andExpect(jsonPath("$.data").isArray()) + .andExpect(jsonPath("$.data[0].id").exists()) + .andExpect(jsonPath("$.data[0].organizationName").exists()) + .andDo( + document( + "organizations-list", + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint()), + resource( + ResourceSnippetParameters.builder() + .tag("Organization") + .summary("조직 목록 조회") + .description("시스템에 등록된 모든 조직의 목록을 조회합니다") + .responseFields( + fieldWithPath("success") + .type(JsonFieldType.BOOLEAN) + .description("요청 성공 여부"), + fieldWithPath("data[]").type(JsonFieldType.ARRAY).description("조직 목록"), + fieldWithPath("data[].id") + .type(JsonFieldType.NUMBER) + .description("조직 ID"), + fieldWithPath("data[].organizationName") + .type(JsonFieldType.STRING) + .description("조직명"), + fieldWithPath("message") + .type(JsonFieldType.STRING) + .description("응답 메시지"), + fieldWithPath("status") + .type(JsonFieldType.STRING) + .description("HTTP 상태")) + .build()))); + } + + @Test + @DisplayName("조직 옵션 정보 조회 성공") + void getOrganizationOptions_success() throws Exception { + // given + Long organizationId = 1L; + + // when & then + mockMvc + .perform( + get(getApiUrlForDocs("/v0/organizations/{organizationId}/options"), organizationId) + .contentType(MediaType.APPLICATION_JSON) + .header("Origin", "https://admin.icebang.site") + .header("Referer", "https://admin.icebang.site/")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.success").value(true)) + .andExpect(jsonPath("$.status").value("OK")) + .andExpect(jsonPath("$.message").value("OK")) + .andExpect(jsonPath("$.data.departments").isArray()) + .andExpect(jsonPath("$.data.positions").isArray()) + .andExpect(jsonPath("$.data.roles").isArray()) + .andExpect(jsonPath("$.data.departments[0].id").exists()) + .andExpect(jsonPath("$.data.departments[0].name").exists()) + .andExpect(jsonPath("$.data.positions[0].id").exists()) + .andExpect(jsonPath("$.data.positions[0].title").exists()) + .andExpect(jsonPath("$.data.roles[0].id").exists()) + .andExpect(jsonPath("$.data.roles[0].name").exists()) + .andExpect(jsonPath("$.data.roles[0].description").exists()) + .andDo( + document( + "organizations-options", + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint()), + resource( + ResourceSnippetParameters.builder() + .tag("Organization") + .summary("조직 옵션 정보 조회") + .description("특정 조직의 부서, 직급, 역할 옵션 정보를 조회합니다") + .pathParameters(parameterWithName("organizationId").description("조직 ID")) + .responseFields( + fieldWithPath("success") + .type(JsonFieldType.BOOLEAN) + .description("요청 성공 여부"), + fieldWithPath("data").type(JsonFieldType.OBJECT).description("옵션 데이터"), + fieldWithPath("data.departments[]") + .type(JsonFieldType.ARRAY) + .description("부서 목록"), + fieldWithPath("data.departments[].id") + .type(JsonFieldType.NUMBER) + .description("부서 ID"), + fieldWithPath("data.departments[].name") + .type(JsonFieldType.STRING) + .description("부서명"), + fieldWithPath("data.positions[]") + .type(JsonFieldType.ARRAY) + .description("직급 목록"), + fieldWithPath("data.positions[].id") + .type(JsonFieldType.NUMBER) + .description("직급 ID"), + fieldWithPath("data.positions[].title") + .type(JsonFieldType.STRING) + .description("직급명"), + fieldWithPath("data.roles[]") + .type(JsonFieldType.ARRAY) + .description("역할 목록"), + fieldWithPath("data.roles[].id") + .type(JsonFieldType.NUMBER) + .description("역할 ID"), + fieldWithPath("data.roles[].name") + .type(JsonFieldType.STRING) + .description("역할명"), + fieldWithPath("data.roles[].description") + .type(JsonFieldType.STRING) + .description("역할 설명"), + fieldWithPath("message") + .type(JsonFieldType.STRING) + .description("응답 메시지"), + fieldWithPath("status") + .type(JsonFieldType.STRING) + .description("HTTP 상태")) + .build()))); + } +} From 7303bdd0745caa7796e7a3ff7ffbd50a4c509158 Mon Sep 17 00:00:00 2001 From: can019 Date: Wed, 10 Sep 2025 13:47:53 +0900 Subject: [PATCH 05/12] test: Integration test --- .github/workflows/ci-java.yml | 6 +++-- apps/user-service/build.gradle | 12 ++++++++++ .../src/main/resources/application.yml | 4 ++++ .../tests/auth/AuthApiIntegrationTest.java | 6 ++--- .../OrganizationApiIntegrationTest.java | 23 +++++++++++++++---- 5 files changed, 41 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci-java.yml b/.github/workflows/ci-java.yml index 2505b59e..459f5143 100644 --- a/.github/workflows/ci-java.yml +++ b/.github/workflows/ci-java.yml @@ -79,9 +79,11 @@ jobs: - name: Run Tests run: | if [ "${{ github.base_ref }}" == "main" ]; then - ./gradlew allTests + ./gradlew unitTest + ./gradlew integrationTest + ./gradlew e2eTest else - ./gradlew allTests + ./gradlew e2eTest fi working-directory: apps/user-service diff --git a/apps/user-service/build.gradle b/apps/user-service/build.gradle index 45abf367..07d5f353 100644 --- a/apps/user-service/build.gradle +++ b/apps/user-service/build.gradle @@ -100,6 +100,18 @@ tasks.named('test') { systemProperty 'spring.profiles.active', 'test-unit' } +tasks.register('integrationTest', Test) { + outputs.dir snippetsDir + useJUnitPlatform { + includeTags 'integration' + } + + systemProperty 'spring.profiles.active', 'test-integration' + + // E2E 테스트는 더 긴 시간 허용 + timeout = Duration.ofMinutes(10) +} + // E2E 테스트 전용 task 추가 tasks.register('e2eTest', Test) { outputs.dir snippetsDir diff --git a/apps/user-service/src/main/resources/application.yml b/apps/user-service/src/main/resources/application.yml index e852951b..c8314375 100644 --- a/apps/user-service/src/main/resources/application.yml +++ b/apps/user-service/src/main/resources/application.yml @@ -3,6 +3,10 @@ spring: name: mvp profiles: active: develop + test: + context: + cache: + maxSize: 1 mybatis: # Mapper XML 파일 위치 mapper-locations: classpath:mapper/**/*.xml diff --git a/apps/user-service/src/test/java/com/gltkorea/icebang/integration/tests/auth/AuthApiIntegrationTest.java b/apps/user-service/src/test/java/com/gltkorea/icebang/integration/tests/auth/AuthApiIntegrationTest.java index 676cc688..0d1e5d19 100644 --- a/apps/user-service/src/test/java/com/gltkorea/icebang/integration/tests/auth/AuthApiIntegrationTest.java +++ b/apps/user-service/src/test/java/com/gltkorea/icebang/integration/tests/auth/AuthApiIntegrationTest.java @@ -14,16 +14,16 @@ import org.junit.jupiter.api.Test; import org.springframework.http.*; import org.springframework.restdocs.payload.JsonFieldType; -import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.jdbc.Sql; +import org.springframework.transaction.annotation.Transactional; import com.epages.restdocs.apispec.ResourceSnippetParameters; import com.gltkorea.icebang.integration.setup.support.IntegrationTestSupport; -@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) @Sql( value = "classpath:sql/01-insert-internal-users.sql", - executionPhase = Sql.ExecutionPhase.BEFORE_TEST_CLASS) + executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD) +@Transactional class AuthApiIntegrationTest extends IntegrationTestSupport { @Test @DisplayName("사용자 로그인 성공") diff --git a/apps/user-service/src/test/java/com/gltkorea/icebang/integration/tests/organization/OrganizationApiIntegrationTest.java b/apps/user-service/src/test/java/com/gltkorea/icebang/integration/tests/organization/OrganizationApiIntegrationTest.java index d7306ec2..5d458146 100644 --- a/apps/user-service/src/test/java/com/gltkorea/icebang/integration/tests/organization/OrganizationApiIntegrationTest.java +++ b/apps/user-service/src/test/java/com/gltkorea/icebang/integration/tests/organization/OrganizationApiIntegrationTest.java @@ -11,19 +11,21 @@ import org.junit.jupiter.api.Test; import org.springframework.http.*; import org.springframework.restdocs.payload.JsonFieldType; -import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.jdbc.Sql; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.transaction.annotation.Transactional; import com.epages.restdocs.apispec.ResourceSnippetParameters; +import com.fasterxml.jackson.databind.JsonNode; import com.gltkorea.icebang.integration.setup.support.IntegrationTestSupport; -@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) @Sql( value = { "classpath:sql/01-insert-internal-users.sql", "classpath:sql/02-insert-external-users.sql" }, - executionPhase = Sql.ExecutionPhase.BEFORE_TEST_CLASS) + executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD) +@Transactional class OrganizationApiIntegrationTest extends IntegrationTestSupport { @Test @@ -76,8 +78,19 @@ void getOrganizations_success() throws Exception { @Test @DisplayName("조직 옵션 정보 조회 성공") void getOrganizationOptions_success() throws Exception { - // given - Long organizationId = 1L; + // given - 먼저 조직 목록을 조회해서 실제 존재하는 ID를 가져옴 + MvcResult organizationsResult = + mockMvc + .perform(get("/v0/organizations").contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andReturn(); + + String responseBody = organizationsResult.getResponse().getContentAsString(); + JsonNode jsonNode = objectMapper.readTree(responseBody); + JsonNode organizations = jsonNode.get("data"); + + // 첫 번째 조직의 ID를 가져옴 + Long organizationId = organizations.get(0).get("id").asLong(); // when & then mockMvc From 338a5a4a2267fee721d1ac6258b1e848f4cf1a62 Mon Sep 17 00:00:00 2001 From: can019 Date: Wed, 10 Sep 2025 14:03:41 +0900 Subject: [PATCH 06/12] =?UTF-8?q?chore:=20gradle=20allTests=20task=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/user-service/build.gradle | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/apps/user-service/build.gradle b/apps/user-service/build.gradle index 07d5f353..c76b49f2 100644 --- a/apps/user-service/build.gradle +++ b/apps/user-service/build.gradle @@ -91,12 +91,12 @@ ext { snippetsDir = file('build/generated-snippets') } -tasks.named('test') { +tasks.register('unitTest', Test) { outputs.dir snippetsDir useJUnitPlatform { - // 기본적으로는 e2e 태그 제외하고 실행 - excludeTags 'e2e' + includeTags 'unit' } + systemProperty 'spring.profiles.active', 'test-unit' } @@ -108,7 +108,6 @@ tasks.register('integrationTest', Test) { systemProperty 'spring.profiles.active', 'test-integration' - // E2E 테스트는 더 긴 시간 허용 timeout = Duration.ofMinutes(10) } @@ -125,12 +124,6 @@ tasks.register('e2eTest', Test) { timeout = Duration.ofMinutes(10) } -// 모든 테스트 실행 task -tasks.register('allTests', Test) { - outputs.dir snippetsDir - useJUnitPlatform() -} - // AsciiDoctor 설정 (REST Docs 문서 생성) asciidoctor { inputs.dir snippetsDir From ce4acd595d1eefa3fb1dfda7338b6e26339dfa8f Mon Sep 17 00:00:00 2001 From: can019 Date: Wed, 10 Sep 2025 14:05:01 +0900 Subject: [PATCH 07/12] =?UTF-8?q?chore:=20Ci=20(java)=20test=20=EC=88=98?= =?UTF-8?q?=ED=96=89=20=ED=95=AD=EB=AA=A9=20=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - main이 target인 경우 모든 test 수행 - 보통의 경우 unit, integration 수행 --- .github/workflows/ci-java.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci-java.yml b/.github/workflows/ci-java.yml index 459f5143..0531e57d 100644 --- a/.github/workflows/ci-java.yml +++ b/.github/workflows/ci-java.yml @@ -81,7 +81,6 @@ jobs: if [ "${{ github.base_ref }}" == "main" ]; then ./gradlew unitTest ./gradlew integrationTest - ./gradlew e2eTest else ./gradlew e2eTest fi From a1368e26b040bec3578f0fa82f3eb4c5f611cc27 Mon Sep 17 00:00:00 2001 From: can019 Date: Wed, 10 Sep 2025 14:06:00 +0900 Subject: [PATCH 08/12] =?UTF-8?q?fix:=20Main=20push=20=EC=8B=9C=20unit,=20?= =?UTF-8?q?integration=20test=20=EC=88=98=ED=96=89=20=EB=88=84=EB=9D=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci-java.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci-java.yml b/.github/workflows/ci-java.yml index 0531e57d..05006c2f 100644 --- a/.github/workflows/ci-java.yml +++ b/.github/workflows/ci-java.yml @@ -82,6 +82,8 @@ jobs: ./gradlew unitTest ./gradlew integrationTest else + ./gradlew unitTest + ./gradlew integrationTest ./gradlew e2eTest fi working-directory: apps/user-service From c624f88063582d7792810c7298ccb0ae74131577 Mon Sep 17 00:00:00 2001 From: can019 Date: Wed, 10 Sep 2025 14:21:06 +0900 Subject: [PATCH 09/12] =?UTF-8?q?chore:=20echo=EB=A1=9C=20test=20=EC=88=98?= =?UTF-8?q?=ED=96=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci-java.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci-java.yml b/.github/workflows/ci-java.yml index 05006c2f..977eb875 100644 --- a/.github/workflows/ci-java.yml +++ b/.github/workflows/ci-java.yml @@ -79,12 +79,13 @@ jobs: - name: Run Tests run: | if [ "${{ github.base_ref }}" == "main" ]; then - ./gradlew unitTest - ./gradlew integrationTest + echo ./gradlew unitTest + echo ./gradlew integrationTest + echo ./gradlew e2eTest else - ./gradlew unitTest - ./gradlew integrationTest - ./gradlew e2eTest + echo ./gradlew unitTest + echo ./gradlew integrationTest + echo ./gradlew e2eTest fi working-directory: apps/user-service From 016c2fd2e29bf90c0fbbbd50a5cdf8bd6fea9bad Mon Sep 17 00:00:00 2001 From: can019 Date: Wed, 10 Sep 2025 14:25:56 +0900 Subject: [PATCH 10/12] =?UTF-8?q?chore:=20=EC=8B=A4=ED=8C=A8=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../icebang/integration/tests/auth/AuthApiIntegrationTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/user-service/src/test/java/com/gltkorea/icebang/integration/tests/auth/AuthApiIntegrationTest.java b/apps/user-service/src/test/java/com/gltkorea/icebang/integration/tests/auth/AuthApiIntegrationTest.java index 0d1e5d19..b5cf2481 100644 --- a/apps/user-service/src/test/java/com/gltkorea/icebang/integration/tests/auth/AuthApiIntegrationTest.java +++ b/apps/user-service/src/test/java/com/gltkorea/icebang/integration/tests/auth/AuthApiIntegrationTest.java @@ -77,5 +77,6 @@ void login_success() throws Exception { .type(JsonFieldType.STRING) .description("HTTP 상태")) .build()))); + throw new RuntimeException("!"); } } From a3987bb729babce33a0a51f6003b876834bf4d1f Mon Sep 17 00:00:00 2001 From: can019 Date: Wed, 10 Sep 2025 14:27:49 +0900 Subject: [PATCH 11/12] =?UTF-8?q?chore:=20echo=20=EB=B9=84=ED=99=9C?= =?UTF-8?q?=EC=84=B1=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci-java.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci-java.yml b/.github/workflows/ci-java.yml index 977eb875..05006c2f 100644 --- a/.github/workflows/ci-java.yml +++ b/.github/workflows/ci-java.yml @@ -79,13 +79,12 @@ jobs: - name: Run Tests run: | if [ "${{ github.base_ref }}" == "main" ]; then - echo ./gradlew unitTest - echo ./gradlew integrationTest - echo ./gradlew e2eTest + ./gradlew unitTest + ./gradlew integrationTest else - echo ./gradlew unitTest - echo ./gradlew integrationTest - echo ./gradlew e2eTest + ./gradlew unitTest + ./gradlew integrationTest + ./gradlew e2eTest fi working-directory: apps/user-service From df4b1e60b26108e7aa03f90c959baa4c67a46ab6 Mon Sep 17 00:00:00 2001 From: can019 Date: Wed, 10 Sep 2025 14:31:13 +0900 Subject: [PATCH 12/12] =?UTF-8?q?chore:=20=EC=8B=A4=ED=8C=A8=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=9B=90=EB=B3=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../icebang/integration/tests/auth/AuthApiIntegrationTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/user-service/src/test/java/com/gltkorea/icebang/integration/tests/auth/AuthApiIntegrationTest.java b/apps/user-service/src/test/java/com/gltkorea/icebang/integration/tests/auth/AuthApiIntegrationTest.java index b5cf2481..0d1e5d19 100644 --- a/apps/user-service/src/test/java/com/gltkorea/icebang/integration/tests/auth/AuthApiIntegrationTest.java +++ b/apps/user-service/src/test/java/com/gltkorea/icebang/integration/tests/auth/AuthApiIntegrationTest.java @@ -77,6 +77,5 @@ void login_success() throws Exception { .type(JsonFieldType.STRING) .description("HTTP 상태")) .build()))); - throw new RuntimeException("!"); } }