chore: clean up codebase for production readiness
Mirror to GitHub / mirror (push) Successful in 44s
Test and Lint / backend-test (push) Successful in 1m42s
Test and Lint / frontend-test (push) Has been cancelled
Version and Release / version-bump (push) Has been cancelled
Version and Release / trigger-drone (push) Has been cancelled
Mirror to GitHub / mirror (push) Successful in 44s
Test and Lint / backend-test (push) Successful in 1m42s
Test and Lint / frontend-test (push) Has been cancelled
Version and Release / version-bump (push) Has been cancelled
Version and Release / trigger-drone (push) Has been cancelled
- Remove all console.log/debug statements from production code - Add NODE_ENV checks for development-only logging - Remove test scripts (test-feedback, test-image-security, test-backup-*, test-restore) - Remove one-time fix scripts (fix-temp-photos, fix-migration-state, mark-migration-applied) - Remove sensitive files (.env.backup, ADMIN_CREDENTIALS.txt) - Update package.json to remove references to deleted scripts - Replace console statements with logger utility in backend - Secure error boundaries to not expose stack traces in production This makes the codebase production-ready with no debug output or test scripts. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,236 @@
|
||||
import React from 'react';
|
||||
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
|
||||
import { ProtectedImage } from '../ProtectedImage';
|
||||
|
||||
// Mock canvas and image APIs
|
||||
const mockCanvas = {
|
||||
getContext: jest.fn(() => ({
|
||||
clearRect: jest.fn(),
|
||||
drawImage: jest.fn(),
|
||||
getImageData: jest.fn(() => ({
|
||||
data: new Uint8ClampedArray(4).fill(255)
|
||||
})),
|
||||
putImageData: jest.fn(),
|
||||
fillRect: jest.fn(),
|
||||
fillText: jest.fn(),
|
||||
strokeText: jest.fn(),
|
||||
measureText: jest.fn(() => ({ width: 100 }))
|
||||
})),
|
||||
width: 100,
|
||||
height: 100,
|
||||
style: {},
|
||||
addEventListener: jest.fn(),
|
||||
removeEventListener: jest.fn()
|
||||
};
|
||||
|
||||
// Mock HTMLCanvasElement
|
||||
Object.defineProperty(HTMLCanvasElement.prototype, 'getContext', {
|
||||
value: () => mockCanvas.getContext()
|
||||
});
|
||||
|
||||
// Mock Image constructor
|
||||
global.Image = class {
|
||||
onload: (() => void) | null = null;
|
||||
onerror: (() => void) | null = null;
|
||||
src = '';
|
||||
naturalWidth = 100;
|
||||
naturalHeight = 100;
|
||||
width = 100;
|
||||
height = 100;
|
||||
crossOrigin = '';
|
||||
|
||||
constructor() {
|
||||
// Simulate image loading
|
||||
setTimeout(() => {
|
||||
if (this.onload) this.onload();
|
||||
}, 10);
|
||||
}
|
||||
} as any;
|
||||
|
||||
describe('ProtectedImage', () => {
|
||||
const defaultProps = {
|
||||
src: '/test-image.jpg',
|
||||
alt: 'Test image'
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('renders loading state initially', () => {
|
||||
render(<ProtectedImage {...defaultProps} />);
|
||||
expect(screen.getByRole('img', { name: /loading test image/i })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders canvas after image loads', async () => {
|
||||
render(<ProtectedImage {...defaultProps} />);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole('img', { name: 'Test image' })).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it('applies protection level classes and events', async () => {
|
||||
const onViolation = jest.fn();
|
||||
|
||||
render(
|
||||
<ProtectedImage
|
||||
{...defaultProps}
|
||||
protectionLevel="enhanced"
|
||||
onProtectionViolation={onViolation}
|
||||
/>
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
const canvas = screen.getByRole('img', { name: 'Test image' });
|
||||
expect(canvas).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// Test context menu blocking
|
||||
const canvas = screen.getByRole('img', { name: 'Test image' });
|
||||
fireEvent.contextMenu(canvas);
|
||||
|
||||
expect(onViolation).toHaveBeenCalledWith('canvas_context_menu');
|
||||
});
|
||||
|
||||
it('applies watermark text when specified', async () => {
|
||||
render(
|
||||
<ProtectedImage
|
||||
{...defaultProps}
|
||||
watermarkText="Test Watermark"
|
||||
protectionLevel="standard"
|
||||
/>
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole('img', { name: 'Test image' })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// Verify canvas context methods were called for watermark
|
||||
expect(mockCanvas.getContext().fillText).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('handles fragment grid rendering', async () => {
|
||||
render(
|
||||
<ProtectedImage
|
||||
{...defaultProps}
|
||||
fragmentGrid={true}
|
||||
gridSize={4}
|
||||
protectionLevel="enhanced"
|
||||
/>
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole('img', { name: 'Test image' })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// Verify multiple drawImage calls for fragments
|
||||
expect(mockCanvas.getContext().drawImage).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('blocks interactions in maximum protection mode', async () => {
|
||||
const onViolation = jest.fn();
|
||||
|
||||
render(
|
||||
<ProtectedImage
|
||||
{...defaultProps}
|
||||
protectionLevel="maximum"
|
||||
onProtectionViolation={onViolation}
|
||||
/>
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
const canvas = screen.getByRole('img', { name: 'Test image' });
|
||||
expect(canvas).toBeInTheDocument();
|
||||
|
||||
// Test click blocking
|
||||
fireEvent.click(canvas);
|
||||
expect(onViolation).toHaveBeenCalledWith('canvas_interaction_blocked');
|
||||
});
|
||||
});
|
||||
|
||||
it('handles image loading errors gracefully', async () => {
|
||||
// Mock image error
|
||||
global.Image = class {
|
||||
onload: (() => void) | null = null;
|
||||
onerror: (() => void) | null = null;
|
||||
src = '';
|
||||
|
||||
constructor() {
|
||||
setTimeout(() => {
|
||||
if (this.onerror) this.onerror();
|
||||
}, 10);
|
||||
}
|
||||
} as any;
|
||||
|
||||
const onViolation = jest.fn();
|
||||
|
||||
render(
|
||||
<ProtectedImage
|
||||
{...defaultProps}
|
||||
onProtectionViolation={onViolation}
|
||||
fallbackSrc="/fallback.jpg"
|
||||
/>
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Image unavailable')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
expect(onViolation).toHaveBeenCalledWith('image_load_error');
|
||||
});
|
||||
|
||||
it('applies invisible watermark for enhanced protection', async () => {
|
||||
render(
|
||||
<ProtectedImage
|
||||
{...defaultProps}
|
||||
watermarkText="Hidden"
|
||||
invisibleWatermark={true}
|
||||
protectionLevel="enhanced"
|
||||
/>
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole('img', { name: 'Test image' })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// Verify getImageData and putImageData called for steganography
|
||||
expect(mockCanvas.getContext().getImageData).toHaveBeenCalled();
|
||||
expect(mockCanvas.getContext().putImageData).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('scrambles fragments when enabled', async () => {
|
||||
render(
|
||||
<ProtectedImage
|
||||
{...defaultProps}
|
||||
fragmentGrid={true}
|
||||
scrambleFragments={true}
|
||||
protectionLevel="maximum"
|
||||
/>
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole('img', { name: 'Test image' })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// Fragment scrambling should result in multiple drawImage calls
|
||||
expect(mockCanvas.getContext().drawImage).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('adds random noise in maximum protection', async () => {
|
||||
render(
|
||||
<ProtectedImage
|
||||
{...defaultProps}
|
||||
protectionLevel="maximum"
|
||||
/>
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole('img', { name: 'Test image' })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// Noise injection requires getImageData and putImageData
|
||||
expect(mockCanvas.getContext().getImageData).toHaveBeenCalled();
|
||||
expect(mockCanvas.getContext().putImageData).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user