/* eslint-disable max-len */ import { Helpers } from '../helpers'; // Mock navigator for testing const mockNavigator = (userAgent: string, maxTouchPoints: number = 0) => { Object.defineProperty(window, 'navigator', { value: { userAgent, maxTouchPoints, }, writable: true, }); }; const mockScreen = (width: number) => { Object.defineProperty(window, 'screen', { value: { width }, writable: true, }); }; // Mock touch support const mockTouchSupport = (hasTouch: boolean) => { if (hasTouch) { Object.defineProperty(window, 'ontouchstart', { value: () => {}, writable: true, }); } else { delete (window as any).ontouchstart; } }; describe('helpers', () => { describe('chunkArray', () => { it('should split array into chunks', () => { const arr = [1, 2, 3, 4, 5, 6, 7, 8]; const chunks = Helpers.chunkArray(arr, 3); expect(chunks).toStrictEqual([ [1, 2, 3], [4, 5, 6], [7, 8], ]); }); it('should return only one chunk', () => { const arr = [1, 2, 3, 4, 5, 6, 7, 8]; const chunks = Helpers.chunkArray(arr, 10); expect(chunks).toStrictEqual([[1, 2, 3, 4, 5, 6, 7, 8]]); }); it('should return an empty array', () => { const arr: any[] = []; const chunks = Helpers.chunkArray(arr, 10); expect(chunks).toStrictEqual([]); }); }); describe('isMobileDevice', () => { afterEach(() => { // Reset to default desktop state mockNavigator('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'); mockTouchSupport(false); }); it('should return true for iPhone', () => { mockNavigator('Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15'); mockTouchSupport(true); expect(Helpers.isMobileDevice()).toBe(true); }); it('should return true for iPad', () => { mockNavigator('Mozilla/5.0 (iPad; CPU OS 14_0 like Mac OS X) AppleWebKit/605.1.15'); mockTouchSupport(true); expect(Helpers.isMobileDevice()).toBe(true); }); it('should return true for Android', () => { mockNavigator('Mozilla/5.0 (Linux; Android 10; SM-G975F) AppleWebKit/537.36'); mockTouchSupport(true); expect(Helpers.isMobileDevice()).toBe(true); }); it('should return false for desktop without touch', () => { mockNavigator('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'); mockTouchSupport(false); expect(Helpers.isMobileDevice()).toBe(false); }); it('should return false for desktop with touch but no mobile user agent', () => { mockNavigator('Mozilla/5.0 (Windows NT 10.0; Touch; Win64; x64) AppleWebKit/537.36'); mockTouchSupport(true); expect(Helpers.isMobileDevice()).toBe(false); }); it('should return false when navigator is undefined', () => { Object.defineProperty(window, 'navigator', { value: undefined, writable: true, }); expect(Helpers.isMobileDevice()).toBe(false); }); }); describe('getDeviceCategory', () => { afterEach(() => { mockNavigator('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', 0); mockScreen(1920); }); it('should return "mobile" for iPhone', () => { mockNavigator( 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15', 5, ); expect(Helpers.getDeviceCategory()).toBe('mobile'); }); it('should return "mobile" for Android phone', () => { mockNavigator( 'Mozilla/5.0 (Linux; Android 13; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Mobile Safari/537.36', 5, ); expect(Helpers.getDeviceCategory()).toBe('mobile'); }); it('should return "mobile" for iPad (legacy UA)', () => { mockNavigator( 'Mozilla/5.0 (iPad; CPU OS 12_0 like Mac OS X) AppleWebKit/605.1.15', 5, ); expect(Helpers.getDeviceCategory()).toBe('mobile'); }); it('should return "mobile" for iPad iOS 13+ (Macintosh UA with touch points)', () => { mockNavigator( 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15', 5, ); expect(Helpers.getDeviceCategory()).toBe('mobile'); }); it('should return "desktop" for Windows', () => { mockNavigator( 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', 0, ); expect(Helpers.getDeviceCategory()).toBe('desktop'); }); it('should return "desktop" for Mac desktop without touch', () => { mockNavigator( 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Safari/537.36', 0, ); expect(Helpers.getDeviceCategory()).toBe('desktop'); }); it('should return "desktop" for Chrome OS', () => { mockNavigator( 'Mozilla/5.0 (X11; CrOS x86_64 14541.0.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', 0, ); expect(Helpers.getDeviceCategory()).toBe('desktop'); }); it('should return "desktop" for Linux desktop', () => { mockNavigator( 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Safari/537.36', 0, ); expect(Helpers.getDeviceCategory()).toBe('desktop'); }); it('should return "other" for PlayStation', () => { mockNavigator('Mozilla/5.0 (PlayStation 5) AppleWebKit/605.1.15', 0); expect(Helpers.getDeviceCategory()).toBe('other'); }); it('should return "other" for Samsung Smart TV (Tizen)', () => { mockNavigator('Mozilla/5.0 (SMART-TV; Linux; Tizen 6.0) AppleWebKit/538.1', 0); expect(Helpers.getDeviceCategory()).toBe('other'); }); it('should return "other" for LG Smart TV (webOS without Mobile)', () => { mockNavigator('Mozilla/5.0 (webOS; U; en-US) AppleWebKit/537.36', 0); expect(Helpers.getDeviceCategory()).toBe('other'); }); it('should return "other" when navigator is undefined', () => { Object.defineProperty(window, 'navigator', { value: undefined, writable: true, }); expect(Helpers.getDeviceCategory()).toBe('other'); }); it('should return "other" for completely unknown UA on wide screen without touch', () => { mockNavigator('SomeUnknownBrowser/1.0', 0); mockScreen(1920); expect(Helpers.getDeviceCategory()).toBe('other'); }); it('should return "mobile" for unknown UA with touch and small screen', () => { mockNavigator('SomeUnknownBrowser/1.0', 1); mockScreen(375); expect(Helpers.getDeviceCategory()).toBe('mobile'); }); }); });