import { renderHook, act } from '@testing-library/react';
import { ThemeProvider } from './ThemeProvider';
import { DEFAULT_BASE_THEME, DEFAULT_SCREEN_MODE } from './const';
import { useTheme } from './useTheme';
describe('useTheme', () => {
it('returns default light theme', () => {
jest.spyOn(console, 'warn').mockImplementation();
const {
result: { current },
} = renderHook(() => useTheme());
expect(current).toMatchObject({
theme: DEFAULT_BASE_THEME,
screenMode: DEFAULT_SCREEN_MODE,
isModern: true,
isForestGreenTheme: false,
isScreenModeDark: false,
className: 'np-theme-personal',
});
expect(current.setTheme).toBeInstanceOf(Function);
expect(current.setScreenMode).toBeInstanceOf(Function);
jest.clearAllMocks();
});
it('returns personal theme', () => {
const {
result: { current },
} = renderHook(() => useTheme(), {
wrapper: (props) => ,
});
expect(current).toMatchObject({
theme: 'personal',
screenMode: DEFAULT_SCREEN_MODE,
isModern: true,
isForestGreenTheme: false,
isScreenModeDark: false,
className: 'np-theme-personal',
});
expect(current.setTheme).toBeInstanceOf(Function);
expect(current.setScreenMode).toBeInstanceOf(Function);
});
it('returns forest-green theme', () => {
const {
result: { current },
} = renderHook(() => useTheme(), {
wrapper: (props) => ,
});
expect(current).toMatchObject({
theme: 'forest-green',
screenMode: DEFAULT_SCREEN_MODE,
isModern: true,
isForestGreenTheme: true,
isScreenModeDark: false,
className: 'np-theme-personal np-theme-personal--forest-green',
});
expect(current.setTheme).toBeInstanceOf(Function);
expect(current.setScreenMode).toBeInstanceOf(Function);
});
it('returns bright-green theme', () => {
const {
result: { current },
} = renderHook(() => useTheme(), {
wrapper: (props) => ,
});
expect(current).toMatchObject({
theme: 'bright-green',
screenMode: DEFAULT_SCREEN_MODE,
isModern: true,
isForestGreenTheme: false,
isScreenModeDark: false,
className: 'np-theme-personal np-theme-personal--bright-green',
});
expect(current.setTheme).toBeInstanceOf(Function);
expect(current.setScreenMode).toBeInstanceOf(Function);
});
it('returns default screen mode if used light theme', () => {
const {
result: { current },
} = renderHook(() => useTheme(), {
wrapper: (props) => ,
});
expect(current).toMatchObject({
theme: DEFAULT_BASE_THEME,
screenMode: DEFAULT_SCREEN_MODE,
isModern: true,
isForestGreenTheme: false,
isScreenModeDark: false,
className: 'np-theme-personal',
});
expect(current.setTheme).toBeInstanceOf(Function);
expect(current.setScreenMode).toBeInstanceOf(Function);
});
it('returns dark screen mode if used light theme + dark screen mode', () => {
const {
result: { current },
} = renderHook(() => useTheme(), {
wrapper: (props) => ,
});
expect(current).toMatchObject({
theme: DEFAULT_BASE_THEME,
screenMode: 'dark',
isModern: true,
isForestGreenTheme: false,
isScreenModeDark: true,
className: 'np-theme-personal np-theme-personal--dark',
});
expect(current.setTheme).toBeInstanceOf(Function);
expect(current.setScreenMode).toBeInstanceOf(Function);
});
it('returns dark screen mode', () => {
const {
result: { current },
} = renderHook(() => useTheme(), {
wrapper: (props) => ,
});
expect(current).toMatchObject({
theme: 'personal',
screenMode: 'dark',
isModern: true,
isForestGreenTheme: false,
isScreenModeDark: true,
className: 'np-theme-personal np-theme-personal--dark',
});
expect(current.setTheme).toBeInstanceOf(Function);
expect(current.setScreenMode).toBeInstanceOf(Function);
});
it('warns when used outside a theme provider on staging or localhost', () => {
jest.spyOn(console, 'warn').mockImplementation();
Object.defineProperty(window, 'location', {
value: {
hostname: 'wise.com',
},
writable: true,
});
const {
result: { current: productionValue },
} = renderHook(() => useTheme());
expect(productionValue).toMatchObject({
theme: DEFAULT_BASE_THEME,
screenMode: DEFAULT_SCREEN_MODE,
isModern: true,
isForestGreenTheme: false,
isScreenModeDark: false,
className: 'np-theme-personal',
});
expect(productionValue.setTheme).toBeInstanceOf(Function);
expect(productionValue.setScreenMode).toBeInstanceOf(Function);
// eslint-disable-next-line no-console
expect(console.warn).not.toHaveBeenCalled();
Object.defineProperty(window, 'location', {
value: {
hostname: 'dev-wi.se',
},
writable: true,
});
const {
result: { current: stagingValue },
} = renderHook(() => useTheme());
expect(stagingValue).toMatchObject({
theme: DEFAULT_BASE_THEME,
screenMode: DEFAULT_SCREEN_MODE,
isModern: true,
isForestGreenTheme: false,
isScreenModeDark: false,
className: 'np-theme-personal',
});
expect(stagingValue.setTheme).toBeInstanceOf(Function);
expect(stagingValue.setScreenMode).toBeInstanceOf(Function);
// eslint-disable-next-line no-console
expect(console.warn).toHaveBeenCalledTimes(1);
Object.defineProperty(window, 'location', {
value: {
hostname: 'localhost',
},
writable: true,
});
const {
result: { current: localhostValue },
} = renderHook(() => useTheme());
expect(localhostValue).toMatchObject({
theme: DEFAULT_BASE_THEME,
screenMode: DEFAULT_SCREEN_MODE,
isModern: true,
isForestGreenTheme: false,
isScreenModeDark: false,
className: 'np-theme-personal',
});
expect(localhostValue.setTheme).toBeInstanceOf(Function);
expect(localhostValue.setScreenMode).toBeInstanceOf(Function);
// eslint-disable-next-line no-console
expect(console.warn).toHaveBeenCalledTimes(2);
Object.defineProperty(window, 'location', {
value: undefined,
writable: true,
});
const {
result: { current: noHostnameValue },
} = renderHook(() => useTheme());
expect(noHostnameValue).toMatchObject({
theme: DEFAULT_BASE_THEME,
screenMode: DEFAULT_SCREEN_MODE,
isModern: true,
isForestGreenTheme: false,
isScreenModeDark: false,
className: 'np-theme-personal',
});
expect(noHostnameValue.setTheme).toBeInstanceOf(Function);
expect(noHostnameValue.setScreenMode).toBeInstanceOf(Function);
// eslint-disable-next-line no-console
expect(console.warn).toHaveBeenCalledTimes(2);
jest.clearAllMocks();
});
it('allows theme changes from child components via setTheme', async () => {
const { result } = renderHook(() => useTheme(), {
wrapper: (props) => ,
});
expect(result.current.theme).toBe('personal');
// Change theme using setTheme
await act(async () => {
result.current.setTheme('business');
});
expect(result.current.theme).toBe('business');
});
it('allows screen mode changes from child components via setScreenMode', async () => {
const { result } = renderHook(() => useTheme(), {
wrapper: (props) => ,
});
expect(result.current.screenMode).toBe('light');
// Change screen mode using setScreenMode
await act(async () => {
result.current.setScreenMode('dark');
});
expect(result.current.screenMode).toBe('dark');
});
});