Skip to content

Commit

Permalink
Merge pull request #179 from com-pas/process-validation-error
Browse files Browse the repository at this point in the history
Changed processing of the new Validation Errors from Validator Service.
  • Loading branch information
juancho0202 authored Aug 23, 2022
2 parents 1b9c6d4 + cabbace commit 6003bde
Show file tree
Hide file tree
Showing 2 changed files with 215 additions and 13 deletions.
47 changes: 34 additions & 13 deletions src/validators/CompasValidateSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ import {
import { createLogEvent } from '../compas-services/foundation.js';
import { getTypeFromDocName } from '../compas/foundation.js';

// Boolean to prevent running the validation multiple times at the same time.
let compasValidationSchemaRunning = false;

export default class CompasValidateSchema extends LitElement {
@property({ attribute: false })
doc!: XMLDocument;
Expand All @@ -22,15 +19,18 @@ export default class CompasValidateSchema extends LitElement {
@property()
pluginId!: string;

// Boolean to prevent running the validation multiple times at the same time.
private compasValidationSchemaRunning = false;

async validate(manual: boolean): Promise<void> {
// We don't want to externally validate every time a save is done. So only start the validation when manually triggered.
// And also if one is already running we don't want to start another one, wait until it's finished.
if (!manual || compasValidationSchemaRunning) {
if (!manual || this.compasValidationSchemaRunning) {
return;
}

// Block running another validation until this one is finished.
compasValidationSchemaRunning = true;
this.compasValidationSchemaRunning = true;

const docType = getTypeFromDocName(this.docName);
const service = CompasSclValidatorService();
Expand All @@ -43,7 +43,7 @@ export default class CompasValidateSchema extends LitElement {
this.processValidationResponse(doc);
},
() => {
compasValidationSchemaRunning = false;
this.compasValidationSchemaRunning = false;
}
);
} else {
Expand All @@ -52,9 +52,8 @@ export default class CompasValidateSchema extends LitElement {
.catch(reason => createLogEvent(this, reason));
if (response instanceof Document) {
this.processValidationResponse(response);
} else {
compasValidationSchemaRunning = false;
}
this.compasValidationSchemaRunning = false;
}
}

Expand All @@ -65,18 +64,40 @@ export default class CompasValidateSchema extends LitElement {
// Check if there are validation errors, if there are we will process them.
if (validationErrors.length > 0) {
validationErrors.forEach(validationError => {
const message = validationError
.getElementsByTagNameNS(SVS_NAMESPACE, 'Message')!
.item(0)!.textContent;
this.dispatchEvent(
newIssueEvent({
validatorId: this.pluginId,
title: message ?? 'No message',
title: this.createTitle(validationError),
message: this.createMessage(validationError),
})
);
});
}
}

private createTitle(validationError: Element): string {
const message = validationError
.getElementsByTagNameNS(SVS_NAMESPACE, 'Message')!
.item(0)!.textContent;
return message ? message : 'No validation message';
}

compasValidationSchemaRunning = false;
private createMessage(validationError: Element): string | undefined {
const ruleName = validationError
.getElementsByTagNameNS(SVS_NAMESPACE, 'RuleName')!
.item(0)!.textContent;
const linenumber = validationError
.getElementsByTagNameNS(SVS_NAMESPACE, 'Linenumber')!
.item(0)!.textContent;

if (!ruleName && !linenumber) {
return undefined;
}

return (
`${ruleName ? `Rule: ${ruleName}` : ``}` +
`${ruleName && linenumber ? `, ` : ``}` +
`${linenumber ? `Linenumber: ${linenumber}` : ``}`
);
}
}
181 changes: 181 additions & 0 deletions test/unit/validators/CompasValidateSchema.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
import { expect, fixture, html } from '@open-wc/testing';
import { SinonSpy, spy } from 'sinon';

import CompasValidateSchema from '../../../src/validators/CompasValidateSchema.js';

describe('CompasValidateSchema', () => {
if (customElements.get('compas-validate-schema') === undefined)
customElements.define('compas-validate-schema', CompasValidateSchema);

let element: CompasValidateSchema;
let response: Document;

let issueEvent: SinonSpy;

beforeEach(async () => {
issueEvent = spy();
window.addEventListener('issue', issueEvent);

element = await fixture(
html`<compas-validate-schema></compas-validate-schema>`
);
});

describe('processValidationResponse', () => {
const responseBody = `
<svs:SclValidateResponse xmlns:svs="https://www.lfenergy.org/compas/SclValidatorService/v1">
<svs:ValidationErrors>
<svs:Message>Message 1</svs:Message>
<svs:RuleName>Rule 1</svs:RuleName>
<svs:Linenumber>1</svs:Linenumber>
</svs:ValidationErrors>
<svs:ValidationErrors>
<svs:Message>Message 2</svs:Message>
<svs:RuleName>Rule 2</svs:RuleName>
<svs:Linenumber>2</svs:Linenumber>
</svs:ValidationErrors>
</svs:SclValidateResponse>
`;

beforeEach(async () => {
response = new DOMParser().parseFromString(
responseBody,
'application/xml'
);
});

it('when processing the response then expect an issue event for each Validation Error', () => {
element['processValidationResponse'](response);

expect(issueEvent).to.have.been.calledTwice;

expect(issueEvent.args[0][0].type).to.equal('issue');
expect(issueEvent.args[0][0].detail.title).to.equal('Message 1');
expect(issueEvent.args[0][0].detail.message).to.equal(
'Rule: Rule 1, Linenumber: 1'
);

expect(issueEvent.args[1][0].type).to.equal('issue');
expect(issueEvent.args[1][0].detail.title).to.equal('Message 2');
expect(issueEvent.args[1][0].detail.message).to.equal(
'Rule: Rule 2, Linenumber: 2'
);
});
});

describe('createTitle', () => {
const responseBody = `
<svs:SclValidateResponse xmlns:svs="https://www.lfenergy.org/compas/SclValidatorService/v1">
<svs:ValidationErrors>
<svs:Message>Message 1</svs:Message>
<svs:RuleName>Rule 1</svs:RuleName>
<svs:Linenumber>1</svs:Linenumber>
</svs:ValidationErrors>
<svs:ValidationErrors>
<svs:Message></svs:Message>
<svs:RuleName>No Message Rule</svs:RuleName>
<svs:Linenumber>1</svs:Linenumber>
</svs:ValidationErrors>
</svs:SclValidateResponse>
`;

beforeEach(async () => {
response = new DOMParser().parseFromString(
responseBody,
'application/xml'
);
});

function getValidationError(ruleName: string): Element {
return Array.from(response.querySelectorAll('ValidationErrors')).filter(
element => {
return ruleName === element.querySelector('RuleName')?.textContent;
}
)[0];
}

it('when message exists in response then message returned as title', () => {
const validationError = getValidationError('Rule 1');

const result = element['createTitle'](validationError);
expect(result).to.be.equal('Message 1');
});

it('when no message exists in response then default message returned as title', () => {
const validationError = getValidationError('No Message Rule');

const result = element['createTitle'](validationError);
expect(result).to.be.equal('No validation message');
});
});

describe('createMessage', () => {
const responseBody = `
<svs:SclValidateResponse xmlns:svs="https://www.lfenergy.org/compas/SclValidatorService/v1">
<svs:ValidationErrors>
<svs:Message>Message 1</svs:Message>
<svs:RuleName></svs:RuleName>
<svs:Linenumber></svs:Linenumber>
</svs:ValidationErrors>
<svs:ValidationErrors>
<svs:Message>Message 2</svs:Message>
<svs:RuleName>Rule 2</svs:RuleName>
<svs:Linenumber></svs:Linenumber>
</svs:ValidationErrors>
<svs:ValidationErrors>
<svs:Message>Message 3</svs:Message>
<svs:RuleName></svs:RuleName>
<svs:Linenumber>3</svs:Linenumber>
</svs:ValidationErrors>
<svs:ValidationErrors>
<svs:Message>Message 4</svs:Message>
<svs:RuleName>Rule 4</svs:RuleName>
<svs:Linenumber>4</svs:Linenumber>
</svs:ValidationErrors>
</svs:SclValidateResponse>
`;

beforeEach(async () => {
response = new DOMParser().parseFromString(
responseBody,
'application/xml'
);
});

function getValidationError(message: string): Element {
return Array.from(response.querySelectorAll('ValidationErrors')).filter(
element => {
return message === element.querySelector('Message')?.textContent;
}
)[0];
}

it('when both rule name and linenumber are missing then undefined returned', () => {
const validationError = getValidationError('Message 1');

const result = element['createMessage'](validationError);
expect(result).to.be.undefined;
});

it('when only rule name is filled then Rule name string returned', () => {
const validationError = getValidationError('Message 2');

const result = element['createMessage'](validationError);
expect(result).to.be.equal('Rule: Rule 2');
});

it('when only linenumber is filled then Linenumber string returned', () => {
const validationError = getValidationError('Message 3');

const result = element['createMessage'](validationError);
expect(result).to.be.equal('Linenumber: 3');
});

it('when both rule name and linenumber are filled then full message returned', () => {
const validationError = getValidationError('Message 4');

const result = element['createMessage'](validationError);
expect(result).to.be.equal('Rule: Rule 4, Linenumber: 4');
});
});
});

0 comments on commit 6003bde

Please sign in to comment.