2
0
mirror of https://github.com/iconify/iconify.git synced 2024-12-14 22:46:06 +00:00
iconify/packages/core/spec/api/loadingSpec.mjs

652 lines
13 KiB
JavaScript
Raw Normal View History

import { addAPIProvider } from '@iconify/core/lib/api/config';
import { setAPIModule } from '@iconify/core/lib/api/modules';
import { loadIcons, isPending } from '@iconify/core/lib/api/icons';
2020-04-28 09:47:35 +00:00
describe('Testing API loadIcons', () => {
let prefixCounter = 0;
function nextPrefix() {
2020-04-28 09:47:35 +00:00
prefixCounter++;
return (
'api-load-test-' + (prefixCounter < 10 ? '0' : '') + prefixCounter
);
}
it('Loading few icons', (done) => {
const provider = nextPrefix();
2020-04-28 09:47:35 +00:00
const prefix = nextPrefix();
let asyncCounter = 0;
// Set config
addAPIProvider(provider, {
resources: ['https://api1.local', 'https://api2.local'],
});
2020-04-28 09:47:35 +00:00
// Icon loader
const prepareQuery = (provider, prefix, icons) => {
const item = {
type: 'icons',
provider,
2020-04-28 09:47:35 +00:00
prefix,
icons,
};
// This callback should be called first
expect(asyncCounter).toBe(1);
2020-04-28 09:47:35 +00:00
asyncCounter++;
// Test input and return as one item
const expected = {
type: 'icons',
provider,
2020-04-28 09:47:35 +00:00
prefix,
icons: ['icon1', 'icon2'],
};
expect(item).toEqual(expected);
2020-04-28 09:47:35 +00:00
return [item];
};
const sendQuery = (host, params, item) => {
2020-04-28 09:47:35 +00:00
// This callback should be called after prepareQuery
expect(asyncCounter).toBe(2);
2020-04-28 09:47:35 +00:00
asyncCounter++;
expect(params.type).toBe('icons');
2020-04-28 09:47:35 +00:00
// Test input
expect(host).toBe('https://api1.local');
const expected = {
type: 'icons',
provider,
2020-04-28 09:47:35 +00:00
prefix,
icons: ['icon1', 'icon2'],
};
expect(params).toEqual(expected);
2020-04-28 09:47:35 +00:00
// Send data
item.done({
2020-04-28 09:47:35 +00:00
prefix,
icons: {
icon1: {
body: '<path d="" />',
},
icon2: {
body: '<path d="" />',
},
},
});
// Counter should not have increased after status.done() call becuse parsing result should be done on next tick
expect(asyncCounter).toBe(3);
2020-04-28 09:47:35 +00:00
};
setAPIModule(provider, {
prepare: prepareQuery,
send: sendQuery,
});
2020-04-28 09:47:35 +00:00
// Load icons
loadIcons(
2020-04-28 09:47:35 +00:00
[
// as icon
{
provider,
2020-04-28 09:47:35 +00:00
prefix,
name: 'icon1',
},
// as string
provider + ':' + prefix + ':icon2',
2020-04-28 09:47:35 +00:00
],
(loaded, missing, pending) => {
2020-04-28 09:47:35 +00:00
// This callback should be called last
expect(asyncCounter).toBe(3);
2020-04-28 09:47:35 +00:00
asyncCounter++;
expect(loaded).toEqual([
2020-04-28 09:47:35 +00:00
{
provider,
2020-04-28 09:47:35 +00:00
prefix,
name: 'icon1',
},
{
provider,
2020-04-28 09:47:35 +00:00
prefix,
name: 'icon2',
},
]);
expect(missing).toEqual([]);
expect(pending).toEqual([]);
2020-04-28 09:47:35 +00:00
expect(
isPending({
provider,
prefix,
name: 'icon1',
})
).toBe(false);
expect(isPending({ provider, prefix, name: 'icon3' })).toBe(
false
);
2020-04-28 09:47:35 +00:00
done();
}
);
// Test isPending
expect(isPending({ provider, prefix, name: 'icon1' })).toBe(true);
expect(isPending({ provider, prefix, name: 'icon3' })).toBe(false);
2020-04-28 09:47:35 +00:00
// Make sure asyncCounter wasn't increased because loading shoud happen on next tick
expect(asyncCounter).toBe(0);
2020-04-28 09:47:35 +00:00
asyncCounter++;
});
it('Split results', (done) => {
const provider = nextPrefix();
2020-04-28 09:47:35 +00:00
const prefix = nextPrefix();
// Set config
addAPIProvider(provider, {
resources: ['https://api1.local', 'https://api2.local'],
});
2020-04-28 09:47:35 +00:00
// Icon loader
const prepareQuery = (provider, prefix, icons) => {
2020-04-28 09:47:35 +00:00
// Split all icons in multiple queries, one icon per query
const results = [];
icons.forEach((icon) => {
const item = {
type: 'icons',
provider,
2020-04-28 09:47:35 +00:00
prefix,
icons: [icon],
};
results.push(item);
});
expect(results.length).toBe(2);
2020-04-28 09:47:35 +00:00
return results;
};
let queryCounter = 0;
const sendQuery = (host, params, item) => {
2020-04-28 09:47:35 +00:00
// Test input
expect(host).toBe('https://api1.local');
2020-04-28 09:47:35 +00:00
expect(params.type).toBe('icons');
if (params.type !== 'icons') {
return;
}
2020-04-28 09:47:35 +00:00
// Icon names should match queryCounter: 'icon1' on first run, 'icon2' on second run
queryCounter++;
const expected = {
type: 'icons',
provider,
2020-04-28 09:47:35 +00:00
prefix,
icons: ['icon' + queryCounter],
};
expect(params).toEqual(expected);
2020-04-28 09:47:35 +00:00
// Send only requested icons
const icons = Object.create(null);
params.icons.forEach((icon) => {
2020-04-28 09:47:35 +00:00
icons[icon] = {
body: '<path d="" />',
};
});
item.done({
2020-04-28 09:47:35 +00:00
prefix,
icons,
// Test mismatched provider: should be ignored because provider name is not affected by actual API response
provider: nextPrefix(),
2020-04-28 09:47:35 +00:00
});
};
setAPIModule(provider, {
prepare: prepareQuery,
send: sendQuery,
});
2020-04-28 09:47:35 +00:00
// Load icons
let callbackCalled = false;
loadIcons(
[
provider + ':' + prefix + ':icon1',
provider + ':' + prefix + ':icon2',
],
(loaded, missing, pending) => {
2020-04-28 09:47:35 +00:00
// Callback should be called only once because results should be sent in same tick
expect(callbackCalled).toBe(false);
2020-04-28 09:47:35 +00:00
callbackCalled = true;
// Test data
expect(loaded).toEqual([
2020-04-28 09:47:35 +00:00
{
provider,
2020-04-28 09:47:35 +00:00
prefix,
name: 'icon1',
},
{
provider,
2020-04-28 09:47:35 +00:00
prefix,
name: 'icon2',
},
]);
expect(missing).toEqual([]);
expect(pending).toEqual([]);
2020-04-28 09:47:35 +00:00
done();
}
);
});
it('Fail on default host', (done) => {
const provider = nextPrefix();
2020-04-28 09:47:35 +00:00
const prefix = nextPrefix();
// Set config
addAPIProvider(provider, {
resources: ['https://api1.local', 'https://api2.local'],
rotate: 100, // 100ms to speed up test
});
2020-04-28 09:47:35 +00:00
// Icon loader
const prepareQuery = (provider, prefix, icons) => {
const item = {
type: 'icons',
provider,
2020-04-28 09:47:35 +00:00
prefix,
icons,
};
return [item];
};
let queryCounter = 0;
const sendQuery = (host, params, item) => {
2020-04-28 09:47:35 +00:00
queryCounter++;
params;
2020-04-28 09:47:35 +00:00
switch (queryCounter) {
case 1:
// First call on api1
expect(host).toBe('https://api1.local');
2020-04-28 09:47:35 +00:00
// Do nothing - fake failed response
break;
case 2:
// First call on api2
expect(host).toBe('https://api2.local');
2020-04-28 09:47:35 +00:00
// Return result
item.done({
2020-04-28 09:47:35 +00:00
prefix,
icons: {
icon1: {
body: '<path d="" />',
},
icon2: {
body: '<path d="" />',
},
},
});
break;
default:
done(
`Unexpected additional call to sendQuery for host ${host}.`
);
}
};
setAPIModule(provider, {
prepare: prepareQuery,
send: sendQuery,
});
2020-04-28 09:47:35 +00:00
// Load icons
let callbackCalled = false;
loadIcons(
[
provider + ':' + prefix + ':icon1',
provider + ':' + prefix + ':icon2',
],
(loaded, missing, pending) => {
2020-04-28 09:47:35 +00:00
// Callback should be called only once
expect(callbackCalled).toBe(false);
2020-04-28 09:47:35 +00:00
callbackCalled = true;
// Test data
expect(loaded).toEqual([
2020-04-28 09:47:35 +00:00
{
provider,
2020-04-28 09:47:35 +00:00
prefix,
name: 'icon1',
},
{
provider,
2020-04-28 09:47:35 +00:00
prefix,
name: 'icon2',
},
]);
expect(missing).toEqual([]);
expect(pending).toEqual([]);
2020-04-28 09:47:35 +00:00
done();
}
);
});
it('Fail on default host, multiple queries', (done) => {
const provider = nextPrefix();
2020-04-28 09:47:35 +00:00
const prefix = nextPrefix();
// Set config
addAPIProvider(provider, {
resources: ['https://api1.local', 'https://api2.local'],
rotate: 100, // 100ms to speed up test
});
2020-04-28 09:47:35 +00:00
// Icon loader
const prepareQuery = (provider, prefix, icons) => {
const item = {
type: 'icons',
provider,
2020-04-28 09:47:35 +00:00
prefix,
icons,
};
return [item];
};
let queryCounter = 0;
const sendQuery = (host, params, item) => {
2020-04-28 09:47:35 +00:00
queryCounter++;
expect(params.type).toBe('icons');
if (params.type !== 'icons') {
return;
}
2020-04-28 09:47:35 +00:00
switch (queryCounter) {
case 1:
// First call on api1
expect(params.icons).toEqual(['icon1', 'icon2']);
expect(host).toBe('https://api1.local');
2020-04-28 09:47:35 +00:00
// Do nothing - fake failed response
break;
case 2:
// First call on api2
expect(params.icons).toEqual(['icon1', 'icon2']);
expect(host).toBe('https://api2.local');
2020-04-28 09:47:35 +00:00
// Return result
item.done({
2020-04-28 09:47:35 +00:00
prefix,
icons: {
icon1: {
body: '<path d="" />',
},
icon2: {
body: '<path d="" />',
},
},
});
break;
case 3:
// Second call, should have api2 as default
expect(params.icons).toEqual(['icon3', 'icon4']);
expect(host).toBe('https://api2.local');
2020-04-28 09:47:35 +00:00
// Return result
item.done({
2020-04-28 09:47:35 +00:00
prefix,
icons: {
icon3: {
body: '<path d="" />',
},
icon4: {
body: '<path d="" />',
},
},
});
break;
default:
done(
`Unexpected additional call to sendQuery for host ${host}.`
);
}
};
setAPIModule(provider, {
prepare: prepareQuery,
send: sendQuery,
});
2020-04-28 09:47:35 +00:00
// Load icons
let callbackCalled = false;
loadIcons(
[
provider + ':' + prefix + ':icon1',
provider + ':' + prefix + ':icon2',
],
(loaded, missing, pending) => {
2020-04-28 09:47:35 +00:00
// Callback should be called only once
expect(callbackCalled).toBe(false);
2020-04-28 09:47:35 +00:00
callbackCalled = true;
// Test data
expect(loaded).toEqual([
2020-04-28 09:47:35 +00:00
{
provider,
2020-04-28 09:47:35 +00:00
prefix,
name: 'icon1',
},
{
provider,
2020-04-28 09:47:35 +00:00
prefix,
name: 'icon2',
},
]);
expect(missing).toEqual([]);
expect(pending).toEqual([]);
2020-04-28 09:47:35 +00:00
// Send another query on next tick
setTimeout(() => {
let callbackCalled = false;
loadIcons(
[
provider + ':' + prefix + ':icon3',
provider + ':' + prefix + ':icon4',
],
(loaded, missing, pending) => {
2020-04-28 09:47:35 +00:00
// Callback should be called only once
expect(callbackCalled).toBe(false);
2020-04-28 09:47:35 +00:00
callbackCalled = true;
// Test data
expect(loaded).toEqual([
2020-04-28 09:47:35 +00:00
{
provider,
2020-04-28 09:47:35 +00:00
prefix,
name: 'icon3',
},
{
provider,
2020-04-28 09:47:35 +00:00
prefix,
name: 'icon4',
},
]);
expect(missing).toEqual([]);
expect(pending).toEqual([]);
2020-04-28 09:47:35 +00:00
done();
}
);
});
}
);
});
it('Fail on default host, multiple queries with different prefixes', (done) => {
const provider = nextPrefix();
2020-04-28 09:47:35 +00:00
const prefix = nextPrefix();
const prefix2 = nextPrefix();
// Set config
addAPIProvider(provider, {
resources: ['https://api1.local', 'https://api2.local'],
rotate: 100, // 100ms to speed up test
});
2020-04-28 09:47:35 +00:00
// Icon loader
const prepareQuery = (provider, prefix, icons) => {
const item = {
type: 'icons',
provider,
2020-04-28 09:47:35 +00:00
prefix,
icons,
};
return [item];
};
let queryCounter = 0;
const sendQuery = (host, params, item) => {
2020-04-28 09:47:35 +00:00
queryCounter++;
expect(params.type).toBe('icons');
if (params.type !== 'icons') {
return;
}
2020-04-28 09:47:35 +00:00
switch (queryCounter) {
case 1:
// First call on api1
expect(params.prefix).toBe(prefix);
expect(params.icons).toEqual(['icon1', 'icon2']);
expect(host).toBe('https://api1.local');
2020-04-28 09:47:35 +00:00
// Do nothing - fake failed response
break;
case 2:
// First call on api2
expect(params.prefix).toBe(prefix);
expect(params.icons).toEqual(['icon1', 'icon2']);
expect(host).toBe('https://api2.local');
2020-04-28 09:47:35 +00:00
// Return result
item.done({
2020-04-28 09:47:35 +00:00
prefix: params.prefix,
icons: {
icon1: {
body: '<path d="" />',
},
icon2: {
body: '<path d="" />',
},
},
});
break;
case 3:
// Second call, should have api2 as default
expect(params.prefix).toBe(prefix2);
expect(params.icons).toEqual(['icon2', 'icon4']);
expect(host).toBe('https://api2.local');
2020-04-28 09:47:35 +00:00
// Return result
item.done({
2020-04-28 09:47:35 +00:00
prefix: params.prefix,
icons: {
icon2: {
body: '<path d="" />',
},
icon4: {
body: '<path d="" />',
},
},
});
break;
default:
done(
`Unexpected additional call to sendQuery for host ${host}.`
);
}
};
setAPIModule(provider, {
prepare: prepareQuery,
send: sendQuery,
});
2020-04-28 09:47:35 +00:00
// Load icons
let callbackCalled = false;
loadIcons(
[
provider + ':' + prefix + ':icon1',
provider + ':' + prefix + ':icon2',
],
(loaded, missing, pending) => {
2020-04-28 09:47:35 +00:00
// Callback should be called only once
expect(callbackCalled).toBe(false);
2020-04-28 09:47:35 +00:00
callbackCalled = true;
// Test data
expect(loaded).toEqual([
2020-04-28 09:47:35 +00:00
{
provider,
2020-04-28 09:47:35 +00:00
prefix,
name: 'icon1',
},
{
provider,
2020-04-28 09:47:35 +00:00
prefix,
name: 'icon2',
},
]);
expect(missing).toEqual([]);
expect(pending).toEqual([]);
2020-04-28 09:47:35 +00:00
// Send another query on next tick for different prefix that shares configuration
setTimeout(() => {
let callbackCalled = false;
loadIcons(
[
provider + ':' + prefix2 + ':icon2',
provider + ':' + prefix2 + ':icon4',
],
(loaded, missing, pending) => {
2020-04-28 09:47:35 +00:00
// Callback should be called only once
expect(callbackCalled).toBe(false);
2020-04-28 09:47:35 +00:00
callbackCalled = true;
// Test data
expect(loaded).toEqual([
2020-04-28 09:47:35 +00:00
{
provider,
2020-04-28 09:47:35 +00:00
prefix: prefix2,
name: 'icon2',
},
{
provider,
2020-04-28 09:47:35 +00:00
prefix: prefix2,
name: 'icon4',
},
]);
expect(missing).toEqual([]);
expect(pending).toEqual([]);
2020-04-28 09:47:35 +00:00
done();
}
);
});
}
);
});
});