@@ -2,7 +2,9 @@ import { describe, expect, test } from "vitest";
2
2
import type { Project } from "@webstudio-is/project" ;
3
3
import {
4
4
ROOT_FOLDER_ID ,
5
+ ROOT_INSTANCE_ID ,
5
6
encodeDataSourceVariable ,
7
+ encodeDataVariableId ,
6
8
type DataSource ,
7
9
type Instance ,
8
10
type WebstudioData ,
@@ -13,6 +15,14 @@ import {
13
15
} from "@webstudio-is/project-build" ;
14
16
import { $project } from "./nano-states" ;
15
17
import { insertPageCopyMutable } from "./page-utils" ;
18
+ import {
19
+ $ ,
20
+ expression ,
21
+ renderData ,
22
+ Variable ,
23
+ ws ,
24
+ } from "@webstudio-is/template" ;
25
+ import { nanoid } from "nanoid" ;
16
26
17
27
const toMap = < T extends { id : string } > ( list : T [ ] ) =>
18
28
new Map ( list . map ( ( item ) => [ item . id , item ] ) ) ;
@@ -401,4 +411,130 @@ describe("insert page copy", () => {
401
411
expect ( data . pages . pages [ 2 ] . name ) . toEqual ( `Name` ) ;
402
412
expect ( data . pages . pages [ 3 ] . name ) . toEqual ( `Name (1)` ) ;
403
413
} ) ;
414
+
415
+ test ( "preserve global variables when duplicate page" , ( ) => {
416
+ const globalVariable = new Variable ( "globalVariable" , "global value" ) ;
417
+ const data = {
418
+ pages : createDefaultPages ( {
419
+ rootInstanceId : "bodyId" ,
420
+ systemDataSourceId : "" ,
421
+ } ) ,
422
+ ...renderData (
423
+ < ws . root ws :id = { ROOT_INSTANCE_ID } vars = { expression `${ globalVariable } ` } >
424
+ < $ . Body ws :id = "bodyId" >
425
+ < $ . Box ws :id = "boxId" > { expression `${ globalVariable } ` } </ $ . Box >
426
+ </ $ . Body >
427
+ </ ws . root >
428
+ ) ,
429
+ } ;
430
+ data . instances . delete ( ROOT_INSTANCE_ID ) ;
431
+ insertPageCopyMutable ( {
432
+ source : { data, pageId : data . pages . homePage . id } ,
433
+ target : { data, folderId : ROOT_FOLDER_ID } ,
434
+ } ) ;
435
+ expect ( data . dataSources . size ) . toEqual ( 1 ) ;
436
+ const [ globalVariableId ] = data . dataSources . keys ( ) ;
437
+ expect ( Array . from ( data . instances . values ( ) ) ) . toEqual ( [
438
+ expect . objectContaining ( { component : "Body" , id : "bodyId" } ) ,
439
+ expect . objectContaining ( { component : "Box" , id : "boxId" } ) ,
440
+ expect . objectContaining ( { component : "Body" } ) ,
441
+ expect . objectContaining ( { component : "Box" } ) ,
442
+ ] ) ;
443
+ const newBox = Array . from ( data . instances . values ( ) ) . at ( - 1 ) ;
444
+ expect ( newBox ?. children ) . toEqual ( [
445
+ { type : "expression" , value : encodeDataVariableId ( globalVariableId ) } ,
446
+ ] ) ;
447
+ } ) ;
448
+
449
+ test ( "preserve existing global variables by name" , ( ) => {
450
+ const globalVariable = new Variable ( "globalVariable" , "global value" ) ;
451
+ const sourceData = {
452
+ pages : createDefaultPages ( {
453
+ rootInstanceId : "bodyId" ,
454
+ systemDataSourceId : "" ,
455
+ } ) ,
456
+ ...renderData (
457
+ < ws . root ws :id = { ROOT_INSTANCE_ID } vars = { expression `${ globalVariable } ` } >
458
+ < $ . Body ws :id = "bodyId" >
459
+ < $ . Box ws :id = "boxId" > { expression `${ globalVariable } ` } </ $ . Box >
460
+ </ $ . Body >
461
+ </ ws . root > ,
462
+ // generate different ids in source and data projects
463
+ nanoid
464
+ ) ,
465
+ } ;
466
+ sourceData . instances . delete ( ROOT_INSTANCE_ID ) ;
467
+ const targetData = {
468
+ pages : createDefaultPages ( {
469
+ rootInstanceId : "anotherBodyId" ,
470
+ systemDataSourceId : "" ,
471
+ } ) ,
472
+ ...renderData (
473
+ < ws . root ws :id = { ROOT_INSTANCE_ID } vars = { expression `${ globalVariable } ` } >
474
+ < $ . Body ws :id = "anotherBodyId" > </ $ . Body >
475
+ </ ws . root > ,
476
+ // generate different ids in source and data projects
477
+ nanoid
478
+ ) ,
479
+ } ;
480
+ targetData . instances . delete ( ROOT_INSTANCE_ID ) ;
481
+ insertPageCopyMutable ( {
482
+ source : { data : sourceData , pageId : sourceData . pages . homePage . id } ,
483
+ target : { data : targetData , folderId : ROOT_FOLDER_ID } ,
484
+ } ) ;
485
+ expect ( targetData . dataSources . size ) . toEqual ( 1 ) ;
486
+ const [ globalVariableId ] = targetData . dataSources . keys ( ) ;
487
+ expect ( Array . from ( targetData . instances . values ( ) ) ) . toEqual ( [
488
+ expect . objectContaining ( { component : "Body" , id : "anotherBodyId" } ) ,
489
+ expect . objectContaining ( { component : "Body" } ) ,
490
+ expect . objectContaining ( { component : "Box" } ) ,
491
+ ] ) ;
492
+ const newBox = Array . from ( targetData . instances . values ( ) ) . at ( - 1 ) ;
493
+ expect ( newBox ?. children ) . toEqual ( [
494
+ { type : "expression" , value : encodeDataVariableId ( globalVariableId ) } ,
495
+ ] ) ;
496
+ } ) ;
497
+
498
+ test ( "restore newly added global variable by name" , ( ) => {
499
+ const globalVariable = new Variable ( "globalVariable" , "global value" ) ;
500
+ const sourceData = {
501
+ pages : createDefaultPages ( {
502
+ rootInstanceId : "bodyId" ,
503
+ systemDataSourceId : "" ,
504
+ } ) ,
505
+ ...renderData (
506
+ < ws . root ws :id = { ROOT_INSTANCE_ID } vars = { expression `${ globalVariable } ` } >
507
+ < $ . Body ws :id = "bodyId" >
508
+ < $ . Box ws :id = "boxId" > { expression `${ globalVariable } ` } </ $ . Box >
509
+ </ $ . Body >
510
+ </ ws . root > ,
511
+ // generate different ids in source and data projects
512
+ nanoid
513
+ ) ,
514
+ } ;
515
+ sourceData . instances . delete ( ROOT_INSTANCE_ID ) ;
516
+ const targetData = {
517
+ pages : createDefaultPages ( {
518
+ rootInstanceId : "anotherBodyId" ,
519
+ systemDataSourceId : "" ,
520
+ } ) ,
521
+ // generate different ids in source and data projects
522
+ ...renderData ( < $ . Body ws :id = "anotherBodyId" > </ $ . Body > , nanoid ) ,
523
+ } ;
524
+ insertPageCopyMutable ( {
525
+ source : { data : sourceData , pageId : sourceData . pages . homePage . id } ,
526
+ target : { data : targetData , folderId : ROOT_FOLDER_ID } ,
527
+ } ) ;
528
+ expect ( targetData . dataSources . size ) . toEqual ( 1 ) ;
529
+ const [ globalVariableId ] = targetData . dataSources . keys ( ) ;
530
+ expect ( Array . from ( targetData . instances . values ( ) ) ) . toEqual ( [
531
+ expect . objectContaining ( { component : "Body" , id : "anotherBodyId" } ) ,
532
+ expect . objectContaining ( { component : "Body" } ) ,
533
+ expect . objectContaining ( { component : "Box" } ) ,
534
+ ] ) ;
535
+ const newBox = Array . from ( targetData . instances . values ( ) ) . at ( - 1 ) ;
536
+ expect ( newBox ?. children ) . toEqual ( [
537
+ { type : "expression" , value : encodeDataVariableId ( globalVariableId ) } ,
538
+ ] ) ;
539
+ } ) ;
404
540
} ) ;
0 commit comments