Files
binect-chrome/tests/pdf-detector.test.ts
tegwick b09290cb83 Release 0.1: Complete BinectChrome implementation
Implements all requirements from ProductRequirementsDocument.md:
- PDF detection via Chrome Downloads API
- Secure credential storage with AES-GCM encryption
- Binect API integration for PDF uploads
- Popup UI with Binect branding
- Local transfer tracking (500 entry cap)
- Help page with tracking view and CSV export
- 60-day credential retention with auto-expiry
- Accessibility compliance (WCAG 2.1 AA)

Technical implementation:
- Chrome Extension Manifest V3
- TypeScript with strict mode
- Webpack build system
- Jest test suite (22/22 passing)
- ESLint configured (0 errors)

Build output: 13 KB total (production minified)
Test coverage: crypto, pdf-detector, tracker, binect-api

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-13 00:30:39 +01:00

104 lines
2.5 KiB
TypeScript

/**
* Tests for PDF detection
*/
import { getLastPDFDownload, fetchPDFBytes } from '../src/utils/pdf-detector';
// Chrome API is mocked in setup.ts
describe('PDF Detector', () => {
beforeEach(() => {
jest.clearAllMocks();
});
test('should detect PDF by extension', async () => {
const mockItems = [
{
id: 1,
filename: 'document.pdf',
url: 'https://example.com/doc.pdf',
fileSize: 1024,
state: 'complete',
mime: 'application/pdf'
}
];
(chrome.downloads.search as jest.Mock).mockImplementation((query, callback) => {
callback(mockItems);
});
const pdf = await getLastPDFDownload();
expect(pdf).toBeDefined();
expect(pdf?.filename).toBe('document.pdf');
expect(pdf?.sourceDomain).toBe('example.com');
});
test('should return null when no PDF found', async () => {
const mockItems = [
{
id: 1,
filename: 'document.txt',
url: 'https://example.com/doc.txt',
fileSize: 1024,
state: 'complete',
mime: 'text/plain'
}
];
(chrome.downloads.search as jest.Mock).mockImplementation((query, callback) => {
callback(mockItems);
});
const pdf = await getLastPDFDownload();
expect(pdf).toBeNull();
});
test('should detect PDF by MIME type even without .pdf extension', async () => {
const mockItems = [
{
id: 1,
filename: 'document',
url: 'https://example.com/doc',
fileSize: 1024,
state: 'complete',
mime: 'application/pdf'
}
];
(chrome.downloads.search as jest.Mock).mockImplementation((query, callback) => {
callback(mockItems);
});
const pdf = await getLastPDFDownload();
expect(pdf).toBeDefined();
expect(pdf?.filename).toBe('document');
});
});
describe('fetchPDFBytes', () => {
test('should throw error on non-200 response', async () => {
(fetch as jest.Mock).mockResolvedValue({
ok: false,
status: 404,
statusText: 'Not Found'
});
await expect(fetchPDFBytes('https://example.com/doc.pdf')).rejects.toThrow(
'Failed to fetch PDF: 404 Not Found'
);
});
test('should throw error on non-PDF content type', async () => {
(fetch as jest.Mock).mockResolvedValue({
ok: true,
headers: {
get: (name: string) => (name === 'Content-Type' ? 'text/html' : null)
}
});
await expect(fetchPDFBytes('https://example.com/doc.pdf')).rejects.toThrow(
'URL did not return a PDF'
);
});
});