hydra-werther/internal/web/web_test.go

188 lines
4.5 KiB
Go

/*
Copyright (c) JSC iCore.
This source code is licensed under the MIT license found in the
LICENSE file in the root directory of this source tree.
*/
package web
import (
"fmt"
"io/ioutil"
"net/http"
"net/http/httptest"
"os"
"path"
"testing"
"github.com/andreyvit/diff"
"github.com/i-core/routegroup"
)
func TestHTMLRenderer(t *testing.T) {
testCases := []struct {
name string
ext bool
basePath string
data interface{}
wantErr error
}{
{
name: "internal template not found",
wantErr: fmt.Errorf(`the template "login.tmpl" does not exist`),
},
{
name: "internal template happy path",
basePath: "testBasePath",
data: map[string]interface{}{
"CSRFToken": "testCSRFToken",
"Challenge": "testChalenge",
"LoginURL": "testLoginURL",
"IsInvalidCredentials": true,
"IsInternalError": true,
},
},
{
name: "external template not found",
ext: true,
wantErr: fmt.Errorf(`the template "login.tmpl" does not exist`),
},
{
name: "external template happy path",
ext: true,
basePath: "testBasePath",
data: map[string]interface{}{
"CSRFToken": "testCSRFToken",
"Challenge": "testChalenge",
"LoginURL": "testLoginURL",
"IsInvalidCredentials": true,
"IsInternalError": true,
},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
tstDir := path.Join("testdata", t.Name())
// Read the main template.
var originMainT = mainT
defer func() { mainT = originMainT }()
f, err := os.Open(path.Join(tstDir, "main.tmpl"))
if err != nil {
t.Fatalf("failed to open main template: %s", err)
}
fc, err := ioutil.ReadAll(f)
if err != nil {
t.Fatalf("failed to read main template: %s", err)
}
mainT = string(fc)
// Create the template renderer.
cnf := Config{BasePath: tc.basePath}
if tc.ext {
cnf.Dir = tstDir
} else {
origin := intTmplsFS
defer func() { intTmplsFS = origin }()
intTmplsFS = http.Dir(tstDir)
}
r, err := NewHTMLRenderer(cnf)
if err != nil {
t.Fatalf("failed to create the template renderer: %s", err)
}
rr := httptest.NewRecorder()
err = r.RenderTemplate(rr, "login.tmpl", tc.data)
if tc.wantErr != nil {
if err == nil {
t.Fatalf("\ngot not errors\nwant error\n\t%s", tc.wantErr)
}
if err.Error() != tc.wantErr.Error() {
t.Fatalf("\ngot error:\n\t%s\nwant error\n\t%s", err, tc.wantErr)
}
return
}
if err != nil {
t.Fatalf("\ngot error\n\t%s\nwant no errors", err)
}
f, err = os.Open(path.Join(tstDir, "golden.file"))
if err != nil {
t.Fatalf("failed to open golden file: %s", err)
}
fc, err = ioutil.ReadAll(f)
if err != nil {
t.Fatalf("failed to read golden file: %s", err)
}
if got, want := rr.Body.String(), string(fc); got != want {
t.Errorf("\nbody diff (-want +got):\n%s", diff.LineDiff(want, got))
}
})
}
}
func TestStaticHandler(t *testing.T) {
testCases := []struct {
name string
ext bool
file string
wantStatus int
wantBody string
}{
{
name: "internal resource not found",
file: "not.found",
wantStatus: http.StatusNotFound,
},
{
name: "internal resource happy path",
file: "test.file",
wantStatus: http.StatusOK,
wantBody: "test",
},
{
name: "external resource not found",
ext: true,
file: "not.found",
wantStatus: http.StatusNotFound,
},
{
name: "external resource happy path",
ext: true,
file: "test.file",
wantStatus: http.StatusOK,
wantBody: "test",
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
tstDir := path.Join("testdata", t.Name())
cnf := Config{}
if tc.ext {
cnf.Dir = tstDir
} else {
origin := intStaticFS
defer func() { intStaticFS = origin }()
intStaticFS = http.Dir(path.Join(tstDir, "static"))
}
r := httptest.NewRequest(http.MethodGet, "/static/"+tc.file, nil)
rr := httptest.NewRecorder()
router := routegroup.NewRouter()
router.AddRoutes(NewStaticHandler(cnf), "/static")
router.ServeHTTP(rr, r)
if rr.Code != tc.wantStatus {
t.Errorf("got status %d, want status %d", rr.Code, tc.wantStatus)
}
if tc.wantBody != "" {
if got := rr.Body.String(); got != tc.wantBody {
t.Errorf("got body %q, want body %q", got, tc.wantBody)
}
}
})
}
}