@@ -198,6 +198,83 @@ enabled = ["ftp", "ntp"]
198
198
disabled = ["telnet"]
199
199
` ;
200
200
201
+ const ONPREM_BLUEPRINT_TOML_WITH_INVALID_VALUES = `
202
+ name = "tmux"
203
+ description = "tmux image with openssh"
204
+ version = "1.2.16"
205
+ distro = "rhel-93"
206
+
207
+ [[packages]]
208
+ name = "tmux"
209
+ version = "*"
210
+
211
+ [[packages]]
212
+ name = "openssh-server"
213
+ version = "*"
214
+
215
+ [[groups]]
216
+ name = "anaconda-tools"
217
+
218
+ [customizations]
219
+ hostname = "--invalid-hostname--"
220
+ fips = true
221
+
222
+ [[customizations.sshkey]]
223
+ user = "root"
224
+ key = "ssh-rsa d"
225
+
226
+ [[customizations.user]]
227
+ name = "admin"
228
+ password = "$6$CHO2$3rN8eviE2t50lmVyBYihTgVRHcaecmeCk31L..."
229
+ key = "ssh-rsa d"
230
+ groups = ["widget", "users", "wheel"]
231
+
232
+ [customizations.services]
233
+ enabled = ["--invalid-enabled-service"]
234
+ disabled = ["--invalid-disabled-service"]
235
+ masked = ["--invalid-masked-service"]
236
+
237
+ [[customizations.files]]
238
+ data = "W1VuaXRdCkRlc2NyaXB0aW9uPVJ1biBmaXJzdCBib290IHNjcmlwdApDb25kaXRpb25QYXRoRXhpc3RzPS91c3IvbG9jYWwvc2Jpbi9jdXN0b20tZmlyc3QtYm9vdApXYW50cz1uZXR3b3JrLW9ubGluZS50YXJnZXQKQWZ0ZXI9bmV0d29yay1vbmxpbmUudGFyZ2V0CkFmdGVyPW9zYnVpbGQtZmlyc3QtYm9vdC5zZXJ2aWNlCgpbU2VydmljZV0KVHlwZT1vbmVzaG90CkV4ZWNTdGFydD0vdXNyL2xvY2FsL3NiaW4vY3VzdG9tLWZpcnN0LWJvb3QKRXhlY1N0YXJ0UG9zdD1tdiAvdXNyL2xvY2FsL3NiaW4vY3VzdG9tLWZpcnN0LWJvb3QgL3Vzci9sb2NhbC9zYmluL2N1c3RvbS1maXJzdC1ib290LmRvbmUKCltJbnN0YWxsXQpXYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldAo="
239
+ data_encoding = "base64"
240
+ ensure_parents = true
241
+ path = "/etc/systemd/system/custom-first-boot.service"
242
+
243
+ [[customizations.files]]
244
+ data = "IyEvYmluL2Jhc2gKZmlyc3Rib290IHNjcmlwdCB0byB0ZXN0IGltcG9ydA=="
245
+ data_encoding = "base64"
246
+ ensure_parents = true
247
+ mode = "0774"
248
+ path = "/usr/local/sbin/custom-first-boot"
249
+
250
+ [[customizations.filesystem]]
251
+ mountpoint = "/var"
252
+ minsize = 1000000
253
+
254
+ [customizations.installer]
255
+ unattended = true
256
+ sudo-nopasswd = ["user", "%wheel"]
257
+
258
+ [customizations.timezone]
259
+ timezone = "invalid-timezone"
260
+ ntpservers = ["0.north-america.pool.ntp.org", "1.north-america.pool.ntp.org", "invalid-ntp-server"]
261
+
262
+ [customizations.locale]
263
+ languages = ["invalid-language"]
264
+ keyboard = "invalid-keyboard"
265
+
266
+ [customizations.kernel]
267
+ name = "--invalid-kernel-name--"
268
+ append = "invalid-kernel-argument"
269
+
270
+ [customizations.firewall]
271
+ ports = ["invalid-port"]
272
+
273
+ [customizations.firewall.services]
274
+ enabled = ["--invalid-enabled-service"]
275
+ disabled = ["--invalid-disabled-service"]
276
+ ` ;
277
+
201
278
const uploadFile = async ( filename : string , content : string ) : Promise < void > => {
202
279
const user = userEvent . setup ( ) ;
203
280
const fileInput : HTMLElement | null =
@@ -437,4 +514,172 @@ describe('Import modal', () => {
437
514
await screen . findByText ( 'telnetd' ) ;
438
515
await screen . findByText ( 'rpcbind' ) ;
439
516
} , 20000 ) ;
517
+
518
+ test ( 'should render errors for invalid values' , async ( ) => {
519
+ await setUp ( ) ;
520
+ await uploadFile (
521
+ `blueprints.toml` ,
522
+ ONPREM_BLUEPRINT_TOML_WITH_INVALID_VALUES
523
+ ) ;
524
+ const reviewButton = screen . getByTestId ( 'import-blueprint-finish' ) ;
525
+ await waitFor ( ( ) => expect ( reviewButton ) . not . toHaveClass ( 'pf-m-disabled' ) ) ;
526
+ user . click ( reviewButton ) ;
527
+
528
+ // Image output
529
+ const guestImageCheckBox = await screen . findByRole ( 'checkbox' , {
530
+ name : / v i r t u a l i z a t i o n g u e s t i m a g e c h e c k b o x / i,
531
+ } ) ;
532
+ await waitFor ( ( ) => user . click ( guestImageCheckBox ) ) ;
533
+
534
+ await clickNext ( ) ; // Registration
535
+ await clickNext ( ) ; // OpenScap
536
+
537
+ // File system configuration
538
+ await clickNext ( ) ;
539
+ expect (
540
+ await screen . findByText ( / T h e W i z a r d o n l y s u p p o r t s K i B , M i B , o r G i B / )
541
+ ) . toBeInTheDocument ( ) ;
542
+
543
+ await clickNext ( ) ; // Repository snapshot
544
+ await clickNext ( ) ; // Custom Repos step
545
+ await clickNext ( ) ; // Packages step
546
+ await clickNext ( ) ; // Users
547
+
548
+ // Timezone
549
+ await clickNext ( ) ;
550
+ expect ( await screen . findByText ( 'Unknown timezone' ) ) . toBeInTheDocument ( ) ;
551
+ expect (
552
+ await screen . findByText ( 'Invalid NTP servers: invalid-ntp-server' )
553
+ ) . toBeInTheDocument ( ) ;
554
+ const clearButtons = await screen . findAllByRole ( 'button' , {
555
+ name : / c l e a r i n p u t / i,
556
+ } ) ;
557
+ await waitFor ( async ( ) => user . click ( clearButtons [ 0 ] ) ) ;
558
+ await waitFor ( async ( ) =>
559
+ user . click (
560
+ await screen . findByRole ( 'button' , {
561
+ name : / c l o s e i n v a l i d - n t p - s e r v e r / i,
562
+ } )
563
+ )
564
+ ) ;
565
+
566
+ // Locale
567
+ await clickNext ( ) ;
568
+ expect (
569
+ await screen . findByText ( 'Unknown languages: invalid-language' )
570
+ ) . toBeInTheDocument ( ) ;
571
+ expect ( await screen . findByText ( 'Unknown keyboard' ) ) . toBeInTheDocument ( ) ;
572
+ await waitFor ( async ( ) =>
573
+ user . click (
574
+ await screen . findByRole ( 'button' , {
575
+ name : / c l o s e i n v a l i d - l a n g u a g e / i,
576
+ } )
577
+ )
578
+ ) ;
579
+ await waitFor ( async ( ) =>
580
+ user . click (
581
+ await screen . findByRole ( 'button' , {
582
+ name : / c l e a r i n p u t / i,
583
+ } )
584
+ )
585
+ ) ;
586
+
587
+ // Hostname
588
+ await clickNext ( ) ;
589
+ expect ( await screen . findByText ( / I n v a l i d h o s t n a m e / ) ) . toBeInTheDocument ( ) ;
590
+ await waitFor ( ( ) =>
591
+ user . clear (
592
+ screen . getByRole ( 'textbox' , {
593
+ name : / h o s t n a m e i n p u t / i,
594
+ } )
595
+ )
596
+ ) ;
597
+
598
+ // Kernel
599
+ await clickNext ( ) ;
600
+ expect ( await screen . findByText ( / I n v a l i d f o r m a t / ) ) . toBeInTheDocument ( ) ;
601
+ expect (
602
+ await screen . findByText ( / I n v a l i d k e r n e l a r g u m e n t s / )
603
+ ) . toBeInTheDocument ( ) ;
604
+ await waitFor ( ( ) =>
605
+ user . click ( screen . getAllByRole ( 'button' , { name : / c l e a r i n p u t / i } ) [ 0 ] )
606
+ ) ;
607
+ await waitFor ( ( ) =>
608
+ user . click (
609
+ screen . getByRole ( 'button' , { name : / c l o s e i n v a l i d - k e r n e l - a r g u m e n t / i } )
610
+ )
611
+ ) ;
612
+
613
+ // Firewall
614
+ await clickNext ( ) ;
615
+ expect (
616
+ await screen . findByText ( / I n v a l i d p o r t s : i n v a l i d - p o r t / )
617
+ ) . toBeInTheDocument ( ) ;
618
+ expect (
619
+ await screen . findByText (
620
+ / I n v a l i d d i s a b l e d s e r v i c e s : - - i n v a l i d - d i s a b l e d - s e r v i c e /
621
+ )
622
+ ) . toBeInTheDocument ( ) ;
623
+ expect (
624
+ await screen . findByText (
625
+ / I n v a l i d e n a b l e d s e r v i c e s : - - i n v a l i d - e n a b l e d - s e r v i c e /
626
+ )
627
+ ) . toBeInTheDocument ( ) ;
628
+ await waitFor ( ( ) =>
629
+ user . click ( screen . getByRole ( 'button' , { name : / c l o s e i n v a l i d - p o r t / i } ) )
630
+ ) ;
631
+ await waitFor ( ( ) =>
632
+ user . click (
633
+ screen . getByRole ( 'button' , {
634
+ name : / c l o s e - - i n v a l i d - d i s a b l e d - s e r v i c e / i,
635
+ } )
636
+ )
637
+ ) ;
638
+ await waitFor ( ( ) =>
639
+ user . click (
640
+ screen . getByRole ( 'button' , { name : / c l o s e - - i n v a l i d - e n a b l e d - s e r v i c e / i } )
641
+ )
642
+ ) ;
643
+
644
+ // Services
645
+ await clickNext ( ) ;
646
+ expect (
647
+ await screen . findByText (
648
+ / I n v a l i d e n a b l e d s e r v i c e s : - - i n v a l i d - e n a b l e d - s e r v i c e /
649
+ )
650
+ ) . toBeInTheDocument ( ) ;
651
+ expect (
652
+ await screen . findByText (
653
+ / I n v a l i d d i s a b l e d s e r v i c e s : - - i n v a l i d - d i s a b l e d - s e r v i c e /
654
+ )
655
+ ) . toBeInTheDocument ( ) ;
656
+ expect (
657
+ await screen . findByText (
658
+ / I n v a l i d m a s k e d s e r v i c e s : - - i n v a l i d - m a s k e d - s e r v i c e /
659
+ )
660
+ ) . toBeInTheDocument ( ) ;
661
+ await waitFor ( ( ) =>
662
+ user . click (
663
+ screen . getByRole ( 'button' , { name : / c l o s e - - i n v a l i d - e n a b l e d - s e r v i c e / i } )
664
+ )
665
+ ) ;
666
+ await waitFor ( ( ) =>
667
+ user . click (
668
+ screen . getByRole ( 'button' , {
669
+ name : / c l o s e - - i n v a l i d - d i s a b l e d - s e r v i c e / i,
670
+ } )
671
+ )
672
+ ) ;
673
+ await waitFor ( ( ) =>
674
+ user . click (
675
+ screen . getByRole ( 'button' , { name : / c l o s e - - i n v a l i d - m a s k e d - s e r v i c e / i } )
676
+ )
677
+ ) ;
678
+
679
+ // Firstboot
680
+ await clickNext ( ) ;
681
+ expect (
682
+ await screen . findByRole ( 'heading' , { name : / F i r s t b o o t c o n f i g u r a t i o n / i } )
683
+ ) . toBeInTheDocument ( ) ;
684
+ } , 20000 ) ;
440
685
} ) ;
0 commit comments