Skip to content

Commit 29e502a

Browse files
committed
test: add tests
1 parent 2bab3dc commit 29e502a

3 files changed

Lines changed: 467 additions & 7 deletions

File tree

packages/compas-open-scd/src/compas/CompasNsdoc.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,10 @@ export async function loadNsdocFilesForEdition(
4040
return;
4141
}
4242

43-
const parts: Array<[string, string]> = [
44-
['7-2', 'IEC 61850-7-2'],
45-
['7-3', 'IEC 61850-7-3'],
46-
['7-4', 'IEC 61850-7-4'],
47-
['8-1', 'IEC 61850-8-1'],
48-
];
43+
const parts = ['7-2', '7-3', '7-4', '8-1'];
4944

5045
await Promise.all(
51-
parts.map(async ([part, nsdocId]) => {
46+
parts.map(async (part) => {
5247
const entry: CodeComponentEntry | undefined = editionComponents[part];
5348
if (!entry?.NSDOC) {
5449
component.dispatchEvent(
Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
import { expect } from '@open-wc/testing';
2+
import sinon, { SinonStub } from 'sinon';
3+
4+
import { loadNsdocFilesForEdition } from '../../../src/compas/CompasNsdoc.js';
5+
import type {
6+
EditionComponents,
7+
IEC61850Edition,
8+
} from '../../../src/compas-services/CompasCodeComponentsService.js';
9+
10+
describe('loadNsdocFilesForEdition', () => {
11+
let component: Element;
12+
let fetchStub: SinonStub;
13+
14+
const EDITION: IEC61850Edition = 'Edition_2';
15+
16+
const FULL_EDITION_COMPONENTS: EditionComponents = {
17+
'7-2': { NSD: 'IEC_61850-7-2_Ed2.nsd', NSDOC: 'IEC_61850-7-2_Ed2.nsdoc' },
18+
'7-3': { NSD: 'IEC_61850-7-3_Ed2.nsd', NSDOC: 'IEC_61850-7-3_Ed2.nsdoc' },
19+
'7-4': { NSD: 'IEC_61850-7-4_Ed2.nsd', NSDOC: 'IEC_61850-7-4_Ed2.nsdoc' },
20+
'8-1': { NSD: 'IEC_61850-8-1_Ed2.nsd', NSDOC: 'IEC_61850-8-1_Ed2.nsdoc' },
21+
};
22+
23+
beforeEach(() => {
24+
component = document.createElement('div');
25+
fetchStub = sinon.stub(globalThis, 'fetch');
26+
});
27+
28+
afterEach(() => {
29+
sinon.restore();
30+
});
31+
32+
describe('when editionComponents is null', () => {
33+
it('dispatches a single error log event', async () => {
34+
const logEvents: CustomEvent[] = [];
35+
component.addEventListener('log', e => logEvents.push(e as CustomEvent));
36+
37+
await loadNsdocFilesForEdition(component, EDITION, null);
38+
39+
expect(logEvents).to.have.length(1);
40+
expect(logEvents[0].detail.kind).to.equal('error');
41+
});
42+
43+
it('does not call fetch', async () => {
44+
await loadNsdocFilesForEdition(component, EDITION, null);
45+
46+
expect(fetchStub).not.to.have.been.called;
47+
});
48+
});
49+
50+
describe('when fetch succeeds for all parts', () => {
51+
beforeEach(() => {
52+
fetchStub.callsFake(() =>
53+
Promise.resolve(new Response('nsdoc content', { status: 200 }))
54+
);
55+
});
56+
57+
it('dispatches a load-nsdoc event for each of the 4 parts', async () => {
58+
const loadEvents: CustomEvent[] = [];
59+
component.addEventListener('load-nsdoc', e =>
60+
loadEvents.push(e as CustomEvent)
61+
);
62+
63+
await loadNsdocFilesForEdition(
64+
component,
65+
EDITION,
66+
FULL_EDITION_COMPONENTS
67+
);
68+
69+
expect(loadEvents).to.have.length(4);
70+
});
71+
72+
it('does not dispatch any log events', async () => {
73+
const logEvents: CustomEvent[] = [];
74+
component.addEventListener('log', e => logEvents.push(e as CustomEvent));
75+
76+
await loadNsdocFilesForEdition(
77+
component,
78+
EDITION,
79+
FULL_EDITION_COMPONENTS
80+
);
81+
82+
expect(logEvents).to.have.length(0);
83+
});
84+
85+
it('fetches from the correct path for each part', async () => {
86+
await loadNsdocFilesForEdition(
87+
component,
88+
EDITION,
89+
FULL_EDITION_COMPONENTS
90+
);
91+
92+
const fetchedUrls = fetchStub.args.map(([url]: [string]) => url);
93+
expect(fetchedUrls).to.include('/public/nsdoc/IEC_61850-7-2_Ed2.nsdoc');
94+
expect(fetchedUrls).to.include('/public/nsdoc/IEC_61850-7-3_Ed2.nsdoc');
95+
expect(fetchedUrls).to.include('/public/nsdoc/IEC_61850-7-4_Ed2.nsdoc');
96+
expect(fetchedUrls).to.include('/public/nsdoc/IEC_61850-8-1_Ed2.nsdoc');
97+
});
98+
99+
it('includes the filename and content in the load-nsdoc event detail', async () => {
100+
fetchStub.callsFake(() =>
101+
Promise.resolve(new Response('my nsdoc content', { status: 200 }))
102+
);
103+
const loadEvents: CustomEvent[] = [];
104+
component.addEventListener('load-nsdoc', e =>
105+
loadEvents.push(e as CustomEvent)
106+
);
107+
108+
await loadNsdocFilesForEdition(component, EDITION, {
109+
'7-2': { NSD: 'file-7-2.nsd', NSDOC: 'file-7-2.nsdoc' },
110+
'7-3': { NSD: 'file-7-3.nsd', NSDOC: 'file-7-3.nsdoc' },
111+
'7-4': { NSD: 'file-7-4.nsd', NSDOC: 'file-7-4.nsdoc' },
112+
'8-1': { NSD: 'file-8-1.nsd', NSDOC: 'file-8-1.nsdoc' },
113+
});
114+
115+
const fileNames = loadEvents.map(e => e.detail.filename);
116+
expect(fileNames).to.include.members([
117+
'file-7-2.nsdoc',
118+
'file-7-3.nsdoc',
119+
'file-7-4.nsdoc',
120+
'file-8-1.nsdoc',
121+
]);
122+
});
123+
});
124+
125+
describe('when a part has no NSDOC entry', () => {
126+
it('dispatches a warning log event for the missing part', async () => {
127+
fetchStub.callsFake(() =>
128+
Promise.resolve(new Response('content', { status: 200 }))
129+
);
130+
const logEvents: CustomEvent[] = [];
131+
component.addEventListener('log', e => logEvents.push(e as CustomEvent));
132+
133+
const partialComponents: EditionComponents = {
134+
...FULL_EDITION_COMPONENTS,
135+
'7-4': { NSD: 'IEC_61850-7-4_Ed2.nsd', NSDOC: '' }, // empty NSDOC — falsy
136+
};
137+
138+
await loadNsdocFilesForEdition(component, EDITION, partialComponents);
139+
140+
const warnings = logEvents.filter(e => e.detail.kind === 'warning');
141+
expect(warnings).to.have.length(1);
142+
});
143+
144+
it('still dispatches load-nsdoc events for parts that do have NSDOC entries', async () => {
145+
fetchStub.callsFake(() =>
146+
Promise.resolve(new Response('content', { status: 200 }))
147+
);
148+
const loadEvents: CustomEvent[] = [];
149+
component.addEventListener('load-nsdoc', e =>
150+
loadEvents.push(e as CustomEvent)
151+
);
152+
153+
const partialComponents: EditionComponents = {
154+
'7-2': { NSD: 'a.nsd', NSDOC: 'a.nsdoc' },
155+
'7-3': { NSD: 'b.nsd', NSDOC: 'b.nsdoc' },
156+
// '7-4' and '8-1' are missing entirely
157+
};
158+
159+
await loadNsdocFilesForEdition(component, EDITION, partialComponents);
160+
161+
expect(loadEvents).to.have.length(2);
162+
});
163+
});
164+
165+
describe('when fetch returns a non-ok response', () => {
166+
it('dispatches a warning log event', async () => {
167+
fetchStub.resolves(new Response(null, { status: 404 }));
168+
const logEvents: CustomEvent[] = [];
169+
component.addEventListener('log', e => logEvents.push(e as CustomEvent));
170+
171+
await loadNsdocFilesForEdition(
172+
component,
173+
EDITION,
174+
FULL_EDITION_COMPONENTS
175+
);
176+
177+
const warnings = logEvents.filter(e => e.detail.kind === 'warning');
178+
expect(warnings).to.have.length(4);
179+
});
180+
181+
it('does not dispatch any load-nsdoc events', async () => {
182+
fetchStub.resolves(new Response(null, { status: 500 }));
183+
const loadEvents: CustomEvent[] = [];
184+
component.addEventListener('load-nsdoc', e =>
185+
loadEvents.push(e as CustomEvent)
186+
);
187+
188+
await loadNsdocFilesForEdition(
189+
component,
190+
EDITION,
191+
FULL_EDITION_COMPONENTS
192+
);
193+
194+
expect(loadEvents).to.have.length(0);
195+
});
196+
});
197+
198+
describe('when fetch throws a network error', () => {
199+
it('dispatches a warning log event', async () => {
200+
fetchStub.rejects(new TypeError('Network error'));
201+
const logEvents: CustomEvent[] = [];
202+
component.addEventListener('log', e => logEvents.push(e as CustomEvent));
203+
204+
await loadNsdocFilesForEdition(
205+
component,
206+
EDITION,
207+
FULL_EDITION_COMPONENTS
208+
);
209+
210+
const warnings = logEvents.filter(e => e.detail.kind === 'warning');
211+
expect(warnings).to.have.length(4);
212+
});
213+
214+
it('does not dispatch any load-nsdoc events', async () => {
215+
fetchStub.rejects(new TypeError('Network error'));
216+
const loadEvents: CustomEvent[] = [];
217+
component.addEventListener('load-nsdoc', e =>
218+
loadEvents.push(e as CustomEvent)
219+
);
220+
221+
await loadNsdocFilesForEdition(
222+
component,
223+
EDITION,
224+
FULL_EDITION_COMPONENTS
225+
);
226+
227+
expect(loadEvents).to.have.length(0);
228+
});
229+
});
230+
});

0 commit comments

Comments
 (0)