generated from coulomb/repo-seed
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>
This commit is contained in:
103
tests/pdf-detector.test.ts
Normal file
103
tests/pdf-detector.test.ts
Normal file
@@ -0,0 +1,103 @@
|
||||
/**
|
||||
* 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'
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user