Skip to content

Commit 7eb2455

Browse files
♻️ rc2 fixes (#255)
1 parent af39eb3 commit 7eb2455

File tree

9 files changed

+65
-87
lines changed

9 files changed

+65
-87
lines changed

.github/workflows/_test-code-samples.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,4 @@ jobs:
3434

3535
- name: Tests sample code
3636
run: |
37-
./tests/test_code_samples.sh ${{ secrets.MINDEE_ACCOUNT_SE_TESTS }} ${{ secrets.MINDEE_ENDPOINT_SE_TESTS }} ${{ secrets.MINDEE_API_KEY_SE_TESTS }}
37+
./tests/test_code_samples.sh ${{ secrets.MINDEE_ACCOUNT_SE_TESTS }} ${{ secrets.MINDEE_ENDPOINT_SE_TESTS }} ${{ secrets.MINDEE_API_KEY_SE_TESTS }} ${{ secrets.MINDEE_V2_SE_TESTS_API_KEY }} ${{ secrets.MINDEE_V2_SE_TESTS_FINDOC_MODEL_ID }}

.github/workflows/_test-integrations.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,7 @@ jobs:
3333
env:
3434
MINDEE_API_KEY: ${{ secrets.MINDEE_API_KEY_SE_TESTS }}
3535
WORKFLOW_ID: ${{ secrets.WORKFLOW_ID_SE_TESTS }}
36+
MINDEE_V2_API_KEY: ${{ secrets.MINDEE_V2_SE_TESTS_API_KEY }}
37+
MINDEE_V2_FINDOC_MODEL_ID: ${{ secrets.MINDEE_V2_SE_TESTS_FINDOC_MODEL_ID }}
3638
run: |
3739
mvn clean test-compile failsafe:integration-test failsafe:verify

src/main/java/com/mindee/MindeeClientV2.java

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -103,18 +103,6 @@ else if (resp.getJob().getStatus().equals("Processed")) {
103103
throw new RuntimeException("Max retries exceeded (" + max + ").");
104104
}
105105

106-
/**
107-
* Deserialize a webhook payload (or any saved response) into an
108-
* {@link InferenceResponse}.
109-
*/
110-
public InferenceResponse loadInference(LocalResponse localResponse) throws IOException {
111-
ObjectMapper mapper = new ObjectMapper().findAndRegisterModules();
112-
InferenceResponse model =
113-
mapper.readValue(localResponse.getFile(), InferenceResponse.class);
114-
model.setRawResponse(localResponse.toString());
115-
return model;
116-
}
117-
118106
private static MindeeApiV2 createDefaultApiV2(String apiKey) {
119107
MindeeSettingsV2 settings = apiKey == null || apiKey.trim().isEmpty()
120108
? new MindeeSettingsV2()

src/main/java/com/mindee/http/MindeeHttpApiV2.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ private HttpPost buildHttpPost(
263263
private <R extends CommonResponse> R deserializeOrThrow(
264264
String body, Class<R> clazz, int httpStatus) throws MindeeHttpExceptionV2 {
265265

266-
if (httpStatus >= 200 && httpStatus < 300) {
266+
if (httpStatus >= 200 && httpStatus < 400) {
267267
try {
268268
R model = mapper.readerFor(clazz).readValue(body);
269269
model.setRawResponse(body);

src/main/java/com/mindee/input/LocalResponse.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package com.mindee.input;
22

3+
import com.fasterxml.jackson.databind.ObjectMapper;
4+
import com.mindee.MindeeException;
5+
import com.mindee.parsing.v2.CommonResponse;
36
import java.io.BufferedReader;
47
import java.io.File;
58
import java.io.IOException;
@@ -91,4 +94,25 @@ public String getHmacSignature(String secretKey) {
9194
public boolean isValidHmacSignature(String secretKey, String signature) {
9295
return signature.equals(getHmacSignature(secretKey));
9396
}
97+
98+
99+
/**
100+
* Deserialize this local JSON payload into a specific {@link CommonResponse}
101+
* subtype: {@code InferenceResponse}, {@code JobResponse}.
102+
*
103+
* @param responseClass the concrete class to instantiate
104+
* @param <T> generic {@link CommonResponse}
105+
* @return Either a {@code InferenceResponse} or {@code JobResponse} instance.
106+
* @throws MindeeException if the payload cannot be deserialized into the requested type
107+
*/
108+
public <T extends CommonResponse> T deserializeResponse(Class<T> responseClass) {
109+
ObjectMapper mapper = new ObjectMapper();
110+
try {
111+
T response = mapper.readValue(this.file, responseClass);
112+
response.setRawResponse(new String(this.file, StandardCharsets.UTF_8));
113+
return response;
114+
} catch (Exception ex) {
115+
throw new MindeeException("Invalid class specified for deserialization.", ex);
116+
}
117+
}
94118
}

src/main/java/com/mindee/parsing/v2/field/BaseField.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public abstract class BaseField {
1111
* Field's location.
1212
*/
1313
@JsonProperty("locations")
14-
private List<FieldLocation> page;
14+
private List<FieldLocation> locations;
1515

1616
/**
1717
* Confidence associated with the field.

src/test/java/com/mindee/MindeeClientV2IT.java

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,6 @@ class MindeeClientV2IT {
2121
void setUp() {
2222
String apiKey = System.getenv("MINDEE_V2_API_KEY");
2323
modelId = System.getenv("MINDEE_V2_FINDOC_MODEL_ID");
24-
25-
assumeTrue(
26-
apiKey != null && !apiKey.trim().isEmpty(),
27-
"MINDEE_V2_API_KEY env var is missing – integration tests skipped"
28-
);
29-
assumeTrue(
30-
modelId != null && !modelId.trim().isEmpty(),
31-
"MINDEE_V2_FINDOC_MODEL_ID env var is missing – integration tests skipped"
32-
);
33-
3424
mindeeClient = new MindeeClientV2(apiKey);
3525
}
3626

@@ -116,7 +106,7 @@ void invalidJob_mustThrowError() {
116106
MindeeHttpExceptionV2.class,
117107
() -> mindeeClient.getInference("not-a-valid-job-ID")
118108
);
119-
assertEquals(404, ex.getStatus());
109+
assertEquals(422, ex.getStatus());
120110
assertNotNull(ex);
121111
}
122112
}

src/test/java/com/mindee/MindeeClientV2Test.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,18 +114,17 @@ void document_getInference_async() throws IOException {
114114
}
115115

116116
@Nested
117-
@DisplayName("loadInference()")
118-
class LoadInference {
117+
@DisplayName("deserializeResponse()")
118+
class DeserializeResponse {
119119

120120
@Test
121121
@DisplayName("parses local JSON and exposes correct field values")
122122
void inference_loadsLocally() throws IOException {
123-
MindeeClientV2 mindeeClient = new MindeeClientV2("dummy");
124123
File jsonFile =
125124
new File("src/test/resources/v2/products/financial_document/complete.json");
126125
LocalResponse localResponse = new LocalResponse(jsonFile);
127126

128-
InferenceResponse loaded = mindeeClient.loadInference(localResponse);
127+
InferenceResponse loaded = localResponse.deserializeResponse(InferenceResponse.class);
129128

130129
assertNotNull(loaded, "Loaded InferenceResponse must not be null");
131130
assertEquals(

src/test/java/com/mindee/parsing/v2/InferenceTest.java

Lines changed: 32 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
class InferenceTest {
2020

2121
private InferenceResponse loadFromResource(String resourcePath) throws IOException {
22-
MindeeClientV2 dummyClient = new MindeeClientV2("dummy");
23-
return dummyClient.loadInference(new LocalResponse(InferenceTest.class.getClassLoader().getResourceAsStream(resourcePath)));
22+
LocalResponse localResponse = new LocalResponse(InferenceTest.class.getClassLoader().getResourceAsStream(resourcePath));
23+
return localResponse.deserializeResponse(InferenceResponse.class);
2424
}
2525

2626
private String readFileAsString(String path)
@@ -90,41 +90,55 @@ void asyncPredict_whenEmpty_mustHaveValidProperties() throws IOException {
9090
class CompletePrediction {
9191

9292
@Test
93-
@DisplayName("all properties must be valid")
94-
void asyncPredict_whenComplete_mustHaveValidProperties() throws IOException {
93+
@DisplayName("every exposed property must be valid and consistent")
94+
void asyncPredict_whenComplete_mustExposeAllProperties() throws IOException {
9595
InferenceResponse response = loadFromResource("v2/products/financial_document/complete.json");
96-
InferenceFields fields = response.getInference().getResult().getFields();
96+
Inference inf = response.getInference();
97+
assertNotNull(inf, "Inference must not be null");
98+
assertEquals("12345678-1234-1234-1234-123456789abc", inf.getId(), "Inference ID mismatch");
9799

98-
assertEquals(21, fields.size(), "Expected 21 fields");
100+
InferenceResultModel model = inf.getModel();
101+
assertNotNull(model, "Model must not be null");
102+
assertEquals("12345678-1234-1234-1234-123456789abc", model.getId(), "Model ID mismatch");
103+
104+
InferenceResultFile file = inf.getFile();
105+
assertNotNull(file, "File must not be null");
106+
assertEquals("complete.jpg", file.getName(), "File name mismatch");
107+
assertNull(file.getAlias(), "File alias must be null for this payload");
108+
109+
InferenceFields fields = inf.getResult().getFields();
110+
assertEquals(21, fields.size(), "Expected 21 fields in the payload");
111+
112+
SimpleField date = fields.get("date").getSimpleField();
113+
assertEquals("2019-11-02", date.getValue(), "'date' value mismatch");
99114

100115
DynamicField taxes = fields.get("taxes");
101116
assertNotNull(taxes, "'taxes' field must exist");
102117
ListField taxesList = taxes.getListField();
103118
assertNotNull(taxesList, "'taxes' must be a ListField");
104119
assertEquals(1, taxesList.getItems().size(), "'taxes' list must contain exactly one item");
105-
assertNotNull(taxes.toString(), "'taxes' toString() must not be null");
106-
107120
ObjectField taxItemObj = taxesList.getItems().get(0).getObjectField();
108121
assertNotNull(taxItemObj, "First item of 'taxes' must be an ObjectField");
109122
assertEquals(3, taxItemObj.getFields().size(), "Tax ObjectField must contain 3 sub-fields");
110-
assertEquals(
111-
31.5,
112-
taxItemObj.getFields().get("base").getSimpleField().getValue(),
113-
"'taxes.base' value mismatch"
114-
);
123+
SimpleField baseTax = taxItemObj.getFields().get("base").getSimpleField();
124+
assertEquals(31.5, baseTax.getValue(), "'taxes.base' value mismatch");
125+
assertNotNull(taxes.toString(), "'taxes'.toString() must not be null");
115126

116127
DynamicField supplierAddress = fields.get("supplier_address");
117128
assertNotNull(supplierAddress, "'supplier_address' field must exist");
118-
119129
ObjectField supplierObj = supplierAddress.getObjectField();
120130
assertNotNull(supplierObj, "'supplier_address' must be an ObjectField");
121-
122131
DynamicField country = supplierObj.getFields().get("country");
123132
assertNotNull(country, "'supplier_address.country' must exist");
124-
assertEquals("USA", country.getSimpleField().getValue());
125-
assertEquals("USA", country.toString());
126-
133+
assertEquals("USA", country.getSimpleField().getValue(), "Country mismatch");
134+
assertEquals("USA", country.toString(), "'country'.toString() mismatch");
127135
assertNotNull(supplierAddress.toString(), "'supplier_address'.toString() must not be null");
136+
137+
ObjectField customerAddr = fields.get("customer_address").getObjectField();
138+
SimpleField city = customerAddr.getFields().get("city").getSimpleField();
139+
assertEquals("New York", city.getValue(), "City mismatch");
140+
141+
assertNull(inf.getResult().getOptions(), "Options must be null");
128142
}
129143
}
130144

@@ -206,45 +220,6 @@ void rawTexts_mustBeAccessible() throws IOException {
206220
}
207221
}
208222

209-
@Nested
210-
@DisplayName("complete.json – full inference response")
211-
class FullInference {
212-
@Test
213-
@DisplayName("complete financial-document JSON must round-trip correctly")
214-
void fullInferenceResponse_mustExposeEveryProperty() throws IOException {
215-
InferenceResponse resp = loadFromResource("v2/products/financial_document/complete.json");
216-
217-
Inference inf = resp.getInference();
218-
assertNotNull(inf);
219-
assertEquals("12345678-1234-1234-1234-123456789abc", inf.getId());
220-
221-
InferenceFields f = inf.getResult().getFields();
222-
223-
SimpleField date = f.get("date").getSimpleField();
224-
assertEquals("2019-11-02", date.getValue());
225-
226-
ListField taxes = f.get("taxes").getListField();
227-
ObjectField firstTax = taxes.getItems().get(0).getObjectField();
228-
SimpleField baseTax = firstTax.getFields().get("base").getSimpleField();
229-
assertEquals(31.5, baseTax.getValue());
230-
231-
ObjectField customerAddr = f.get("customer_address").getObjectField();
232-
SimpleField city = customerAddr.getFields().get("city").getSimpleField();
233-
assertEquals("New York", city.getValue());
234-
235-
InferenceResultModel model = inf.getModel();
236-
assertNotNull(model);
237-
assertEquals("12345678-1234-1234-1234-123456789abc", model.getId());
238-
239-
InferenceResultFile file = inf.getFile();
240-
assertNotNull(file);
241-
assertEquals("complete.jpg", file.getName());
242-
assertNull(file.getAlias());
243-
244-
assertNull(inf.getResult().getOptions());
245-
}
246-
}
247-
248223
@Nested
249224
@DisplayName("rst display")
250225
class RstDisplay {

0 commit comments

Comments
 (0)