diff --git a/src/main/java/org/ezcode/codetest/application/submission/model/SubmissionContext.java b/src/main/java/org/ezcode/codetest/application/submission/model/SubmissionContext.java index fc523d61..aff717f7 100644 --- a/src/main/java/org/ezcode/codetest/application/submission/model/SubmissionContext.java +++ b/src/main/java/org/ezcode/codetest/application/submission/model/SubmissionContext.java @@ -134,14 +134,6 @@ public List getCategories() { return problemInfo.categories(); } - public void incrementTotalSubmissions() { - getProblem().incrementTotalSubmissions(); - } - - public void incrementCorrectSubmissions() { - getProblem().incrementCorrectSubmissions(); - } - public boolean isGitPushStatus() { return user.getGitPushStatus(); } diff --git a/src/main/java/org/ezcode/codetest/application/submission/port/GitHubClient.java b/src/main/java/org/ezcode/codetest/application/submission/port/GitHubClient.java index 76c368b2..5c6c3687 100644 --- a/src/main/java/org/ezcode/codetest/application/submission/port/GitHubClient.java +++ b/src/main/java/org/ezcode/codetest/application/submission/port/GitHubClient.java @@ -3,5 +3,8 @@ import org.ezcode.codetest.application.submission.dto.request.github.GitHubPushRequest; public interface GitHubClient { - void commitAndPushToRepo(GitHubPushRequest request); + + boolean isSourceCodeNewOrChanged(GitHubPushRequest req); + + void commitAndPushToRepo(GitHubPushRequest req); } diff --git a/src/main/java/org/ezcode/codetest/application/submission/service/GitHubPushService.java b/src/main/java/org/ezcode/codetest/application/submission/service/GitHubPushService.java index 8a281d34..6e922b83 100644 --- a/src/main/java/org/ezcode/codetest/application/submission/service/GitHubPushService.java +++ b/src/main/java/org/ezcode/codetest/application/submission/service/GitHubPushService.java @@ -28,12 +28,17 @@ public void pushSolutionToRepo(SubmissionContext ctx) { return; } - eventService.publishGitPushStatus(GitPushStatusEvent.started(ctx)); - UserGithubInfo info = userGithubService.getUserGithubInfoById(ctx.getUserId()); - try { + UserGithubInfo info = userGithubService.getUserGithubInfoById(ctx.getUserId()); String decryptedToken = aesUtil.decrypt(info.getGithubAccessToken()); - gitHubClient.commitAndPushToRepo(GitHubPushRequest.of(ctx, info, decryptedToken)); + GitHubPushRequest req = GitHubPushRequest.of(ctx, info, decryptedToken); + + if (!gitHubClient.isSourceCodeNewOrChanged(req)) { + return; + } + + eventService.publishGitPushStatus(GitPushStatusEvent.started(ctx)); + gitHubClient.commitAndPushToRepo(req); eventService.publishGitPushStatus(GitPushStatusEvent.succeeded(ctx)); } catch (Exception e) { exceptionNotifier.notifyException("commitAndPush", e); diff --git a/src/main/java/org/ezcode/codetest/domain/problem/model/entity/Testcase.java b/src/main/java/org/ezcode/codetest/domain/problem/model/entity/Testcase.java index c3f15fda..73c0485e 100644 --- a/src/main/java/org/ezcode/codetest/domain/problem/model/entity/Testcase.java +++ b/src/main/java/org/ezcode/codetest/domain/problem/model/entity/Testcase.java @@ -58,6 +58,7 @@ public String getInput() { } public String getOutput() { - return this.output.replace("\\n", "\n"); + if (output != null) return this.output.replace("\\n", "\n"); + return null; } } \ No newline at end of file diff --git a/src/main/java/org/ezcode/codetest/infrastructure/github/GitHubClientImpl.java b/src/main/java/org/ezcode/codetest/infrastructure/github/GitHubClientImpl.java index 21a6e052..e746afe9 100644 --- a/src/main/java/org/ezcode/codetest/infrastructure/github/GitHubClientImpl.java +++ b/src/main/java/org/ezcode/codetest/infrastructure/github/GitHubClientImpl.java @@ -20,13 +20,16 @@ public class GitHubClientImpl implements GitHubClient { private final GitBlobCalculator blobCalculator; @Override - public void commitAndPushToRepo(GitHubPushRequest req) { + public boolean isSourceCodeNewOrChanged(GitHubPushRequest req) { String codeBlobSha = blobCalculator.calculateBlobSha(req.sourceCode()); Optional existingSha = gitHubApiClient.fetchSourceBlobSha(req); - if (existingSha.map(codeBlobSha::equals).orElse(false)) { - return; - } + return !existingSha.map(codeBlobSha::equals).orElse(false); + } + + @Override + public void commitAndPushToRepo(GitHubPushRequest req) { + String codeBlobSha = blobCalculator.calculateBlobSha(req.sourceCode()); List> entries = templateBuilder.buildGitTreeEntries(req, codeBlobSha); diff --git a/src/test/java/org/ezcode/codetest/application/submission/GitHubPushServiceTest.java b/src/test/java/org/ezcode/codetest/application/submission/GitHubPushServiceTest.java index 271bd904..f53c6d6a 100644 --- a/src/test/java/org/ezcode/codetest/application/submission/GitHubPushServiceTest.java +++ b/src/test/java/org/ezcode/codetest/application/submission/GitHubPushServiceTest.java @@ -105,6 +105,38 @@ void noPushWhenNotPassed() { then(exceptionNotifier).should(never()).notifyException(anyString(), any()); } + @Test + @DisplayName("코드 변경 없음 -> 푸시 생략") + void noPushWhenCodeNotChanged() throws Exception { + + // given + given(ctx.isGitPushStatus()).willReturn(true); + given(ctx.isPassed()).willReturn(true); + + given(ctx.getSessionKey()).willReturn(sessionKey); + given(ctx.getUserId()).willReturn(userId); + + given(userGithubService.getUserGithubInfoById(userId)).willReturn(info); + given(info.getGithubAccessToken()).willReturn(encryptedToken); + + given(aesUtil.decrypt(encryptedToken)).willReturn(decryptedToken); + + try (var ms = mockStatic(GitHubPushRequest.class)) { + ms.when(() -> GitHubPushRequest.of(ctx, info, decryptedToken)).thenReturn(req); + + given(gitHubClient.isSourceCodeNewOrChanged(req)).willReturn(false); + + // when + gitHubPushService.pushSolutionToRepo(ctx); + + // then + then(gitHubClient).should(never()).commitAndPushToRepo(any()); + then(eventService).should(never()).publishGitPushStatus(GitPushStatusEvent.started(ctx)); + then(eventService).should(never()).publishGitPushStatus(GitPushStatusEvent.succeeded(ctx)); + then(exceptionNotifier).should(never()).notifyException(anyString(), any()); + } + } + @Test @DisplayName("활성화 & 정답 제출 -> 메서드 실행 및 시작 & 성공 이벤트 발행") void pushSuccess() throws Exception { @@ -124,6 +156,8 @@ void pushSuccess() throws Exception { try (var ms = mockStatic(GitHubPushRequest.class)) { ms.when(() -> GitHubPushRequest.of(ctx, info, decryptedToken)).thenReturn(req); + given(gitHubClient.isSourceCodeNewOrChanged(req)).willReturn(true); + gitHubPushService.pushSolutionToRepo(ctx); then(eventService).should().publishGitPushStatus(GitPushStatusEvent.started(ctx)); @@ -158,6 +192,8 @@ void pushFailure() throws Exception { ms.when(() -> GitHubPushRequest.of(ctx, info, decryptedToken)) .thenReturn(req); + given(gitHubClient.isSourceCodeNewOrChanged(req)).willReturn(true); + gitHubPushService.pushSolutionToRepo(ctx); then(eventService).should().publishGitPushStatus(GitPushStatusEvent.started(ctx)); diff --git a/src/test/java/org/ezcode/codetest/infrastructure/github/GitHubClientTest.java b/src/test/java/org/ezcode/codetest/infrastructure/github/GitHubClientTest.java index 822457dd..0c38ad59 100644 --- a/src/test/java/org/ezcode/codetest/infrastructure/github/GitHubClientTest.java +++ b/src/test/java/org/ezcode/codetest/infrastructure/github/GitHubClientTest.java @@ -56,13 +56,10 @@ void blobUnchanged_earlyReturn() { given(gitHubApiClient.fetchSourceBlobSha(request)).willReturn(Optional.of(sha)); // when - gitHubClientImpl.commitAndPushToRepo(request); + boolean result = gitHubClientImpl.isSourceCodeNewOrChanged(request); // then - then(gitHubApiClient).should(never()).fetchCommitContext(any()); - then(templateBuilder).should(never()).buildGitTreeEntries(any(), any()); - then(gitHubApiClient).should(never()).createTree(any(), any(), anyList()); - then(gitHubApiClient).should(never()).commitAndPush(any(), any(), any()); + assert !result; } @Test @@ -70,18 +67,16 @@ void blobUnchanged_earlyReturn() { void newBlobEqualsTreeBlob_earlyReturn() { // given - String oldSha = "old"; String newSha = "new"; given(request.sourceCode()).willReturn(sourceCode); given(blobCalculator.calculateBlobSha(request.sourceCode())).willReturn(newSha); - given(gitHubApiClient.fetchSourceBlobSha(request)).willReturn(Optional.of(oldSha)); - given(gitHubApiClient.fetchCommitContext(request)).willReturn(ctx); List> entries = List.of(Map.of()); given(templateBuilder.buildGitTreeEntries(request, newSha)).willReturn(entries); given(ctx.baseTreeSha()).willReturn("tree"); given(gitHubApiClient.createTree(request, "tree", entries)).willReturn("tree"); + given(gitHubApiClient.fetchCommitContext(request)).willReturn(ctx); // when gitHubClientImpl.commitAndPushToRepo(request); @@ -98,24 +93,27 @@ void newBlobEqualsTreeBlob_earlyReturn() { void blobAndTreeChanged_commitAndPush() { // given - String oldSha = "old"; String newSha = "new"; - given(blobCalculator.calculateBlobSha(request.sourceCode())).willReturn(newSha); - given(gitHubApiClient.fetchSourceBlobSha(request)).willReturn(Optional.of(oldSha)); - given(gitHubApiClient.fetchCommitContext(request)).willReturn(ctx); + String baseTree = "tree"; + String head = "head"; + String newTree = "newTree"; List> entries = List.of(Map.of()); + + given(request.sourceCode()).willReturn(sourceCode); + given(blobCalculator.calculateBlobSha(sourceCode)).willReturn(newSha); given(templateBuilder.buildGitTreeEntries(request, newSha)).willReturn(entries); - given(ctx.baseTreeSha()).willReturn("tree"); - given(ctx.headCommitSha()).willReturn("head"); - String newTree = "newTree"; - given(gitHubApiClient.createTree(request, "tree", entries)).willReturn(newTree); + given(gitHubApiClient.fetchCommitContext(request)).willReturn(ctx); + + given(ctx.baseTreeSha()).willReturn(baseTree); + given(ctx.headCommitSha()).willReturn(head); + given(gitHubApiClient.createTree(request, baseTree, entries)).willReturn(newTree); // when gitHubClientImpl.commitAndPushToRepo(request); // then - then(gitHubApiClient).should().commitAndPush(request, "head", newTree); + then(gitHubApiClient).should().commitAndPush(request, head, newTree); } }