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 }