@@ -3,6 +3,7 @@ package coderd_test
33import (
44"bytes"
55"context"
6+ "errors"
67"net/http"
78"slices"
89"testing"
@@ -2154,7 +2155,7 @@ func TestInvalidateTemplatePrebuilds(t *testing.T) {
21542155},
21552156LicenseOptions :& coderdenttest.LicenseOptions {
21562157Features : license.Features {
2157- codersdk .FeatureTemplateRBAC :1 ,
2158+ codersdk .FeatureWorkspacePrebuilds :1 ,
21582159},
21592160},
21602161})
@@ -2208,3 +2209,121 @@ func TestInvalidateTemplatePrebuilds(t *testing.T) {
22082209require .Equal (t , codersdk.InvalidatedPreset {TemplateName :template .Name ,TemplateVersionName :version2 .Name ,PresetName :presetWithParameters2 .Name },invalidated .Invalidated [0 ])
22092210require .Equal (t , codersdk.InvalidatedPreset {TemplateName :template .Name ,TemplateVersionName :version2 .Name ,PresetName :presetWithParameters3 .Name },invalidated .Invalidated [1 ])
22102211}
2212+
2213+ func TestInvalidateTemplatePrebuilds_RegularUser (t * testing.T ) {
2214+ t .Parallel ()
2215+
2216+ // Given the following parameters and presets...
2217+ templateVersionParameters := []* proto.RichParameter {
2218+ {Name :"param1" ,Type :"string" ,Required :false ,DefaultValue :"default1" },
2219+ }
2220+ presetWithParameters1 := & proto.Preset {
2221+ Name :"Preset With Parameters 1" ,
2222+ Parameters : []* proto.PresetParameter {
2223+ {Name :"param1" ,Value :"value1" },
2224+ },
2225+ }
2226+
2227+ ownerClient ,owner := coderdenttest .New (t ,& coderdenttest.Options {
2228+ Options :& coderdtest.Options {
2229+ IncludeProvisionerDaemon :true ,
2230+ },
2231+ LicenseOptions :& coderdenttest.LicenseOptions {
2232+ Features : license.Features {
2233+ codersdk .FeatureWorkspacePrebuilds :1 ,
2234+ },
2235+ },
2236+ })
2237+ regularUserClient ,_ := coderdtest .CreateAnotherUser (t ,ownerClient ,owner .OrganizationID )
2238+
2239+ // Given
2240+ version1 := coderdtest .CreateTemplateVersion (t ,ownerClient ,owner .OrganizationID ,& echo.Responses {
2241+ Parse :echo .ParseComplete ,
2242+ ProvisionPlan : []* proto.Response {
2243+ {
2244+ Type :& proto.Response_Plan {
2245+ Plan :& proto.PlanComplete {
2246+ Presets : []* proto.Preset {presetWithParameters1 },
2247+ Parameters :templateVersionParameters ,
2248+ },
2249+ },
2250+ },
2251+ },
2252+ ProvisionApply :echo .ApplyComplete ,
2253+ })
2254+ coderdtest .AwaitTemplateVersionJobCompleted (t ,ownerClient ,version1 .ID )
2255+ template := coderdtest .CreateTemplate (t ,ownerClient ,owner .OrganizationID ,version1 .ID )
2256+
2257+ // When
2258+ ctx := testutil .Context (t ,testutil .WaitShort )
2259+ _ ,err := regularUserClient .InvalidateTemplatePresets (ctx ,template .ID )
2260+
2261+ // Then
2262+ require .Error (t ,err ,"regular user cannot invalidate presets" )
2263+ var sdkError * codersdk.Error
2264+ require .True (t ,errors .As (err ,& sdkError ))
2265+ require .ErrorAs (t ,err ,& sdkError )
2266+ require .Equal (t ,http .StatusNotFound ,sdkError .StatusCode ())
2267+ }
2268+
2269+ func TestInvalidateTemplatePrebuilds_NoPresets (t * testing.T ) {
2270+ t .Parallel ()
2271+
2272+ // Given the template versions and template...
2273+ ownerClient ,owner := coderdenttest .New (t ,& coderdenttest.Options {
2274+ Options :& coderdtest.Options {
2275+ IncludeProvisionerDaemon :true ,
2276+ },
2277+ LicenseOptions :& coderdenttest.LicenseOptions {
2278+ Features : license.Features {
2279+ codersdk .FeatureWorkspacePrebuilds :1 ,
2280+ },
2281+ },
2282+ })
2283+ templateAdminClient ,_ := coderdtest .CreateAnotherUser (t ,ownerClient ,owner .OrganizationID ,rbac .RoleTemplateAdmin ())
2284+
2285+ version1 := coderdtest .CreateTemplateVersion (t ,templateAdminClient ,owner .OrganizationID ,& echo.Responses {
2286+ Parse :echo .ParseComplete ,ProvisionPlan :echo .PlanComplete ,ProvisionApply :echo .ApplyComplete ,
2287+ })
2288+ coderdtest .AwaitTemplateVersionJobCompleted (t ,templateAdminClient ,version1 .ID )
2289+ template := coderdtest .CreateTemplate (t ,templateAdminClient ,owner .OrganizationID ,version1 .ID )
2290+
2291+ // When
2292+ ctx := testutil .Context (t ,testutil .WaitLong )
2293+ invalidated ,err := templateAdminClient .InvalidateTemplatePresets (ctx ,template .ID )
2294+ require .NoError (t ,err )
2295+
2296+ // Then
2297+ require .NotNil (t ,invalidated .Invalidated )
2298+ require .Len (t ,invalidated .Invalidated ,0 )
2299+ }
2300+
2301+ func TestInvalidateTemplatePrebuilds_LicenseFeatureDisabled (t * testing.T ) {
2302+ t .Parallel ()
2303+
2304+ // Given the template versions and template...
2305+ ownerClient ,owner := coderdenttest .New (t ,& coderdenttest.Options {
2306+ Options :& coderdtest.Options {
2307+ IncludeProvisionerDaemon :true ,
2308+ },
2309+ LicenseOptions :& coderdenttest.LicenseOptions {},
2310+ })
2311+ templateAdminClient ,_ := coderdtest .CreateAnotherUser (t ,ownerClient ,owner .OrganizationID ,rbac .RoleTemplateAdmin ())
2312+
2313+ version1 := coderdtest .CreateTemplateVersion (t ,templateAdminClient ,owner .OrganizationID ,& echo.Responses {
2314+ Parse :echo .ParseComplete ,ProvisionPlan :echo .PlanComplete ,ProvisionApply :echo .ApplyComplete ,
2315+ })
2316+ coderdtest .AwaitTemplateVersionJobCompleted (t ,templateAdminClient ,version1 .ID )
2317+ template := coderdtest .CreateTemplate (t ,templateAdminClient ,owner .OrganizationID ,version1 .ID )
2318+
2319+ // When
2320+ ctx := testutil .Context (t ,testutil .WaitLong )
2321+ _ ,err := templateAdminClient .InvalidateTemplatePresets (ctx ,template .ID )
2322+
2323+ // Then
2324+ require .Error (t ,err ,"license feature prebuilds is required" )
2325+ var sdkError * codersdk.Error
2326+ require .True (t ,errors .As (err ,& sdkError ))
2327+ require .ErrorAs (t ,err ,& sdkError )
2328+ require .Equal (t ,http .StatusForbidden ,sdkError .StatusCode ())
2329+ }