@@ -8,61 +8,153 @@ import (
88 "github.com/stretchr/testify/assert"
99)
1010
11- func TestVariableCreate (t * testing.T ) {
11+ // variableTestSetup holds common test infrastructure for variable tests.
12+ type variableTestSetup struct {
13+ authServer * httptest.Server
14+ apiServer * httptest.Server
15+ apiHandler * mockapi.Handler
16+ projectID string
17+ mainEnv * mockapi.Environment
18+ factory * cmdFactory
19+ }
20+
21+ // setupVariableTest creates the common test infrastructure for variable tests.
22+ func setupVariableTest (t * testing.T ) * variableTestSetup {
1223 authServer := mockapi .NewAuthServer (t )
13- defer authServer .Close ( )
24+ t . Cleanup ( authServer .Close )
1425
1526 apiHandler := mockapi .NewHandler (t )
1627 apiServer := httptest .NewServer (apiHandler )
17- defer apiServer .Close ( )
28+ t . Cleanup ( apiServer .Close )
1829
1930 projectID := mockapi .ProjectID ()
2031
2132 apiHandler .SetProjects ([]* mockapi.Project {{
2233 ID : projectID ,
23- Links : mockapi .MakeHALLinks ("self=/projects/" + projectID ,
24- "environments=/projects/" + projectID + "/environments" ),
34+ Links : mockapi .MakeHALLinks (
35+ "self=/projects/" + projectID ,
36+ "environments=/projects/" + projectID + "/environments" ,
37+ ),
2538 DefaultBranch : "main" ,
2639 }})
27- main := makeEnv (projectID , "main" , "production" , "active" , nil )
28- main .Links ["#variables" ] = mockapi.HALLink {HREF : "/projects/" + projectID + "/environments/main/variables" }
29- main .Links ["#manage-variables" ] = mockapi.HALLink {HREF : "/projects/" + projectID + "/environments/main/variables" }
30- envs := []* mockapi.Environment {main }
31- apiHandler .SetEnvironments (envs )
3240
33- apiHandler .SetProjectVariables (projectID , []* mockapi.Variable {
41+ mainEnv := makeEnv (projectID , "main" , "production" , "active" , nil )
42+ mainEnv .Links ["#variables" ] = mockapi.HALLink {HREF : "/projects/" + projectID + "/environments/main/variables" }
43+ mainEnv .Links ["#manage-variables" ] = mockapi.HALLink {HREF : "/projects/" + projectID + "/environments/main/variables" }
44+
45+ return & variableTestSetup {
46+ authServer : authServer ,
47+ apiServer : apiServer ,
48+ apiHandler : apiHandler ,
49+ projectID : projectID ,
50+ mainEnv : mainEnv ,
51+ factory : newCommandFactory (t , apiServer .URL , authServer .URL ),
52+ }
53+ }
54+
55+ func TestVariableCreate (t * testing.T ) {
56+ s := setupVariableTest (t )
57+ s .apiHandler .SetEnvironments ([]* mockapi.Environment {s .mainEnv })
58+ s .apiHandler .SetProjectVariables (s .projectID , []* mockapi.Variable {
3459 {
3560 Name : "existing" ,
3661 IsSensitive : true ,
3762 VisibleBuild : true ,
3863 },
3964 })
4065
41- f := newCommandFactory ( t , apiServer . URL , authServer . URL )
66+ f , p := s . factory , s . projectID
4267
43- _ , stdErr , err := f .RunCombinedOutput ("var:create" , "-p" , projectID , "-l" , "e" , "-e" , "main" , "env:TEST" , "--value" , "env-level-value" )
68+ _ , stdErr , err := f .RunCombinedOutput ("var:create" , "-p" , p , "-l" , "e" , "-e" , "main" , "env:TEST" , "--value" , "env-level-value" )
4469 assert .NoError (t , err )
4570 assert .Contains (t , stdErr , "Creating variable env:TEST on the environment main" )
4671
47- assertTrimmed (t , "env-level-value" , f .Run ("var:get" , "-p" , projectID , "-e" , "main" , "env:TEST" , "-P" , "value" ))
72+ assertTrimmed (t , "env-level-value" , f .Run ("var:get" , "-p" , p , "-e" , "main" , "env:TEST" , "-P" , "value" ))
4873
49- _ , stdErr , err = f .RunCombinedOutput ("var:create" , "-p" , projectID , "env:TEST" , "-l" , "p" , "--value" , "project-level-value" )
74+ _ , stdErr , err = f .RunCombinedOutput ("var:create" , "-p" , p , "env:TEST" , "-l" , "p" , "--value" , "project-level-value" )
5075 assert .NoError (t , err )
51- assert .Contains (t , stdErr , "Creating variable env:TEST on the project " + projectID )
76+ assert .Contains (t , stdErr , "Creating variable env:TEST on the project " + p )
5277
53- assertTrimmed (t , "project-level-value" , f .Run ("var:get" , "-p" , projectID , "-e" , "main" , "env:TEST" , "-P" , "value" , "-l" , "p" ))
54- assertTrimmed (t , "env-level-value" , f .Run ("var:get" , "-p" , projectID , "-e" , "main" , "env:TEST" , "-P" , "value" , "-l" , "e" ))
78+ assertTrimmed (t , "project-level-value" , f .Run ("var:get" , "-p" , p , "-e" , "main" , "env:TEST" , "-P" , "value" , "-l" , "p" ))
79+ assertTrimmed (t , "env-level-value" , f .Run ("var:get" , "-p" , p , "-e" , "main" , "env:TEST" , "-P" , "value" , "-l" , "e" ))
5580
56- _ , stdErr , err = f .RunCombinedOutput ("var:create" , "-p" , projectID , "existing" , "-l" , "p" , "--value" , "test" )
81+ _ , stdErr , err = f .RunCombinedOutput ("var:create" , "-p" , p , "existing" , "-l" , "p" , "--value" , "test" )
5782 assert .Error (t , err )
5883 assert .Contains (t , stdErr , "The variable already exists" )
5984
60- _ , _ , err = f .RunCombinedOutput ("var:update" , "-p" , projectID , "env:TEST" , "-l" , "p" , "--value" , "project-level-value2" )
85+ _ , _ , err = f .RunCombinedOutput ("var:update" , "-p" , p , "env:TEST" , "-l" , "p" , "--value" , "project-level-value2" )
86+ assert .NoError (t , err )
87+ assertTrimmed (t , "project-level-value2" , f .Run ("var:get" , "-p" , p , "env:TEST" , "-l" , "p" , "-P" , "value" ))
88+
89+ assertTrimmed (t , "true" , f .Run ("var:get" , "-p" , p , "env:TEST" , "-l" , "p" , "-P" , "visible_runtime" ))
90+ _ , _ , err = f .RunCombinedOutput ("var:update" , "-p" , p , "env:TEST" , "-l" , "p" , "--visible-runtime" , "false" )
91+ assert .NoError (t , err )
92+ assertTrimmed (t , "false" , f .Run ("var:get" , "-p" , p , "env:TEST" , "-l" , "p" , "-P" , "visible_runtime" ))
93+ }
94+
95+ func TestVariableCreateWithAppScope (t * testing.T ) {
96+ s := setupVariableTest (t )
97+
98+ // Set up deployment with app names for validation.
99+ s .mainEnv .SetCurrentDeployment (& mockapi.Deployment {
100+ WebApps : map [string ]mockapi.App {
101+ "app1" : {Name : "app1" , Type : "golang:1.23" },
102+ "app2" : {Name : "app2" , Type : "php:8.3" },
103+ },
104+ Routes : make (map [string ]any ),
105+ Links : mockapi .MakeHALLinks ("self=/projects/" + s .projectID + "/environments/main/deployment/current" ),
106+ })
107+ s .apiHandler .SetEnvironments ([]* mockapi.Environment {s .mainEnv })
108+
109+ f , p := s .factory , s .projectID
110+
111+ // Test creating project-level variable with single app-scope.
112+ _ , stdErr , err := f .RunCombinedOutput ("var:create" , "-p" , p , "-l" , "p" ,
113+ "env:SCOPED" , "--value" , "val" , "--app-scope" , "app1" )
114+ assert .NoError (t , err )
115+ assert .Contains (t , stdErr , "Creating variable env:SCOPED" )
116+
117+ // Verify application_scope was set.
118+ out := f .Run ("var:get" , "-p" , p , "-l" , "p" , "env:SCOPED" , "-P" , "application_scope" )
119+ assert .Contains (t , out , "app1" )
120+
121+ // Test creating variable with multiple app scopes.
122+ _ , _ , err = f .RunCombinedOutput ("var:create" , "-p" , p , "-l" , "p" ,
123+ "env:MULTI" , "--value" , "val" , "--app-scope" , "app1" , "--app-scope" , "app2" )
61124 assert .NoError (t , err )
62- assertTrimmed (t , "project-level-value2" , f .Run ("var:get" , "-p" , projectID , "env:TEST" , "-l" , "p" , "-P" , "value" ))
63125
64- assertTrimmed (t , "true" , f .Run ("var:get" , "-p" , projectID , "env:TEST" , "-l" , "p" , "-P" , "visible_runtime" ))
65- _ , _ , err = f .RunCombinedOutput ("var:update" , "-p" , projectID , "env:TEST" , "-l" , "p" , "--visible-runtime" , "false" )
126+ out = f .Run ("var:get" , "-p" , p , "-l" , "p" , "env:MULTI" , "-P" , "application_scope" )
127+ assert .Contains (t , out , "app1" )
128+ assert .Contains (t , out , "app2" )
129+
130+ // Test validation rejects invalid app names (when deployment exists).
131+ _ , stdErr , err = f .RunCombinedOutput ("var:create" , "-p" , p , "-l" , "p" ,
132+ "env:BAD" , "--value" , "val" , "--app-scope" , "nonexistent" )
133+ assert .Error (t , err )
134+ assert .Contains (t , stdErr , "was not found" )
135+
136+ // Test updating app-scope.
137+ _ , _ , err = f .RunCombinedOutput ("var:update" , "-p" , p , "-l" , "p" ,
138+ "env:SCOPED" , "--app-scope" , "app2" )
66139 assert .NoError (t , err )
67- assertTrimmed (t , "false" , f .Run ("var:get" , "-p" , projectID , "env:TEST" , "-l" , "p" , "-P" , "visible_runtime" ))
140+
141+ out = f .Run ("var:get" , "-p" , p , "-l" , "p" , "env:SCOPED" , "-P" , "application_scope" )
142+ assert .Contains (t , out , "app2" )
143+ }
144+
145+ func TestVariableCreateWithAppScopeNoDeployment (t * testing.T ) {
146+ // Uses an environment without a deployment, so app-scope validation is skipped.
147+ s := setupVariableTest (t )
148+ s .apiHandler .SetEnvironments ([]* mockapi.Environment {s .mainEnv })
149+
150+ f , p := s .factory , s .projectID
151+
152+ // Without a deployment, any app-scope value should be accepted.
153+ _ , stdErr , err := f .RunCombinedOutput ("var:create" , "-p" , p , "-l" , "p" ,
154+ "env:ANY_APP" , "--value" , "val" , "--app-scope" , "anyapp" )
155+ assert .NoError (t , err )
156+ assert .Contains (t , stdErr , "Creating variable env:ANY_APP" )
157+
158+ out := f .Run ("var:get" , "-p" , p , "-l" , "p" , "env:ANY_APP" , "-P" , "application_scope" )
159+ assert .Contains (t , out , "anyapp" )
68160}
0 commit comments