Skip to content

Commit 05cf611

Browse files
test: add unit tests for log file download error scenarios and controller logic
1 parent 2cda6aa commit 05cf611

4 files changed

Lines changed: 105 additions & 14 deletions

File tree

src/main/java/com/itasocialacademy/oitassist/logfile/exceptions/LogFileNotFoundException.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@
55

66
public class LogFileNotFoundException extends NotFoundException {
77
public LogFileNotFoundException(String fileName) {
8-
super("Log file not found" + fileName, ErrorCode.LOG_FILE_NOT_FOUND);
8+
super("Log file not found " + fileName, ErrorCode.LOG_FILE_NOT_FOUND);
99
}
1010
}

src/test/java/com/itasocialacademy/oitassist/logfile/controller/LogFileControllerTest.java

Lines changed: 99 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,25 @@
11
package com.itasocialacademy.oitassist.logfile.controller;
22

33
import static org.assertj.core.api.Assertions.assertThat;
4+
import static org.hamcrest.Matchers.containsString;
45
import static org.mockito.ArgumentMatchers.any;
56
import static org.mockito.ArgumentMatchers.eq;
67
import static org.mockito.Mockito.verify;
78
import static org.mockito.Mockito.verifyNoInteractions;
89
import static org.mockito.Mockito.when;
10+
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user;
911
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
10-
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
11-
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
12-
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
12+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
1313

1414
import com.itasocialacademy.oitassist.core.web.AppExceptionHttpStatusMapper;
1515
import com.itasocialacademy.oitassist.logfile.api.LogFileResponse;
1616
import com.itasocialacademy.oitassist.logfile.api.PageResponse;
17+
import com.itasocialacademy.oitassist.logfile.dao.model.LogFileDownloadResult;
18+
import com.itasocialacademy.oitassist.logfile.exceptions.InvalidLogFileNameException;
19+
import com.itasocialacademy.oitassist.logfile.exceptions.LogFileNotFoundException;
1720
import com.itasocialacademy.oitassist.logfile.service.LogFileService;
1821
import com.itasocialacademy.oitassist.security.jwt.JwtFilter;
22+
import java.nio.charset.StandardCharsets;
1923
import java.time.Instant;
2024
import java.util.List;
2125
import org.junit.jupiter.api.Test;
@@ -28,8 +32,10 @@
2832
import org.springframework.context.annotation.ComponentScan;
2933
import org.springframework.context.annotation.FilterType;
3034
import org.springframework.context.annotation.Import;
35+
import org.springframework.core.io.ByteArrayResource;
3136
import org.springframework.data.domain.Pageable;
3237
import org.springframework.data.domain.Sort;
38+
import org.springframework.http.HttpHeaders;
3339
import org.springframework.http.MediaType;
3440
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
3541
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
@@ -45,7 +51,10 @@
4551
excludeFilters = @ComponentScan.Filter(
4652
type = FilterType.ASSIGNABLE_TYPE,
4753
classes = JwtFilter.class))
48-
@Import(LogFileControllerTest.SecurityTestConfiguration.class)
54+
@Import({
55+
LogFileControllerTest.SecurityTestConfiguration.class,
56+
AppExceptionHttpStatusMapper.class
57+
})
4958
class LogFileControllerTest {
5059

5160
private static final String ENDPOINT =
@@ -62,9 +71,6 @@ class LogFileControllerTest {
6271
@MockitoBean
6372
private LogFileService logFileService;
6473

65-
@MockitoBean
66-
private AppExceptionHttpStatusMapper appExceptionHttpStatusMapper;
67-
6874
@Test
6975
void shouldLoadControllerThroughMethodSecurityProxy() {
7076
assertThat(AopUtils.isAopProxy(logFileController))
@@ -476,4 +482,90 @@ void shouldReturnBadRequestWhenSearchNameIsMissing()
476482

477483
verifyNoInteractions(logFileService);
478484
}
485+
486+
@Test
487+
void shouldDownloadLogFile() throws Exception {
488+
byte[] fileContent =
489+
"test log content"
490+
.getBytes(StandardCharsets.UTF_8);
491+
492+
LogFileDownloadResult downloadResult =
493+
new LogFileDownloadResult(
494+
"app.log",
495+
new ByteArrayResource(fileContent));
496+
497+
when(logFileService.downloadFile("app.log"))
498+
.thenReturn(downloadResult);
499+
500+
mockMvc.perform(
501+
get("/api/v1/admin/log-files/app.log/download")
502+
.with(
503+
user("admin")
504+
.roles("ADMIN")))
505+
.andExpect(status().isOk())
506+
.andExpect(
507+
content().contentType(
508+
MediaType.APPLICATION_OCTET_STREAM))
509+
.andExpect(
510+
header().string(
511+
HttpHeaders.CONTENT_DISPOSITION,
512+
containsString("attachment")))
513+
.andExpect(
514+
header().string(
515+
HttpHeaders.CONTENT_DISPOSITION,
516+
containsString("app.log")))
517+
.andExpect(
518+
content().bytes(fileContent));
519+
520+
verify(logFileService)
521+
.downloadFile("app.log");
522+
}
523+
524+
@Test
525+
void shouldReturnBadRequestForInvalidDownloadFileName()
526+
throws Exception {
527+
528+
when(logFileService.downloadFile("app..log"))
529+
.thenThrow(
530+
new InvalidLogFileNameException());
531+
532+
mockMvc.perform(
533+
get("/api/v1/admin/log-files/app..log/download")
534+
.with(
535+
user("admin")
536+
.roles("ADMIN")))
537+
.andExpect(
538+
status().isBadRequest())
539+
.andExpect(
540+
jsonPath("$.code")
541+
.value("INVALID_LOG_FILE_NAME"));
542+
543+
verify(logFileService)
544+
.downloadFile("app..log");
545+
}
546+
547+
@Test
548+
void shouldReturnNotFoundWhenDownloadFileDoesNotExist()
549+
throws Exception {
550+
551+
when(logFileService.downloadFile("missing.log"))
552+
.thenThrow(
553+
new LogFileNotFoundException(
554+
"missing.log"));
555+
556+
mockMvc.perform(
557+
get("/api/v1/admin/log-files/missing.log/download")
558+
.with(
559+
user("admin")
560+
.roles("ADMIN")))
561+
.andExpect(
562+
status().isNotFound())
563+
.andExpect(
564+
jsonPath("$.code")
565+
.value("LOG_FILE_NOT_FOUND"));
566+
567+
verify(logFileService)
568+
.downloadFile("missing.log");
569+
}
570+
479571
}

src/test/java/com/itasocialacademy/oitassist/logfile/dao/FileSystemLogFileDaoTest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ void shouldExcludeDirectoriesMatchingSearchName()
237237
}
238238

239239
@Test
240-
void shouldThrowLogFileListingExceptionWhenDirectoryListingFails(){
240+
void shouldThrowLogFileListingExceptionWhenDirectoryListingFails() {
241241

242242
Path logDirectory = tempDirectory;
243243
String configuredLogFile =
@@ -269,7 +269,7 @@ void shouldThrowLogFileListingExceptionWhenDirectoryListingFails(){
269269
}
270270

271271
@Test
272-
void shouldThrowLogFileListingExceptionWhenReadingMetadataFails(){
272+
void shouldThrowLogFileListingExceptionWhenReadingMetadataFails() {
273273

274274
Path logDirectory = tempDirectory;
275275
Path logFile = logDirectory.resolve("app.log");
@@ -308,7 +308,7 @@ void shouldThrowLogFileListingExceptionWhenReadingMetadataFails(){
308308
}
309309

310310
@Test
311-
void shouldSkipFileWhenItDisappearsDuringDirectoryScan(){
311+
void shouldSkipFileWhenItDisappearsDuringDirectoryScan() {
312312

313313
Path logDirectory = tempDirectory;
314314
Path logFile = logDirectory.resolve("app.log");
@@ -427,7 +427,7 @@ void shouldReturnEmptyWhenDownloadPathIsDirectory()
427427
}
428428

429429
@Test
430-
void shouldReturnEmptyWhenDownloadFileIsSymbolicLink(){
430+
void shouldReturnEmptyWhenDownloadFileIsSymbolicLink() {
431431

432432
Path filePath =
433433
tempDirectory

src/test/java/com/itasocialacademy/oitassist/logfile/service/LogFileServiceImplTest.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ class LogFileServiceImplTest {
5151
@TempDir
5252
Path tempDirectory;
5353

54-
5554
private LogFileServiceImpl logFileService;
5655

5756
@BeforeEach
@@ -510,7 +509,7 @@ void shouldReturnDownloadResultForValidFileName()
510509
.isNotNull();
511510

512511
try (InputStream inputStream =
513-
result.resource().getInputStream()) {
512+
result.resource().getInputStream()) {
514513

515514
String content =
516515
new String(

0 commit comments

Comments
 (0)