From 16ba02b7af63f35039d274b69ef1b8bdd203b5e5 Mon Sep 17 00:00:00 2001 From: JanooGwan Date: Wed, 1 Apr 2026 20:27:08 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20Google=20Drive=20=EA=B6=8C=ED=95=9C=20?= =?UTF-8?q?=EC=97=B0=EA=B2=B0=20URL=20=EC=A1=B0=ED=9A=8C=20API=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../oauth/GoogleDriveOAuthController.java | 13 ++++++ .../GoogleDriveAuthorizationUrlResponse.java | 15 ++++++ .../oauth/GoogleDriveOAuthControllerTest.java | 46 +++++++++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 src/main/java/gg/agit/konect/infrastructure/oauth/dto/GoogleDriveAuthorizationUrlResponse.java create mode 100644 src/test/java/gg/agit/konect/integration/infrastructure/oauth/GoogleDriveOAuthControllerTest.java diff --git a/src/main/java/gg/agit/konect/infrastructure/oauth/GoogleDriveOAuthController.java b/src/main/java/gg/agit/konect/infrastructure/oauth/GoogleDriveOAuthController.java index bb5485a4..3912c616 100644 --- a/src/main/java/gg/agit/konect/infrastructure/oauth/GoogleDriveOAuthController.java +++ b/src/main/java/gg/agit/konect/infrastructure/oauth/GoogleDriveOAuthController.java @@ -11,15 +11,27 @@ import gg.agit.konect.global.auth.annotation.PublicApi; import gg.agit.konect.global.auth.annotation.UserId; +import gg.agit.konect.infrastructure.oauth.dto.GoogleDriveAuthorizationUrlResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; @RestController @RequiredArgsConstructor @RequestMapping("/auth/oauth/google/drive") +@Tag(name = "(Normal) OAuth - Google Drive") public class GoogleDriveOAuthController { private final GoogleDriveOAuthService googleDriveOAuthService; + @Operation(summary = "Google Drive 권한 연결 URL 조회") + @GetMapping("/authorize-url") + public ResponseEntity getAuthorizationUrl(@UserId Integer userId) { + String authUrl = googleDriveOAuthService.buildAuthorizationUrl(userId); + return ResponseEntity.ok(new GoogleDriveAuthorizationUrlResponse(authUrl)); + } + + @Operation(summary = "Google Drive 권한 연결 페이지로 리다이렉트") @GetMapping("/authorize") public ResponseEntity authorize(@UserId Integer userId) { String authUrl = googleDriveOAuthService.buildAuthorizationUrl(userId); @@ -27,6 +39,7 @@ public ResponseEntity authorize(@UserId Integer userId) { } @PublicApi + @Operation(summary = "Google Drive OAuth callback 처리") @GetMapping("/callback") public ResponseEntity callback( @RequestParam("code") String code, diff --git a/src/main/java/gg/agit/konect/infrastructure/oauth/dto/GoogleDriveAuthorizationUrlResponse.java b/src/main/java/gg/agit/konect/infrastructure/oauth/dto/GoogleDriveAuthorizationUrlResponse.java new file mode 100644 index 00000000..cea6906f --- /dev/null +++ b/src/main/java/gg/agit/konect/infrastructure/oauth/dto/GoogleDriveAuthorizationUrlResponse.java @@ -0,0 +1,15 @@ +package gg.agit.konect.infrastructure.oauth.dto; + +import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; + +import io.swagger.v3.oas.annotations.media.Schema; + +public record GoogleDriveAuthorizationUrlResponse( + @Schema( + description = "Google Drive 권한 연결을 위해 브라우저를 이동시킬 authorize URL", + example = "https://accounts.google.com/o/oauth2/v2/auth?client_id=example&redirect_uri=https://api.stage.agit.gg/auth/oauth/google/drive/callback&response_type=code&scope=https://www.googleapis.com/auth/drive&access_type=offline&prompt=consent&state=example-state", + requiredMode = REQUIRED + ) + String authorizationUrl +) { +} diff --git a/src/test/java/gg/agit/konect/integration/infrastructure/oauth/GoogleDriveOAuthControllerTest.java b/src/test/java/gg/agit/konect/integration/infrastructure/oauth/GoogleDriveOAuthControllerTest.java new file mode 100644 index 00000000..503fc8db --- /dev/null +++ b/src/test/java/gg/agit/konect/integration/infrastructure/oauth/GoogleDriveOAuthControllerTest.java @@ -0,0 +1,46 @@ +package gg.agit.konect.integration.infrastructure.oauth; + +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.BDDMockito.given; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.test.context.bean.override.mockito.MockitoBean; + +import gg.agit.konect.infrastructure.oauth.GoogleDriveOAuthService; +import gg.agit.konect.support.IntegrationTestSupport; + +class GoogleDriveOAuthControllerTest extends IntegrationTestSupport { + + @MockitoBean + private GoogleDriveOAuthService googleDriveOAuthService; + + private static final Integer USER_ID = 100; + private static final String AUTHORIZATION_URL = + "https://accounts.google.com/o/oauth2/v2/auth?client_id=test-client&state=test-state"; + + @BeforeEach + void setUp() throws Exception { + mockLoginUser(USER_ID); + } + + @Nested + @DisplayName("GET /auth/oauth/google/drive/authorize-url - Google Drive 권한 연결 URL 조회") + class GetAuthorizationUrl { + + @Test + @DisplayName("로그인 사용자의 authorize URL을 JSON으로 반환한다") + void getAuthorizationUrl() throws Exception { + given(googleDriveOAuthService.buildAuthorizationUrl(eq(USER_ID))) + .willReturn(AUTHORIZATION_URL); + + performGet("/auth/oauth/google/drive/authorize-url") + .andExpect(status().isOk()) + .andExpect(jsonPath("$.authorizationUrl").value(AUTHORIZATION_URL)); + } + } +}