diff --git a/packages/query-devtools/src/__tests__/utils.test.ts b/packages/query-devtools/src/__tests__/utils.test.ts index 1c30c5e918..30178af5ad 100644 --- a/packages/query-devtools/src/__tests__/utils.test.ts +++ b/packages/query-devtools/src/__tests__/utils.test.ts @@ -1,10 +1,12 @@ -import { describe, expect, it } from 'vitest' +import { afterEach, beforeEach, describe, expect, it } from 'vitest' import { + convertRemToPixels, deleteNestedDataByPath, displayValue, getMutationStatusColor, getQueryStatusColorByLabel, getSidedProp, + setupStyleSheet, updateNestedDataByPath, } from '../utils' import type { MutationStatus } from '@tanstack/query-core' @@ -846,4 +848,109 @@ describe('Utils tests', () => { expect(getSidedProp('padding', 'right')).toBe('paddingRight') }) }) + + describe('convertRemToPixels', () => { + beforeEach(() => { + document.documentElement.style.fontSize = '16px' + }) + + afterEach(() => { + document.documentElement.style.fontSize = '' + }) + + it('should convert 1 rem to the document root font size in pixels', () => { + expect(convertRemToPixels(1)).toBe(16) + }) + + it('should return 0 for 0 rem', () => { + expect(convertRemToPixels(0)).toBe(0) + }) + + it('should multiply rem by the document root font size', () => { + expect(convertRemToPixels(2)).toBe(32) + }) + + it('should support decimal rem values', () => { + expect(convertRemToPixels(0.5)).toBe(8) + }) + + it('should reflect the current document root font size', () => { + document.documentElement.style.fontSize = '20px' + expect(convertRemToPixels(1)).toBe(20) + }) + + it('should support negative rem values', () => { + expect(convertRemToPixels(-1)).toBe(-16) + }) + + it('should support non-integer font sizes', () => { + document.documentElement.style.fontSize = '15.5px' + expect(convertRemToPixels(1)).toBe(15.5) + }) + }) + + describe('setupStyleSheet', () => { + afterEach(() => { + document.head.querySelector('#_goober')?.remove() + }) + + it('should not insert any style tag when "nonce" is missing', () => { + setupStyleSheet() + + expect(document.head.querySelector('#_goober')).toBeNull() + }) + + it('should not insert any style tag when "nonce" is an empty string', () => { + setupStyleSheet('') + + expect(document.head.querySelector('#_goober')).toBeNull() + }) + + it('should append a style tag with id "_goober" to "document.head"', () => { + setupStyleSheet('test-nonce') + + const styleTag = document.head.querySelector('#_goober') + expect(styleTag).not.toBeNull() + expect(styleTag?.tagName).toBe('STYLE') + }) + + it('should set the "nonce" attribute on the inserted style tag', () => { + setupStyleSheet('test-nonce') + + expect( + document.head.querySelector('#_goober')?.getAttribute('nonce'), + ).toBe('test-nonce') + }) + + it('should not insert a duplicate style tag when "document.head" already has one', () => { + setupStyleSheet('first-nonce') + setupStyleSheet('second-nonce') + + const styleTags = document.head.querySelectorAll('#_goober') + expect(styleTags).toHaveLength(1) + expect(styleTags[0]?.getAttribute('nonce')).toBe('first-nonce') + }) + + it('should append the style tag to the provided "ShadowRoot" target', () => { + const host = document.createElement('div') + const shadow = host.attachShadow({ mode: 'open' }) + + setupStyleSheet('test-nonce', shadow) + + expect(shadow.querySelector('#_goober')).not.toBeNull() + expect(document.head.querySelector('#_goober')).toBeNull() + }) + + it('should not insert a duplicate style tag when the target already has one', () => { + const host = document.createElement('div') + const shadow = host.attachShadow({ mode: 'open' }) + + setupStyleSheet('first-nonce', shadow) + setupStyleSheet('second-nonce', shadow) + + const styleTags = shadow.querySelectorAll('#_goober') + expect(styleTags).toHaveLength(1) + expect(styleTags[0]?.getAttribute('nonce')).toBe('first-nonce') + }) + }) })