From 33b8510a1c879c25fa473ef44a105d1cc30e3527 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Wed, 21 Sep 2022 12:16:17 +0300 Subject: [PATCH] fix(loadIcon): do not attempt to load invalid icons --- packages/core/src/api/icons.ts | 8 ++- packages/core/tests/api/loading-test.ts | 83 +++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 1 deletion(-) diff --git a/packages/core/src/api/icons.ts b/packages/core/src/api/icons.ts index 24be773..31c1acd 100644 --- a/packages/core/src/api/icons.ts +++ b/packages/core/src/api/icons.ts @@ -256,7 +256,13 @@ export const loadIcon = ( icon: IconifyIconName | string ): Promise> => { return new Promise((fulfill, reject) => { - const iconObj = typeof icon === 'string' ? stringToIcon(icon) : icon; + const iconObj = + typeof icon === 'string' ? stringToIcon(icon, true) : icon; + if (!iconObj) { + reject(icon); + return; + } + loadIcons([iconObj || icon], (loaded) => { if (loaded.length && iconObj) { const data = getIconData(iconObj); diff --git a/packages/core/tests/api/loading-test.ts b/packages/core/tests/api/loading-test.ts index e1018b1..08bfa78 100644 --- a/packages/core/tests/api/loading-test.ts +++ b/packages/core/tests/api/loading-test.ts @@ -233,6 +233,89 @@ describe('Testing API loadIcons', () => { expect(isPending({ provider, prefix, name: 'icon1' })).toBe(false); }); + it('Loading icon with bad name', async () => { + const provider = nextPrefix(); + const prefix = nextPrefix(); + + // Set config + addAPIProvider(provider, { + resources: ['https://api1.local', 'https://api2.local'], + }); + + // Icon loader + const prepareQuery = ( + provider: string, + prefix: string, + icons: string[] + ): IconifyAPIIconsQueryParams[] => { + const item: IconifyAPIIconsQueryParams = { + type: 'icons', + provider, + prefix, + icons, + }; + + // Test input and return as one item + const expected: IconifyAPIIconsQueryParams = { + type: 'icons', + provider, + prefix, + icons: ['BadIconName'], + }; + expect(item).toEqual(expected); + + return [item]; + }; + + const sendQuery = ( + host: string, + params: IconifyAPIQueryParams, + callback: QueryModuleResponse + ): void => { + expect(params.type).toBe('icons'); + + // Test input + expect(host).toBe('https://api1.local'); + const expected: IconifyAPIQueryParams = { + type: 'icons', + provider, + prefix, + icons: ['BadIconName'], + }; + expect(params).toEqual(expected); + + // Send data + callback('success', { + prefix, + icons: { + BadIconName: { + body: '', + }, + }, + }); + }; + + setAPIModule(provider, { + prepare: prepareQuery, + send: sendQuery, + }); + + // Load icon: should throw an error + let loadedIcon = false; + try { + await loadIcon(provider + ':' + prefix + ':BadIconName'); + loadedIcon = true; + } catch { + // Do nothing + } + expect(loadedIcon).toBe(false); + + // Test isPending + expect(isPending({ provider, prefix, name: 'BadIconName' })).toBe( + false + ); + }); + it('Loading one icon twice with Promise', () => { return new Promise((fulfill, reject) => { const provider = nextPrefix();