@@ -439,6 +439,168 @@ func TestCreateWithRichParameters(t *testing.T) {
439439 })
440440}
441441
442+ func TestCreateValidateRichParameters (t * testing.T ) {
443+ t .Parallel ()
444+
445+ const (
446+ stringParameterName = "string_parameter"
447+ stringParameterValue = "abc"
448+
449+ numberParameterName = "number_parameter"
450+ numberParameterValue = "7"
451+
452+ boolParameterName = "bool_parameter"
453+ boolParameterValue = "true"
454+ )
455+
456+ numberRichParameters := []* proto.RichParameter {
457+ {Name : numberParameterName , Type : "number" , Mutable : true , ValidationMin : 3 , ValidationMax : 10 },
458+ }
459+
460+ stringRichParameters := []* proto.RichParameter {
461+ {Name : stringParameterName , Type : "string" , Mutable : true , ValidationRegex : "^[a-z]+$" , ValidationError : "this is error" },
462+ }
463+
464+ boolRichParameters := []* proto.RichParameter {
465+ {Name : boolParameterName , Type : "bool" , Mutable : true },
466+ }
467+
468+ prepareEchoResponses := func (richParameters []* proto.RichParameter ) * echo.Responses {
469+ return & echo.Responses {
470+ Parse : echo .ParseComplete ,
471+ ProvisionPlan : []* proto.Provision_Response {
472+ {
473+ Type : & proto.Provision_Response_Complete {
474+ Complete : & proto.Provision_Complete {
475+ Parameters : richParameters ,
476+ },
477+ },
478+ }},
479+ ProvisionApply : []* proto.Provision_Response {
480+ {
481+ Type : & proto.Provision_Response_Complete {
482+ Complete : & proto.Provision_Complete {},
483+ },
484+ },
485+ },
486+ }
487+ }
488+
489+ t .Run ("ValidateString" , func (t * testing.T ) {
490+ t .Parallel ()
491+
492+ client := coderdtest .New (t , & coderdtest.Options {IncludeProvisionerDaemon : true })
493+ user := coderdtest .CreateFirstUser (t , client )
494+ version := coderdtest .CreateTemplateVersion (t , client , user .OrganizationID , prepareEchoResponses (stringRichParameters ))
495+ coderdtest .AwaitTemplateVersionJob (t , client , version .ID )
496+
497+ template := coderdtest .CreateTemplate (t , client , user .OrganizationID , version .ID )
498+
499+ cmd , root := clitest .New (t , "create" , "my-workspace" , "--template" , template .Name )
500+ clitest .SetupConfig (t , client , root )
501+ doneChan := make (chan struct {})
502+ pty := ptytest .New (t )
503+ cmd .SetIn (pty .Input ())
504+ cmd .SetOut (pty .Output ())
505+ go func () {
506+ defer close (doneChan )
507+ err := cmd .Execute ()
508+ assert .NoError (t , err )
509+ }()
510+
511+ matches := []string {
512+ stringParameterName , "$$" ,
513+ "does not match" , "" ,
514+ "Enter a value" , "abc" ,
515+ "Confirm create?" , "yes" ,
516+ }
517+ for i := 0 ; i < len (matches ); i += 2 {
518+ match := matches [i ]
519+ value := matches [i + 1 ]
520+ pty .ExpectMatch (match )
521+ pty .WriteLine (value )
522+ }
523+ <- doneChan
524+ })
525+
526+ t .Run ("ValidateNumber" , func (t * testing.T ) {
527+ t .Parallel ()
528+
529+ client := coderdtest .New (t , & coderdtest.Options {IncludeProvisionerDaemon : true })
530+ user := coderdtest .CreateFirstUser (t , client )
531+ version := coderdtest .CreateTemplateVersion (t , client , user .OrganizationID , prepareEchoResponses (numberRichParameters ))
532+ coderdtest .AwaitTemplateVersionJob (t , client , version .ID )
533+
534+ template := coderdtest .CreateTemplate (t , client , user .OrganizationID , version .ID )
535+
536+ cmd , root := clitest .New (t , "create" , "my-workspace" , "--template" , template .Name )
537+ clitest .SetupConfig (t , client , root )
538+ doneChan := make (chan struct {})
539+ pty := ptytest .New (t )
540+ cmd .SetIn (pty .Input ())
541+ cmd .SetOut (pty .Output ())
542+ go func () {
543+ defer close (doneChan )
544+ err := cmd .Execute ()
545+ assert .NoError (t , err )
546+ }()
547+
548+ matches := []string {
549+ numberParameterName , "12" ,
550+ "is more than the maximum" , "" ,
551+ "Enter a value" , "8" ,
552+ "Confirm create?" , "yes" ,
553+ }
554+ for i := 0 ; i < len (matches ); i += 2 {
555+ match := matches [i ]
556+ value := matches [i + 1 ]
557+ pty .ExpectMatch (match )
558+
559+ if value != "" {
560+ pty .WriteLine (value )
561+ }
562+ }
563+ <- doneChan
564+ })
565+
566+ t .Run ("ValidateBool" , func (t * testing.T ) {
567+ t .Parallel ()
568+
569+ client := coderdtest .New (t , & coderdtest.Options {IncludeProvisionerDaemon : true })
570+ user := coderdtest .CreateFirstUser (t , client )
571+ version := coderdtest .CreateTemplateVersion (t , client , user .OrganizationID , prepareEchoResponses (boolRichParameters ))
572+ coderdtest .AwaitTemplateVersionJob (t , client , version .ID )
573+
574+ template := coderdtest .CreateTemplate (t , client , user .OrganizationID , version .ID )
575+
576+ cmd , root := clitest .New (t , "create" , "my-workspace" , "--template" , template .Name )
577+ clitest .SetupConfig (t , client , root )
578+ doneChan := make (chan struct {})
579+ pty := ptytest .New (t )
580+ cmd .SetIn (pty .Input ())
581+ cmd .SetOut (pty .Output ())
582+ go func () {
583+ defer close (doneChan )
584+ err := cmd .Execute ()
585+ assert .NoError (t , err )
586+ }()
587+
588+ matches := []string {
589+ boolParameterName , "cat" ,
590+ "boolean value can be either" , "" ,
591+ "Enter a value" , "true" ,
592+ "Confirm create?" , "yes" ,
593+ }
594+ for i := 0 ; i < len (matches ); i += 2 {
595+ match := matches [i ]
596+ value := matches [i + 1 ]
597+ pty .ExpectMatch (match )
598+ pty .WriteLine (value )
599+ }
600+ <- doneChan
601+ })
602+ }
603+
442604func createTestParseResponseWithDefault (defaultValue string ) []* proto.Parse_Response {
443605 return []* proto.Parse_Response {{
444606 Type : & proto.Parse_Response_Complete {
0 commit comments