diff --git a/chronograf.go b/chronograf.go index 9d743e97e1..4bf273910c 100644 --- a/chronograf.go +++ b/chronograf.go @@ -29,6 +29,7 @@ const ( ErrAlertNotFound = Error("alert not found") ErrAuthentication = Error("user not authenticated") ErrUninitialized = Error("client uninitialized. Call Open() method") + ErrInvalidAxis = Error("Unexpected axis in cell. Valid axes are 'x', 'y', and 'y2'") ) // Error is a domain error encountered while processing chronograf requests diff --git a/server/cells.go b/server/cells.go index b6a79290b6..f60437c910 100644 --- a/server/cells.go +++ b/server/cells.go @@ -43,9 +43,23 @@ func newCellResponses(dID chronograf.DashboardID, dcells []chronograf.DashboardC return cells } -// ValidDashboardCellRequest verifies that the dashboard cells have a query +// ValidDashboardCellRequest verifies that the dashboard cells have a query and +// have the correct axes specified func ValidDashboardCellRequest(c *chronograf.DashboardCell) error { CorrectWidthHeight(c) + return HasCorrectAxes(c) +} + +// HasCorrectAxes verifies that only permitted axes exist within a DashboardCell +func HasCorrectAxes(c *chronograf.DashboardCell) error { + for axis, _ := range c.Axes { + switch axis { + case "x", "y", "y2": + // no-op + default: + return chronograf.ErrInvalidAxis + } + } return nil } diff --git a/server/cells_test.go b/server/cells_test.go new file mode 100644 index 0000000000..be694b3dff --- /dev/null +++ b/server/cells_test.go @@ -0,0 +1,60 @@ +package server_test + +import ( + "testing" + + "github.com/influxdata/chronograf" + "github.com/influxdata/chronograf/server" +) + +func Test_Cells_CorrectAxis(t *testing.T) { + t.Parallel() + + axisTests := []struct { + name string + cell *chronograf.DashboardCell + shouldFail bool + }{ + { + "correct axes", + &chronograf.DashboardCell{ + Axes: map[string]chronograf.Axis{ + "x": chronograf.Axis{ + Bounds: [2]int64{0, 100}, + }, + "y": chronograf.Axis{ + Bounds: [2]int64{0, 100}, + }, + "y2": chronograf.Axis{ + Bounds: [2]int64{0, 100}, + }, + }, + }, + false, + }, + { + "invalid axes present", + &chronograf.DashboardCell{ + Axes: map[string]chronograf.Axis{ + "axis of evil": chronograf.Axis{ + Bounds: [2]int64{666, 666}, + }, + "axis of awesome": chronograf.Axis{ + Bounds: [2]int64{1337, 31337}, + }, + }, + }, + true, + }, + } + + for _, test := range axisTests { + t.Run(test.name, func(tt *testing.T) { + if err := server.HasCorrectAxes(test.cell); err != nil && !test.shouldFail { + t.Errorf("%q: Unexpected error: err: %s", test.name, err) + } else if err == nil && test.shouldFail { + t.Errorf("%q: Expected error and received none", test.name) + } + }) + } +} diff --git a/server/dashboards_test.go b/server/dashboards_test.go index 613d56d574..b5116913c5 100644 --- a/server/dashboards_test.go +++ b/server/dashboards_test.go @@ -4,6 +4,7 @@ import ( "reflect" "testing" + "github.com/google/go-cmp/cmp" "github.com/influxdata/chronograf" ) @@ -219,6 +220,14 @@ func Test_newDashboardResponse(t *testing.T) { Command: "SELECT donors from hill_valley_preservation_society where time > '1985-10-25 08:00:00'", }, }, + Axes: map[string]chronograf.Axis{ + "x": chronograf.Axis{ + Bounds: [2]int64{0, 100}, + }, + "y": chronograf.Axis{ + Bounds: [2]int64{2, 95}, + }, + }, }, { ID: "b", @@ -257,6 +266,14 @@ func Test_newDashboardResponse(t *testing.T) { }, }, }, + Axes: map[string]chronograf.Axis{ + "x": chronograf.Axis{ + Bounds: [2]int64{0, 100}, + }, + "y": chronograf.Axis{ + Bounds: [2]int64{2, 95}, + }, + }, }, }, dashboardCellResponse{ @@ -301,8 +318,8 @@ func Test_newDashboardResponse(t *testing.T) { }, } for _, tt := range tests { - if got := newDashboardResponse(tt.d); !reflect.DeepEqual(got, tt.want) { - t.Errorf("%q. newDashboardResponse() = \n%#v\n\n, want\n\n%#v", tt.name, got, tt.want) + if got := newDashboardResponse(tt.d); !cmp.Equal(got, tt.want) { + t.Errorf("%q. newDashboardResponse() = diff:\n%s", tt.name, cmp.Diff(got, tt.want)) } } } diff --git a/server/swagger.json b/server/swagger.json index 6a0da5692c..486984cae5 100644 --- a/server/swagger.json +++ b/server/swagger.json @@ -3718,8 +3718,16 @@ "axes": { "description": "The viewport for a cell's visualizations", "type": "object", - "additionalProperties": { - "$ref": "#/definitions/DashboardRange" + "properties": { + "x": { + "$ref": "#/definitions/DashboardRange" + }, + "y": { + "$ref": "#/definitions/DashboardRange" + }, + "y2": { + "$ref": "#/definitions/DashboardRange" + } } }, "type": { @@ -3814,7 +3822,7 @@ "description": "The extents of an axis in the form [lower, upper]. Clients determine whether bounds are to be inclusive or exclusive of their limits", "items": { "type": "integer", - "format": "int32" + "format": "int64" } } }