blob: 4b0fdc586b768285eb9f1156adfe82b0590b815f [file] [log] [blame]
Ash Wilson64d67b22014-09-05 13:04:12 -04001package gophercloud
2
3import (
4 "errors"
5 "fmt"
6 "net/http"
7 "reflect"
8 "testing"
9
10 "github.com/rackspace/gophercloud/testhelper"
11)
12
13// SinglePage sample and test cases.
14
15type SinglePageCollection struct {
16 results []int
17}
18
19func (c SinglePageCollection) Pager() Pager {
20 return SinglePager{}
21}
22
Ash Wilsonb110fc92014-09-08 13:54:59 -040023func (c SinglePageCollection) Concat(other Collection) Collection {
24 panic("Concat should never be called on a single-paged collection.")
25}
26
Ash Wilson64d67b22014-09-05 13:04:12 -040027func AsSingleInts(c Collection) []int {
28 return c.(SinglePageCollection).results
29}
30
31var single = SinglePageCollection{
32 results: []int{1, 2, 3},
33}
34
35func TestEnumerateSinglePaged(t *testing.T) {
36 callCount := 0
37 EachPage(single, func(page Collection) bool {
38 callCount++
39
40 expected := []int{1, 2, 3}
41 actual := AsSingleInts(page)
42 if !reflect.DeepEqual(expected, actual) {
43 t.Errorf("Expected %v, but was %v", expected, actual)
44 }
45 return true
46 })
47
48 if callCount != 1 {
49 t.Errorf("Callback was invoked %d times", callCount)
50 }
51}
52
53func TestAllSinglePaged(t *testing.T) {
54 r, err := AllPages(single)
55 if err != nil {
56 t.Fatalf("Unexpected error when iterating pages: %v", err)
57 }
58
59 expected := []int{1, 2, 3}
60 actual := AsSingleInts(r)
61 if !reflect.DeepEqual(expected, actual) {
62 t.Errorf("Expected %v, but was %v", expected, actual)
63 }
64}
65
66// LinkedPager sample and test cases.
67
68type LinkedCollection struct {
69 PaginationLinks
70
71 service *ServiceClient
72 results []int
73}
74
Ash Wilsonb110fc92014-09-08 13:54:59 -040075func (c LinkedCollection) Pager() Pager {
76 return NewLinkPager(c)
77}
78
79func (c LinkedCollection) Concat(other Collection) Collection {
80 return LinkedCollection{
81 service: c.service,
82 results: append(c.results, AsLinkedInts(other)...),
83 }
84}
85
Ash Wilson64d67b22014-09-05 13:04:12 -040086func (c LinkedCollection) Links() PaginationLinks {
87 return c.PaginationLinks
88}
89
90func (c LinkedCollection) Service() *ServiceClient {
91 return c.service
92}
93
94func (c LinkedCollection) Interpret(response interface{}) (LinkCollection, error) {
Ash Wilson64d67b22014-09-05 13:04:12 -040095 casted, ok := response.([]interface{})
96 if ok {
97 asInts := make([]int, len(casted))
98 for index, item := range casted {
99 f := item.(float64)
100 asInts[index] = int(f)
101 }
102
103 var nextURL *string
104 switch asInts[0] {
105 case 4:
106 u := testhelper.Server.URL + "/foo?page=3&perPage=3"
107 nextURL = &u
108 case 7:
109 // Leave nextURL as nil.
110 default:
111 return nil, fmt.Errorf("Unexpected resultset: %#v", asInts)
112 }
113
114 result := LinkedCollection{
115 PaginationLinks: PaginationLinks{Next: nextURL},
116 service: c.service,
117 results: asInts,
118 }
Ash Wilson64d67b22014-09-05 13:04:12 -0400119 return result, nil
120 }
121 return nil, errors.New("Wat")
122}
123
Ash Wilson64d67b22014-09-05 13:04:12 -0400124func AsLinkedInts(results Collection) []int {
125 return results.(LinkedCollection).results
126}
127
128func createLinked() LinkedCollection {
129 nextURL := testhelper.Server.URL + "/foo?page=2&perPage=3"
130 return LinkedCollection{
131 PaginationLinks: PaginationLinks{Next: &nextURL},
132 service: &ServiceClient{
133 Provider: &ProviderClient{TokenID: "1234"},
134 Endpoint: testhelper.Endpoint(),
135 },
136 results: []int{1, 2, 3},
137 }
138}
139
140func setupLinkedResponses(t *testing.T) {
141 testhelper.Mux.HandleFunc("/foo", func(w http.ResponseWriter, r *http.Request) {
142 testhelper.TestMethod(t, r, "GET")
143 testhelper.TestHeader(t, r, "X-Auth-Token", "1234")
144 w.Header().Add("Content-Type", "application/json")
145
146 r.ParseForm()
147
148 pages := r.Form["page"]
149 if len(pages) != 1 {
150 t.Errorf("Endpoint called with unexpected page: %#v", r.Form)
151 }
152
153 switch pages[0] {
154 case "2":
155 fmt.Fprintf(w, `[4, 5, 6]`)
156 case "3":
157 fmt.Fprintf(w, `[7, 8, 9]`)
158 default:
159 t.Errorf("Endpoint called with unexpected page: %s", pages[0])
160 }
161 })
162}
163
164func TestEnumerateLinked(t *testing.T) {
165 testhelper.SetupHTTP()
166 defer testhelper.TeardownHTTP()
167
168 setupLinkedResponses(t)
169 lc := createLinked()
170
171 callCount := 0
172 err := EachPage(lc, func(page Collection) bool {
173 actual := AsLinkedInts(page)
174 t.Logf("Handler invoked with %v", actual)
175
176 var expected []int
177 switch callCount {
178 case 0:
179 expected = []int{1, 2, 3}
180 case 1:
181 expected = []int{4, 5, 6}
182 case 2:
183 expected = []int{7, 8, 9}
184 default:
185 t.Fatalf("Unexpected call count: %d", callCount)
186 return false
187 }
188
189 if !reflect.DeepEqual(expected, actual) {
190 t.Errorf("Call %d: Expected %#v, but was %#v", callCount, expected, actual)
191 }
192
193 callCount++
194 return true
195 })
196 if err != nil {
197 t.Errorf("Unexpected error for page iteration: %v", err)
198 }
199
200 if callCount != 3 {
201 t.Errorf("Expected 3 calls, but was %d", callCount)
202 }
203}
Ash Wilsonb110fc92014-09-08 13:54:59 -0400204
205func TestAllLinked(t *testing.T) {
206 testhelper.SetupHTTP()
207 defer testhelper.TeardownHTTP()
208
209 setupLinkedResponses(t)
210 lc := createLinked()
211
212 all, err := AllPages(lc)
213 if err != nil {
214 t.Fatalf("Unexpected error collection all linked pages: %v", err)
215 }
216
217 actual := AsLinkedInts(all)
218 expected := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
219
220 if !reflect.DeepEqual(expected, actual) {
221 t.Errorf("Expected %v, but was %v", expected, actual)
222 }
223
224 original := []int{1, 2, 3}
225 if !reflect.DeepEqual(AsLinkedInts(lc), original) {
226 t.Errorf("AllPages modified the original page, and now it contains: %v", lc)
227 }
228}