Compare commits
2 Commits
bbb0cf3f42
...
70ddd91d6b
| Author | SHA1 | Date | |
|---|---|---|---|
|
70ddd91d6b
|
|||
|
95d945dda7
|
2
do.sh
2
do.sh
@@ -12,7 +12,7 @@ build() {
|
|||||||
|
|
||||||
test() {
|
test() {
|
||||||
echo "I am ${FUNCNAME[0]}ing"
|
echo "I am ${FUNCNAME[0]}ing"
|
||||||
_lint && _vet && _test
|
fmt && _lint && _vet && _test
|
||||||
}
|
}
|
||||||
|
|
||||||
run() {
|
run() {
|
||||||
|
|||||||
@@ -6,14 +6,14 @@ import (
|
|||||||
|
|
||||||
// Action represents a single action item.
|
// Action represents a single action item.
|
||||||
type Action struct {
|
type Action struct {
|
||||||
ActionID int64 `json:"action_id"`
|
ActionID int64 `json:"action_id"`
|
||||||
ActionDescription string `json:"action_description"`
|
ActionDescription string `json:"action_description"`
|
||||||
EstimatedChunks int `json:"estimated_chunks"`
|
EstimatedChunks int `json:"estimated_chunks"`
|
||||||
CompletedChunks int `json:"completed_chunks"`
|
CompletedChunks int `json:"completed_chunks"`
|
||||||
CompletedOn time.Time `json:"completed_on"`
|
CompletedOn *time.Time `json:"completed_on,omitempty"`
|
||||||
PlanID int `json:"plan_id"`
|
PlanID int `json:"plan_id"`
|
||||||
CreatedAt time.Time `json:"created_at"`
|
CreatedAt *time.Time `json:"created_at"`
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
UpdatedAt *time.Time `json:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actions returns all actions from the model.
|
// Actions returns all actions from the model.
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import (
|
|||||||
|
|
||||||
// Plan represents a single day's agenda of actions.
|
// Plan represents a single day's agenda of actions.
|
||||||
type Plan struct {
|
type Plan struct {
|
||||||
PlanID int64 `json:"plan_id"`
|
PlanID int64 `json:"plan_id"`
|
||||||
PlanDate time.Time `json:"plan_date"`
|
PlanDate *time.Time `json:"plan_date"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Plans returns all plans in the model.
|
// Plans returns all plans in the model.
|
||||||
|
|||||||
54
routes/actions.go
Normal file
54
routes/actions.go
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
package routes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"gitea.deepak.science/deepak/gogmagog/models"
|
||||||
|
"github.com/go-chi/chi"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newActionRouter(m *models.Model) http.Handler {
|
||||||
|
router := chi.NewRouter()
|
||||||
|
router.Get("/", getAllActionsFunc(m))
|
||||||
|
router.Get("/{actionid}", getActionByIDFunc(m))
|
||||||
|
return router
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAllActionsFunc(m *models.Model) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
actions, err := m.Actions()
|
||||||
|
if err != nil {
|
||||||
|
serverError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.Header().Add("Content-Type", "application/json")
|
||||||
|
if err := json.NewEncoder(w).Encode(actions); err != nil {
|
||||||
|
serverError(w, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getActionByIDFunc(m *models.Model) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
id, err := strconv.Atoi(chi.URLParam(r, "actionid"))
|
||||||
|
if err != nil {
|
||||||
|
notFoundHandler(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
action, err := m.Action(id)
|
||||||
|
if err != nil {
|
||||||
|
if models.IsNotFoundError(err) {
|
||||||
|
notFoundHandler(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
serverError(w, err)
|
||||||
|
return
|
||||||
|
|
||||||
|
}
|
||||||
|
w.Header().Add("Content-Type", "application/json")
|
||||||
|
if err := json.NewEncoder(w).Encode(action); err != nil {
|
||||||
|
serverError(w, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
228
routes/actions_test.go
Normal file
228
routes/actions_test.go
Normal file
@@ -0,0 +1,228 @@
|
|||||||
|
package routes_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gitea.deepak.science/deepak/gogmagog/models"
|
||||||
|
"gitea.deepak.science/deepak/gogmagog/routes"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestEmptyActions(t *testing.T) {
|
||||||
|
// set up
|
||||||
|
assert := assert.New(t)
|
||||||
|
m := getEmptyModel()
|
||||||
|
router := routes.NewRouter(m)
|
||||||
|
req, _ := http.NewRequest("GET", "/actions", nil)
|
||||||
|
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
|
||||||
|
// function under test
|
||||||
|
router.ServeHTTP(rr, req)
|
||||||
|
|
||||||
|
// check results
|
||||||
|
status := rr.Code
|
||||||
|
assert.Equal(http.StatusOK, status)
|
||||||
|
expected := `[]`
|
||||||
|
|
||||||
|
assert.JSONEq(expected, rr.Body.String())
|
||||||
|
contentType := rr.Header().Get("Content-Type")
|
||||||
|
assert.Equal("application/json", contentType)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOneAction(t *testing.T) {
|
||||||
|
// set up
|
||||||
|
assert := assert.New(t)
|
||||||
|
createdDate, _ := time.Parse("2006-01-02", "2021-01-01")
|
||||||
|
updatedDate, _ := time.Parse("2006-01-02", "2021-01-02")
|
||||||
|
completedDate, _ := time.Parse("2006-01-02", "2021-01-03")
|
||||||
|
a1 := &models.Action{ActionID: 3, ActionDescription: "testing", CompletedChunks: 1, CompletedOn: &completedDate, CreatedAt: &createdDate, UpdatedAt: &updatedDate, EstimatedChunks: 3, PlanID: 0}
|
||||||
|
m := getModel([]*models.Plan{}, []*models.Action{a1})
|
||||||
|
router := routes.NewRouter(m)
|
||||||
|
req, _ := http.NewRequest("GET", "/actions", nil)
|
||||||
|
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
|
||||||
|
// function under test
|
||||||
|
router.ServeHTTP(rr, req)
|
||||||
|
|
||||||
|
// check results
|
||||||
|
status := rr.Code
|
||||||
|
assert.Equal(http.StatusOK, status)
|
||||||
|
// We pass in the date as a time.time so it makes sense that it comes back with a midnight timestamp.
|
||||||
|
expected := `[
|
||||||
|
{
|
||||||
|
"action_id": 3,
|
||||||
|
"action_description": "testing",
|
||||||
|
"estimated_chunks": 3,
|
||||||
|
"completed_chunks": 1,
|
||||||
|
"completed_on": "2021-01-03T00:00:00Z",
|
||||||
|
"updated_at": "2021-01-02T00:00:00Z",
|
||||||
|
"created_at": "2021-01-01T00:00:00Z",
|
||||||
|
"plan_id": 0
|
||||||
|
}
|
||||||
|
]`
|
||||||
|
assert.JSONEq(expected, rr.Body.String())
|
||||||
|
contentType := rr.Header().Get("Content-Type")
|
||||||
|
assert.Equal("application/json", contentType)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestErrorAction(t *testing.T) {
|
||||||
|
// set up
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
m := getErrorModel("Model always errors")
|
||||||
|
|
||||||
|
router := routes.NewRouter(m)
|
||||||
|
req, _ := http.NewRequest("GET", "/actions", nil)
|
||||||
|
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
|
||||||
|
// function under test
|
||||||
|
router.ServeHTTP(rr, req)
|
||||||
|
|
||||||
|
// check results
|
||||||
|
status := rr.Code
|
||||||
|
assert.Equal(http.StatusInternalServerError, status)
|
||||||
|
// We pass in the date as a time.time so it makes sense that it comes back with a midnight timestamp.
|
||||||
|
expected := `Internal Server Error`
|
||||||
|
assert.Equal(expected, strings.TrimSpace(rr.Body.String()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEmptyActionErrorWriter(t *testing.T) {
|
||||||
|
// set up
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
m := getEmptyModel()
|
||||||
|
|
||||||
|
router := routes.NewRouter(m)
|
||||||
|
req, _ := http.NewRequest("GET", "/actions", nil)
|
||||||
|
|
||||||
|
rr := NewBadWriter()
|
||||||
|
|
||||||
|
// function under test
|
||||||
|
router.ServeHTTP(rr, req)
|
||||||
|
|
||||||
|
// check results
|
||||||
|
status := rr.Code
|
||||||
|
assert.Equal(http.StatusInternalServerError, status)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOneActionByID(t *testing.T) {
|
||||||
|
// set up
|
||||||
|
assert := assert.New(t)
|
||||||
|
createdDate, _ := time.Parse("2006-01-02", "2021-01-01")
|
||||||
|
updatedDate, _ := time.Parse("2006-01-02", "2021-01-02")
|
||||||
|
a := &models.Action{ActionID: 6, ActionDescription: "howdy", CompletedOn: nil, CreatedAt: &createdDate, UpdatedAt: &updatedDate, CompletedChunks: 0, EstimatedChunks: 54, PlanID: 3}
|
||||||
|
m := getModel([]*models.Plan{}, []*models.Action{a})
|
||||||
|
router := routes.NewRouter(m)
|
||||||
|
req, _ := http.NewRequest("GET", "/actions/6", nil)
|
||||||
|
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
|
||||||
|
// function under test
|
||||||
|
router.ServeHTTP(rr, req)
|
||||||
|
|
||||||
|
// check results
|
||||||
|
status := rr.Code
|
||||||
|
assert.Equal(http.StatusOK, status)
|
||||||
|
// We pass in the date as a time.time so it makes sense that it comes back with a midnight timestamp.
|
||||||
|
expected := `{
|
||||||
|
"action_id": 6,
|
||||||
|
"action_description": "howdy",
|
||||||
|
"estimated_chunks": 54,
|
||||||
|
"completed_chunks": 0,
|
||||||
|
"updated_at": "2021-01-02T00:00:00Z",
|
||||||
|
"created_at": "2021-01-01T00:00:00Z",
|
||||||
|
"plan_id": 3
|
||||||
|
}`
|
||||||
|
assert.JSONEq(expected, rr.Body.String())
|
||||||
|
contentType := rr.Header().Get("Content-Type")
|
||||||
|
assert.Equal("application/json", contentType)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestErrorActionByID(t *testing.T) {
|
||||||
|
// set up
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
m := getErrorModel("Model always errors")
|
||||||
|
|
||||||
|
router := routes.NewRouter(m)
|
||||||
|
req, _ := http.NewRequest("GET", "/actions/5", nil)
|
||||||
|
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
|
||||||
|
// function under test
|
||||||
|
router.ServeHTTP(rr, req)
|
||||||
|
|
||||||
|
// check results
|
||||||
|
status := rr.Code
|
||||||
|
assert.Equal(http.StatusInternalServerError, status)
|
||||||
|
// We pass in the date as a time.time so it makes sense that it comes back with a midnight timestamp.
|
||||||
|
expected := `Internal Server Error`
|
||||||
|
assert.Equal(expected, strings.TrimSpace(rr.Body.String()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEmptyActionErrorWriterByID(t *testing.T) {
|
||||||
|
// set up
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
a := &models.Action{ActionID: 6}
|
||||||
|
m := getModel([]*models.Plan{}, []*models.Action{a})
|
||||||
|
|
||||||
|
router := routes.NewRouter(m)
|
||||||
|
req, _ := http.NewRequest("GET", "/actions/6", nil)
|
||||||
|
|
||||||
|
rr := NewBadWriter()
|
||||||
|
|
||||||
|
// function under test
|
||||||
|
router.ServeHTTP(rr, req)
|
||||||
|
|
||||||
|
// check results
|
||||||
|
status := rr.Code
|
||||||
|
assert.Equal(http.StatusInternalServerError, status)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNotFoundActionByIDText(t *testing.T) {
|
||||||
|
// set up
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
m := getEmptyModel()
|
||||||
|
|
||||||
|
router := routes.NewRouter(m)
|
||||||
|
req, _ := http.NewRequest("GET", "/actions/wo", nil)
|
||||||
|
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
|
||||||
|
// function under test
|
||||||
|
router.ServeHTTP(rr, req)
|
||||||
|
|
||||||
|
// check results
|
||||||
|
status := rr.Code
|
||||||
|
assert.Equal(http.StatusNotFound, status)
|
||||||
|
|
||||||
|
}
|
||||||
|
func TestNotFoundActionByIDEmpty(t *testing.T) {
|
||||||
|
// set up
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
m := getEmptyModel()
|
||||||
|
|
||||||
|
router := routes.NewRouter(m)
|
||||||
|
req, _ := http.NewRequest("GET", "/actions/1", nil)
|
||||||
|
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
|
||||||
|
// function under test
|
||||||
|
router.ServeHTTP(rr, req)
|
||||||
|
|
||||||
|
// check results
|
||||||
|
status := rr.Code
|
||||||
|
assert.Equal(http.StatusNotFound, status)
|
||||||
|
|
||||||
|
}
|
||||||
@@ -10,3 +10,12 @@ func serverError(w http.ResponseWriter, err error) {
|
|||||||
log.Printf("received error: {%v}", err)
|
log.Printf("received error: {%v}", err)
|
||||||
http.Error(w, http.StatusText(code), code)
|
http.Error(w, http.StatusText(code), code)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func methodNotAllowedHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
code := http.StatusMethodNotAllowed
|
||||||
|
http.Error(w, http.StatusText(code), code)
|
||||||
|
}
|
||||||
|
func notFoundHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
code := http.StatusNotFound
|
||||||
|
http.Error(w, http.StatusText(code), code)
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,11 +5,13 @@ import (
|
|||||||
"gitea.deepak.science/deepak/gogmagog/models"
|
"gitea.deepak.science/deepak/gogmagog/models"
|
||||||
"github.com/go-chi/chi"
|
"github.com/go-chi/chi"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newPlanRouter(m *models.Model) http.Handler {
|
func newPlanRouter(m *models.Model) http.Handler {
|
||||||
router := chi.NewRouter()
|
router := chi.NewRouter()
|
||||||
router.Get("/", getAllPlansFunc(m))
|
router.Get("/", getAllPlansFunc(m))
|
||||||
|
router.Get("/{planid}", getPlanByIDFunc(m))
|
||||||
return router
|
return router
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,3 +28,27 @@ func getAllPlansFunc(m *models.Model) http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getPlanByIDFunc(m *models.Model) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
id, err := strconv.Atoi(chi.URLParam(r, "planid"))
|
||||||
|
if err != nil {
|
||||||
|
notFoundHandler(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
plan, err := m.Plan(id)
|
||||||
|
if err != nil {
|
||||||
|
if models.IsNotFoundError(err) {
|
||||||
|
notFoundHandler(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
serverError(w, err)
|
||||||
|
return
|
||||||
|
|
||||||
|
}
|
||||||
|
w.Header().Add("Content-Type", "application/json")
|
||||||
|
if err := json.NewEncoder(w).Encode(plan); err != nil {
|
||||||
|
serverError(w, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ func TestOnePlan(t *testing.T) {
|
|||||||
// set up
|
// set up
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
planDate, _ := time.Parse("2006-01-02", "2021-01-01")
|
planDate, _ := time.Parse("2006-01-02", "2021-01-01")
|
||||||
p := &models.Plan{PlanID: 6, PlanDate: planDate}
|
p := &models.Plan{PlanID: 6, PlanDate: &planDate}
|
||||||
m := getModel([]*models.Plan{p}, []*models.Action{})
|
m := getModel([]*models.Plan{p}, []*models.Action{})
|
||||||
router := routes.NewRouter(m)
|
router := routes.NewRouter(m)
|
||||||
req, _ := http.NewRequest("GET", "/plans", nil)
|
req, _ := http.NewRequest("GET", "/plans", nil)
|
||||||
@@ -103,3 +103,113 @@ func TestEmptyPlanErrorWriter(t *testing.T) {
|
|||||||
assert.Equal(http.StatusInternalServerError, status)
|
assert.Equal(http.StatusInternalServerError, status)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestOnePlanByID(t *testing.T) {
|
||||||
|
// set up
|
||||||
|
assert := assert.New(t)
|
||||||
|
planDate, _ := time.Parse("2006-01-02", "2021-01-01")
|
||||||
|
p := &models.Plan{PlanID: 6, PlanDate: &planDate}
|
||||||
|
m := getModel([]*models.Plan{p}, []*models.Action{})
|
||||||
|
router := routes.NewRouter(m)
|
||||||
|
req, _ := http.NewRequest("GET", "/plans/6", nil)
|
||||||
|
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
|
||||||
|
// function under test
|
||||||
|
router.ServeHTTP(rr, req)
|
||||||
|
|
||||||
|
// check results
|
||||||
|
status := rr.Code
|
||||||
|
assert.Equal(http.StatusOK, status)
|
||||||
|
// We pass in the date as a time.time so it makes sense that it comes back with a midnight timestamp.
|
||||||
|
expected := `{
|
||||||
|
"plan_id": 6,
|
||||||
|
"plan_date": "2021-01-01T00:00:00Z"
|
||||||
|
}`
|
||||||
|
assert.JSONEq(expected, rr.Body.String())
|
||||||
|
contentType := rr.Header().Get("Content-Type")
|
||||||
|
assert.Equal("application/json", contentType)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestErrorPlanByID(t *testing.T) {
|
||||||
|
// set up
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
m := getErrorModel("Model always errors")
|
||||||
|
|
||||||
|
router := routes.NewRouter(m)
|
||||||
|
req, _ := http.NewRequest("GET", "/plans/5", nil)
|
||||||
|
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
|
||||||
|
// function under test
|
||||||
|
router.ServeHTTP(rr, req)
|
||||||
|
|
||||||
|
// check results
|
||||||
|
status := rr.Code
|
||||||
|
assert.Equal(http.StatusInternalServerError, status)
|
||||||
|
// We pass in the date as a time.time so it makes sense that it comes back with a midnight timestamp.
|
||||||
|
expected := `Internal Server Error`
|
||||||
|
assert.Equal(expected, strings.TrimSpace(rr.Body.String()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEmptyPlanErrorWriterByID(t *testing.T) {
|
||||||
|
// set up
|
||||||
|
assert := assert.New(t)
|
||||||
|
planDate, _ := time.Parse("2006-01-02", "2021-01-01")
|
||||||
|
|
||||||
|
p := &models.Plan{PlanID: 6, PlanDate: &planDate}
|
||||||
|
m := getModel([]*models.Plan{p}, []*models.Action{})
|
||||||
|
|
||||||
|
router := routes.NewRouter(m)
|
||||||
|
req, _ := http.NewRequest("GET", "/plans/6", nil)
|
||||||
|
|
||||||
|
rr := NewBadWriter()
|
||||||
|
|
||||||
|
// function under test
|
||||||
|
router.ServeHTTP(rr, req)
|
||||||
|
|
||||||
|
// check results
|
||||||
|
status := rr.Code
|
||||||
|
assert.Equal(http.StatusInternalServerError, status)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNotFoundPlanByIDText(t *testing.T) {
|
||||||
|
// set up
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
m := getEmptyModel()
|
||||||
|
|
||||||
|
router := routes.NewRouter(m)
|
||||||
|
req, _ := http.NewRequest("GET", "/plans/wo", nil)
|
||||||
|
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
|
||||||
|
// function under test
|
||||||
|
router.ServeHTTP(rr, req)
|
||||||
|
|
||||||
|
// check results
|
||||||
|
status := rr.Code
|
||||||
|
assert.Equal(http.StatusNotFound, status)
|
||||||
|
|
||||||
|
}
|
||||||
|
func TestNotFoundPlanByIDEmpty(t *testing.T) {
|
||||||
|
// set up
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
m := getEmptyModel()
|
||||||
|
|
||||||
|
router := routes.NewRouter(m)
|
||||||
|
req, _ := http.NewRequest("GET", "/plans/1", nil)
|
||||||
|
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
|
||||||
|
// function under test
|
||||||
|
router.ServeHTTP(rr, req)
|
||||||
|
|
||||||
|
// check results
|
||||||
|
status := rr.Code
|
||||||
|
assert.Equal(http.StatusNotFound, status)
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,11 +10,23 @@ type multiStore struct {
|
|||||||
plans []*models.Plan
|
plans []*models.Plan
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type testNotFoundError struct {
|
||||||
|
error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *testNotFoundError) NotFound() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
func (ms *multiStore) SelectActions() ([]*models.Action, error) {
|
func (ms *multiStore) SelectActions() ([]*models.Action, error) {
|
||||||
return ms.actions, nil
|
return ms.actions, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ms *multiStore) SelectActionByID(id int) (*models.Action, error) {
|
func (ms *multiStore) SelectActionByID(id int) (*models.Action, error) {
|
||||||
|
if len(ms.actions) < 1 {
|
||||||
|
err := &testNotFoundError{fmt.Errorf("too small")}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
return ms.actions[0], nil
|
return ms.actions[0], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,6 +35,10 @@ func (ms *multiStore) SelectPlans() ([]*models.Plan, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ms *multiStore) SelectPlanByID(id int) (*models.Plan, error) {
|
func (ms *multiStore) SelectPlanByID(id int) (*models.Plan, error) {
|
||||||
|
if len(ms.plans) < 1 {
|
||||||
|
err := &testNotFoundError{fmt.Errorf("too small")}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
return ms.plans[0], nil
|
return ms.plans[0], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,18 +13,11 @@ func NewRouter(m *models.Model) http.Handler {
|
|||||||
router.MethodNotAllowed(methodNotAllowedHandler)
|
router.MethodNotAllowed(methodNotAllowedHandler)
|
||||||
router.NotFound(notFoundHandler)
|
router.NotFound(notFoundHandler)
|
||||||
router.Mount("/plans", newPlanRouter(m))
|
router.Mount("/plans", newPlanRouter(m))
|
||||||
|
router.Mount("/actions", newActionRouter(m))
|
||||||
router.Mount("/health", newHealthRouter(m))
|
router.Mount("/health", newHealthRouter(m))
|
||||||
router.Get("/ping", ping)
|
router.Get("/ping", ping)
|
||||||
return router
|
return router
|
||||||
}
|
}
|
||||||
func methodNotAllowedHandler(w http.ResponseWriter, r *http.Request) {
|
|
||||||
code := http.StatusMethodNotAllowed
|
|
||||||
http.Error(w, http.StatusText(code), code)
|
|
||||||
}
|
|
||||||
func notFoundHandler(w http.ResponseWriter, r *http.Request) {
|
|
||||||
code := http.StatusNotFound
|
|
||||||
http.Error(w, http.StatusText(code), code)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ping(w http.ResponseWriter, r *http.Request) {
|
func ping(w http.ResponseWriter, r *http.Request) {
|
||||||
// A very simple health check.
|
// A very simple health check.
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ func TestSelectPlans(t *testing.T) {
|
|||||||
assert.Equal(1, len(plans))
|
assert.Equal(1, len(plans))
|
||||||
plan := plans[0]
|
plan := plans[0]
|
||||||
assert.EqualValues(idToUse, plan.PlanID)
|
assert.EqualValues(idToUse, plan.PlanID)
|
||||||
assert.Equal(currentTime, plan.PlanDate)
|
assert.Equal(currentTime, *plan.PlanDate)
|
||||||
|
|
||||||
if err := mock.ExpectationsWereMet(); err != nil {
|
if err := mock.ExpectationsWereMet(); err != nil {
|
||||||
t.Errorf("unfulfilled expectations: %s", err)
|
t.Errorf("unfulfilled expectations: %s", err)
|
||||||
@@ -61,7 +61,7 @@ func TestSelectPlanByID(t *testing.T) {
|
|||||||
plan, err := str.SelectPlanByID(idToUse)
|
plan, err := str.SelectPlanByID(idToUse)
|
||||||
assert.Nil(err)
|
assert.Nil(err)
|
||||||
assert.EqualValues(idToUse, plan.PlanID)
|
assert.EqualValues(idToUse, plan.PlanID)
|
||||||
assert.Equal(currentTime, plan.PlanDate)
|
assert.Equal(currentTime, *plan.PlanDate)
|
||||||
|
|
||||||
if err := mock.ExpectationsWereMet(); err != nil {
|
if err := mock.ExpectationsWereMet(); err != nil {
|
||||||
t.Errorf("unfulfilled expectations: %s", err)
|
t.Errorf("unfulfilled expectations: %s", err)
|
||||||
@@ -74,7 +74,7 @@ func TestInsertPlan(t *testing.T) {
|
|||||||
|
|
||||||
str, mock := getDbMock(t)
|
str, mock := getDbMock(t)
|
||||||
planDate, _ := time.Parse("2006-01-02", "2021-01-01")
|
planDate, _ := time.Parse("2006-01-02", "2021-01-01")
|
||||||
plan := &models.Plan{PlanDate: planDate}
|
plan := &models.Plan{PlanDate: &planDate}
|
||||||
|
|
||||||
idToUse := 8
|
idToUse := 8
|
||||||
|
|
||||||
@@ -103,7 +103,7 @@ func TestInsertPlanErr(t *testing.T) {
|
|||||||
|
|
||||||
str, mock := getDbMock(t)
|
str, mock := getDbMock(t)
|
||||||
planDate, _ := time.Parse("2006-01-02", "2021-01-01")
|
planDate, _ := time.Parse("2006-01-02", "2021-01-01")
|
||||||
plan := &models.Plan{PlanDate: planDate}
|
plan := &models.Plan{PlanDate: &planDate}
|
||||||
|
|
||||||
mock.ExpectBegin()
|
mock.ExpectBegin()
|
||||||
mock.ExpectQuery("^INSERT INTO plans \\(plan_date\\) VALUES \\(\\$1\\) RETURNING plan_id$").
|
mock.ExpectQuery("^INSERT INTO plans \\(plan_date\\) VALUES \\(\\$1\\) RETURNING plan_id$").
|
||||||
@@ -127,7 +127,7 @@ func TestInsertPlanCommitErr(t *testing.T) {
|
|||||||
|
|
||||||
str, mock := getDbMock(t)
|
str, mock := getDbMock(t)
|
||||||
planDate, _ := time.Parse("2006-01-02", "2021-01-01")
|
planDate, _ := time.Parse("2006-01-02", "2021-01-01")
|
||||||
plan := &models.Plan{PlanDate: planDate}
|
plan := &models.Plan{PlanDate: &planDate}
|
||||||
|
|
||||||
idToUse := 8
|
idToUse := 8
|
||||||
|
|
||||||
@@ -205,9 +205,9 @@ func TestSelectActions(t *testing.T) {
|
|||||||
assert.Equal(desc, action.ActionDescription)
|
assert.Equal(desc, action.ActionDescription)
|
||||||
assert.Equal(estChunks, action.EstimatedChunks)
|
assert.Equal(estChunks, action.EstimatedChunks)
|
||||||
assert.Equal(compChunks, action.CompletedChunks)
|
assert.Equal(compChunks, action.CompletedChunks)
|
||||||
assert.Equal(completeTime, action.CompletedOn)
|
assert.Equal(completeTime, *action.CompletedOn)
|
||||||
assert.Equal(createTime, action.CreatedAt)
|
assert.Equal(createTime, *action.CreatedAt)
|
||||||
assert.Equal(updateTime, action.UpdatedAt)
|
assert.Equal(updateTime, *action.UpdatedAt)
|
||||||
assert.Equal(idToUse, action.PlanID)
|
assert.Equal(idToUse, action.PlanID)
|
||||||
|
|
||||||
if err := mock.ExpectationsWereMet(); err != nil {
|
if err := mock.ExpectationsWereMet(); err != nil {
|
||||||
@@ -255,9 +255,9 @@ func TestSelectActionsByPlanID(t *testing.T) {
|
|||||||
assert.Equal(desc, action.ActionDescription)
|
assert.Equal(desc, action.ActionDescription)
|
||||||
assert.Equal(estChunks, action.EstimatedChunks)
|
assert.Equal(estChunks, action.EstimatedChunks)
|
||||||
assert.Equal(compChunks, action.CompletedChunks)
|
assert.Equal(compChunks, action.CompletedChunks)
|
||||||
assert.Equal(completeTime, action.CompletedOn)
|
assert.Equal(completeTime, *action.CompletedOn)
|
||||||
assert.Equal(createTime, action.CreatedAt)
|
assert.Equal(createTime, *action.CreatedAt)
|
||||||
assert.Equal(updateTime, action.UpdatedAt)
|
assert.Equal(updateTime, *action.UpdatedAt)
|
||||||
assert.Equal(idToUse, action.PlanID)
|
assert.Equal(idToUse, action.PlanID)
|
||||||
|
|
||||||
if err := mock.ExpectationsWereMet(); err != nil {
|
if err := mock.ExpectationsWereMet(); err != nil {
|
||||||
@@ -328,9 +328,9 @@ func TestSelectActionById(t *testing.T) {
|
|||||||
assert.Equal(desc, action.ActionDescription)
|
assert.Equal(desc, action.ActionDescription)
|
||||||
assert.Equal(estChunks, action.EstimatedChunks)
|
assert.Equal(estChunks, action.EstimatedChunks)
|
||||||
assert.Equal(compChunks, action.CompletedChunks)
|
assert.Equal(compChunks, action.CompletedChunks)
|
||||||
assert.Equal(completeTime, action.CompletedOn)
|
assert.Equal(completeTime, *action.CompletedOn)
|
||||||
assert.Equal(createTime, action.CreatedAt)
|
assert.Equal(createTime, *action.CreatedAt)
|
||||||
assert.Equal(updateTime, action.UpdatedAt)
|
assert.Equal(updateTime, *action.UpdatedAt)
|
||||||
assert.Equal(idToUse, action.PlanID)
|
assert.Equal(idToUse, action.PlanID)
|
||||||
|
|
||||||
if err := mock.ExpectationsWereMet(); err != nil {
|
if err := mock.ExpectationsWereMet(); err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user