Commit 0e3f9150 by Torkel Ödegaard

Added validation to stop duplicate dashboards with same name from being saved

parent 4131b755
Subproject commit 344812f1e0f0e804f9e9dd425168069d63c3fae3 Subproject commit 34427f34e89fe3913523b5b236a149b88931b71d
...@@ -69,6 +69,10 @@ func PostDashboard(c *middleware.Context) { ...@@ -69,6 +69,10 @@ func PostDashboard(c *middleware.Context) {
err := bus.Dispatch(&cmd) err := bus.Dispatch(&cmd)
if err != nil { if err != nil {
if err == m.ErrDashboardWithSameNameExists {
c.JsonApiErr(400, "Dashboard with the same title already exists", nil)
return
}
c.JsonApiErr(500, "Failed to save dashboard", err) c.JsonApiErr(500, "Failed to save dashboard", err)
return return
} }
......
...@@ -10,6 +10,7 @@ import ( ...@@ -10,6 +10,7 @@ import (
// Typed errors // Typed errors
var ( var (
ErrDashboardNotFound = errors.New("Account not found") ErrDashboardNotFound = errors.New("Account not found")
ErrDashboardWithSameNameExists = errors.New("A dashboard with the same name already exists")
) )
type Dashboard struct { type Dashboard struct {
...@@ -39,8 +40,6 @@ type SearchDashboardsQuery struct { ...@@ -39,8 +40,6 @@ type SearchDashboardsQuery struct {
} }
type SaveDashboardCommand struct { type SaveDashboardCommand struct {
Id string `json:"id"`
Title string `json:"title"`
Dashboard map[string]interface{} `json:"dashboard"` Dashboard map[string]interface{} `json:"dashboard"`
AccountId int64 `json:"-"` AccountId int64 `json:"-"`
......
...@@ -17,7 +17,17 @@ func SaveDashboard(cmd *m.SaveDashboardCommand) error { ...@@ -17,7 +17,17 @@ func SaveDashboard(cmd *m.SaveDashboardCommand) error {
return inTransaction(func(sess *xorm.Session) error { return inTransaction(func(sess *xorm.Session) error {
dash := cmd.GetDashboardModel() dash := cmd.GetDashboardModel()
var err error // try get existing dashboard
existing := m.Dashboard{Slug: dash.Slug, AccountId: dash.AccountId}
hasExisting, err := sess.Get(&existing)
if err != nil {
return err
}
if hasExisting && dash.Id != existing.Id {
return m.ErrDashboardWithSameNameExists
}
if dash.Id == 0 { if dash.Id == 0 {
_, err = sess.Insert(dash) _, err = sess.Insert(dash)
} else { } else {
......
package sqlstore
import (
"testing"
. "github.com/smartystreets/goconvey/convey"
m "github.com/torkelo/grafana-pro/pkg/models"
)
func TestDashboardDataAccess(t *testing.T) {
Convey("Testing DB", t, func() {
InitTestDB(t)
Convey("Given saved dashboard", func() {
var savedDash *m.Dashboard
cmd := m.SaveDashboardCommand{
AccountId: 1,
Dashboard: map[string]interface{}{
"id": nil,
"title": "test dash 23",
"tags": make([]interface{}, 0),
},
}
err := SaveDashboard(&cmd)
So(err, ShouldBeNil)
savedDash = cmd.Result
Convey("Should return dashboard model", func() {
So(savedDash.Title, ShouldEqual, "test dash 23")
So(savedDash.Slug, ShouldEqual, "test-dash-23")
So(savedDash.Id, ShouldNotEqual, 0)
})
Convey("Should be able to get dashboard", func() {
query := m.GetDashboardQuery{
Slug: "test-dash-23",
AccountId: 1,
}
err := GetDashboard(&query)
So(err, ShouldBeNil)
So(query.Result.Title, ShouldEqual, "test dash 23")
So(query.Result.Slug, ShouldEqual, "test-dash-23")
})
Convey("Should not be able to save dashboard with same name", func() {
cmd := m.SaveDashboardCommand{
AccountId: 1,
Dashboard: map[string]interface{}{
"id": nil,
"title": "test dash 23",
"tags": make([]interface{}, 0),
},
}
err := SaveDashboard(&cmd)
So(err, ShouldNotBeNil)
})
})
})
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment