From d9d9e4f1597313b2d11a44d8f7867b9f75b62f5e Mon Sep 17 00:00:00 2001 From: Javier Cortejoso Date: Thu, 11 Dec 2025 18:57:55 +0100 Subject: [PATCH] Refactor NFC scanner tests to use a global variable for platform OS, allowing dynamic switching between iOS and Android during tests. This change improves test isolation and avoids hoisting issues with jest.mock. --- .../src/integrations/nfc/nfcScanner.test.ts | 47 +++++++++++-------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/app/tests/src/integrations/nfc/nfcScanner.test.ts b/app/tests/src/integrations/nfc/nfcScanner.test.ts index 9fed64ff4..fa7d8350a 100644 --- a/app/tests/src/integrations/nfc/nfcScanner.test.ts +++ b/app/tests/src/integrations/nfc/nfcScanner.test.ts @@ -3,19 +3,35 @@ // NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE. // Mock Platform without requiring react-native to avoid memory issues -// Use a simple object that can be modified directly +// Use a global variable with getter to allow per-test platform switching +// This pattern avoids hoisting issues with jest.mock import { Buffer } from 'buffer'; import { parseScanResponse, scan } from '@/integrations/nfc/nfcScanner'; import { PassportReader } from '@/integrations/nfc/passportReader'; -const Platform = { - OS: 'ios', // Default to iOS - Version: 14, -}; +// Declare global variable for platform OS that can be modified per-test +declare global { + // eslint-disable-next-line no-var + var mockPlatformOS: 'ios' | 'android'; +} +// Initialize the global mock platform - default to iOS +global.mockPlatformOS = 'ios'; + +// Override the react-native mock from jest.setup.js with a getter-based Platform +// This allows tests to change Platform.OS dynamically by modifying global.mockPlatformOS jest.mock('react-native', () => ({ - Platform, + Platform: { + get OS() { + return global.mockPlatformOS; + }, + Version: 14, + select: jest.fn((obj: Record) => { + const os = global.mockPlatformOS; + return obj[os] || obj.default; + }), + }, })); // Ensure the Node Buffer implementation is available to the module under test @@ -25,7 +41,7 @@ describe('parseScanResponse', () => { beforeEach(() => { jest.clearAllMocks(); // Reset Platform.OS to default before each test to prevent pollution - Platform.OS = 'ios'; + global.mockPlatformOS = 'ios'; }); it('parses iOS response', () => { @@ -56,9 +72,8 @@ describe('parseScanResponse', () => { }); it('parses Android response', () => { - // Temporarily override Platform.OS for this test - const originalOS = Platform.OS; - Platform.OS = 'android'; + // Set Platform.OS to android for this test + global.mockPlatformOS = 'android'; const mrz = 'P { // dg2Hash should be parsed from hex string '1234': 12 = 18, 34 = 52 expect(result.dg2Hash).toEqual([18, 52]); expect(result.dgPresents).toEqual([1, 2]); - - // Restore original value - Platform.OS = originalOS; }); it('handles malformed iOS response', () => { @@ -93,8 +105,8 @@ describe('parseScanResponse', () => { }); it('handles malformed Android response', () => { - const originalOS = Platform.OS; - Platform.OS = 'android'; + // Set Platform.OS to android for this test + global.mockPlatformOS = 'android'; const response = { mrz: 'valid_mrz', @@ -103,9 +115,6 @@ describe('parseScanResponse', () => { }; expect(() => parseScanResponse(response)).toThrow(); - - // Restore original value - Platform.OS = originalOS; }); it('handles missing required fields', () => { @@ -153,7 +162,7 @@ describe('scan', () => { beforeEach(() => { jest.clearAllMocks(); // Reset Platform.OS to default before each test to prevent pollution - Platform.OS = 'ios'; + global.mockPlatformOS = 'ios'; // Reset PassportReader mock before each test // The implementation checks for scanPassport property, so we need to ensure it exists Object.defineProperty(PassportReader, 'scanPassport', {