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:
116
tests/binect-api.test.ts
Normal file
116
tests/binect-api.test.ts
Normal file
@@ -0,0 +1,116 @@
|
||||
/**
|
||||
* Tests for Binect API client
|
||||
*/
|
||||
|
||||
import { authenticate, uploadPDF, BinectAPIError } from '../src/utils/binect-api';
|
||||
|
||||
describe('Binect API', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
describe('authenticate', () => {
|
||||
test('should authenticate successfully', async () => {
|
||||
const mockResponse = {
|
||||
token: 'test-token',
|
||||
expiresAt: '2024-12-31T23:59:59Z'
|
||||
};
|
||||
|
||||
(fetch as jest.Mock).mockResolvedValue({
|
||||
ok: true,
|
||||
json: async () => mockResponse
|
||||
});
|
||||
|
||||
const result = await authenticate('user', 'pass');
|
||||
expect(result.token).toBe('test-token');
|
||||
expect(fetch).toHaveBeenCalledWith(
|
||||
'https://api.binect.de/auth/login',
|
||||
expect.objectContaining({
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ username: 'user', password: 'pass' })
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
test('should throw on invalid credentials', async () => {
|
||||
(fetch as jest.Mock).mockResolvedValue({
|
||||
ok: false,
|
||||
status: 401,
|
||||
statusText: 'Unauthorized'
|
||||
});
|
||||
|
||||
await expect(authenticate('user', 'wrong')).rejects.toThrow(
|
||||
BinectAPIError
|
||||
);
|
||||
await expect(authenticate('user', 'wrong')).rejects.toThrow(
|
||||
'Invalid credentials'
|
||||
);
|
||||
});
|
||||
|
||||
test('should handle network errors', async () => {
|
||||
(fetch as jest.Mock).mockRejectedValue(new Error('Network failure'));
|
||||
|
||||
await expect(authenticate('user', 'pass')).rejects.toThrow(
|
||||
BinectAPIError
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('uploadPDF', () => {
|
||||
test('should upload PDF successfully', async () => {
|
||||
const mockResponse = {
|
||||
documentId: 'doc-123',
|
||||
status: 'received',
|
||||
uploadedAt: '2024-01-01T00:00:00Z'
|
||||
};
|
||||
|
||||
(fetch as jest.Mock).mockResolvedValue({
|
||||
ok: true,
|
||||
json: async () => mockResponse
|
||||
});
|
||||
|
||||
const pdfData = new ArrayBuffer(1024);
|
||||
const result = await uploadPDF(pdfData, 'test.pdf', 'token-123');
|
||||
|
||||
expect(result.documentId).toBe('doc-123');
|
||||
expect(fetch).toHaveBeenCalledWith(
|
||||
'https://api.binect.de/documents/upload',
|
||||
expect.objectContaining({
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: 'Bearer token-123'
|
||||
}
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
test('should throw on authentication failure', async () => {
|
||||
(fetch as jest.Mock).mockResolvedValue({
|
||||
ok: false,
|
||||
status: 401,
|
||||
statusText: 'Unauthorized',
|
||||
json: async () => ({ error: 'Invalid token' })
|
||||
});
|
||||
|
||||
const pdfData = new ArrayBuffer(1024);
|
||||
await expect(uploadPDF(pdfData, 'test.pdf', 'bad-token')).rejects.toThrow(
|
||||
BinectAPIError
|
||||
);
|
||||
});
|
||||
|
||||
test('should throw on file size exceeded', async () => {
|
||||
(fetch as jest.Mock).mockResolvedValue({
|
||||
ok: false,
|
||||
status: 413,
|
||||
statusText: 'Payload Too Large',
|
||||
json: async () => ({ error: 'File too large' })
|
||||
});
|
||||
|
||||
const pdfData = new ArrayBuffer(10 * 1024 * 1024); // 10MB
|
||||
await expect(uploadPDF(pdfData, 'test.pdf', 'token')).rejects.toThrow(
|
||||
'File size exceeds limit'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user