fix(import): address round-3 review concerns

- Add comment to openFileStream() explaining package-private visibility
  is intentional (Mockito spy seam for IOException test)
- Key {#each} skippedFiles by filename instead of array index
- Add test: skipped section hidden when state is FAILED
- Add test: reasonLabel returns raw code for unknown reason strings

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-05-18 19:04:06 +02:00
committed by marcel
parent c932dd19d9
commit d5043053e0
3 changed files with 35 additions and 1 deletions

View File

@@ -312,6 +312,7 @@ public class MassImportService {
return new ProcessResult(processed, skippedFiles); return new ProcessResult(processed, skippedFiles);
} }
// package-private: Mockito spy in tests can override to inject IOException
InputStream openFileStream(File file) throws IOException { InputStream openFileStream(File file) throws IOException {
return new FileInputStream(file); return new FileInputStream(file);
} }

View File

@@ -78,7 +78,7 @@ function reasonLabel(code: string): string {
</div> </div>
</summary> </summary>
<ul class="mt-3 space-y-1"> <ul class="mt-3 space-y-1">
{#each importStatus.skippedFiles as skipped, i (i)} {#each importStatus.skippedFiles as skipped (skipped.filename)}
<li class="font-mono text-sm text-ink-2"> <li class="font-mono text-sm text-ink-2">
{skipped.filename}{reasonLabel(skipped.reason)} {skipped.filename}{reasonLabel(skipped.reason)}
</li> </li>

View File

@@ -199,4 +199,37 @@ describe('ImportStatusCard', () => {
await expect.element(getByTestId('skipped-count')).not.toBeInTheDocument(); await expect.element(getByTestId('skipped-count')).not.toBeInTheDocument();
}); });
it('does not show skipped section when FAILED even with skipped > 0', async () => {
const { getByTestId } = render(ImportStatusCard, {
props: {
importStatus: makeStatus({
state: 'FAILED',
statusCode: 'IMPORT_FAILED_INTERNAL',
skipped: 1,
skippedFiles: [{ filename: 'bad.pdf', reason: 'INVALID_PDF_SIGNATURE' }]
}),
ontrigger: () => {}
}
});
await expect.element(getByTestId('skipped-count')).not.toBeInTheDocument();
});
it('shows raw reason code for unknown skip reasons', async () => {
const { getByText } = render(ImportStatusCard, {
props: {
importStatus: makeStatus({
state: 'DONE',
statusCode: 'IMPORT_DONE',
processed: 1,
skipped: 1,
skippedFiles: [{ filename: 'odd.pdf', reason: 'SOME_FUTURE_CODE' }]
}),
ontrigger: () => {}
}
});
await expect.element(getByText('SOME_FUTURE_CODE', { exact: false })).toBeInTheDocument();
});
}); });