PhotoSwipe Pro - Testing Summary
Test Coverage Overview
All tests use Node's built-in test runner (no external dependencies like Jest/Mocha).
Run tests with:
npm test
✅ Tier 1: Critical Features (Fully Tested)
1. License Validation (src/pro/license.js)
Test file: test/pro/license.test.js
Coverage:
- ✅ Rejects empty/invalid license keys
- ✅ Accepts
pswp_*format keys - ✅ Offline grace period (14 days after last validation)
- ✅
withLicenseGateconditional feature activation
Why critical: Core monetization - bugs allow unauthorized access.
2. Remote License Gating (src/pro/license-remote.js)
Test file: test/pro/license-remote.test.js
Coverage:
- ✅
withRemoteAwareGatebehavior with mock provider - ✅ Validation failure handling
- ✅ Validation success allowing execution
- ✅ Instance ID caching
- ✅ Grace period refresh on successful validation
Why critical: Server-side validation prevents key sharing/fraud.
3. AI Plugin (src/pro/ai/plugin.js)
Test file: test/pro/ai/plugin.test.js
Coverage:
- ✅ Caption/alt text generation flow
- ✅ License key injection
- ✅ Provider response parsing
- ✅ Error handling
Why critical: The "Aha" Pro feature - must work reliably for paying customers.
✅ Tier 2: Important Features (Fully Tested)
4. ImageObject Schema Builder (src/pro/ai/schema/ImageObject.js)
Test file: test/pro/ai/schema/ImageObject.test.js
Coverage:
- ✅ Valid schema.org ImageObject structure
- ✅ Correct JSON-LD generation
- ✅ Special character escaping
- ✅ Minimal input handling
- ✅ ContentUrl preservation from slide data
Why important: SEO is a core Pro value proposition; schema must be valid for search engines.
5. CaptionProvider Client (src/pro/ai/CaptionProvider.js)
Test file: test/pro/ai/CaptionProvider.test.js
Coverage:
- ✅ Generates captions with valid input
- ✅ Includes license key in request when provided
- ✅ Sends correct request format (POST, JSON, headers)
- ✅ Throws on network error
- ✅ Throws on non-200 response
- ✅ Handles missing alt/caption in response
- ✅ Constructs correct endpoint URL
- ✅ Omits licenseKey when not provided
Why important: AI calls cost money; failures should be caught early.
6. LemonSqueezyProvider Client (src/pro/licensing/LemonSqueezyProvider.js)
Test file: test/pro/licensing/LemonSqueezyProvider.test.js
Coverage:
- ✅ Activate sends correct request
- ✅ Validate sends correct request
- ✅ Deactivate sends instanceId
- ✅ Activate includes optional email
- ✅ Throws on activation failure
- ✅ Throws on validation failure
- ✅ Handles network errors
- ✅ Constructs correct endpoint URLs
- ✅ Returns response data on success
Why important: License activation/deactivation API calls are security-critical.
❌ Not Tested (Future Consideration)
Server Proxy Endpoints
server/lemonsqueezy/router.jsserver/ai/router.js
Reason not tested: Express router integration tests require supertest or similar frameworks. Manual testing via curl has been performed successfully.
Manual verification:
# License validation
curl -X POST http://localhost:4000/api/license/validate \
-H 'content-type: application/json' \
-d '{"licenseKey":"pswp_demo_1234"}'
# AI caption generation
curl -X POST http://localhost:4000/api/ai/caption \
-H 'content-type: application/json' \
-d '{"url":"https://example.com/image.jpg","licenseKey":"pswp_demo_1234"}'
UI Components
demo-docs-website/src/components/LicensePanel.jsdemo-docs-website/src/components/ProDemo/index.js
Reason not tested: Would require React Testing Library. Manual browser testing has been performed.
Mock Providers
src/pro/providers/mock.js
Reason not tested: Simple mock data generation; low risk.
Test Results
Latest run: All 29 tests passing ✅
# tests 29
# suites 0
# pass 29
# fail 0
# cancelled 0
# skipped 0
# todo 0
Test execution time: ~86ms (very fast)
Test Architecture Principles
All tests follow SOLID and DRY principles:
Single Responsibility
Each test file tests one module/class only.
Dependency Inversion
Tests mock external dependencies (fetch, providers) using simple function overrides.
DRY
Reusable mock setup functions (setupMockFetch, restoreFetch) eliminate duplication.
Liskov Substitution
Mock providers satisfy the same interface as real providers.
CI/CD Integration
The npm test command runs:
- ESLint - Code quality checks
- Node test runner - Unit and integration tests
Both must pass before deployment.
Coverage Summary
| Module | Test Coverage | Status |
|---|---|---|
| License Validation | Unit + Integration | ✅ Complete |
| Remote License Gating | Integration | ✅ Complete |
| AI Plugin | Unit | ✅ Complete |
| ImageObject Schema | Unit | ✅ Complete |
| CaptionProvider | Unit | ✅ Complete |
| LemonSqueezyProvider | Unit | ✅ Complete |
| Server Routers | Manual | ⚠️ Manual only |
| UI Components | Manual | ⚠️ Manual only |
Adding New Tests
To add tests for a new Pro feature:
- Create
test/pro/[module-name].test.js - Import Node's test API:
import { test } from 'node:test';
import assert from 'node:assert/strict'; - Write tests using
test('description', async () => { ... }) - Mock external dependencies (fetch, providers, etc.)
- Run
npm testto verify
Example:
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { MyNewFeature } from '../../src/pro/my-feature.js';
test('MyNewFeature - does something useful', async () => {
const feature = new MyNewFeature();
const result = await feature.doSomething();
assert.equal(result, 'expected');
});
Security Testing
License validation and API proxy endpoints have been tested for:
- ✅ Required parameter validation
- ✅ License key format checking
- ✅ Error handling for invalid keys
- ✅ Network error resilience
- ✅ Proper secret handling (no client-side exposure)
Performance
All tests run in < 100ms, ensuring fast development feedback loops.
No external test dependencies required - uses only Node.js built-in test runner.