Skip to main content

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)
  • withLicenseGate conditional 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:

  • withRemoteAwareGate behavior 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.js
  • server/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.js
  • demo-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:

  1. ESLint - Code quality checks
  2. Node test runner - Unit and integration tests

Both must pass before deployment.


Coverage Summary

ModuleTest CoverageStatus
License ValidationUnit + Integration✅ Complete
Remote License GatingIntegration✅ Complete
AI PluginUnit✅ Complete
ImageObject SchemaUnit✅ Complete
CaptionProviderUnit✅ Complete
LemonSqueezyProviderUnit✅ Complete
Server RoutersManual⚠️ Manual only
UI ComponentsManual⚠️ Manual only

Adding New Tests

To add tests for a new Pro feature:

  1. Create test/pro/[module-name].test.js
  2. Import Node's test API:
    import { test } from 'node:test';
    import assert from 'node:assert/strict';
  3. Write tests using test('description', async () => { ... })
  4. Mock external dependencies (fetch, providers, etc.)
  5. Run npm test to 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.