1package testing 2 3import ( 4 "fmt" 5 "net/http" 6 "testing" 7 8 "github.com/gophercloud/gophercloud/openstack/identity/v3/projects" 9 th "github.com/gophercloud/gophercloud/testhelper" 10 "github.com/gophercloud/gophercloud/testhelper/client" 11) 12 13// ListAvailableOutput provides a single page of available Project results. 14const ListAvailableOutput = ` 15{ 16 "projects": [ 17 { 18 "description": "my first project", 19 "domain_id": "11111", 20 "enabled": true, 21 "id": "abcde", 22 "links": { 23 "self": "http://localhost:5000/identity/v3/projects/abcde" 24 }, 25 "name": "project 1", 26 "parent_id": "11111" 27 }, 28 { 29 "description": "my second project", 30 "domain_id": "22222", 31 "enabled": true, 32 "id": "bcdef", 33 "links": { 34 "self": "http://localhost:5000/identity/v3/projects/bcdef" 35 }, 36 "name": "project 2", 37 "parent_id": "22222" 38 } 39 ], 40 "links": { 41 "next": null, 42 "previous": null, 43 "self": "http://localhost:5000/identity/v3/users/foobar/projects" 44 } 45} 46` 47 48// ListOutput provides a single page of Project results. 49const ListOutput = ` 50{ 51 "projects": [ 52 { 53 "is_domain": false, 54 "description": "The team that is red", 55 "domain_id": "default", 56 "enabled": true, 57 "id": "1234", 58 "name": "Red Team", 59 "parent_id": null, 60 "tags": ["Red", "Team"], 61 "test": "old" 62 }, 63 { 64 "is_domain": false, 65 "description": "The team that is blue", 66 "domain_id": "default", 67 "enabled": true, 68 "id": "9876", 69 "name": "Blue Team", 70 "parent_id": null, 71 "options": { 72 "immutable": true 73 } 74 } 75 ], 76 "links": { 77 "next": null, 78 "previous": null 79 } 80} 81` 82 83// GetOutput provides a Get result. 84const GetOutput = ` 85{ 86 "project": { 87 "is_domain": false, 88 "description": "The team that is red", 89 "domain_id": "default", 90 "enabled": true, 91 "id": "1234", 92 "name": "Red Team", 93 "parent_id": null, 94 "tags": ["Red", "Team"], 95 "test": "old" 96 } 97} 98` 99 100// CreateRequest provides the input to a Create request. 101const CreateRequest = ` 102{ 103 "project": { 104 "description": "The team that is red", 105 "name": "Red Team", 106 "tags": ["Red", "Team"], 107 "test": "old" 108 } 109} 110` 111 112// UpdateRequest provides the input to an Update request. 113const UpdateRequest = ` 114{ 115 "project": { 116 "description": "The team that is bright red", 117 "name": "Bright Red Team", 118 "tags": ["Red"], 119 "test": "new" 120 } 121} 122` 123 124// UpdateOutput provides an Update response. 125const UpdateOutput = ` 126{ 127 "project": { 128 "is_domain": false, 129 "description": "The team that is bright red", 130 "domain_id": "default", 131 "enabled": true, 132 "id": "1234", 133 "name": "Bright Red Team", 134 "parent_id": null, 135 "tags": ["Red"], 136 "test": "new" 137 } 138} 139` 140 141// FirstProject is a Project fixture. 142var FirstProject = projects.Project{ 143 Description: "my first project", 144 DomainID: "11111", 145 Enabled: true, 146 ID: "abcde", 147 Name: "project 1", 148 ParentID: "11111", 149 Extra: map[string]interface{}{ 150 "links": map[string]interface{}{"self": "http://localhost:5000/identity/v3/projects/abcde"}, 151 }, 152} 153 154// SecondProject is a Project fixture. 155var SecondProject = projects.Project{ 156 Description: "my second project", 157 DomainID: "22222", 158 Enabled: true, 159 ID: "bcdef", 160 Name: "project 2", 161 ParentID: "22222", 162 Extra: map[string]interface{}{ 163 "links": map[string]interface{}{"self": "http://localhost:5000/identity/v3/projects/bcdef"}, 164 }, 165} 166 167// RedTeam is a Project fixture. 168var RedTeam = projects.Project{ 169 IsDomain: false, 170 Description: "The team that is red", 171 DomainID: "default", 172 Enabled: true, 173 ID: "1234", 174 Name: "Red Team", 175 ParentID: "", 176 Tags: []string{"Red", "Team"}, 177 Extra: map[string]interface{}{"test": "old"}, 178} 179 180// BlueTeam is a Project fixture. 181var BlueTeam = projects.Project{ 182 IsDomain: false, 183 Description: "The team that is blue", 184 DomainID: "default", 185 Enabled: true, 186 ID: "9876", 187 Name: "Blue Team", 188 ParentID: "", 189 Extra: make(map[string]interface{}), 190 Options: map[projects.Option]interface{}{ 191 projects.Immutable: true, 192 }, 193} 194 195// UpdatedRedTeam is a Project Fixture. 196var UpdatedRedTeam = projects.Project{ 197 IsDomain: false, 198 Description: "The team that is bright red", 199 DomainID: "default", 200 Enabled: true, 201 ID: "1234", 202 Name: "Bright Red Team", 203 ParentID: "", 204 Tags: []string{"Red"}, 205 Extra: map[string]interface{}{"test": "new"}, 206} 207 208// ExpectedAvailableProjectsSlice is the slice of projects expected to be returned 209// from ListAvailableOutput. 210var ExpectedAvailableProjectsSlice = []projects.Project{FirstProject, SecondProject} 211 212// ExpectedProjectSlice is the slice of projects expected to be returned from ListOutput. 213var ExpectedProjectSlice = []projects.Project{RedTeam, BlueTeam} 214 215// HandleListAvailableProjectsSuccessfully creates an HTTP handler at `/auth/projects` 216// on the test handler mux that responds with a list of two tenants. 217func HandleListAvailableProjectsSuccessfully(t *testing.T) { 218 th.Mux.HandleFunc("/auth/projects", func(w http.ResponseWriter, r *http.Request) { 219 th.TestMethod(t, r, "GET") 220 th.TestHeader(t, r, "Accept", "application/json") 221 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 222 223 w.Header().Set("Content-Type", "application/json") 224 w.WriteHeader(http.StatusOK) 225 fmt.Fprintf(w, ListAvailableOutput) 226 }) 227} 228 229// HandleListProjectsSuccessfully creates an HTTP handler at `/projects` on the 230// test handler mux that responds with a list of two tenants. 231func HandleListProjectsSuccessfully(t *testing.T) { 232 th.Mux.HandleFunc("/projects", func(w http.ResponseWriter, r *http.Request) { 233 th.TestMethod(t, r, "GET") 234 th.TestHeader(t, r, "Accept", "application/json") 235 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 236 237 w.Header().Set("Content-Type", "application/json") 238 w.WriteHeader(http.StatusOK) 239 fmt.Fprintf(w, ListOutput) 240 }) 241} 242 243// HandleGetProjectSuccessfully creates an HTTP handler at `/projects` on the 244// test handler mux that responds with a single project. 245func HandleGetProjectSuccessfully(t *testing.T) { 246 th.Mux.HandleFunc("/projects/1234", func(w http.ResponseWriter, r *http.Request) { 247 th.TestMethod(t, r, "GET") 248 th.TestHeader(t, r, "Accept", "application/json") 249 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 250 251 w.Header().Set("Content-Type", "application/json") 252 w.WriteHeader(http.StatusOK) 253 fmt.Fprintf(w, GetOutput) 254 }) 255} 256 257// HandleCreateProjectSuccessfully creates an HTTP handler at `/projects` on the 258// test handler mux that tests project creation. 259func HandleCreateProjectSuccessfully(t *testing.T) { 260 th.Mux.HandleFunc("/projects", func(w http.ResponseWriter, r *http.Request) { 261 th.TestMethod(t, r, "POST") 262 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 263 th.TestJSONRequest(t, r, CreateRequest) 264 265 w.WriteHeader(http.StatusCreated) 266 fmt.Fprintf(w, GetOutput) 267 }) 268} 269 270// HandleDeleteProjectSuccessfully creates an HTTP handler at `/projects` on the 271// test handler mux that tests project deletion. 272func HandleDeleteProjectSuccessfully(t *testing.T) { 273 th.Mux.HandleFunc("/projects/1234", func(w http.ResponseWriter, r *http.Request) { 274 th.TestMethod(t, r, "DELETE") 275 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 276 277 w.WriteHeader(http.StatusNoContent) 278 }) 279} 280 281// HandleUpdateProjectSuccessfully creates an HTTP handler at `/projects` on the 282// test handler mux that tests project updates. 283func HandleUpdateProjectSuccessfully(t *testing.T) { 284 th.Mux.HandleFunc("/projects/1234", func(w http.ResponseWriter, r *http.Request) { 285 th.TestMethod(t, r, "PATCH") 286 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 287 th.TestJSONRequest(t, r, UpdateRequest) 288 289 w.WriteHeader(http.StatusOK) 290 fmt.Fprintf(w, UpdateOutput) 291 }) 292} 293