Skip to content

Commit

Permalink
feat(wizard/sampledvaluecontrol): allow removing including referenced…
Browse files Browse the repository at this point in the history
… elements (#536)
  • Loading branch information
JakobVogelsang authored Feb 14, 2022
1 parent 2b11ae8 commit 1940571
Show file tree
Hide file tree
Showing 4 changed files with 210 additions and 1 deletion.
60 changes: 60 additions & 0 deletions src/wizards/sampledvaluecontrol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,14 @@ import '../wizard-select.js';
import '../wizard-textfield.js';
import {
cloneElement,
Delete,
EditorAction,
getValue,
identity,
isPublic,
newActionEvent,
newSubWizardEvent,
newWizardEvent,
selector,
Wizard,
WizardActor,
Expand All @@ -43,6 +46,52 @@ function getSMV(element: Element): Element | null {
);
}

export function removeSampledValueControlAction(element: Element): Delete[] {
if (!element.parentElement) return [];

const dataSet = element.parentElement!.querySelector(
`DataSet[name="${element.getAttribute('datSet')}"]`
);
const sMV = getSMV(element);

const singleUse =
Array.from(
element.parentElement.querySelectorAll<Element>(
'ReportControl, GSEControl, SampledValueControl'
)
).filter(
controlblock =>
controlblock.getAttribute('datSet') === dataSet?.getAttribute('name')
).length <= 1;

const actions: Delete[] = [];

actions.push({
old: {
parent: element.parentElement!,
element,
},
});

if (dataSet && singleUse)
actions.push({
old: {
parent: element.parentElement!,
element: dataSet,
},
});

if (sMV)
actions.push({
old: {
parent: sMV.parentElement!,
element: sMV,
},
});

return actions;
}

interface ContentOptions {
name: string | null;
desc: string | null;
Expand Down Expand Up @@ -208,6 +257,17 @@ export function editSampledValueControlWizard(element: Element): Wizard {
}}}"
></mwc-button>`
: html``,
html`<mwc-button
label="${translate('remove')}"
icon="delete"
@click=${(e: MouseEvent) => {
const deleteActions = removeSampledValueControlAction(element);
deleteActions.forEach(deleteAction =>
e.target?.dispatchEvent(newActionEvent(deleteAction))
);
e.target?.dispatchEvent(newWizardEvent());
}}
></mwc-button>`,
],
},
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,32 @@ describe('Wizards for SCL element SampledValueControl', () => {
?.textContent?.trim()
);
});

it('removes the SampledValueControl element and its referenced elements on remove button click', async () => {
expect(
doc.querySelector(
'IED[name="IED3"] SampledValueControl[name="MSVCB01"]'
)
).to.exist;
expect(doc.querySelector('IED[name="IED3"] DataSet[name="PhsMeas1"]'))
.to.exist;
expect(doc.querySelector('SMV[cbName="MSVCB01"]')).to.exist;

const deleteButton = <Button>(
element.wizardUI.dialog!.querySelector('mwc-button[icon="delete"]')!
);
await deleteButton.updateComplete;
deleteButton.click();

expect(
doc.querySelector(
'IED[name="IED3"] SampledValueControl[name="MSVCB01"]'
)
).to.not.exist;
expect(doc.querySelector('IED[name="IED3"] DataSet[name="PhsMeas1"]'))
.to.not.exist;
expect(doc.querySelector('SMV[cbName="MSVCB01"]')).to.not.exist;
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,11 @@ snapshots["Wizards for SCL element SampledValueControl define an edit wizard tha
SignatureAndEncryption
</mwc-list-item>
</wizard-select>
<mwc-button
icon="delete"
label="[remove]"
>
</mwc-button>
</div>
<mwc-button
dialogaction="close"
Expand Down
120 changes: 119 additions & 1 deletion test/unit/wizards/sampledvaluecontrol.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,15 @@ import { SinonSpy, spy } from 'sinon';
import '../../mock-wizard.js';
import { MockWizard } from '../../mock-wizard.js';

import { isUpdate, Update, WizardInput } from '../../../src/foundation.js';
import {
isDelete,
isUpdate,
Update,
WizardInput,
} from '../../../src/foundation.js';
import {
editSampledValueControlWizard,
removeSampledValueControlAction,
selectSampledValueControlWizard,
} from '../../../src/wizards/sampledvaluecontrol.js';
import fc, { integer } from 'fast-check';
Expand Down Expand Up @@ -265,6 +271,118 @@ describe('Wizards for SCL element SampledValueControl', () => {
'Signature'
);
});

describe('contains a remove button that', () => {
const ln01smv = <Element>new DOMParser().parseFromString(
`<LN0 lnClass="LLN0" lnType="myType">
<DataSet name="myDataSet"/>
<DataSet name="myDataSet2"/>
<SampledValueControl name="myName" datSet="myDataSet"/>
<ReportControl name="myName2" datSet="myDataSet2"/>
</LN0>`,
'application/xml'
).documentElement;

const ln02smv2 = <Element>new DOMParser().parseFromString(
`<LN0 lnClass="LLN0" lnType="myType">
<DataSet name="myDataSet"/>
<SampledValueControl name="myName" datSet="myDataSet"/>
<SampledValueControl name="myName2" datSet="myDataSet"/>
</LN0>`,
'application/xml'
).documentElement;

const ln02gse = <Element>new DOMParser().parseFromString(
`<LN0 lnClass="LLN0" lnType="myType">
<DataSet name="myDataSet"/>
<SampledValueControl name="myName" datSet="myDataSet"/>
<GSEControl name="myName2" datSet="myDataSet"/>
</LN0>`,
'application/xml'
).documentElement;

const ln02rp = <Element>new DOMParser().parseFromString(
`<LN0 lnClass="LLN0" lnType="myType">
<DataSet name="myDataSet"/>
<ReportControl name="myName" datSet="myDataSet"/>
<SampledValueControl name="myName2" datSet="myDataSet"/>
</LN0>`,
'application/xml'
).documentElement;

const missingparent = <Element>(
new DOMParser().parseFromString(
`<SampledValueControl name="myName" datSet="myDataSet"/>`,
'application/xml'
).documentElement
);

it('removes SampledValueControl and its referenced DataSet if no other SampledValueControl is assigned', () => {
const sampledValueControl = ln01smv.querySelector(
'SampledValueControl'
)!;
const actions = removeSampledValueControlAction(sampledValueControl);
expect(actions.length).to.equal(2);
expect(actions[0]).to.satisfy(isDelete);
expect(actions[0].old.element).to.equal(sampledValueControl);
expect(actions[1]).to.satisfy(isDelete);
expect(actions[1].old.element).to.equal(
ln01smv.querySelector('DataSet')
);
});

it('does not remove DataSet with another SampledValueControl referenced', () => {
const sampledValueControl = ln02smv2.querySelector(
'SampledValueControl'
)!;
const actions = removeSampledValueControlAction(sampledValueControl);
expect(actions.length).to.equal(1);
expect(actions[0]).to.satisfy(isDelete);
expect(actions[0].old.element).to.equal(sampledValueControl);
});

it('does not remove DataSet with another GSEControl referenced', () => {
const sampledValueControl = ln02gse.querySelector(
'SampledValueControl'
)!;
const actions = removeSampledValueControlAction(sampledValueControl);
expect(actions.length).to.equal(1);
expect(actions[0]).to.satisfy(isDelete);
expect(actions[0].old.element).to.equal(sampledValueControl);
});

it('does not remove DataSet with another ReportControl referenced', () => {
const sampledValueControl = ln02rp.querySelector(
'SampledValueControl'
)!;
const actions = removeSampledValueControlAction(sampledValueControl);
expect(actions.length).to.equal(1);
expect(actions[0]).to.satisfy(isDelete);
expect(actions[0].old.element).to.equal(sampledValueControl);
});

it('does not remove with missing parent element', () => {
const actions = removeSampledValueControlAction(missingparent);
expect(actions.length).to.equal(0);
});

it('removes referenced SMV element in the Communication section', () => {
const sampledValueControl = doc.querySelector(
'IED[name="IED3"] SampledValueControl'
)!;
const actions = removeSampledValueControlAction(sampledValueControl);
expect(actions.length).to.equal(3);
expect(actions[0]).to.satisfy(isDelete);
expect(actions[0].old.element).to.equal(sampledValueControl);
expect(actions[1]).to.satisfy(isDelete);
expect(actions[2]).to.satisfy(isDelete);
expect(actions[2].old.element).to.equal(
doc.querySelector(
'Communication SMV[ldInst="MU01"][cbName="MSVCB01"]'
)
);
});
});
});

describe('define a select wizard that', () => {
Expand Down

0 comments on commit 1940571

Please sign in to comment.