auth

Paddy 2014-11-11 Parent:b3cd7765a7c8 Child:0a6e3f14b054

71:c8b0208c9e5d Go to Latest

auth/client_test.go

Remove extraneous TODOs. One TODO shouldn't actually be done. Another is already done. Remove both.

History
1 package auth
3 import (
4 "fmt"
5 "net/url"
6 "testing"
7 "time"
9 "sort"
10 "code.secondbit.org/uuid"
11 )
13 const (
14 clientChangeSecret = 1 << iota
15 clientChangeOwnerID
16 clientChangeName
17 clientChangeLogo
18 clientChangeWebsite
19 )
21 var clientStores = []clientStore{NewMemstore()}
23 func compareClients(client1, client2 Client) (success bool, field string, val1, val2 interface{}) {
24 if !client1.ID.Equal(client2.ID) {
25 return false, "ID", client1.ID, client2.ID
26 }
27 if client1.Secret != client2.Secret {
28 return false, "secret", client1.Secret, client2.Secret
29 }
30 if !client1.OwnerID.Equal(client2.OwnerID) {
31 return false, "owner ID", client1.OwnerID, client2.OwnerID
32 }
33 if client1.Name != client2.Name {
34 return false, "name", client1.Name, client2.Name
35 }
36 if client1.Logo != client2.Logo {
37 return false, "logo", client1.Logo, client2.Logo
38 }
39 if client1.Website != client2.Website {
40 return false, "website", client1.Website, client2.Website
41 }
42 if client1.Type != client2.Type {
43 return false, "type", client1.Type, client2.Type
44 }
45 return true, "", nil, nil
46 }
48 func compareEndpoints(endpoint1, endpoint2 Endpoint) (success bool, field string, val1, val2 interface{}) {
49 if !endpoint1.ID.Equal(endpoint2.ID) {
50 return false, "ID", endpoint1.ID, endpoint2.ID
51 }
52 if !endpoint1.ClientID.Equal(endpoint2.ClientID) {
53 return false, "OwnerID", endpoint1.ClientID, endpoint2.ClientID
54 }
55 if !endpoint1.Added.Equal(endpoint2.Added) {
56 return false, "Added", endpoint1.Added, endpoint2.Added
57 }
58 if endpoint1.URI.String() != endpoint2.URI.String() {
59 return false, "URI", endpoint1.URI, endpoint2.URI
60 }
61 return true, "", nil, nil
62 }
64 func TestClientStoreSuccess(t *testing.T) {
65 t.Parallel()
66 client := Client{
67 ID: uuid.NewID(),
68 Secret: "secret",
69 OwnerID: uuid.NewID(),
70 Name: "name",
71 Logo: "logo",
72 Website: "website",
73 }
74 for _, store := range clientStores {
75 err := store.saveClient(client)
76 if err != nil {
77 t.Fatalf("Error saving client to %T: %s", store, err)
78 }
79 err = store.saveClient(client)
80 if err != ErrClientAlreadyExists {
81 t.Fatalf("Expected ErrClientAlreadyExists, got %v from %T", err, store)
82 }
83 retrieved, err := store.getClient(client.ID)
84 if err != nil {
85 t.Fatalf("Error retrieving client from %T: %s", store, err)
86 }
87 success, field, expectation, result := compareClients(client, retrieved)
88 if !success {
89 t.Fatalf("Expected field %s to be %v, but %T returned %v", field, expectation, store, result)
90 }
91 clients, err := store.listClientsByOwner(client.OwnerID, 25, 0)
92 if err != nil {
93 t.Fatalf("Error retrieving clients by owner from %T: %s", store, err)
94 }
95 if len(clients) != 1 {
96 t.Fatalf("Expected 1 client in response from %T, got %+v", store, clients)
97 }
98 success, field, expectation, result = compareClients(client, clients[0])
99 if !success {
100 t.Fatalf("Expected field %s to be %v, but %T returned %v", field, expectation, store, result)
101 }
102 err = store.deleteClient(client.ID)
103 if err != nil {
104 t.Fatalf("Error deleting client from %T: %s", store, err)
105 }
106 err = store.deleteClient(client.ID)
107 if err != ErrClientNotFound {
108 t.Fatalf("Expected ErrClientNotFound, got %s from %T", err, store)
109 }
110 retrieved, err = store.getClient(client.ID)
111 if err != ErrClientNotFound {
112 t.Fatalf("Expected ErrClientNotFound from %T, got %+v and %s", store, retrieved, err)
113 }
114 clients, err = store.listClientsByOwner(client.OwnerID, 25, 0)
115 if err != nil {
116 t.Fatalf("Error listing clients by owner from %T: %s", store, err)
117 }
118 if len(clients) != 0 {
119 t.Fatalf("Expected 0 clients in response from %T, got %+v", store, clients)
120 }
121 }
122 }
124 func TestEndpointStoreSuccess(t *testing.T) {
125 t.Parallel()
126 client := Client{
127 ID: uuid.NewID(),
128 Secret: "secret",
129 OwnerID: uuid.NewID(),
130 Name: "name",
131 Logo: "logo",
132 Website: "website",
133 }
134 uri1, _ := url.Parse("https://www.example.com/")
135 uri2, _ := url.Parse("https://www.example.com/my/full/path")
136 endpoint1 := Endpoint{
137 ID: uuid.NewID(),
138 ClientID: client.ID,
139 Added: time.Now(),
140 URI: *uri1,
141 }
142 endpoint2 := Endpoint{
143 ID: uuid.NewID(),
144 ClientID: client.ID,
145 Added: time.Now(),
146 URI: *uri2,
147 }
148 for _, store := range clientStores {
149 err := store.saveClient(client)
150 if err != nil {
151 t.Fatalf("Error saving client to %T: %s", store, err)
152 }
153 err = store.addEndpoint(client.ID, endpoint1)
154 if err != nil {
155 t.Fatalf("Error adding endpoint to client in %T: %s", store, err)
156 }
157 endpoints, err := store.listEndpoints(client.ID, 10, 0)
158 if err != nil {
159 t.Fatalf("Error retrieving endpoints from %T: %s", store, err)
160 }
161 if len(endpoints) != 1 {
162 t.Fatalf("Expected %d endpoints, got %+v from %T", 1, endpoints, store)
163 }
164 success, field, expectation, result := compareEndpoints(endpoint1, endpoints[0])
165 if !success {
166 t.Fatalf("Expected field %s to be %v, but %T returned %v", field, expectation, store, result)
167 }
168 err = store.addEndpoint(client.ID, endpoint2)
169 if err != nil {
170 t.Fatalf("Error adding endpoint to client in %T: %s", store, err)
171 }
172 endpoints, err = store.listEndpoints(client.ID, 10, 0)
173 if err != nil {
174 t.Fatalf("Error retrieving endpoints from %T: %s", store, err)
175 }
176 if len(endpoints) != 2 {
177 t.Fatalf("Expected %d endpoints, got %+v from %T", 2, endpoints, store)
178 }
179 sortedEnd := sortedEndpoints(endpoints)
180 sort.Sort(sortedEnd)
181 endpoints = []Endpoint(sortedEnd)
182 success, field, expectation, result = compareEndpoints(endpoint1, endpoints[0])
183 if !success {
184 t.Fatalf("Expected field %s to be %v, but %T returned %v", field, expectation, store, result)
185 }
186 success, field, expectation, result = compareEndpoints(endpoint2, endpoints[1])
187 if !success {
188 t.Fatalf("Expected field %s to be %v, but %T returned %v", field, expectation, store, result)
189 }
190 err = store.removeEndpoint(client.ID, endpoint1.ID)
191 if err != nil {
192 t.Fatalf("Error removing endpoint from client in %T: %s", store, err)
193 }
194 endpoints, err = store.listEndpoints(client.ID, 10, 0)
195 if err != nil {
196 t.Fatalf("Error listing endpoints in %T: %s", store, err)
197 }
198 if len(endpoints) != 1 {
199 t.Fatalf("Expected %d endpoints, got %+v from %T", 1, endpoints, store)
200 }
201 success, field, expectation, result = compareEndpoints(endpoint2, endpoints[0])
202 if !success {
203 t.Fatalf("Expected field %s to be %v, but %T returned %v", field, expectation, store, result)
204 }
205 err = store.removeEndpoint(client.ID, endpoint2.ID)
206 if err != nil {
207 t.Fatalf("Error removing endpoint from client in %T: %s", store, err)
208 }
209 endpoints, err = store.listEndpoints(client.ID, 10, 0)
210 if err != nil {
211 t.Fatalf("Error listing endpoints in %T: %s", store, err)
212 }
213 if len(endpoints) != 0 {
214 t.Fatalf("Expected %d endpoints, got %+v from %T", 0, endpoints, store)
215 }
216 }
217 }
219 func TestClientUpdates(t *testing.T) {
220 t.Parallel()
221 variations := 1 << 5
222 client := Client{
223 ID: uuid.NewID(),
224 Secret: "secret",
225 OwnerID: uuid.NewID(),
226 Name: "name",
227 Logo: "logo",
228 Website: "website",
229 }
230 for i := 0; i < variations; i++ {
231 var secret, name, logo, website string
232 change := ClientChange{}
233 expectation := client
234 result := client
235 if i&clientChangeSecret != 0 {
236 secret = fmt.Sprintf("secret-%d", i)
237 change.Secret = &secret
238 expectation.Secret = secret
239 }
240 if i&clientChangeOwnerID != 0 {
241 change.OwnerID = uuid.NewID()
242 expectation.OwnerID = change.OwnerID
243 }
244 if i&clientChangeName != 0 {
245 name = fmt.Sprintf("name-%d", i)
246 change.Name = &name
247 expectation.Name = name
248 }
249 if i&clientChangeLogo != 0 {
250 logo = fmt.Sprintf("logo-%d", i)
251 change.Logo = &logo
252 expectation.Logo = logo
253 }
254 if i&clientChangeWebsite != 0 {
255 website = fmt.Sprintf("website-%d", i)
256 change.Website = &website
257 expectation.Website = website
258 }
259 result.ApplyChange(change)
260 match, field, expected, got := compareClients(expectation, result)
261 if !match {
262 t.Fatalf("Expected field `%s` to be `%v`, got `%v`", field, expected, got)
263 }
264 for _, store := range clientStores {
265 err := store.saveClient(client)
266 if err != nil {
267 t.Fatalf("Error saving client in %T: %s", store, err)
268 }
269 err = store.updateClient(client.ID, change)
270 if err != nil {
271 t.Fatalf("Error updating client in %T: %s", store, err)
272 }
273 retrieved, err := store.getClient(client.ID)
274 if err != nil {
275 t.Fatalf("Error getting profile from %T: %s", store, err)
276 }
277 match, field, expected, got = compareClients(expectation, retrieved)
278 if !match {
279 t.Fatalf("Expected field `%s` to be `%v`, got `%v` from %T", field, expected, got, store)
280 }
281 err = store.deleteClient(client.ID)
282 if err != nil {
283 t.Fatalf("Error deleting client from %T: %s", store, err)
284 }
285 err = store.updateClient(client.ID, change)
286 if err != ErrClientNotFound {
287 t.Fatalf("Expected ErrClientNotFound, got %v from %T", err, store)
288 }
289 }
290 }
291 }
293 func TestClientEndpointChecks(t *testing.T) {
294 t.Parallel()
295 client := Client{
296 ID: uuid.NewID(),
297 Secret: "secret",
298 OwnerID: uuid.NewID(),
299 Name: "name",
300 Logo: "logo",
301 Website: "website",
302 }
303 uri1, _ := url.Parse("https://www.example.com/first")
304 uri2, _ := url.Parse("https://www.example.com/my/full/path")
305 endpoint1 := Endpoint{
306 ID: uuid.NewID(),
307 ClientID: client.ID,
308 Added: time.Now(),
309 URI: *uri1,
310 }
311 endpoint2 := Endpoint{
312 ID: uuid.NewID(),
313 ClientID: client.ID,
314 Added: time.Now(),
315 URI: *uri2,
316 }
317 candidates := map[string]bool{
318 "https://www.example.com/": false,
319 "https://www.example.com/first": true,
320 "https://www.example.com/first/extra/path": false,
321 "https://www.example.com/my": false,
322 "https://www.example.com/my/full/path": true,
323 }
324 for _, store := range clientStores {
325 err := store.saveClient(client)
326 if err != nil {
327 t.Fatalf("Error saving client in %T: %s", store, err)
328 }
329 err = store.addEndpoint(client.ID, endpoint1)
330 if err != nil {
331 t.Fatalf("Error saving endpoint in %T: %s", store, err)
332 }
333 err = store.addEndpoint(client.ID, endpoint2)
334 if err != nil {
335 t.Fatalf("Error saving endpoint in %T: %s", store, err)
336 }
337 for candidate, expectation := range candidates {
338 result, err := store.checkEndpoint(client.ID, candidate)
339 if err != nil {
340 t.Fatalf("Error checking endpoint %s in %T: %s", candidate, store, err)
341 }
342 if result != expectation {
343 expectStr := "no"
344 resultStr := "a"
345 if expectation {
346 expectStr = "a"
347 resultStr = "no"
348 }
349 t.Errorf("Expected %s match for %s in %T, got %s match", expectStr, candidate, store, resultStr)
350 }
351 }
352 }
353 }
355 func TestClientEndpointChecksStrict(t *testing.T) {
356 t.Parallel()
357 client := Client{
358 ID: uuid.NewID(),
359 Secret: "secret",
360 OwnerID: uuid.NewID(),
361 Name: "name",
362 Logo: "logo",
363 Website: "website",
364 }
365 uri1, _ := url.Parse("https://www.example.com/first")
366 uri2, _ := url.Parse("https://www.example.com/my/full/path")
367 endpoint1 := Endpoint{
368 ID: uuid.NewID(),
369 ClientID: client.ID,
370 Added: time.Now(),
371 URI: *uri1,
372 }
373 endpoint2 := Endpoint{
374 ID: uuid.NewID(),
375 ClientID: client.ID,
376 Added: time.Now(),
377 URI: *uri2,
378 }
379 candidates := map[string]bool{
380 "https://www.example.com/": false,
381 "https://www.example.com/first": true,
382 "https://www.example.com/first/extra/path": false,
383 "https://www.example.com/my": false,
384 "https://www.example.com/my/full/path": true,
385 }
386 for _, store := range clientStores {
387 err := store.saveClient(client)
388 if err != nil {
389 t.Fatalf("Error saving client in %T: %s", store, err)
390 }
391 err = store.addEndpoint(client.ID, endpoint1)
392 if err != nil {
393 t.Fatalf("Error saving endpoint in %T: %s", store, err)
394 }
395 err = store.addEndpoint(client.ID, endpoint2)
396 if err != nil {
397 t.Fatalf("Error saving endpoint in %T: %s", store, err)
398 }
399 for candidate, expectation := range candidates {
400 result, err := store.checkEndpoint(client.ID, candidate)
401 if err != nil {
402 t.Fatalf("Error checking endpoint %s in %T: %s", candidate, store, err)
403 }
404 if result != expectation {
405 expectStr := "no"
406 resultStr := "a"
407 if expectation {
408 expectStr = "a"
409 resultStr = "no"
410 }
411 t.Errorf("Expected %s match for %s in %T, got %s match", expectStr, candidate, store, resultStr)
412 }
413 }
414 }
415 }
417 func TestClientChangeValidation(t *testing.T) {
418 t.Parallel()
419 change := ClientChange{}
420 if err := change.Validate(); err != ErrEmptyChange {
421 t.Errorf("Expected %s to give an error of %s, gave %s", "empty change", ErrEmptyChange, err)
422 }
423 names := map[string]error{
424 "a": ErrClientNameTooShort,
425 "ab": nil,
426 "abc": nil,
427 "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopq": ErrClientNameTooLong,
428 }
429 for name, expectation := range names {
430 change = ClientChange{Name: &name}
431 if err := change.Validate(); err != expectation {
432 t.Errorf("Expected %s to give an error of %s, gave %s", name, expectation, err)
433 }
434 }
435 longPath := ""
436 for i := 0; i < 1025; i++ {
437 longPath = fmt.Sprintf("%s%d", longPath, i)
438 }
439 logos := map[string]error{
440 "https://www.example.com/" + longPath: ErrClientLogoTooLong,
441 "https://www.example.com/ab": nil,
442 "www.example.com/ab": ErrClientLogoNotURL,
443 "test": ErrClientLogoNotURL,
444 "": nil,
445 }
446 for logo, expectation := range logos {
447 change = ClientChange{Logo: &logo}
448 if err := change.Validate(); err != expectation {
449 t.Errorf("Expected %s to give an error of %s, gave %s", logo, expectation, err)
450 }
451 }
452 websites := map[string]error{
453 "https://www.example.com/" + longPath: ErrClientWebsiteTooLong,
454 "https://www.example.com/ab": nil,
455 "www.example.com/ab": ErrClientWebsiteNotURL,
456 "test": ErrClientWebsiteNotURL,
457 "": nil,
458 }
459 for website, expectation := range websites {
460 change = ClientChange{Website: &website}
461 if err := change.Validate(); err != expectation {
462 t.Errorf("Expected %s to give an error of %s, gave %s", website, expectation, err)
463 }
464 }
465 }