/** * Unit tests for browserCheck module */ import { isBrowserSupported, getBrowserInfo, getRecommendedBrowsers, getUnsupportedMessage, } from '../lib/browserCheck'; describe('browserCheck', () => { // Store original navigator const originalNavigator = global.navigator; beforeEach(() => { // Reset navigator before each test Object.defineProperty(global, 'navigator', { writable: true, configurable: true, value: { userAgent: '', platform: '', }, }); }); afterEach(() => { // Restore original navigator Object.defineProperty(global, 'navigator', { writable: true, configurable: true, value: originalNavigator, }); }); describe('isBrowserSupported', () => { it('should return true for Chrome 70+', () => { Object.defineProperty(global.navigator, 'userAgent', { writable: true, value: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.0.0 Safari/537.36', }); Object.defineProperty(global.navigator, 'platform', { writable: true, value: 'Win32', }); Object.defineProperty(global.navigator, 'bluetooth', { writable: true, value: {}, }); expect(isBrowserSupported()).toBe(true); }); it('should return false for Chrome below version 70', () => { Object.defineProperty(global.navigator, 'userAgent', { writable: true, value: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.0.0 Safari/537.36', }); Object.defineProperty(global.navigator, 'platform', { writable: true, value: 'Win32', }); expect(isBrowserSupported()).toBe(false); }); it('should return true for Edge 79+', () => { Object.defineProperty(global.navigator, 'userAgent', { writable: true, value: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.0.0 Safari/537.36 Edg/100.0.0.0', }); Object.defineProperty(global.navigator, 'platform', { writable: true, value: 'Win32', }); Object.defineProperty(global.navigator, 'bluetooth', { writable: true, value: {}, }); expect(isBrowserSupported()).toBe(true); }); it('should return false for Edge below version 79', () => { Object.defineProperty(global.navigator, 'userAgent', { writable: true, value: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.0.0 Safari/537.36 Edg/78.0.0.0', }); Object.defineProperty(global.navigator, 'platform', { writable: true, value: 'Win32', }); expect(isBrowserSupported()).toBe(false); }); it('should return true for Opera 57+', () => { Object.defineProperty(global.navigator, 'userAgent', { writable: true, value: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.0.0 Safari/537.36 OPR/86.0.0.0', }); Object.defineProperty(global.navigator, 'platform', { writable: true, value: 'Win32', }); Object.defineProperty(global.navigator, 'bluetooth', { writable: true, value: {}, }); expect(isBrowserSupported()).toBe(true); }); it('should return false for Opera below version 57', () => { Object.defineProperty(global.navigator, 'userAgent', { writable: true, value: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.0.0 Safari/537.36 OPR/56.0.0.0', }); Object.defineProperty(global.navigator, 'platform', { writable: true, value: 'Win32', }); expect(isBrowserSupported()).toBe(false); }); it('should return false for Safari', () => { Object.defineProperty(global.navigator, 'userAgent', { writable: true, value: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Safari/605.1.15', }); Object.defineProperty(global.navigator, 'platform', { writable: true, value: 'MacIntel', }); expect(isBrowserSupported()).toBe(false); }); it('should return false for Firefox', () => { Object.defineProperty(global.navigator, 'userAgent', { writable: true, value: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0', }); Object.defineProperty(global.navigator, 'platform', { writable: true, value: 'Win32', }); expect(isBrowserSupported()).toBe(false); }); it('should return false for iOS browsers', () => { Object.defineProperty(global.navigator, 'userAgent', { writable: true, value: 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1', }); Object.defineProperty(global.navigator, 'platform', { writable: true, value: 'iPhone', }); expect(isBrowserSupported()).toBe(false); }); }); describe('getBrowserInfo', () => { it('should return correct info for Chrome on Windows', () => { Object.defineProperty(global.navigator, 'userAgent', { writable: true, value: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.0.0 Safari/537.36', }); Object.defineProperty(global.navigator, 'platform', { writable: true, value: 'Win32', }); Object.defineProperty(global.navigator, 'bluetooth', { writable: true, value: {}, }); const info = getBrowserInfo(); expect(info.name).toBe('Chrome'); expect(info.version).toBe('100'); expect(info.platform).toBe('Windows'); expect(info.hasWebBluetooth).toBe(true); expect(info.isSupported).toBe(true); }); it('should return correct info for Edge on macOS', () => { Object.defineProperty(global.navigator, 'userAgent', { writable: true, value: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.0.0 Safari/537.36 Edg/100.0.0.0', }); Object.defineProperty(global.navigator, 'platform', { writable: true, value: 'MacIntel', }); Object.defineProperty(global.navigator, 'bluetooth', { writable: true, value: {}, }); const info = getBrowserInfo(); expect(info.name).toBe('Edge'); expect(info.version).toBe('100'); expect(info.platform).toBe('macOS'); expect(info.hasWebBluetooth).toBe(true); expect(info.isSupported).toBe(true); }); it('should detect when Web Bluetooth is not available', () => { Object.defineProperty(global.navigator, 'userAgent', { writable: true, value: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.0.0 Safari/537.36', }); Object.defineProperty(global.navigator, 'platform', { writable: true, value: 'Win32', }); // Explicitly delete bluetooth property delete (global.navigator as any).bluetooth; const info = getBrowserInfo(); expect(info.hasWebBluetooth).toBe(false); }); it('should handle Safari correctly', () => { Object.defineProperty(global.navigator, 'userAgent', { writable: true, value: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Safari/605.1.15', }); Object.defineProperty(global.navigator, 'platform', { writable: true, value: 'MacIntel', }); const info = getBrowserInfo(); expect(info.name).toBe('Safari'); expect(info.isSupported).toBe(false); }); }); describe('getRecommendedBrowsers', () => { it('should return an array of recommended browsers', () => { const browsers = getRecommendedBrowsers(); expect(Array.isArray(browsers)).toBe(true); expect(browsers.length).toBeGreaterThan(0); }); it('should include Chrome, Edge, and Opera', () => { const browsers = getRecommendedBrowsers(); const browserNames = browsers.map((b) => b.name); expect(browserNames).toContain('Google Chrome'); expect(browserNames).toContain('Microsoft Edge'); expect(browserNames).toContain('Opera'); }); it('should have correct minimum versions', () => { const browsers = getRecommendedBrowsers(); const chrome = browsers.find((b) => b.name === 'Google Chrome'); const edge = browsers.find((b) => b.name === 'Microsoft Edge'); const opera = browsers.find((b) => b.name === 'Opera'); expect(chrome?.minVersion).toBe('70'); expect(edge?.minVersion).toBe('79'); expect(opera?.minVersion).toBe('57'); }); it('should include download URLs', () => { const browsers = getRecommendedBrowsers(); browsers.forEach((browser) => { expect(browser.downloadUrl).toBeTruthy(); expect(browser.downloadUrl.startsWith('https://')).toBe(true); }); }); it('should include platform information', () => { const browsers = getRecommendedBrowsers(); browsers.forEach((browser) => { expect(Array.isArray(browser.platforms)).toBe(true); expect(browser.platforms.length).toBeGreaterThan(0); }); }); }); describe('getUnsupportedMessage', () => { it('should return iOS-specific message for iOS platform', () => { const browserInfo = { name: 'Safari', version: '16', isSupported: false, hasWebBluetooth: false, platform: 'iOS', }; const message = getUnsupportedMessage(browserInfo); expect(message).toContain('iOS'); expect(message).toContain('system limitations'); }); it('should return Safari-specific message', () => { const browserInfo = { name: 'Safari', version: '16', isSupported: false, hasWebBluetooth: false, platform: 'macOS', }; const message = getUnsupportedMessage(browserInfo); expect(message).toContain('Safari'); expect(message).toContain('does not support'); }); it('should return Firefox-specific message', () => { const browserInfo = { name: 'Firefox', version: '115', isSupported: false, hasWebBluetooth: false, platform: 'Windows', }; const message = getUnsupportedMessage(browserInfo); expect(message).toContain('Firefox'); expect(message).toContain('privacy concerns'); }); it('should return generic message for browsers without Web Bluetooth', () => { const browserInfo = { name: 'Chrome', version: '50', isSupported: false, hasWebBluetooth: false, platform: 'Windows', }; const message = getUnsupportedMessage(browserInfo); expect(message).toContain('does not support'); expect(message).toContain('Web Bluetooth API'); }); it('should return version requirement message for supported browsers with old versions', () => { const browserInfo = { name: 'Chrome', version: '69', isSupported: false, hasWebBluetooth: true, platform: 'Windows', }; const message = getUnsupportedMessage(browserInfo); expect(message).toContain('Chrome 70+'); }); }); });