Skip to content

Latest commit

Β 

History

History
371 lines (296 loc) Β· 11 KB

File metadata and controls

371 lines (296 loc) Β· 11 KB

Testing Setup for React Native Preview URL

This document provides a complete overview of the testing setup for the react-native-preview-url library.

What Was Added

1. Test Dependencies

The following dependencies were added to package.json:

{
  "devDependencies": {
    "@testing-library/react": "^14.0.0",
    "@testing-library/react-native": "^12.0.0",
    "@vitejs/plugin-react": "^4.2.0",
    "@vitest/ui": "^1.0.0",
    "jsdom": "^23.0.0",
    "vitest": "^1.0.0"
  }
}

2. Test Scripts

Updated package.json scripts:

{
  "scripts": {
    "test": "vitest",
    "test:ui": "vitest --ui",
    "test:coverage": "vitest --coverage"
  }
}

3. Configuration Files

vitest.config.ts

Main Vitest configuration file with:

  • React plugin for JSX support
  • JSDOM environment for DOM simulation
  • Setup file for test initialization
  • Coverage configuration (v8 provider)
  • Path aliases for module resolution
  • Test file patterns (tests/**/*.test.{ts,tsx})

vitest.setup.ts

Test environment setup file that:

  • Configures cleanup after each test
  • Mocks React Native components (Image, Text, TouchableOpacity, View, etc.)
  • Mocks React Native APIs (Linking, StyleSheet)
  • Mocks global fetch API
  • Sets up testing utilities

Test Files Created

1. Utility Function Tests

tests/utils/getDomainFromUrl.test.ts (108 tests coverage)

Tests for URL domain extraction:

  • Happy Path (11 tests): Basic HTTP/HTTPS URLs, www URLs, subdomains, ports, paths, fragments, special characters
  • Error Handling (6 tests): Invalid URLs, empty strings, malformed URLs, special characters
  • Edge Cases (6 tests): Complex subdomains, internationalized domains, long domain names, case sensitivity

tests/utils/isValidHttpUrl.test.ts (47 tests coverage)

Tests for URL validation:

  • Happy Path (12 tests): Valid HTTP/HTTPS URLs with various configurations
  • Invalid Protocols (7 tests): FTP, WebSocket, file, custom protocols, mailto, data URIs
  • Malformed URLs (8 tests): Empty strings, special characters, incomplete URLs
  • Edge Cases (9 tests): Uppercase protocols, multiple subdomains, very long URLs, encoded characters

tests/utils/clamp.test.ts (35 tests coverage)

Tests for value clamping utility:

  • Happy Path (10 tests): Within range, below min, above max, boundary values
  • Timeout Constants (6 tests): Integration with MIN_TIMEOUT, MAX_TIMEOUT, DEFAULT_TIMEOUT
  • Edge Cases (8 tests): Very large numbers, Infinity, floating-point precision
  • Precision and Rounding (5 tests): Decimal preservation, no rounding

2. Hook Tests

tests/useUrlPreview.test.ts (38 tests coverage)

Comprehensive tests for the useUrlPreview hook:

  • Happy Path (7 tests): Successful fetching, loading states, timeout handling, URL encoding
  • Error Handling (7 tests): Empty URL, invalid URL, network errors, API errors, AbortError
  • Timeout Handling (2 tests): Clamping below/above bounds
  • Cache Behavior (3 tests): Refetch on URL change, abort previous request
  • Response Handling (3 tests): Various response formats, empty arrays, minimal fields
  • Loading State Lifecycle (1 test): State transitions

Key test scenarios:

  • Validates URL before fetching
  • Clamps timeout within MIN_TIMEOUT and MAX_TIMEOUT
  • Handles AbortError gracefully (doesn't set error state)
  • Refetches when URL changes
  • Encodes URL properly in fetch request
  • Handles various API error formats

3. Component Tests

tests/LinkPreview.test.tsx (45 tests coverage)

Tests for the LinkPreview component:

  • Happy Path (11 tests): Loading states, custom loaders, preview rendering, URL display, callbacks
  • Error Handling (6 tests): Error states, error callbacks, missing data, image errors
  • Text Truncation (4 tests): Title and description line limits
  • Timeout Handling (2 tests): Default and custom timeout propagation
  • Callback Lifecycle (4 tests): Success, error, and press callbacks
  • Accessibility (2 tests): Accessibility attributes and hints
  • Image Error Handling (2 tests): Failed images, fallback images
  • Prop Combinations (2 tests): Various prop combinations

Key test scenarios:

  • Renders loading state or custom loader
  • Displays preview data with title, description, and URL
  • Respects visibility prop (visible/hidden)
  • Calls onPress with data when component is pressed
  • Falls back to Linking.openURL if onPress not provided
  • Handles image loading errors and fallbacks
  • Applies custom styles and text truncation

4. Configuration Tests

tests/constants.test.ts (24 tests coverage)

Tests for constants and configuration management:

  • Timeout Constants (7 tests): Validation of MIN_TIMEOUT, MAX_TIMEOUT, DEFAULT_TIMEOUT
  • Base URL Configuration (4 tests): Default URL, URL validation, domain verification
  • setBaseUrl Functionality (7 tests): Setting custom URLs, persistence, multiple changes
  • Consistency Checks (3 tests): Value consistency, type validation

Key test scenarios:

  • MIN_TIMEOUT = 1000ms, MAX_TIMEOUT = 30000ms, DEFAULT_TIMEOUT = 3000ms
  • Base URL is a valid HTTPS URL pointing to Vercel API
  • setBaseUrl persists across multiple calls
  • getBaseUrl returns consistent values

5. Integration Tests

tests/integration.test.ts (21 tests coverage)

End-to-end workflow tests:

  • URL Validation & Domain Extraction Workflow (4 tests)
  • Timeout Configuration Workflow (3 tests)
  • Configuration Management (2 tests)
  • Error Handling Across Components (3 tests)
  • Complete Workflow (1 test)
  • Performance and Edge Cases (2 tests)

Tests verify:

  • Complete fetch workflow from URL validation to data retrieval
  • Proper error handling across multiple layers
  • Timeout constraints are applied correctly
  • Base URL configuration is used in API calls
  • Multiple URL changes are handled properly

Test Statistics

Total Test Files: 8
Total Test Cases: 218+

Breakdown by Type:
β”œβ”€β”€ Utility Tests: 90 tests
β”‚   β”œβ”€β”€ getDomainFromUrl: 23 tests
β”‚   β”œβ”€β”€ isValidHttpUrl: 29 tests
β”‚   └── clamp: 38 tests
β”œβ”€β”€ Hook Tests: 38 tests
β”œβ”€β”€ Component Tests: 45 tests
β”œβ”€β”€ Configuration Tests: 24 tests
└── Integration Tests: 21 tests

Coverage Areas:
β”œβ”€β”€ Happy Path: ~60% of tests
β”œβ”€β”€ Error Handling: ~25% of tests
β”œβ”€β”€ Edge Cases: ~15% of tests

Running Tests

Install Dependencies

yarn install

Run All Tests

yarn test

Run Tests in Watch Mode

yarn test --watch

Run Specific Test File

yarn test tests/utils/getDomainFromUrl.test.ts

Run Tests Matching Pattern

yarn test --grep "error handling"

Generate Coverage Report

yarn test:coverage

Output: coverage/ directory with HTML report

View Test UI

yarn test:ui

Opens browser-based interactive test UI

Test Coverage Goals

Target coverage percentages:

  • Statements: > 85%
  • Branches: > 80%
  • Functions: > 85%
  • Lines: > 85%

Key Testing Patterns

1. Utility Function Testing

  • Test all input variations (valid, invalid, edge cases)
  • Verify return types and values
  • Test error conditions
  • Validate boundary conditions

2. Hook Testing

  • Mock external dependencies (fetch, constants)
  • Test state updates with waitFor
  • Verify cleanup with AbortController
  • Test dependency array changes

3. Component Testing

  • Mock child components and hooks
  • Verify callback invocations
  • Test prop combinations
  • Validate render output

4. Integration Testing

  • Test workflows across multiple modules
  • Verify data flow between components
  • Test error propagation
  • Validate complete user scenarios

Mocking Strategy

React Native Mocks

// Automatically mocked in vitest.setup.ts
- Image, Text, TouchableOpacity, View
- Linking.openURL
- StyleSheet.create

API Mocks

// Mocked globally
- global.fetch (for all network tests)
- useUrlPreview (in component tests for isolation)

Component Mocks

// Mocked as needed
- LoaderComponent (in LinkPreview tests)
- Child components (for isolated testing)

Debugging Tests

Enable Verbose Output

yarn test --reporter=verbose

Run Single Test

yarn test --reporter=verbose tests/utils/getDomainFromUrl.test.ts

Debug with Node Inspector

node --inspect-brk ./node_modules/.bin/vitest

Then open chrome://inspect in Chrome

Print Debug Information

import { describe, it, expect, vi } from 'vitest';

it('should test something', () => {
  console.log('Debug:', someValue);
  expect(someValue).toBe(expected);
});

Best Practices Applied

  1. Organization: Tests grouped by feature/module with describe blocks
  2. Naming: Clear, descriptive test names starting with "should"
  3. Isolation: Each test is independent with setup/cleanup
  4. DRY: Shared mocks and utilities to reduce duplication
  5. Coverage: Happy path, errors, and edge cases for each feature
  6. Integration: End-to-end tests verify component interactions
  7. Maintainability: Tests use stable APIs and avoid implementation details

File Structure

project-root/
β”œβ”€β”€ tests/
β”‚   β”œβ”€β”€ README.md                          # Test documentation
β”‚   β”œβ”€β”€ constants.test.ts                  # Configuration tests
β”‚   β”œβ”€β”€ integration.test.ts                # End-to-end tests
β”‚   β”œβ”€β”€ LinkPreview.test.tsx              # Component tests
β”‚   β”œβ”€β”€ useUrlPreview.test.ts             # Hook tests
β”‚   └── utils/
β”‚       β”œβ”€β”€ clamp.test.ts                 # Clamp utility tests
β”‚       β”œβ”€β”€ getDomainFromUrl.test.ts      # Domain extraction tests
β”‚       └── isValidHttpUrl.test.ts        # URL validation tests
β”œβ”€β”€ vitest.config.ts                       # Vitest configuration
β”œβ”€β”€ vitest.setup.ts                        # Test setup and mocks
└── package.json                           # Updated with test deps and scripts

Next Steps

  1. Install Dependencies: Run yarn install
  2. Run Tests: Run yarn test to execute all tests
  3. Check Coverage: Run yarn test:coverage to see coverage report
  4. Review Results: Check test output and fix any failures
  5. Watch Mode: Run yarn test --watch for development

Continuous Integration

These tests are ready to be integrated into CI/CD pipelines:

# Example GitHub Actions workflow
- name: Run tests
  run: yarn test

- name: Generate coverage
  run: yarn test:coverage

- name: Upload coverage
  uses: codecov/codecov-action@v3

Support

For issues or questions about the test setup:

  1. Check tests/README.md for detailed test documentation
  2. Review individual test files for implementation examples
  3. Check vitest.config.ts for configuration options
  4. Consult Vitest documentation: https://vitest.dev

Resources