From b989d5ac062264d259184f9fd493a37bef1c035d Mon Sep 17 00:00:00 2001 From: dnjstjt1297 Date: Thu, 15 May 2025 17:02:26 +0900 Subject: [PATCH 1/9] =?UTF-8?q?feat:=20=EA=B9=83=20=ED=97=88=EB=B8=8C=20?= =?UTF-8?q?=EB=A0=88=ED=8F=AC=20=EC=A1=B0=ED=9A=8C=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=B6=94=EA=B0=80=20(#40)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../conal/GithubRepoServiceTest.java | 130 ++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 src/test/java/com/specialwarriors/conal/GithubRepoServiceTest.java diff --git a/src/test/java/com/specialwarriors/conal/GithubRepoServiceTest.java b/src/test/java/com/specialwarriors/conal/GithubRepoServiceTest.java new file mode 100644 index 0000000..de4fd7a --- /dev/null +++ b/src/test/java/com/specialwarriors/conal/GithubRepoServiceTest.java @@ -0,0 +1,130 @@ +package com.specialwarriors.conal; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; + +import com.specialwarriors.conal.contributor.domain.Contributor; +import com.specialwarriors.conal.contributor.repository.ContributorRepository; +import com.specialwarriors.conal.github_repo.domain.GithubRepo; +import com.specialwarriors.conal.github_repo.dto.GithubRepoMapper; +import com.specialwarriors.conal.github_repo.dto.request.GithubRepoCreateRequest; +import com.specialwarriors.conal.github_repo.dto.response.GithubRepoCreateResponse; +import com.specialwarriors.conal.github_repo.dto.response.GithubRepoGetResponse; +import com.specialwarriors.conal.github_repo.repository.GithubRepoRepository; +import com.specialwarriors.conal.github_repo.service.GithubRepoQuery; +import com.specialwarriors.conal.github_repo.service.GithubRepoService; +import com.specialwarriors.conal.notification.domain.NotificationAgreement; +import com.specialwarriors.conal.notification.enums.NotificationType; +import com.specialwarriors.conal.notification.repository.NotificationAgreementRepository; +import com.specialwarriors.conal.user.domain.User; +import com.specialwarriors.conal.user.service.UserQuery; +import com.specialwarriors.conal.util.UrlUtil; +import java.time.LocalDate; +import java.util.List; +import java.util.Set; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +public class GithubRepoServiceTest { + + @InjectMocks + private GithubRepoService githubRepoService; + + @Mock + private NotificationAgreementRepository notificationAgreementRepository; + + @Mock + private GithubRepoRepository githubRepoRepository; + + @Mock + private ContributorRepository contributorRepository; + + @Mock + private GithubRepoQuery githubRepoQuery; + + @Mock + private UserQuery userQuery; + + @Mock + private GithubRepoMapper githubRepoMapper; + + @Mock + private GithubRepo mockRepo; + + @Mock + private List mockContributorList; + + @Mock + private User mockUser; + + @Mock + private List mockNotificationAgreements; + + @BeforeEach + void setUp() { + mockRepo = new GithubRepo("test", "https://github.com/owner/reponame", LocalDate.now()); + mockUser = new User(1, "testUser", "testurl"); + mockContributorList = List.of(new Contributor("test@gmail.com"), + new Contributor("test2@gmail.com")); + mockNotificationAgreements = List.of(new NotificationAgreement(NotificationType.VOTE), + new NotificationAgreement(NotificationType.CONTRIBUTION)); + + mockRepo.setUser(mockUser); + mockRepo.addContributors(mockContributorList); + mockRepo.assignRepoIdToNotificationAgreements(mockNotificationAgreements); + + String[] ownerAndRepo = UrlUtil.urlToOwnerAndReponame(mockRepo.getUrl()); + given(githubRepoMapper.toGithubRepoGetResponse(mockRepo, ownerAndRepo[0], + ownerAndRepo[1], 1L)).willReturn( + new GithubRepoGetResponse( + mockRepo.getUser().getId(), + mockRepo.getId(), + mockRepo.getName(), + mockRepo.getUrl(), + mockRepo.getEndDate(), + ownerAndRepo[0], + ownerAndRepo[1] + ) + ); + } + + @Test + @DisplayName("레포를 생성할 수 있다.") + void createRepo() { + //given + given(githubRepoService.createGithubRepo(1L, + new GithubRepoCreateRequest("repoName", "https://github.com/owner/reponame", + LocalDate.now(), Set.of("test@test.com")))); + + //when + GithubRepoCreateResponse result = githubRepoService.createGithubRepo(1L, + new GithubRepoCreateRequest("repoName", "https://github.com/owner/reponame", + LocalDate.now(), Set.of("test@test.com"))); + + assertThat(result.repo()).isEqualTo("repoName"); + assertThat(result.owner()).isEqualTo("owner"); + + } + + @Test + @DisplayName("레포 아이디와 유저 아이디로 깃 레포를 검색할 수 있다.") + void findRepoByUserIdAndRepositoryId() { + //given + given(githubRepoQuery.findByUserIdAndRepositoryId(1L, 1L)).willReturn(mockRepo); + + //when + GithubRepoGetResponse result = githubRepoService.getGithubRepoInfo(1L, 1L); + + // then + assertThat(result.name()).isEqualTo(mockRepo.getName()); + assertThat(result.userId()).isEqualTo(mockRepo.getUser().getId()); + assertThat(result.url()).isEqualTo(mockRepo.getUrl()); + } + +} From c82e43f4404755d74ffbb425aaa0cad189095c46 Mon Sep 17 00:00:00 2001 From: dnjstjt1297 Date: Thu, 15 May 2025 17:24:59 +0900 Subject: [PATCH 2/9] =?UTF-8?q?fix:=20=EC=8B=A4=EC=88=98=EB=A1=9C=20?= =?UTF-8?q?=EC=BB=A4=EB=B0=8B=ED=95=9C=20=ED=8C=8C=EC=9D=BC=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20(#40)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../conal/ConalApplicationTests.java | 30 ------------------- 1 file changed, 30 deletions(-) delete mode 100644 src/test/java/com/specialwarriors/conal/ConalApplicationTests.java diff --git a/src/test/java/com/specialwarriors/conal/ConalApplicationTests.java b/src/test/java/com/specialwarriors/conal/ConalApplicationTests.java deleted file mode 100644 index 41c651a..0000000 --- a/src/test/java/com/specialwarriors/conal/ConalApplicationTests.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.specialwarriors.conal; - -import com.specialwarriors.conal.common.auth.jwt.JwtTokenProvider; -import com.specialwarriors.conal.util.MailUtil; -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.bean.override.mockito.MockitoBean; -import org.springframework.web.reactive.function.client.WebClient; - -@ActiveProfiles("test") -@SpringBootTest -class ConalApplicationTests { - - @MockitoBean - private WebClient githubRevokeWebClient; - - @MockitoBean - private WebClient githubWebClient; - - @MockitoBean - private JwtTokenProvider jwtTokenProvider; - - @MockitoBean - private MailUtil mailUtil; - - @Test - void contextLoads() { - } -} From dbf5434daa4a03a4fd38e1709f77ae28e4f134c4 Mon Sep 17 00:00:00 2001 From: song hyeongyu Date: Thu, 15 May 2025 17:28:23 +0900 Subject: [PATCH 3/9] =?UTF-8?q?fix:=20=EC=9D=B4=EB=A9=94=EC=9D=BC=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?(#40)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/GithubRepoService.java | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/specialwarriors/conal/github_repo/service/GithubRepoService.java b/src/main/java/com/specialwarriors/conal/github_repo/service/GithubRepoService.java index 98bf3eb..f8e7342 100644 --- a/src/main/java/com/specialwarriors/conal/github_repo/service/GithubRepoService.java +++ b/src/main/java/com/specialwarriors/conal/github_repo/service/GithubRepoService.java @@ -74,25 +74,38 @@ private void validateCreateRequest(GithubRepoCreateRequest request) { if (request.name().isEmpty()) { throw new GeneralException(GithubRepoException.NOT_FOUND_GITHUBREPO_NAME); } + if (!GITHUB_URL_PATTERN.matcher(request.url()).matches()) { throw new GeneralException(GithubRepoException.INVALID_GITHUBREPO_URL); } - if (request.emails().isEmpty()) { + + long validEmailCount = request.emails().stream() + .filter(email -> email != null && !email.trim().isEmpty()) + .count(); + + if (validEmailCount == 0) { throw new GeneralException(GithubRepoException.NOT_FOUND_GITHUBREPO_EMAIL); } - if (request.emails().size() > 5) { + if (validEmailCount > 5) { throw new GeneralException(GithubRepoException.EXCEED_GITHUBREPO_EMAIL); } + for (String email : request.emails()) { - if (!EMAIL_PATTERN.matcher(email).matches()) { + if (email == null || email.trim().isEmpty()) { + continue; + } + + if (!EMAIL_PATTERN.matcher(email.trim()).matches()) { throw new GeneralException(GithubRepoException.INVALID_GITHUBREPO_EMAIL); } } + if (request.endDate() == null) { throw new GeneralException(GithubRepoException.INVALID_GITHUBREPO_DURATION); } } + private List createAndSaveContributors(Set emails) { List contributors = emails.stream() From 13b74be70c11e21a0ec8b511de98214e1126e991 Mon Sep 17 00:00:00 2001 From: song hyeongyu Date: Thu, 15 May 2025 17:37:12 +0900 Subject: [PATCH 4/9] =?UTF-8?q?fix:=20null=20=EC=82=AD=EC=A0=9C=20?= =?UTF-8?q?=EB=B0=8F=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95=20(#40)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../github_repo/service/GithubRepoService.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/specialwarriors/conal/github_repo/service/GithubRepoService.java b/src/main/java/com/specialwarriors/conal/github_repo/service/GithubRepoService.java index f8e7342..7288090 100644 --- a/src/main/java/com/specialwarriors/conal/github_repo/service/GithubRepoService.java +++ b/src/main/java/com/specialwarriors/conal/github_repo/service/GithubRepoService.java @@ -18,6 +18,7 @@ import com.specialwarriors.conal.user.service.UserQuery; import com.specialwarriors.conal.util.UrlUtil; import java.util.List; +import java.util.Objects; import java.util.Set; import java.util.regex.Pattern; import lombok.RequiredArgsConstructor; @@ -80,7 +81,8 @@ private void validateCreateRequest(GithubRepoCreateRequest request) { } long validEmailCount = request.emails().stream() - .filter(email -> email != null && !email.trim().isEmpty()) + .filter(Objects::nonNull) + .filter(email -> !email.trim().isEmpty()) .count(); if (validEmailCount == 0) { @@ -91,13 +93,14 @@ private void validateCreateRequest(GithubRepoCreateRequest request) { } for (String email : request.emails()) { - if (email == null || email.trim().isEmpty()) { - continue; - } - if (!EMAIL_PATTERN.matcher(email.trim()).matches()) { - throw new GeneralException(GithubRepoException.INVALID_GITHUBREPO_EMAIL); + if (Objects.nonNull(email)) { + String trimmed = email.trim(); + if (!trimmed.isEmpty() && !EMAIL_PATTERN.matcher(trimmed).matches()) { + throw new GeneralException(GithubRepoException.INVALID_GITHUBREPO_EMAIL); + } } + } if (request.endDate() == null) { From 410005f5d6e3e9357bcf34bb14461c9dd9592b00 Mon Sep 17 00:00:00 2001 From: dnjstjt1297 Date: Thu, 15 May 2025 17:51:44 +0900 Subject: [PATCH 5/9] =?UTF-8?q?fix:=20=ED=95=84=EC=9A=94=EC=97=86=EB=8A=94?= =?UTF-8?q?=20html=ED=8C=8C=EC=9D=BC=20=EC=82=AD=EC=A0=9C=20(#40)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/templates/repo/list.html | 44 --------------------- 1 file changed, 44 deletions(-) delete mode 100644 src/main/resources/templates/repo/list.html diff --git a/src/main/resources/templates/repo/list.html b/src/main/resources/templates/repo/list.html deleted file mode 100644 index 133c0fc..0000000 --- a/src/main/resources/templates/repo/list.html +++ /dev/null @@ -1,44 +0,0 @@ - - - - GitHub 저장소 목록 - - -

GitHub 저장소 목록

- -
-

-
- - - - -
- -
- -
- -
-

현재 페이지:

-
- - - \ No newline at end of file From aceaa4a4a61ef9ea2c5dfbbd1b9c19bd6d353cec Mon Sep 17 00:00:00 2001 From: dnjstjt1297 Date: Thu, 15 May 2025 17:51:57 +0900 Subject: [PATCH 6/9] =?UTF-8?q?fix:=20=EB=A0=88=ED=8F=AC=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20delete=EB=A7=A4=ED=95=91=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20(#40)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../github_repo/controller/GithubRepoController.java | 11 ++++++----- src/main/resources/templates/main/home.html | 1 + 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/specialwarriors/conal/github_repo/controller/GithubRepoController.java b/src/main/java/com/specialwarriors/conal/github_repo/controller/GithubRepoController.java index dd53e5b..37c8dc9 100644 --- a/src/main/java/com/specialwarriors/conal/github_repo/controller/GithubRepoController.java +++ b/src/main/java/com/specialwarriors/conal/github_repo/controller/GithubRepoController.java @@ -10,6 +10,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; @@ -39,7 +40,7 @@ public String showCreateForm(@SessionAttribute Long userId, Model model) { // 저장 (POST) @PostMapping public String createGitHubRepo(@SessionAttribute Long userId, - @ModelAttribute GithubRepoCreateRequest request) { + @ModelAttribute GithubRepoCreateRequest request) { GithubRepoCreateResponse response = githubRepoService.createGithubRepo(userId, request); gitHubService.updateRepoContribution(response.owner(), response.repo()).subscribe(); @@ -50,7 +51,7 @@ public String createGitHubRepo(@SessionAttribute Long userId, // 목록 조회 (GET) @GetMapping public String getGithubRepos(@SessionAttribute Long userId, - @RequestParam(defaultValue = "0") int page, Model model) { + @RequestParam(defaultValue = "0") int page, Model model) { GithubRepoPageResponse response = githubRepoService.getGithubRepoInfos(userId, page); model.addAttribute("repositories", response); @@ -62,7 +63,7 @@ public String getGithubRepos(@SessionAttribute Long userId, // 단일 조회 (GET) @GetMapping("/{repositoryId}") public String getRepositoryId(@SessionAttribute Long userId, - @PathVariable long repositoryId, Model model) { + @PathVariable long repositoryId, Model model) { GithubRepoGetResponse response = githubRepoService.getGithubRepoInfo(userId, repositoryId); model.addAttribute("repoInfo", response); @@ -70,9 +71,9 @@ public String getRepositoryId(@SessionAttribute Long userId, return "repo/detail"; } - @PostMapping("/{repositoryId}") + @DeleteMapping("/{repositoryId}") public String deleteRepository(@SessionAttribute Long userId, - @PathVariable long repositoryId) { + @PathVariable long repositoryId) { githubRepoService.deleteRepo(userId, repositoryId); diff --git a/src/main/resources/templates/main/home.html b/src/main/resources/templates/main/home.html index 1de7c61..0aa2785 100644 --- a/src/main/resources/templates/main/home.html +++ b/src/main/resources/templates/main/home.html @@ -153,6 +153,7 @@
+
From 0a268adac12ed3eb9cea3c3ef76ce6350d2f680f Mon Sep 17 00:00:00 2001 From: dnjstjt1297 Date: Fri, 16 May 2025 09:07:07 +0900 Subject: [PATCH 7/9] =?UTF-8?q?fix:=20=EC=82=AD=EC=A0=9C=20=EC=9E=98?= =?UTF-8?q?=EB=AA=BB=ED=95=9C=20=ED=8C=8C=EC=9D=BC=20=EB=8B=A4=EC=8B=9C=20?= =?UTF-8?q?=EC=97=85=EB=A1=9C=EB=93=9C=20(#40)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../conal/ConalApplicationTests.java | 30 ++++ .../conal/GithubRepoServiceTest.java | 130 ------------------ 2 files changed, 30 insertions(+), 130 deletions(-) create mode 100644 src/test/java/com/specialwarriors/conal/ConalApplicationTests.java delete mode 100644 src/test/java/com/specialwarriors/conal/GithubRepoServiceTest.java diff --git a/src/test/java/com/specialwarriors/conal/ConalApplicationTests.java b/src/test/java/com/specialwarriors/conal/ConalApplicationTests.java new file mode 100644 index 0000000..d2763a7 --- /dev/null +++ b/src/test/java/com/specialwarriors/conal/ConalApplicationTests.java @@ -0,0 +1,30 @@ +package com.specialwarriors.conal; + +import com.specialwarriors.conal.common.auth.jwt.JwtTokenProvider; +import com.specialwarriors.conal.util.MailUtil; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.web.reactive.function.client.WebClient; + +@ActiveProfiles("test") +@SpringBootTest +class ConalApplicationTests { + + @MockitoBean + private WebClient githubRevokeWebClient; + + @MockitoBean + private WebClient githubWebClient; + + @MockitoBean + private JwtTokenProvider jwtTokenProvider; + + @MockitoBean + private MailUtil mailUtil; + + @Test + void contextLoads() { + } +} \ No newline at end of file diff --git a/src/test/java/com/specialwarriors/conal/GithubRepoServiceTest.java b/src/test/java/com/specialwarriors/conal/GithubRepoServiceTest.java deleted file mode 100644 index de4fd7a..0000000 --- a/src/test/java/com/specialwarriors/conal/GithubRepoServiceTest.java +++ /dev/null @@ -1,130 +0,0 @@ -package com.specialwarriors.conal; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; - -import com.specialwarriors.conal.contributor.domain.Contributor; -import com.specialwarriors.conal.contributor.repository.ContributorRepository; -import com.specialwarriors.conal.github_repo.domain.GithubRepo; -import com.specialwarriors.conal.github_repo.dto.GithubRepoMapper; -import com.specialwarriors.conal.github_repo.dto.request.GithubRepoCreateRequest; -import com.specialwarriors.conal.github_repo.dto.response.GithubRepoCreateResponse; -import com.specialwarriors.conal.github_repo.dto.response.GithubRepoGetResponse; -import com.specialwarriors.conal.github_repo.repository.GithubRepoRepository; -import com.specialwarriors.conal.github_repo.service.GithubRepoQuery; -import com.specialwarriors.conal.github_repo.service.GithubRepoService; -import com.specialwarriors.conal.notification.domain.NotificationAgreement; -import com.specialwarriors.conal.notification.enums.NotificationType; -import com.specialwarriors.conal.notification.repository.NotificationAgreementRepository; -import com.specialwarriors.conal.user.domain.User; -import com.specialwarriors.conal.user.service.UserQuery; -import com.specialwarriors.conal.util.UrlUtil; -import java.time.LocalDate; -import java.util.List; -import java.util.Set; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -public class GithubRepoServiceTest { - - @InjectMocks - private GithubRepoService githubRepoService; - - @Mock - private NotificationAgreementRepository notificationAgreementRepository; - - @Mock - private GithubRepoRepository githubRepoRepository; - - @Mock - private ContributorRepository contributorRepository; - - @Mock - private GithubRepoQuery githubRepoQuery; - - @Mock - private UserQuery userQuery; - - @Mock - private GithubRepoMapper githubRepoMapper; - - @Mock - private GithubRepo mockRepo; - - @Mock - private List mockContributorList; - - @Mock - private User mockUser; - - @Mock - private List mockNotificationAgreements; - - @BeforeEach - void setUp() { - mockRepo = new GithubRepo("test", "https://github.com/owner/reponame", LocalDate.now()); - mockUser = new User(1, "testUser", "testurl"); - mockContributorList = List.of(new Contributor("test@gmail.com"), - new Contributor("test2@gmail.com")); - mockNotificationAgreements = List.of(new NotificationAgreement(NotificationType.VOTE), - new NotificationAgreement(NotificationType.CONTRIBUTION)); - - mockRepo.setUser(mockUser); - mockRepo.addContributors(mockContributorList); - mockRepo.assignRepoIdToNotificationAgreements(mockNotificationAgreements); - - String[] ownerAndRepo = UrlUtil.urlToOwnerAndReponame(mockRepo.getUrl()); - given(githubRepoMapper.toGithubRepoGetResponse(mockRepo, ownerAndRepo[0], - ownerAndRepo[1], 1L)).willReturn( - new GithubRepoGetResponse( - mockRepo.getUser().getId(), - mockRepo.getId(), - mockRepo.getName(), - mockRepo.getUrl(), - mockRepo.getEndDate(), - ownerAndRepo[0], - ownerAndRepo[1] - ) - ); - } - - @Test - @DisplayName("레포를 생성할 수 있다.") - void createRepo() { - //given - given(githubRepoService.createGithubRepo(1L, - new GithubRepoCreateRequest("repoName", "https://github.com/owner/reponame", - LocalDate.now(), Set.of("test@test.com")))); - - //when - GithubRepoCreateResponse result = githubRepoService.createGithubRepo(1L, - new GithubRepoCreateRequest("repoName", "https://github.com/owner/reponame", - LocalDate.now(), Set.of("test@test.com"))); - - assertThat(result.repo()).isEqualTo("repoName"); - assertThat(result.owner()).isEqualTo("owner"); - - } - - @Test - @DisplayName("레포 아이디와 유저 아이디로 깃 레포를 검색할 수 있다.") - void findRepoByUserIdAndRepositoryId() { - //given - given(githubRepoQuery.findByUserIdAndRepositoryId(1L, 1L)).willReturn(mockRepo); - - //when - GithubRepoGetResponse result = githubRepoService.getGithubRepoInfo(1L, 1L); - - // then - assertThat(result.name()).isEqualTo(mockRepo.getName()); - assertThat(result.userId()).isEqualTo(mockRepo.getUser().getId()); - assertThat(result.url()).isEqualTo(mockRepo.getUrl()); - } - -} From 3e6273945a1db0000002d77e1f2641d482eb3c04 Mon Sep 17 00:00:00 2001 From: dnjstjt1297 Date: Fri, 16 May 2025 09:13:39 +0900 Subject: [PATCH 8/9] =?UTF-8?q?fix:=20=EA=B8=B0=EC=97=AC=EB=8F=84=20?= =?UTF-8?q?=EC=82=B0=EC=A0=95=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?(#40)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../conal/github/service/GitHubService.java | 120 +++++++++--------- 1 file changed, 60 insertions(+), 60 deletions(-) diff --git a/src/main/java/com/specialwarriors/conal/github/service/GitHubService.java b/src/main/java/com/specialwarriors/conal/github/service/GitHubService.java index 8a8e9de..e32a204 100644 --- a/src/main/java/com/specialwarriors/conal/github/service/GitHubService.java +++ b/src/main/java/com/specialwarriors/conal/github/service/GitHubService.java @@ -29,86 +29,86 @@ public class GitHubService { public Mono updateRepoContribution(String owner, String repo) { return getContributors(owner, repo) - .flatMapMany(contributors -> { - String contributorKey = buildContributorsKey(owner, repo); - List logins = contributors.stream() - .map(GitHubContributor::login) - .collect(Collectors.toList()); - - return reactiveRedisTemplate.delete(contributorKey) - .thenMany(Flux.fromIterable(logins)) - .flatMap(login -> reactiveRedisTemplate.opsForList() - .rightPush(contributorKey, login)) - .then(reactiveRedisTemplate.expire(contributorKey, TTL)) - .thenMany(Flux.fromIterable(contributors)); - }) - .flatMap(contributor -> updateContributorScore(owner, repo, contributor)) - .then(); + .flatMapMany(contributors -> { + String contributorKey = buildContributorsKey(owner, repo); + List logins = contributors.stream() + .map(GitHubContributor::login) + .collect(Collectors.toList()); + + return reactiveRedisTemplate.delete(contributorKey) + .thenMany(Flux.fromIterable(logins)) + .flatMap(login -> reactiveRedisTemplate.opsForList() + .rightPush(contributorKey, login)) + .then(reactiveRedisTemplate.expire(contributorKey, TTL)) + .thenMany(Flux.fromIterable(contributors)); + }) + .flatMap(contributor -> updateContributorScore(owner, repo, contributor)) + .then(); } private Mono> getContributors(String owner, String repo) { return githubWebClient.get() - .uri("/repos/{owner}/{repo}/contributors", owner, repo) - .retrieve() - .bodyToFlux(GitHubContributor.class) - .collectList(); + .uri("/repos/{owner}/{repo}/contributors", owner, repo) + .retrieve() + .bodyToFlux(GitHubContributor.class) + .collectList(); } private Mono updateContributorScore(String owner, String repo, - GitHubContributor contributor) { + GitHubContributor contributor) { String login = contributor.login(); return Mono.zip( - getCommitCount(owner, repo, login), - getPullRequestCount(owner, repo, login), - getMergedPullRequestCount(owner, repo, login), - getIssueCount(owner, repo, login) + getCommitCount(owner, repo, login), + getPullRequestCount(owner, repo, login), + getMergedPullRequestCount(owner, repo, login), + getIssueCount(owner, repo, login) ).flatMap(tuple -> { long commit = tuple.getT1(); long pr = tuple.getT2(); long mpr = tuple.getT3(); long issue = tuple.getT4(); - long score = commit + pr + mpr + issue; + double score = commit * 0.1 + pr * 0.2 + mpr + issue * 0.2; String detailKey = buildDetailKey(owner, repo, login); return reactiveRedisTemplate.opsForHash().putAll(detailKey, Map.of( - "commit", String.valueOf(commit), - "pr", String.valueOf(pr), - "mpr", String.valueOf(mpr), - "issue", String.valueOf(issue), - "score", String.valueOf(score) - )) - .then(reactiveRedisTemplate.expire(detailKey, TTL)); + "commit", String.valueOf(commit), + "pr", String.valueOf(pr), + "mpr", String.valueOf(mpr), + "issue", String.valueOf(issue), + "score", String.valueOf(score) + )) + .then(reactiveRedisTemplate.expire(detailKey, TTL)); }).then(); } private Mono getCommitCount(String owner, String repo, String login) { return getAllCommits(owner, repo, 1) - .filter(commit -> { - Map author = (Map) commit.get("author"); + .filter(commit -> { + Map author = (Map) commit.get("author"); - return author != null && login.equalsIgnoreCase((String) author.get("login")); - }) - .count(); + return author != null && login.equalsIgnoreCase((String) author.get("login")); + }) + .count(); } private Flux getAllCommits(String owner, String repo, int page) { return githubWebClient.get() - .uri(uriBuilder -> uriBuilder - .path("/repos/{owner}/{repo}/commits") - .queryParam("per_page", PER_PAGE) - .queryParam("page", page) - .build(owner, repo)) - .retrieve() - .bodyToFlux(Map.class) - .collectList() - .flatMapMany(list -> list.size() < PER_PAGE ? Flux.fromIterable(list) - : Flux.fromIterable(list).concatWith(getAllCommits(owner, repo, page + 1))); + .uri(uriBuilder -> uriBuilder + .path("/repos/{owner}/{repo}/commits") + .queryParam("per_page", PER_PAGE) + .queryParam("page", page) + .build(owner, repo)) + .retrieve() + .bodyToFlux(Map.class) + .collectList() + .flatMapMany(list -> list.size() < PER_PAGE ? Flux.fromIterable(list) + : Flux.fromIterable(list).concatWith(getAllCommits(owner, repo, page + 1))); } private Mono getPullRequestCount(String owner, String repo, String login) { @@ -127,14 +127,14 @@ private Mono getIssueCount(String owner, String repo, String login) { } private Mono queryGithubIssueCount(String owner, String repo, String login, - String queryType) { + String queryType) { String query = String.format("repo:%s/%s+%s+author:%s", owner, repo, queryType, login); return githubWebClient.get() - .uri(uriBuilder -> uriBuilder.path("/search/issues").queryParam("q", query).build()) - .retrieve() - .bodyToMono(Map.class) - .map(map -> ((Number) map.get("total_count")).longValue()); + .uri(uriBuilder -> uriBuilder.path("/search/issues").queryParam("q", query).build()) + .retrieve() + .bodyToMono(Map.class) + .map(map -> ((Number) map.get("total_count")).longValue()); } private String buildDetailKey(String owner, String repo, String login) { @@ -154,23 +154,23 @@ public Mono> getContributorsFromRedis(String owner, String repo) { String key = "contributors:" + owner + ":" + repo; return reactiveRedisTemplate.opsForList() - .range(key, 0, -1) - .collectList(); + .range(key, 0, -1) + .collectList(); } /** * 특정 contributor에 대한 상세 점수 정보 가져오기 */ public Mono> getContributorDetailFromRedis(String owner, String repo, - String contributor) { + String contributor) { String detailKey = "detail:" + owner + ":" + repo + ":" + contributor; return reactiveRedisTemplate.opsForHash() - .entries(detailKey) - .collectMap( - e -> e.getKey().toString(), - e -> e.getValue().toString() - ); + .entries(detailKey) + .collectMap( + e -> e.getKey().toString(), + e -> e.getValue().toString() + ); } } From 065ca1d6d8fb3a594027115497d7b8e1a94de769 Mon Sep 17 00:00:00 2001 From: dnjstjt1297 Date: Fri, 16 May 2025 09:25:12 +0900 Subject: [PATCH 9/9] =?UTF-8?q?fix:=20=ED=8C=A8=ED=82=A4=EC=A7=80=20?= =?UTF-8?q?=EA=B2=BD=EB=A1=9C=20=EC=88=98=EC=A0=95=20(#40)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../conal/github_repo/service/GithubRepoService.java | 10 +++++----- .../java/com/specialwarriors/conal/util/UrlUtil.java | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/specialwarriors/conal/github_repo/service/GithubRepoService.java b/src/main/java/com/specialwarriors/conal/github_repo/service/GithubRepoService.java index 3bc00b1..880be04 100644 --- a/src/main/java/com/specialwarriors/conal/github_repo/service/GithubRepoService.java +++ b/src/main/java/com/specialwarriors/conal/github_repo/service/GithubRepoService.java @@ -11,12 +11,12 @@ import com.specialwarriors.conal.github_repo.dto.response.GithubRepoPageResponse; import com.specialwarriors.conal.github_repo.exception.GithubRepoException; import com.specialwarriors.conal.github_repo.repository.GithubRepoRepository; -import com.specialwarriors.conal.github_repo.util.UrlUtil; import com.specialwarriors.conal.notification.domain.NotificationAgreement; import com.specialwarriors.conal.notification.enums.NotificationType; import com.specialwarriors.conal.notification.repository.NotificationAgreementRepository; import com.specialwarriors.conal.user.domain.User; import com.specialwarriors.conal.user.service.UserQuery; +import com.specialwarriors.conal.util.UrlUtil; import java.util.List; import java.util.Objects; import java.util.Set; @@ -82,9 +82,9 @@ private void validateCreateRequest(GithubRepoCreateRequest request) { } long validEmailCount = request.emails().stream() - .filter(Objects::nonNull) - .filter(email -> !email.trim().isEmpty()) - .count(); + .filter(Objects::nonNull) + .filter(email -> !email.trim().isEmpty()) + .count(); if (validEmailCount == 0) { throw new GeneralException(GithubRepoException.NOT_FOUND_GITHUBREPO_EMAIL); @@ -101,7 +101,7 @@ private void validateCreateRequest(GithubRepoCreateRequest request) { throw new GeneralException(GithubRepoException.INVALID_GITHUBREPO_EMAIL); } } - + } if (request.endDate() == null) { diff --git a/src/main/java/com/specialwarriors/conal/util/UrlUtil.java b/src/main/java/com/specialwarriors/conal/util/UrlUtil.java index b851c76..f06c023 100644 --- a/src/main/java/com/specialwarriors/conal/util/UrlUtil.java +++ b/src/main/java/com/specialwarriors/conal/util/UrlUtil.java @@ -1,4 +1,4 @@ -package com.specialwarriors.conal.github_repo.util; +package com.specialwarriors.conal.util; import com.specialwarriors.conal.common.exception.GeneralException; import com.specialwarriors.conal.github_repo.exception.GithubRepoException;