Testing Guide
Comprehensive testing strategies and best practices for integrating the Vehicle Custody Identity Verification SDKs.
Applies To
This testing guide applies to all Vehicle Custody SDKs. Use sandbox mode for all testing scenarios.
Quick Integration Test
import { createVecuIDVSDK } from 'vec-idp-web-sdk';
// Initialize SDK in sandbox mode
const sdk = createVecuIDVSDK({
deploymentStage: 'sandbox',
bearerToken: 'your-bearer-token-here',
debug: true,
logLevel: 'debug',
});
// Start verification with test customer data
async function test() {
const cleanup = await sdk.startVerificationWithCustomer(
'#verification-container',
{
customerInfo: {
firstName: 'John',
lastName: 'Doe',
email: 'john.doe@example.com',
address: { country: 'US' },
},
onProgress: event => {
console.log(`Progress: ${event.step} (${event.percentage}%)`);
},
onSuccess: result => {
console.log('Verification completed!', result);
cleanup();
},
onError: error => {
console.error('Verification failed:', error);
cleanup();
},
}
);
}
Test Customer Data
Use these predefined test customer profiles to test different verification scenarios in sandbox mode.
Successful Verification
This customer profile will pass all verification checks with high confidence.
const successfulCustomer = {
firstName: 'John',
lastName: 'Doe',
email: 'john.doe@example.com',
phone: '+1-555-123-4567',
dateOfBirth: '1990-01-15',
address: {
line1: '123 Main Street',
line2: 'Apt 4B',
locality: 'Springfield',
majorAdminDivision: 'IL',
country: 'US',
postalCode: '62701',
type: 'residential',
},
};
Failed Verification
This customer profile will fail verification for testing error handling.
const failedCustomer = {
firstName: 'Jane',
lastName: 'Smith',
email: 'jane.fail@example.com',
phone: '+1-555-987-6543',
dateOfBirth: '1985-05-20',
address: {
line1: '456 Test Avenue',
locality: 'Failtown',
majorAdminDivision: 'TX',
country: 'US',
postalCode: '12345',
type: 'residential',
},
};
Manual Review Required
This customer profile will require manual review to test pending states.
const manualReviewCustomer = {
firstName: 'Robert',
lastName: 'Johnson',
email: 'robert.review@example.com',
phone: '+1-555-444-3333',
dateOfBirth: '1975-12-08',
address: {
line1: '789 Review Street',
locality: 'Reviewville',
majorAdminDivision: 'CA',
country: 'US',
postalCode: '90210',
type: 'residential',
},
};
Validation Error Testing
Use these incomplete profiles to test client-side validation.
// Missing required fields
const incompleteCustomer = {
firstName: 'Alice',
// lastName missing - will trigger validation error
email: 'alice@example.com',
// address missing - will trigger validation error
};
// Invalid format
const invalidFormatCustomer = {
firstName: 'Bob',
lastName: 'Wilson',
email: 'invalid-email-format', // Invalid email
phone: '123', // Invalid phone format
address: {
line1: '123 Test St',
locality: 'Test City',
majorAdminDivision: 'ZZ', // Invalid state code
country: 'XX', // Invalid country code
postalCode: '1', // Invalid postal code format
type: 'residential',
},
};
Backend Validation Error Testing (v1.5.5+)
Test data that triggers specific backend validation errors. These errors include a recoverable: true flag, allowing users to correct their data and retry.
// Invalid ZIP code - triggers INVALID_ZIP_CODE
const invalidZipCustomer = {
firstName: 'John',
lastName: 'Doe',
email: 'john.doe@example.com',
phone: '+1-555-123-4567',
address: {
line1: '123 Main Street',
locality: 'Springfield',
majorAdminDivision: 'IL',
country: 'US',
postalCode: '12', // Too short - triggers backend error
type: 'residential',
},
};
// Invalid country - triggers INVALID_COUNTRY
const invalidCountryCustomer = {
firstName: 'Jane',
lastName: 'Smith',
email: 'jane.smith@example.com',
phone: '+1-555-987-6543',
address: {
line1: '456 Oak Avenue',
locality: 'Test City',
majorAdminDivision: 'TX',
country: 'XX', // Invalid country code - triggers backend error
postalCode: '75001',
type: 'residential',
},
};
// Invalid state - triggers INVALID_STATE
const invalidStateCustomer = {
firstName: 'Bob',
lastName: 'Johnson',
email: 'bob.johnson@example.com',
phone: '+1-555-444-3333',
address: {
line1: '789 Pine Road',
locality: 'Testville',
majorAdminDivision: 'XX', // Non-existent state - triggers backend error
country: 'US',
postalCode: '90210',
type: 'residential',
},
};
Expected Error Response Structure:
{
code: 'INVALID_ZIP_CODE', // or INVALID_COUNTRY, INVALID_STATE, etc.
message: 'The zip code is invalid',
provider: 'identity_provider',
details: {
category: 'validation_error',
recoverable: true,
timestamp: '2026-01-07T14:54:33.251Z'
}
}
Backend Validation Error Testing Notes
- Confirmed error codes:
INVALID_ZIP_CODE,INVALID_COUNTRY,INVALID_STATE,INVALID_ADDRESS,INVALID_CITY,INVALID_PHONE- Backend validation errors (v1.5.5+) are marked asrecoverable: true- Users should be guided to correct the invalid data and retry verification - Error messages are human-readable and can be displayed directly to users - Test error handling by checking for specific error codes in theonErrorcallback
Reverification Testing
Test the reverification flow using reference IDs from completed verifications.
Successful Reverification
// First, complete a regular verification
const verificationCleanup = await sdk.startVerificationWithCustomer(
'#container',
{
customerInfo: {
firstName: 'John',
lastName: 'Doe',
email: 'john.doe@example.com',
address: { country: 'US' },
},
referenceId: 'test-customer-123',
onSuccess: result => {
console.log('Initial verification completed:', result.verificationId);
},
}
);
// Later, perform reverification using the same referenceId
const reverifyCleanup = await sdk.startReverification('#container', {
referenceId: 'test-customer-123', // Same referenceId as original
phoneNumber: '+1-555-123-4567', // Optional
onProgress: event => {
console.log(`Reverification progress: ${event.percentage}%`);
},
onSuccess: result => {
console.log('Reverification completed!', result);
},
onError: error => {
console.error('Reverification failed:', error);
},
});
Test Reference IDs
Use these test reference IDs in sandbox mode to trigger specific reverification scenarios:
| Reference ID | Scenario |
|---|---|
test-reverify-success-001 | Successful Reverification |
test-reverify-fail-selfie | Failed (Selfie Mismatch) |
test-reverify-fail-quality | Failed (Quality Issues) |
test-reverify-review-pending | Manual Review Required |
Reverification Testing Tips
- Always test reverification in sandbox mode before production - Verify that
webhook events use
reverification.*event types - Test both success and failure scenarios - Confirm that verification IDs start withreverifyprefix
Mock Webhook Server
Set up a local webhook server for testing webhook events during development.
Express.js Mock Server
// webhook-server.js
const express = require('express');
const app = express();
app.use(express.json());
// Webhook endpoint for VECU events
app.post('/webhooks/vecu-idv', (req, res) => {
const event = req.body;
console.log('Received webhook event:');
console.log('Event ID:', event.eventId);
console.log('Event Type:', event.eventType);
console.log('Timestamp:', event.timestamp);
console.log('Decision:', event.data?.decision);
console.log('Reason Codes:', event.data?.reasons);
console.log('Full Data:', JSON.stringify(event.data, null, 2));
console.log('---');
// Always return success to acknowledge receipt
res.status(200).json({
status: 'received',
eventId: event.eventId,
timestamp: new Date().toISOString(),
});
});
// Health check endpoint
app.get('/health', (req, res) => {
res.json({ status: 'healthy', timestamp: new Date().toISOString() });
});
const PORT = process.env.PORT || 3001;
app.listen(PORT, () => {
console.log(`Webhook server running on http://localhost:${PORT}`);
console.log(`Webhook URL: http://localhost:${PORT}/webhooks/vecu-idv`);
});
Setup Instructions:
- Save the code above as
webhook-server.js - Install dependencies:
npm install express - Run the server:
node webhook-server.js - Use ngrok to expose locally:
ngrok http 3001 - Configure the ngrok URL as your webhook endpoint
Python (Flask) Mock Server
# webhook_server.py
from flask import Flask, request, jsonify
from datetime import datetime
import json
app = Flask(__name__)
@app.route('/webhooks/vecu-idv', methods=['POST'])
def handle_webhook():
event = request.get_json()
print('Received webhook event:')
print(f'Event ID: {event.get("eventId")}')
print(f'Event Type: {event.get("eventType")}')
print(f'Timestamp: {event.get("timestamp")}')
print(f'Data: {json.dumps(event.get("data"), indent=2)}')
print('---')
return jsonify({
'status': 'received',
'eventId': event.get('eventId'),
'timestamp': datetime.utcnow().isoformat() + 'Z'
}), 200
@app.route('/health', methods=['GET'])
def health_check():
return jsonify({
'status': 'healthy',
'timestamp': datetime.utcnow().isoformat() + 'Z'
}), 200
if __name__ == '__main__':
print('Webhook server running on http://localhost:3001')
app.run(host='0.0.0.0', port=3001, debug=True)
Testing Scenarios
Happy Path Testing
- Successful verification with high confidence
- Proper webhook event handling
- Correct UI state transitions
- Customer data persistence
- Cleanup function execution
Error Handling
- Network connectivity failures
- Invalid customer data validation
- Authentication failures
- Timeout scenarios
- SDK initialization errors
Edge Cases
- Manual review required scenarios
- Multiple verification attempts
- Browser compatibility issues
- Mobile device testing
- Slow network conditions
Integration Testing
- Framework-specific implementations
- Multiple SDK instances
- Webhook delivery reliability
- Database state consistency
- User experience flows
Compliance Testing (v1.3.3+)
Test SSN/National ID field visibility for different compliance scenarios.
SSN Field Hidden (GDPR Compliance)
const sdk = createVecuIDVSDK({
deploymentStage: 'sandbox',
bearerToken: 'your-bearer-token',
});
const cleanup = await sdk.startVerificationWithCustomer(
'#verification-container',
{
customerInfo: {
firstName: 'John',
lastName: 'Doe',
email: 'john.doe@example.com',
phone: '+1-555-123-4567',
address: { country: 'DE' }, // German user
},
referenceId: 'eu-customer-123',
config: {
showSsnOnInitialForm: false, // Hide SSN field
},
}
);
// Expected: Address form shows NO SSN field
// API payload will NOT include national_id
Conditional Visibility (Location-Based)
// Determine SSN requirement based on user's country
function shouldShowSsn(country) {
const gdprCountries = ['AT', 'BE', 'DE', 'FR', 'IT', 'ES'];
return !gdprCountries.includes(country);
}
const userCountry = getUserCountry();
await sdk.startVerificationWithCustomer('#container', {
customerInfo: {
/* ... */
},
config: {
showSsnOnInitialForm: shouldShowSsn(userCountry),
},
});
// Test with different countries:
// - US, CA, MX: SSN field visible
// - DE, FR, IT: SSN field hidden
Environment Configuration
Development Environment
# .env.development
VECU_DEPLOYMENT_STAGE=sandbox
VECU_CLIENT_ID=dev-client-id-here
VECU_CLIENT_SECRET=dev-client-secret-here
VECU_DEBUG=true
VECU_LOG_LEVEL=debug
const sdk = createVecuIDVSDK({
deploymentStage: process.env.VECU_DEPLOYMENT_STAGE,
bearerToken: process.env.VECU_BEARER_TOKEN,
debug: process.env.VECU_DEBUG === 'true',
logLevel: process.env.VECU_LOG_LEVEL,
});
Testing Environment
# .env.test
VECU_DEPLOYMENT_STAGE=sandbox
VECU_DEBUG=false
VECU_LOG_LEVEL=error
VECU_WEBHOOK_URL=http://localhost:3001/webhooks/vecu-idv
// Jest setup - jest.setup.js
import { createVecuIDVSDK } from 'vec-idp-web-sdk';
// Mock SDK for testing
jest.mock('vec-idp-web-sdk', () => ({
createVecuIDVSDK: jest.fn(() => ({
startVerificationWithCustomer: jest.fn().mockResolvedValue(() => {}),
destroy: jest.fn(),
})),
}));
Development Tools
Local Development
| Tool | Purpose |
|---|---|
| ngrok | Expose local webhook server publicly |
| Postman | Test webhook endpoints and SDK integrations |
| curl | Command-line webhook testing |
| Browser DevTools | Debug SDK integration and network requests |
Testing Services
| Service | Purpose |
|---|---|
| RequestBin | Temporary webhook endpoint for testing |
| Webhook.site | Inspect webhook payloads in real-time |
| Mockoon | Mock backend responses for SDK testing |
| JSONPlaceholder | Mock REST API for development |
Debugging Checklist
SDK Integration Issues
- Check browser console for error messages
- Verify SDK configuration parameters
- Ensure container element exists and is visible
- Check network tab for failed API requests
- Validate customer data format
Webhook Issues
- Verify webhook URL is publicly accessible
- Check webhook server logs for incoming requests
- Ensure proper HTTP response codes (200)
- Validate webhook authentication if configured
- Test webhook endpoint with curl or Postman
Environment Issues
- Verify all environment variables are set
- Check API credentials are valid and not expired
- Ensure correct deployment stage (sandbox/production)
- Test network connectivity to VECU services
- Review CORS configuration for your domain
Need More Help?
If you're still experiencing issues, enable debug mode and check the SDK troubleshooting guide for detailed solutions.
Next Steps
- Web SDK Demo - Try the interactive demo
- Webhooks Guide - Comprehensive webhook reference
- API Reference - SDK methods reference