diff --git a/service/src/main/java/greencity/service/CommitInfoServiceImpl.java b/service/src/main/java/greencity/service/CommitInfoServiceImpl.java index 820e4cc49..039d3cf17 100644 --- a/service/src/main/java/greencity/service/CommitInfoServiceImpl.java +++ b/service/src/main/java/greencity/service/CommitInfoServiceImpl.java @@ -4,7 +4,6 @@ import greencity.dto.commitinfo.CommitInfoDto; import greencity.dto.commitinfo.CommitInfoErrorDto; import greencity.dto.commitinfo.CommitInfoSuccessDto; -import jakarta.annotation.PostConstruct; import java.io.File; import java.io.IOException; import java.time.ZoneId; @@ -13,6 +12,8 @@ import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.storage.file.FileRepositoryBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; /** @@ -24,8 +25,9 @@ public class CommitInfoServiceImpl implements CommitInfoService { private static final String COMMIT_REF = "HEAD"; - @PostConstruct - private void init() { + private static final Logger log = LoggerFactory.getLogger(CommitInfoServiceImpl.class); + + public CommitInfoServiceImpl() { try { repository = new FileRepositoryBuilder() .setGitDir(new File(".git")) @@ -33,7 +35,8 @@ private void init() { .findGitDir() .build(); } catch (IOException e) { - throw new IllegalStateException("Failed to initialize repository", e); + repository = null; + log.warn("WARNING: .git directory not found. Git commit info will be unavailable."); } } @@ -42,6 +45,10 @@ private void init() { */ @Override public CommitInfoDto getLatestCommitInfo() { + if (repository == null) { + return new CommitInfoErrorDto("Git repository not initialized. Commit info is unavailable."); + } + try (RevWalk revWalk = new RevWalk(repository)) { RevCommit latestCommit = revWalk.parseCommit(repository.resolve(COMMIT_REF)); String latestCommitHash = latestCommit.name(); diff --git a/service/src/test/java/greencity/service/CommitInfoServiceImplTest.java b/service/src/test/java/greencity/service/CommitInfoServiceImplTest.java index 7ad5261ad..495ae3a1e 100644 --- a/service/src/test/java/greencity/service/CommitInfoServiceImplTest.java +++ b/service/src/test/java/greencity/service/CommitInfoServiceImplTest.java @@ -6,7 +6,6 @@ import greencity.dto.commitinfo.CommitInfoSuccessDto; import java.io.File; import java.io.IOException; -import java.lang.reflect.InvocationTargetException; import java.time.Instant; import java.time.ZoneId; import java.time.format.DateTimeFormatter; @@ -23,11 +22,10 @@ import org.mockito.MockedConstruction; import org.mockito.junit.jupiter.MockitoExtension; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.mockito.Mockito.mockConstruction; import static org.mockito.Mockito.when; @@ -51,7 +49,7 @@ class CommitInfoServiceImplTest { private static final String COMMIT_HASH = "abc123"; @Test - void postConstructInitSuccessTest() throws Exception { + void constructorInitializationSuccessTest() throws NoSuchFieldException, IllegalAccessException { try (MockedConstruction ignored = mockConstruction(FileRepositoryBuilder.class, (builderMock, context) -> { when(builderMock.setGitDir(new File(".git"))).thenReturn(builderMock); @@ -59,22 +57,37 @@ void postConstructInitSuccessTest() throws Exception { when(builderMock.findGitDir()).thenReturn(builderMock); when(builderMock.build()).thenReturn(repository); })) { + CommitInfoServiceImpl service = new CommitInfoServiceImpl(); - var initMethod = CommitInfoServiceImpl.class.getDeclaredMethod("init"); - initMethod.setAccessible(true); + var repositoryField = CommitInfoServiceImpl.class.getDeclaredField("repository"); + repositoryField.setAccessible(true); + Repository initializedRepository = (Repository) repositoryField.get(service); - assertDoesNotThrow(() -> initMethod.invoke(commitInfoService)); + assertNotNull(initializedRepository); + } + } + + @Test + void constructorInitializationFailureTest() throws NoSuchFieldException, IllegalAccessException { + try (MockedConstruction ignored = mockConstruction(FileRepositoryBuilder.class, + (builderMock, context) -> { + when(builderMock.setGitDir(new File(".git"))).thenReturn(builderMock); + when(builderMock.readEnvironment()).thenReturn(builderMock); + when(builderMock.findGitDir()).thenReturn(builderMock); + when(builderMock.build()).thenThrow(new IOException("Repository not found")); + })) { + CommitInfoServiceImpl service = new CommitInfoServiceImpl(); var repositoryField = CommitInfoServiceImpl.class.getDeclaredField("repository"); repositoryField.setAccessible(true); - Repository initializedRepository = (Repository) repositoryField.get(commitInfoService); + Repository initializedRepository = (Repository) repositoryField.get(service); - assertNotNull(initializedRepository); + assertNull(initializedRepository); } } @Test - void postConstructInitFailureThrowsExceptionTest() { + void getLatestCommitInfoWhenRepositoryNotInitializedReturnsErrorDtoTest() { try (MockedConstruction ignored = mockConstruction(FileRepositoryBuilder.class, (builderMock, context) -> { when(builderMock.setGitDir(new File(".git"))).thenReturn(builderMock); @@ -82,15 +95,13 @@ void postConstructInitFailureThrowsExceptionTest() { when(builderMock.findGitDir()).thenReturn(builderMock); when(builderMock.build()).thenThrow(new IOException("Repository not found")); })) { - InvocationTargetException exception = assertThrows(InvocationTargetException.class, () -> { - var initMethod = CommitInfoServiceImpl.class.getDeclaredMethod("init"); - initMethod.setAccessible(true); - initMethod.invoke(commitInfoService); - }); - - Throwable cause = exception.getCause(); - assertInstanceOf(IllegalStateException.class, cause); - assertEquals("Failed to initialize repository", cause.getMessage()); + CommitInfoServiceImpl service = new CommitInfoServiceImpl(); + CommitInfoDto actualDto = service.getLatestCommitInfo(); + + assertInstanceOf(CommitInfoErrorDto.class, actualDto); + + CommitInfoErrorDto errorDto = (CommitInfoErrorDto) actualDto; + assertEquals("Git repository not initialized. Commit info is unavailable.", errorDto.getError()); } }