// GetSession implements the http.Handler interface. // // The method responds with JSON-encoded api.Session value. // // GetSession validates the authentication - for every // api.Session it reads from requests, the session must // already exist in Sessions map. Otherwise handler // responds with 401. func (fa *FakeAuth) GetSession(w http.ResponseWriter, r *http.Request) { var req api.Session req.ReadFrom(r) var session *api.Session fa.mu.RLock() for _, s := range fa.Sessions { if s.ClientID == req.ClientID { session = s break } } fa.mu.RUnlock() if session == nil { w.WriteHeader(http.StatusUnauthorized) } else { json.NewEncoder(w).Encode(session) } }
func TestTransport(t *testing.T) { var auth = apitest.NewFakeAuth() s, err := discovertest.NewServer(http.HandlerFunc(auth.GetSession)) if err != nil { t.Fatalf("NewServer()=%s", err) } defer s.Close() cache := api.NewCache(auth.Auth) users := []*api.Session{ {User: &api.User{Username: "******", Team: "foobar"}}, {User: &api.User{Username: "******", Team: "foobar"}}, {User: &api.User{Username: "******", Team: "foobar"}}, {User: &api.User{Username: "******", Team: "team"}}, } cases := []struct { name string sess *api.Session // client errs []error // fake errors for endpoint codes []int // fake response codes for endpoint err error // final error from client }{{ "new user1", users[0], nil, nil, nil, }, { "cached user1", users[0], nil, nil, nil, }, { "new user2", users[1], nil, nil, nil, }, { "new user3 with an error", users[2], []error{&net.DNSError{IsTemporary: true}}, nil, nil, }, { "cached user3 with an error and response codes", users[2], []error{&net.DNSError{IsTemporary: true}}, []int{401, 401}, nil, }} rec := &apitest.AuthRecorder{ AuthFunc: cache.Auth, } client := http.Client{ Transport: &api.Transport{ RoundTripper: &apitest.FakeTransport{}, AuthFunc: rec.Auth, }, } for _, cas := range cases { t.Run(cas.name, func(t *testing.T) { rec.Reset() req, err := http.NewRequest("POST", s.URL, strings.NewReader(cas.name)) if err != nil { t.Fatalf("NewRequest()=%s", err) } req = cas.sess.User.WithRequest(req) if len(cas.errs) != 0 { req = apitest.WithErrors(req, cas.errs...) } if len(cas.codes) != 0 { req = apitest.WithResponseCodes(req, cas.codes...) } resp, err := client.Do(req) if err != nil { t.Fatalf("Do()=%s", err) } if want, got := 1+len(cas.errs)+len(cas.codes), len(rec.Options); got != want { t.Fatalf("want %d, got %d: %+v", got, want, rec.Options) } if resp.StatusCode != http.StatusOK { t.Fatalf("got %q, want %q", http.StatusText(resp.StatusCode), http.StatusText(http.StatusOK)) } var other api.Session if err := json.NewDecoder(resp.Body).Decode(&other); err != nil { t.Fatalf("Decode()=%s", err) } if err := other.Valid(); err != nil { t.Fatalf("Valid()=%s", err) } if err := other.Match(cas.sess); err != nil { t.Fatalf("Match()=%s", err) } api.Log.Info("received session: %#v", &other) }) } }