Эх сурвалжийг харах

Add new tests and overall refactoring

Andrea Fazzi 6 жил өмнө
parent
commit
19336fa358

+ 9 - 8
handlers/handlers.go

@@ -74,19 +74,19 @@ func generateHandler(r *mux.Router, model string) {
 			PathPattern{"/%s/{id}/delete", "/%s?format=html&tpl_layout=base&tpl_content=%s", []string{"DELETE"}},
 		}
 
-		jsonPatterns []PathPattern = []PathPattern{
+		apiPatterns []PathPattern = []PathPattern{
 			PathPattern{"/api/%s", "", []string{"GET"}},
 			PathPattern{"/api/%s/{id}", "", []string{"GET"}},
-			PathPattern{"/api/%s/add/", "/%s/%d?format=json&tpl_layout=base&tpl_content=%s_show", []string{"GET", "POST"}},
-			PathPattern{"/api/%s/{id}/update", "/%s/%d?format=json&tpl_layout=base&tpl_content=%s_show", []string{"GET", "POST"}},
-			PathPattern{"/api/%s/{id}/delete", "/%s?format=json&tpl_layout=base&tpl_content=%s", []string{"DELETE"}},
+			PathPattern{"/api/%s/add/", "", []string{"GET", "POST"}},
+			PathPattern{"/api/%s/{id}/update", "", []string{"GET", "POST"}},
+			PathPattern{"/api/%s/{id}/delete", "", []string{"DELETE"}},
 		}
 	)
 	for _, pattern := range patterns {
 		r.Handle(pattern.Path(model), jwtCookie.Handler(recoverHandler(modelHandler(model, pattern)))).Methods(pattern.Methods...)
 	}
 
-	for _, pattern := range jsonPatterns {
+	for _, pattern := range apiPatterns {
 		r.Handle(pattern.Path(model), jwtHeader.Handler(recoverHandler(modelHandler(model, pattern)))).Methods(pattern.Methods...)
 	}
 
@@ -189,7 +189,7 @@ func post(w http.ResponseWriter, r *http.Request, model string, pattern PathPatt
 		err  error
 	)
 
-	format := r.URL.Query().Get("format")
+	respFormat := renderer.GetContentFormat(r)
 	postFn, err := orm.PostFunc(pattern.Path(model))
 
 	if err != nil {
@@ -198,18 +198,19 @@ func post(w http.ResponseWriter, r *http.Request, model string, pattern PathPatt
 		data, err = postFn(mux.Vars(r), r)
 		if err != nil {
 			respondWithError(w, r, err)
-		} else if format == "html" {
+		} else if pattern.RedirectPattern != "" {
 			if id := mux.Vars(r)["id"]; id != "" {
 				modelId, _ := strconv.Atoi(id)
 				http.Redirect(w, r, pattern.RedirectPath(model, uint(modelId)), http.StatusSeeOther)
 			} else {
 				http.Redirect(w, r, pattern.RedirectPath(model, data.GetID()), http.StatusSeeOther)
 			}
+		} else {
+			renderer.Render[respFormat](w, r, data.GetID())
 		}
 
 	}
 
-	renderer.Render[format](w, r, data.GetID())
 }
 
 func modelHandler(model string, pattern PathPattern) http.Handler {

+ 101 - 3
handlers/handlers_test.go

@@ -3,6 +3,7 @@ package handlers
 import (
 	"bytes"
 	"encoding/json"
+	"fmt"
 	"net/http"
 	"net/http/httptest"
 	"net/url"
@@ -10,6 +11,7 @@ import (
 	"testing"
 	"time"
 
+	"github.com/gorilla/mux"
 	"github.com/jinzhu/gorm"
 	"github.com/remogatto/prettytest"
 	"gogs.carducci-dante.gov.it/karmen/core/config"
@@ -177,6 +179,39 @@ func (t *testSuite) TestGetTeachersJSON() {
 
 }
 
+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
 
@@ -227,7 +262,7 @@ func (t *testSuite) TestGetErrorJSON() {
 
 }
 
-func (t *testSuite) TestPostTeacherJSON() {
+func (t *testSuite) TestAddTeacherJSON() {
 	var (
 		response renderer.JsonResponse
 		id       uint
@@ -240,7 +275,7 @@ func (t *testSuite) TestPostTeacherJSON() {
 	data, err := json.Marshal(teacher)
 	t.Nil(err)
 
-	req, err := http.NewRequest("POST", "/api/teachers/add?format=json", bytes.NewBuffer(data))
+	req, err := http.NewRequest("POST", "/api/teachers/add", bytes.NewBuffer(data))
 	req.Header.Set("Content-Type", "application/json; charset=utf-8")
 
 	if err != nil {
@@ -249,7 +284,7 @@ func (t *testSuite) TestPostTeacherJSON() {
 
 	pattern := PathPattern{
 		"/api/%s/add",
-		"/%s?format=json",
+		"",
 		[]string{"POST"},
 	}
 
@@ -269,3 +304,66 @@ func (t *testSuite) TestPostTeacherJSON() {
 	}
 
 }
+
+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
+
+}

+ 13 - 12
orm/orm.go

@@ -147,36 +147,37 @@ var (
 		"/teachers/{id}/delete": DeleteTeacher,
 		"/teachers/add/":        AddTeacher,
 
-		"/api/teachers/add":          AddTeacher,
-		"/api//teachers/{id}/delete": DeleteTeacher,
-		"/api//teachers/add/":        AddTeacher,
+		"/api/teachers/add":         AddTeacher,
+		"/api/teachers/{id}/update": UpdateTeacher,
+		"/api/teachers/{id}/delete": DeleteTeacher,
+		"/api/teachers/add/":        AddTeacher,
 
 		// Classes
 		"/classes/{id}/update": UpdateClass,
 		"/classes/{id}/delete": DeleteClass,
 		"/classes/add/":        AddClass,
 
-		"/api//classes/{id}/update": UpdateClass,
-		"/api//classes/{id}/delete": DeleteClass,
-		"/api//classes/add/":        AddClass,
+		"/api/classes/{id}/update": UpdateClass,
+		"/api/classes/{id}/delete": DeleteClass,
+		"/api/classes/add/":        AddClass,
 
 		// Subjects
 		"/subjects/{id}/update": UpdateSubject,
 		"/subjects/{id}/delete": DeleteSubject,
 		"/subjects/add/":        AddSubject,
 
-		"/api//subjects/{id}/update": UpdateSubject,
-		"/api//subjects/{id}/delete": DeleteSubject,
-		"/api//subjects/add/":        AddSubject,
+		"/api/subjects/{id}/update": UpdateSubject,
+		"/api/subjects/{id}/delete": DeleteSubject,
+		"/api/subjects/add/":        AddSubject,
 
 		// Activity
 		"/activities/{id}/update": UpdateActivity,
 		"/activities/{id}/delete": DeleteActivity,
 		"/activities/add/":        AddActivity,
 
-		"/api//activities/{id}/update": UpdateActivity,
-		"/api//activities/{id}/delete": DeleteActivity,
-		"/api//activities/add/":        AddActivity,
+		"/api/activities/{id}/update": UpdateActivity,
+		"/api/activities/{id}/delete": DeleteActivity,
+		"/api/activities/add/":        AddActivity,
 	}
 )
 

+ 1 - 1
orm/teacher.go

@@ -108,7 +108,7 @@ func GetTeachersAll(args map[string]string) (interface{}, error) {
 }
 
 func SaveTeacher(teacher interface{}) (interface{}, error) {
-	if err := DB().Save(teacher).Error; err != nil {
+	if err := DB().Omit("Classes", "Subjects", "Activities").Save(teacher).Error; err != nil {
 		return nil, err
 	}
 	return teacher, nil

+ 30 - 4
renderer/renderer.go

@@ -5,6 +5,7 @@ import (
 	"fmt"
 	"html/template"
 	"log"
+	"mime"
 	"net/http"
 	"net/url"
 	"path"
@@ -40,6 +41,12 @@ var (
 	funcMap = template.FuncMap{
 		"query": query,
 	}
+
+	contentTypeToFormat = map[string]string{
+		"application/x-www-form-urlencoded": "html",
+		"application/json":                  "json",
+		"text/csv; charset=utf-8":           "csv",
+	}
 )
 
 func init() {
@@ -217,11 +224,30 @@ func (rend *HTMLRenderer) Render(w http.ResponseWriter, r *http.Request, data in
 	}
 }
 
-func Decode(dst interface{}, r *http.Request) error {
+func GetContentFormat(r *http.Request) string {
+	var (
+		t   string
+		err error
+	)
+
+	contentType := r.Header.Get("Content-type")
+
+	if contentType == "" {
+		return "application/octet-stream"
+	}
 
-	switch r.Header.Get("Content-type") {
+	t, _, err = mime.ParseMediaType(contentType)
+	if err != nil {
+		return ""
+	}
+
+	return contentTypeToFormat[t]
+}
+
+func Decode(dst interface{}, r *http.Request) error {
+	switch GetContentFormat(r) {
 
-	case "application/x-www-form-urlencoded":
+	case "html":
 		if err := r.ParseForm(); err != nil {
 			return err
 		}
@@ -230,7 +256,7 @@ func Decode(dst interface{}, r *http.Request) error {
 		if err := decoder.Decode(dst, r.PostForm); err != nil {
 			return err
 		}
-	case "application/json; charset=utf-8":
+	case "json":
 		decoder := json.NewDecoder(r.Body)
 		err := decoder.Decode(&dst)
 		if err != nil {