Skip to content

Commit

Permalink
fix(editors/communication,wizards): Fix P-type names and display of B…
Browse files Browse the repository at this point in the history
…itRate (#1277)

* fix(editors/communication,wizards): Fix P-type names and display of BitRate, closes #1264

* Add test
  • Loading branch information
danyill authored Jul 24, 2023
1 parent 8bdd990 commit 2706f82
Show file tree
Hide file tree
Showing 4 changed files with 192 additions and 17 deletions.
4 changes: 1 addition & 3 deletions src/editors/communication/subnetwork-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,7 @@ export class SubNetworkEditor extends LitElement {
private subNetworkSpecs(): string {
if (!this.type && !this.bitrate) return '';

return `(${this.type}${
this.type && this.bitrate ? ` — ${this.bitrate}` : ``
})`;
return `(${[this.type, this.bitrate].filter(text => !!text).join(' — ')})`;
}

private header(): string {
Expand Down
8 changes: 4 additions & 4 deletions src/wizards/connectedap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,13 @@ function initSMVElements(
actions.push({ new: { parent: address, element: pAppId } });

const pVlanId = createElement(connectedAp.ownerDocument, 'P', {
type: 'VLANID',
type: 'VLAN-ID',
});
pVlanId.textContent = '000';
actions.push({ new: { parent: address, element: pVlanId } });

const pVlanPrio = createElement(connectedAp.ownerDocument, 'P', {
type: 'VLAN-Priority',
type: 'VLAN-PRIORITY',
});
pVlanPrio.textContent = '4';
actions.push({ new: { parent: address, element: pVlanPrio } });
Expand Down Expand Up @@ -172,13 +172,13 @@ function initGSEElements(
actions.push({ new: { parent: address, element: pAppId } });

const pVlanId = createElement(connectedAp.ownerDocument, 'P', {
type: 'VLANID',
type: 'VLAN-ID',
});
pVlanId.textContent = '000';
actions.push({ new: { parent: address, element: pVlanId } });

const pVlanPrio = createElement(connectedAp.ownerDocument, 'P', {
type: 'VLAN-Priority',
type: 'VLAN-PRIORITY',
});
pVlanPrio.textContent = '4';
actions.push({ new: { parent: address, element: pVlanPrio } });
Expand Down
17 changes: 10 additions & 7 deletions src/wizards/subnetwork.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,19 +127,22 @@ function getBitRateAction(
multiplier: string | null,
SubNetwork: Element
): EditorAction {
if (oldBitRate === null)
if (oldBitRate === null) {
const bitRateElement = createElement(SubNetwork.ownerDocument, 'BitRate', {
unit: 'b/s',
});

if (multiplier) bitRateElement.setAttribute('multiplier', multiplier);
if (BitRate) bitRateElement.textContent = BitRate;

return {
new: {
parent: SubNetwork,
element: new DOMParser().parseFromString(
`<BitRate unit="b/s" ${
multiplier === null ? '' : `multiplier="${multiplier}"`
}>${BitRate === null ? '' : BitRate}</BitRate>`,
'application/xml'
).documentElement,
element: bitRateElement,
reference: SubNetwork.firstElementChild,
},
};
}

if (BitRate === null)
return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ describe('subnetwork-editor wizarding editing integration', () => {
)
);
});

it('closes on secondary action', async () => {
await (<HTMLElement>(
parent.wizardUI.dialog?.querySelector(
Expand Down Expand Up @@ -153,6 +154,7 @@ describe('subnetwork-editor wizarding editing integration', () => {
.null;
});
});

describe('remove action', () => {
let doc: XMLDocument;
let parent: MockWizardEditor;
Expand Down Expand Up @@ -211,13 +213,16 @@ describe('subnetwork-editor wizarding editing integration', () => {
)
);
element = parent.querySelector('subnetwork-editor');
});

it('adds ConnectedAP on primary action', async () => {
(<HTMLElement>(
element?.shadowRoot?.querySelector(
'mwc-icon-button[icon="playlist_add"]'
)
)).click();
await parent.updateComplete;
await element?.updateComplete;

newConnectedAPItem = <ListItemBase>(
parent.wizardUI.dialog!.querySelector(
Expand All @@ -230,23 +235,192 @@ describe('subnetwork-editor wizarding editing integration', () => {
'mwc-button[slot="primaryAction"]'
)
);
});

it('add ConnectedAP on primary action', async () => {
expect(
doc.querySelector(
':root > Communication > SubNetwork[name="StationBus"] > ConnectedAP[iedName="IED3"][apName="P2"]'
)
).to.not.exist;

newConnectedAPItem.click();
await parent.updateComplete;
primaryAction.click();
await parent.updateComplete;

expect(
doc.querySelector(
':root > Communication > SubNetwork[name="StationBus"] > ConnectedAP[iedName="IED3"][apName="P2"]'
)
).to.exist;
});

it('add ConnectedAP with GSE and generates correct addresses', async () => {
doc = await fetch('/test/testfiles/editors/MessageBindingGOOSE2007B4.scd')
.then(response => response.text())
.then(str => new DOMParser().parseFromString(str, 'application/xml'));
parent = <MockWizardEditor>(
await fixture(
html`<mock-wizard-editor
><subnetwork-editor
.doc=${doc}
.element=${doc.querySelector('SubNetwork[name="StationBus"]')}
></subnetwork-editor
></mock-wizard-editor>`
)
);
element = parent.querySelector('subnetwork-editor');
await parent.updateComplete;
await element?.updateComplete;

(<HTMLElement>(
element?.shadowRoot?.querySelector(
'mwc-icon-button[icon="playlist_add"]'
)
)).click();
await parent.updateComplete;
await element?.updateComplete;

expect(
doc.querySelector(
':root > Communication > SubNetwork[name="StationBus"] > ConnectedAP[iedName="IED4"][apName="P1"]'
)
).to.not.exist;

newConnectedAPItem = <ListItemBase>(
parent.wizardUI.dialog!.querySelector(
'mwc-check-list-item:nth-child(2)'
)
);

primaryAction = <HTMLElement>(
parent.wizardUI.dialog?.querySelector(
'mwc-button[slot="primaryAction"]'
)
);

newConnectedAPItem.click();
primaryAction.click();
await parent.updateComplete;

const connectedAp = doc.querySelector(
':root > Communication > SubNetwork[name="StationBus"] > ConnectedAP[iedName="IED4"][apName="P1"]'
);

expect(connectedAp).to.exist;
const gse1 = connectedAp!.querySelector('GSE[cbName="GCB2"]');
const gse2 = connectedAp!.querySelector('GSE[cbName="GCB2"]');
expect(gse1).to.exist;
expect(gse2).to.exist;

expect(gse1?.getAttribute('ldInst')).to.equal('CircuitBreaker_CB1');

const address1 = gse1?.querySelector('Address');
expect(address1).to.exist;

const vlanPriority = address1?.querySelector('P[type="VLAN-PRIORITY"]');
expect(vlanPriority).to.exist;
expect(vlanPriority?.textContent).to.equal('4');

const vlanId = address1?.querySelector('P[type="VLAN-ID"]');
expect(vlanId).to.exist;
expect(vlanId?.textContent).to.equal('000');

const appId = address1?.querySelector('P[type="APPID"]');
expect(appId).to.exist;
expect(appId?.textContent).to.equal('0001');

const mac = address1?.querySelector('P[type="MAC-Address"]');
expect(mac).to.exist;
expect(mac?.textContent).to.equal('01-0C-CD-01-00-01');

const minTime = gse1?.querySelector('MinTime');
expect(minTime).to.exist;
expect(minTime?.getAttribute('unit')).to.equal('s');
expect(minTime?.getAttribute('multiplier')).to.equal('m');
expect(minTime?.textContent).to.equal('10');

const maxTime = gse1?.querySelector('MaxTime');
expect(maxTime).to.exist;
expect(maxTime?.getAttribute('unit')).to.equal('s');
expect(maxTime?.getAttribute('multiplier')).to.equal('m');
expect(maxTime?.textContent).to.equal('10000');
});

it('add ConnectedAP with SMV and generates correct addresses', async () => {
doc = await fetch('/test/testfiles/editors/MessageBindingSMV2007B4.scd')
.then(response => response.text())
.then(str => new DOMParser().parseFromString(str, 'application/xml'));
parent = <MockWizardEditor>(
await fixture(
html`<mock-wizard-editor
><subnetwork-editor
.doc=${doc}
.element=${doc.querySelector('SubNetwork[name="StationBus"]')}
></subnetwork-editor
></mock-wizard-editor>`
)
);
element = parent.querySelector('subnetwork-editor');
await parent.updateComplete;
await element?.updateComplete;

(<HTMLElement>(
element?.shadowRoot?.querySelector(
'mwc-icon-button[icon="playlist_add"]'
)
)).click();
await parent.updateComplete;
await element?.updateComplete;

expect(
doc.querySelector(
':root > Communication > SubNetwork[name="StationBus"] > ConnectedAP[iedName="IED4"][apName="P1"]'
)
).to.not.exist;

newConnectedAPItem = <ListItemBase>(
parent.wizardUI.dialog!.querySelector(
'mwc-check-list-item:nth-child(2)'
)
);

primaryAction = <HTMLElement>(
parent.wizardUI.dialog?.querySelector(
'mwc-button[slot="primaryAction"]'
)
);

newConnectedAPItem.click();
primaryAction.click();
await parent.updateComplete;

const connectedAp = doc.querySelector(
':root > Communication > SubNetwork[name="StationBus"] > ConnectedAP[iedName="IED4"][apName="P1"]'
);

expect(connectedAp).to.exist;
const smv1 = connectedAp!.querySelector('SMV[cbName="MSVCB02"]');
expect(smv1).to.exist;

expect(smv1?.getAttribute('ldInst')).to.equal('CircuitBreaker_CB1');

const address1 = smv1?.querySelector('Address');
expect(address1).to.exist;

const vlanPriority = address1?.querySelector('P[type="VLAN-PRIORITY"]');
expect(vlanPriority).to.exist;
expect(vlanPriority?.textContent).to.equal('4');

const vlanId = address1?.querySelector('P[type="VLAN-ID"]');
expect(vlanId).to.exist;
expect(vlanId?.textContent).to.equal('000');

const appId = address1?.querySelector('P[type="APPID"]');
expect(appId).to.exist;
expect(appId?.textContent).to.equal('4000');

const mac = address1?.querySelector('P[type="MAC-Address"]');
expect(mac).to.exist;
expect(mac?.textContent).to.equal('01-0C-CD-04-00-00');
});
});
});

0 comments on commit 2706f82

Please sign in to comment.