From 312389ba7f8516ea5e61f65796a8e9f38a733495 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sat, 9 Dec 2023 14:22:28 -0500 Subject: [PATCH] Merge branch 'ags/inject-theme-css' of github.com:openedx/frontend-platform into ags/inject-theme-css --- .../hooks/paragon/useParagonTheme.test.js | 38 ++++++++ .../hooks/paragon/useParagonThemeCore.test.js | 2 +- src/react/hooks/paragon/utils.test.js | 95 +++++++++++++++++++ 3 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 src/react/hooks/paragon/useParagonTheme.test.js create mode 100644 src/react/hooks/paragon/utils.test.js diff --git a/src/react/hooks/paragon/useParagonTheme.test.js b/src/react/hooks/paragon/useParagonTheme.test.js new file mode 100644 index 000000000..b72307db8 --- /dev/null +++ b/src/react/hooks/paragon/useParagonTheme.test.js @@ -0,0 +1,38 @@ +import { act, renderHook } from '@testing-library/react-hooks'; +import useParagonTheme from './useParagonTheme'; + +describe('useParagonTheme', () => { + it('should return an array with and object that indicates the theme status, and a function', () => { + const config = { + PARAGON_THEME_URLS: { + core: { + urls: { + default: 'https://cdn.jsdelivr.net/npm/@edx/paragon@$paragonVersion/dist/core.min.css', + }, + }, + defaults: { + light: 'light', + dark: 'dark', + }, + variants: { + light: { + urls: { + default: 'https://cdn.jsdelivr.net/npm/@edx/paragon@$paragonVersion/dist/light.min.css', + }, + }, + dark: { + urls: { + default: 'https://cdn.jsdelivr.net/npm/@edx/paragon@$paragonVersion/dist/dark.min.css', + }, + }, + }, + }, + }; + + const { result } = renderHook(() => useParagonTheme(config)); + const createdLinksTag = document.head.querySelectorAll('link'); + act(() => { createdLinksTag.forEach((link) => link.onload()); }); + + expect(result.current).toEqual([{ isThemeLoaded: true, themeVariant: 'light' }, expect.any(Function)]); + }); +}); diff --git a/src/react/hooks/paragon/useParagonThemeCore.test.js b/src/react/hooks/paragon/useParagonThemeCore.test.js index 1eecf876c..9df01d8ad 100644 --- a/src/react/hooks/paragon/useParagonThemeCore.test.js +++ b/src/react/hooks/paragon/useParagonThemeCore.test.js @@ -33,7 +33,7 @@ describe('useParagonThemeCore', () => { themeCore: { urls: { default: 'https://cdn.jsdelivr.net/npm/@edx/paragon@$21.0.0/dist/core.min.css', - brandOverride: 'https://cdn.jsdelivr.net/npm/@edx/brand@$2.0.0Version/dist/core.min.css', + brandOverride: 'https://cdn.jsdelivr.net/npm/@edx/brand@$2.0.0/dist/core.min.css', }, }, onLoad: themeOnLoad, diff --git a/src/react/hooks/paragon/utils.test.js b/src/react/hooks/paragon/utils.test.js new file mode 100644 index 000000000..77edce2e6 --- /dev/null +++ b/src/react/hooks/paragon/utils.test.js @@ -0,0 +1,95 @@ +import { removeExistingLinks, getDefaultThemeVariant, handleVersionSubstitution } from './utils'; + +Object.defineProperty(window, 'matchMedia', { + writable: true, + value: jest.fn().mockImplementation(query => ({ + matches: true, + media: query, + })), +}); + +const mockGetItem = jest.fn(); +Object.defineProperty(window, 'localStorage', { + value: { + getItem: mockGetItem, + }, +}); + +describe('removeExistingLinks', () => { + afterEach(() => { + document.head.innerHTML = ''; + jest.clearAllMocks(); + }); + + it('should remove all the links in the DOM', () => { + document.head.innerHTML = ` + + + + `; + + removeExistingLinks(document.querySelectorAll('link')); + expect(document.querySelectorAll('link').length).toBe(0); + }); +}); + +describe('getDefaultThemeVariant', () => { + it('should return the theme variant according with system preference', () => { + const variant = getDefaultThemeVariant({ + themeVariantDefaults: { + light: 'light', + dark: 'dark', + }, + themeVariants: { + light: { + fileName: 'light.min.css', + }, + dark: { + fileName: 'dark.min.css', + }, + }, + }); + expect(variant).toEqual({ metadata: { fileName: 'dark.min.css' }, name: 'dark' }); + }); + + it('should return the theme variant according with local storage preference', () => { + mockGetItem.mockImplementation(() => 'light'); + const variant = getDefaultThemeVariant({ + themeVariantDefaults: { + light: 'light', + dark: 'dark', + }, + themeVariants: { + light: { + fileName: 'light.min.css', + }, + dark: { + fileName: 'dark.min.css', + }, + }, + }); + expect(variant).toEqual({ metadata: { fileName: 'light.min.css' }, name: 'light' }); + }); + + it('should return the theme variant configuration as default', () => { + const variant = getDefaultThemeVariant({ + themeVariantDefaults: { + light: 'light', + }, + themeVariants: { + light: { + fileName: 'light.min.css', + }, + }, + }); + expect(variant).toEqual({ metadata: { fileName: 'light.min.css' }, name: 'light' }); + }); +}); + +describe('handleVersionSubstitution', () => { + it('should substitude the paragon version to use', () => { + const config = { localVersion: '21.1.1', wildcardKeyword: 'alpha', url: 'https://cdn.jsdelivr.net/npm/@edx/paragon@alpha/dist/core.min.css' }; + const newLink = handleVersionSubstitution(config); + expect(newLink).toBe('https://cdn.jsdelivr.net/npm/@edx/paragon@21.1.1/dist/core.min.css'); + }); +});