github.com/volatiletech/authboss@v2.4.1+incompatible/defaults/responder_test.go (about)

     1  package defaults
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"net/http"
     7  	"net/http/httptest"
     8  	"reflect"
     9  	"testing"
    10  
    11  	"github.com/volatiletech/authboss"
    12  	"github.com/volatiletech/authboss/mocks"
    13  )
    14  
    15  type testRenderer struct {
    16  	Callback func(context.Context, string, authboss.HTMLData) ([]byte, string, error)
    17  }
    18  
    19  func (t testRenderer) Load(names ...string) error {
    20  	return nil
    21  }
    22  
    23  func (t testRenderer) Render(ctx context.Context, name string, data authboss.HTMLData) ([]byte, string, error) {
    24  	return t.Callback(ctx, name, data)
    25  }
    26  
    27  func testJSONRender(ctx context.Context, name string, data authboss.HTMLData) ([]byte, string, error) {
    28  	b, err := json.Marshal(data)
    29  	if err != nil {
    30  		panic(err)
    31  	}
    32  
    33  	return b, "application/json", nil
    34  }
    35  
    36  func TestResponder(t *testing.T) {
    37  	t.Parallel()
    38  
    39  	renderer := testRenderer{
    40  		Callback: testJSONRender,
    41  	}
    42  
    43  	responder := Responder{
    44  		Renderer: renderer,
    45  	}
    46  
    47  	r := httptest.NewRequest("GET", "/", nil)
    48  	w := httptest.NewRecorder()
    49  
    50  	r = r.WithContext(context.WithValue(context.Background(), authboss.CTXKeyData, authboss.HTMLData{
    51  		"csrfname":  "csrf",
    52  		"csrftoken": "12345",
    53  	}))
    54  
    55  	err := responder.Respond(w, r, http.StatusCreated, "some_template.tpl", authboss.HTMLData{"auth_happy": true})
    56  	if err != nil {
    57  		t.Error(err)
    58  	}
    59  
    60  	if w.Code != http.StatusCreated {
    61  		t.Error("code was wrong:", w.Code)
    62  	}
    63  
    64  	if got := w.Result().Header.Get("Content-Type"); got != "application/json" {
    65  		t.Error("content type was wrong:", got)
    66  	}
    67  
    68  	expectData := authboss.HTMLData{
    69  		"csrfname":   "csrf",
    70  		"csrftoken":  "12345",
    71  		"auth_happy": true,
    72  	}
    73  
    74  	var gotData authboss.HTMLData
    75  	if err := json.Unmarshal(w.Body.Bytes(), &gotData); err != nil {
    76  		t.Error(err)
    77  	}
    78  
    79  	if !reflect.DeepEqual(gotData, expectData) {
    80  		t.Errorf("data mismatched:\nwant: %#v\ngot:  %#v", expectData, gotData)
    81  	}
    82  }
    83  
    84  func TestRedirector(t *testing.T) {
    85  	t.Parallel()
    86  
    87  	renderer := testRenderer{
    88  		Callback: testJSONRender,
    89  	}
    90  
    91  	redir := Redirector{
    92  		FormValueName: "redir",
    93  		Renderer:      renderer,
    94  	}
    95  
    96  	r := httptest.NewRequest("POST", "/?redir=/pow", nil)
    97  	w := httptest.NewRecorder()
    98  
    99  	r.Header.Set("Content-Type", "application/json")
   100  
   101  	ro := authboss.RedirectOptions{
   102  		Success:      "ok!",
   103  		Code:         http.StatusTeapot,
   104  		RedirectPath: "/redirect", FollowRedirParam: false,
   105  	}
   106  
   107  	if err := redir.Redirect(w, r, ro); err != nil {
   108  		t.Error(err)
   109  	}
   110  
   111  	if w.Code != http.StatusTeapot {
   112  		t.Error("code is wrong:", w.Code)
   113  	}
   114  
   115  	var gotData map[string]string
   116  	if err := json.Unmarshal(w.Body.Bytes(), &gotData); err != nil {
   117  		t.Fatal(err)
   118  	}
   119  
   120  	if got := gotData["status"]; got != "success" {
   121  		t.Error("status was wrong:", got)
   122  	}
   123  	if got := gotData["message"]; got != "ok!" {
   124  		t.Error("message was wrong:", got)
   125  	}
   126  	if got := gotData["location"]; got != "/redirect" {
   127  		t.Error("location was wrong:", got)
   128  	}
   129  }
   130  
   131  func TestResponseRedirectAPIFollowRedir(t *testing.T) {
   132  	t.Parallel()
   133  
   134  	renderer := testRenderer{
   135  		Callback: testJSONRender,
   136  	}
   137  
   138  	redir := Redirector{
   139  		FormValueName: "redir",
   140  		Renderer:      renderer,
   141  	}
   142  
   143  	r := httptest.NewRequest("POST", "/?redir=/pow", nil)
   144  	w := httptest.NewRecorder()
   145  
   146  	r.Header.Set("Content-Type", "application/json")
   147  
   148  	ro := authboss.RedirectOptions{
   149  		Failure:      ":(",
   150  		Code:         http.StatusTeapot,
   151  		RedirectPath: "/redirect", FollowRedirParam: true,
   152  	}
   153  
   154  	if err := redir.Redirect(w, r, ro); err != nil {
   155  		t.Error(err)
   156  	}
   157  
   158  	if w.Code != http.StatusTeapot {
   159  		t.Error("code is wrong:", w.Code)
   160  	}
   161  
   162  	var gotData map[string]string
   163  	if err := json.Unmarshal(w.Body.Bytes(), &gotData); err != nil {
   164  		t.Fatal(err)
   165  	}
   166  
   167  	if got := gotData["status"]; got != "failure" {
   168  		t.Error("status was wrong:", got)
   169  	}
   170  	if got := gotData["message"]; got != ":(" {
   171  		t.Error("message was wrong:", got)
   172  	}
   173  	if got := gotData["location"]; got != "/pow" {
   174  		t.Error("location was wrong:", got)
   175  	}
   176  }
   177  
   178  func TestResponseRedirectNonAPI(t *testing.T) {
   179  	t.Parallel()
   180  
   181  	renderer := testRenderer{
   182  		Callback: func(ctx context.Context, name string, data authboss.HTMLData) ([]byte, string, error) {
   183  			return nil, "", nil
   184  		},
   185  	}
   186  
   187  	redir := Redirector{
   188  		FormValueName: "redir",
   189  		Renderer:      renderer,
   190  	}
   191  
   192  	r := httptest.NewRequest("POST", "/?redir=/pow", nil)
   193  	w := httptest.NewRecorder()
   194  
   195  	ab := authboss.New()
   196  	ab.Config.Storage.SessionState = mocks.NewClientRW()
   197  	ab.Config.Storage.CookieState = mocks.NewClientRW()
   198  	aw := ab.NewResponse(w)
   199  
   200  	ro := authboss.RedirectOptions{
   201  		Success: "success", Failure: "failure",
   202  		RedirectPath: "/redirect", FollowRedirParam: false,
   203  	}
   204  
   205  	if err := redir.Redirect(aw, r, ro); err != nil {
   206  		t.Error(err)
   207  	}
   208  
   209  	if w.Code != http.StatusFound {
   210  		t.Error("code is wrong:", w.Code)
   211  	}
   212  	if got := w.Header().Get("Location"); got != "/redirect" {
   213  		t.Error("redirect location was wrong:", got)
   214  	}
   215  }
   216  
   217  func TestResponseRedirectNonAPIFollowRedir(t *testing.T) {
   218  	t.Parallel()
   219  
   220  	renderer := testRenderer{
   221  		Callback: func(ctx context.Context, name string, data authboss.HTMLData) ([]byte, string, error) {
   222  			return nil, "", nil
   223  		},
   224  	}
   225  
   226  	redir := Redirector{
   227  		FormValueName: "redir",
   228  		Renderer:      renderer,
   229  	}
   230  
   231  	r := httptest.NewRequest("POST", "/?redir=/pow", nil)
   232  	w := httptest.NewRecorder()
   233  
   234  	ab := authboss.New()
   235  	ab.Config.Storage.SessionState = mocks.NewClientRW()
   236  	ab.Config.Storage.CookieState = mocks.NewClientRW()
   237  	aw := ab.NewResponse(w)
   238  
   239  	ro := authboss.RedirectOptions{
   240  		RedirectPath: "/redirect", FollowRedirParam: true,
   241  	}
   242  	if err := redir.Redirect(aw, r, ro); err != nil {
   243  		t.Error(err)
   244  	}
   245  
   246  	if w.Code != http.StatusFound {
   247  		t.Error("code is wrong:", w.Code)
   248  	}
   249  	if got := w.Header().Get("Location"); got != "/pow" {
   250  		t.Error("redirect location was wrong:", got)
   251  	}
   252  }