226 lines
5.7 KiB
Go
226 lines
5.7 KiB
Go
package transport
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"github.com/golang/mock/gomock"
|
|
"github.com/influxdata/influxdb/v2"
|
|
"github.com/influxdata/influxdb/v2/kit/platform"
|
|
"github.com/influxdata/influxdb/v2/mock"
|
|
"github.com/stretchr/testify/require"
|
|
"go.uber.org/zap/zaptest"
|
|
)
|
|
|
|
var (
|
|
orgStr = "1234123412341234"
|
|
orgID, _ = platform.IDFromString(orgStr)
|
|
idStr = "4321432143214321"
|
|
id, _ = platform.IDFromString(idStr)
|
|
testNotebook = &influxdb.Notebook{
|
|
OrgID: *orgID,
|
|
ID: *id,
|
|
Name: "test notebook",
|
|
Spec: influxdb.NotebookSpec{
|
|
"hello": "goodbye",
|
|
},
|
|
}
|
|
testReqBody = &influxdb.NotebookReqBody{
|
|
OrgID: *orgID,
|
|
Name: "Test notebook",
|
|
Spec: influxdb.NotebookSpec{
|
|
"hello": "goodbye",
|
|
},
|
|
}
|
|
)
|
|
|
|
func TestNotebookHandler(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
t.Run("get notebooks happy path", func(t *testing.T) {
|
|
ts, svc := newTestServer(t)
|
|
defer ts.Close()
|
|
|
|
req := newTestRequest(t, "GET", ts.URL, nil)
|
|
|
|
q := req.URL.Query()
|
|
q.Add("orgID", orgStr)
|
|
req.URL.RawQuery = q.Encode()
|
|
|
|
svc.EXPECT().
|
|
ListNotebooks(gomock.Any(), influxdb.NotebookListFilter{OrgID: *orgID}).
|
|
Return([]*influxdb.Notebook{testNotebook}, nil)
|
|
|
|
res := doTestRequest(t, req, http.StatusOK, true)
|
|
|
|
got := map[string][]*influxdb.Notebook{}
|
|
err := json.NewDecoder(res.Body).Decode(&got)
|
|
require.NoError(t, err)
|
|
require.Equal(t, got[allNotebooksJSONKey], []*influxdb.Notebook{testNotebook})
|
|
})
|
|
|
|
t.Run("create notebook happy path", func(t *testing.T) {
|
|
ts, svc := newTestServer(t)
|
|
defer ts.Close()
|
|
|
|
req := newTestRequest(t, "POST", ts.URL, testReqBody)
|
|
|
|
svc.EXPECT().
|
|
CreateNotebook(gomock.Any(), testReqBody).
|
|
Return(testNotebook, nil)
|
|
|
|
res := doTestRequest(t, req, http.StatusOK, true)
|
|
|
|
got := &influxdb.Notebook{}
|
|
err := json.NewDecoder(res.Body).Decode(got)
|
|
require.NoError(t, err)
|
|
require.Equal(t, got, testNotebook)
|
|
})
|
|
|
|
t.Run("get notebook happy path", func(t *testing.T) {
|
|
ts, svc := newTestServer(t)
|
|
defer ts.Close()
|
|
|
|
req := newTestRequest(t, "GET", ts.URL+"/"+idStr, nil)
|
|
|
|
svc.EXPECT().
|
|
GetNotebook(gomock.Any(), *id).
|
|
Return(testNotebook, nil)
|
|
|
|
res := doTestRequest(t, req, http.StatusOK, true)
|
|
|
|
got := &influxdb.Notebook{}
|
|
err := json.NewDecoder(res.Body).Decode(got)
|
|
require.NoError(t, err)
|
|
require.Equal(t, got, testNotebook)
|
|
})
|
|
|
|
t.Run("delete notebook happy path", func(t *testing.T) {
|
|
ts, svc := newTestServer(t)
|
|
defer ts.Close()
|
|
|
|
req := newTestRequest(t, "DELETE", ts.URL+"/"+idStr, nil)
|
|
|
|
svc.EXPECT().
|
|
DeleteNotebook(gomock.Any(), *id).
|
|
Return(nil)
|
|
|
|
doTestRequest(t, req, http.StatusNoContent, false)
|
|
})
|
|
|
|
t.Run("update notebook happy path", func(t *testing.T) {
|
|
ts, svc := newTestServer(t)
|
|
defer ts.Close()
|
|
|
|
req := newTestRequest(t, "PUT", ts.URL+"/"+idStr, testReqBody)
|
|
|
|
svc.EXPECT().
|
|
UpdateNotebook(gomock.Any(), *id, testReqBody).
|
|
Return(testNotebook, nil)
|
|
|
|
res := doTestRequest(t, req, http.StatusOK, true)
|
|
|
|
got := &influxdb.Notebook{}
|
|
err := json.NewDecoder(res.Body).Decode(got)
|
|
require.NoError(t, err)
|
|
require.Equal(t, got, testNotebook)
|
|
})
|
|
|
|
t.Run("invalid notebook ids return 400", func(t *testing.T) {
|
|
methodsWithBody := []string{"PATCH", "PUT"}
|
|
methodsNoBody := []string{"GET", "DELETE"}
|
|
|
|
for _, m := range methodsWithBody {
|
|
t.Run(m+" /notebooks", func(t *testing.T) {
|
|
ts, _ := newTestServer(t)
|
|
defer ts.Close()
|
|
|
|
req := newTestRequest(t, m, ts.URL+"/badid", testReqBody)
|
|
doTestRequest(t, req, http.StatusBadRequest, false)
|
|
})
|
|
}
|
|
|
|
for _, m := range methodsNoBody {
|
|
t.Run(m+" /notebooks", func(t *testing.T) {
|
|
ts, _ := newTestServer(t)
|
|
defer ts.Close()
|
|
|
|
req := newTestRequest(t, m, ts.URL+"/badid", nil)
|
|
doTestRequest(t, req, http.StatusBadRequest, false)
|
|
})
|
|
}
|
|
})
|
|
|
|
t.Run("invalid org id to GET /notebooks returns 400", func(t *testing.T) {
|
|
ts, _ := newTestServer(t)
|
|
defer ts.Close()
|
|
|
|
req := newTestRequest(t, "GET", ts.URL, nil)
|
|
|
|
q := req.URL.Query()
|
|
q.Add("orgID", "badid")
|
|
req.URL.RawQuery = q.Encode()
|
|
|
|
doTestRequest(t, req, http.StatusBadRequest, false)
|
|
})
|
|
|
|
t.Run("invalid request body returns 400", func(t *testing.T) {
|
|
badBady := &influxdb.NotebookReqBody{
|
|
OrgID: *orgID,
|
|
}
|
|
|
|
methods := []string{"PUT", "PATCH"}
|
|
for _, m := range methods {
|
|
t.Run(m+"/notebooks/{id]", func(t *testing.T) {
|
|
ts, _ := newTestServer(t)
|
|
defer ts.Close()
|
|
|
|
req := newTestRequest(t, m, ts.URL+"/"+idStr, badBady)
|
|
doTestRequest(t, req, http.StatusBadRequest, false)
|
|
})
|
|
}
|
|
|
|
t.Run("POST /notebooks", func(t *testing.T) {
|
|
ts, _ := newTestServer(t)
|
|
defer ts.Close()
|
|
|
|
req := newTestRequest(t, "POST", ts.URL+"/", badBady)
|
|
doTestRequest(t, req, http.StatusBadRequest, false)
|
|
})
|
|
})
|
|
}
|
|
|
|
// The svc generated is returned so that the caller can specify the expected
|
|
// use of the mock service.
|
|
func newTestServer(t *testing.T) (*httptest.Server, *mock.MockNotebookService) {
|
|
ctrlr := gomock.NewController(t)
|
|
svc := mock.NewMockNotebookService(ctrlr)
|
|
server := NewNotebookHandler(zaptest.NewLogger(t), svc)
|
|
return httptest.NewServer(server), svc
|
|
}
|
|
|
|
func newTestRequest(t *testing.T, method, path string, body interface{}) *http.Request {
|
|
dat, err := json.Marshal(body)
|
|
require.NoError(t, err)
|
|
|
|
req, err := http.NewRequest(method, path, bytes.NewBuffer(dat))
|
|
require.NoError(t, err)
|
|
|
|
req.Header.Add("Content-Type", "application/json")
|
|
|
|
return req
|
|
}
|
|
|
|
func doTestRequest(t *testing.T, req *http.Request, wantCode int, needJSON bool) *http.Response {
|
|
res, err := http.DefaultClient.Do(req)
|
|
require.NoError(t, err)
|
|
require.Equal(t, wantCode, res.StatusCode)
|
|
if needJSON {
|
|
require.Equal(t, "application/json; charset=utf-8", res.Header.Get("Content-Type"))
|
|
}
|
|
return res
|
|
}
|