package handlers import ( "bytes" "encoding/json" "fmt" "net/http" "net/http/httptest" "net/url" "strings" "testing" "time" "github.com/gorilla/mux" "github.com/jinzhu/gorm" "github.com/remogatto/prettytest" "gogs.carduccidante.edu.it/karmen/core/config" "gogs.carduccidante.edu.it/karmen/core/orm" "gogs.carduccidante.edu.it/karmen/core/renderer" ) var ( token string ) // Start of setup type testSuite struct { prettytest.Suite } func TestRunner(t *testing.T) { prettytest.Run( t, new(testSuite), ) } func (t *testSuite) BeforeAll() { var ( db *gorm.DB err error ) // Initialize the ORM connected := false for !connected { time.Sleep(10 * time.Second) db, err = orm.New("karmen:karmen@/karmen_test?charset=utf8&parseTime=True&loc=Local") if err != nil { time.Sleep(5 * time.Second) continue } connected = true } orm.Use(db) orm.AutoMigrate() // Initialize the renderers htmlRenderer, err := renderer.NewHTMLRenderer("./testdata/templates/") if err != nil { panic(err) } jsonRenderer, err := renderer.NewJSONRenderer() if err != nil { panic(err) } csvRenderer, err := renderer.NewCSVRenderer() if err != nil { panic(err) } renderer.Render = make(map[string]func(http.ResponseWriter, *http.Request, interface{}, ...url.Values)) renderer.Render["html"] = func(w http.ResponseWriter, r *http.Request, data interface{}, options ...url.Values) { htmlRenderer.Render(w, r, data, options...) } renderer.Render["json"] = func(w http.ResponseWriter, r *http.Request, data interface{}, options ...url.Values) { jsonRenderer.Render(w, r, data, options...) } renderer.Render["csv"] = func(w http.ResponseWriter, r *http.Request, data interface{}, options ...url.Values) { csvRenderer.Render(w, r, data, options...) } // Load the configuration err = config.ReadFile("testdata/config.yaml", config.Config) if err != nil { panic(err) } config.Config.LogLevel = config.LOG_LEVEL_OFF req, err := http.NewRequest("GET", "/get_token", nil) if err != nil { panic(err) } req.SetBasicAuth("admin", "admin") rr := httptest.NewRecorder() tokenHandler().ServeHTTP(rr, req) var data struct { Token string UserID string } if err := json.Unmarshal(rr.Body.Bytes(), &data); err != nil { panic(err) } token = data.Token } func (t *testSuite) TestGetTeachersHTML() { req, err := http.NewRequest("GET", "/teachers?format=html&tpl_layout=base&tpl_content=teachers", nil) if err != nil { panic(err) } pattern := PathPattern{ "/%s", "/%s?format=html&tpl_layout=base&tpl_content=%s", []string{"GET"}, } rr := httptest.NewRecorder() modelHandler("teachers", pattern).ServeHTTP(rr, req) t.Equal(http.StatusOK, rr.Code) if !t.Failed() { t.True(strings.Contains(rr.Body.String(), "DELLE ROSE")) } } func (t *testSuite) TestGetTeachersJSON() { var ( teachers []*orm.Teacher response renderer.JsonResponse ) req, err := http.NewRequest("GET", "/api/teachers?format=json", nil) if err != nil { panic(err) } pattern := PathPattern{ "/api/%s", "/%s/%d?format=json", []string{"GET"}, } rr := httptest.NewRecorder() modelHandler("teachers", pattern).ServeHTTP(rr, req) t.Equal(http.StatusOK, rr.Code) if !t.Failed() { err := json.Unmarshal(rr.Body.Bytes(), &response) t.Nil(err) if !t.Failed() { err := json.Unmarshal(response.Result, &teachers) t.Nil(err) t.Equal("AGOSTINO", teachers[0].Surname) } } } func (t *testSuite) TestDeleteActivityJSON() { var response renderer.JsonResponse req, err := http.NewRequest("DELETE", fmt.Sprintf("/api/activities/%d/delete?format=json", 1), nil) if err != nil { panic(err) } req.Header.Set("Content-Type", "application/json; charset=utf-8") rr := httptest.NewRecorder() pattern := PathPattern{"/api/%s/{id}/delete", "", []string{"DELETE"}} router := mux.NewRouter() router.Handle("/api/activities/{id}/delete", modelHandler("activities", pattern)) router.ServeHTTP(rr, req) if !t.Failed() { err := json.Unmarshal(rr.Body.Bytes(), &response) t.Nil(err) if !t.Failed() { t.Equal("1", string(response.Result)) } } t.Equal(http.StatusOK, rr.Code) } func (t *testSuite) TestGetTeacherJSON() { var ( teacher *orm.Teacher response renderer.JsonResponse ) req, err := http.NewRequest("GET", "/api/teachers/9?format=json", nil) if err != nil { panic(err) } pattern := PathPattern{"/api/%s/{id}", "", []string{"GET"}} rr := httptest.NewRecorder() router := mux.NewRouter() router.Handle("/api/teachers/{id}", modelHandler("teachers", pattern)) router.ServeHTTP(rr, req) t.Equal(http.StatusOK, rr.Code) if !t.Failed() { err := json.Unmarshal(rr.Body.Bytes(), &response) t.Nil(err) if !t.Failed() { err := json.Unmarshal(response.Result, &teacher) t.Nil(err) t.Equal("FRANCESCHINI", teacher.Surname) } } } func (t *testSuite) TestGetTeachersCSV() { var response renderer.JsonResponse req, err := http.NewRequest("GET", "/api/teachers?format=csv", nil) if err != nil { panic(err) } pattern := PathPattern{ "/api/%s", "/%s/%d?format=csv", []string{"GET"}, } rr := httptest.NewRecorder() modelHandler("teachers", pattern).ServeHTTP(rr, req) t.Equal(http.StatusOK, rr.Code) if !t.Failed() { err := json.Unmarshal(rr.Body.Bytes(), &response) t.Nil(err) if !t.Failed() { t.True(strings.Contains(string(response.Result), "AGOSTINO")) } } } func (t *testSuite) TestGetErrorJSON() { var ( response renderer.JsonResponse ) req, err := http.NewRequest("GET", "/api/teacher/100?format=json", nil) if err != nil { panic(err) } pattern := PathPattern{"/api/%s/{id}", "/%s?format=json", []string{"GET"}} rr := httptest.NewRecorder() modelHandler("teachers", pattern).ServeHTTP(rr, req) err = json.Unmarshal(rr.Body.Bytes(), &response) t.Nil(err) t.Equal("record not found", string(response.Error)) } func (t *testSuite) TestPostErrorJSON() { var ( response renderer.JsonResponse ) teacher := getTeacherJSON(1) teacher.Name = "Mario" teacher.Surname = "ROSSI" data, err := json.Marshal(teacher) if err != nil { panic(err) } req, err := http.NewRequest("POST", "/api/teachers/0/update?format=json", bytes.NewBuffer(data)) if err != nil { panic(err) } req.Header.Set("Content-Type", "application/json; charset=utf-8") rr := httptest.NewRecorder() pattern := PathPattern{"/api/%s/{id}/update", "", []string{"POST"}} router := mux.NewRouter() router.Handle("/api/teachers/{id}/update", modelHandler("teachers", pattern)) router.ServeHTTP(rr, req) t.Equal(http.StatusInternalServerError, rr.Code) err = json.Unmarshal(rr.Body.Bytes(), &response) t.Nil(err) t.Equal("record not found", string(response.Error)) } func (t *testSuite) TestAddTeacherJSON() { var ( response renderer.JsonResponse id uint ) teacher := new(orm.Teacher) teacher.Name = "Mario" teacher.Surname = "ROSSI" data, err := json.Marshal(teacher) t.Nil(err) req, err := http.NewRequest("POST", "/api/teachers/add", bytes.NewBuffer(data)) req.Header.Set("Content-Type", "application/json; charset=utf-8") if err != nil { panic(err) } pattern := PathPattern{ "/api/%s/add", "", []string{"POST"}, } rr := httptest.NewRecorder() modelHandler("teachers", pattern).ServeHTTP(rr, req) t.Equal(http.StatusOK, rr.Code) if !t.Failed() { err := json.Unmarshal(rr.Body.Bytes(), &response) t.Nil(err) if !t.Failed() { err := json.Unmarshal(response.Result, &id) t.Nil(err) t.Equal(uint(10), id) } } } func (t *testSuite) TestUpdateTeacherJSON() { teacher := getTeacherJSON(1) teacher.Name = "Mario" teacher.Surname = "ROSSI" data, err := json.Marshal(teacher) if err != nil { panic(err) } req, err := http.NewRequest("POST", fmt.Sprintf("/api/teachers/%d/update?format=json", teacher.ID), bytes.NewBuffer(data)) if err != nil { panic(err) } req.Header.Set("Content-Type", "application/json; charset=utf-8") rr := httptest.NewRecorder() pattern := PathPattern{"/api/%s/{id}/update", "", []string{"POST"}} router := mux.NewRouter() router.Handle("/api/teachers/{id}/update", modelHandler("teachers", pattern)) router.ServeHTTP(rr, req) t.Equal(http.StatusOK, rr.Code) if !t.Failed() { dbTeacher := getTeacherJSON(1) t.Equal("ROSSI", dbTeacher.Surname) } } func getTeacherJSON(id uint) *orm.Teacher { var ( teacher *orm.Teacher response renderer.JsonResponse ) req, err := http.NewRequest("GET", fmt.Sprintf("/api/teachers/%d?format=json", id), nil) if err != nil { panic(err) } pattern := PathPattern{"/api/%s/{id}", "", []string{"GET"}} rr := httptest.NewRecorder() router := mux.NewRouter() router.Handle("/api/teachers/{id}", modelHandler("teachers", pattern)) router.ServeHTTP(rr, req) err = json.Unmarshal(rr.Body.Bytes(), &response) if err != nil { panic(err) } err = json.Unmarshal(response.Result, &teacher) if err != nil { panic(err) } return teacher } func (t *testSuite) TestGetDepartmentJSON() { var ( department *orm.Department response renderer.JsonResponse ) req, err := http.NewRequest("GET", "/api/departments/1?format=json", nil) if err != nil { panic(err) } pattern := PathPattern{"/api/%s/{id}", "", []string{"GET"}} rr := httptest.NewRecorder() router := mux.NewRouter() router.Handle("/api/departments/{id}", modelHandler("departments", pattern)) router.ServeHTTP(rr, req) t.Equal(http.StatusOK, rr.Code) if !t.Failed() { err := json.Unmarshal(rr.Body.Bytes(), &response) t.Nil(err) if !t.Failed() { err := json.Unmarshal(response.Result, &department) t.Nil(err) t.Equal("LINGUE STRANIERE", department.Name) } } }