// Copyright 2016 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package httptest import ( "crypto/tls" "io" "io/ioutil" "net/http" "net/url" "reflect" "strings" "testing" ) func TestNewRequest(t *testing.T) { tests := [...]struct { method, uri string body io.Reader want *http.Request wantBody string }{ // Empty method means GET: 0: { method: "", uri: "/", body: nil, want: &http.Request{ Method: "GET", Host: "example.com", URL: &url.URL{Path: "/"}, Header: http.Header{}, Proto: "HTTP/1.1", ProtoMajor: 1, ProtoMinor: 1, RemoteAddr: "192.0.2.1:1234", RequestURI: "/", }, wantBody: "", }, // GET with full URL: 1: { method: "GET", uri: "http://foo.com/path/%2f/bar/", body: nil, want: &http.Request{ Method: "GET", Host: "foo.com", URL: &url.URL{ Scheme: "http", Path: "/path///bar/", RawPath: "/path/%2f/bar/", Host: "foo.com", }, Header: http.Header{}, Proto: "HTTP/1.1", ProtoMajor: 1, ProtoMinor: 1, RemoteAddr: "192.0.2.1:1234", RequestURI: "http://foo.com/path/%2f/bar/", }, wantBody: "", }, // GET with full https URL: 2: { method: "GET", uri: "https://foo.com/path/", body: nil, want: &http.Request{ Method: "GET", Host: "foo.com", URL: &url.URL{ Scheme: "https", Path: "/path/", Host: "foo.com", }, Header: http.Header{}, Proto: "HTTP/1.1", ProtoMajor: 1, ProtoMinor: 1, RemoteAddr: "192.0.2.1:1234", RequestURI: "https://foo.com/path/", TLS: &tls.ConnectionState{ Version: tls.VersionTLS12, HandshakeComplete: true, ServerName: "foo.com", }, }, wantBody: "", }, // Post with known length 3: { method: "POST", uri: "/", body: strings.NewReader("foo"), want: &http.Request{ Method: "POST", Host: "example.com", URL: &url.URL{Path: "/"}, Header: http.Header{}, Proto: "HTTP/1.1", ContentLength: 3, ProtoMajor: 1, ProtoMinor: 1, RemoteAddr: "192.0.2.1:1234", RequestURI: "/", }, wantBody: "foo", }, // Post with unknown length 4: { method: "POST", uri: "/", body: struct{ io.Reader }{strings.NewReader("foo")}, want: &http.Request{ Method: "POST", Host: "example.com", URL: &url.URL{Path: "/"}, Header: http.Header{}, Proto: "HTTP/1.1", ContentLength: -1, ProtoMajor: 1, ProtoMinor: 1, RemoteAddr: "192.0.2.1:1234", RequestURI: "/", }, wantBody: "foo", }, // OPTIONS * 5: { method: "OPTIONS", uri: "*", want: &http.Request{ Method: "OPTIONS", Host: "example.com", URL: &url.URL{Path: "*"}, Header: http.Header{}, Proto: "HTTP/1.1", ProtoMajor: 1, ProtoMinor: 1, RemoteAddr: "192.0.2.1:1234", RequestURI: "*", }, }, } for i, tt := range tests { got := NewRequest(tt.method, tt.uri, tt.body) slurp, err := ioutil.ReadAll(got.Body) if err != nil { t.Errorf("%d. ReadAll: %v", i, err) } if string(slurp) != tt.wantBody { t.Errorf("%d. Body = %q; want %q", i, slurp, tt.wantBody) } got.Body = nil // before DeepEqual if !reflect.DeepEqual(got.URL, tt.want.URL) { t.Errorf("%d. Request.URL mismatch:\n got: %#v\nwant: %#v", i, got.URL, tt.want.URL) } if !reflect.DeepEqual(got.Header, tt.want.Header) { t.Errorf("%d. Request.Header mismatch:\n got: %#v\nwant: %#v", i, got.Header, tt.want.Header) } if !reflect.DeepEqual(got.TLS, tt.want.TLS) { t.Errorf("%d. Request.TLS mismatch:\n got: %#v\nwant: %#v", i, got.TLS, tt.want.TLS) } if !reflect.DeepEqual(got, tt.want) { t.Errorf("%d. Request mismatch:\n got: %#v\nwant: %#v", i, got, tt.want) } } }