// Copyright 2012 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 (
	"fmt"
	"io"
	"net/http"
	"testing"
)

func TestRecorder(t *testing.T) {
	type checkFunc func(*ResponseRecorder) error
	check := func(fns ...checkFunc) []checkFunc { return fns }

	hasStatus := func(wantCode int) checkFunc {
		return func(rec *ResponseRecorder) error {
			if rec.Code != wantCode {
				return fmt.Errorf("Status = %d; want %d", rec.Code, wantCode)
			}
			return nil
		}
	}
	hasResultStatus := func(wantCode int) checkFunc {
		return func(rec *ResponseRecorder) error {
			if rec.Result().StatusCode != wantCode {
				return fmt.Errorf("Result().StatusCode = %d; want %d", rec.Result().StatusCode, wantCode)
			}
			return nil
		}
	}
	hasContents := func(want string) checkFunc {
		return func(rec *ResponseRecorder) error {
			if rec.Body.String() != want {
				return fmt.Errorf("wrote = %q; want %q", rec.Body.String(), want)
			}
			return nil
		}
	}
	hasFlush := func(want bool) checkFunc {
		return func(rec *ResponseRecorder) error {
			if rec.Flushed != want {
				return fmt.Errorf("Flushed = %v; want %v", rec.Flushed, want)
			}
			return nil
		}
	}
	hasOldHeader := func(key, want string) checkFunc {
		return func(rec *ResponseRecorder) error {
			if got := rec.HeaderMap.Get(key); got != want {
				return fmt.Errorf("HeaderMap header %s = %q; want %q", key, got, want)
			}
			return nil
		}
	}
	hasHeader := func(key, want string) checkFunc {
		return func(rec *ResponseRecorder) error {
			if got := rec.Result().Header.Get(key); got != want {
				return fmt.Errorf("final header %s = %q; want %q", key, got, want)
			}
			return nil
		}
	}
	hasNotHeaders := func(keys ...string) checkFunc {
		return func(rec *ResponseRecorder) error {
			for _, k := range keys {
				v, ok := rec.Result().Header[http.CanonicalHeaderKey(k)]
				if ok {
					return fmt.Errorf("unexpected header %s with value %q", k, v)
				}
			}
			return nil
		}
	}
	hasTrailer := func(key, want string) checkFunc {
		return func(rec *ResponseRecorder) error {
			if got := rec.Result().Trailer.Get(key); got != want {
				return fmt.Errorf("trailer %s = %q; want %q", key, got, want)
			}
			return nil
		}
	}
	hasNotTrailers := func(keys ...string) checkFunc {
		return func(rec *ResponseRecorder) error {
			trailers := rec.Result().Trailer
			for _, k := range keys {
				_, ok := trailers[http.CanonicalHeaderKey(k)]
				if ok {
					return fmt.Errorf("unexpected trailer %s", k)
				}
			}
			return nil
		}
	}

	tests := []struct {
		name   string
		h      func(w http.ResponseWriter, r *http.Request)
		checks []checkFunc
	}{
		{
			"200 default",
			func(w http.ResponseWriter, r *http.Request) {},
			check(hasStatus(200), hasContents("")),
		},
		{
			"first code only",
			func(w http.ResponseWriter, r *http.Request) {
				w.WriteHeader(201)
				w.WriteHeader(202)
				w.Write([]byte("hi"))
			},
			check(hasStatus(201), hasContents("hi")),
		},
		{
			"write sends 200",
			func(w http.ResponseWriter, r *http.Request) {
				w.Write([]byte("hi first"))
				w.WriteHeader(201)
				w.WriteHeader(202)
			},
			check(hasStatus(200), hasContents("hi first"), hasFlush(false)),
		},
		{
			"write string",
			func(w http.ResponseWriter, r *http.Request) {
				io.WriteString(w, "hi first")
			},
			check(
				hasStatus(200),
				hasContents("hi first"),
				hasFlush(false),
				hasHeader("Content-Type", "text/plain; charset=utf-8"),
			),
		},
		{
			"flush",
			func(w http.ResponseWriter, r *http.Request) {
				w.(http.Flusher).Flush() // also sends a 200
				w.WriteHeader(201)
			},
			check(hasStatus(200), hasFlush(true)),
		},
		{
			"Content-Type detection",
			func(w http.ResponseWriter, r *http.Request) {
				io.WriteString(w, "<html>")
			},
			check(hasHeader("Content-Type", "text/html; charset=utf-8")),
		},
		{
			"no Content-Type detection with Transfer-Encoding",
			func(w http.ResponseWriter, r *http.Request) {
				w.Header().Set("Transfer-Encoding", "some encoding")
				io.WriteString(w, "<html>")
			},
			check(hasHeader("Content-Type", "")), // no header
		},
		{
			"no Content-Type detection if set explicitly",
			func(w http.ResponseWriter, r *http.Request) {
				w.Header().Set("Content-Type", "some/type")
				io.WriteString(w, "<html>")
			},
			check(hasHeader("Content-Type", "some/type")),
		},
		{
			"Content-Type detection doesn't crash if HeaderMap is nil",
			func(w http.ResponseWriter, r *http.Request) {
				// Act as if the user wrote new(httptest.ResponseRecorder)
				// rather than using NewRecorder (which initializes
				// HeaderMap)
				w.(*ResponseRecorder).HeaderMap = nil
				io.WriteString(w, "<html>")
			},
			check(hasHeader("Content-Type", "text/html; charset=utf-8")),
		},
		{
			"Header is not changed after write",
			func(w http.ResponseWriter, r *http.Request) {
				hdr := w.Header()
				hdr.Set("Key", "correct")
				w.WriteHeader(200)
				hdr.Set("Key", "incorrect")
			},
			check(hasHeader("Key", "correct")),
		},
		{
			"Trailer headers are correctly recorded",
			func(w http.ResponseWriter, r *http.Request) {
				w.Header().Set("Non-Trailer", "correct")
				w.Header().Set("Trailer", "Trailer-A")
				w.Header().Add("Trailer", "Trailer-B")
				w.Header().Add("Trailer", "Trailer-C")
				io.WriteString(w, "<html>")
				w.Header().Set("Non-Trailer", "incorrect")
				w.Header().Set("Trailer-A", "valuea")
				w.Header().Set("Trailer-C", "valuec")
				w.Header().Set("Trailer-NotDeclared", "should be omitted")
			},
			check(
				hasStatus(200),
				hasHeader("Content-Type", "text/html; charset=utf-8"),
				hasHeader("Non-Trailer", "correct"),
				hasNotHeaders("Trailer-A", "Trailer-B", "Trailer-C", "Trailer-NotDeclared"),
				hasTrailer("Trailer-A", "valuea"),
				hasTrailer("Trailer-C", "valuec"),
				hasNotTrailers("Non-Trailer", "Trailer-B", "Trailer-NotDeclared"),
			),
		},
		{
			"Header set without any write", // Issue 15560
			func(w http.ResponseWriter, r *http.Request) {
				w.Header().Set("X-Foo", "1")

				// Simulate somebody using
				// new(ResponseRecorder) instead of
				// using the constructor which sets
				// this to 200
				w.(*ResponseRecorder).Code = 0
			},
			check(
				hasOldHeader("X-Foo", "1"),
				hasStatus(0),
				hasHeader("X-Foo", "1"),
				hasResultStatus(200),
			),
		},
		{
			"HeaderMap vs FinalHeaders", // more for Issue 15560
			func(w http.ResponseWriter, r *http.Request) {
				h := w.Header()
				h.Set("X-Foo", "1")
				w.Write([]byte("hi"))
				h.Set("X-Foo", "2")
				h.Set("X-Bar", "2")
			},
			check(
				hasOldHeader("X-Foo", "2"),
				hasOldHeader("X-Bar", "2"),
				hasHeader("X-Foo", "1"),
				hasNotHeaders("X-Bar"),
			),
		},
	}
	r, _ := http.NewRequest("GET", "http://foo.com/", nil)
	for _, tt := range tests {
		h := http.HandlerFunc(tt.h)
		rec := NewRecorder()
		h.ServeHTTP(rec, r)
		for _, check := range tt.checks {
			if err := check(rec); err != nil {
				t.Errorf("%s: %v", tt.name, err)
			}
		}
	}
}
