Dashboards: Split GetDashboardVersions method (#49967)

* Split GetDashboarVersions method

* Add sqlstore dialect and tests

* Fix signature of PAtchPreference

* Add GetDialect to sqlstore and remove GetDashboardVersions

* Add GetDialect to db interface

* Implement List

* add deleted test function

* Remove GetDialect from sqlstore interface

* Remove deleted method from mock

* Refactor test
This commit is contained in:
idafurjes
2022-06-02 15:59:05 +02:00
committed by GitHub
parent 3e81fa0716
commit bdf50f3dd2
16 changed files with 284 additions and 175 deletions
@@ -20,7 +20,8 @@ type Service struct {
func ProvideService(db db.DB) dashver.Service {
return &Service{
store: &sqlStore{
db: db,
db: db,
dialect: db.GetDialect(),
},
}
}
@@ -63,3 +64,11 @@ func (s *Service) DeleteExpired(ctx context.Context, cmd *dashver.DeleteExpiredV
}
return nil
}
// List all dashboard versions for the given dashboard ID.
func (s *Service) List(ctx context.Context, query *dashver.ListDashboardVersionsQuery) ([]*dashver.DashboardVersionDTO, error) {
if query.Limit == 0 {
query.Limit = 1000
}
return s.store.List(ctx, query)
}
@@ -53,10 +53,24 @@ func TestDeleteExpiredVersions(t *testing.T) {
})
}
func TestListDashboardVersions(t *testing.T) {
dashboardVersionStore := newDashboardVersionStoreFake()
dashboardVersionService := Service{store: dashboardVersionStore}
t.Run("Get all versions for a given Dashboard ID", func(t *testing.T) {
query := dashver.ListDashboardVersionsQuery{}
dashboardVersionStore.ExpectedListVersions = []*dashver.DashboardVersionDTO{{}}
res, err := dashboardVersionService.List(context.Background(), &query)
require.Nil(t, err)
require.Equal(t, 1, len(res))
})
}
type FakeDashboardVersionStore struct {
ExpectedDashboardVersion *dashver.DashboardVersion
ExptectedDeletedVersions int64
ExpectedVersions []interface{}
ExpectedListVersions []*dashver.DashboardVersionDTO
ExpectedError error
}
@@ -75,3 +89,7 @@ func (f *FakeDashboardVersionStore) GetBatch(ctx context.Context, cmd *dashver.D
func (f *FakeDashboardVersionStore) DeleteBatch(ctx context.Context, cmd *dashver.DeleteExpiredVersionsCommand, versionIdsToDelete []interface{}) (int64, error) {
return f.ExptectedDeletedVersions, f.ExpectedError
}
func (f *FakeDashboardVersionStore) List(ctx context.Context, query *dashver.ListDashboardVersionsQuery) ([]*dashver.DashboardVersionDTO, error) {
return f.ExpectedListVersions, f.ExpectedError
}
@@ -7,16 +7,19 @@ import (
dashver "github.com/grafana/grafana/pkg/services/dashboardversion"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/db"
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
)
type store interface {
Get(context.Context, *dashver.GetDashboardVersionQuery) (*dashver.DashboardVersion, error)
GetBatch(context.Context, *dashver.DeleteExpiredVersionsCommand, int, int) ([]interface{}, error)
DeleteBatch(context.Context, *dashver.DeleteExpiredVersionsCommand, []interface{}) (int64, error)
List(context.Context, *dashver.ListDashboardVersionsQuery) ([]*dashver.DashboardVersionDTO, error)
}
type sqlStore struct {
db db.DB
db db.DB
dialect migrator.Dialect
}
func (ss *sqlStore) Get(ctx context.Context, query *dashver.GetDashboardVersionQuery) (*dashver.DashboardVersion, error) {
@@ -75,3 +78,38 @@ func (ss *sqlStore) DeleteBatch(ctx context.Context, cmd *dashver.DeleteExpiredV
})
return deleted, err
}
func (ss *sqlStore) List(ctx context.Context, query *dashver.ListDashboardVersionsQuery) ([]*dashver.DashboardVersionDTO, error) {
var dashboardVersion []*dashver.DashboardVersionDTO
err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
err := sess.Table("dashboard_version").
Select(`dashboard_version.id,
dashboard_version.dashboard_id,
dashboard_version.parent_version,
dashboard_version.restored_from,
dashboard_version.version,
dashboard_version.created,
dashboard_version.created_by as created_by_id,
dashboard_version.message,
dashboard_version.data,`+
ss.dialect.Quote("user")+`.login as created_by`).
Join("LEFT", ss.dialect.Quote("user"), `dashboard_version.created_by = `+ss.dialect.Quote("user")+`.id`).
Join("LEFT", "dashboard", `dashboard.id = dashboard_version.dashboard_id`).
Where("dashboard_version.dashboard_id=? AND dashboard.org_id=?", query.DashboardID, query.OrgID).
OrderBy("dashboard_version.version DESC").
Limit(query.Limit, query.Start).
Find(&dashboardVersion)
if err != nil {
return err
}
if len(dashboardVersion) < 1 {
return dashver.ErrNoVersionsForDashboardID
}
return nil
})
if err != nil {
return nil, err
}
return dashboardVersion, nil
}
@@ -30,8 +30,8 @@ func TestIntegrationGetDashboardVersion(t *testing.T) {
res, err := dashVerStore.Get(context.Background(), &query)
require.Nil(t, err)
require.Equal(t, query.DashboardID, savedDash.Id)
require.Equal(t, query.Version, savedDash.Version)
assert.Equal(t, query.DashboardID, savedDash.Id)
assert.Equal(t, query.Version, savedDash.Version)
dashCmd := &models.Dashboard{
Id: res.ID,
@@ -41,8 +41,8 @@ func TestIntegrationGetDashboardVersion(t *testing.T) {
err = getDashboard(t, ss, dashCmd)
require.Nil(t, err)
require.EqualValues(t, dashCmd.Data.Get("uid"), res.Data.Get("uid"))
require.EqualValues(t, dashCmd.Data.Get("orgId"), res.Data.Get("orgId"))
assert.EqualValues(t, dashCmd.Data.Get("uid"), res.Data.Get("uid"))
assert.EqualValues(t, dashCmd.Data.Get("orgId"), res.Data.Get("orgId"))
})
t.Run("Attempt to get a version that doesn't exist", func(t *testing.T) {
@@ -54,7 +54,7 @@ func TestIntegrationGetDashboardVersion(t *testing.T) {
_, err := dashVerStore.Get(context.Background(), &query)
require.Error(t, err)
require.Equal(t, models.ErrDashboardVersionNotFound, err)
assert.Equal(t, models.ErrDashboardVersionNotFound, err)
})
}
@@ -79,6 +79,44 @@ func TestIntegrationDeleteExpiredVersions(t *testing.T) {
})
}
func TestIntegrationListDashboardVersions(t *testing.T) {
ss := sqlstore.InitTestDB(t)
dashVerStore := sqlStore{db: ss, dialect: ss.Dialect}
savedDash := insertTestDashboard(t, ss, "test dash 43", 1, 0, false, "diff-all")
t.Run("Get all versions for a given Dashboard ID", func(t *testing.T) {
query := dashver.ListDashboardVersionsQuery{
DashboardID: savedDash.Id,
OrgID: 1,
Limit: 1000,
}
res, err := dashVerStore.List(context.Background(), &query)
require.Nil(t, err)
assert.Equal(t, 1, len(res))
})
t.Run("Attempt to get the versions for a non-existent Dashboard ID", func(t *testing.T) {
query := dashver.ListDashboardVersionsQuery{DashboardID: int64(999), OrgID: 1, Limit: 1000}
res, err := dashVerStore.List(context.Background(), &query)
require.Error(t, err)
assert.ErrorIs(t, dashver.ErrNoVersionsForDashboardID, err)
assert.Equal(t, 0, len(res))
})
t.Run("Get all versions for an updated dashboard", func(t *testing.T) {
updateTestDashboard(t, ss, savedDash, map[string]interface{}{
"tags": "different-tag",
})
query := dashver.ListDashboardVersionsQuery{DashboardID: savedDash.Id, OrgID: 1, Limit: 1000}
res, err := dashVerStore.List(context.Background(), &query)
require.Nil(t, err)
assert.Equal(t, 2, len(res))
})
}
func getDashboard(t *testing.T, sqlStore *sqlstore.SQLStore, dashboard *models.Dashboard) error {
t.Helper()
return sqlStore.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
@@ -95,6 +133,7 @@ func getDashboard(t *testing.T, sqlStore *sqlstore.SQLStore, dashboard *models.D
return nil
})
}
func insertTestDashboard(t *testing.T, sqlStore *sqlstore.SQLStore, title string, orgId int64,
folderId int64, isFolder bool, tags ...interface{}) *models.Dashboard {
t.Helper()
@@ -149,3 +188,64 @@ func insertTestDashboard(t *testing.T, sqlStore *sqlstore.SQLStore, title string
return dash
}
func updateTestDashboard(t *testing.T, sqlStore *sqlstore.SQLStore, dashboard *models.Dashboard, data map[string]interface{}) {
t.Helper()
data["id"] = dashboard.Id
parentVersion := dashboard.Version
cmd := models.SaveDashboardCommand{
OrgId: dashboard.OrgId,
Overwrite: true,
Dashboard: simplejson.NewFromAny(data),
}
var dash *models.Dashboard
err := sqlStore.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
var existing models.Dashboard
dash = cmd.GetDashboardModel()
dashWithIdExists, err := sess.Where("id=? AND org_id=?", dash.Id, dash.OrgId).Get(&existing)
require.NoError(t, err)
require.True(t, dashWithIdExists)
if dash.Version != existing.Version {
dash.SetVersion(existing.Version)
dash.Version = existing.Version
}
dash.SetVersion(dash.Version + 1)
dash.Created = time.Now()
dash.Updated = time.Now()
dash.Id = dashboard.Id
dash.Uid = util.GenerateShortUID()
_, err = sess.MustCols("folder_id").ID(dash.Id).Update(dash)
return err
})
require.Nil(t, err)
err = sqlStore.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
dashVersion := &models.DashboardVersion{
DashboardId: dash.Id,
ParentVersion: parentVersion,
RestoredFrom: cmd.RestoredFrom,
Version: dash.Version,
Created: time.Now(),
CreatedBy: dash.UpdatedBy,
Message: cmd.Message,
Data: dash.Data,
}
if affectedRows, err := sess.Insert(dashVersion); err != nil {
return err
} else if affectedRows == 0 {
return models.ErrDashboardNotFound
}
return nil
})
require.NoError(t, err)
}