Skip to content

Commit

Permalink
[FormRecognizer] Fix an issue accessing undefined object
Browse files Browse the repository at this point in the history
when input document to receipt recognition contains blank pages
  • Loading branch information
jeremymeng committed May 7, 2020
1 parent a98996d commit c894276
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 4 deletions.
1 change: 1 addition & 0 deletions sdk/formrecognizer/ai-form-recognizer/.vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"<node_internals>/**"
],
"program": "${file}",
"cwd": "${fileDirname}",
"outFiles": [
"${workspaceFolder}/dist/**/*.js"
]
Expand Down
2 changes: 2 additions & 0 deletions sdk/formrecognizer/ai-form-recognizer/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## 1.0.0-preview.3 (Unreleased)

- Blank pages in receipt recognition are now handled properly.

## 1.0.0-preview.2 (2020-05-06)

- `FormTrainingClient.listModels()` now works correctly on NodeJs v8.
Expand Down

Large diffs are not rendered by default.

10 changes: 8 additions & 2 deletions sdk/formrecognizer/ai-form-recognizer/src/transforms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ function toRecognizedReceipt(result: DocumentResultModel, pages: FormPage[]): Re
const form = toRecognizedForm(result, pages);
return {
recognizedForm: form,
locale: undefined
locale: undefined // in the future service would return locale info
};
}

Expand Down Expand Up @@ -506,11 +506,17 @@ export function toReceiptResultResponse(
return common;
}

if (!result.analyzeResult) {
throw new Error("Expecting valid analyzeResult from the service response")
}

const pages = result.analyzeResult!.readResults.map(toFormPage);
return {
...common,
version: result.analyzeResult!.version,
receipts: result.analyzeResult!.documentResults!.map((d) => {
receipts: result.analyzeResult!.documentResults!.filter(d => {
return !!d.fields
}).map((d) => {
const receipt = toRecognizedReceipt(d, pages);
return toReceiptWithLocale({ ...receipt, locale: "US" }); // default to US until service returns locale info.
})
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -185,4 +185,27 @@ describe("FormRecognizerClient NodeJS only", () => {
const usReceipt = response!.receipts![0];
assert.equal(usReceipt.recognizedForm.formType, "prebuilt:receipt");
});

it("recognizes multi-page receipt with blank page", async () => {
const filePath = path.join(ASSET_PATH, "receipt", "multipage_invoice1.pdf");
const stream = fs.createReadStream(filePath);

const poller = await client.beginRecognizeReceipts(stream, "application/pdf", {
includeTextDetails: true
});
await poller.pollUntilDone();
const response = poller.getResult();

assert.ok(response, "Expect valid response object");
assert.equal(response!.status, "succeeded");
assert.ok(
response!.receipts && response!.receipts.length > 0,
`Expect no-empty pages but got ${response!.receipts}`
);
const usReceipt = response!.receipts![0];
assert.equal(usReceipt.recognizedForm.formType, "prebuilt:receipt");
assert.equal(usReceipt.locale, "US"); // default to "US" for now
assert.equal(usReceipt.receiptType, "itemized");
assert.equal(usReceipt.locale, "US");
});
}).timeout(60000);
19 changes: 17 additions & 2 deletions sdk/formrecognizer/ai-form-recognizer/test/transforms.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@ import {
toFormTable,
toRecognizeFormResultResponse,
toReceiptResultResponse,
toFormModelResponse
toFormModelResponse,
toRecognizedForm
} from "../src/transforms";
import {
GeneratedClientGetAnalyzeFormResultResponse as GetAnalyzeFormResultResponse,
GeneratedClientGetAnalyzeReceiptResultResponse as GetAnalyzeReceiptResultResponse,
GeneratedClientGetCustomModelResponse as GetCustomModelResponse,
ReadResult as ReadResultModel,
FieldValue as FieldValueModel,
DataTable as DataTableModel
DataTable as DataTableModel,
DocumentResult as DocumentResultModel
} from "../src/generated/models";
import {
StringFieldValue,
Expand Down Expand Up @@ -456,6 +458,19 @@ describe("Transforms", () => {
assert.equal(transformed.rows[2].cells[0].columnSpan, 2);
});

it("toRecognizedForm() should handle empty page", () => {
const original: DocumentResultModel = {
docType: "prebuilt:receipt",
pageRange: [1, 1],
fields: {}
}

const transformed = toRecognizedForm(original, formPages);

assert.ok(transformed, "Expected valid recognized form");
assert.deepStrictEqual(transformed.fields, {}, "expected empty fields in recognzied form");
});

it("toRecognizeFormResultResponse() converts unsupervised response into recognized forms", () => {
const original: GetAnalyzeFormResultResponse = JSON.parse(unsupervisedResponseString);
const transformed = toRecognizeFormResultResponse(original);
Expand Down

0 comments on commit c894276

Please sign in to comment.