Skip to content

Commit 05320fd

Browse files
author
Dennis Labordus
committed
Changed processing of the new Validation Errors from Validator Service.
Signed-off-by: Dennis Labordus <[email protected]>
1 parent 1b9c6d4 commit 05320fd

File tree

2 files changed

+215
-13
lines changed

2 files changed

+215
-13
lines changed

src/validators/CompasValidateSchema.ts

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@ import {
99
import { createLogEvent } from '../compas-services/foundation.js';
1010
import { getTypeFromDocName } from '../compas/foundation.js';
1111

12-
// Boolean to prevent running the validation multiple times at the same time.
13-
let compasValidationSchemaRunning = false;
14-
1512
export default class CompasValidateSchema extends LitElement {
1613
@property({ attribute: false })
1714
doc!: XMLDocument;
@@ -22,15 +19,18 @@ export default class CompasValidateSchema extends LitElement {
2219
@property()
2320
pluginId!: string;
2421

22+
// Boolean to prevent running the validation multiple times at the same time.
23+
private compasValidationSchemaRunning = false;
24+
2525
async validate(manual: boolean): Promise<void> {
2626
// We don't want to externally validate every time a save is done. So only start the validation when manually triggered.
2727
// And also if one is already running we don't want to start another one, wait until it's finished.
28-
if (!manual || compasValidationSchemaRunning) {
28+
if (!manual || this.compasValidationSchemaRunning) {
2929
return;
3030
}
3131

3232
// Block running another validation until this one is finished.
33-
compasValidationSchemaRunning = true;
33+
this.compasValidationSchemaRunning = true;
3434

3535
const docType = getTypeFromDocName(this.docName);
3636
const service = CompasSclValidatorService();
@@ -43,7 +43,7 @@ export default class CompasValidateSchema extends LitElement {
4343
this.processValidationResponse(doc);
4444
},
4545
() => {
46-
compasValidationSchemaRunning = false;
46+
this.compasValidationSchemaRunning = false;
4747
}
4848
);
4949
} else {
@@ -52,9 +52,8 @@ export default class CompasValidateSchema extends LitElement {
5252
.catch(reason => createLogEvent(this, reason));
5353
if (response instanceof Document) {
5454
this.processValidationResponse(response);
55-
} else {
56-
compasValidationSchemaRunning = false;
5755
}
56+
this.compasValidationSchemaRunning = false;
5857
}
5958
}
6059

@@ -65,18 +64,40 @@ export default class CompasValidateSchema extends LitElement {
6564
// Check if there are validation errors, if there are we will process them.
6665
if (validationErrors.length > 0) {
6766
validationErrors.forEach(validationError => {
68-
const message = validationError
69-
.getElementsByTagNameNS(SVS_NAMESPACE, 'Message')!
70-
.item(0)!.textContent;
7167
this.dispatchEvent(
7268
newIssueEvent({
7369
validatorId: this.pluginId,
74-
title: message ?? 'No message',
70+
title: this.createTitle(validationError),
71+
message: this.createMessage(validationError),
7572
})
7673
);
7774
});
7875
}
76+
}
77+
78+
private createTitle(validationError: Element): string {
79+
const message = validationError
80+
.getElementsByTagNameNS(SVS_NAMESPACE, 'Message')!
81+
.item(0)!.textContent;
82+
return message ? message : 'No validation message';
83+
}
7984

80-
compasValidationSchemaRunning = false;
85+
private createMessage(validationError: Element): string | undefined {
86+
const ruleName = validationError
87+
.getElementsByTagNameNS(SVS_NAMESPACE, 'RuleName')!
88+
.item(0)!.textContent;
89+
const linenumber = validationError
90+
.getElementsByTagNameNS(SVS_NAMESPACE, 'Linenumber')!
91+
.item(0)!.textContent;
92+
93+
if (!ruleName && !linenumber) {
94+
return undefined;
95+
}
96+
97+
return (
98+
`${ruleName ? `Rule: ${ruleName}` : ``}` +
99+
`${ruleName && linenumber ? `, ` : ``}` +
100+
`${linenumber ? `Linenumber: ${linenumber}` : ``}`
101+
);
81102
}
82103
}
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
import { expect, fixture, html } from '@open-wc/testing';
2+
import { SinonSpy, spy } from 'sinon';
3+
4+
import CompasValidateSchema from '../../../src/validators/CompasValidateSchema.js';
5+
6+
describe('CompasValidateSchema', () => {
7+
if (customElements.get('compas-validate-schema') === undefined)
8+
customElements.define('compas-validate-schema', CompasValidateSchema);
9+
10+
let element: CompasValidateSchema;
11+
let response: Document;
12+
13+
let issueEvent: SinonSpy;
14+
15+
beforeEach(async () => {
16+
issueEvent = spy();
17+
window.addEventListener('issue', issueEvent);
18+
19+
element = await fixture(
20+
html`<compas-validate-schema></compas-validate-schema>`
21+
);
22+
});
23+
24+
describe('processValidationResponse', () => {
25+
const responseBody = `
26+
<svs:SclValidateResponse xmlns:svs="https://www.lfenergy.org/compas/SclValidatorService/v1">
27+
<svs:ValidationErrors>
28+
<svs:Message>Message 1</svs:Message>
29+
<svs:RuleName>Rule 1</svs:RuleName>
30+
<svs:Linenumber>1</svs:Linenumber>
31+
</svs:ValidationErrors>
32+
<svs:ValidationErrors>
33+
<svs:Message>Message 2</svs:Message>
34+
<svs:RuleName>Rule 2</svs:RuleName>
35+
<svs:Linenumber>2</svs:Linenumber>
36+
</svs:ValidationErrors>
37+
</svs:SclValidateResponse>
38+
`;
39+
40+
beforeEach(async () => {
41+
response = new DOMParser().parseFromString(
42+
responseBody,
43+
'application/xml'
44+
);
45+
});
46+
47+
it('when processing the response then expect an issue event for each Validation Error', () => {
48+
element['processValidationResponse'](response);
49+
50+
expect(issueEvent).to.have.been.calledTwice;
51+
52+
expect(issueEvent.args[0][0].type).to.equal('issue');
53+
expect(issueEvent.args[0][0].detail.title).to.equal('Message 1');
54+
expect(issueEvent.args[0][0].detail.message).to.equal(
55+
'Rule: Rule 1, Linenumber: 1'
56+
);
57+
58+
expect(issueEvent.args[1][0].type).to.equal('issue');
59+
expect(issueEvent.args[1][0].detail.title).to.equal('Message 2');
60+
expect(issueEvent.args[1][0].detail.message).to.equal(
61+
'Rule: Rule 2, Linenumber: 2'
62+
);
63+
});
64+
});
65+
66+
describe('createTitle', () => {
67+
const responseBody = `
68+
<svs:SclValidateResponse xmlns:svs="https://www.lfenergy.org/compas/SclValidatorService/v1">
69+
<svs:ValidationErrors>
70+
<svs:Message>Message 1</svs:Message>
71+
<svs:RuleName>Rule 1</svs:RuleName>
72+
<svs:Linenumber>1</svs:Linenumber>
73+
</svs:ValidationErrors>
74+
<svs:ValidationErrors>
75+
<svs:Message></svs:Message>
76+
<svs:RuleName>Now Message Rule</svs:RuleName>
77+
<svs:Linenumber>1</svs:Linenumber>
78+
</svs:ValidationErrors>
79+
</svs:SclValidateResponse>
80+
`;
81+
82+
beforeEach(async () => {
83+
response = new DOMParser().parseFromString(
84+
responseBody,
85+
'application/xml'
86+
);
87+
});
88+
89+
function getValidationError(ruleName: string): Element {
90+
return Array.from(response.querySelectorAll('ValidationErrors')).filter(
91+
element => {
92+
return ruleName === element.querySelector('RuleName')?.textContent;
93+
}
94+
)[0];
95+
}
96+
97+
it('when message exists in response then message returned as title', () => {
98+
const validationError = getValidationError('Rule 1');
99+
100+
const result = element['createTitle'](validationError);
101+
expect(result).to.be.equal('Message 1');
102+
});
103+
104+
it('when no message exists in response then default message returned as title', () => {
105+
const validationError = getValidationError('Now Message Rule');
106+
107+
const result = element['createTitle'](validationError);
108+
expect(result).to.be.equal('No validation message');
109+
});
110+
});
111+
112+
describe('createMessage', () => {
113+
const responseBody = `
114+
<svs:SclValidateResponse xmlns:svs="https://www.lfenergy.org/compas/SclValidatorService/v1">
115+
<svs:ValidationErrors>
116+
<svs:Message>Message 1</svs:Message>
117+
<svs:RuleName></svs:RuleName>
118+
<svs:Linenumber></svs:Linenumber>
119+
</svs:ValidationErrors>
120+
<svs:ValidationErrors>
121+
<svs:Message>Message 2</svs:Message>
122+
<svs:RuleName>Rule 2</svs:RuleName>
123+
<svs:Linenumber></svs:Linenumber>
124+
</svs:ValidationErrors>
125+
<svs:ValidationErrors>
126+
<svs:Message>Message 3</svs:Message>
127+
<svs:RuleName></svs:RuleName>
128+
<svs:Linenumber>3</svs:Linenumber>
129+
</svs:ValidationErrors>
130+
<svs:ValidationErrors>
131+
<svs:Message>Message 4</svs:Message>
132+
<svs:RuleName>Rule 4</svs:RuleName>
133+
<svs:Linenumber>4</svs:Linenumber>
134+
</svs:ValidationErrors>
135+
</svs:SclValidateResponse>
136+
`;
137+
138+
beforeEach(async () => {
139+
response = new DOMParser().parseFromString(
140+
responseBody,
141+
'application/xml'
142+
);
143+
});
144+
145+
function getValidationError(message: string): Element {
146+
return Array.from(response.querySelectorAll('ValidationErrors')).filter(
147+
element => {
148+
return message === element.querySelector('Message')?.textContent;
149+
}
150+
)[0];
151+
}
152+
153+
it('when both rule name and linenumber are missing then undefined returned', () => {
154+
const validationError = getValidationError('Message 1');
155+
156+
const result = element['createMessage'](validationError);
157+
expect(result).to.be.undefined;
158+
});
159+
160+
it('when only rule name is filled then Rule name string returned', () => {
161+
const validationError = getValidationError('Message 2');
162+
163+
const result = element['createMessage'](validationError);
164+
expect(result).to.be.equal('Rule: Rule 2');
165+
});
166+
167+
it('when only linenumber is filled then Linenumber string returned', () => {
168+
const validationError = getValidationError('Message 3');
169+
170+
const result = element['createMessage'](validationError);
171+
expect(result).to.be.equal('Linenumber: 3');
172+
});
173+
174+
it('when both rule name and linenumber are filled then full message returned', () => {
175+
const validationError = getValidationError('Message 4');
176+
177+
const result = element['createMessage'](validationError);
178+
expect(result).to.be.equal('Rule: Rule 4, Linenumber: 4');
179+
});
180+
});
181+
});

0 commit comments

Comments
 (0)