oef/handlers/handlers_test.go

296 lines
6.7 KiB
Go

package handlers
import (
"context"
"encoding/json"
"log"
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"
"time"
"git.andreafazzi.eu/andrea/oef/config"
"git.andreafazzi.eu/andrea/oef/orm"
"git.andreafazzi.eu/andrea/oef/renderer"
"github.com/PuerkitoBio/goquery"
jwt "github.com/dgrijalva/jwt-go"
"github.com/remogatto/prettytest"
)
var (
token string
handlers *Handlers
conf *config.ConfigT
)
// Start of setup
type testSuite struct {
prettytest.Suite
}
func login(request *http.Request, handlers *Handlers, username string, password string) (*http.Request, error) {
tokenString := requestToken(handlers, username, password)
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
return []byte(handlers.Config.Keys.JWTSigningKey), nil
})
if err != nil {
return nil, err
}
ctx := request.Context()
ctx = context.WithValue(ctx, "user", token)
return request.WithContext(ctx), nil
}
func requestToken(handlers *Handlers, username string, password string) string {
req, err := http.NewRequest("GET", "/get_token", nil)
if err != nil {
panic(err)
}
req.SetBasicAuth(username, password)
rr := httptest.NewRecorder()
handlers.GetToken(handlers.Database, []byte(handlers.Config.Keys.JWTSigningKey)).ServeHTTP(rr, req)
var data struct {
Token string
}
if err := json.Unmarshal(rr.Body.Bytes(), &data); err != nil {
panic(err)
}
return data.Token
}
func TestRunner(t *testing.T) {
prettytest.Run(
t,
new(testSuite),
)
}
func (t *testSuite) BeforeAll() {
var db *orm.Database
conf = new(config.ConfigT)
// Load the configuration
err := config.ReadFile("testdata/config.yaml", conf)
if err != nil {
panic(err)
}
// conf.LogLevel = config.LOG_LEVEL_OFF
// Initialize the ORM
connected := false
for !connected {
var err error
time.Sleep(2 * time.Second)
db, err = orm.NewDatabase(conf, orm.Models)
if err != nil {
log.Print(err)
continue
}
connected = true
}
db.AutoMigrate()
// Initialize the renderers
htmlRenderer, err := renderer.NewHTMLRenderer("../templates/")
if err != nil {
panic(err)
}
renderer := map[string]renderer.Renderer{
"html": htmlRenderer,
}
conf.Handlers.Permissions = map[string]map[string][]int{
"administrator": map[string][]int{
"Contest": []int{PermissionCreate, PermissionRead, PermissionReadAll, PermissionUpdate, PermissionDelete},
"Participant": []int{PermissionCreate, PermissionRead, PermissionReadAll, PermissionUpdate, PermissionDelete},
"School": []int{PermissionCreate, PermissionRead, PermissionReadAll, PermissionUpdate, PermissionDelete},
"Question": []int{PermissionCreate, PermissionRead, PermissionReadAll, PermissionUpdate, PermissionDelete},
"Answer": []int{PermissionCreate, PermissionRead, PermissionReadAll, PermissionUpdate, PermissionDelete},
"Response": []int{PermissionCreate, PermissionRead, PermissionReadAll, PermissionUpdate, PermissionDelete},
},
"school": map[string][]int{
"Participant": []int{PermissionCreate, PermissionRead, PermissionReadAll, PermissionUpdate, PermissionDelete},
"School": []int{PermissionRead, PermissionUpdate},
},
"participant": map[string][]int{
"Participant": []int{PermissionRead},
"Response": []int{PermissionUpdate, PermissionRead},
},
"subscriber": map[string][]int{
"School": []int{PermissionCreate, PermissionRead},
},
}
conf.Handlers.PathPatterns = DefaultPathPatterns
conf.Handlers.APIPathPatterns = DefaultAPIPathPatterns
handlers = NewHandlers(conf, renderer, db, orm.Models)
}
func (t *testSuite) TestReadAllContests() {
req, err := handlers.NewReadAllRequest(&orm.Contest{}, "/contests", "html")
t.Nil(err)
req, err = login(req, handlers, "admin", "admin")
t.Nil(err)
if !t.Failed() {
rr := httptest.NewRecorder()
handlers.ReadAll(&orm.Contest{}).ServeHTTP(rr, req)
t.Equal(http.StatusOK, rr.Code)
if !t.Failed() {
doc, err := goquery.NewDocumentFromReader(rr.Body)
if err != nil {
log.Fatal(err)
}
expected := []string{"JUNIOR Contest", "SENIOR Contest"}
ok := true
doc.Find(".list-group-item").Each(func(i int, s *goquery.Selection) {
if !strings.Contains(s.Text(), expected[i]) {
ok = false
}
})
t.True(ok)
}
}
}
func (t *testSuite) TestReadContest() {
req, err := handlers.NewReadRequest(&orm.Contest{}, "/contests/1", "html")
t.Nil(err)
req, err = login(req, handlers, "admin", "admin")
t.Nil(err)
if !t.Failed() {
rr := httptest.NewRecorder()
handlers.Read(&orm.Contest{}).ServeHTTP(rr, req)
t.Equal(http.StatusOK, rr.Code)
if !t.Failed() {
doc, err := goquery.NewDocumentFromReader(rr.Body)
if err != nil {
log.Fatal(err)
}
expected := "JUNIOR Contest"
ok := true
doc.Find("h1").Each(func(i int, s *goquery.Selection) {
if !strings.Contains(s.Text(), expected) {
ok = false
}
})
t.True(ok)
}
}
}
func (t *testSuite) TestGetSchoolSubscription() {
req, err := handlers.NewCreateRequest(&orm.School{}, "/create/", "html", "GET", nil)
t.Nil(err)
req, err = login(req, handlers, "subscriber", "subscribe")
t.Nil(err)
rr := httptest.NewRecorder()
handlers.Read(&orm.School{}).ServeHTTP(rr, req)
t.Equal(http.StatusOK, rr.Code)
doc, err := goquery.NewDocumentFromReader(rr.Body)
if err != nil {
log.Fatal(err)
}
expected := []string{
"Denominazione dell'istituto",
"Codice meccanografico",
"Indirizzo dell'istituto",
"Regione",
"Cognome referente di sede",
"Nome referente di sede",
"Cognome responsabile di gara",
"Nome responsabile di gara",
"Cognome referente di sede",
"Nome referente di sede",
"Indirizzo email",
}
ok := true
doc.Find(".control-label").Each(func(i int, s *goquery.Selection) {
t.Equal(expected[i], s.Text())
if t.Failed() {
ok = false
}
})
t.True(ok)
}
func (t *testSuite) TestPostCreateSchoolFormAsSubscriber() {
form := url.Values{}
form.Add("Name", "FooSchool")
form.Add("Code", "123")
form.Add("Email", "foo@school.org")
req, err := handlers.NewCreateRequest(&orm.School{}, "/create/", "html", "POST", form)
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
t.Nil(err)
req, err = login(req, handlers, "subscriber", "subscribe")
t.Nil(err)
if !t.Failed() {
rr := httptest.NewRecorder()
handlers.Create(&orm.School{}).ServeHTTP(rr, req)
t.Equal(http.StatusSeeOther, rr.Code)
if !t.Failed() {
doc, err := goquery.NewDocumentFromReader(rr.Body)
if err != nil {
log.Fatal(err)
}
expected := []string{
"FooSchooll",
"123",
}
ok := true
doc.Find("dd").Each(func(i int, s *goquery.Selection) {
log.Print(s)
t.Equal(expected[i], s.Text())
if t.Failed() {
ok = false
}
})
t.True(ok)
}
}
}