diff --git a/packages/core/jest-setup.ts b/packages/core/jest-setup.ts index 218b757c..84a0f78b 100644 --- a/packages/core/jest-setup.ts +++ b/packages/core/jest-setup.ts @@ -1,22 +1,25 @@ -// Initialize error array -window.testErrors = [] +// window is absent in node-environment suites (SSR specs) +if (typeof window !== 'undefined') { + // Initialize error array + window.testErrors = [] -// Add global error listener -window.addEventListener('error', (event: MyErrorEvent) => { - window.testErrors.push({ - message: event.message, - filename: event.filename, - lineno: event.lineno, - colno: event.colno, - error: event.error, + // Add global error listener + window.addEventListener('error', (event: MyErrorEvent) => { + window.testErrors.push({ + message: event.message, + filename: event.filename, + lineno: event.lineno, + colno: event.colno, + error: event.error, + }) }) -}) -// Jest configuration -beforeEach(() => { - // Clear error array before each test - window.testErrors = [] -}) + // Jest configuration + beforeEach(() => { + // Clear error array before each test + window.testErrors = [] + }) +} expect.extend({ toHaveErrorMatching(received: typeof window.testErrors, expectedError: string | RegExp) { diff --git a/packages/core/src/useOrientation/index.spec.ts b/packages/core/src/useOrientation/index.spec.ts index 9b1953c0..63540af9 100644 --- a/packages/core/src/useOrientation/index.spec.ts +++ b/packages/core/src/useOrientation/index.spec.ts @@ -75,4 +75,53 @@ describe('useOrientation', () => { expect(hook.result.current[0].type).toBe(void 0) expect(hook.result.current[0].angle).toBe(0) }) + + it('should lock orientation through screen.orientation.lock', () => { + const lockResult = Promise.resolve() + const lock = jest.fn().mockReturnValue(lockResult); + (window.screen.orientation as unknown) = { + type: 'landscape-primary', + angle: 0, + lock, + unlock: jest.fn(), + } + + const hook = getHook() + + expect(hook.result.current[1]('portrait')).toBe(lockResult) + expect(lock).toHaveBeenCalledWith('portrait') + }) + + it('should unlock orientation through screen.orientation.unlock', () => { + const unlock = jest.fn(); + (window.screen.orientation as unknown) = { + type: 'landscape-primary', + angle: 0, + lock: jest.fn(), + unlock, + } + + const hook = getHook() + hook.result.current[2]() + + expect(unlock).toHaveBeenCalledTimes(1) + }) + + it('should reject the lock when screen.orientation is not available', async () => { + delete (window.screen as { orientation?: unknown }).orientation + + const hook = getHook() + + await expect(hook.result.current[1]('portrait')).rejects.toThrow( + 'Not supported', + ) + }) + + it('should not throw when unlocking without screen.orientation', () => { + delete (window.screen as { orientation?: unknown }).orientation + + const hook = getHook() + + expect(hook.result.current[2]()).toBeUndefined() + }) }) diff --git a/packages/core/src/useOrientation/index.ssr.spec.tsx b/packages/core/src/useOrientation/index.ssr.spec.tsx new file mode 100644 index 00000000..350feeb3 --- /dev/null +++ b/packages/core/src/useOrientation/index.ssr.spec.tsx @@ -0,0 +1,33 @@ +/** + * @jest-environment node + */ + +import ReactDOMServer from 'react-dom/server' +import type { UseOrientationLockType } from './interface' +import { useOrientation } from '.' + +describe('useOrientation SSR', () => { + it('should not touch window when locking or unlocking on the server', () => { + let lockOrientation: ((type: UseOrientationLockType) => any) | undefined + let unlockOrientation: (() => void) | undefined + + function TestComponent() { + const [state, lock, unlock] = useOrientation() + lockOrientation = lock + unlockOrientation = unlock + return {`${state.type}:${state.angle}`} + } + + const markup = ReactDOMServer.renderToString() + + // Guard against a vacuous pass: the render must have happened and + // handed the real functions out before we exercise them. + expect(markup).toBe('landscape-primary:0') + expect(lockOrientation).toBeDefined() + expect(unlockOrientation).toBeDefined() + + expect(() => lockOrientation!('portrait')).not.toThrow() + expect(lockOrientation!('portrait')).toBeUndefined() + expect(() => unlockOrientation!()).not.toThrow() + }) +}) diff --git a/packages/core/src/useOrientation/index.ts b/packages/core/src/useOrientation/index.ts index 35580c0a..b0a52408 100644 --- a/packages/core/src/useOrientation/index.ts +++ b/packages/core/src/useOrientation/index.ts @@ -45,7 +45,7 @@ export const useOrientation: UseOrientation = ( }, []) const lockOrientation = (type: UseOrientationLockType) => { - if (isBrowser) { + if (!isBrowser) { return } if (!(window && 'screen' in window && 'orientation' in window.screen)) { @@ -55,7 +55,7 @@ export const useOrientation: UseOrientation = ( } const unlockOrientation = () => { - if (isBrowser) { + if (!isBrowser) { return } if (!(window && 'screen' in window && 'orientation' in window.screen)) {