From f7162c9ab6f4c79922f14e3ebf450e42a47e9fcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Vay=C3=A1?= Date: Mon, 4 Aug 2025 10:41:03 +0200 Subject: [PATCH] Fix flaky biometric authentication test (#8995) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix flaky biometric authentication test Eliminates timing race conditions in SecurityManager test by using fixed timestamps instead of real Date.now() values. The test was failing inconsistently due to timing variations between test runs. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude * use fake timers * revert changes --------- Co-authored-by: Claude --- app/managers/security_manager/index.test.ts | 28 +++++++++++++++++---- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/app/managers/security_manager/index.test.ts b/app/managers/security_manager/index.test.ts index 0d6210838..2b9db6198 100644 --- a/app/managers/security_manager/index.test.ts +++ b/app/managers/security_manager/index.test.ts @@ -344,11 +344,29 @@ describe('SecurityManager', () => { }); test('should not attempt biometric authentication if server was previously authenticated within 5 mins', async () => { - SecurityManager.addServer('server-12', {MobileEnableBiometrics: 'true'} as ClientConfig, true); - SecurityManager.serverConfig['server-12'].lastAccessed = Date.now() - toMilliseconds({minutes: 1}); - await expect(SecurityManager.authenticateWithBiometricsIfNeeded('server-12')).resolves.toBe(true); - expect(Emm.isDeviceSecured).not.toHaveBeenCalled(); - expect(Emm.authenticate).not.toHaveBeenCalled(); + // Mock toMilliseconds locally to return correct value for this test + const originalToMilliseconds = jest.requireActual('@utils/datetime').toMilliseconds; + jest.mocked(require('@utils/datetime').toMilliseconds).mockImplementation(originalToMilliseconds); + + // Use a fixed timestamp instead of Date.now() to eliminate timing races + const fixedTime = 1672574400000; // Fixed timestamp: Jan 1, 2023 12:00:00 GMT + const oneMinuteAgo = fixedTime - (60 * 1000); + + // Mock Date.now to return our fixed time + const originalDateNow = Date.now; + Date.now = jest.fn(() => fixedTime); + + try { + SecurityManager.addServer('server-12', {MobileEnableBiometrics: 'true'} as ClientConfig, true); + SecurityManager.serverConfig['server-12'].lastAccessed = oneMinuteAgo; + await expect(SecurityManager.authenticateWithBiometricsIfNeeded('server-12')).resolves.toBe(true); + expect(Emm.isDeviceSecured).not.toHaveBeenCalled(); + expect(Emm.authenticate).not.toHaveBeenCalled(); + } finally { + // Restore original implementations + Date.now = originalDateNow; + jest.mocked(require('@utils/datetime').toMilliseconds).mockReturnValue(25000); + } }); test('should not attempt biometric authentication if server was previously failed authentication even though lastAccess is less than 5 mins', async () => {