diff --git a/pom.xml b/pom.xml
index 2d22f99..e5b130b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -29,6 +29,7 @@
17
2025.0.0
+ 1.21.4
@@ -57,11 +58,31 @@
postgresql
runtime
+
+
+ org.springframework.boot
+ spring-boot-testcontainers
+ test
+
+
+ org.testcontainers
+ junit-jupiter
+ test
+
+
+ org.testcontainers
+ postgresql
+ test
+
org.springframework.boot
spring-boot-starter-test
test
+
+ org.springframework.retry
+ spring-retry
+
com.fasterxml.jackson.core
jackson-databind
diff --git a/src/main/java/com/pledge/torgi/MainApplication.java b/src/main/java/com/pledge/torgi/MainApplication.java
index ef30111..4e03566 100644
--- a/src/main/java/com/pledge/torgi/MainApplication.java
+++ b/src/main/java/com/pledge/torgi/MainApplication.java
@@ -5,11 +5,13 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import org.springframework.retry.annotation.EnableRetry;
@SpringBootApplication
@EnableJpaRepositories
@EnableJpaAuditing
@EnableConfigurationProperties
+@EnableRetry
public class MainApplication {
public static void main(String[] args) {
SpringApplication.run(MainApplication.class, args);
diff --git a/src/main/java/com/pledge/torgi/controller/DownloadHeadlessController.java b/src/main/java/com/pledge/torgi/controller/DownloadHeadlessController.java
index 17a86b0..5ea169b 100644
--- a/src/main/java/com/pledge/torgi/controller/DownloadHeadlessController.java
+++ b/src/main/java/com/pledge/torgi/controller/DownloadHeadlessController.java
@@ -33,10 +33,13 @@ public class DownloadHeadlessController {
private final Set content = new HashSet<>();
private final TorgiEventRepository eventRepository;
private final MissedDataRepository missedDataRepository;
+ private final DownloadHeadlessService downloadHeadlessService;
- public DownloadHeadlessController(TorgiEventRepository eventRepository, MissedDataRepository missedDataRepository) {
+ public DownloadHeadlessController(TorgiEventRepository eventRepository, MissedDataRepository missedDataRepository,
+ DownloadHeadlessService downloadHeadlessService) {
this.eventRepository = eventRepository;
this.missedDataRepository = missedDataRepository;
+ this.downloadHeadlessService = downloadHeadlessService;
eventRepository.findAllByOrderByCreatedAtDesc(PageRequest.of(0, 10000)).forEach(event -> content.add(event.getKey()));
}
@@ -46,8 +49,7 @@ public class DownloadHeadlessController {
private void addNewToDiff() {
businessLogger.info("startProcessing");
- DownloadHeadlessService downloadHeadlessService = new DownloadHeadlessService();
- Map currentContent = downloadHeadlessService.downloadExcel(0, EXCEL_LINK);
+ Map currentContent = downloadHeadlessService.downloadExcel(EXCEL_LINK);
List newEvents = new ArrayList<>();
for (String key : currentContent.keySet()) {
@@ -58,11 +60,10 @@ public class DownloadHeadlessController {
}
}
eventRepository.saveAll(newEvents);
- businessLogger.info("completeProcessing");
+ businessLogger.info("completeProcessing readed from torgi = {}, added to DB = {}", currentContent.size(), newEvents.size());
}
public void sendNewContent(StartParams params, List cadastral, String email) {
- DownloadHeadlessService downloadHeadlessService = new DownloadHeadlessService();
LocalDate now = LocalDate.now();
downloadHeadlessService.createNewDocument(eventRepository, cadastral, now);
createArchive(now);
@@ -142,9 +143,8 @@ public class DownloadHeadlessController {
public void richData() {
try {
List all = missedDataRepository.findAll(PageRequest.of(0, 10)).toList();
- DownloadHeadlessService downloadHeadlessService = new DownloadHeadlessService();
for (MissedData missedCadastral : all) {
- Map currentContent = downloadHeadlessService.downloadExcel(0, String.format(CUSTOM_EXCEL_LINK, missedCadastral.getCadastral()));
+ Map currentContent = downloadHeadlessService.downloadExcel(String.format(CUSTOM_EXCEL_LINK, missedCadastral.getCadastral()));
businessLogger.info("get content by cadastral {} {}", missedCadastral.getCadastral(), currentContent.size());
if (!currentContent.isEmpty()) {
List newEvents = new ArrayList<>();
diff --git a/src/main/java/com/pledge/torgi/service/DownloadHeadlessService.java b/src/main/java/com/pledge/torgi/service/DownloadHeadlessService.java
index b2361ea..4853927 100644
--- a/src/main/java/com/pledge/torgi/service/DownloadHeadlessService.java
+++ b/src/main/java/com/pledge/torgi/service/DownloadHeadlessService.java
@@ -10,9 +10,15 @@ import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.retry.annotation.Backoff;
+import org.springframework.retry.annotation.Recover;
+import org.springframework.retry.annotation.Retryable;
+import org.springframework.stereotype.Service;
import java.io.File;
import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.UncheckedIOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.FileSystems;
@@ -23,6 +29,7 @@ import java.util.*;
import static com.pledge.torgi.utils.AppUtils.EMPTY;
import static java.util.Objects.nonNull;
+@Service
public class DownloadHeadlessService {
private final Logger logger = LoggerFactory.getLogger(DownloadHeadlessService.class);
@@ -40,54 +47,60 @@ public class DownloadHeadlessService {
private static final int COL_FINAL_PRICE = 27;
private static final int COL_FULL_INFO = 29;
- public Map downloadExcel(int retryCount, String link) {
+ @Retryable(retryFor = UncheckedIOException.class, maxAttempts = 11,
+ backoff = @Backoff(delay = 1000))
+ public Map downloadExcel(String link) {
+ HttpURLConnection connection;
+ int responseCode;
try {
- HttpURLConnection connection = (HttpURLConnection) new URL(link).openConnection();
+ connection = (HttpURLConnection) new URL(link).openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36");
connection.setRequestProperty("Accept", "application/json, text/plain, */*");
connection.setRequestProperty("Accept-Language", "ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7");
connection.setConnectTimeout(5000);
connection.setReadTimeout(10000);
- int responseCode = connection.getResponseCode();
- if (responseCode == HttpURLConnection.HTTP_OK) {
- Map data = new HashMap<>();
- Workbook wb = new XSSFWorkbook(connection.getInputStream());
- Sheet sheetWithData = wb.getSheetAt(0);
- int currentRow = 2;
- while (sheetWithData.getRow(currentRow) != null) {
- List cadastrals = extractCadastral(sheetWithData.getRow(currentRow).getCell(29).getStringCellValue());
- if (cadastrals.isEmpty()) {
- Lot extractedContent = extractDataFromRow(sheetWithData.getRow(currentRow), "");
- data.put(extractedContent.getNotice() + "_" + extractedContent.getLotNumber() + "_" + extractedContent.getStatus(), extractedContent);
- } else {
- for (String cadastral : cadastrals) {
- Lot extractedContent = extractDataFromRow(sheetWithData.getRow(currentRow), cadastral);
- data.put(extractedContent.getNotice() + "_" + extractedContent.getLotNumber() + "_" + extractedContent.getStatus() + "_" + cadastral, extractedContent);
- }
- }
-
- currentRow++;
- }
- return data;
- } else {
- logger.error("Wrong response code {} during call link {} ", responseCode, link);
- Thread.sleep(1000);
- return downloadExcel(retryCount + 1, link);
- }
- } catch (Exception e) {
+ responseCode = connection.getResponseCode();
+ } catch (IOException e) {
logger.error("Error during processing link {} ", link, e);
- if (retryCount > 10) {
- return new HashMap<>();
+ throw new UncheckedIOException(e);
+ }
+ if (responseCode != HttpURLConnection.HTTP_OK) {
+ logger.error("Wrong response code {} during call link {} ", responseCode, link);
+ throw new UncheckedIOException(new IOException("Wrong response code " + responseCode + " during call link " + link));
+ }
+ try (Workbook wb = new XSSFWorkbook(connection.getInputStream())) {
+ Map data = new HashMap<>();
+ Sheet sheetWithData = wb.getSheetAt(0);
+ int currentRow = 2;
+ while (sheetWithData.getRow(currentRow) != null) {
+ List cadastrals = extractCadastral(sheetWithData.getRow(currentRow).getCell(29).getStringCellValue());
+ if (cadastrals.isEmpty()) {
+ Lot extractedContent = extractDataFromRow(sheetWithData.getRow(currentRow), "");
+ data.put(extractedContent.getNotice() + "_" + extractedContent.getLotNumber() + "_" + extractedContent.getStatus(), extractedContent);
+ } else {
+ for (String cadastral : cadastrals) {
+ Lot extractedContent = extractDataFromRow(sheetWithData.getRow(currentRow), cadastral);
+ data.put(extractedContent.getNotice() + "_" + extractedContent.getLotNumber() + "_" + extractedContent.getStatus() + "_" + cadastral, extractedContent);
+ }
+ }
+
+ currentRow++;
}
+ return data;
+ } catch (IOException e) {
+ logger.error("Error during processing link {} ", link, e);
+ throw new UncheckedIOException(e);
+ } catch (Exception e) {
+ logger.error("Error during parsing content by link {} ", link, e);
+ throw new UncheckedIOException(new IOException("Failed to parse content by link " + link, e));
}
- try {
- Thread.sleep(1000);
- return downloadExcel(retryCount + 1, link);
- } catch (Exception ex) {
- logger.error("Exception during retry downloadExcel by link {}", link, ex);
- return new HashMap<>();
- }
+ }
+
+ @Recover
+ public Map downloadExcelFallback(Exception e, String link) {
+ logger.error("Failed to download excel by link {} after retries", link, e);
+ return new HashMap<>();
}
private Lot extractDataFromRow(Row row, String cadastral) {
diff --git a/src/test/java/com/pledge/torgi/DatabaseIntegrationTest.java b/src/test/java/com/pledge/torgi/DatabaseIntegrationTest.java
new file mode 100644
index 0000000..7a4e2e3
--- /dev/null
+++ b/src/test/java/com/pledge/torgi/DatabaseIntegrationTest.java
@@ -0,0 +1,34 @@
+package com.pledge.torgi;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.DynamicPropertyRegistry;
+import org.springframework.test.context.DynamicPropertySource;
+import org.testcontainers.containers.PostgreSQLContainer;
+import org.testcontainers.junit.jupiter.Container;
+import org.testcontainers.junit.jupiter.Testcontainers;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@SpringBootTest
+@Testcontainers
+class DatabaseIntegrationTest {
+
+ @Container
+ static PostgreSQLContainer> postgres = new PostgreSQLContainer<>("postgres:15-alpine")
+ .withDatabaseName("torgi_test")
+ .withUsername("postgres")
+ .withPassword("postgres");
+
+ @DynamicPropertySource
+ static void configureProperties(DynamicPropertyRegistry registry) {
+ registry.add("spring.datasource.url", postgres::getJdbcUrl);
+ registry.add("spring.datasource.username", postgres::getUsername);
+ registry.add("spring.datasource.password", postgres::getPassword);
+ }
+
+ @Test
+ void connectionEstablished() {
+ assertThat(postgres.isRunning()).isTrue();
+ }
+}
diff --git a/src/test/java/com/pledge/torgi/controller/DownloadHeadlessControllerTest.java b/src/test/java/com/pledge/torgi/controller/DownloadHeadlessControllerTest.java
index ac7b914..c616d22 100644
--- a/src/test/java/com/pledge/torgi/controller/DownloadHeadlessControllerTest.java
+++ b/src/test/java/com/pledge/torgi/controller/DownloadHeadlessControllerTest.java
@@ -56,6 +56,9 @@ class DownloadHeadlessControllerTest {
@Mock
private MissedDataRepository missedDataRepository;
+ @Mock
+ private DownloadHeadlessService downloadHeadlessService;
+
@BeforeEach
void setUp() {
lenient().when(eventRepository.findAllByOrderByCreatedAtDesc(any(PageRequest.class)))
@@ -73,7 +76,7 @@ class DownloadHeadlessControllerTest {
.thenReturn(page);
// when
- new DownloadHeadlessController(eventRepository, missedDataRepository);
+ new DownloadHeadlessController(eventRepository, missedDataRepository, downloadHeadlessService);
// then
verify(eventRepository).findAllByOrderByCreatedAtDesc(any(PageRequest.class));
@@ -90,14 +93,14 @@ class DownloadHeadlessControllerTest {
.thenReturn(new PageImpl<>(List.of(event1, event2)));
// when
- DownloadHeadlessController controller = new DownloadHeadlessController(eventRepository, missedDataRepository);
+ DownloadHeadlessController controller = new DownloadHeadlessController(eventRepository, missedDataRepository, downloadHeadlessService);
// then
assertThat(getContent(controller)).containsExactlyInAnyOrder("key-1", "key-2");
}
@Test
- void process_shouldSaveNewEvents() {
+ void process_shouldSaveNewEvents() throws Exception {
// given
Lot lot = new Lot();
lot.setStatus("PUBLISHED");
@@ -106,51 +109,45 @@ class DownloadHeadlessControllerTest {
lot.setCadastral(CADASTRAL);
lot.setFullInfo("Full info");
Map downloaded = Map.of(EVENT_KEY, lot);
+ when(downloadHeadlessService.downloadExcel(anyString())).thenReturn(downloaded);
+ DownloadHeadlessController controller = new DownloadHeadlessController(eventRepository, missedDataRepository, downloadHeadlessService);
- try (MockedConstruction ignored = mockConstruction(DownloadHeadlessService.class,
- (mock, context) -> when(mock.downloadExcel(anyInt(), anyString())).thenReturn(downloaded))) {
- DownloadHeadlessController controller = new DownloadHeadlessController(eventRepository, missedDataRepository);
+ // when
+ controller.process();
- // when
- controller.process();
-
- // then
- ArgumentCaptor> captor = ArgumentCaptor.forClass(List.class);
- verify(eventRepository).saveAll(captor.capture());
- List saved = captor.getValue();
- assertThat(saved).hasSize(1);
- assertThat(saved.get(0).getKey()).isEqualTo(EVENT_KEY);
- assertThat(saved.get(0).getStatus()).isEqualTo("PUBLISHED");
- assertThat(saved.get(0).getNotice()).isEqualTo("Notice1");
- assertThat(saved.get(0).getLotNumber()).isEqualTo(1);
- assertThat(saved.get(0).getCadastral()).isEqualTo(CADASTRAL);
- assertThat(saved.get(0).getFullInfo()).isEqualTo("Full info");
- assertThat(getContent(controller)).contains(EVENT_KEY);
- }
+ // then
+ ArgumentCaptor> captor = ArgumentCaptor.forClass(List.class);
+ verify(eventRepository).saveAll(captor.capture());
+ List saved = captor.getValue();
+ assertThat(saved).hasSize(1);
+ assertThat(saved.get(0).getKey()).isEqualTo(EVENT_KEY);
+ assertThat(saved.get(0).getStatus()).isEqualTo("PUBLISHED");
+ assertThat(saved.get(0).getNotice()).isEqualTo("Notice1");
+ assertThat(saved.get(0).getLotNumber()).isEqualTo(1);
+ assertThat(saved.get(0).getCadastral()).isEqualTo(CADASTRAL);
+ assertThat(saved.get(0).getFullInfo()).isEqualTo("Full info");
+ assertThat(getContent(controller)).contains(EVENT_KEY);
}
@Test
- void process_shouldSkipAlreadyKnownKeys() {
+ void process_shouldSkipAlreadyKnownKeys() throws Exception {
// given
TorgiEvent existing = new TorgiEvent();
existing.setKey(EVENT_KEY);
when(eventRepository.findAllByOrderByCreatedAtDesc(any(PageRequest.class)))
.thenReturn(new PageImpl<>(List.of(existing)));
Map downloaded = Map.of(EVENT_KEY, new Lot());
+ when(downloadHeadlessService.downloadExcel(anyString())).thenReturn(downloaded);
+ DownloadHeadlessController controller = new DownloadHeadlessController(eventRepository, missedDataRepository, downloadHeadlessService);
- try (MockedConstruction ignored = mockConstruction(DownloadHeadlessService.class,
- (mock, context) -> when(mock.downloadExcel(anyInt(), anyString())).thenReturn(downloaded))) {
- DownloadHeadlessController controller = new DownloadHeadlessController(eventRepository, missedDataRepository);
+ // when
+ controller.process();
- // when
- controller.process();
-
- // then
- ArgumentCaptor> captor = ArgumentCaptor.forClass(List.class);
- verify(eventRepository).saveAll(captor.capture());
- assertThat(captor.getValue()).isEmpty();
- assertThat(getContent(controller)).containsExactly(EVENT_KEY);
- }
+ // then
+ ArgumentCaptor> captor = ArgumentCaptor.forClass(List.class);
+ verify(eventRepository).saveAll(captor.capture());
+ assertThat(captor.getValue()).isEmpty();
+ assertThat(getContent(controller)).containsExactly(EVENT_KEY);
}
@Test
@@ -161,17 +158,15 @@ class DownloadHeadlessControllerTest {
params.setToken("token");
List cadastral = List.of(CADASTRAL);
- try (MockedConstruction serviceConstruction = mockConstruction(DownloadHeadlessService.class);
- MockedConstruction emailConstruction = mockConstruction(SendEmailService.class)) {
- DownloadHeadlessController controller = new DownloadHeadlessController(eventRepository, missedDataRepository);
+ try (MockedConstruction emailConstruction = mockConstruction(SendEmailService.class)) {
+ DownloadHeadlessController controller = new DownloadHeadlessController(eventRepository, missedDataRepository, downloadHeadlessService);
// when
controller.sendNewContent(params, cadastral, "to@example.com");
// then
- DownloadHeadlessService service = serviceConstruction.constructed().get(0);
ArgumentCaptor dateCaptor = ArgumentCaptor.forClass(LocalDate.class);
- verify(service).createNewDocument(eq(eventRepository), eq(cadastral), dateCaptor.capture());
+ verify(downloadHeadlessService).createNewDocument(eq(eventRepository), eq(cadastral), dateCaptor.capture());
LocalDate now = dateCaptor.getValue();
SendEmailService emailService = emailConstruction.constructed().get(0);
@@ -191,7 +186,7 @@ class DownloadHeadlessControllerTest {
StartParams params = new StartParams();
params.setFrom("from@example.com");
params.setToken("token");
- DownloadHeadlessController controller = new DownloadHeadlessController(eventRepository, missedDataRepository);
+ DownloadHeadlessController controller = new DownloadHeadlessController(eventRepository, missedDataRepository, downloadHeadlessService);
try (MockedConstruction ignored = mockConstruction(SendEmailService.class,
(mock, context) -> doThrow(new RuntimeException("smtp failure"))
@@ -206,7 +201,7 @@ class DownloadHeadlessControllerTest {
}
@Test
- void richData_shouldSaveNewEventsForMissedCadastral() {
+ void richData_shouldSaveNewEventsForMissedCadastral() throws Exception {
// given
MissedData missed = new MissedData();
missed.setCadastral(CADASTRAL);
@@ -219,25 +214,22 @@ class DownloadHeadlessControllerTest {
lot.setLotNumber(1);
lot.setCadastral(CADASTRAL);
Map downloaded = Map.of(EVENT_KEY, lot);
+ when(downloadHeadlessService.downloadExcel(anyString())).thenReturn(downloaded);
+ DownloadHeadlessController controller = new DownloadHeadlessController(eventRepository, missedDataRepository, downloadHeadlessService);
- try (MockedConstruction ignored = mockConstruction(DownloadHeadlessService.class,
- (mock, context) -> when(mock.downloadExcel(anyInt(), anyString())).thenReturn(downloaded))) {
- DownloadHeadlessController controller = new DownloadHeadlessController(eventRepository, missedDataRepository);
+ // when
+ controller.richData();
- // when
- controller.richData();
-
- // then
- ArgumentCaptor> captor = ArgumentCaptor.forClass(List.class);
- verify(eventRepository).saveAll(captor.capture());
- assertThat(captor.getValue()).hasSize(1);
- assertThat(captor.getValue().get(0).getKey()).isEqualTo(EVENT_KEY);
- verify(missedDataRepository).delete(missed);
- }
+ // then
+ ArgumentCaptor> captor = ArgumentCaptor.forClass(List.class);
+ verify(eventRepository).saveAll(captor.capture());
+ assertThat(captor.getValue()).hasSize(1);
+ assertThat(captor.getValue().get(0).getKey()).isEqualTo(EVENT_KEY);
+ verify(missedDataRepository).delete(missed);
}
@Test
- void richData_shouldSkipKnownEventsForCadastral() {
+ void richData_shouldSkipKnownEventsForCadastral() throws Exception {
// given
MissedData missed = new MissedData();
missed.setCadastral(CADASTRAL);
@@ -248,44 +240,38 @@ class DownloadHeadlessControllerTest {
when(eventRepository.findAllByFullInfoLikeOrderByCreatedAtDesc("%" + CADASTRAL + "%")).thenReturn(List.of(existing));
Map downloaded = Map.of(EVENT_KEY, new Lot());
+ when(downloadHeadlessService.downloadExcel(anyString())).thenReturn(downloaded);
+ DownloadHeadlessController controller = new DownloadHeadlessController(eventRepository, missedDataRepository, downloadHeadlessService);
- try (MockedConstruction ignored = mockConstruction(DownloadHeadlessService.class,
- (mock, context) -> when(mock.downloadExcel(anyInt(), anyString())).thenReturn(downloaded))) {
- DownloadHeadlessController controller = new DownloadHeadlessController(eventRepository, missedDataRepository);
+ // when
+ controller.richData();
- // when
- controller.richData();
-
- // then
- ArgumentCaptor> captor = ArgumentCaptor.forClass(List.class);
- verify(eventRepository).saveAll(captor.capture());
- assertThat(captor.getValue()).isEmpty();
- verify(missedDataRepository).delete(missed);
- }
+ // then
+ ArgumentCaptor> captor = ArgumentCaptor.forClass(List.class);
+ verify(eventRepository).saveAll(captor.capture());
+ assertThat(captor.getValue()).isEmpty();
+ verify(missedDataRepository).delete(missed);
}
@Test
- void richData_shouldDeleteMissedDataWhenDownloadedContentEmpty() {
+ void richData_shouldDeleteMissedDataWhenDownloadedContentEmpty() throws Exception {
// given
MissedData missed = new MissedData();
missed.setCadastral(CADASTRAL);
when(missedDataRepository.findAll(any(PageRequest.class))).thenReturn(new PageImpl<>(List.of(missed)));
+ when(downloadHeadlessService.downloadExcel(anyString())).thenReturn(Collections.emptyMap());
+ DownloadHeadlessController controller = new DownloadHeadlessController(eventRepository, missedDataRepository, downloadHeadlessService);
- try (MockedConstruction ignored = mockConstruction(DownloadHeadlessService.class,
- (mock, context) -> when(mock.downloadExcel(anyInt(), anyString())).thenReturn(Collections.emptyMap()))) {
- DownloadHeadlessController controller = new DownloadHeadlessController(eventRepository, missedDataRepository);
+ // when
+ controller.richData();
- // when
- controller.richData();
-
- // then
- verify(eventRepository, never()).saveAll(anyList());
- verify(missedDataRepository).delete(missed);
- }
+ // then
+ verify(eventRepository, never()).saveAll(anyList());
+ verify(missedDataRepository).delete(missed);
}
@Test
- void richData_shouldAbortProcessingOnRepositoryError() {
+ void richData_shouldAbortProcessingOnRepositoryError() throws Exception {
// given
MissedData missed = new MissedData();
missed.setCadastral(CADASTRAL);
@@ -294,25 +280,22 @@ class DownloadHeadlessControllerTest {
.thenThrow(new RuntimeException("Database error"));
Map downloaded = Map.of(EVENT_KEY, new Lot());
+ when(downloadHeadlessService.downloadExcel(anyString())).thenReturn(downloaded);
+ DownloadHeadlessController controller = new DownloadHeadlessController(eventRepository, missedDataRepository, downloadHeadlessService);
- try (MockedConstruction ignored = mockConstruction(DownloadHeadlessService.class,
- (mock, context) -> when(mock.downloadExcel(anyInt(), anyString())).thenReturn(downloaded))) {
- DownloadHeadlessController controller = new DownloadHeadlessController(eventRepository, missedDataRepository);
+ // when
+ controller.richData();
- // when
- controller.richData();
-
- // then
- verify(eventRepository, never()).saveAll(anyList());
- verify(missedDataRepository, never()).delete(any());
- }
+ // then
+ verify(eventRepository, never()).saveAll(anyList());
+ verify(missedDataRepository, never()).delete(any());
}
@Test
void richData_shouldHandleExceptionGracefully() {
// given
when(missedDataRepository.findAll(any(PageRequest.class))).thenThrow(new RuntimeException("Database error"));
- DownloadHeadlessController controller = new DownloadHeadlessController(eventRepository, missedDataRepository);
+ DownloadHeadlessController controller = new DownloadHeadlessController(eventRepository, missedDataRepository, downloadHeadlessService);
// when / then
assertThatCode(controller::richData).doesNotThrowAnyException();
@@ -325,7 +308,7 @@ class DownloadHeadlessControllerTest {
File deeper = new File(nested, "deeper");
assertThat(deeper.mkdirs()).isTrue();
writeFile(new File(deeper, "file.txt"), "content");
- DownloadHeadlessController controller = new DownloadHeadlessController(eventRepository, missedDataRepository);
+ DownloadHeadlessController controller = new DownloadHeadlessController(eventRepository, missedDataRepository, downloadHeadlessService);
// when
boolean result = invokeDeleteDirectory(controller, nested);
@@ -388,7 +371,7 @@ class DownloadHeadlessControllerTest {
File nested = new File(sourceDir, "nested");
assertThat(nested.mkdirs()).isTrue();
writeFile(new File(nested, "data.txt"), "archive-content");
- DownloadHeadlessController controller = new DownloadHeadlessController(eventRepository, missedDataRepository);
+ DownloadHeadlessController controller = new DownloadHeadlessController(eventRepository, missedDataRepository, downloadHeadlessService);
try {
// when