@@ -428,6 +428,147 @@ func TestTemplateEdit(t *testing.T) {
428
428
429
429
require .EqualValues (t , 1 , atomic .LoadInt64 (& updateTemplateCalled ))
430
430
431
+ // Assert that the template metadata did not change. We verify the
432
+ // correct request gets sent to the server already.
433
+ updated , err := client .Template (context .Background (), template .ID )
434
+ require .NoError (t , err )
435
+ assert .Equal (t , template .Name , updated .Name )
436
+ assert .Equal (t , template .Description , updated .Description )
437
+ assert .Equal (t , template .Icon , updated .Icon )
438
+ assert .Equal (t , template .DisplayName , updated .DisplayName )
439
+ assert .Equal (t , template .DefaultTTLMillis , updated .DefaultTTLMillis )
440
+ assert .Equal (t , template .MaxTTLMillis , updated .MaxTTLMillis )
441
+ })
442
+ })
443
+ t .Run ("AllowUserScheduling" , func (t * testing.T ) {
444
+ t .Parallel ()
445
+ t .Run ("BlockedAGPL" , func (t * testing.T ) {
446
+ t .Parallel ()
447
+ client := coderdtest .New (t , & coderdtest.Options {IncludeProvisionerDaemon : true })
448
+ user := coderdtest .CreateFirstUser (t , client )
449
+ version := coderdtest .CreateTemplateVersion (t , client , user .OrganizationID , nil )
450
+ _ = coderdtest .AwaitTemplateVersionJob (t , client , version .ID )
451
+ template := coderdtest .CreateTemplate (t , client , user .OrganizationID , version .ID , func (ctr * codersdk.CreateTemplateRequest ) {
452
+ ctr .DefaultTTLMillis = nil
453
+ ctr .MaxTTLMillis = nil
454
+ })
455
+
456
+ // Test the cli command with --allow-user-autostart.
457
+ cmdArgs := []string {
458
+ "templates" ,
459
+ "edit" ,
460
+ template .Name ,
461
+ "--allow-user-autostart=false" ,
462
+ }
463
+ inv , root := clitest .New (t , cmdArgs ... )
464
+ clitest .SetupConfig (t , client , root )
465
+
466
+ ctx := testutil .Context (t , testutil .WaitLong )
467
+ err := inv .WithContext (ctx ).Run ()
468
+ require .Error (t , err )
469
+ require .ErrorContains (t , err , "appears to be an AGPL deployment" )
470
+
471
+ // Test the cli command with --allow-user-autostop.
472
+ cmdArgs = []string {
473
+ "templates" ,
474
+ "edit" ,
475
+ template .Name ,
476
+ "--allow-user-autostop=false" ,
477
+ }
478
+ inv , root = clitest .New (t , cmdArgs ... )
479
+ clitest .SetupConfig (t , client , root )
480
+
481
+ ctx = testutil .Context (t , testutil .WaitLong )
482
+ err = inv .WithContext (ctx ).Run ()
483
+ require .Error (t , err )
484
+ require .ErrorContains (t , err , "appears to be an AGPL deployment" )
485
+
486
+ // Assert that the template metadata did not change.
487
+ updated , err := client .Template (context .Background (), template .ID )
488
+ require .NoError (t , err )
489
+ assert .Equal (t , template .Name , updated .Name )
490
+ assert .Equal (t , template .Description , updated .Description )
491
+ assert .Equal (t , template .Icon , updated .Icon )
492
+ assert .Equal (t , template .DisplayName , updated .DisplayName )
493
+ assert .Equal (t , template .DefaultTTLMillis , updated .DefaultTTLMillis )
494
+ assert .Equal (t , template .MaxTTLMillis , updated .MaxTTLMillis )
495
+ assert .Equal (t , template .AllowUserAutostart , updated .AllowUserAutostart )
496
+ assert .Equal (t , template .AllowUserAutostop , updated .AllowUserAutostop )
497
+ })
498
+
499
+ t .Run ("BlockedNotEntitled" , func (t * testing.T ) {
500
+ t .Parallel ()
501
+ client := coderdtest .New (t , & coderdtest.Options {IncludeProvisionerDaemon : true })
502
+ user := coderdtest .CreateFirstUser (t , client )
503
+ version := coderdtest .CreateTemplateVersion (t , client , user .OrganizationID , nil )
504
+ _ = coderdtest .AwaitTemplateVersionJob (t , client , version .ID )
505
+ template := coderdtest .CreateTemplate (t , client , user .OrganizationID , version .ID )
506
+
507
+ // Make a proxy server that will return a valid entitlements
508
+ // response, but without advanced scheduling entitlement.
509
+ proxy := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
510
+ if r .URL .Path == "/api/v2/entitlements" {
511
+ res := codersdk.Entitlements {
512
+ Features : map [codersdk.FeatureName ]codersdk.Feature {},
513
+ Warnings : []string {},
514
+ Errors : []string {},
515
+ HasLicense : true ,
516
+ Trial : true ,
517
+ RequireTelemetry : false ,
518
+ }
519
+ for _ , feature := range codersdk .FeatureNames {
520
+ res .Features [feature ] = codersdk.Feature {
521
+ Entitlement : codersdk .EntitlementNotEntitled ,
522
+ Enabled : false ,
523
+ Limit : nil ,
524
+ Actual : nil ,
525
+ }
526
+ }
527
+ httpapi .Write (r .Context (), w , http .StatusOK , res )
528
+ return
529
+ }
530
+
531
+ // Otherwise, proxy the request to the real API server.
532
+ httputil .NewSingleHostReverseProxy (client .URL ).ServeHTTP (w , r )
533
+ }))
534
+ defer proxy .Close ()
535
+
536
+ // Create a new client that uses the proxy server.
537
+ proxyURL , err := url .Parse (proxy .URL )
538
+ require .NoError (t , err )
539
+ proxyClient := codersdk .New (proxyURL )
540
+ proxyClient .SetSessionToken (client .SessionToken ())
541
+
542
+ // Test the cli command with --allow-user-autostart.
543
+ cmdArgs := []string {
544
+ "templates" ,
545
+ "edit" ,
546
+ template .Name ,
547
+ "--allow-user-autostart=false" ,
548
+ }
549
+ inv , root := clitest .New (t , cmdArgs ... )
550
+ clitest .SetupConfig (t , proxyClient , root )
551
+
552
+ ctx := testutil .Context (t , testutil .WaitLong )
553
+ err = inv .WithContext (ctx ).Run ()
554
+ require .Error (t , err )
555
+ require .ErrorContains (t , err , "license is not entitled" )
556
+
557
+ // Test the cli command with --allow-user-autostop.
558
+ cmdArgs = []string {
559
+ "templates" ,
560
+ "edit" ,
561
+ template .Name ,
562
+ "--allow-user-autostop=false" ,
563
+ }
564
+ inv , root = clitest .New (t , cmdArgs ... )
565
+ clitest .SetupConfig (t , proxyClient , root )
566
+
567
+ ctx = testutil .Context (t , testutil .WaitLong )
568
+ err = inv .WithContext (ctx ).Run ()
569
+ require .Error (t , err )
570
+ require .ErrorContains (t , err , "license is not entitled" )
571
+
431
572
// Assert that the template metadata did not change.
432
573
updated , err := client .Template (context .Background (), template .ID )
433
574
require .NoError (t , err )
@@ -437,6 +578,98 @@ func TestTemplateEdit(t *testing.T) {
437
578
assert .Equal (t , template .DisplayName , updated .DisplayName )
438
579
assert .Equal (t , template .DefaultTTLMillis , updated .DefaultTTLMillis )
439
580
assert .Equal (t , template .MaxTTLMillis , updated .MaxTTLMillis )
581
+ assert .Equal (t , template .AllowUserAutostart , updated .AllowUserAutostart )
582
+ assert .Equal (t , template .AllowUserAutostop , updated .AllowUserAutostop )
583
+ })
584
+ t .Run ("Entitled" , func (t * testing.T ) {
585
+ t .Parallel ()
586
+ client := coderdtest .New (t , & coderdtest.Options {IncludeProvisionerDaemon : true })
587
+ user := coderdtest .CreateFirstUser (t , client )
588
+ version := coderdtest .CreateTemplateVersion (t , client , user .OrganizationID , nil )
589
+ _ = coderdtest .AwaitTemplateVersionJob (t , client , version .ID )
590
+ template := coderdtest .CreateTemplate (t , client , user .OrganizationID , version .ID )
591
+
592
+ // Make a proxy server that will return a valid entitlements
593
+ // response, including a valid advanced scheduling entitlement.
594
+ var updateTemplateCalled int64
595
+ proxy := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
596
+ if r .URL .Path == "/api/v2/entitlements" {
597
+ res := codersdk.Entitlements {
598
+ Features : map [codersdk.FeatureName ]codersdk.Feature {},
599
+ Warnings : []string {},
600
+ Errors : []string {},
601
+ HasLicense : true ,
602
+ Trial : true ,
603
+ RequireTelemetry : false ,
604
+ }
605
+ for _ , feature := range codersdk .FeatureNames {
606
+ var one int64 = 1
607
+ res .Features [feature ] = codersdk.Feature {
608
+ Entitlement : codersdk .EntitlementNotEntitled ,
609
+ Enabled : true ,
610
+ Limit : & one ,
611
+ Actual : & one ,
612
+ }
613
+ }
614
+ httpapi .Write (r .Context (), w , http .StatusOK , res )
615
+ return
616
+ }
617
+ if strings .HasPrefix (r .URL .Path , "/api/v2/templates/" ) {
618
+ body , err := io .ReadAll (r .Body )
619
+ require .NoError (t , err )
620
+ _ = r .Body .Close ()
621
+
622
+ var req codersdk.UpdateTemplateMeta
623
+ err = json .Unmarshal (body , & req )
624
+ require .NoError (t , err )
625
+ assert .False (t , req .AllowUserAutostart )
626
+ assert .False (t , req .AllowUserAutostop )
627
+
628
+ r .Body = io .NopCloser (bytes .NewReader (body ))
629
+ atomic .AddInt64 (& updateTemplateCalled , 1 )
630
+ // We still want to call the real route.
631
+ }
632
+
633
+ // Otherwise, proxy the request to the real API server.
634
+ httputil .NewSingleHostReverseProxy (client .URL ).ServeHTTP (w , r )
635
+ }))
636
+ defer proxy .Close ()
637
+
638
+ // Create a new client that uses the proxy server.
639
+ proxyURL , err := url .Parse (proxy .URL )
640
+ require .NoError (t , err )
641
+ proxyClient := codersdk .New (proxyURL )
642
+ proxyClient .SetSessionToken (client .SessionToken ())
643
+
644
+ // Test the cli command.
645
+ cmdArgs := []string {
646
+ "templates" ,
647
+ "edit" ,
648
+ template .Name ,
649
+ "--allow-user-autostart=false" ,
650
+ "--allow-user-autostop=false" ,
651
+ }
652
+ inv , root := clitest .New (t , cmdArgs ... )
653
+ clitest .SetupConfig (t , proxyClient , root )
654
+
655
+ ctx := testutil .Context (t , testutil .WaitLong )
656
+ err = inv .WithContext (ctx ).Run ()
657
+ require .NoError (t , err )
658
+
659
+ require .EqualValues (t , 1 , atomic .LoadInt64 (& updateTemplateCalled ))
660
+
661
+ // Assert that the template metadata did not change. We verify the
662
+ // correct request gets sent to the server already.
663
+ updated , err := client .Template (context .Background (), template .ID )
664
+ require .NoError (t , err )
665
+ assert .Equal (t , template .Name , updated .Name )
666
+ assert .Equal (t , template .Description , updated .Description )
667
+ assert .Equal (t , template .Icon , updated .Icon )
668
+ assert .Equal (t , template .DisplayName , updated .DisplayName )
669
+ assert .Equal (t , template .DefaultTTLMillis , updated .DefaultTTLMillis )
670
+ assert .Equal (t , template .MaxTTLMillis , updated .MaxTTLMillis )
671
+ assert .Equal (t , template .AllowUserAutostart , updated .AllowUserAutostart )
672
+ assert .Equal (t , template .AllowUserAutostop , updated .AllowUserAutostop )
440
673
})
441
674
})
442
675
}
0 commit comments