diff --git a/foundation/subscription/subscription.ts b/foundation/subscription/subscription.ts index efc7016..1f7d0af 100644 --- a/foundation/subscription/subscription.ts +++ b/foundation/subscription/subscription.ts @@ -143,7 +143,6 @@ export function removeSubscriptionSupervision( return edits; } -// TODO: Daniel has changed this function /** * Counts the max number of LN instances with supervision allowed for * the given control block's type of message. @@ -254,3 +253,29 @@ export function createNewSupervisionLnEvent( } return null; } + +export function clearSupervisionReference(ln: Element): Edit[] | undefined { + const val = ln.querySelector( + ':scope > DOI[name="GoCBRef"] > DAI[name="setSrcRef"] > Val, :scope > DOI[name="SvCBRef"] > DAI[name="setSrcRef"] > Val' + ); + if (!val || val.textContent === '') return undefined; + + const edits: Edit[] = []; + + // remove old element + edits.push({ + node: val + }); + + const newValElement = val.cloneNode(true); + newValElement.textContent = ''; + + // add new element + edits.push({ + parent: val.parentElement!, + reference: null, + node: newValElement + }); + + return edits; +} diff --git a/oscd-supervision.ts b/oscd-supervision.ts index db65c2d..175f7d7 100644 --- a/oscd-supervision.ts +++ b/oscd-supervision.ts @@ -14,7 +14,7 @@ import { sourceControlBlock, instantiateSubscriptionSupervision } from '@openenergytools/scl-lib'; -import { newEditEvent, Remove } from '@openscd/open-scd-core'; +import { Edit, newEditEvent, Remove } from '@openscd/open-scd-core'; import '@material/mwc-button'; import '@material/mwc-formfield'; @@ -50,6 +50,7 @@ import { } from './foundation/icons.js'; import { + clearSupervisionReference, controlBlockReference, createNewSupervisionLnEvent as createNewSupervisionLnEdit, isSupervisionModificationAllowed, @@ -449,7 +450,7 @@ export default class OscdSupervision extends LitElement { } } - if (_changedProperties.has('selectedIed')) { + if (_changedProperties.has('selectedIEDs')) { this.updateCBRefInfo(this.selectedIed, this.controlType); this.clearListSelections(); this.resetSearchFilters(); @@ -943,7 +944,19 @@ export default class OscdSupervision extends LitElement { this.selectedControl && (this.selectedSupervision || this.newSupervision) ) { - const edits = instantiateSubscriptionSupervision( + if (this.selectedSupervision) { + // TODO: We have to remove first to use the scl-lib function + // We hope to have an upstream overwrite option before too long + // See https://github.com/OpenEnergyTools/scl-lib/issues/79 + + const edits: Edit[] = []; + const removalEdit = clearSupervisionReference( + this.selectedSupervision + ); + if (removalEdit) edits.push(removalEdit); + this.dispatchEvent(newEditEvent(edits)); + } + const instantiationEdit = instantiateSubscriptionSupervision( { subscriberIedOrLn: this.newSupervision ? this.selectedIed! @@ -953,12 +966,13 @@ export default class OscdSupervision extends LitElement { { newSupervisionLn: this.newSupervision, fixedLnInst: -1, - checkEditableSrcRef: false, + checkEditableSrcRef: true, checkDuplicateSupervisions: true, checkMaxSupervisionLimits: true } ); - if (edits) this.dispatchEvent(newEditEvent(edits)); + if (instantiationEdit) + this.dispatchEvent(newEditEvent(instantiationEdit)); } this.updateCBRefInfo(this.selectedIed, this.controlType); diff --git a/test/fixtures/supervisions.scd b/test/fixtures/supervisions.scd index 22d2ee0..8e05cc0 100644 --- a/test/fixtures/supervisions.scd +++ b/test/fixtures/supervisions.scd @@ -519,7 +519,12 @@ - + + + + + + @@ -530,7 +535,14 @@ - + + + + + GOOSE_PublisherQB2_Disconnector/LLN0.GOOSE1 + + + diff --git a/test/integration/supervision.test.ts b/test/integration/supervision.test.ts index 247dbf7..cabef59 100644 --- a/test/integration/supervision.test.ts +++ b/test/integration/supervision.test.ts @@ -300,6 +300,14 @@ describe(pluginName, () => { await resetMouseState(); await visualDiff(plugin, testName(this)); }); + + it('including where supervisions cannot be changed', async function () { + await changeIED(plugin, 'GOOSE_Subscriber3'); + + await plugin.updateComplete; + await timeout(standardWait); + await visualDiff(plugin, testName(this)); + }); }); describe('changes supervisions', () => { @@ -469,80 +477,137 @@ describe(pluginName, () => { await visualDiff(plugin, testName(this)); }); - // TODO: - // it('can reassign a supervision with no local subscriptions', async function () { - // it('can reassign a supervision with an invalid control block', async function () { - - // TODO: REmove comment, is caused by no local subscriptions but valid control block - // See https://github.com/OpenEnergyTools/scl-lib/issues/79 - // - // it('can carry out a sequence of create, disconnect, delete and connect', async function () { - // // can create - // await changeIED(plugin, 'GOOSE_Subscriber1'); - // await timeout(standardWait); - - // const createNewSupLn = plugin.shadowRoot!.querySelector( - // 'section.unused mwc-icon-button#createNewLN' - // ); - // await sendMouse({ - // type: 'click', - // button: 'left', - // position: midEl(createNewSupLn!) - // }); - // await plugin.updateComplete; - // await timeout(standardWait); - - // // can disconnect - // const removeButton = plugin.shadowRoot!.querySelector( - // 'section > .mlist.remover > mwc-list-item[data-ln="GOOSE_Subscriber1>>GOOSE_Supervision> LGOS 2"] > mwc-icon' - // ); - // await sendMouse({ - // type: 'click', - // button: 'left', - // position: midEl(removeButton!) - // }); - // await plugin.updateComplete; - // await timeout(standardWait); - - // // can delete - // const deleteUnusedSupLn = plugin.shadowRoot!.querySelector( - // 'section.unused div.available-grouper > mwc-list.deleter > mwc-list-item[data-ln="GOOSE_Subscriber1>>GOOSE_Supervision> LGOS 2"]' - // ); - // await sendMouse({ - // type: 'click', - // button: 'left', - // position: midEl(deleteUnusedSupLn!) - // }); - // await plugin.updateComplete; - // await timeout(standardWait); - - // // can assign - // const assignNewSupLn = plugin.shadowRoot!.querySelector( - // 'section.unused div.available-grouper > .filteredList > mwc-list > mwc-list-item[data-ln="GOOSE_Subscriber1>>GOOSE_Supervision> LGOS 3"]' - // ); - // await sendMouse({ - // type: 'click', - // button: 'left', - // position: midEl(assignNewSupLn!) - // }); - // await plugin.updateComplete; - // await timeout(standardWait); - - // const existingCb = plugin.shadowRoot!.querySelector( - // 'section.unused oscd-filtered-list#unusedControls > mwc-list-item[data-control="GOOSE_Publisher2>>QB2_Disconnector>GOOSE2"]' - // ); - // await sendMouse({ - // type: 'click', - // button: 'left', - // position: midEl(existingCb!) - // }); - - // await plugin.updateComplete; - // await timeout(standardWait); - // await resetMouseState(); - - // await visualDiff(plugin, testName(this)); - // }); + it('can reassign a supervision with no local subscriptions', async function () { + await changeIED(plugin, 'GOOSE_Subscriber5'); + await timeout(standardWait); + + // can assign + const assignNewSupLn = plugin.shadowRoot!.querySelector( + 'section.unused div.available-grouper > .filteredList > mwc-list > mwc-list-item[data-ln="GOOSE_Subscriber5>>GOOSE_supervision> LGOS 2"]' + ); + await sendMouse({ + type: 'click', + button: 'left', + position: midEl(assignNewSupLn!) + }); + await plugin.updateComplete; + await timeout(standardWait); + + const existingCb = plugin.shadowRoot!.querySelector( + 'section.unused oscd-filtered-list#unusedControls > mwc-list-item[data-control="GOOSE_Publisher>>QB2_Disconnector>GOOSE2"]' + ); + await sendMouse({ + type: 'click', + button: 'left', + position: midEl(existingCb!) + }); + + await plugin.updateComplete; + await timeout(standardWait); + await resetMouseState(); + + await visualDiff(plugin, testName(this)); + }); + + it('can reassign a supervision with an invalid control block', async function () { + await changeIED(plugin, 'GOOSE_Subscriber5'); + await timeout(standardWait); + + // can assign + const assignNewSupLn = plugin.shadowRoot!.querySelector( + 'section.unused div.available-grouper > .filteredList > mwc-list > mwc-list-item[data-ln="GOOSE_Subscriber5>>GOOSE_supervision> LGOS 1"]' + ); + await sendMouse({ + type: 'click', + button: 'left', + position: midEl(assignNewSupLn!) + }); + await plugin.updateComplete; + await timeout(standardWait); + + const existingCb = plugin.shadowRoot!.querySelector( + 'section.unused oscd-filtered-list#unusedControls > mwc-list-item[data-control="GOOSE_Publisher>>QB2_Disconnector>GOOSE2"]' + ); + await sendMouse({ + type: 'click', + button: 'left', + position: midEl(existingCb!) + }); + + await plugin.updateComplete; + await timeout(standardWait); + await resetMouseState(); + + await visualDiff(plugin, testName(this)); + }); + + it('can carry out a sequence of create, disconnect, delete and connect', async function () { + // can create + await changeIED(plugin, 'GOOSE_Subscriber1'); + await timeout(standardWait); + + const createNewSupLn = plugin.shadowRoot!.querySelector( + 'section.unused mwc-icon-button#createNewLN' + ); + await sendMouse({ + type: 'click', + button: 'left', + position: midEl(createNewSupLn!) + }); + await plugin.updateComplete; + await timeout(standardWait); + + // can disconnect + const removeButton = plugin.shadowRoot!.querySelector( + 'section > .mlist.remover > mwc-list-item[data-ln="GOOSE_Subscriber1>>GOOSE_Supervision> LGOS 2"] > mwc-icon' + ); + await sendMouse({ + type: 'click', + button: 'left', + position: midEl(removeButton!) + }); + await plugin.updateComplete; + await timeout(standardWait); + + // can delete + const deleteUnusedSupLn = plugin.shadowRoot!.querySelector( + 'section.unused div.available-grouper > mwc-list.deleter > mwc-list-item[data-ln="GOOSE_Subscriber1>>GOOSE_Supervision> LGOS 2"]' + ); + await sendMouse({ + type: 'click', + button: 'left', + position: midEl(deleteUnusedSupLn!) + }); + await plugin.updateComplete; + await timeout(standardWait); + + // can assign + const assignNewSupLn = plugin.shadowRoot!.querySelector( + 'section.unused div.available-grouper > .filteredList > mwc-list > mwc-list-item[data-ln="GOOSE_Subscriber1>>GOOSE_Supervision> LGOS 3"]' + ); + await sendMouse({ + type: 'click', + button: 'left', + position: midEl(assignNewSupLn!) + }); + await plugin.updateComplete; + await timeout(standardWait); + + const existingCb = plugin.shadowRoot!.querySelector( + 'section.unused oscd-filtered-list#unusedControls > mwc-list-item[data-control="GOOSE_Publisher2>>QB2_Disconnector>GOOSE2"]' + ); + await sendMouse({ + type: 'click', + button: 'left', + position: midEl(existingCb!) + }); + + await plugin.updateComplete; + await timeout(standardWait); + await resetMouseState(); + + await visualDiff(plugin, testName(this)); + }); it('can carry out a sequence of delete, connect and delete, connect', async function () { await changeIED(plugin, 'GOOSE_Subscriber1'); diff --git a/test/screenshots/baseline/LGOS changes supervisions can delete an unused supervision-Firefox.png b/test/screenshots/baseline/LGOS changes supervisions can delete an unused supervision-Firefox.png index db698ea..00e17d9 100644 Binary files a/test/screenshots/baseline/LGOS changes supervisions can delete an unused supervision-Firefox.png and b/test/screenshots/baseline/LGOS changes supervisions can delete an unused supervision-Firefox.png differ diff --git a/test/screenshots/baseline/LGOS changes supervisions can reassign a supervision with an invalid control block-Chromium.png b/test/screenshots/baseline/LGOS changes supervisions can reassign a supervision with an invalid control block-Chromium.png new file mode 100644 index 0000000..84bf500 Binary files /dev/null and b/test/screenshots/baseline/LGOS changes supervisions can reassign a supervision with an invalid control block-Chromium.png differ diff --git a/test/screenshots/baseline/LGOS changes supervisions can reassign a supervision with an invalid control block-Firefox.png b/test/screenshots/baseline/LGOS changes supervisions can reassign a supervision with an invalid control block-Firefox.png new file mode 100644 index 0000000..a8bcdd0 Binary files /dev/null and b/test/screenshots/baseline/LGOS changes supervisions can reassign a supervision with an invalid control block-Firefox.png differ diff --git a/test/screenshots/baseline/LGOS changes supervisions can reassign a supervision with no local subscriptions-Chromium.png b/test/screenshots/baseline/LGOS changes supervisions can reassign a supervision with no local subscriptions-Chromium.png new file mode 100644 index 0000000..c0fe02b Binary files /dev/null and b/test/screenshots/baseline/LGOS changes supervisions can reassign a supervision with no local subscriptions-Chromium.png differ diff --git a/test/screenshots/baseline/LGOS changes supervisions can reassign a supervision with no local subscriptions-Firefox.png b/test/screenshots/baseline/LGOS changes supervisions can reassign a supervision with no local subscriptions-Firefox.png new file mode 100644 index 0000000..1ca4f64 Binary files /dev/null and b/test/screenshots/baseline/LGOS changes supervisions can reassign a supervision with no local subscriptions-Firefox.png differ diff --git a/test/screenshots/baseline/LGOS shows supervisions including where supervisions cannot be changed-Chromium.png b/test/screenshots/baseline/LGOS shows supervisions including where supervisions cannot be changed-Chromium.png new file mode 100644 index 0000000..5d1da2b Binary files /dev/null and b/test/screenshots/baseline/LGOS shows supervisions including where supervisions cannot be changed-Chromium.png differ diff --git a/test/screenshots/baseline/LGOS shows supervisions including where supervisions cannot be changed-Firefox.png b/test/screenshots/baseline/LGOS shows supervisions including where supervisions cannot be changed-Firefox.png new file mode 100644 index 0000000..54cfe99 Binary files /dev/null and b/test/screenshots/baseline/LGOS shows supervisions including where supervisions cannot be changed-Firefox.png differ