Files
wehub-resource-sync c48612c494
CI / E2E Tests (push) Has been cancelled
CI / Lint, Typecheck & Unit Tests (push) Has been cancelled
Docs Build / Build docs site (push) Has been cancelled
Publish @openmaic packages / Build, validate & publish (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:03:23 +08:00

178 lines
5.6 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import {
getDocumentExtractorProvider,
getDocumentExtractorProviders,
selectDocumentExtractorProvider,
} from '@/lib/document';
import { PROVIDER_SUPPORTED_MIME_TYPES } from '@/lib/document/mime';
describe('document extractor registry', () => {
it('exposes existing PDF providers through the document extractor boundary', () => {
const providers = getDocumentExtractorProviders();
expect(providers.map((provider) => provider.id)).toEqual([
'plain-text',
'unpdf',
'mineru',
'mineru-cloud',
]);
expect(providers.every((provider) => provider.supportedMimeTypes)).toBe(true);
expect(
providers
.filter((provider) => provider.id !== 'plain-text')
.every((provider) => provider.supportedMimeTypes.includes('application/pdf')),
).toBe(true);
});
it('exposes a local plain-text extractor for TXT and Markdown', () => {
const plainText = getDocumentExtractorProvider('plain-text');
expect(plainText).toBeDefined();
expect(plainText?.supportedMimeTypes).toEqual([
'text/plain',
'text/markdown',
'text/x-markdown',
]);
expect(plainText?.capabilities).toMatchObject({
text: true,
images: false,
tables: false,
formulas: false,
layout: false,
ocr: false,
async: false,
});
});
it('declares MinerU capabilities and supported course material formats', () => {
const mineru = getDocumentExtractorProvider('mineru');
const mineruCloud = getDocumentExtractorProvider('mineru-cloud');
expect(mineru).toBeDefined();
expect(mineru?.displayName).toBe('MinerU');
// Self-host MinerU (v3.1+): pdf + modern Office (docx/pptx/xlsx) + images.
// No legacy OLE (.doc/.ppt/.xls) — those are cloud-only.
expect(mineru?.supportedMimeTypes).toEqual([
'application/pdf',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'image/png',
'image/jpeg',
'image/webp',
'image/gif',
'image/bmp',
'image/jp2',
]);
expect(mineru?.capabilities).toMatchObject({
text: true,
images: true,
tables: true,
formulas: true,
layout: true,
ocr: true,
async: false,
});
expect(mineruCloud).toBeDefined();
// Cloud adds legacy OLE formats on top of self-host list.
expect(mineruCloud?.supportedMimeTypes).toEqual([
...(mineru?.supportedMimeTypes ?? []),
'application/msword',
'application/vnd.ms-powerpoint',
'application/vnd.ms-excel',
]);
expect(mineruCloud?.capabilities).toMatchObject({
text: true,
images: true,
tables: true,
formulas: true,
layout: true,
ocr: true,
async: true,
});
});
it('selects a preferred provider only when it supports the requested MIME type', () => {
expect(
selectDocumentExtractorProvider({
mimeType: 'application/pdf',
preferredProviderId: 'mineru-cloud',
}).id,
).toBe('mineru-cloud');
expect(
selectDocumentExtractorProvider({
mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
preferredProviderId: 'mineru',
}).id,
).toBe('mineru');
expect(() =>
selectDocumentExtractorProvider({
mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
preferredProviderId: 'unpdf',
}),
).toThrow(/does not support MIME type/);
});
it('can select by required capabilities', () => {
expect(
selectDocumentExtractorProvider({
mimeType: 'application/pdf',
requiredCapabilities: { tables: true, formulas: true },
}).id,
).toBe('mineru');
expect(() =>
selectDocumentExtractorProvider({
mimeType: 'application/pdf',
preferredProviderId: 'unpdf',
requiredCapabilities: { tables: true },
}),
).toThrow(/requested capabilities/);
});
it('returns a clear error when no provider supports the MIME type', () => {
expect(() =>
selectDocumentExtractorProvider({
mimeType: 'application/x-shockwave-flash',
}),
).toThrow(/No document extractor supports MIME type/);
});
it('can capability-match Office course material to MinerU', () => {
expect(
selectDocumentExtractorProvider({
mimeType: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
requiredCapabilities: { text: true },
}).id,
).toBe('mineru');
expect(
selectDocumentExtractorProvider({
mimeType: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
preferredProviderId: 'mineru-cloud',
requiredCapabilities: { text: true },
}).id,
).toBe('mineru-cloud');
});
it('can capability-match text course material locally', () => {
expect(
selectDocumentExtractorProvider({
mimeType: 'text/markdown',
requiredCapabilities: { text: true },
}).id,
).toBe('plain-text');
});
it('keeps PROVIDER_SUPPORTED_MIME_TYPES in sync with the extractor registry', () => {
// Drift guard: mime.ts (client-safe, drives the upload UI) and the registry
// (server-side extractors) must advertise the same MIME lists per provider.
for (const provider of getDocumentExtractorProviders()) {
expect(PROVIDER_SUPPORTED_MIME_TYPES[provider.id]).toEqual(provider.supportedMimeTypes);
}
});
});