import mocha from 'mocha';
import chai from 'chai';
import { getNode, setRoot } from './node';
import { addFinder } from '@iconify/iconify/lib/modules/finder';
import { FakeData, setFakeData, prepareQuery, sendQuery } from './fake-api';
import { setAPIModule } from '@iconify/core/lib/api/modules';
import { addAPIProvider } from '@iconify/core/lib/api/config';
import { finder as iconifyFinder } from '@iconify/iconify/lib/finders/iconify';
import { finder as iconifyIconFinder } from '@iconify/iconify/lib/finders/iconify-icon';
import { listRootNodes } from '@iconify/iconify/lib/modules/root';
import { scanDOM, scanElement } from '@iconify/iconify/lib/modules/scanner';
const expect = chai.expect;
let prefixCounter = 0;
function nextPrefix(): string {
return 'scan-dom-api-' + prefixCounter++;
}
describe('Scanning DOM with API', () => {
before(() => {
// Add finders
addFinder(iconifyFinder);
addFinder(iconifyIconFinder);
// Set API
setAPIModule('', {
prepare: prepareQuery,
send: sendQuery,
});
});
it('Scan DOM with API', (done) => {
const provider = nextPrefix();
const prefix1 = nextPrefix();
const prefix2 = nextPrefix();
// Set fake API hosts to make test reliable
addAPIProvider(provider, {
resources: ['https://api1.local', 'https://api2.local'],
});
// Set icons, load them with various delay
const data1: FakeData = {
icons: ['home', 'account-cash'],
delay: 100,
data: {
prefix: prefix1,
icons: {
'account-cash': {
body: '',
},
'home': {
body: '',
},
},
width: 24,
height: 24,
},
};
setFakeData(provider, prefix1, data1);
const data2: FakeData = {
icons: ['account', 'account-box'],
delay: 500,
data: {
prefix: prefix2,
icons: {
'account-box': {
body: '',
},
'account': {
body: '',
},
},
width: 24,
height: 24,
},
};
setFakeData(provider, prefix2, data2);
const node = getNode('scan-dom');
node.innerHTML =
'
Testing scanning DOM with API (should render SVG!)
' +
'- Inline icons:' +
' ' +
' ' +
'
' +
'- Block icons:' +
' ' +
' ' +
'
' +
'
';
// Scan DOM
setRoot(node);
scanDOM();
// Test listRootNodes
const nodes = listRootNodes();
expect(nodes.length).to.be.equal(1);
expect(nodes[0].node).to.be.equal(node);
expect(nodes[0].temporary).to.be.equal(false);
// First API response should have loaded
setTimeout(() => {
const elements = node.querySelectorAll('svg.iconify');
expect(elements.length).to.be.equal(
2,
'Expected to find 2 rendered SVG elements'
);
}, 200);
// Second API response should have loaded
setTimeout(() => {
const elements = node.querySelectorAll('svg.iconify');
expect(elements.length).to.be.equal(
4,
'Expected to find 4 rendered SVG elements'
);
done();
}, 700);
});
it('Changing icon name before it loaded', (done) => {
const provider = nextPrefix();
const prefix1 = nextPrefix();
const prefix2 = nextPrefix();
// Set fake API hosts to make test reliable
addAPIProvider(provider, {
resources: ['https://api1.local', 'https://api2.local'],
});
// Set icons, load them with various delay
const data1: FakeData = {
icons: ['home', 'account-cash'],
delay: 100,
data: {
prefix: prefix1,
icons: {
'account-cash': {
body: '',
},
'home': {
body: '',
},
},
width: 24,
height: 24,
},
};
setFakeData(provider, prefix1, data1);
const data2: FakeData = {
icons: ['account', 'account-box'],
delay: 500,
data: {
prefix: prefix2,
icons: {
'account-box': {
body: '',
},
'account': {
body: '',
},
},
width: 24,
height: 24,
},
};
setFakeData(provider, prefix2, data2);
const data1b: FakeData = {
icons: ['account', 'account-box'],
delay: 800, // +100ms for first query
data: {
prefix: prefix1,
icons: {
'account-box': {
body: '',
},
'account': {
body: '',
},
},
width: 24,
height: 24,
},
};
setFakeData(provider, prefix1, data1b);
const node = getNode('scan-dom');
node.innerHTML =
'Testing scanning DOM with API: renamed icon (should render SVG!)
' +
'- Default finder:' +
' ' +
' ' +
'
' +
'- IconifyIcon finder:' +
' ' +
' ' +
'
' +
'
';
// Scan DOM
setRoot(node);
scanDOM();
// Test listRootNodes
const nodes = listRootNodes();
expect(nodes.length).to.be.equal(1);
expect(nodes[0].node).to.be.equal(node);
expect(nodes[0].temporary).to.be.equal(false);
// Make sure no icons were rendered yet
const elements = node.querySelectorAll('svg.iconify');
expect(elements.length).to.be.equal(
0,
'Expected to find 0 rendered SVG elements'
);
// Change icon name
const icon = node.querySelector('iconify-icon[title]');
expect(icon).to.not.be.equal(null);
expect(icon.getAttribute('class')).to.be.equal('third-icon');
icon.setAttribute(
'data-icon',
'@' + provider + ':' + prefix1 + ':account'
);
// First API response should have loaded, but only 1 icon should have been rendered
setTimeout(() => {
// Loaded for prefix1: account-cash, home
// Loaded for prefix2: -
const elements = node.querySelectorAll('svg.iconify');
expect(elements.length).to.be.equal(1, '200ms delay error');
}, 200);
// Second API response should have loaded
setTimeout(() => {
// Loaded for prefix1: account-cash, home
// Loaded for prefix2: account, account-box
const elements = node.querySelectorAll('svg.iconify');
expect(elements.length).to.be.equal(3, '700ms delay error');
}, 700);
// Renamed icon from first API response
setTimeout(() => {
// Loaded for prefix1: account-cash, home, account-box, account
// Loaded for prefix2: account, account-box
const elements = node.querySelectorAll('svg.iconify');
expect(elements.length).to.be.equal(4, '1000ms delay error');
done();
}, 1100);
});
it('Changing icon name before it loaded to invalid name', (done) => {
const provider = nextPrefix();
const prefix1 = nextPrefix();
const prefix2 = nextPrefix();
// Set fake API hosts to make test reliable
addAPIProvider(provider, {
resources: ['https://api1.local', 'https://api2.local'],
});
// Set icons, load them with various delay
const data1: FakeData = {
icons: ['home', 'account-cash'],
delay: 100,
data: {
prefix: prefix1,
icons: {
'account-cash': {
body: '',
},
'home': {
body: '',
},
},
width: 24,
height: 24,
},
};
setFakeData(provider, prefix1, data1);
const data2: FakeData = {
icons: ['account', 'account-box'],
delay: 500,
data: {
prefix: prefix2,
icons: {
'account-box': {
body: '',
},
'account': {
body: '',
},
},
width: 24,
height: 24,
},
};
setFakeData(provider, prefix2, data2);
const node = getNode('scan-dom');
node.innerHTML =
'Testing scanning DOM with API: invalid name (should render 3 SVGs!)
' +
'- Inline icons (2 valid):' +
' ' +
' ' +
'
' +
'- Block icons (1 valid):' +
' ' +
' ' +
'
' +
'
';
// Scan DOM
setRoot(node);
scanDOM();
// Change icon name
const icon = node.querySelector('iconify-icon[title]');
expect(icon).to.not.be.equal(null);
icon.setAttribute('data-icon', '@' + provider + ':foo');
// First API response should have loaded, but only 1 icon
setTimeout(() => {
const elements = node.querySelectorAll('svg.iconify');
expect(elements.length).to.be.equal(1);
}, 200);
// Second API response should have loaded
setTimeout(() => {
const elements = node.querySelectorAll('svg.iconify');
expect(elements.length).to.be.equal(3);
done();
}, 700);
});
it('Unattached DOM node', (done) => {
const fakeRoot = getNode('scan-dom-unattached');
const provider = nextPrefix();
const prefix = nextPrefix();
// Set fake API hosts to make test reliable
addAPIProvider(provider, {
resources: ['https://api1.local', 'https://api2.local'],
});
// Load icons after 100ms
const data: FakeData = {
icons: ['home'],
delay: 100,
data: {
prefix,
icons: {
home: {
body: '',
},
},
width: 24,
height: 24,
},
};
setFakeData(provider, prefix, data);
const node = document.createElement('div');
node.innerHTML =
'Icon:' +
' ';
// Set root node, test nodes list
setRoot(fakeRoot);
// Test listRootNodes
let nodes = listRootNodes();
expect(nodes.length).to.be.equal(1);
expect(nodes[0].node).to.be.equal(fakeRoot);
expect(nodes[0].temporary).to.be.equal(false);
// Scan different node
scanElement(node);
// Test listRootNodes
nodes = listRootNodes();
expect(nodes.length).to.be.equal(2);
expect(nodes[0].node).to.be.equal(fakeRoot);
expect(nodes[1].node).to.be.equal(node);
expect(nodes[1].temporary).to.be.equal(true);
// API response should have loaded
setTimeout(() => {
const elements = node.querySelectorAll('svg.iconify');
expect(elements.length).to.be.equal(
1,
'Expected to find 1 rendered SVG element'
);
// Test nodes list: temporary node should have been removed
nodes = listRootNodes();
expect(nodes.length).to.be.equal(1);
expect(nodes[0].node).to.be.equal(fakeRoot);
// Done
done();
}, 200);
});
});