@@ -11,7 +11,7 @@ import {
1111 isRemove ,
1212} from '@openenergytools/scl-lib/dist/foundation/utils.js' ;
1313
14- import { dataSetDoc } from './data-set-editor.testfiles.js' ;
14+ import { dataSetDoc , dataSetCopyDoc } from './data-set-editor.testfiles.js' ;
1515
1616import { DataSetEditor } from './data-set-editor.js' ;
1717
@@ -140,3 +140,124 @@ describe('DataSet editor component', () => {
140140 expect ( actionList . searchValue ) . to . equal ( 'IED1' ) ;
141141 } ) ;
142142} ) ;
143+
144+ describe ( 'DataSet copy' , ( ) => {
145+ const copyDoc = new DOMParser ( ) . parseFromString (
146+ dataSetCopyDoc ,
147+ 'application/xml'
148+ ) ;
149+
150+ let editor : DataSetEditor ;
151+ let editEvent : SinonSpy ;
152+
153+ beforeEach ( async ( ) => {
154+ editor = await fixture (
155+ html `< data-set-editor .doc ="${ copyDoc } "> </ data-set-editor > `
156+ ) ;
157+ editEvent = spy ( ) ;
158+ window . addEventListener ( 'oscd-edit-v2' , editEvent ) ;
159+ } ) ;
160+
161+ afterEach ( ( ) => {
162+ window . removeEventListener ( 'oscd-edit-v2' , editEvent ) ;
163+ } ) ;
164+
165+ it ( 'determines CanCopy status when target IED has matching structure and no conflict' , ( ) => {
166+ const dataSet = copyDoc . querySelector (
167+ 'IED[name="IED"] DataSet[name="datSet"]'
168+ ) ! ;
169+ const ied2 = copyDoc . querySelector ( 'IED[name="IED2"]' ) ! ;
170+
171+ const status = ( editor as any ) . getDataSetCopyStatus ( dataSet , ied2 ) ;
172+ expect ( status ) . to . equal ( 'CanCopy' ) ;
173+ } ) ;
174+
175+ it ( 'determines DataSetAlreadyExists when target IED has a DataSet with the same name' , ( ) => {
176+ const dataSet = copyDoc . querySelector (
177+ 'IED[name="IED"] DataSet[name="datSet"]'
178+ ) ! ;
179+ const ied3 = copyDoc . querySelector ( 'IED[name="IED3"]' ) ! ;
180+
181+ const status = ( editor as any ) . getDataSetCopyStatus ( dataSet , ied3 ) ;
182+ expect ( status ) . to . equal ( 'DataSetAlreadyExists' ) ;
183+ } ) ;
184+
185+ it ( 'determines IEDStructureIncompatible when target IED has no matching LDevice' , ( ) => {
186+ const dataSet = copyDoc . querySelector (
187+ 'IED[name="IED"] DataSet[name="datSet"]'
188+ ) ! ;
189+ const ied4 = copyDoc . querySelector ( 'IED[name="IED4"]' ) ! ;
190+
191+ const status = ( editor as any ) . getDataSetCopyStatus ( dataSet , ied4 ) ;
192+ expect ( status ) . to . equal ( 'IEDStructureIncompatible' ) ;
193+ } ) ;
194+
195+ it ( 'pre-selects only CanCopy IEDs when copy dialog is opened' , async ( ) => {
196+ const dataSet = copyDoc . querySelector (
197+ 'IED[name="IED"] DataSet[name="datSet"]'
198+ ) ! ;
199+
200+ // Simulate the folder_copy callback by setting copy options directly
201+ editor . dataSetCopyOptions = [ 'IED2' , 'IED3' , 'IED4' ] . map ( name => {
202+ const ied = copyDoc . querySelector ( `IED[name="${ name } "]` ) ! ;
203+ const status = ( editor as any ) . getDataSetCopyStatus ( dataSet , ied ) ;
204+ return { ied, dataSet, status, selected : status === 'CanCopy' } ;
205+ } ) ;
206+ await editor . updateComplete ;
207+
208+ const ied2Option = editor . dataSetCopyOptions . find (
209+ o => o . ied . getAttribute ( 'name' ) === 'IED2'
210+ ) ;
211+ const ied3Option = editor . dataSetCopyOptions . find (
212+ o => o . ied . getAttribute ( 'name' ) === 'IED3'
213+ ) ;
214+ const ied4Option = editor . dataSetCopyOptions . find (
215+ o => o . ied . getAttribute ( 'name' ) === 'IED4'
216+ ) ;
217+
218+ expect ( ied2Option ?. selected ) . to . be . true ;
219+ expect ( ied3Option ?. selected ) . to . be . false ;
220+ expect ( ied4Option ?. selected ) . to . be . false ;
221+ } ) ;
222+
223+ it ( 'dispatches an insert edit event for each selected IED when copying' , async ( ) => {
224+ const dataSet = copyDoc . querySelector (
225+ 'IED[name="IED"] DataSet[name="datSet"]'
226+ ) ! ;
227+ const ied2 = copyDoc . querySelector ( 'IED[name="IED2"]' ) ! ;
228+
229+ // Set up copy options with IED2 selected (CanCopy)
230+ editor . dataSetCopyOptions = [
231+ { ied : ied2 , dataSet, status : 'CanCopy' as any , selected : true } ,
232+ ] ;
233+ await editor . updateComplete ;
234+
235+ ( editor as any ) . copyDataSet ( ) ;
236+
237+ expect ( editEvent ) . to . have . been . calledOnce ;
238+
239+ const edits = editEvent . args [ 0 ] [ 0 ] . detail . edit ;
240+ expect ( edits ) . to . be . an ( 'array' ) . with . lengthOf ( 1 ) ;
241+ expect ( edits [ 0 ] ) . to . satisfy ( isInsert ) ;
242+ expect ( edits [ 0 ] . parent . tagName ) . to . equal ( 'LN0' ) ;
243+ expect ( edits [ 0 ] . node . tagName ) . to . equal ( 'DataSet' ) ;
244+ expect ( edits [ 0 ] . node . getAttribute ( 'name' ) ) . to . equal ( 'datSet' ) ;
245+ } ) ;
246+
247+ it ( 'does not dispatch an edit event when no IED is selected' , async ( ) => {
248+ const dataSet = copyDoc . querySelector (
249+ 'IED[name="IED"] DataSet[name="datSet"]'
250+ ) ! ;
251+ const ied2 = copyDoc . querySelector ( 'IED[name="IED2"]' ) ! ;
252+
253+ // All options deselected
254+ editor . dataSetCopyOptions = [
255+ { ied : ied2 , dataSet, status : 'CanCopy' as any , selected : false } ,
256+ ] ;
257+ await editor . updateComplete ;
258+
259+ ( editor as any ) . copyDataSet ( ) ;
260+
261+ expect ( editEvent ) . to . not . have . been . called ;
262+ } ) ;
263+ } ) ;
0 commit comments