import { cleanupGlobals, expectedBlock, setupDOM, nextTick, nextPrefix, fakeAPI, mockAPIData, awaitUntil, styleOpeningTag, } from '../src/tests/helpers'; import { defineIconifyIcon, IconifyIconHTMLElement } from '../src/component'; import type { IconState } from '../src/state'; import type { IconifyMockAPIDelayDoneCallback } from '@iconify/core/lib/api/modules/mock'; export declare interface DebugIconifyIconHTMLElement extends IconifyIconHTMLElement { // Internal stuff, used for debugging _shadowRoot: ShadowRoot; _state: IconState; } describe('Testing icon component with API', () => { afterEach(async () => { await nextTick(); cleanupGlobals(); }); it('Loading icon from API', async () => { // Setup DOM and fake API const doc = setupDOM('').window.document; const provider = nextPrefix(); const prefix = nextPrefix(); fakeAPI(provider); // Define component const IconifyIcon = defineIconifyIcon(); expect(IconifyIcon).toBeDefined(); expect(window.customElements.get('iconify-icon')).toBeDefined(); // Create element const node = document.createElement( 'iconify-icon' ) as DebugIconifyIconHTMLElement; // Should be empty expect(node._shadowRoot.innerHTML).toBe( `${styleOpeningTag}${expectedBlock}` ); expect(node.status).toBe('loading'); // Mock data const name = 'mock-test'; const iconName = `@${provider}:${prefix}:${name}`; let sendQuery: IconifyMockAPIDelayDoneCallback | undefined; mockAPIData({ type: 'icons', provider, prefix, response: { prefix, icons: { [name]: { body: '', }, }, }, delay: (next) => { sendQuery = next; }, }); // Set icon node.setAttribute('icon', iconName); expect(node.icon).toEqual(iconName); expect(node.getAttribute('icon')).toBe(iconName); // Should not have sent query to API yet expect(sendQuery).toBeUndefined(); expect(node._shadowRoot.innerHTML).toBe( `${styleOpeningTag}${expectedBlock}` ); expect(node.status).toBe('loading'); // Wait until sendQuery is defined and send response await awaitUntil(() => !!sendQuery); sendQuery(); // Wait until icon exists const iconExists = node.iconExists; await awaitUntil(() => iconExists(iconName)); // Wait for render await nextTick(); // Should render SVG const blankSVG = ''; expect(node._shadowRoot.innerHTML).toBe( `${styleOpeningTag}${expectedBlock}${blankSVG}` ); expect(node.status).toBe('rendered'); }); it('Failing to load from API', async () => { // Setup DOM and fake API const doc = setupDOM('').window.document; const provider = nextPrefix(); const prefix = nextPrefix(); fakeAPI(provider); // Define component const IconifyIcon = defineIconifyIcon(); expect(IconifyIcon).toBeDefined(); expect(window.customElements.get('iconify-icon')).toBeDefined(); // Create element const node = document.createElement( 'iconify-icon' ) as DebugIconifyIconHTMLElement; // Should be empty expect(node._shadowRoot.innerHTML).toBe( `${styleOpeningTag}${expectedBlock}` ); expect(node.status).toBe('loading'); // Mock data const name = 'mock-test'; const iconName = `@${provider}:${prefix}:${name}`; mockAPIData({ type: 'icons', provider, prefix, response: { prefix, icons: {}, not_found: [name], }, }); // Set icon node.setAttribute('icon', iconName); expect(node.icon).toEqual(iconName); expect(node.getAttribute('icon')).toBe(iconName); // Should not have sent query to API yet expect(node._shadowRoot.innerHTML).toBe( `${styleOpeningTag}${expectedBlock}` ); expect(node.status).toBe('loading'); // Wait until status changes expect(node.status).toBe('loading'); await awaitUntil(() => node.status !== 'loading'); // Should fail to render expect(node._shadowRoot.innerHTML).toBe( `${styleOpeningTag}${expectedBlock}` ); expect(node.status).toBe('failed'); }); });