Skip to content

Commit

Permalink
Refactor repository initialization in CommitInfoService
Browse files Browse the repository at this point in the history
Replaced @PostConstruct initialization with constructor-based logic to improve clarity and simplify error handling. Added logging for missing `.git` directory and updated related tests to handle uninitialized repository scenarios. Enhanced `getLatestCommitInfo` with proper error handling when the repository is null.
  • Loading branch information
LazarenkoDmytro committed Dec 17, 2024
1 parent 2d2e3e9 commit df5ff1c
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 23 deletions.
15 changes: 11 additions & 4 deletions service/src/main/java/greencity/service/CommitInfoServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;

/**
Expand All @@ -24,16 +25,18 @@ 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"))
.readEnvironment()
.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.");
}
}

Expand All @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;

Expand All @@ -51,46 +49,59 @@ class CommitInfoServiceImplTest {
private static final String COMMIT_HASH = "abc123";

@Test
void postConstructInitSuccessTest() throws Exception {
void constructorInitializationSuccessTest() throws NoSuchFieldException, IllegalAccessException {
try (MockedConstruction<FileRepositoryBuilder> 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()).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<FileRepositoryBuilder> 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<FileRepositoryBuilder> 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"));
})) {
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());
}
}

Expand Down

0 comments on commit df5ff1c

Please sign in to comment.