github.com/spinnaker/spin@v1.30.0/cmd/application/get_test.go (about) 1 // Copyright (c) 2018, Google, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package application 16 17 import ( 18 "bytes" 19 "fmt" 20 "io/ioutil" 21 "net/http" 22 "net/http/httptest" 23 "strings" 24 "testing" 25 26 "github.com/andreyvit/diff" 27 28 "github.com/spinnaker/spin/cmd" 29 "github.com/spinnaker/spin/util" 30 ) 31 32 const ( 33 APP = "app" 34 ) 35 36 func TestApplicationGet_json(t *testing.T) { 37 ts := testGateApplicationGetSuccess() 38 defer ts.Close() 39 40 buffer := new(bytes.Buffer) 41 rootCmd, rootOpts := cmd.NewCmdRoot(buffer, buffer) 42 rootCmd.AddCommand(NewApplicationCmd(rootOpts)) 43 44 args := []string{"application", "get", APP, "--gate-endpoint=" + ts.URL} 45 rootCmd.SetArgs(args) 46 err := rootCmd.Execute() 47 if err != nil { 48 t.Fatalf("Command failed with: %s", err) 49 } 50 51 expected := strings.TrimSpace(applicationJson) 52 recieved := strings.TrimSpace(buffer.String()) 53 if expected != recieved { 54 t.Fatalf("Unexpected command output:\n%s", diff.LineDiff(expected, recieved)) 55 } 56 } 57 58 func TestApplicationGet_jsonpath(t *testing.T) { 59 ts := testGateApplicationGetSuccess() 60 defer ts.Close() 61 62 buffer := new(bytes.Buffer) 63 rootCmd, rootOpts := cmd.NewCmdRoot(buffer, buffer) 64 rootCmd.AddCommand(NewApplicationCmd(rootOpts)) 65 66 args := []string{"application", "get", APP, "--output", "jsonpath={.permissions}", "--gate-endpoint=" + ts.URL} 67 rootCmd.SetArgs(args) 68 err := rootCmd.Execute() 69 if err != nil { 70 t.Fatalf("Command failed with: %s", err) 71 } 72 73 expected := strings.TrimSpace(permissionsJson) 74 recieved := strings.TrimSpace(buffer.String()) 75 if expected != recieved { 76 t.Fatalf("Unexpected command output:\n%s", diff.LineDiff(expected, recieved)) 77 } 78 } 79 80 func TestApplicationGet_yaml(t *testing.T) { 81 ts := testGateApplicationGetSuccess() 82 defer ts.Close() 83 84 buffer := new(bytes.Buffer) 85 rootCmd, rootOpts := cmd.NewCmdRoot(buffer, buffer) 86 rootCmd.AddCommand(NewApplicationCmd(rootOpts)) 87 88 args := []string{"application", "get", APP, "--output", "yaml", "--gate-endpoint=" + ts.URL} 89 rootCmd.SetArgs(args) 90 err := rootCmd.Execute() 91 if err != nil { 92 t.Fatalf("Command failed with: %s", err) 93 } 94 95 expected := strings.TrimSpace(applicationYaml) 96 recieved := strings.TrimSpace(buffer.String()) 97 if expected != recieved { 98 t.Fatalf("Unexpected command output:\n%s", diff.LineDiff(expected, recieved)) 99 } 100 } 101 102 func TestApplicationGet_flags(t *testing.T) { 103 ts := testGateApplicationGetSuccess() 104 defer ts.Close() 105 106 rootCmd, rootOpts := cmd.NewCmdRoot(ioutil.Discard, ioutil.Discard) 107 rootCmd.AddCommand(NewApplicationCmd(rootOpts)) 108 109 args := []string{"application", "get", "--gate-endpoint", ts.URL} // Missing positional arg. 110 rootCmd.SetArgs(args) 111 err := rootCmd.Execute() 112 if err == nil { // Success is actually failure here, flags are malformed. 113 t.Fatalf("Command failed with: %s", err) 114 } 115 } 116 117 func TestApplicationGet_fail(t *testing.T) { 118 ts := testGateFail() 119 defer ts.Close() 120 121 rootCmd, rootOpts := cmd.NewCmdRoot(ioutil.Discard, ioutil.Discard) 122 rootCmd.AddCommand(NewApplicationCmd(rootOpts)) 123 124 args := []string{"application", "get", APP, "--gate-endpoint=" + ts.URL} 125 rootCmd.SetArgs(args) 126 err := rootCmd.Execute() 127 if err == nil { // Success is actually failure here, return payload is malformed. 128 t.Fatalf("Command failed with: %d", err) 129 } 130 } 131 132 // testGateApplicationGetSuccess spins up a local http server that we will configure the GateClient 133 // to direct requests to. Responds with a 200 and a well-formed pipeline list. 134 func testGateApplicationGetSuccess() *httptest.Server { 135 mux := util.TestGateMuxWithVersionHandler() 136 mux.Handle("/applications/"+APP, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 137 w.Header().Add("content-type", "application/json") 138 fmt.Fprintln(w, strings.TrimSpace(applicationJsonExpanded)) 139 })) 140 return httptest.NewServer(mux) 141 } 142 143 // GET /applications/{app} returns an envelope with 'attributes' and 'clusters'. 144 const applicationJsonExpanded = ` 145 { 146 "attributes": { 147 "accounts": "account1", 148 "cloudproviders": [ 149 "gce", 150 "kubernetes" 151 ], 152 "createTs": "1527261941734", 153 "email": "app", 154 "instancePort": 80, 155 "lastModifiedBy": "anonymous", 156 "name": "app", 157 "permissions": { 158 "EXECUTE": [ 159 "admin-group" 160 ], 161 "READ": [ 162 "admin-group", 163 "user-group" 164 ], 165 "WRITE": [ 166 "admin-group" 167 ] 168 }, 169 "updateTs": "1527261941735", 170 "user": "anonymous" 171 }, 172 "clusters": { 173 "account1": [ 174 { 175 "loadBalancers": [], 176 "name": "deployment example-deployment", 177 "provider": "kubernetes", 178 "serverGroups": [] 179 } 180 ] 181 } 182 } 183 ` 184 185 const applicationJson = ` 186 { 187 "accounts": "account1", 188 "cloudproviders": [ 189 "gce", 190 "kubernetes" 191 ], 192 "createTs": "1527261941734", 193 "email": "app", 194 "instancePort": 80, 195 "lastModifiedBy": "anonymous", 196 "name": "app", 197 "permissions": { 198 "EXECUTE": [ 199 "admin-group" 200 ], 201 "READ": [ 202 "admin-group", 203 "user-group" 204 ], 205 "WRITE": [ 206 "admin-group" 207 ] 208 }, 209 "updateTs": "1527261941735", 210 "user": "anonymous" 211 } 212 ` 213 214 const applicationYaml = ` 215 accounts: account1 216 cloudproviders: 217 - gce 218 - kubernetes 219 createTs: "1527261941734" 220 email: app 221 instancePort: 80 222 lastModifiedBy: anonymous 223 name: app 224 permissions: 225 EXECUTE: 226 - admin-group 227 READ: 228 - admin-group 229 - user-group 230 WRITE: 231 - admin-group 232 updateTs: "1527261941735" 233 user: anonymous 234 ` 235 236 const permissionsJson = ` 237 { 238 "EXECUTE": [ 239 "admin-group" 240 ], 241 "READ": [ 242 "admin-group", 243 "user-group" 244 ], 245 "WRITE": [ 246 "admin-group" 247 ] 248 } 249 `