mirror of
https://github.com/volatiletech/authboss.git
synced 2025-02-03 13:21:22 +02:00
Add many tests.
- Finish up render package, rename some things. - Add authboss view data/error tests.
This commit is contained in:
parent
585f842a5c
commit
8b87d9c826
@ -33,7 +33,7 @@ type ClientDataErr struct {
|
||||
}
|
||||
|
||||
func (c ClientDataErr) Error() string {
|
||||
return fmt.Sprintf("Failed to retrieve client attribute: %s (%v)", c.Name)
|
||||
return fmt.Sprintf("Failed to retrieve client attribute: %s", c.Name)
|
||||
}
|
||||
|
||||
// ErrAndRedirect represents a general error whose response should
|
||||
@ -46,7 +46,7 @@ type ErrAndRedirect struct {
|
||||
}
|
||||
|
||||
func (e ErrAndRedirect) Error() string {
|
||||
return fmt.Sprintf("Error: %v, Redirecting to: %s", e.Error, e.Endpoint)
|
||||
return fmt.Sprintf("Error: %v, Redirecting to: %s", e.Err, e.Endpoint)
|
||||
}
|
||||
|
||||
// RenderErr represents an error that occured during rendering
|
||||
@ -58,5 +58,5 @@ type RenderErr struct {
|
||||
}
|
||||
|
||||
func (r RenderErr) Error() string {
|
||||
return fmt.Sprintf("Error rendering template %q (%#v): %v", r.TemplateName, r.Data, r.Err)
|
||||
return fmt.Sprintf("Error rendering template %q: %v, data: %#v", r.TemplateName, r.Err, r.Data)
|
||||
}
|
||||
|
43
errors_test.go
Normal file
43
errors_test.go
Normal file
@ -0,0 +1,43 @@
|
||||
package authboss
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAttributeErr(t *testing.T) {
|
||||
estr := "Failed to retrieve database attribute, type was wrong: lol (want: String, got: int)"
|
||||
if str := MakeAttributeErr("lol", String, 5).Error(); str != estr {
|
||||
t.Error("Error was wrong:", str)
|
||||
}
|
||||
|
||||
estr = "Failed to retrieve database attribute: lol"
|
||||
err := AttributeErr{Name: "lol"}
|
||||
if str := err.Error(); str != estr {
|
||||
t.Error("Error was wrong:", str)
|
||||
}
|
||||
}
|
||||
|
||||
func TestClientDataErr(t *testing.T) {
|
||||
estr := "Failed to retrieve client attribute: lol"
|
||||
err := ClientDataErr{"lol"}
|
||||
if str := err.Error(); str != estr {
|
||||
t.Error("Error was wrong:", str)
|
||||
}
|
||||
}
|
||||
|
||||
func TestErrAndRedirect(t *testing.T) {
|
||||
estr := "Error: cause, Redirecting to: /"
|
||||
err := ErrAndRedirect{errors.New("cause"), "/", "success", "failure"}
|
||||
if str := err.Error(); str != estr {
|
||||
t.Error("Error was wrong:", str)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRenderErr(t *testing.T) {
|
||||
estr := `Error rendering template "lol": cause, data: authboss.HTMLData{"a":5}`
|
||||
err := RenderErr{"lol", NewHTMLData("a", 5), errors.New("cause")}
|
||||
if str := err.Error(); str != estr {
|
||||
t.Error("Error was wrong:", str)
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ package render
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"html/template"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
@ -13,34 +14,36 @@ import (
|
||||
func View(ctx *authboss.Context, w http.ResponseWriter, r *http.Request, t views.Templates, name string, data authboss.HTMLData) error {
|
||||
tpl, ok := t[name]
|
||||
if !ok {
|
||||
return authboss.RenderErr{tpl.Name(), data, ErrTemplateNotFound}
|
||||
return authboss.RenderErr{tpl.Name(), data, views.ErrTemplateNotFound}
|
||||
}
|
||||
|
||||
data.Merge("xsrfName", authboss.Cfg.XSRFName, "xsrfToken", authboss.Cfg.XSRFMaker(w, r))
|
||||
|
||||
if flash, ok := ctx.CookieStorer.Get(authboss.FlashSuccessKey); ok {
|
||||
ctx.CookieStorer.Del(authboss.FlashSuccessKey)
|
||||
data.Merge(authboss.FlashSuccessKey, flash)
|
||||
}
|
||||
if flash, ok := ctx.CookieStorer.Get(authboss.FlashErrorKey); ok {
|
||||
ctx.CookieStorer.Del(authboss.FlashErrorKey)
|
||||
data.Merge(authboss.FlashErrorKey, flash)
|
||||
}
|
||||
data.MergeKV("xsrfName", template.HTML(authboss.Cfg.XSRFName), "xsrfToken", template.HTML(authboss.Cfg.XSRFMaker(w, r)))
|
||||
|
||||
if authboss.Cfg.LayoutDataMaker != nil {
|
||||
data.Merge(authboss.Cfg.LayoutDataMaker(w, r))
|
||||
}
|
||||
|
||||
buffer = &bytes.Buffer{}
|
||||
err = tpl.ExecuteTemplate(buffer, tpl.Name(), data)
|
||||
if flash, ok := ctx.CookieStorer.Get(authboss.FlashSuccessKey); ok {
|
||||
ctx.CookieStorer.Del(authboss.FlashSuccessKey)
|
||||
data.MergeKV(authboss.FlashSuccessKey, flash)
|
||||
}
|
||||
if flash, ok := ctx.CookieStorer.Get(authboss.FlashErrorKey); ok {
|
||||
ctx.CookieStorer.Del(authboss.FlashErrorKey)
|
||||
data.MergeKV(authboss.FlashErrorKey, flash)
|
||||
}
|
||||
|
||||
buffer := &bytes.Buffer{}
|
||||
err := tpl.ExecuteTemplate(buffer, tpl.Name(), data)
|
||||
if err != nil {
|
||||
return authboss.RenderErr{tpl.Name(), data, err}
|
||||
}
|
||||
|
||||
err = io.Copy(w, buffer)
|
||||
_, err = io.Copy(w, buffer)
|
||||
if err != nil {
|
||||
return authboss.RenderErr{tpl.Name(), data, err}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Redirect sets any flash messages given and redirects the user.
|
||||
|
75
internal/render/render_test.go
Normal file
75
internal/render/render_test.go
Normal file
@ -0,0 +1,75 @@
|
||||
package render
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"gopkg.in/authboss.v0"
|
||||
"gopkg.in/authboss.v0/internal/mocks"
|
||||
"gopkg.in/authboss.v0/internal/views"
|
||||
)
|
||||
|
||||
var testViewTemplate = template.Must(template.New("").Parse(`{{.external}} {{.fun}} {{.flash_success}} {{.flash_error}} {{.xsrfName}} {{.xsrfToken}}`))
|
||||
|
||||
func TestView(t *testing.T) {
|
||||
cookies := mocks.NewMockClientStorer()
|
||||
authboss.Cfg = &authboss.Config{
|
||||
LayoutDataMaker: func(_ http.ResponseWriter, _ *http.Request) authboss.HTMLData {
|
||||
return authboss.HTMLData{"fun": "is"}
|
||||
},
|
||||
XSRFName: "do you think",
|
||||
XSRFMaker: func(_ http.ResponseWriter, _ *http.Request) string {
|
||||
return "that's air you're breathing now?"
|
||||
},
|
||||
}
|
||||
|
||||
// Set up flashes
|
||||
cookies.Put(authboss.FlashSuccessKey, "no")
|
||||
cookies.Put(authboss.FlashErrorKey, "spoon")
|
||||
|
||||
r, _ := http.NewRequest("GET", "http://localhost", nil)
|
||||
w := httptest.NewRecorder()
|
||||
ctx, _ := authboss.ContextFromRequest(r)
|
||||
ctx.CookieStorer = cookies
|
||||
|
||||
tpls := views.Templates{
|
||||
"hello": testViewTemplate,
|
||||
}
|
||||
|
||||
err := View(ctx, w, r, tpls, "hello", authboss.HTMLData{"external": "there"})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if w.Body.String() != "there is no spoon do you think that's air you're breathing now?" {
|
||||
t.Error("Body was wrong:", w.Body.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestRedirect(t *testing.T) {
|
||||
cookies := mocks.NewMockClientStorer()
|
||||
|
||||
r, _ := http.NewRequest("GET", "http://localhost", nil)
|
||||
w := httptest.NewRecorder()
|
||||
ctx, _ := authboss.ContextFromRequest(r)
|
||||
ctx.CookieStorer = cookies
|
||||
|
||||
Redirect(ctx, w, r, "/", "success", "failure")
|
||||
|
||||
if w.Code != http.StatusTemporaryRedirect {
|
||||
t.Error("Expected a redirect.")
|
||||
}
|
||||
|
||||
if w.Header().Get("Location") != "/" {
|
||||
t.Error("Expected to be redirected to root.")
|
||||
}
|
||||
|
||||
if val, _ := cookies.Get(authboss.FlashSuccessKey); val != "success" {
|
||||
t.Error("Flash success msg wrong:", val)
|
||||
}
|
||||
if val, _ := cookies.Get(authboss.FlashErrorKey); val != "failure" {
|
||||
t.Error("Flash failure msg wrong:", val)
|
||||
}
|
||||
}
|
13
views.go
13
views.go
@ -29,9 +29,18 @@ func NewHTMLData(data ...interface{}) HTMLData {
|
||||
return h
|
||||
}
|
||||
|
||||
// Merge adds extra key-values to the HTMLData. The input is a key-value
|
||||
// Merge adds the data from other to h. If there are conflicting keys
|
||||
// they are overwritten by other's values.
|
||||
func (h HTMLData) Merge(other HTMLData) HTMLData {
|
||||
for k, v := range other {
|
||||
h[k] = v
|
||||
}
|
||||
return h
|
||||
}
|
||||
|
||||
// MergeKV adds extra key-values to the HTMLData. The input is a key-value
|
||||
// slice, where odd elements are keys, and the following even element is their value.
|
||||
func (h HTMLData) Merge(data ...interface{}) HTMLData {
|
||||
func (h HTMLData) MergeKV(data ...interface{}) HTMLData {
|
||||
if len(data)%2 != 0 {
|
||||
panic("It should be a key value list of arguments.")
|
||||
}
|
||||
|
49
views_test.go
Normal file
49
views_test.go
Normal file
@ -0,0 +1,49 @@
|
||||
package authboss
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestHTMLData(t *testing.T) {
|
||||
data := NewHTMLData("a", "b").MergeKV("c", "d").Merge(NewHTMLData("e", "f"))
|
||||
if data["a"].(string) != "b" {
|
||||
t.Error("A was wrong:", data["a"])
|
||||
}
|
||||
if data["c"].(string) != "d" {
|
||||
t.Error("C was wrong:", data["c"])
|
||||
}
|
||||
if data["e"].(string) != "f" {
|
||||
t.Error("E was wrong:", data["e"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestHTMLData_Panics(t *testing.T) {
|
||||
nPanics := 0
|
||||
panicCount := func() {
|
||||
if r := recover(); r != nil {
|
||||
nPanics++
|
||||
}
|
||||
}
|
||||
|
||||
func() {
|
||||
defer panicCount()
|
||||
NewHTMLData("hello")
|
||||
}()
|
||||
|
||||
func() {
|
||||
defer panicCount()
|
||||
NewHTMLData().MergeKV("hello")
|
||||
}()
|
||||
|
||||
func() {
|
||||
defer panicCount()
|
||||
NewHTMLData(5, 6)
|
||||
}()
|
||||
|
||||
func() {
|
||||
defer panicCount()
|
||||
NewHTMLData().MergeKV(7, 8)
|
||||
}()
|
||||
|
||||
if nPanics != 4 {
|
||||
t.Error("They all should have paniced.")
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user