DEV Community

Mohammad Waseem
Mohammad Waseem

Posted on

Mastering Geo-Blocked Feature Testing in Legacy React Applications

Introduction

Testing geo-restricted features in legacy React applications presents unique challenges. These involve simulating user locations, handling legacy codebases that lack modern testing hooks, and ensuring compliance with regional content restrictions. As a Lead QA Engineer, addressing these complexities requires a strategic approach combining environmental control, mocking, and careful test design.

Understanding the Challenge

In scenarios where a feature is geo-blocked—say, a video player or subscription service available only in certain countries—your tests must reliably simulate different geographic contexts. Legacy React apps, often built without built-in support for such simulation, demand clever techniques to replicate location-specific conditions without invasive changes to the codebase.

Approaches to Testing Geo-Blocked Features

1. Mocking External Location Services

Most geo-restriction logic relies on external IP geolocation APIs or browser locale settings. Mocking these dependencies is essential.

Mocking API Calls

Suppose your app fetches the user's location via an API:

// Actual fetch implementation
fetch('/api/location')
  .then(res => res.json())
  .then(data => {
    // handle location data
  });
Enter fullscreen mode Exit fullscreen mode

For testing, you can intercept and mock the API response:

// In your test setup or using Jest
jest.spyOn(global, 'fetch').mockImplementation((url) => {
  if (url === '/api/location') {
    return Promise.resolve({
      json: () => Promise.resolve({ country: 'BR' }) // Brazil, geo-allowed
    });
  }
  return fetch(url);
});
Enter fullscreen mode Exit fullscreen mode

This allows simulating different countries without changing the app code.

2. Overriding Browser Locale and Geolocation APIs

Many apps utilize navigator.geolocation or navigator.language. These can be overridden during tests:

// Overriding geolocation
Object.defineProperty(navigator, 'geolocation', {
  value: {
    getCurrentPosition: jest.fn().mockImplementation((success) => {
      success({ coords: { latitude: 37.7749, longitude: -122.4194 } });
    })
  }
});
Enter fullscreen mode Exit fullscreen mode

Similarly, for navigator.language:

Object.defineProperty(navigator, 'language', {
  value: 'en-US',
  configurable: true
});
Enter fullscreen mode Exit fullscreen mode

This method is useful for simulating locale-based restrictions.

3. Environment Simulation via Environment Variables

Legacy apps may not have a dedicated mock-friendly architecture. In such cases, leveraging environment variables at runtime helps control feature toggles based on location.

// In your app logic
const userCountry = process.env.USER_COUNTRY || 'US';

const isFeatureAvailable = ['US', 'CA', 'UK'].includes(userCountry);

// In test, set environment variables accordingly
process.env.USER_COUNTRY = 'BR';
Enter fullscreen mode Exit fullscreen mode

Note:

Ensure your build process supports switching environment variables during testing.

Testing in Practice

Here's a sample test case using React Testing Library and Jest:

import { render, screen } from '@testing-library/react';
import App from '../App';

test('renders geo-allowed content for Brazil', async () => {
  // Mock API response for Brazil
  jest.spyOn(global, 'fetch').mockImplementationOnce(() =>
    Promise.resolve({ json: () => Promise.resolve({ country: 'BR' }) })
  );

  render(<App />);

  const content = await screen.findByText('Welcome to our Brazil site!');
  expect(content).toBeInTheDocument();
});

test('blocks content for North Korea', async () => {
  jest.spyOn(global, 'fetch').mockImplementationOnce(() =>
    Promise.resolve({ json: () => Promise.resolve({ country: 'KP' }) })
  );

  render(<App />);

  const blockedMessage = await screen.findByText('Content not available in your region.');
  expect(blockedMessage).toBeInTheDocument();
});
Enter fullscreen mode Exit fullscreen mode

Best Practices

  • Isolate location logic: Encapsulate geo-determination in modules that can be easily mocked.
  • Use feature flags: Enable or disable features based on simulated location in testing environments.
  • Leverage headless browsers: Use Puppeteer or Playwright to manipulate navigator properties for end-to-end tests.
  • Maintain test environment consistency: Always reset mocks after each test.

Conclusion

Testing geo-blocked features in legacy React applications demands a combination of mocking external dependencies and manipulating runtime environment variables. By carefully designing tests around these principles, QA engineers can ensure reliable coverage and seamless user experiences across different regions, even within complex, aged codebases.

References


🛠️ QA Tip

To test this safely without using real user data, I use TempoMail USA.

Top comments (0)