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  }