This PR moves public dashboards into its own self contained service including API, Service, Database, and Models. Routes are mounted on the Grafana HTTPServer by the API service at injection time with wire.go. The main route that loads the frontend for public dashboards is still handled by the API package. Co-authored-by: Jesse Weaver <jesse.weaver@grafana.com> Co-authored-by: Owen Smallwood <owen.smallwood@grafana.com>
304 lines
11 KiB
Go
304 lines
11 KiB
Go
package database
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/grafana/grafana/pkg/components/simplejson"
|
|
"github.com/grafana/grafana/pkg/models"
|
|
dashboards "github.com/grafana/grafana/pkg/services/dashboards"
|
|
dashboardsDB "github.com/grafana/grafana/pkg/services/dashboards/database"
|
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
|
. "github.com/grafana/grafana/pkg/services/publicdashboards/models"
|
|
"github.com/grafana/grafana/pkg/services/sqlstore"
|
|
"github.com/grafana/grafana/pkg/util"
|
|
)
|
|
|
|
// This is what the db sets empty time settings to
|
|
var DefaultTimeSettings, _ = simplejson.NewJson([]byte(`{}`))
|
|
|
|
// Default time to pass in with seconds rounded
|
|
var DefaultTime = time.Now().UTC().Round(time.Second)
|
|
|
|
// GetPublicDashboard
|
|
func TestIntegrationGetPublicDashboard(t *testing.T) {
|
|
var sqlStore *sqlstore.SQLStore
|
|
var dashboardStore *dashboardsDB.DashboardStore
|
|
var publicdashboardStore *PublicDashboardStoreImpl
|
|
var savedDashboard *models.Dashboard
|
|
|
|
setup := func() {
|
|
sqlStore = sqlstore.InitTestDB(t)
|
|
dashboardStore = dashboardsDB.ProvideDashboardStore(sqlStore)
|
|
publicdashboardStore = ProvideStore(sqlStore)
|
|
savedDashboard = insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true)
|
|
}
|
|
|
|
t.Run("returns PublicDashboard and Dashboard", func(t *testing.T) {
|
|
setup()
|
|
pubdash, err := publicdashboardStore.SavePublicDashboardConfig(context.Background(), SavePublicDashboardConfigCommand{
|
|
PublicDashboard: PublicDashboard{
|
|
IsEnabled: true,
|
|
Uid: "abc1234",
|
|
DashboardUid: savedDashboard.Uid,
|
|
OrgId: savedDashboard.OrgId,
|
|
TimeSettings: DefaultTimeSettings,
|
|
CreatedAt: DefaultTime,
|
|
CreatedBy: 7,
|
|
AccessToken: "NOTAREALUUID",
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
pd, d, err := publicdashboardStore.GetPublicDashboard(context.Background(), "NOTAREALUUID")
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, pd, pubdash)
|
|
assert.Equal(t, d.Uid, pubdash.DashboardUid)
|
|
})
|
|
|
|
t.Run("returns ErrPublicDashboardNotFound with empty uid", func(t *testing.T) {
|
|
setup()
|
|
_, _, err := publicdashboardStore.GetPublicDashboard(context.Background(), "")
|
|
require.Error(t, ErrPublicDashboardIdentifierNotSet, err)
|
|
})
|
|
|
|
t.Run("returns ErrPublicDashboardNotFound when PublicDashboard not found", func(t *testing.T) {
|
|
setup()
|
|
_, _, err := publicdashboardStore.GetPublicDashboard(context.Background(), "zzzzzz")
|
|
require.Error(t, ErrPublicDashboardNotFound, err)
|
|
})
|
|
|
|
t.Run("returns ErrDashboardNotFound when Dashboard not found", func(t *testing.T) {
|
|
setup()
|
|
_, err := publicdashboardStore.SavePublicDashboardConfig(context.Background(), SavePublicDashboardConfigCommand{
|
|
DashboardUid: savedDashboard.Uid,
|
|
OrgId: savedDashboard.OrgId,
|
|
PublicDashboard: PublicDashboard{
|
|
IsEnabled: true,
|
|
Uid: "abc1234",
|
|
DashboardUid: "nevergonnafindme",
|
|
OrgId: savedDashboard.OrgId,
|
|
CreatedAt: DefaultTime,
|
|
CreatedBy: 7,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
_, _, err = publicdashboardStore.GetPublicDashboard(context.Background(), "abc1234")
|
|
require.Error(t, dashboards.ErrDashboardNotFound, err)
|
|
})
|
|
}
|
|
|
|
// GetPublicDashboardConfig
|
|
func TestIntegrationGetPublicDashboardConfig(t *testing.T) {
|
|
var sqlStore *sqlstore.SQLStore
|
|
var dashboardStore *dashboardsDB.DashboardStore
|
|
var publicdashboardStore *PublicDashboardStoreImpl
|
|
var savedDashboard *models.Dashboard
|
|
|
|
setup := func() {
|
|
sqlStore = sqlstore.InitTestDB(t)
|
|
dashboardStore = dashboardsDB.ProvideDashboardStore(sqlStore)
|
|
publicdashboardStore = ProvideStore(sqlStore)
|
|
savedDashboard = insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true)
|
|
}
|
|
|
|
t.Run("returns isPublic and set dashboardUid and orgId", func(t *testing.T) {
|
|
setup()
|
|
pubdash, err := publicdashboardStore.GetPublicDashboardConfig(context.Background(), savedDashboard.OrgId, savedDashboard.Uid)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, &PublicDashboard{IsEnabled: false, DashboardUid: savedDashboard.Uid, OrgId: savedDashboard.OrgId}, pubdash)
|
|
})
|
|
|
|
t.Run("returns dashboard errDashboardIdentifierNotSet", func(t *testing.T) {
|
|
setup()
|
|
_, err := publicdashboardStore.GetPublicDashboardConfig(context.Background(), savedDashboard.OrgId, "")
|
|
require.Error(t, dashboards.ErrDashboardIdentifierNotSet, err)
|
|
})
|
|
|
|
t.Run("returns isPublic along with public dashboard when exists", func(t *testing.T) {
|
|
setup()
|
|
// insert test public dashboard
|
|
resp, err := publicdashboardStore.SavePublicDashboardConfig(context.Background(), SavePublicDashboardConfigCommand{
|
|
DashboardUid: savedDashboard.Uid,
|
|
OrgId: savedDashboard.OrgId,
|
|
PublicDashboard: PublicDashboard{
|
|
IsEnabled: true,
|
|
Uid: "pubdash-uid",
|
|
DashboardUid: savedDashboard.Uid,
|
|
OrgId: savedDashboard.OrgId,
|
|
TimeSettings: DefaultTimeSettings,
|
|
CreatedAt: DefaultTime,
|
|
CreatedBy: 7,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
pubdash, err := publicdashboardStore.GetPublicDashboardConfig(context.Background(), savedDashboard.OrgId, savedDashboard.Uid)
|
|
require.NoError(t, err)
|
|
|
|
assert.True(t, assert.ObjectsAreEqualValues(resp, pubdash))
|
|
assert.True(t, assert.ObjectsAreEqual(resp, pubdash))
|
|
})
|
|
}
|
|
|
|
// SavePublicDashboardConfig
|
|
func TestIntegrationSavePublicDashboardConfig(t *testing.T) {
|
|
var sqlStore *sqlstore.SQLStore
|
|
var dashboardStore *dashboardsDB.DashboardStore
|
|
var publicdashboardStore *PublicDashboardStoreImpl
|
|
var savedDashboard *models.Dashboard
|
|
var savedDashboard2 *models.Dashboard
|
|
|
|
setup := func() {
|
|
sqlStore = sqlstore.InitTestDB(t, sqlstore.InitTestDBOpt{FeatureFlags: []string{featuremgmt.FlagPublicDashboards}})
|
|
dashboardStore = dashboardsDB.ProvideDashboardStore(sqlStore)
|
|
publicdashboardStore = ProvideStore(sqlStore)
|
|
savedDashboard = insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true)
|
|
savedDashboard2 = insertTestDashboard(t, dashboardStore, "testDashie2", 1, 0, true)
|
|
}
|
|
|
|
t.Run("saves new public dashboard", func(t *testing.T) {
|
|
setup()
|
|
resp, err := publicdashboardStore.SavePublicDashboardConfig(context.Background(), SavePublicDashboardConfigCommand{
|
|
DashboardUid: savedDashboard.Uid,
|
|
OrgId: savedDashboard.OrgId,
|
|
PublicDashboard: PublicDashboard{
|
|
IsEnabled: true,
|
|
Uid: "pubdash-uid",
|
|
DashboardUid: savedDashboard.Uid,
|
|
OrgId: savedDashboard.OrgId,
|
|
TimeSettings: DefaultTimeSettings,
|
|
CreatedAt: DefaultTime,
|
|
CreatedBy: 7,
|
|
AccessToken: "NOTAREALUUID",
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
pubdash, err := publicdashboardStore.GetPublicDashboardConfig(context.Background(), savedDashboard.OrgId, savedDashboard.Uid)
|
|
require.NoError(t, err)
|
|
|
|
//verify saved response and queried response are the same
|
|
assert.Equal(t, resp, pubdash)
|
|
|
|
// verify we have a valid uid
|
|
assert.True(t, util.IsValidShortUID(pubdash.Uid))
|
|
|
|
// verify we didn't update all dashboards
|
|
pubdash2, err := publicdashboardStore.GetPublicDashboardConfig(context.Background(), savedDashboard2.OrgId, savedDashboard2.Uid)
|
|
require.NoError(t, err)
|
|
assert.False(t, pubdash2.IsEnabled)
|
|
})
|
|
}
|
|
|
|
func TestIntegrationUpdatePublicDashboard(t *testing.T) {
|
|
var sqlStore *sqlstore.SQLStore
|
|
var dashboardStore *dashboardsDB.DashboardStore
|
|
var publicdashboardStore *PublicDashboardStoreImpl
|
|
var savedDashboard *models.Dashboard
|
|
var anotherSavedDashboard *models.Dashboard
|
|
|
|
setup := func() {
|
|
sqlStore = sqlstore.InitTestDB(t, sqlstore.InitTestDBOpt{FeatureFlags: []string{featuremgmt.FlagPublicDashboards}})
|
|
dashboardStore = dashboardsDB.ProvideDashboardStore(sqlStore)
|
|
publicdashboardStore = ProvideStore(sqlStore)
|
|
savedDashboard = insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true)
|
|
anotherSavedDashboard = insertTestDashboard(t, dashboardStore, "test another Dashie", 1, 0, true)
|
|
}
|
|
|
|
t.Run("updates an existing dashboard", func(t *testing.T) {
|
|
setup()
|
|
|
|
pdUid := "asdf1234"
|
|
_, err := publicdashboardStore.SavePublicDashboardConfig(context.Background(), SavePublicDashboardConfigCommand{
|
|
DashboardUid: savedDashboard.Uid,
|
|
OrgId: savedDashboard.OrgId,
|
|
PublicDashboard: PublicDashboard{
|
|
Uid: pdUid,
|
|
DashboardUid: savedDashboard.Uid,
|
|
OrgId: savedDashboard.OrgId,
|
|
IsEnabled: true,
|
|
CreatedAt: DefaultTime,
|
|
CreatedBy: 7,
|
|
AccessToken: "NOTAREALUUID",
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// inserting two different public dashboards to test update works and only affect the desired pd by uid
|
|
anotherPdUid := "anotherUid"
|
|
_, err = publicdashboardStore.SavePublicDashboardConfig(context.Background(), SavePublicDashboardConfigCommand{
|
|
DashboardUid: anotherSavedDashboard.Uid,
|
|
OrgId: anotherSavedDashboard.OrgId,
|
|
PublicDashboard: PublicDashboard{
|
|
Uid: anotherPdUid,
|
|
DashboardUid: anotherSavedDashboard.Uid,
|
|
OrgId: anotherSavedDashboard.OrgId,
|
|
IsEnabled: true,
|
|
CreatedAt: DefaultTime,
|
|
CreatedBy: 7,
|
|
AccessToken: "fakeaccesstoken",
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
updatedPublicDashboard := PublicDashboard{
|
|
Uid: pdUid,
|
|
DashboardUid: savedDashboard.Uid,
|
|
OrgId: savedDashboard.OrgId,
|
|
IsEnabled: false,
|
|
TimeSettings: simplejson.NewFromAny(map[string]interface{}{"from": "now-8", "to": "now"}),
|
|
UpdatedAt: time.Now().UTC().Round(time.Second),
|
|
UpdatedBy: 8,
|
|
}
|
|
// update initial record
|
|
err = publicdashboardStore.UpdatePublicDashboardConfig(context.Background(), SavePublicDashboardConfigCommand{
|
|
DashboardUid: savedDashboard.Uid,
|
|
OrgId: savedDashboard.OrgId,
|
|
PublicDashboard: updatedPublicDashboard,
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// updated dashboard should have changed
|
|
pdRetrieved, err := publicdashboardStore.GetPublicDashboardConfig(context.Background(), savedDashboard.OrgId, savedDashboard.Uid)
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, updatedPublicDashboard.UpdatedAt, pdRetrieved.UpdatedAt)
|
|
// make sure we're correctly updated IsEnabled because we have to call
|
|
// UseBool with xorm
|
|
assert.Equal(t, updatedPublicDashboard.IsEnabled, pdRetrieved.IsEnabled)
|
|
|
|
// not updated dashboard shouldn't have changed
|
|
pdNotUpdatedRetrieved, err := publicdashboardStore.GetPublicDashboardConfig(context.Background(), anotherSavedDashboard.OrgId, anotherSavedDashboard.Uid)
|
|
require.NoError(t, err)
|
|
|
|
assert.NotEqual(t, updatedPublicDashboard.UpdatedAt, pdNotUpdatedRetrieved.UpdatedAt)
|
|
assert.NotEqual(t, updatedPublicDashboard.IsEnabled, pdNotUpdatedRetrieved.IsEnabled)
|
|
})
|
|
}
|
|
func insertTestDashboard(t *testing.T, dashboardStore *dashboardsDB.DashboardStore, title string, orgId int64,
|
|
folderId int64, isFolder bool, tags ...interface{}) *models.Dashboard {
|
|
t.Helper()
|
|
cmd := models.SaveDashboardCommand{
|
|
OrgId: orgId,
|
|
FolderId: folderId,
|
|
IsFolder: isFolder,
|
|
Dashboard: simplejson.NewFromAny(map[string]interface{}{
|
|
"id": nil,
|
|
"title": title,
|
|
"tags": tags,
|
|
}),
|
|
}
|
|
dash, err := dashboardStore.SaveDashboard(cmd)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, dash)
|
|
dash.Data.Set("id", dash.Id)
|
|
dash.Data.Set("uid", dash.Uid)
|
|
return dash
|
|
}
|