1package testing
2
3import (
4	"fmt"
5	"net/http"
6	"testing"
7
8	"github.com/gophercloud/gophercloud/pagination"
9	th "github.com/gophercloud/gophercloud/testhelper"
10	"github.com/gophercloud/utils/gnocchi/metric/v1/resourcetypes"
11	fake "github.com/gophercloud/utils/gnocchi/testhelper/client"
12)
13
14func TestList(t *testing.T) {
15	th.SetupHTTP()
16	defer th.TeardownHTTP()
17
18	th.Mux.HandleFunc("/v1/resource_type", func(w http.ResponseWriter, r *http.Request) {
19		th.TestMethod(t, r, "GET")
20		th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
21
22		w.Header().Add("Content-Type", "application/json")
23		w.WriteHeader(http.StatusOK)
24
25		fmt.Fprintf(w, ResourceTypeListResult)
26	})
27
28	count := 0
29
30	resourcetypes.List(fake.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) {
31		count++
32		actual, err := resourcetypes.ExtractResourceTypes(page)
33		if err != nil {
34			t.Errorf("Failed to extract resource types: %v", err)
35			return false, nil
36		}
37
38		expected := []resourcetypes.ResourceType{
39			ResourceType1,
40			ResourceType2,
41			ResourceType3,
42		}
43
44		th.CheckDeepEquals(t, expected, actual)
45
46		return true, nil
47	})
48
49	if count != 1 {
50		t.Errorf("Expected 1 page, got %d", count)
51	}
52}
53
54func TestGet(t *testing.T) {
55	th.SetupHTTP()
56	defer th.TeardownHTTP()
57
58	th.Mux.HandleFunc("/v1/resource_type/compute_instance", func(w http.ResponseWriter, r *http.Request) {
59		th.TestMethod(t, r, "GET")
60		th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
61
62		w.Header().Add("Content-Type", "application/json")
63		w.WriteHeader(http.StatusOK)
64
65		fmt.Fprintf(w, ResourceTypeGetResult)
66	})
67
68	s, err := resourcetypes.Get(fake.ServiceClient(), "compute_instance").Extract()
69	th.AssertNoErr(t, err)
70
71	th.AssertEquals(t, s.Name, "compute_instance")
72	th.AssertEquals(t, s.State, "active")
73	th.AssertDeepEquals(t, s.Attributes, map[string]resourcetypes.Attribute{
74		"host": resourcetypes.Attribute{
75			Type: "string",
76			Details: map[string]interface{}{
77				"max_length": float64(255),
78				"min_length": float64(0),
79				"required":   true,
80			},
81		},
82		"image_ref": resourcetypes.Attribute{
83			Type: "uuid",
84			Details: map[string]interface{}{
85				"required": false,
86			},
87		},
88	})
89}
90
91func TestCreateWithoutAttributes(t *testing.T) {
92	th.SetupHTTP()
93	defer th.TeardownHTTP()
94
95	th.Mux.HandleFunc("/v1/resource_type", func(w http.ResponseWriter, r *http.Request) {
96		th.TestMethod(t, r, "POST")
97		th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
98		th.TestHeader(t, r, "Content-Type", "application/json")
99		th.TestHeader(t, r, "Accept", "application/json")
100		th.TestJSONRequest(t, r, ResourceTypeCreateWithoutAttributesRequest)
101
102		w.Header().Add("Content-Type", "application/json")
103		w.WriteHeader(http.StatusCreated)
104
105		fmt.Fprintf(w, ResourceTypeCreateWithoutAttributesResult)
106	})
107
108	opts := resourcetypes.CreateOpts{
109		Name: "identity_project",
110	}
111	s, err := resourcetypes.Create(fake.ServiceClient(), opts).Extract()
112	th.AssertNoErr(t, err)
113
114	th.AssertEquals(t, s.Name, "identity_project")
115	th.AssertEquals(t, s.State, "active")
116	th.AssertDeepEquals(t, s.Attributes, map[string]resourcetypes.Attribute{})
117}
118
119func TestCreateWithAttributes(t *testing.T) {
120	th.SetupHTTP()
121	defer th.TeardownHTTP()
122
123	th.Mux.HandleFunc("/v1/resource_type", func(w http.ResponseWriter, r *http.Request) {
124		th.TestMethod(t, r, "POST")
125		th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
126		th.TestHeader(t, r, "Content-Type", "application/json")
127		th.TestHeader(t, r, "Accept", "application/json")
128		th.TestJSONRequest(t, r, ResourceTypeCreateWithAttributesRequest)
129
130		w.Header().Add("Content-Type", "application/json")
131		w.WriteHeader(http.StatusCreated)
132
133		fmt.Fprintf(w, ResourceTypeCreateWithAttributesResult)
134	})
135
136	opts := resourcetypes.CreateOpts{
137		Name: "compute_instance_network",
138		Attributes: map[string]resourcetypes.AttributeOpts{
139			"port_name": resourcetypes.AttributeOpts{
140				Type: "string",
141				Details: map[string]interface{}{
142					"max_length": 128,
143					"required":   false,
144				},
145			},
146			"port_id": resourcetypes.AttributeOpts{
147				Type: "uuid",
148				Details: map[string]interface{}{
149					"required": true,
150				},
151			},
152		},
153	}
154	s, err := resourcetypes.Create(fake.ServiceClient(), opts).Extract()
155	th.AssertNoErr(t, err)
156
157	th.AssertEquals(t, s.Name, "compute_instance_network")
158	th.AssertEquals(t, s.State, "active")
159	th.AssertDeepEquals(t, s.Attributes, map[string]resourcetypes.Attribute{
160		"port_name": resourcetypes.Attribute{
161			Type: "string",
162			Details: map[string]interface{}{
163				"max_length": float64(128),
164				"min_length": float64(0),
165				"required":   false,
166			},
167		},
168		"port_id": resourcetypes.Attribute{
169			Type: "uuid",
170			Details: map[string]interface{}{
171				"required": true,
172			},
173		},
174	})
175}
176
177func TestUpdate(t *testing.T) {
178	th.SetupHTTP()
179	defer th.TeardownHTTP()
180
181	th.Mux.HandleFunc("/v1/resource_type/identity_project", func(w http.ResponseWriter, r *http.Request) {
182		th.TestMethod(t, r, "PATCH")
183		th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
184		th.TestHeader(t, r, "Content-Type", "application/json-patch+json")
185		th.TestHeader(t, r, "Accept", "application/json")
186		th.TestJSONRequest(t, r, ResourceTypeUpdateRequest)
187
188		w.Header().Add("Content-Type", "application/json-patch+json")
189		w.WriteHeader(http.StatusOK)
190
191		fmt.Fprintf(w, ResourceTypeUpdateResult)
192	})
193
194	enabledAttributeOptions := resourcetypes.AttributeOpts{
195		Details: map[string]interface{}{
196			"required": true,
197			"options": map[string]interface{}{
198				"fill": true,
199			},
200		},
201		Type: "bool",
202	}
203	parendIDAttributeOptions := resourcetypes.AttributeOpts{
204		Details: map[string]interface{}{
205			"required": false,
206		},
207		Type: "uuid",
208	}
209	opts := resourcetypes.UpdateOpts{
210		Attributes: []resourcetypes.AttributeUpdateOpts{
211			{
212				Name:      "enabled",
213				Operation: resourcetypes.AttributeAdd,
214				Value:     &enabledAttributeOptions,
215			},
216			{
217				Name:      "parent_id",
218				Operation: resourcetypes.AttributeAdd,
219				Value:     &parendIDAttributeOptions,
220			},
221			{
222				Name:      "domain_id",
223				Operation: resourcetypes.AttributeRemove,
224			},
225		},
226	}
227
228	s, err := resourcetypes.Update(fake.ServiceClient(), "identity_project", opts).Extract()
229	th.AssertNoErr(t, err)
230
231	th.AssertEquals(t, s.Name, "identity_project")
232	th.AssertEquals(t, s.State, "active")
233	th.AssertDeepEquals(t, s.Attributes, map[string]resourcetypes.Attribute{
234		"enabled": resourcetypes.Attribute{
235			Type: "bool",
236			Details: map[string]interface{}{
237				"required": true,
238			},
239		},
240		"parent_id": resourcetypes.Attribute{
241			Type: "uuid",
242			Details: map[string]interface{}{
243				"required": false,
244			},
245		},
246		"name": resourcetypes.Attribute{
247			Type: "string",
248			Details: map[string]interface{}{
249				"required":   true,
250				"min_length": float64(0),
251				"max_length": float64(128),
252			},
253		},
254	})
255}
256
257func TestDelete(t *testing.T) {
258	th.SetupHTTP()
259	defer th.TeardownHTTP()
260
261	th.Mux.HandleFunc("/v1/resource_type/compute_instance_network", func(w http.ResponseWriter, r *http.Request) {
262		th.TestMethod(t, r, "DELETE")
263		th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
264		w.WriteHeader(http.StatusNoContent)
265	})
266
267	res := resourcetypes.Delete(fake.ServiceClient(), "compute_instance_network")
268	th.AssertNoErr(t, res.Err)
269}
270