Testing 
This guide covers how to test your PocketDNS integration effectively.
Sandbox Environment 
The PocketDNS sandbox environment provides a safe space to test your integration without affecting real domains or billing.
Sandbox Features 
- Test domains: Use .testTLD for testing
- Simulated transactions: No real charges occur
- Isolated data: Separate from production data
- Full API compatibility: Same endpoints and responses as production
Sandbox URLs 
- API: https://api.sandbox.pocketdns.com
- Embed: https://embed.sandbox.pocketdns.com
- Dashboard: https://dashboard.sandbox.pocketdns.com
Test Domain Purchases 
In sandbox, you can purchase test domains:
javascript
// Test domains are automatically available in sandbox
const testDomains = [
  'example1.test',
  'example2.test',
  'mysite.test'
];
// Purchase will succeed immediately without paymentIntegration Testing Checklist 
Basic Integration Tests 
- [ ] User Session Creation - [ ] Create session with valid user identifier
- [ ] Handle invalid user identifiers
- [ ] Session expires after 24 hours
- [ ] Email parameter is optional
 
- [ ] Iframe Embedding - [ ] Iframe loads successfully
- [ ] Responsive design works on mobile
- [ ] Payment flows complete in sandbox
- [ ] Session expiration is handled gracefully
 
- [ ] Domain Management - [ ] Fetch user domains after purchase
- [ ] Get individual domain details
- [ ] Handle users with no domains
 
Advanced Integration Tests 
- [ ] DNS Management - [ ] Create DNS records programmatically
- [ ] Update existing DNS records
- [ ] Delete DNS records
- [ ] Apply DNS templates
- [ ] Handle DNS propagation delays
 
- [ ] Error Handling - [ ] API errors are caught and handled
- [ ] User-friendly error messages displayed
- [ ] Network timeouts handled gracefully
- [ ] Rate limiting respected
 
- [ ] Security - [ ] API keys never exposed client-side
- [ ] User identifiers are validated
- [ ] HTTPS enforced for all requests
- [ ] CORS headers configured correctly
 
Unit Testing 
Testing API Calls 
javascript
// __tests__/pocketdns.test.js
import { createUserSession } from '../src/services/pocketdns';
// Mock fetch for testing
global.fetch = jest.fn();
describe('PocketDNS API', () => {
  beforeEach(() => {
    fetch.mockClear();
  });
  test('creates user session successfully', async () => {
    const mockResponse = {
      user_identifier: 'test_user_123',
      login_url: 'https://embed.sandbox.pocketdns.com/session/abc123',
      expires_at: '2025-01-07T12:00:00Z'
    };
    fetch.mockResolvedValueOnce({
      ok: true,
      json: async () => mockResponse
    });
    const result = await createUserSession('test_user_123', '[email protected]');
    
    expect(result).toEqual(mockResponse);
    expect(fetch).toHaveBeenCalledWith(
      'https://api.sandbox.pocketdns.com/api/v1/users',
      expect.objectContaining({
        method: 'POST',
        headers: expect.objectContaining({
          'Authorization': expect.stringContaining('Bearer'),
          'Content-Type': 'application/json'
        })
      })
    );
  });
  test('handles API errors gracefully', async () => {
    fetch.mockResolvedValueOnce({
      ok: false,
      status: 401,
      statusText: 'Unauthorized'
    });
    await expect(
      createUserSession('invalid_user')
    ).rejects.toThrow('Failed to create session: Unauthorized');
  });
});Testing React Components 
javascript
// __tests__/PocketDNSEmbed.test.js
import React from 'react';
import { render, screen, waitFor } from '@testing-library/react';
import PocketDNSEmbed from '../src/components/PocketDNSEmbed';
// Mock the API service
jest.mock('../src/services/pocketdns', () => ({
  createUserSession: jest.fn()
}));
import { createUserSession } from '../src/services/pocketdns';
describe('PocketDNSEmbed', () => {
  test('shows loading state initially', () => {
    render(<PocketDNSEmbed userIdentifier="test_user" />);
    expect(screen.getByText('Loading domain interface...')).toBeInTheDocument();
  });
  test('renders iframe when session loads', async () => {
    createUserSession.mockResolvedValue({
      login_url: 'https://embed.sandbox.pocketdns.com/session/abc123'
    });
    render(<PocketDNSEmbed userIdentifier="test_user" />);
    await waitFor(() => {
      const iframe = screen.getByTitle('Domain Management');
      expect(iframe).toBeInTheDocument();
      expect(iframe.src).toBe('https://embed.sandbox.pocketdns.com/session/abc123');
    });
  });
  test('shows error state on API failure', async () => {
    createUserSession.mockRejectedValue(new Error('API Error'));
    render(<PocketDNSEmbed userIdentifier="test_user" />);
    await waitFor(() => {
      expect(screen.getByText('Error: API Error')).toBeInTheDocument();
    });
  });
});Integration Testing 
End-to-End Testing with Cypress 
javascript
// cypress/integration/domain-purchase.spec.js
describe('Domain Purchase Flow', () => {
  beforeEach(() => {
    // Set up test user
    cy.request('POST', 'https://api.sandbox.pocketdns.com/api/v1/users', {
      user_identifier: 'cypress_test_user',
      email: '[email protected]'
    }).then((response) => {
      cy.window().then((win) => {
        win.testSession = response.body;
      });
    });
  });
  it('completes domain purchase flow', () => {
    cy.visit('/domains');
    
    // Load the embed
    cy.get('[data-testid="pocketdns-embed"]').should('be.visible');
    
    // Switch to iframe context
    cy.get('iframe').then(($iframe) => {
      const iframe = $iframe.contents();
      
      // Search for a domain
      cy.wrap(iframe.find('input[placeholder="Search for a domain"]'))
        .type('cypress-test.test{enter}');
      
      // Click purchase button
      cy.wrap(iframe.find('button[data-testid="purchase-button"]'))
        .click();
      
      // Complete purchase (in sandbox, this is instant)
      cy.wrap(iframe.find('button[data-testid="confirm-purchase"]'))
        .click();
      
      // Verify success message
      cy.wrap(iframe.find('[data-testid="purchase-success"]'))
        .should('contain', 'Domain purchased successfully');
    });
    
    // Verify domain appears in user's account
    cy.request({
      url: `https://api.sandbox.pocketdns.com/api/v1/users/cypress_test_user/domains`,
      headers: {
        'Authorization': `Bearer ${Cypress.env('POCKETDNS_SANDBOX_API_KEY')}`
      }
    }).then((response) => {
      expect(response.body.domains).to.have.length.greaterThan(0);
      expect(response.body.domains[0].name).to.equal('cypress-test.test');
    });
  });
});Testing Webhooks 
javascript
// __tests__/webhooks.test.js
import request from 'supertest';
import app from '../src/app';
describe('PocketDNS Webhooks', () => {
  test('handles domain purchase webhook', async () => {
    const webhookPayload = {
      event: 'domain.purchased',
      data: {
        domain_id: 'dom_123456',
        user_identifier: 'test_user_123',
        domain_name: 'example.test',
        purchased_at: '2025-01-06T12:00:00Z'
      }
    };
    const response = await request(app)
      .post('/webhooks/pocketdns')
      .send(webhookPayload)
      .expect(200);
    expect(response.body.success).toBe(true);
    
    // Verify that DNS records were created
    // Verify user notification was sent
    // etc.
  });
});Performance Testing 
API Response Time Testing 
javascript
// __tests__/performance.test.js
import { createUserSession, getUserDomains } from '../src/services/pocketdns';
describe('PocketDNS Performance', () => {
  test('user session creation completes within 2 seconds', async () => {
    const start = Date.now();
    
    await createUserSession('perf_test_user', '[email protected]');
    
    const duration = Date.now() - start;
    expect(duration).toBeLessThan(2000);
  });
  test('domain fetching handles large datasets', async () => {
    // Test with user that has many domains
    const start = Date.now();
    
    const domains = await getUserDomains('user_with_many_domains');
    
    const duration = Date.now() - start;
    expect(domains.length).toBeGreaterThan(0);
    expect(duration).toBeLessThan(5000);
  });
});Load Testing with Artillery 
yaml
# load-test.yml
config:
  target: 'https://api.sandbox.pocketdns.com'
  phases:
    - duration: 60
      arrivalRate: 10
  defaults:
    headers:
      Authorization: 'Bearer {{ $env.POCKETDNS_SANDBOX_API_KEY }}'
      Content-Type: 'application/json'
scenarios:
  - name: 'Create user sessions'
    weight: 80
    flow:
      - post:
          url: '/api/v1/users'
          json:
            user_identifier: 'load_test_{{ $randomString() }}'
            email: 'test{{ $randomInt(1, 1000) }}@example.com'
          capture:
            - json: '$.user_identifier'
              as: 'userId'
      - get:
          url: '/api/v1/users/{{ userId }}/domains'
          
  - name: 'Health check'
    weight: 20
    flow:
      - get:
          url: '/health'Run the load test:
bash
npx artillery run load-test.ymlManual Testing 
Testing Checklist 
User Session Testing 
- Create session with valid user ID
- Create session with email parameter
- Try to reuse expired session
- Test with invalid API key
- Test with malformed requests
Domain Interface Testing 
- Load iframe in different browsers
- Test responsive design on mobile
- Search for available domains
- Purchase a test domain
- Verify domain appears in account
API Integration Testing 
- Fetch user domains after purchase
- Create DNS records programmatically
- Update existing DNS records
- Test error handling scenarios
- Verify webhook delivery
Monitoring and Debugging 
Test Data Cleanup 
javascript
// scripts/cleanup-test-data.js
const cleanupTestData = async () => {
  const testUsers = await getUsersWithPrefix('test_');
  
  for (const user of testUsers) {
    const domains = await getUserDomains(user.user_identifier);
    
    for (const domain of domains) {
      if (domain.name.endsWith('.test')) {
        await deleteDomain(domain.id);
      }
    }
    
    await deleteUser(user.user_identifier);
  }
  
  console.log(`Cleaned up ${testUsers.length} test users`);
};Debug Logging 
javascript
// utils/debug.js
const debug = require('debug');
const pocketDNSDebug = debug('app:pocketdns');
export const logAPICall = (method, url, data) => {
  pocketDNSDebug(`${method} ${url}`, data);
};
export const logAPIResponse = (response) => {
  pocketDNSDebug('Response:', response.status, response.data);
};Best Practices 
- Always test in sandbox first before production deployment
- Use test data that's easy to identify and clean up
- Test error scenarios as thoroughly as success scenarios
- Monitor API response times and set performance budgets
- Clean up test data regularly to avoid clutter
- Test across different browsers and devices
- Validate all user inputs before sending to API
- Test webhook delivery and handling
- Use proper test isolation to avoid test interference
- Keep test credentials separate from production credentials
