diff --git a/src/main/java/io/carbone/CarboneServices.java b/src/main/java/io/carbone/CarboneServices.java index 30828b6..5747313 100644 --- a/src/main/java/io/carbone/CarboneServices.java +++ b/src/main/java/io/carbone/CarboneServices.java @@ -9,6 +9,8 @@ import feign.FeignException; import feign.Response; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.File; import java.io.FileInputStream; @@ -17,11 +19,11 @@ class CarboneServices implements ICarboneServices { - int err; + private static final Logger logger = LoggerFactory.getLogger(CarboneServices.class); + private final ICarboneTemplateClient carboneTemplateClient; private final ICarboneRenderClient carboneRenderClient; - private final ICarboneStatusClient carboneStatusClient ; - String reportName; + private final ICarboneStatusClient carboneStatusClient; public CarboneServices(ICarboneTemplateClient carboneTemplateClient, ICarboneRenderClient carboneRenderClient, ICarboneStatusClient carboneStatusClient) { this.carboneTemplateClient = carboneTemplateClient; @@ -43,7 +45,7 @@ public String addTemplate(byte[] templateFile) throws CarboneException { } @Override - public boolean deleteTemplate(String templateId) throws CarboneException { + public boolean deleteTemplate(String templateId) throws CarboneException { CarboneResponse carboneResponse = carboneTemplateClient.deleteTemplate(templateId); return carboneResponse.isSuccess(); } @@ -63,7 +65,7 @@ public String generateTemplateId(String path) { e.printStackTrace(); return null; } - + MessageDigest digest; try { digest = MessageDigest.getInstance("SHA-256"); @@ -71,7 +73,7 @@ public String generateTemplateId(String path) { e.printStackTrace(); return null; } - + digest.update(fileBytes); byte[] hashByte = digest.digest(); StringBuilder hexString = new StringBuilder(); @@ -86,57 +88,81 @@ public String generateTemplateId(String path) { return null; } } - public CarboneDocument render(String Json, String fileOrTemplateID) throws CarboneException - { - if (fileOrTemplateID.isEmpty()) { + + + public CarboneDocument render(String jsonData, String fileOrTemplateID) throws CarboneException { + + if (fileOrTemplateID == null || fileOrTemplateID.isEmpty()) { throw new CarboneException("Carbone SDK render error: argument is missing: file_or_template_id"); } - if (Json.isEmpty()) { + if (jsonData == null || jsonData.isEmpty()) { throw new CarboneException("Carbone SDK render error: argument is missing: json_data"); } - CarboneResponse resp = null; + + CarboneResponse renderResponse; File file = new File(fileOrTemplateID); - if (!file.exists()) { - resp = carboneRenderClient.renderReport(Json, fileOrTemplateID); - } - else { - try { + + try { + if (!file.exists()) { + renderResponse = carboneRenderClient.renderReport(jsonData, fileOrTemplateID); + } else { String templateId = generateTemplateId(fileOrTemplateID); - resp = carboneRenderClient.renderReport(Json, templateId); - } catch (CarboneException e) { - if(e.getHttpStatus() == 404) - { - try { - Path filePath = Paths.get(fileOrTemplateID); - CarboneResponse respAddTemplate = carboneTemplateClient.addTemplate(Files.readAllBytes(filePath)); - if (respAddTemplate.isSuccess()) { - resp = carboneRenderClient.renderReport(Json, respAddTemplate.getData().templateId); - } else { - throw new CarboneException("Carbone SDK render error: failed to add template"); + if (templateId == null) { + throw new CarboneException("Carbone SDK render error: failed to generate template ID"); + } + + try { + renderResponse = carboneRenderClient.renderReport(jsonData, templateId); + } catch (CarboneException e) { + if (e.getHttpStatus() == 404) { + try { + Path filePath = Paths.get(fileOrTemplateID); + byte[] fileBytes = Files.readAllBytes(filePath); + CarboneResponse addTemplateResponse = carboneTemplateClient.addTemplate(fileBytes); + + if (addTemplateResponse.isSuccess()) { + renderResponse = carboneRenderClient.renderReport(jsonData, addTemplateResponse.getData().getTemplateId()); + } else { + throw new CarboneException("Carbone SDK render error: failed to add template: " + + (addTemplateResponse.getError() != null ? addTemplateResponse.getError() : "unknown error")); + } + } catch (IOException ioErr) { + throw new CarboneException("Carbone SDK render error: failed to read template file: " + ioErr.getMessage()); } - } catch (IOException err) { - throw new CarboneException("Carbone SDK render error: failed to read template file"); + } else if (e.getHttpStatus() == 401) { + throw new CarboneException("Carbone error: invalid token"); + } else { + throw new CarboneException("Carbone SDK render error: " + e.getMessage()); } } - else{ - throw new CarboneException("Carbone SDK render error: failed to generate the template id"); - } } + + if (renderResponse == null) { + throw new CarboneException("Carbone SDK render error: no response from render service"); + } + + if (!renderResponse.isSuccess()) { + throw new CarboneException("Carbone SDK render error: " + + (renderResponse.getError() != null ? renderResponse.getError() : "render_id empty")); + } + + if (renderResponse.getData() == null || renderResponse.getData().getRenderId() == null || renderResponse.getData().getRenderId().isEmpty()) { + throw new CarboneException("Carbone SDK render error: render_id empty or invalid"); + } + + return getReport(renderResponse.getData().getRenderId()); + + } catch (CarboneException e) { + throw e; + } catch (Exception e) { + throw new CarboneException("Carbone SDK render error: unexpected error: " + e.getMessage()); } - if (resp == null) { - throw new CarboneException("Carbone SDK render error: something went wrong"); - } - if (!resp.isSuccess()) { - throw new CarboneException("Carbone SDK render error: render_id empty"); - } - return getReport(resp.getData().getRenderId()); } @Override public String renderReport(String renderData, String templateId) throws CarboneException { - if(checkPathIsAbsolute(templateId)) - { + if (checkPathIsAbsolute(templateId)) { String newTemplateId = generateTemplateId(templateId); CarboneResponse carboneResponse = carboneRenderClient.renderReport(renderData, newTemplateId); return carboneResponse.getData().getRenderId(); @@ -148,36 +174,32 @@ public String renderReport(String renderData, String templateId) throws CarboneE @Override public CarboneDocument getReport(String renderId) throws CarboneException { - CarboneDocument response = carboneRenderClient.getReport(renderId); - return response; - } + return carboneRenderClient.getReport(renderId); + } @Override - public byte[] getTemplate(String templateId) throws CarboneException - { + public byte[] getTemplate(String templateId) throws CarboneException { CarboneFileResponse response = carboneTemplateClient.getTemplate(templateId); return response.getFileContent(); } @Override - public String getStatus() throws CarboneException - { + public String getStatus() throws CarboneException { Response response = null; try { response = carboneStatusClient.getStatus(); InputStream bodyIs = response.body().asInputStream(); - String body = new String(bodyIs.readAllBytes(), StandardCharsets.UTF_8); - return body; + return new String(bodyIs.readAllBytes(), StandardCharsets.UTF_8); } catch (IOException e) { throw new CarboneException("Error reading response body"); } catch (FeignException e) { - throw new CarboneException("Feign exception occurred"); + throw new CarboneException("Carbone server error: " + e); } finally { if (response != null && response.body() != null) { try { response.body().close(); } catch (IOException e) { - e.printStackTrace(); + logger.error("Failed to close response body", e); } } } diff --git a/src/test/java/io/carbone/CarboneTest.java b/src/test/java/io/carbone/CarboneTest.java index ee81644..e617b5c 100644 --- a/src/test/java/io/carbone/CarboneTest.java +++ b/src/test/java/io/carbone/CarboneTest.java @@ -52,7 +52,7 @@ public void Test_Add_Template_With_Path() throws CarboneException, IOException, byte[] fileBytes = Files.readAllBytes(filePath); when(carboneTemplate.addTemplate(fileBytes)).thenReturn(mockedResponse); - + String resp = carboneServices.addTemplate(file); assertEquals(resp, mockedResponse.getData().templateId); @@ -73,7 +73,7 @@ public void Test_Add_Template_With_Array_Byte() throws CarboneException, IOExcep byte[] fileBytes = Files.readAllBytes(filePath); when(carboneTemplate.addTemplate(fileBytes)).thenReturn(mockedResponse); - + String resp = carboneServices.addTemplate(Files.readAllBytes(filePath)); assertEquals(resp, mockedResponse.getData().templateId); @@ -235,13 +235,13 @@ public void Test_Render_Error_From_Directory() throws CarboneException, NoSuchFi String filename = "/src/test/java/io/carbone/template.odt"; String json = "{ \"data\": { \"invoiceId\": \"FR-2023-781\", \"invoiceDate\": \"2023-01-17\", \"name\": \"Quentin Le Forestier\", \"phone\": \"+33 (0)2 23 12 33 24\", \"email\": \"tim+serverpro@carbone.io\", \"partner\": { \"name\": \"Corp\", \"phone\": \"+33 (0)6 27 89 01 23\", \"email\": \"quentinleforestierleforestier0@gmail.com\", \"vat\": \"FR45899106785\", \"siren\": \"899106785\", \"address\": { \"street\": \"12 Doctor Street\", \"postalcode\": 34920, \"city\": \"Anger\", \"country\": \"France\" } }, \"note\": \"Our team is confident that this cutting-edge technology will enhance your operations and take your business to the next level. Should you have any questions or concerns, please don't hesitate to reach out to us.\", \"subscriptionFromDate\": \"2023-02-02T07:28:05+00:00\", \"subscriptionToDate\": \"2024-04-18T07:28:05+00:00\", \"products\": [ { \"name\": \"Rackmount case (With bays for multiple 3.5-inch drives and room for the motherboard and other components.)\", \"exTaxTotal\": 1000, \"unit\": 1000, \"vat\": 20, \"qty\": 1 }, { \"name\": \"Motherboard (has the necessary number of SATA ports for your storage needs)\", \"exTaxTotal\": 150, \"unit\": 150, \"vat\": 20, \"qty\": 1 }, { \"name\": \"3.5-inch SATA hard drives (20TO)\", \"exTaxTotal\": 1000, \"unit\": 100, \"vat\": 20, \"qty\": 10 }, { \"name\": \"Processor ( A low-power consumption processor)\", \"exTaxTotal\": 100, \"unit\": 100, \"vat\": 20, \"qty\": 1 }, { \"name\": \"4GB DDR5 RAM\", \"exTaxTotal\": 120, \"unit\": 30, \"vat\": 20, \"qty\": 4 } ], \"exTaxTotal\": 1870, \"taxTotal\": 374, \"inTaxTotal\": 2244, \"amountRemaining\": 1044, \"invoicePaymentList\": [ { \"paymentDate\": \"2023-02-03T07:28:05+00:00\", \"typeSelect\": \"Paiement\", \"amount\": 1200 } ], \"payment\": { \"name\": \"SEPA Transfer\", \"typeSelect\": \"SEPAtransfer\", \"condition\": \"Upon receipt of invoice\", \"bankLabel\": \"Revolut\", \"bankBIC\": \"REVOGB2L\", \"bankIBAN\": \"FR2112739000409352423869N75\" } }, \"convertTo\" : { \"formatName\" : \"pdf\" } }"; - when(carboneRender.renderReport(json, filename)).thenThrow(new CarboneException("Carbone SDK render error: failled to generate the template id")); + when(carboneRender.renderReport(json, filename)).thenThrow(new CarboneException("Carbone SDK render error: failed to generate template ID")); try { carboneServices.render(json, filename); } catch (CarboneException e) { - assertEquals("Carbone SDK render error: failled to generate the template id", e.getMessage()); + assertEquals("Carbone SDK render error: failed to generate template ID", e.getMessage()); } - + } @Test @@ -250,7 +250,7 @@ public void Test_Render_A_Report_From_An_Null_Template_Id() throws CarboneExcept final String templateId = ""; final String json = "{ \"data\": { \"invoiceId\": \"FR-2023-781\", \"invoiceDate\": \"2023-01-17\", \"name\": \"Quentin Le Forestier\", \"phone\": \"+33 (0)2 23 12 33 24\", \"email\": \"tim+serverpro@carbone.io\", \"partner\": { \"name\": \"Corp\", \"phone\": \"+33 (0)6 27 89 01 23\", \"email\": \"quentinleforestierleforestier0@gmail.com\", \"vat\": \"FR45899106785\", \"siren\": \"899106785\", \"address\": { \"street\": \"12 Doctor Street\", \"postalcode\": 34920, \"city\": \"Anger\", \"country\": \"France\" } }, \"note\": \"Our team is confident that this cutting-edge technology will enhance your operations and take your business to the next level. Should you have any questions or concerns, please don't hesitate to reach out to us.\", \"subscriptionFromDate\": \"2023-02-02T07:28:05+00:00\", \"subscriptionToDate\": \"2024-04-18T07:28:05+00:00\", \"products\": [ { \"name\": \"Rackmount case (With bays for multiple 3.5-inch drives and room for the motherboard and other components.)\", \"exTaxTotal\": 1000, \"unit\": 1000, \"vat\": 20, \"qty\": 1 }, { \"name\": \"Motherboard (has the necessary number of SATA ports for your storage needs)\", \"exTaxTotal\": 150, \"unit\": 150, \"vat\": 20, \"qty\": 1 }, { \"name\": \"3.5-inch SATA hard drives (20TO)\", \"exTaxTotal\": 1000, \"unit\": 100, \"vat\": 20, \"qty\": 10 }, { \"name\": \"Processor ( A low-power consumption processor)\", \"exTaxTotal\": 100, \"unit\": 100, \"vat\": 20, \"qty\": 1 }, { \"name\": \"4GB DDR5 RAM\", \"exTaxTotal\": 120, \"unit\": 30, \"vat\": 20, \"qty\": 4 } ], \"exTaxTotal\": 1870, \"taxTotal\": 374, \"inTaxTotal\": 2244, \"amountRemaining\": 1044, \"invoicePaymentList\": [ { \"paymentDate\": \"2023-02-03T07:28:05+00:00\", \"typeSelect\": \"Paiement\", \"amount\": 1200 } ], \"payment\": { \"name\": \"SEPA Transfer\", \"typeSelect\": \"SEPAtransfer\", \"condition\": \"Upon receipt of invoice\", \"bankLabel\": \"Revolut\", \"bankBIC\": \"REVOGB2L\", \"bankIBAN\": \"FR2112739000409352423869N75\" } }, \"convertTo\" : { \"formatName\" : \"pdf\" } }"; final String name = "test.pdf"; - + CarboneResponse.CarboneResponseData responseData = CarboneResponse.CarboneResponseData.builder() .renderId("MTAuMjAuMTEuNDAgICAgCRLu7jNNEe84ubAa82ofaAcmVwb3J0.pdf") .build(); @@ -264,16 +264,16 @@ public void Test_Render_A_Report_From_An_Null_Template_Id() throws CarboneExcept byte[] fileBytes = Files.readAllBytes(filePath); when(carboneRender.renderReport(json, templateId)).thenReturn(mockedResponse); when(carboneRender.getReport(mockedResponse.getData().renderId)).thenReturn(new CarboneDocument(fileBytes, name)); - + try{ carboneServices.render(json, templateId); } catch(CarboneException e){ assertEquals(e.getMessage(), "Carbone SDK render error: argument is missing: file_or_template_id"); } - - - + + + } @@ -283,7 +283,7 @@ public void Test_Render_A_Report_From_An_Null_Json() throws CarboneException, IO final String templateId = "fb9241ea2218ffd8f974110e539386384620244618c2efbf182b7bd47242987B"; final String json = ""; final String name = "test.pdf"; - + CarboneResponse.CarboneResponseData responseData = CarboneResponse.CarboneResponseData.builder() .renderId("MTAuMjAuMTEuNDAgICAgCRLu7jNNEe84ubAa82ofaAcmVwb3J0.pdf") .build(); @@ -297,16 +297,16 @@ public void Test_Render_A_Report_From_An_Null_Json() throws CarboneException, IO byte[] fileBytes = Files.readAllBytes(filePath); when(carboneRender.renderReport(json, templateId)).thenReturn(mockedResponse); when(carboneRender.getReport(mockedResponse.getData().renderId)).thenReturn(new CarboneDocument(fileBytes, name)); - + try{ carboneServices.render(json, templateId); } catch(CarboneException e){ assertEquals(e.getMessage(), "Carbone SDK render error: argument is missing: json_data"); } - - - + + + } @Test @@ -315,7 +315,7 @@ public void Test_Render_A_Report_From_An_Existing_Template_Id() throws CarboneEx final String templateId = "fb9241ea2218ffd8f974110e539386384620244618c2efbf182b7bd47242987B"; final String json = "{ \"data\": { \"invoiceId\": \"FR-2023-781\", \"invoiceDate\": \"2023-01-17\", \"name\": \"Quentin Le Forestier\", \"phone\": \"+33 (0)2 23 12 33 24\", \"email\": \"tim+serverpro@carbone.io\", \"partner\": { \"name\": \"Corp\", \"phone\": \"+33 (0)6 27 89 01 23\", \"email\": \"quentinleforestierleforestier0@gmail.com\", \"vat\": \"FR45899106785\", \"siren\": \"899106785\", \"address\": { \"street\": \"12 Doctor Street\", \"postalcode\": 34920, \"city\": \"Anger\", \"country\": \"France\" } }, \"note\": \"Our team is confident that this cutting-edge technology will enhance your operations and take your business to the next level. Should you have any questions or concerns, please don't hesitate to reach out to us.\", \"subscriptionFromDate\": \"2023-02-02T07:28:05+00:00\", \"subscriptionToDate\": \"2024-04-18T07:28:05+00:00\", \"products\": [ { \"name\": \"Rackmount case (With bays for multiple 3.5-inch drives and room for the motherboard and other components.)\", \"exTaxTotal\": 1000, \"unit\": 1000, \"vat\": 20, \"qty\": 1 }, { \"name\": \"Motherboard (has the necessary number of SATA ports for your storage needs)\", \"exTaxTotal\": 150, \"unit\": 150, \"vat\": 20, \"qty\": 1 }, { \"name\": \"3.5-inch SATA hard drives (20TO)\", \"exTaxTotal\": 1000, \"unit\": 100, \"vat\": 20, \"qty\": 10 }, { \"name\": \"Processor ( A low-power consumption processor)\", \"exTaxTotal\": 100, \"unit\": 100, \"vat\": 20, \"qty\": 1 }, { \"name\": \"4GB DDR5 RAM\", \"exTaxTotal\": 120, \"unit\": 30, \"vat\": 20, \"qty\": 4 } ], \"exTaxTotal\": 1870, \"taxTotal\": 374, \"inTaxTotal\": 2244, \"amountRemaining\": 1044, \"invoicePaymentList\": [ { \"paymentDate\": \"2023-02-03T07:28:05+00:00\", \"typeSelect\": \"Paiement\", \"amount\": 1200 } ], \"payment\": { \"name\": \"SEPA Transfer\", \"typeSelect\": \"SEPAtransfer\", \"condition\": \"Upon receipt of invoice\", \"bankLabel\": \"Revolut\", \"bankBIC\": \"REVOGB2L\", \"bankIBAN\": \"FR2112739000409352423869N75\" } }, \"convertTo\" : { \"formatName\" : \"pdf\" } }"; final String name = "test.pdf"; - + CarboneResponse.CarboneResponseData responseData = CarboneResponse.CarboneResponseData.builder() .renderId("MTAuMjAuMTEuNDAgICAgCRLu7jNNEe84ubAa82ofaAcmVwb3J0.pdf") .build(); @@ -329,10 +329,10 @@ public void Test_Render_A_Report_From_An_Existing_Template_Id() throws CarboneEx byte[] fileBytes = Files.readAllBytes(filePath); when(carboneRender.renderReport(json, templateId)).thenReturn(mockedResponse); when(carboneRender.getReport(mockedResponse.getData().renderId)).thenReturn(new CarboneDocument(fileBytes, name)); - + CarboneDocument resp = carboneServices.render(json, templateId); - - + + assertArrayEquals(fileBytes, resp.getFileContent()); assertEquals(resp.getName(), name); } @@ -354,13 +354,13 @@ public void Test_Render_From_A_Template_Already_Upload() throws IOException, Car .success(true) .data(responseData) .build(); - + when(carboneRender.renderReport(json, templateId)).thenReturn(mockedResponse); when(carboneRender.getReport(mockedResponse.getData().renderId)).thenReturn(new CarboneDocument(fileBytes, name)); CarboneDocument resp = carboneServices.render(json, templateId); - - + + assertArrayEquals(fileBytes, resp.getFileContent()); assertEquals(resp.getName(), name); @@ -368,7 +368,6 @@ public void Test_Render_From_A_Template_Already_Upload() throws IOException, Car @Test public void Test_Render_Something_Wrong() throws IOException, CarboneException{ - final String json = "{ \"data\": { \"invoiceId\": \"FR-2023-781\", \"invoiceDate\": \"2023-01-17\", \"name\": \"Quentin Le Forestier\", \"phone\": \"+33 (0)2 23 12 33 24\", \"email\": \"tim+serverpro@carbone.io\", \"partner\": { \"name\": \"Corp\", \"phone\": \"+33 (0)6 27 89 01 23\", \"email\": \"quentinleforestierleforestier0@gmail.com\", \"vat\": \"FR45899106785\", \"siren\": \"899106785\", \"address\": { \"street\": \"12 Doctor Street\", \"postalcode\": 34920, \"city\": \"Anger\", \"country\": \"France\" } }, \"note\": \"Our team is confident that this cutting-edge technology will enhance your operations and take your business to the next level. Should you have any questions or concerns, please don't hesitate to reach out to us.\", \"subscriptionFromDate\": \"2023-02-02T07:28:05+00:00\", \"subscriptionToDate\": \"2024-04-18T07:28:05+00:00\", \"products\": [ { \"name\": \"Rackmount case (With bays for multiple 3.5-inch drives and room for the motherboard and other components.)\", \"exTaxTotal\": 1000, \"unit\": 1000, \"vat\": 20, \"qty\": 1 }, { \"name\": \"Motherboard (has the necessary number of SATA ports for your storage needs)\", \"exTaxTotal\": 150, \"unit\": 150, \"vat\": 20, \"qty\": 1 }, { \"name\": \"3.5-inch SATA hard drives (20TO)\", \"exTaxTotal\": 1000, \"unit\": 100, \"vat\": 20, \"qty\": 10 }, { \"name\": \"Processor ( A low-power consumption processor)\", \"exTaxTotal\": 100, \"unit\": 100, \"vat\": 20, \"qty\": 1 }, { \"name\": \"4GB DDR5 RAM\", \"exTaxTotal\": 120, \"unit\": 30, \"vat\": 20, \"qty\": 4 } ], \"exTaxTotal\": 1870, \"taxTotal\": 374, \"inTaxTotal\": 2244, \"amountRemaining\": 1044, \"invoicePaymentList\": [ { \"paymentDate\": \"2023-02-03T07:28:05+00:00\", \"typeSelect\": \"Paiement\", \"amount\": 1200 } ], \"payment\": { \"name\": \"SEPA Transfer\", \"typeSelect\": \"SEPAtransfer\", \"condition\": \"Upon receipt of invoice\", \"bankLabel\": \"Revolut\", \"bankBIC\": \"REVOGB2L\", \"bankIBAN\": \"FR2112739000409352423869N75\" } }, \"convertTo\" : { \"formatName\" : \"pdf\" } }"; final String name = "test.pdf"; @@ -376,7 +375,7 @@ public void Test_Render_Something_Wrong() throws IOException, CarboneException{ Path filePath = Paths.get(directory, filename); byte[] fileBytes = Files.readAllBytes(filePath); - + CarboneResponse.CarboneResponseData responseData = CarboneResponse.CarboneResponseData.builder() .renderId("MTAuMjAuMTEuNDAgICAgCRLu7jNNEe84ubAa82ofaAcmVwb3J0.pdf") .build(); @@ -384,14 +383,14 @@ public void Test_Render_Something_Wrong() throws IOException, CarboneException{ .success(true) .data(responseData) .build(); - + when(carboneRender.renderReport(json, directory + filename)).thenReturn(mockedResponse); when(carboneRender.getReport(mockedResponse.getData().renderId)).thenReturn(new CarboneDocument(fileBytes, name)); try{ carboneServices.render(json, directory + filename); } catch(CarboneException e){ - assertEquals(e.getMessage(), "Carbone SDK render error: something went wrong"); + assertEquals(e.getMessage(), "Carbone SDK render error: no response from render service"); } } @@ -413,7 +412,7 @@ public void Test_Render_From_A_Generate_Template_Id() throws IOException, Carbon .success(true) .data(responseDataRender) .build(); - + CarboneResponse.CarboneResponseData responseData = CarboneResponse.CarboneResponseData.builder() .templateId(templateId) .build(); @@ -428,18 +427,75 @@ public void Test_Render_From_A_Generate_Template_Id() throws IOException, Carbon .carboneResponse(mocked) .httpStatus(404) .build(); - + when(carboneRender.renderReport(json, templateId)).thenThrow(mockException).thenReturn(mockedResponseRender); - + when(carboneTemplate.addTemplate(fileBytes)).thenReturn(mockedResponse); when(carboneRender.getReport(mockedResponseRender.getData().renderId)).thenReturn(new CarboneDocument(fileBytes, name)); - + CarboneDocument resp = carboneServices.render(json, filename); - - assertArrayEquals(fileBytes, resp.getFileContent()); - assertEquals(resp.getName(), name); - + assertEquals(name, resp.getName()); + + } + + @Test + public void Test_Render_With_Response_No_Data() throws CarboneException, IOException { + final String templateId = "fb9241ea2218ffd8f974110e539386384620244618c2efbf182b7bd47242987B"; + final String json = "{ \"data\": { \"invoiceId\": \"FR-2023-781\", \"invoiceDate\": \"2023-01-17\", \"name\": \"Quentin Le Forestier\", \"phone\": \"+33 (0)2 23 12 33 24\", \"email\": \"tim+serverpro@carbone.io\", \"partner\": { \"name\": \"Corp\", \"phone\": \"+33 (0)6 27 89 01 23\", \"email\": \"quentinleforestierleforestier0@gmail.com\", \"vat\": \"FR45899106785\", \"siren\": \"899106785\", \"address\": { \"street\": \"12 Doctor Street\", \"postalcode\": 34920, \"city\": \"Anger\", \"country\": \"France\" } }, \"note\": \"Our team is confident that this cutting-edge technology will enhance your operations and take your business to the next level. Should you have any questions or concerns, please don't hesitate to reach out to us.\", \"subscriptionFromDate\": \"2023-02-02T07:28:05+00:00\", \"subscriptionToDate\": \"2024-04-18T07:28:05+00:00\", \"products\": [ { \"name\": \"Rackmount case (With bays for multiple 3.5-inch drives and room for the motherboard and other components.)\", \"exTaxTotal\": 1000, \"unit\": 1000, \"vat\": 20, \"qty\": 1 }, { \"name\": \"Motherboard (has the necessary number of SATA ports for your storage needs)\", \"exTaxTotal\": 150, \"unit\": 150, \"vat\": 20, \"qty\": 1 }, { \"name\": \"3.5-inch SATA hard drives (20TO)\", \"exTaxTotal\": 1000, \"unit\": 100, \"vat\": 20, \"qty\": 10 }, { \"name\": \"Processor ( A low-power consumption processor)\", \"exTaxTotal\": 100, \"unit\": 100, \"vat\": 20, \"qty\": 1 }, { \"name\": \"4GB DDR5 RAM\", \"exTaxTotal\": 120, \"unit\": 30, \"vat\": 20, \"qty\": 4 } ], \"exTaxTotal\": 1870, \"taxTotal\": 374, \"inTaxTotal\": 2244, \"amountRemaining\": 1044, \"invoicePaymentList\": [ { \"paymentDate\": \"2023-02-03T07:28:05+00:00\", \"typeSelect\": \"Paiement\", \"amount\": 1200 } ], \"payment\": { \"name\": \"SEPA Transfer\", \"typeSelect\": \"SEPAtransfer\", \"condition\": \"Upon receipt of invoice\", \"bankLabel\": \"Revolut\", \"bankBIC\": \"REVOGB2L\", \"bankIBAN\": \"FR2112739000409352423869N75\" } }, \"convertTo\" : { \"formatName\" : \"pdf\" } }"; + + + CarboneResponse mockedResponse = CarboneResponse.builder() + .success(true) + .data(null) + .build(); + + when(carboneRender.renderReport(json, templateId)).thenReturn(mockedResponse); + + try { + carboneServices.render(json, templateId); + assertEquals(true, false, "Should have thrown an exception"); + } catch (CarboneException e) { + assertEquals("Carbone SDK render error: render_id empty or invalid", e.getMessage()); + } + } + + @Test + public void Test_Render_With_Response_No_RenderId() throws CarboneException, IOException { + final String templateId = "fb9241ea2218ffd8f974110e539386384620244618c2efbf182b7bd47242987B"; + final String json = "{ \"data\": { \"invoiceId\": \"FR-2023-781\", \"invoiceDate\": \"2023-01-17\", \"name\": \"Quentin Le Forestier\", \"phone\": \"+33 (0)2 23 12 33 24\", \"email\": \"tim+serverpro@carbone.io\", \"partner\": { \"name\": \"Corp\", \"phone\": \"+33 (0)6 27 89 01 23\", \"email\": \"quentinleforestierleforestier0@gmail.com\", \"vat\": \"FR45899106785\", \"siren\": \"899106785\", \"address\": { \"street\": \"12 Doctor Street\", \"postalcode\": 34920, \"city\": \"Anger\", \"country\": \"France\" } }, \"note\": \"Our team is confident that this cutting-edge technology will enhance your operations and take your business to the next level. Should you have any questions or concerns, please don't hesitate to reach out to us.\", \"subscriptionFromDate\": \"2023-02-02T07:28:05+00:00\", \"subscriptionToDate\": \"2024-04-18T07:28:05+00:00\", \"products\": [ { \"name\": \"Rackmount case (With bays for multiple 3.5-inch drives and room for the motherboard and other components.)\", \"exTaxTotal\": 1000, \"unit\": 1000, \"vat\": 20, \"qty\": 1 }, { \"name\": \"Motherboard (has the necessary number of SATA ports for your storage needs)\", \"exTaxTotal\": 150, \"unit\": 150, \"vat\": 20, \"qty\": 1 }, { \"name\": \"3.5-inch SATA hard drives (20TO)\", \"exTaxTotal\": 1000, \"unit\": 100, \"vat\": 20, \"qty\": 10 }, { \"name\": \"Processor ( A low-power consumption processor)\", \"exTaxTotal\": 100, \"unit\": 100, \"vat\": 20, \"qty\": 1 }, { \"name\": \"4GB DDR5 RAM\", \"exTaxTotal\": 120, \"unit\": 30, \"vat\": 20, \"qty\": 4 } ], \"exTaxTotal\": 1870, \"taxTotal\": 374, \"inTaxTotal\": 2244, \"amountRemaining\": 1044, \"invoicePaymentList\": [ { \"paymentDate\": \"2023-02-03T07:28:05+00:00\", \"typeSelect\": \"Paiement\", \"amount\": 1200 } ], \"payment\": { \"name\": \"SEPA Transfer\", \"typeSelect\": \"SEPAtransfer\", \"condition\": \"Upon receipt of invoice\", \"bankLabel\": \"Revolut\", \"bankBIC\": \"REVOGB2L\", \"bankIBAN\": \"FR2112739000409352423869N75\" } }, \"convertTo\" : { \"formatName\" : \"pdf\" } }"; + + CarboneResponse.CarboneResponseData responseData = CarboneResponse.CarboneResponseData.builder() + .renderId(null) + .build(); + CarboneResponse mockedResponse = CarboneResponse.builder() + .success(true) + .data(responseData) + .build(); + + when(carboneRender.renderReport(json, templateId)).thenReturn(mockedResponse); + + try { + carboneServices.render(json, templateId); + assertEquals(true, false, "Should have thrown an exception"); + } catch (CarboneException e) { + assertEquals("Carbone SDK render error: render_id empty or invalid", e.getMessage()); + } + } + + @Test + public void Test_Render_With_Unexpected_Exception() throws CarboneException, IOException { + final String templateId = "fb9241ea2218ffd8f974110e539386384620244618c2efbf182b7bd47242987B"; + final String json = "{ \"data\": { \"invoiceId\": \"FR-2023-781\", \"invoiceDate\": \"2023-01-17\", \"name\": \"Quentin Le Forestier\", \"phone\": \"+33 (0)2 23 12 33 24\", \"email\": \"tim+serverpro@carbone.io\", \"partner\": { \"name\": \"Corp\", \"phone\": \"+33 (0)6 27 89 01 23\", \"email\": \"quentinleforestierleforestier0@gmail.com\", \"vat\": \"FR45899106785\", \"siren\": \"899106785\", \"address\": { \"street\": \"12 Doctor Street\", \"postalcode\": 34920, \"city\": \"Anger\", \"country\": \"France\" } }, \"note\": \"Our team is confident that this cutting-edge technology will enhance your operations and take your business to the next level. Should you have any questions or concerns, please don't hesitate to reach out to us.\", \"subscriptionFromDate\": \"2023-02-02T07:28:05+00:00\", \"subscriptionToDate\": \"2024-04-18T07:28:05+00:00\", \"products\": [ { \"name\": \"Rackmount case (With bays for multiple 3.5-inch drives and room for the motherboard and other components.)\", \"exTaxTotal\": 1000, \"unit\": 1000, \"vat\": 20, \"qty\": 1 }, { \"name\": \"Motherboard (has the necessary number of SATA ports for your storage needs)\", \"exTaxTotal\": 150, \"unit\": 150, \"vat\": 20, \"qty\": 1 }, { \"name\": \"3.5-inch SATA hard drives (20TO)\", \"exTaxTotal\": 1000, \"unit\": 100, \"vat\": 20, \"qty\": 10 }, { \"name\": \"Processor ( A low-power consumption processor)\", \"exTaxTotal\": 100, \"unit\": 100, \"vat\": 20, \"qty\": 1 }, { \"name\": \"4GB DDR5 RAM\", \"exTaxTotal\": 120, \"unit\": 30, \"vat\": 20, \"qty\": 4 } ], \"exTaxTotal\": 1870, \"taxTotal\": 374, \"inTaxTotal\": 2244, \"amountRemaining\": 1044, \"invoicePaymentList\": [ { \"paymentDate\": \"2023-02-03T07:28:05+00:00\", \"typeSelect\": \"Paiement\", \"amount\": 1200 } ], \"payment\": { \"name\": \"SEPA Transfer\", \"typeSelect\": \"SEPAtransfer\", \"condition\": \"Upon receipt of invoice\", \"bankLabel\": \"Revolut\", \"bankBIC\": \"REVOGB2L\", \"bankIBAN\": \"FR2112739000409352423869N75\" } }, \"convertTo\" : { \"formatName\" : \"pdf\" } }"; + + when(carboneRender.renderReport(json, templateId)).thenThrow(new RuntimeException("Unexpected error")); + + try { + carboneServices.render(json, templateId); + assertEquals(true, false, "Should have thrown an exception"); + } catch (CarboneException e) { + assertEquals("Carbone SDK render error: unexpected error: Unexpected error", e.getMessage()); + } } @Test