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