github.com/m-lab/locate@v0.17.6/api/locate/client_test.go (about) 1 // Package locate implements a client for the Locate API v2. 2 package locate 3 4 import ( 5 "context" 6 "encoding/json" 7 "net/http" 8 "net/http/httptest" 9 "net/url" 10 "reflect" 11 "testing" 12 13 v2 "github.com/m-lab/locate/api/v2" 14 ) 15 16 func TestClient_Nearest(t *testing.T) { 17 tests := []struct { 18 name string 19 UserAgent string 20 service string 21 BaseURL *url.URL 22 reply *v2.NearestResult 23 status int 24 wantErr bool 25 closeServer bool 26 badJSON bool 27 }{ 28 { 29 name: "success", 30 service: "ndt/ndt7", 31 UserAgent: "unit-test", 32 status: http.StatusOK, 33 reply: &v2.NearestResult{ 34 Results: []v2.Target{ 35 { 36 Machine: "mlab1-foo01.mlab-sandbox.measurement-lab.org", 37 URLs: map[string]string{ 38 "ws:///ndt/v7/download": "fake-url"}, 39 }, 40 }, 41 }, 42 }, 43 { 44 name: "error-nil-results", 45 service: "ndt/ndt7", 46 UserAgent: "unit-test", 47 status: http.StatusOK, 48 reply: &v2.NearestResult{}, 49 wantErr: true, 50 }, 51 { 52 name: "error-empty-user-agent", 53 service: "ndt/ndt7", 54 UserAgent: "", // empty user agent. 55 reply: &v2.NearestResult{}, 56 wantErr: true, 57 }, 58 { 59 name: "error-http-client-do-failure", 60 service: "ndt/ndt7", 61 UserAgent: "fake-user-agent", 62 reply: &v2.NearestResult{}, 63 wantErr: true, 64 closeServer: true, 65 }, 66 { 67 name: "error-bad-json-response", 68 service: "ndt/ndt7", 69 UserAgent: "fake-user-agent", 70 status: http.StatusOK, 71 wantErr: true, 72 badJSON: true, 73 }, 74 { 75 name: "error-result-with-error", 76 service: "ndt/ndt7", 77 UserAgent: "unit-test", 78 status: http.StatusInternalServerError, 79 reply: &v2.NearestResult{ 80 Error: &v2.Error{ 81 Title: "error", 82 Detail: "detail", 83 }, 84 }, 85 wantErr: true, 86 }, 87 } 88 for _, tt := range tests { 89 t.Run(tt.name, func(t *testing.T) { 90 c := NewClient(tt.UserAgent) 91 mux := http.NewServeMux() 92 path := "/v2/nearest/" + tt.service 93 mux.HandleFunc(path, func(rw http.ResponseWriter, req *http.Request) { 94 var b []byte 95 if tt.badJSON { 96 b = []byte("this-is-not-JSON{") 97 } else { 98 b, _ = json.Marshal(tt.reply) 99 } 100 rw.WriteHeader(tt.status) 101 rw.Write(b) 102 }) 103 srv := httptest.NewServer(mux) 104 defer srv.Close() 105 if tt.closeServer { 106 srv.Close() 107 } 108 109 u, err := url.Parse(srv.URL) 110 u.Path = "/v2/nearest" 111 if tt.BaseURL != nil { 112 c.BaseURL = tt.BaseURL 113 } else { 114 c.BaseURL = u 115 } 116 117 ctx := context.Background() 118 got, err := c.Nearest(ctx, tt.service) 119 if (err != nil) != tt.wantErr { 120 t.Errorf("Client.Nearest() error = %v, wantErr %v", err, tt.wantErr) 121 return 122 } 123 if tt.reply != nil && !reflect.DeepEqual(got, tt.reply.Results) { 124 t.Errorf("Client.Nearest() = %v, want %v", got, tt.reply.Results) 125 } 126 }) 127 } 128 } 129 130 // This test case is unreachable through the public interface. 131 func TestClient_get(t *testing.T) { 132 t.Run("bad-url", func(t *testing.T) { 133 c := &Client{} 134 ctx := context.Background() 135 _, _, err := c.get(ctx, "://this-is-invalid") 136 if err == nil { 137 t.Errorf("Client.get() error nil, wantErr") 138 return 139 } 140 }) 141 }