Added zip export
This commit is contained in:
@@ -226,7 +226,7 @@
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>${version.commons-io}</version>
|
||||
<version>2.21.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Apache POI -->
|
||||
|
||||
@@ -20,14 +20,16 @@ import jakarta.persistence.*;
|
||||
|
||||
@Entity
|
||||
@Table(name = "questionnaire_customer")
|
||||
@NamedQuery(name = QuestionnaireCustomer.FIND_ALL, query = "select c from QuestionnaireCustomer c order by c.name")
|
||||
@NamedQuery(name = QuestionnaireCustomer.FIND_BY_NUMBER, query = "select c from QuestionnaireCustomer c where c.customerNumber = :customerNumber")
|
||||
public class QuestionnaireCustomer extends AbstractDateEntity {
|
||||
private static final long serialVersionUID = 1L;
|
||||
public static final String SEQUENCE = "questionnaire_customer_seq";
|
||||
|
||||
public static final String FIND_ALL = "QuestionnaireCustomer.findAll";
|
||||
public static final String FIND_BY_NUMBER = "QuestionnaireCustomer.findByNumber";
|
||||
public static final String PARAM_NUMBER = "customerNumber";
|
||||
|
||||
|
||||
@Id
|
||||
@Column(name = "customer_id", length = 22)
|
||||
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SEQUENCE)
|
||||
|
||||
@@ -33,6 +33,14 @@ public class QueryService {
|
||||
@PersistenceContext
|
||||
private EntityManager eManager;
|
||||
|
||||
public <T> T callNamedQueryList(String namedQuery, Param... objects) {
|
||||
Query query = eManager.createNamedQuery(namedQuery);
|
||||
for (Param param : objects) {
|
||||
query.setParameter(param.name(), param.value());
|
||||
}
|
||||
return (T) query.getResultList();
|
||||
}
|
||||
|
||||
public <T> Optional<T> callNamedQuerySingleResult(String namedQuery, Param... params) {
|
||||
return singleResult(eManager.createNamedQuery(namedQuery), Arrays.asList(params));
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import java.util.*;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import jakarta.annotation.security.PermitAll;
|
||||
import jakarta.ejb.EJB;
|
||||
import jakarta.ejb.LocalBean;
|
||||
import jakarta.ejb.Stateless;
|
||||
import jakarta.inject.Inject;
|
||||
@@ -12,8 +13,10 @@ import jakarta.persistence.TypedQuery;
|
||||
import jakarta.persistence.criteria.*;
|
||||
import marketing.heyday.hartmann.fotodocumentation.core.model.Questionnaire;
|
||||
import marketing.heyday.hartmann.fotodocumentation.core.model.QuestionnaireCustomer;
|
||||
import marketing.heyday.hartmann.fotodocumentation.core.query.QueryService;
|
||||
import marketing.heyday.hartmann.fotodocumentation.core.utils.CalendarUtil;
|
||||
import marketing.heyday.hartmann.fotodocumentation.core.utils.ExcelUtils;
|
||||
import marketing.heyday.hartmann.fotodocumentation.core.utils.ZipExportUtils;
|
||||
import marketing.heyday.hartmann.fotodocumentation.rest.vo.QuestionnaireCustomerListValue;
|
||||
import marketing.heyday.hartmann.fotodocumentation.rest.vo.QuestionnaireCustomerValue;
|
||||
|
||||
@@ -32,6 +35,12 @@ import marketing.heyday.hartmann.fotodocumentation.rest.vo.QuestionnaireCustomer
|
||||
@PermitAll
|
||||
public class QuestionnaireCustomerService extends AbstractService {
|
||||
|
||||
@EJB
|
||||
private QueryService queryService;
|
||||
|
||||
@Inject
|
||||
private ZipExportUtils zipExportUtils;
|
||||
|
||||
@Inject
|
||||
private ExcelUtils excelUtils;
|
||||
|
||||
@@ -100,11 +109,16 @@ public class QuestionnaireCustomerService extends AbstractService {
|
||||
return QuestionnaireCustomerValue.builder(customer);
|
||||
}
|
||||
|
||||
public Optional<byte[]> getExport() {
|
||||
List<QuestionnaireCustomer> customers = queryService.callNamedQueryList(QuestionnaireCustomer.FIND_ALL);
|
||||
return zipExportUtils.getExport(customers);
|
||||
}
|
||||
|
||||
public Optional<byte[]> getExport(Long id, Long questionnaireId) {
|
||||
QuestionnaireCustomer customer = entityManager.find(QuestionnaireCustomer.class, id);
|
||||
if (customer == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
List<Questionnaire> questionnaires = customer.getQuestionnaires().stream().sorted((x, y) -> x.getQuestionnaireDate().compareTo(y.getQuestionnaireDate())).toList();
|
||||
|
||||
|
||||
@@ -38,7 +38,6 @@ public class ExcelUtils {
|
||||
try (ByteArrayOutputStream bos = new ByteArrayOutputStream(); XSSFWorkbook workbook = new XSSFWorkbook()) {
|
||||
|
||||
for (var questionnaire : questionnaires) {
|
||||
//TODO: set sheet name
|
||||
writeSheet(workbook, customer, questionnaire);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package marketing.heyday.hartmann.fotodocumentation.core.utils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import marketing.heyday.hartmann.fotodocumentation.core.model.Questionnaire;
|
||||
import marketing.heyday.hartmann.fotodocumentation.core.model.QuestionnaireCustomer;
|
||||
|
||||
/**
|
||||
*
|
||||
* <p>Copyright: Copyright (c) 2024</p>
|
||||
* <p>Company: heyday Marketing GmbH</p>
|
||||
* @author <a href="mailto:p.verboom@heyday.marketing">Patrick Verboom</a>
|
||||
* @version 1.0
|
||||
*
|
||||
* created: 23 Feb 2026
|
||||
*/
|
||||
|
||||
public class ZipExportUtils {
|
||||
private static final Log LOG = LogFactory.getLog(ZipExportUtils.class);
|
||||
|
||||
@Inject
|
||||
private ExcelUtils excelUtils;
|
||||
|
||||
public Optional<byte[]> getExport(List<QuestionnaireCustomer> customers) {
|
||||
if (customers.isEmpty()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
try (ZipUtils zipUtils = new ZipUtils()) {
|
||||
boolean hasContent = false;
|
||||
for (var customer : customers) {
|
||||
List<Questionnaire> questionnaires = customer.getQuestionnaires().stream().sorted((x, y) -> x.getQuestionnaireDate().compareTo(y.getQuestionnaireDate())).toList();
|
||||
var file = excelUtils.create(customer, questionnaires);
|
||||
if (file.isPresent()) {
|
||||
zipUtils.addFile(customer.getName() + ".xlsx", file.get());
|
||||
hasContent = true;
|
||||
}
|
||||
}
|
||||
if (!hasContent) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return Optional.of(zipUtils.create());
|
||||
} catch (IOException ioe) {
|
||||
LOG.error("Failed to create zip file " + ioe.getMessage(), ioe);
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package marketing.heyday.hartmann.fotodocumentation.core.utils;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
* <p>Copyright: Copyright (c) 2024</p>
|
||||
* <p>Company: heyday Marketing GmbH</p>
|
||||
* @author <a href="mailto:p.verboom@heyday.marketing">Patrick Verboom</a>
|
||||
* @version 1.0
|
||||
*
|
||||
* created: 23 Feb 2026
|
||||
*/
|
||||
|
||||
public class ZipUtils implements AutoCloseable {
|
||||
private ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
private ZipOutputStream zos = new ZipOutputStream(baos);
|
||||
|
||||
public void addFile(String name, byte[] file) throws IOException {
|
||||
ZipEntry entry = new ZipEntry(name);
|
||||
|
||||
zos.putNextEntry(entry);
|
||||
zos.write(file);
|
||||
zos.closeEntry();
|
||||
}
|
||||
|
||||
public byte[] create() throws IOException {
|
||||
zos.flush();
|
||||
zos.close();
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
zos.close();
|
||||
baos.close();
|
||||
}
|
||||
}
|
||||
@@ -65,6 +65,28 @@ public class QuestionnaireCustomerResource {
|
||||
var retVal = questionnaireCustomerService.get(id);
|
||||
return Response.ok().entity(retVal).build();
|
||||
}
|
||||
|
||||
|
||||
@GZIP
|
||||
@GET
|
||||
@Path("exportall")
|
||||
@Produces("application/zip")
|
||||
@Operation(summary = "Get Export")
|
||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved export")
|
||||
public Response doExport() {
|
||||
LOG.debug("Create export for customer ");
|
||||
Optional<byte[]> pdfOpt = questionnaireCustomerService.getExport();
|
||||
|
||||
if (pdfOpt.isEmpty()) {
|
||||
return Response.status(Status.NOT_FOUND).build();
|
||||
}
|
||||
|
||||
StreamingOutput streamingOutput = (OutputStream output) -> {
|
||||
LOG.debug("Start writing content to OutputStream available bytes");
|
||||
output.write(pdfOpt.get());
|
||||
};
|
||||
return Response.status(Status.OK).entity(streamingOutput).build();
|
||||
}
|
||||
|
||||
@GZIP
|
||||
@GET
|
||||
|
||||
@@ -3,17 +3,12 @@ package marketing.heyday.hartmann.fotodocumentation.core.utils;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.poi.xssf.usermodel.XSSFRow;
|
||||
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
@@ -32,8 +27,7 @@ import marketing.heyday.hartmann.fotodocumentation.core.model.QuestionnaireCusto
|
||||
*
|
||||
* created: 19 Feb 2026
|
||||
*/
|
||||
class ExcelUtilsTest {
|
||||
private static final Log LOG = LogFactory.getLog(ExcelUtilsTest.class);
|
||||
class ExcelUtilsTest implements TestAble {
|
||||
|
||||
private ExcelUtils excelUtils;
|
||||
|
||||
@@ -103,7 +97,7 @@ class ExcelUtilsTest {
|
||||
try (XSSFWorkbook workbook = new XSSFWorkbook(new ByteArrayInputStream(bytes))) {
|
||||
assertEquals(3, workbook.getNumberOfSheets());
|
||||
}
|
||||
|
||||
|
||||
writeToFile(bytes, "create_multipleQuestionnaires_createsSheetPerQuestionnaire.xlsx");
|
||||
}
|
||||
|
||||
@@ -190,7 +184,6 @@ class ExcelUtilsTest {
|
||||
assertNotNull(row.getCell(0));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --- create: null handling ---
|
||||
|
||||
@@ -256,15 +249,4 @@ class ExcelUtilsTest {
|
||||
.questions(QuestionnaireJsonParserTest.testJson1)
|
||||
.build();
|
||||
}
|
||||
|
||||
public void writeToFile(final byte[] content, final String fileName) {
|
||||
File file = new File("target/test/output/");
|
||||
file.mkdirs();
|
||||
try (FileOutputStream out = new FileOutputStream(new File(file, fileName))) {
|
||||
|
||||
IOUtils.write(content, out);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Error saveing pdf file", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ public class QuestionnaireJsonParserTest {
|
||||
[
|
||||
{
|
||||
"id": "answer1",
|
||||
"answer": 47,
|
||||
"answer": "47",
|
||||
"selected": true
|
||||
}
|
||||
]
|
||||
@@ -172,7 +172,7 @@ public class QuestionnaireJsonParserTest {
|
||||
{
|
||||
"id": "answer4",
|
||||
"answer": "Ontex",
|
||||
"selected": true
|
||||
"selected": false
|
||||
},
|
||||
{
|
||||
"id": "answer5",
|
||||
@@ -205,7 +205,7 @@ public class QuestionnaireJsonParserTest {
|
||||
{
|
||||
"id": "answer1",
|
||||
"answer": "HARTMANN",
|
||||
"selected": true
|
||||
"selected": false
|
||||
},
|
||||
{
|
||||
"id": "answer2",
|
||||
@@ -261,7 +261,7 @@ public class QuestionnaireJsonParserTest {
|
||||
{
|
||||
"id": "answer3",
|
||||
"answer": "Ontex",
|
||||
"selected": true
|
||||
"selected": false
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package marketing.heyday.hartmann.fotodocumentation.core.utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
* <p>Copyright: Copyright (c) 2024</p>
|
||||
* <p>Company: heyday Marketing GmbH</p>
|
||||
* @author <a href="mailto:p.verboom@heyday.marketing">Patrick Verboom</a>
|
||||
* @version 1.0
|
||||
*
|
||||
* created: 23 Feb 2026
|
||||
*/
|
||||
|
||||
public interface TestAble {
|
||||
public static final Log LOG = LogFactory.getLog(ExcelUtilsTest.class);
|
||||
|
||||
default void writeToFile(final byte[] content, final String fileName) {
|
||||
File file = new File("target/test/output/");
|
||||
file.mkdirs();
|
||||
try (FileOutputStream out = new FileOutputStream(new File(file, fileName))) {
|
||||
|
||||
IOUtils.write(content, out);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Error saveing pdf file", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
package marketing.heyday.hartmann.fotodocumentation.core.utils;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import marketing.heyday.hartmann.fotodocumentation.core.model.Questionnaire;
|
||||
import marketing.heyday.hartmann.fotodocumentation.core.model.QuestionnaireCustomer;
|
||||
|
||||
/**
|
||||
*
|
||||
* <p>Copyright: Copyright (c) 2024</p>
|
||||
* <p>Company: heyday Marketing GmbH</p>
|
||||
* @author <a href="mailto:p.verboom@heyday.marketing">Patrick Verboom</a>
|
||||
* @version 1.0
|
||||
*
|
||||
* created: 23 Feb 2026
|
||||
*/
|
||||
class ZipExportUtilsTest implements TestAble {
|
||||
|
||||
private ZipExportUtils zipExportUtils;
|
||||
private ExcelUtils excelUtils;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() throws Exception {
|
||||
zipExportUtils = new ZipExportUtils();
|
||||
excelUtils = mock(ExcelUtils.class);
|
||||
|
||||
Field field = ZipExportUtils.class.getDeclaredField("excelUtils");
|
||||
field.setAccessible(true);
|
||||
field.set(zipExportUtils, excelUtils);
|
||||
}
|
||||
|
||||
// --- getExport: empty input ---
|
||||
|
||||
@Test
|
||||
void getExport_emptyList_returnsEmpty() {
|
||||
Optional<byte[]> result = zipExportUtils.getExport(Collections.emptyList());
|
||||
|
||||
assertTrue(result.isEmpty());
|
||||
}
|
||||
|
||||
// --- getExport: single customer ---
|
||||
|
||||
@Test
|
||||
void getExport_singleCustomer_returnsPresent() {
|
||||
QuestionnaireCustomer customer = createCustomerWithQuestionnaires("Müller Apotheke", 1);
|
||||
when(excelUtils.create(any(), anyList())).thenReturn(Optional.of(new byte[] { 1, 2, 3 }));
|
||||
|
||||
Optional<byte[]> result = zipExportUtils.getExport(List.of(customer));
|
||||
|
||||
assertTrue(result.isPresent());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getExport_singleCustomer_returnsValidZip() throws IOException {
|
||||
QuestionnaireCustomer customer = createCustomerWithQuestionnaires("Müller Apotheke", 1);
|
||||
when(excelUtils.create(any(), anyList())).thenReturn(Optional.of(new byte[] { 1, 2, 3 }));
|
||||
|
||||
byte[] bytes = zipExportUtils.getExport(List.of(customer)).orElseThrow();
|
||||
|
||||
List<String> entries = getZipEntryNames(bytes);
|
||||
assertEquals(1, entries.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getExport_singleCustomer_zipEntryNamedAfterCustomer() throws IOException {
|
||||
QuestionnaireCustomer customer = createCustomerWithQuestionnaires("Müller Apotheke", 1);
|
||||
when(excelUtils.create(any(), anyList())).thenReturn(Optional.of(new byte[] { 1, 2, 3 }));
|
||||
|
||||
byte[] bytes = zipExportUtils.getExport(List.of(customer)).orElseThrow();
|
||||
|
||||
List<String> entries = getZipEntryNames(bytes);
|
||||
assertEquals("Müller Apotheke.xlsx", entries.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getExport_singleCustomer_zipEntryContainsExcelContent() throws IOException {
|
||||
byte[] excelContent = new byte[] { 10, 20, 30, 40, 50 };
|
||||
QuestionnaireCustomer customer = createCustomerWithQuestionnaires("Test", 1);
|
||||
when(excelUtils.create(any(), anyList())).thenReturn(Optional.of(excelContent));
|
||||
|
||||
byte[] bytes = zipExportUtils.getExport(List.of(customer)).orElseThrow();
|
||||
|
||||
byte[] entryContent = getZipEntryContent(bytes, "Test.xlsx");
|
||||
assertArrayEquals(excelContent, entryContent);
|
||||
}
|
||||
|
||||
// --- getExport: multiple customers ---
|
||||
|
||||
@Test
|
||||
void getExport_multipleCustomers_createsEntryPerCustomer() throws IOException {
|
||||
QuestionnaireCustomer c1 = createCustomerWithQuestionnaires("Apotheke A", 1);
|
||||
QuestionnaireCustomer c2 = createCustomerWithQuestionnaires("Apotheke B", 1);
|
||||
QuestionnaireCustomer c3 = createCustomerWithQuestionnaires("Apotheke C", 1);
|
||||
when(excelUtils.create(any(), anyList())).thenReturn(Optional.of(new byte[] { 1 }));
|
||||
|
||||
byte[] bytes = zipExportUtils.getExport(List.of(c1, c2, c3)).orElseThrow();
|
||||
|
||||
List<String> entries = getZipEntryNames(bytes);
|
||||
assertEquals(3, entries.size());
|
||||
assertTrue(entries.contains("Apotheke A.xlsx"));
|
||||
assertTrue(entries.contains("Apotheke B.xlsx"));
|
||||
assertTrue(entries.contains("Apotheke C.xlsx"));
|
||||
|
||||
writeToFile(bytes, "getExport_multipleCustomers_createsEntryPerCustomer.zip");
|
||||
}
|
||||
|
||||
// --- getExport: excel creation fails ---
|
||||
|
||||
@Test
|
||||
void getExport_excelReturnsEmpty_returnsEmpty() {
|
||||
QuestionnaireCustomer customer = createCustomerWithQuestionnaires("Test", 1);
|
||||
when(excelUtils.create(any(), anyList())).thenReturn(Optional.empty());
|
||||
|
||||
Optional<byte[]> result = zipExportUtils.getExport(List.of(customer));
|
||||
|
||||
assertTrue(result.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getExport_someExcelsFail_onlyIncludesSuccessful() throws IOException {
|
||||
QuestionnaireCustomer c1 = createCustomerWithQuestionnaires("Success", 1);
|
||||
QuestionnaireCustomer c2 = createCustomerWithQuestionnaires("Fail", 1);
|
||||
when(excelUtils.create(eq(c1), anyList())).thenReturn(Optional.of(new byte[] { 1 }));
|
||||
when(excelUtils.create(eq(c2), anyList())).thenReturn(Optional.empty());
|
||||
|
||||
byte[] bytes = zipExportUtils.getExport(List.of(c1, c2)).orElseThrow();
|
||||
|
||||
List<String> entries = getZipEntryNames(bytes);
|
||||
assertEquals(1, entries.size());
|
||||
assertEquals("Success.xlsx", entries.get(0));
|
||||
}
|
||||
|
||||
// --- getExport: questionnaire sorting ---
|
||||
|
||||
@Test
|
||||
void getExport_questionnairesPassedSortedByDate() {
|
||||
QuestionnaireCustomer customer = new QuestionnaireCustomer.Builder()
|
||||
.name("Test").customerNumber("C-001").build();
|
||||
|
||||
Questionnaire q1 = new Questionnaire.Builder().questionnaireDate(new Date(2000)).build();
|
||||
Questionnaire q2 = new Questionnaire.Builder().questionnaireDate(new Date(1000)).build();
|
||||
Questionnaire q3 = new Questionnaire.Builder().questionnaireDate(new Date(3000)).build();
|
||||
customer.getQuestionnaires().addAll(Set.of(q1, q2, q3));
|
||||
|
||||
when(excelUtils.create(any(), anyList())).thenAnswer(invocation -> {
|
||||
List<Questionnaire> questionnaires = invocation.getArgument(1);
|
||||
for (int i = 0; i < questionnaires.size() - 1; i++) {
|
||||
assertTrue(questionnaires.get(i).getQuestionnaireDate()
|
||||
.compareTo(questionnaires.get(i + 1).getQuestionnaireDate()) <= 0,
|
||||
"Questionnaires should be sorted by date");
|
||||
}
|
||||
return Optional.of(new byte[] { 1 });
|
||||
});
|
||||
|
||||
zipExportUtils.getExport(List.of(customer));
|
||||
|
||||
verify(excelUtils).create(eq(customer), anyList());
|
||||
}
|
||||
|
||||
// --- getExport: calls excelUtils correctly ---
|
||||
|
||||
@Test
|
||||
void getExport_callsExcelUtilsForEachCustomer() {
|
||||
QuestionnaireCustomer c1 = createCustomerWithQuestionnaires("A", 1);
|
||||
QuestionnaireCustomer c2 = createCustomerWithQuestionnaires("B", 1);
|
||||
when(excelUtils.create(any(), anyList())).thenReturn(Optional.of(new byte[] { 1 }));
|
||||
|
||||
zipExportUtils.getExport(List.of(c1, c2));
|
||||
|
||||
verify(excelUtils).create(eq(c1), anyList());
|
||||
verify(excelUtils).create(eq(c2), anyList());
|
||||
}
|
||||
|
||||
// --- helpers ---
|
||||
|
||||
private QuestionnaireCustomer createCustomerWithQuestionnaires(String name, int questionnaireCount) {
|
||||
QuestionnaireCustomer customer = new QuestionnaireCustomer.Builder()
|
||||
.name(name).customerNumber("C-" + name.hashCode()).build();
|
||||
|
||||
for (int i = 0; i < questionnaireCount; i++) {
|
||||
Questionnaire q = new Questionnaire.Builder()
|
||||
.questionnaireDate(new Date(1000L * (i + 1)))
|
||||
.questions("[]")
|
||||
.build();
|
||||
customer.getQuestionnaires().add(q);
|
||||
}
|
||||
return customer;
|
||||
}
|
||||
|
||||
private List<String> getZipEntryNames(byte[] zipBytes) throws IOException {
|
||||
List<String> names = new ArrayList<>();
|
||||
try (ZipInputStream zis = new ZipInputStream(new ByteArrayInputStream(zipBytes))) {
|
||||
ZipEntry entry;
|
||||
while ((entry = zis.getNextEntry()) != null) {
|
||||
names.add(entry.getName());
|
||||
}
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
private byte[] getZipEntryContent(byte[] zipBytes, String entryName) throws IOException {
|
||||
try (ZipInputStream zis = new ZipInputStream(new ByteArrayInputStream(zipBytes))) {
|
||||
ZipEntry entry;
|
||||
while ((entry = zis.getNextEntry()) != null) {
|
||||
if (entry.getName().equals(entryName)) {
|
||||
return zis.readAllBytes();
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new IOException("Entry not found: " + entryName);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user