Skip to content

Commit

Permalink
feat: adds properties to each cell on GET /dashboards/:dashboardID
Browse files Browse the repository at this point in the history
  • Loading branch information
dearyhud committed Nov 27, 2019
1 parent 380b411 commit f6e6a7b
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 22 deletions.
28 changes: 24 additions & 4 deletions dashboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,26 @@ func SortDashboards(opts FindOptions, ds []*Dashboard) {
type Cell struct {
ID ID `json:"id,omitempty"`
CellProperty
View *View `json:"-"`
}

// Marshals the cell
func (cell *Cell) MarshalJSON() ([]byte, error) {
type resp struct {
ID ID `json:"id,omitempty"`
CellProperty
ViewProperties ViewProperties `json:"properties,omitempty"`
}

response := resp{
ID: cell.ID,
CellProperty: cell.CellProperty,
}

if cell.View != nil {
response.ViewProperties = cell.View.Properties
}
return json.Marshal(response)
}

// CellProperty contains the properties of a cell.
Expand Down Expand Up @@ -550,8 +570,8 @@ func MarshalViewPropertiesJSON(v ViewProperties) ([]byte, error) {
}

// MarshalJSON encodes a view to JSON bytes.
func (c View) MarshalJSON() ([]byte, error) {
vis, err := MarshalViewPropertiesJSON(c.Properties)
func (v View) MarshalJSON() ([]byte, error) {
viewProperties, err := MarshalViewPropertiesJSON(v.Properties)
if err != nil {
return nil, err
}
Expand All @@ -560,8 +580,8 @@ func (c View) MarshalJSON() ([]byte, error) {
ViewContents
ViewProperties json.RawMessage `json:"properties"`
}{
ViewContents: c.ViewContents,
ViewProperties: vis,
ViewContents: v.ViewContents,
ViewProperties: viewProperties,
})
}

Expand Down
21 changes: 21 additions & 0 deletions http/dashboard_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -472,12 +472,33 @@ func (h *DashboardHandler) handleGetDashboard(w http.ResponseWriter, r *http.Req
return
}

include := r.URL.Query().Get("include")
var showViewProperties bool

if include == "properties" {
showViewProperties = true
}

dashboard, err := h.DashboardService.FindDashboardByID(ctx, req.DashboardID)
if err != nil {
h.HandleHTTPError(ctx, err, w)
return
}

if showViewProperties {
for _, c := range dashboard.Cells {
view, err := h.DashboardService.GetDashboardCellView(ctx, dashboard.ID, c.ID)
if err != nil {
h.HandleHTTPError(ctx, err, w)
return
}

if view != nil {
c.View = view
}
}
}

labels, err := h.LabelService.FindResourceLabels(ctx, platform.LabelMappingFilter{ResourceID: dashboard.ID})
if err != nil {
h.HandleHTTPError(ctx, err, w)
Expand Down
133 changes: 115 additions & 18 deletions http/dashboard_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ import (
"go.uber.org/zap"

"github.com/google/go-cmp/cmp"
"github.com/influxdata/httprouter"
platform "github.com/influxdata/influxdb"
"github.com/influxdata/influxdb/inmem"
"github.com/influxdata/influxdb/mock"
platformtesting "github.com/influxdata/influxdb/testing"
"github.com/influxdata/httprouter"
"github.com/yudai/gojsondiff"
"github.com/yudai/gojsondiff/formatter"
)
Expand Down Expand Up @@ -375,24 +375,27 @@ func TestService_handleGetDashboard(t *testing.T) {
DashboardService platform.DashboardService
}
type args struct {
id string
id string
queryString map[string]string
}
type wants struct {
statusCode int
contentType string
body string
}

tests := []struct {
name string
fields fields
args args
wants wants
}{
{
name: "get a dashboard by id",
name: "get a dashboard by id with view properties",
fields: fields{
&mock.DashboardService{
GetDashboardCellViewF: func(ctx context.Context, dashboardID platform.ID, cellID platform.ID) (*platform.View, error) {
return &platform.View{Properties: platform.XYViewProperties{Type: platform.ViewPropertyTypeXY}}, nil
},
FindDashboardByIDF: func(ctx context.Context, id platform.ID) (*platform.Dashboard, error) {
if id == platformtesting.MustIDBase16("020f755c3c082000") {
return &platform.Dashboard{
Expand Down Expand Up @@ -423,6 +426,9 @@ func TestService_handleGetDashboard(t *testing.T) {
},
args: args{
id: "020f755c3c082000",
queryString: map[string]string{
"include": "properties",
},
},
wants: wants{
statusCode: http.StatusOK,
Expand All @@ -444,26 +450,110 @@ func TestService_handleGetDashboard(t *testing.T) {
"x": 1,
"y": 2,
"w": 3,
"h": 4,
"links": {
"self": "/api/v2/dashboards/020f755c3c082000/cells/da7aba5e5d81e550",
"view": "/api/v2/dashboards/020f755c3c082000/cells/da7aba5e5d81e550/view"
}
"h": 4,
"properties": {
"axes": null,
"colors": null,
"geom": "",
"legend": {},
"note": "",
"queries": null,
"shadeBelow": false,
"showNoteWhenEmpty": false,
"type": "xy",
"xColumn": "",
"yColumn": ""
}
}
],
"links": {
"self": "/api/v2/dashboards/020f755c3c082000",
"org": "/api/v2/orgs/0000000000000001",
"members": "/api/v2/dashboards/020f755c3c082000/members",
"owners": "/api/v2/dashboards/020f755c3c082000/owners",
"logs": "/api/v2/dashboards/020f755c3c082000/logs",
"cells": "/api/v2/dashboards/020f755c3c082000/cells",
"labels": "/api/v2/dashboards/020f755c3c082000/labels"
}
"self": "/api/v2/dashboards/020f755c3c082000",
"org": "/api/v2/orgs/0000000000000001",
"members": "/api/v2/dashboards/020f755c3c082000/members",
"owners": "/api/v2/dashboards/020f755c3c082000/owners",
"logs": "/api/v2/dashboards/020f755c3c082000/logs",
"cells": "/api/v2/dashboards/020f755c3c082000/cells",
"labels": "/api/v2/dashboards/020f755c3c082000/labels"
}
}
`,
},
},
{
name: "get a dashboard by id",
fields: fields{
&mock.DashboardService{
FindDashboardByIDF: func(ctx context.Context, id platform.ID) (*platform.Dashboard, error) {
if id == platformtesting.MustIDBase16("020f755c3c082000") {
return &platform.Dashboard{
ID: platformtesting.MustIDBase16("020f755c3c082000"),
OrganizationID: 1,
Meta: platform.DashboardMeta{
CreatedAt: time.Date(2012, time.November, 10, 23, 0, 0, 0, time.UTC),
UpdatedAt: time.Date(2012, time.November, 10, 24, 0, 0, 0, time.UTC),
},
Name: "hello",
Cells: []*platform.Cell{
{
ID: platformtesting.MustIDBase16("da7aba5e5d81e550"),
CellProperty: platform.CellProperty{
X: 1,
Y: 2,
W: 3,
H: 4,
},
},
},
}, nil
}

return nil, fmt.Errorf("not found")
},
},
},
args: args{
id: "020f755c3c082000",
},
wants: wants{
statusCode: http.StatusOK,
contentType: "application/json; charset=utf-8",
body: `
{
"id": "020f755c3c082000",
"orgID": "0000000000000001",
"name": "hello",
"description": "",
"labels": [],
"meta": {
"createdAt": "2012-11-10T23:00:00Z",
"updatedAt": "2012-11-11T00:00:00Z"
},
"cells": [
{
"id": "da7aba5e5d81e550",
"x": 1,
"y": 2,
"w": 3,
"h": 4,
"links": {
"self": "/api/v2/dashboards/020f755c3c082000/cells/da7aba5e5d81e550",
"view": "/api/v2/dashboards/020f755c3c082000/cells/da7aba5e5d81e550/view"
}
}
],
"links": {
"self": "/api/v2/dashboards/020f755c3c082000",
"org": "/api/v2/orgs/0000000000000001",
"members": "/api/v2/dashboards/020f755c3c082000/members",
"owners": "/api/v2/dashboards/020f755c3c082000/owners",
"logs": "/api/v2/dashboards/020f755c3c082000/logs",
"cells": "/api/v2/dashboards/020f755c3c082000/cells",
"labels": "/api/v2/dashboards/020f755c3c082000/labels"
}
}
`,
},
},
{
name: "not found",
fields: fields{
Expand Down Expand Up @@ -494,6 +584,14 @@ func TestService_handleGetDashboard(t *testing.T) {

r := httptest.NewRequest("GET", "http://any.url", nil)

urlQuery := r.URL.Query()

for k, v := range tt.args.queryString {
urlQuery.Add(k, v)
}

r.URL.RawQuery = urlQuery.Encode()

r = r.WithContext(context.WithValue(
context.Background(),
httprouter.ParamsKey,
Expand All @@ -511,7 +609,6 @@ func TestService_handleGetDashboard(t *testing.T) {
res := w.Result()
content := res.Header.Get("Content-Type")
body, _ := ioutil.ReadAll(res.Body)

if res.StatusCode != tt.wants.statusCode {
t.Errorf("%q. handleGetDashboard() = %v, want %v", tt.name, res.StatusCode, tt.wants.statusCode)
}
Expand Down

0 comments on commit f6e6a7b

Please sign in to comment.