Folders: Export folder store implementation (#93897)

* Export folder store implementation

* Rename folder store

* Add folder store as a parameter to folder service

* Add folder store to dash service implementation

* Fix folder store comments
This commit is contained in:
Arati R. 2024-09-30 10:28:47 +02:00 committed by GitHub
parent daf9273cd1
commit ed75aea21d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
24 changed files with 226 additions and 187 deletions

View File

@ -833,20 +833,22 @@ func getDashboardShouldReturn200WithConfig(t *testing.T, sc *scenarioContext, pr
folderPermissions := accesscontrolmock.NewMockedPermissionsService() folderPermissions := accesscontrolmock.NewMockedPermissionsService()
dashboardPermissions := accesscontrolmock.NewMockedPermissionsService() dashboardPermissions := accesscontrolmock.NewMockedPermissionsService()
folderSvc := folderimpl.ProvideService(ac, bus.ProvideBus(tracing.InitializeTracerForTest()), db := db.InitTestDB(t)
dashboardStore, folderStore, db.InitTestDB(t), features, supportbundlestest.NewFakeBundleService(), nil, tracing.InitializeTracerForTest()) fStore := folderimpl.ProvideStore(db)
folderSvc := folderimpl.ProvideService(fStore, ac, bus.ProvideBus(tracing.InitializeTracerForTest()),
dashboardStore, folderStore, db, features,
supportbundlestest.NewFakeBundleService(), nil, tracing.InitializeTracerForTest())
if dashboardService == nil { if dashboardService == nil {
dashboardService, err = service.ProvideDashboardServiceImpl( dashboardService, err = service.ProvideDashboardServiceImpl(
cfg, dashboardStore, folderStore, features, folderPermissions, dashboardPermissions, cfg, dashboardStore, folderStore, features, folderPermissions, dashboardPermissions,
ac, folderSvc, nil, ac, folderSvc, fStore, nil,
) )
require.NoError(t, err) require.NoError(t, err)
} }
dashboardProvisioningService, err := service.ProvideDashboardServiceImpl( dashboardProvisioningService, err := service.ProvideDashboardServiceImpl(
cfg, dashboardStore, folderStore, features, folderPermissions, dashboardPermissions, cfg, dashboardStore, folderStore, features, folderPermissions, dashboardPermissions,
ac, folderSvc, nil, ac, folderSvc, fStore, nil,
) )
require.NoError(t, err) require.NoError(t, err)

View File

@ -457,18 +457,19 @@ func setupServer(b testing.TB, sc benchScenario, features featuremgmt.FeatureTog
folderStore := folderimpl.ProvideDashboardFolderStore(sc.db) folderStore := folderimpl.ProvideDashboardFolderStore(sc.db)
ac := acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()) ac := acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient())
folderServiceWithFlagOn := folderimpl.ProvideService(ac, bus.ProvideBus(tracing.InitializeTracerForTest()), dashStore, folderStore, sc.db, features, supportbundlestest.NewFakeBundleService(), nil, tracing.InitializeTracerForTest())
cfg := setting.NewCfg() cfg := setting.NewCfg()
actionSets := resourcepermissions.NewActionSetService(features) actionSets := resourcepermissions.NewActionSetService(features)
acSvc := acimpl.ProvideOSSService( acSvc := acimpl.ProvideOSSService(
sc.cfg, acdb.ProvideService(sc.db), actionSets, localcache.ProvideService(), sc.cfg, acdb.ProvideService(sc.db), actionSets, localcache.ProvideService(),
features, tracing.InitializeTracerForTest(), zanzana.NewNoopClient(), sc.db, permreg.ProvidePermissionRegistry(), features, tracing.InitializeTracerForTest(), zanzana.NewNoopClient(), sc.db, permreg.ProvidePermissionRegistry(),
) )
fStore := folderimpl.ProvideStore(sc.db)
folderServiceWithFlagOn := folderimpl.ProvideService(fStore, ac, bus.ProvideBus(tracing.InitializeTracerForTest()), dashStore,
folderStore, sc.db, features, supportbundlestest.NewFakeBundleService(), nil, tracing.InitializeTracerForTest())
folderPermissions, err := ossaccesscontrol.ProvideFolderPermissions( folderPermissions, err := ossaccesscontrol.ProvideFolderPermissions(
cfg, features, routing.NewRouteRegister(), sc.db, ac, license, &dashboards.FakeDashboardStore{}, folderServiceWithFlagOn, acSvc, sc.teamSvc, sc.userSvc, actionSets) cfg, features, routing.NewRouteRegister(), sc.db, ac, license, &dashboards.FakeDashboardStore{}, folderServiceWithFlagOn, acSvc, sc.teamSvc, sc.userSvc, actionSets)
require.NoError(b, err) require.NoError(b, err)
dashboardPermissions, err := ossaccesscontrol.ProvideDashboardPermissions( dashboardPermissions, err := ossaccesscontrol.ProvideDashboardPermissions(
cfg, features, routing.NewRouteRegister(), sc.db, ac, license, &dashboards.FakeDashboardStore{}, folderServiceWithFlagOn, acSvc, sc.teamSvc, sc.userSvc, actionSets) cfg, features, routing.NewRouteRegister(), sc.db, ac, license, &dashboards.FakeDashboardStore{}, folderServiceWithFlagOn, acSvc, sc.teamSvc, sc.userSvc, actionSets)
require.NoError(b, err) require.NoError(b, err)
@ -476,7 +477,7 @@ func setupServer(b testing.TB, sc benchScenario, features featuremgmt.FeatureTog
dashboardSvc, err := dashboardservice.ProvideDashboardServiceImpl( dashboardSvc, err := dashboardservice.ProvideDashboardServiceImpl(
sc.cfg, dashStore, folderStore, sc.cfg, dashStore, folderStore,
features, folderPermissions, dashboardPermissions, ac, features, folderPermissions, dashboardPermissions, ac,
folderServiceWithFlagOn, nil, folderServiceWithFlagOn, fStore, nil,
) )
require.NoError(b, err) require.NoError(b, err)

View File

@ -295,6 +295,8 @@ var wireBasicSet = wire.NewSet(
dashboardservice.ProvideDashboardPluginService, dashboardservice.ProvideDashboardPluginService,
dashboardstore.ProvideDashboardStore, dashboardstore.ProvideDashboardStore,
folderimpl.ProvideService, folderimpl.ProvideService,
folderimpl.ProvideStore,
wire.Bind(new(folder.Store), new(*folderimpl.FolderStoreImpl)),
folderimpl.ProvideDashboardFolderStore, folderimpl.ProvideDashboardFolderStore,
wire.Bind(new(folder.FolderStore), new(*folderimpl.DashboardFolderStoreImpl)), wire.Bind(new(folder.FolderStore), new(*folderimpl.DashboardFolderStoreImpl)),
dashboardimportservice.ProvideService, dashboardimportservice.ProvideService,

View File

@ -227,7 +227,9 @@ func TestIntegrationAnnotationListingWithInheritedRBAC(t *testing.T) {
}) })
ac := acimpl.ProvideAccessControl(features, zanzana.NewNoopClient()) ac := acimpl.ProvideAccessControl(features, zanzana.NewNoopClient())
folderSvc := folderimpl.ProvideService(ac, bus.ProvideBus(tracing.InitializeTracerForTest()), dashStore, folderimpl.ProvideDashboardFolderStore(sql), sql, features, supportbundlestest.NewFakeBundleService(), nil, tracing.InitializeTracerForTest()) fStore := folderimpl.ProvideStore(sql)
folderSvc := folderimpl.ProvideService(fStore, ac, bus.ProvideBus(tracing.InitializeTracerForTest()), dashStore,
folderimpl.ProvideDashboardFolderStore(sql), sql, features, supportbundlestest.NewFakeBundleService(), nil, tracing.InitializeTracerForTest())
cfg.AnnotationMaximumTagsLength = 60 cfg.AnnotationMaximumTagsLength = 60

View File

@ -303,7 +303,8 @@ func TestIntegrationDashboardInheritedFolderRBAC(t *testing.T) {
guardian.New = origNewGuardian guardian.New = origNewGuardian
}) })
folderSvc := folderimpl.ProvideService(mock.New(), bus.ProvideBus(tracer), dashboardWriteStore, folderimpl.ProvideDashboardFolderStore(sqlStore), sqlStore, features, supportbundlestest.NewFakeBundleService(), nil, tracing.InitializeTracerForTest()) folderStore := folderimpl.ProvideStore(sqlStore)
folderSvc := folderimpl.ProvideService(folderStore, mock.New(), bus.ProvideBus(tracer), dashboardWriteStore, folderimpl.ProvideDashboardFolderStore(sqlStore), sqlStore, features, supportbundlestest.NewFakeBundleService(), nil, tracing.InitializeTracerForTest())
parentUID := "" parentUID := ""
for i := 0; ; i++ { for i := 0; ; i++ {

View File

@ -830,7 +830,9 @@ func TestIntegrationFindDashboardsByTitle(t *testing.T) {
ac := acimpl.ProvideAccessControl(features, zanzana.NewNoopClient()) ac := acimpl.ProvideAccessControl(features, zanzana.NewNoopClient())
folderStore := folderimpl.ProvideDashboardFolderStore(sqlStore) folderStore := folderimpl.ProvideDashboardFolderStore(sqlStore)
folderServiceWithFlagOn := folderimpl.ProvideService(ac, bus.ProvideBus(tracing.InitializeTracerForTest()), dashboardStore, folderStore, sqlStore, features, supportbundlestest.NewFakeBundleService(), nil, tracing.InitializeTracerForTest()) fStore := folderimpl.ProvideStore(sqlStore)
folderServiceWithFlagOn := folderimpl.ProvideService(fStore, ac, bus.ProvideBus(tracing.InitializeTracerForTest()), dashboardStore,
folderStore, sqlStore, features, supportbundlestest.NewFakeBundleService(), nil, tracing.InitializeTracerForTest())
user := &user.SignedInUser{ user := &user.SignedInUser{
OrgID: 1, OrgID: 1,
@ -936,8 +938,7 @@ func TestIntegrationFindDashboardsByFolder(t *testing.T) {
t.Skip("skipping integration test") t.Skip("skipping integration test")
} }
sqlStore := db.InitTestDB(t) sqlStore, cfg := db.InitTestDBWithCfg(t)
cfg := setting.NewCfg()
quotaService := quotatest.New(false, nil) quotaService := quotatest.New(false, nil)
features := featuremgmt.WithFeatures(featuremgmt.FlagNestedFolders, featuremgmt.FlagPanelTitleSearch) features := featuremgmt.WithFeatures(featuremgmt.FlagNestedFolders, featuremgmt.FlagPanelTitleSearch)
dashboardStore, err := ProvideDashboardStore(sqlStore, cfg, features, tagimpl.ProvideService(sqlStore), quotaService) dashboardStore, err := ProvideDashboardStore(sqlStore, cfg, features, tagimpl.ProvideService(sqlStore), quotaService)
@ -948,7 +949,10 @@ func TestIntegrationFindDashboardsByFolder(t *testing.T) {
ac := acimpl.ProvideAccessControl(features, zanzana.NewNoopClient()) ac := acimpl.ProvideAccessControl(features, zanzana.NewNoopClient())
folderStore := folderimpl.ProvideDashboardFolderStore(sqlStore) folderStore := folderimpl.ProvideDashboardFolderStore(sqlStore)
folderServiceWithFlagOn := folderimpl.ProvideService(ac, bus.ProvideBus(tracing.InitializeTracerForTest()), dashboardStore, folderStore, sqlStore, features, supportbundlestest.NewFakeBundleService(), nil, tracing.InitializeTracerForTest()) fStore := folderimpl.ProvideStore(sqlStore)
folderServiceWithFlagOn := folderimpl.ProvideService(fStore, ac, bus.ProvideBus(tracing.InitializeTracerForTest()), dashboardStore,
folderStore, sqlStore, features, supportbundlestest.NewFakeBundleService(), nil, tracing.InitializeTracerForTest())
user := &user.SignedInUser{ user := &user.SignedInUser{
OrgID: 1, OrgID: 1,

View File

@ -66,7 +66,7 @@ func ProvideDashboardServiceImpl(
cfg *setting.Cfg, dashboardStore dashboards.Store, folderStore folder.FolderStore, cfg *setting.Cfg, dashboardStore dashboards.Store, folderStore folder.FolderStore,
features featuremgmt.FeatureToggles, folderPermissionsService accesscontrol.FolderPermissionsService, features featuremgmt.FeatureToggles, folderPermissionsService accesscontrol.FolderPermissionsService,
dashboardPermissionsService accesscontrol.DashboardPermissionsService, ac accesscontrol.AccessControl, dashboardPermissionsService accesscontrol.DashboardPermissionsService, ac accesscontrol.AccessControl,
folderSvc folder.Service, r prometheus.Registerer, folderSvc folder.Service, fStore folder.Store, r prometheus.Registerer,
) (*DashboardServiceImpl, error) { ) (*DashboardServiceImpl, error) {
dashSvc := &DashboardServiceImpl{ dashSvc := &DashboardServiceImpl{
cfg: cfg, cfg: cfg,

View File

@ -17,6 +17,7 @@ import (
"github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/dashboards/database" "github.com/grafana/grafana/pkg/services/dashboards/database"
"github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/folder"
"github.com/grafana/grafana/pkg/services/folder/folderimpl" "github.com/grafana/grafana/pkg/services/folder/folderimpl"
"github.com/grafana/grafana/pkg/services/folder/foldertest" "github.com/grafana/grafana/pkg/services/folder/foldertest"
"github.com/grafana/grafana/pkg/services/guardian" "github.com/grafana/grafana/pkg/services/guardian"
@ -874,6 +875,7 @@ func permissionScenario(t *testing.T, desc string, canSave bool, fn permissionSc
dashboardPermissions, dashboardPermissions,
ac, ac,
foldertest.NewFakeService(), foldertest.NewFakeService(),
folder.NewFakeStore(),
nil, nil,
) )
require.NoError(t, err) require.NoError(t, err)
@ -939,6 +941,7 @@ func callSaveWithResult(t *testing.T, cmd dashboards.SaveDashboardCommand, sqlSt
dashboardPermissions, dashboardPermissions,
actest.FakeAccessControl{}, actest.FakeAccessControl{},
foldertest.NewFakeService(), foldertest.NewFakeService(),
folder.NewFakeStore(),
nil, nil,
) )
require.NoError(t, err) require.NoError(t, err)
@ -963,6 +966,7 @@ func callSaveWithError(t *testing.T, cmd dashboards.SaveDashboardCommand, sqlSto
accesscontrolmock.NewMockedPermissionsService(), accesscontrolmock.NewMockedPermissionsService(),
actest.FakeAccessControl{}, actest.FakeAccessControl{},
foldertest.NewFakeService(), foldertest.NewFakeService(),
folder.NewFakeStore(),
nil, nil,
) )
require.NoError(t, err) require.NoError(t, err)
@ -1006,6 +1010,7 @@ func saveTestDashboard(t *testing.T, title string, orgID int64, folderUID string
dashboardPermissions, dashboardPermissions,
actest.FakeAccessControl{}, actest.FakeAccessControl{},
foldertest.NewFakeService(), foldertest.NewFakeService(),
folder.NewFakeStore(),
nil, nil,
) )
require.NoError(t, err) require.NoError(t, err)
@ -1056,6 +1061,7 @@ func saveTestFolder(t *testing.T, title string, orgID int64, sqlStore db.DB) *da
accesscontrolmock.NewMockedPermissionsService(), accesscontrolmock.NewMockedPermissionsService(),
actest.FakeAccessControl{}, actest.FakeAccessControl{},
foldertest.NewFakeService(), foldertest.NewFakeService(),
folder.NewFakeStore(),
nil, nil,
) )
require.NoError(t, err) require.NoError(t, err)

View File

@ -18,6 +18,7 @@ import (
"github.com/grafana/grafana/pkg/services/dashboardsnapshots" "github.com/grafana/grafana/pkg/services/dashboardsnapshots"
dashsnapdb "github.com/grafana/grafana/pkg/services/dashboardsnapshots/database" dashsnapdb "github.com/grafana/grafana/pkg/services/dashboardsnapshots/database"
"github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/folder"
"github.com/grafana/grafana/pkg/services/folder/folderimpl" "github.com/grafana/grafana/pkg/services/folder/folderimpl"
"github.com/grafana/grafana/pkg/services/folder/foldertest" "github.com/grafana/grafana/pkg/services/folder/foldertest"
"github.com/grafana/grafana/pkg/services/quota/quotatest" "github.com/grafana/grafana/pkg/services/quota/quotatest"
@ -98,7 +99,7 @@ func TestValidateDashboardExists(t *testing.T) {
secretsService := secretsManager.SetupTestService(t, database.ProvideSecretsStore(sqlStore)) secretsService := secretsManager.SetupTestService(t, database.ProvideSecretsStore(sqlStore))
dashboardStore, err := dashdb.ProvideDashboardStore(sqlStore, cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore), quotatest.New(false, nil)) dashboardStore, err := dashdb.ProvideDashboardStore(sqlStore, cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore), quotatest.New(false, nil))
require.NoError(t, err) require.NoError(t, err)
dashSvc, err := dashsvc.ProvideDashboardServiceImpl(cfg, dashboardStore, folderimpl.ProvideDashboardFolderStore(sqlStore), nil, nil, nil, acmock.New(), foldertest.NewFakeService(), nil) dashSvc, err := dashsvc.ProvideDashboardServiceImpl(cfg, dashboardStore, folderimpl.ProvideDashboardFolderStore(sqlStore), nil, nil, nil, acmock.New(), foldertest.NewFakeService(), folder.NewFakeStore(), nil)
require.NoError(t, err) require.NoError(t, err)
s := ProvideService(dsStore, secretsService, dashSvc) s := ProvideService(dsStore, secretsService, dashSvc)
ctx := context.Background() ctx := context.Background()

View File

@ -40,7 +40,7 @@ import (
const FULLPATH_SEPARATOR = "/" const FULLPATH_SEPARATOR = "/"
type Service struct { type Service struct {
store store store folder.Store
db db.DB db db.DB
log *slog.Logger log *slog.Logger
dashboardStore dashboards.Store dashboardStore dashboards.Store
@ -58,6 +58,7 @@ type Service struct {
} }
func ProvideService( func ProvideService(
store *FolderStoreImpl,
ac accesscontrol.AccessControl, ac accesscontrol.AccessControl,
bus bus.Bus, bus bus.Bus,
dashboardStore dashboards.Store, dashboardStore dashboards.Store,
@ -68,7 +69,6 @@ func ProvideService(
r prometheus.Registerer, r prometheus.Registerer,
tracer tracing.Tracer, tracer tracing.Tracer,
) folder.Service { ) folder.Service {
store := ProvideStore(db)
srv := &Service{ srv := &Service{
log: slog.Default().With("logger", "folder-service"), log: slog.Default().With("logger", "folder-service"),
dashboardStore: dashboardStore, dashboardStore: dashboardStore,
@ -143,10 +143,10 @@ func (s *Service) GetFolders(ctx context.Context, q folder.GetFoldersQuery) ([]*
return nil, folder.ErrBadRequest.Errorf("missing signed in user") return nil, folder.ErrBadRequest.Errorf("missing signed in user")
} }
qry := NewGetFoldersQuery(q) qry := folder.NewGetFoldersQuery(q)
permissions := q.SignedInUser.GetPermissions() permissions := q.SignedInUser.GetPermissions()
folderPermissions := permissions[dashboards.ActionFoldersRead] folderPermissions := permissions[dashboards.ActionFoldersRead]
qry.ancestorUIDs = make([]string, 0, len(folderPermissions)) qry.AncestorUIDs = make([]string, 0, len(folderPermissions))
if len(folderPermissions) == 0 && !q.SignedInUser.GetIsGrafanaAdmin() { if len(folderPermissions) == 0 && !q.SignedInUser.GetIsGrafanaAdmin() {
return nil, nil return nil, nil
} }
@ -154,12 +154,12 @@ func (s *Service) GetFolders(ctx context.Context, q folder.GetFoldersQuery) ([]*
if p == dashboards.ScopeFoldersAll { if p == dashboards.ScopeFoldersAll {
// no need to query for folders with permissions // no need to query for folders with permissions
// the user has permission to access all folders // the user has permission to access all folders
qry.ancestorUIDs = nil qry.AncestorUIDs = nil
break break
} }
if folderUid, found := strings.CutPrefix(p, dashboards.ScopeFoldersPrefix); found { if folderUid, found := strings.CutPrefix(p, dashboards.ScopeFoldersPrefix); found {
if !slices.Contains(qry.ancestorUIDs, folderUid) { if !slices.Contains(qry.AncestorUIDs, folderUid) {
qry.ancestorUIDs = append(qry.ancestorUIDs, folderUid) qry.AncestorUIDs = append(qry.AncestorUIDs, folderUid)
} }
} }
} }

View File

@ -62,8 +62,10 @@ func TestIntegrationProvideFolderService(t *testing.T) {
} }
t.Run("should register scope resolvers", func(t *testing.T) { t.Run("should register scope resolvers", func(t *testing.T) {
ac := acmock.New() ac := acmock.New()
db := db.InitTestDB(t) db, _ := db.InitTestDBWithCfg(t)
ProvideService(ac, bus.ProvideBus(tracing.InitializeTracerForTest()), nil, nil, db, featuremgmt.WithFeatures(), supportbundlestest.NewFakeBundleService(), nil, tracing.InitializeTracerForTest()) store := ProvideStore(db)
ProvideService(store, ac, bus.ProvideBus(tracing.InitializeTracerForTest()), nil, nil, db,
featuremgmt.WithFeatures(), supportbundlestest.NewFakeBundleService(), nil, tracing.InitializeTracerForTest())
require.Len(t, ac.Calls.RegisterAttributeScopeResolver, 3) require.Len(t, ac.Calls.RegisterAttributeScopeResolver, 3)
}) })
@ -486,7 +488,7 @@ func TestIntegrationNestedFolderService(t *testing.T) {
CanEditValue: true, CanEditValue: true,
}) })
dashSrv, err := dashboardservice.ProvideDashboardServiceImpl(cfg, dashStore, folderStore, featuresFlagOn, folderPermissions, dashboardPermissions, ac, serviceWithFlagOn, nil) dashSrv, err := dashboardservice.ProvideDashboardServiceImpl(cfg, dashStore, folderStore, featuresFlagOn, folderPermissions, dashboardPermissions, ac, serviceWithFlagOn, nestedFolderStore, nil)
require.NoError(t, err) require.NoError(t, err)
alertStore, err := ngstore.ProvideDBStore(cfg, featuresFlagOn, db, serviceWithFlagOn, dashSrv, ac) alertStore, err := ngstore.ProvideDBStore(cfg, featuresFlagOn, db, serviceWithFlagOn, dashSrv, ac)
@ -568,7 +570,7 @@ func TestIntegrationNestedFolderService(t *testing.T) {
}) })
dashSrv, err := dashboardservice.ProvideDashboardServiceImpl(cfg, dashStore, folderStore, featuresFlagOff, dashSrv, err := dashboardservice.ProvideDashboardServiceImpl(cfg, dashStore, folderStore, featuresFlagOff,
folderPermissions, dashboardPermissions, ac, serviceWithFlagOff, nil) folderPermissions, dashboardPermissions, ac, serviceWithFlagOff, nestedFolderStore, nil)
require.NoError(t, err) require.NoError(t, err)
alertStore, err := ngstore.ProvideDBStore(cfg, featuresFlagOff, db, serviceWithFlagOff, dashSrv, ac) alertStore, err := ngstore.ProvideDBStore(cfg, featuresFlagOff, db, serviceWithFlagOff, dashSrv, ac)
@ -713,7 +715,7 @@ func TestIntegrationNestedFolderService(t *testing.T) {
tc.service.dashboardStore = dashStore tc.service.dashboardStore = dashStore
tc.service.store = nestedFolderStore tc.service.store = nestedFolderStore
dashSrv, err := dashboardservice.ProvideDashboardServiceImpl(cfg, dashStore, folderStore, tc.featuresFlag, folderPermissions, dashboardPermissions, ac, tc.service, nil) dashSrv, err := dashboardservice.ProvideDashboardServiceImpl(cfg, dashStore, folderStore, tc.featuresFlag, folderPermissions, dashboardPermissions, ac, tc.service, tc.service.store, nil)
require.NoError(t, err) require.NoError(t, err)
alertStore, err := ngstore.ProvideDBStore(cfg, tc.featuresFlag, db, tc.service, dashSrv, ac) alertStore, err := ngstore.ProvideDBStore(cfg, tc.featuresFlag, db, tc.service, dashSrv, ac)
require.NoError(t, err) require.NoError(t, err)
@ -792,7 +794,7 @@ func TestNestedFolderServiceFeatureToggle(t *testing.T) {
guardian.New = g guardian.New = g
}) })
nestedFolderStore := NewFakeStore() nestedFolderStore := folder.NewFakeStore()
dashStore := dashboards.FakeDashboardStore{} dashStore := dashboards.FakeDashboardStore{}
dashStore.On("ValidateDashboardBeforeSave", mock.Anything, mock.AnythingOfType("*dashboards.Dashboard"), mock.AnythingOfType("bool")).Return(true, nil) dashStore.On("ValidateDashboardBeforeSave", mock.Anything, mock.AnythingOfType("*dashboards.Dashboard"), mock.AnythingOfType("bool")).Return(true, nil)
@ -906,7 +908,7 @@ func TestNestedFolderService(t *testing.T) {
dashboardFolderStore := foldertest.NewFakeFolderStore(t) dashboardFolderStore := foldertest.NewFakeFolderStore(t)
nestedFolderStore := NewFakeStore() nestedFolderStore := folder.NewFakeStore()
features := featuremgmt.WithFeatures() features := featuremgmt.WithFeatures()
db, _ := sqlstore.InitTestDB(t) db, _ := sqlstore.InitTestDB(t)
@ -944,7 +946,7 @@ func TestNestedFolderService(t *testing.T) {
dashStore.On("SaveDashboard", mock.Anything, mock.AnythingOfType("dashboards.SaveDashboardCommand")).Return(dash, nil) dashStore.On("SaveDashboard", mock.Anything, mock.AnythingOfType("dashboards.SaveDashboardCommand")).Return(dash, nil)
dashboardFolderStore := foldertest.NewFakeFolderStore(t) dashboardFolderStore := foldertest.NewFakeFolderStore(t)
nestedFolderStore := NewFakeStore() nestedFolderStore := folder.NewFakeStore()
features := featuremgmt.WithFeatures("nestedFolders") features := featuremgmt.WithFeatures("nestedFolders")
tempUser := &user.SignedInUser{UserID: 1, OrgID: orgID, Permissions: map[int64]map[string][]string{}} tempUser := &user.SignedInUser{UserID: 1, OrgID: orgID, Permissions: map[int64]map[string][]string{}}
@ -974,7 +976,7 @@ func TestNestedFolderService(t *testing.T) {
dashStore := &dashboards.FakeDashboardStore{} dashStore := &dashboards.FakeDashboardStore{}
dashboardFolderStore := foldertest.NewFakeFolderStore(t) dashboardFolderStore := foldertest.NewFakeFolderStore(t)
nestedFolderStore := NewFakeStore() nestedFolderStore := folder.NewFakeStore()
features := featuremgmt.WithFeatures("nestedFolders") features := featuremgmt.WithFeatures("nestedFolders")
tempUser := &user.SignedInUser{UserID: 1, OrgID: orgID, Permissions: map[int64]map[string][]string{}} tempUser := &user.SignedInUser{UserID: 1, OrgID: orgID, Permissions: map[int64]map[string][]string{}}
@ -1044,7 +1046,7 @@ func TestNestedFolderService(t *testing.T) {
nestedFolderUser := &user.SignedInUser{UserID: 1, OrgID: orgID, Permissions: map[int64]map[string][]string{}} nestedFolderUser := &user.SignedInUser{UserID: 1, OrgID: orgID, Permissions: map[int64]map[string][]string{}}
nestedFolderUser.Permissions[orgID] = map[string][]string{dashboards.ActionFoldersWrite: {dashboards.ScopeFoldersProvider.GetResourceScopeUID("some_parent")}} nestedFolderUser.Permissions[orgID] = map[string][]string{dashboards.ActionFoldersWrite: {dashboards.ScopeFoldersProvider.GetResourceScopeUID("some_parent")}}
nestedFolderStore := NewFakeStore() nestedFolderStore := folder.NewFakeStore()
db, _ := sqlstore.InitTestDB(t) db, _ := sqlstore.InitTestDB(t)
features := featuremgmt.WithFeatures("nestedFolders") features := featuremgmt.WithFeatures("nestedFolders")
folderSvc := setup(t, dashStore, dashboardFolderStore, nestedFolderStore, features, acimpl.ProvideAccessControl(features, zanzana.NewNoopClient()), db) folderSvc := setup(t, dashStore, dashboardFolderStore, nestedFolderStore, features, acimpl.ProvideAccessControl(features, zanzana.NewNoopClient()), db)
@ -1085,7 +1087,7 @@ func TestNestedFolderService(t *testing.T) {
dashStore.On("SaveDashboard", mock.Anything, mock.AnythingOfType("dashboards.SaveDashboardCommand")).Return(&dashboards.Dashboard{UID: "newUID"}, nil) dashStore.On("SaveDashboard", mock.Anything, mock.AnythingOfType("dashboards.SaveDashboardCommand")).Return(&dashboards.Dashboard{UID: "newUID"}, nil)
dashboardFolderStore := foldertest.NewFakeFolderStore(t) dashboardFolderStore := foldertest.NewFakeFolderStore(t)
nestedFolderStore := NewFakeStore() nestedFolderStore := folder.NewFakeStore()
db, _ := sqlstore.InitTestDB(t) db, _ := sqlstore.InitTestDB(t)
folderSvc := setup(t, dashStore, dashboardFolderStore, nestedFolderStore, featuremgmt.WithFeatures("nestedFolders"), actest.FakeAccessControl{ folderSvc := setup(t, dashStore, dashboardFolderStore, nestedFolderStore, featuremgmt.WithFeatures("nestedFolders"), actest.FakeAccessControl{
@ -1122,7 +1124,7 @@ func TestNestedFolderService(t *testing.T) {
dashboardFolderStore := foldertest.NewFakeFolderStore(t) dashboardFolderStore := foldertest.NewFakeFolderStore(t)
dashboardFolderStore.On("GetFolderByUID", mock.Anything, orgID, dashboardFolder.UID).Return(f, nil) dashboardFolderStore.On("GetFolderByUID", mock.Anything, orgID, dashboardFolder.UID).Return(f, nil)
nestedFolderStore := NewFakeStore() nestedFolderStore := folder.NewFakeStore()
nestedFolderStore.ExpectedParentFolders = []*folder.Folder{ nestedFolderStore.ExpectedParentFolders = []*folder.Folder{
{UID: "newFolder", ParentUID: "newFolder"}, {UID: "newFolder", ParentUID: "newFolder"},
{UID: "newFolder2", ParentUID: "newFolder2"}, {UID: "newFolder2", ParentUID: "newFolder2"},
@ -1164,7 +1166,7 @@ func TestNestedFolderService(t *testing.T) {
dashboardFolderStore := foldertest.NewFakeFolderStore(t) dashboardFolderStore := foldertest.NewFakeFolderStore(t)
// return an error from the folder store // return an error from the folder store
nestedFolderStore := NewFakeStore() nestedFolderStore := folder.NewFakeStore()
nestedFolderStore.ExpectedError = errors.New("FAILED") nestedFolderStore.ExpectedError = errors.New("FAILED")
// the service return success as long as the legacy create succeeds // the service return success as long as the legacy create succeeds
@ -1189,7 +1191,7 @@ func TestNestedFolderService(t *testing.T) {
dashboardFolderStore := foldertest.NewFakeFolderStore(t) dashboardFolderStore := foldertest.NewFakeFolderStore(t)
//dashboardFolderStore.On("GetFolderByUID", mock.Anything, mock.AnythingOfType("int64"), mock.AnythingOfType("string")).Return(&folder.Folder{}, nil) //dashboardFolderStore.On("GetFolderByUID", mock.Anything, mock.AnythingOfType("int64"), mock.AnythingOfType("string")).Return(&folder.Folder{}, nil)
nestedFolderStore := NewFakeStore() nestedFolderStore := folder.NewFakeStore()
nestedFolderStore.ExpectedFolder = &folder.Folder{UID: "myFolder", ParentUID: "newFolder"} nestedFolderStore.ExpectedFolder = &folder.Folder{UID: "myFolder", ParentUID: "newFolder"}
nestedFolderUser := &user.SignedInUser{UserID: 1, OrgID: orgID, Permissions: map[int64]map[string][]string{}} nestedFolderUser := &user.SignedInUser{UserID: 1, OrgID: orgID, Permissions: map[int64]map[string][]string{}}
@ -1205,7 +1207,7 @@ func TestNestedFolderService(t *testing.T) {
dashStore := &dashboards.FakeDashboardStore{} dashStore := &dashboards.FakeDashboardStore{}
dashboardFolderStore := foldertest.NewFakeFolderStore(t) dashboardFolderStore := foldertest.NewFakeFolderStore(t)
nestedFolderStore := NewFakeStore() nestedFolderStore := folder.NewFakeStore()
nestedFolderStore.ExpectedFolder = &folder.Folder{UID: "myFolder", ParentUID: "newFolder"} nestedFolderStore.ExpectedFolder = &folder.Folder{UID: "myFolder", ParentUID: "newFolder"}
nestedFolderStore.ExpectedParentFolders = []*folder.Folder{ nestedFolderStore.ExpectedParentFolders = []*folder.Folder{
{UID: "newFolder", ParentUID: "newFolder"}, {UID: "newFolder", ParentUID: "newFolder"},
@ -1236,7 +1238,7 @@ func TestNestedFolderService(t *testing.T) {
nestedFolderUser.Permissions[orgID] = map[string][]string{dashboards.ActionFoldersWrite: {dashboards.ScopeFoldersProvider.GetResourceAllScope()}} nestedFolderUser.Permissions[orgID] = map[string][]string{dashboards.ActionFoldersWrite: {dashboards.ScopeFoldersProvider.GetResourceAllScope()}}
features := featuremgmt.WithFeatures("nestedFolders") features := featuremgmt.WithFeatures("nestedFolders")
folderSvc := setup(t, &dashboards.FakeDashboardStore{}, foldertest.NewFakeFolderStore(t), NewFakeStore(), features, acimpl.ProvideAccessControl(features, zanzana.NewNoopClient()), dbtest.NewFakeDB()) folderSvc := setup(t, &dashboards.FakeDashboardStore{}, foldertest.NewFakeFolderStore(t), folder.NewFakeStore(), features, acimpl.ProvideAccessControl(features, zanzana.NewNoopClient()), dbtest.NewFakeDB())
_, err := folderSvc.Move(context.Background(), &folder.MoveFolderCommand{UID: accesscontrol.K6FolderUID, NewParentUID: "newFolder", OrgID: orgID, SignedInUser: nestedFolderUser}) _, err := folderSvc.Move(context.Background(), &folder.MoveFolderCommand{UID: accesscontrol.K6FolderUID, NewParentUID: "newFolder", OrgID: orgID, SignedInUser: nestedFolderUser})
require.Error(t, err, folder.ErrBadRequest) require.Error(t, err, folder.ErrBadRequest)
}) })
@ -1246,7 +1248,7 @@ func TestNestedFolderService(t *testing.T) {
nestedFolderUser.Permissions[orgID] = map[string][]string{dashboards.ActionFoldersWrite: {dashboards.ScopeFoldersProvider.GetResourceAllScope()}} nestedFolderUser.Permissions[orgID] = map[string][]string{dashboards.ActionFoldersWrite: {dashboards.ScopeFoldersProvider.GetResourceAllScope()}}
childUID := "k6-app-child" childUID := "k6-app-child"
nestedFolderStore := NewFakeStore() nestedFolderStore := folder.NewFakeStore()
nestedFolderStore.ExpectedFolder = &folder.Folder{ nestedFolderStore.ExpectedFolder = &folder.Folder{
OrgID: orgID, OrgID: orgID,
UID: childUID, UID: childUID,
@ -1263,7 +1265,7 @@ func TestNestedFolderService(t *testing.T) {
dashStore := &dashboards.FakeDashboardStore{} dashStore := &dashboards.FakeDashboardStore{}
dashboardFolderStore := foldertest.NewFakeFolderStore(t) dashboardFolderStore := foldertest.NewFakeFolderStore(t)
nestedFolderStore := NewFakeStore() nestedFolderStore := folder.NewFakeStore()
nestedFolderStore.ExpectedFolder = &folder.Folder{UID: "myFolder", ParentUID: "newFolder"} nestedFolderStore.ExpectedFolder = &folder.Folder{UID: "myFolder", ParentUID: "newFolder"}
nestedFolderUser := &user.SignedInUser{UserID: 1, OrgID: orgID, Permissions: map[int64]map[string][]string{}} nestedFolderUser := &user.SignedInUser{UserID: 1, OrgID: orgID, Permissions: map[int64]map[string][]string{}}
@ -1279,7 +1281,7 @@ func TestNestedFolderService(t *testing.T) {
dashStore := &dashboards.FakeDashboardStore{} dashStore := &dashboards.FakeDashboardStore{}
dashboardFolderStore := foldertest.NewFakeFolderStore(t) dashboardFolderStore := foldertest.NewFakeFolderStore(t)
nestedFolderStore := NewFakeStore() nestedFolderStore := folder.NewFakeStore()
nestedFolderStore.ExpectedFolder = &folder.Folder{UID: "myFolder", ParentUID: "newFolder"} nestedFolderStore.ExpectedFolder = &folder.Folder{UID: "myFolder", ParentUID: "newFolder"}
nestedFolderStore.ExpectedParentFolders = []*folder.Folder{ nestedFolderStore.ExpectedParentFolders = []*folder.Folder{
{UID: "newFolder", ParentUID: "newFolder"}, {UID: "newFolder", ParentUID: "newFolder"},
@ -1307,7 +1309,7 @@ func TestNestedFolderService(t *testing.T) {
dashStore := &dashboards.FakeDashboardStore{} dashStore := &dashboards.FakeDashboardStore{}
dashboardFolderStore := foldertest.NewFakeFolderStore(t) dashboardFolderStore := foldertest.NewFakeFolderStore(t)
nestedFolderStore := NewFakeStore() nestedFolderStore := folder.NewFakeStore()
nestedFolderUser := &user.SignedInUser{UserID: 1, OrgID: orgID, Permissions: map[int64]map[string][]string{}} nestedFolderUser := &user.SignedInUser{UserID: 1, OrgID: orgID, Permissions: map[int64]map[string][]string{}}
nestedFolderUser.Permissions[orgID] = map[string][]string{dashboards.ActionFoldersCreate: {dashboards.ScopeFoldersProvider.GetResourceScopeUID("some_subfolder")}} nestedFolderUser.Permissions[orgID] = map[string][]string{dashboards.ActionFoldersCreate: {dashboards.ScopeFoldersProvider.GetResourceScopeUID("some_subfolder")}}
@ -1328,7 +1330,7 @@ func TestNestedFolderService(t *testing.T) {
dashStore := &dashboards.FakeDashboardStore{} dashStore := &dashboards.FakeDashboardStore{}
dashboardFolderStore := foldertest.NewFakeFolderStore(t) dashboardFolderStore := foldertest.NewFakeFolderStore(t)
nestedFolderStore := NewFakeStore() nestedFolderStore := folder.NewFakeStore()
nestedFolderStore.ExpectedFolder = &folder.Folder{UID: "myFolder", ParentUID: "newFolder"} nestedFolderStore.ExpectedFolder = &folder.Folder{UID: "myFolder", ParentUID: "newFolder"}
nestedFolderStore.ExpectedError = folder.ErrCircularReference nestedFolderStore.ExpectedError = folder.ErrCircularReference
@ -1350,7 +1352,7 @@ func TestNestedFolderService(t *testing.T) {
dashStore := &dashboards.FakeDashboardStore{} dashStore := &dashboards.FakeDashboardStore{}
dashboardFolderStore := foldertest.NewFakeFolderStore(t) dashboardFolderStore := foldertest.NewFakeFolderStore(t)
nestedFolderStore := NewFakeStore() nestedFolderStore := folder.NewFakeStore()
nestedFolderStore.ExpectedFolder = &folder.Folder{UID: "myFolder", ParentUID: "newFolder"} nestedFolderStore.ExpectedFolder = &folder.Folder{UID: "myFolder", ParentUID: "newFolder"}
nestedFolderStore.ExpectedParentFolders = []*folder.Folder{ nestedFolderStore.ExpectedParentFolders = []*folder.Folder{
{UID: "newFolder", ParentUID: "newFolder"}, {UID: "newFolder", ParentUID: "newFolder"},
@ -1376,7 +1378,7 @@ func TestNestedFolderService(t *testing.T) {
dashStore := &dashboards.FakeDashboardStore{} dashStore := &dashboards.FakeDashboardStore{}
dashboardFolderStore := foldertest.NewFakeFolderStore(t) dashboardFolderStore := foldertest.NewFakeFolderStore(t)
nestedFolderStore := NewFakeStore() nestedFolderStore := folder.NewFakeStore()
nestedFolderStore.ExpectedFolder = &folder.Folder{UID: "myFolder", ParentUID: "newFolder"} nestedFolderStore.ExpectedFolder = &folder.Folder{UID: "myFolder", ParentUID: "newFolder"}
nestedFolderStore.ExpectedParentFolders = []*folder.Folder{{UID: "myFolder", ParentUID: "12345"}, {UID: "12345", ParentUID: ""}} nestedFolderStore.ExpectedParentFolders = []*folder.Folder{{UID: "myFolder", ParentUID: "12345"}, {UID: "12345", ParentUID: ""}}
@ -1409,7 +1411,7 @@ func TestNestedFolderService(t *testing.T) {
parents = append(parents, &folder.Folder{UID: fmt.Sprintf("folder%d", i)}) parents = append(parents, &folder.Folder{UID: fmt.Sprintf("folder%d", i)})
} }
nestedFolderStore := NewFakeStore() nestedFolderStore := folder.NewFakeStore()
//nestedFolderStore.ExpectedFolder = &folder.Folder{UID: "myFolder", ParentUID: "newFolder"} //nestedFolderStore.ExpectedFolder = &folder.Folder{UID: "myFolder", ParentUID: "newFolder"}
nestedFolderStore.ExpectedParentFolders = parents nestedFolderStore.ExpectedParentFolders = parents
@ -1439,7 +1441,7 @@ func TestNestedFolderService(t *testing.T) {
dashboardFolderStore := foldertest.NewFakeFolderStore(t) dashboardFolderStore := foldertest.NewFakeFolderStore(t)
nestedFolderStore := NewFakeStore() nestedFolderStore := folder.NewFakeStore()
nestedFolderStore.ExpectedError = folder.ErrFolderNotFound nestedFolderStore.ExpectedError = folder.ErrFolderNotFound
folderSvc := setup(t, dashStore, dashboardFolderStore, nestedFolderStore, featuremgmt.WithFeatures("nestedFolders"), actest.FakeAccessControl{ folderSvc := setup(t, dashStore, dashboardFolderStore, nestedFolderStore, featuremgmt.WithFeatures("nestedFolders"), actest.FakeAccessControl{
@ -1493,6 +1495,7 @@ func TestIntegrationNestedFolderSharedWithMe(t *testing.T) {
dashboardPermissions, dashboardPermissions,
actest.FakeAccessControl{}, actest.FakeAccessControl{},
serviceWithFlagOn, serviceWithFlagOn,
nestedFolderStore,
nil, nil,
) )
require.NoError(t, err) require.NoError(t, err)
@ -2496,7 +2499,7 @@ func TestSupportBundle(t *testing.T) {
} }
} }
func CreateSubtreeInStore(t *testing.T, store store, service *Service, depth int, prefix string, cmd folder.CreateFolderCommand) []*folder.Folder { func CreateSubtreeInStore(t *testing.T, store folder.Store, service *Service, depth int, prefix string, cmd folder.CreateFolderCommand) []*folder.Folder {
t.Helper() t.Helper()
folders := make([]*folder.Folder, 0, depth) folders := make([]*folder.Folder, 0, depth)
@ -2520,7 +2523,7 @@ func CreateSubtreeInStore(t *testing.T, store store, service *Service, depth int
return folders return folders
} }
func setup(t *testing.T, dashStore dashboards.Store, dashboardFolderStore folder.FolderStore, nestedFolderStore store, features featuremgmt.FeatureToggles, ac accesscontrol.AccessControl, db db.DB) folder.Service { func setup(t *testing.T, dashStore dashboards.Store, dashboardFolderStore folder.FolderStore, nestedFolderStore folder.Store, features featuremgmt.FeatureToggles, ac accesscontrol.AccessControl, db db.DB) folder.Service {
t.Helper() t.Helper()
// nothing enabled yet // nothing enabled yet

View File

@ -22,19 +22,19 @@ import (
const DEFAULT_BATCH_SIZE = 999 const DEFAULT_BATCH_SIZE = 999
type sqlStore struct { type FolderStoreImpl struct {
db db.DB db db.DB
log log.Logger log log.Logger
} }
// sqlStore implements the store interface. // sqlStore implements the store interface.
var _ store = (*sqlStore)(nil) var _ folder.Store = (*FolderStoreImpl)(nil)
func ProvideStore(db db.DB) *sqlStore { func ProvideStore(db db.DB) *FolderStoreImpl {
return &sqlStore{db: db, log: log.New("folder-store")} return &FolderStoreImpl{db: db, log: log.New("folder-store")}
} }
func (ss *sqlStore) Create(ctx context.Context, cmd folder.CreateFolderCommand) (*folder.Folder, error) { func (ss *FolderStoreImpl) Create(ctx context.Context, cmd folder.CreateFolderCommand) (*folder.Folder, error) {
if cmd.UID == "" { if cmd.UID == "" {
return nil, folder.ErrBadRequest.Errorf("missing UID") return nil, folder.ErrBadRequest.Errorf("missing UID")
} }
@ -83,7 +83,7 @@ func (ss *sqlStore) Create(ctx context.Context, cmd folder.CreateFolderCommand)
return foldr.WithURL(), err return foldr.WithURL(), err
} }
func (ss *sqlStore) Delete(ctx context.Context, UIDs []string, orgID int64) error { func (ss *FolderStoreImpl) Delete(ctx context.Context, UIDs []string, orgID int64) error {
if len(UIDs) == 0 { if len(UIDs) == 0 {
return nil return nil
} }
@ -103,7 +103,7 @@ func (ss *sqlStore) Delete(ctx context.Context, UIDs []string, orgID int64) erro
}) })
} }
func (ss *sqlStore) Update(ctx context.Context, cmd folder.UpdateFolderCommand) (*folder.Folder, error) { func (ss *FolderStoreImpl) Update(ctx context.Context, cmd folder.UpdateFolderCommand) (*folder.Folder, error) {
updated := time.Now() updated := time.Now()
uid := cmd.UID uid := cmd.UID
@ -191,7 +191,7 @@ func (ss *sqlStore) Update(ctx context.Context, cmd folder.UpdateFolderCommand)
// └── B/C // └── B/C
// //
// The full path of C is "A/B\/C". // The full path of C is "A/B\/C".
func (ss *sqlStore) Get(ctx context.Context, q folder.GetFolderQuery) (*folder.Folder, error) { func (ss *FolderStoreImpl) Get(ctx context.Context, q folder.GetFolderQuery) (*folder.Folder, error) {
foldr := &folder.Folder{} foldr := &folder.Folder{}
err := ss.db.WithDbSession(ctx, func(sess *db.Session) error { err := ss.db.WithDbSession(ctx, func(sess *db.Session) error {
exists := false exists := false
@ -244,7 +244,7 @@ func (ss *sqlStore) Get(ctx context.Context, q folder.GetFolderQuery) (*folder.F
return foldr.WithURL(), err return foldr.WithURL(), err
} }
func (ss *sqlStore) GetParents(ctx context.Context, q folder.GetParentsQuery) ([]*folder.Folder, error) { func (ss *FolderStoreImpl) GetParents(ctx context.Context, q folder.GetParentsQuery) ([]*folder.Folder, error) {
if q.UID == "" { if q.UID == "" {
return []*folder.Folder{}, nil return []*folder.Folder{}, nil
} }
@ -295,7 +295,7 @@ func (ss *sqlStore) GetParents(ctx context.Context, q folder.GetParentsQuery) ([
return util.Reverse(folders[1:]), nil return util.Reverse(folders[1:]), nil
} }
func (ss *sqlStore) GetChildren(ctx context.Context, q folder.GetChildrenQuery) ([]*folder.Folder, error) { func (ss *FolderStoreImpl) GetChildren(ctx context.Context, q folder.GetChildrenQuery) ([]*folder.Folder, error) {
var folders []*folder.Folder var folders []*folder.Folder
err := ss.db.WithDbSession(ctx, func(sess *db.Session) error { err := ss.db.WithDbSession(ctx, func(sess *db.Session) error {
@ -353,7 +353,7 @@ func (ss *sqlStore) GetChildren(ctx context.Context, q folder.GetChildrenQuery)
return folders, err return folders, err
} }
func (ss *sqlStore) getParentsMySQL(ctx context.Context, q folder.GetParentsQuery) (folders []*folder.Folder, err error) { func (ss *FolderStoreImpl) getParentsMySQL(ctx context.Context, q folder.GetParentsQuery) (folders []*folder.Folder, err error) {
err = ss.db.WithDbSession(ctx, func(sess *db.Session) error { err = ss.db.WithDbSession(ctx, func(sess *db.Session) error {
uid := "" uid := ""
// covered by UQE_folder_org_id_uid // covered by UQE_folder_org_id_uid
@ -387,7 +387,7 @@ func (ss *sqlStore) getParentsMySQL(ctx context.Context, q folder.GetParentsQuer
} }
// TODO use a single query to get the height of a folder // TODO use a single query to get the height of a folder
func (ss *sqlStore) GetHeight(ctx context.Context, foldrUID string, orgID int64, parentUID *string) (int, error) { func (ss *FolderStoreImpl) GetHeight(ctx context.Context, foldrUID string, orgID int64, parentUID *string) (int, error) {
height := -1 height := -1
queue := []string{foldrUID} queue := []string{foldrUID}
for len(queue) > 0 && height <= folder.MaxNestedFolderDepth { for len(queue) > 0 && height <= folder.MaxNestedFolderDepth {
@ -445,7 +445,7 @@ func (ss *sqlStore) GetHeight(ctx context.Context, foldrUID string, orgID int64,
// The full path UIDs of C is "uid1/uid2/uid3". // The full path UIDs of C is "uid1/uid2/uid3".
// The full path UIDs of B is "uid1/uid2". // The full path UIDs of B is "uid1/uid2".
// The full path UIDs of A is "uid1". // The full path UIDs of A is "uid1".
func (ss *sqlStore) GetFolders(ctx context.Context, q getFoldersQuery) ([]*folder.Folder, error) { func (ss *FolderStoreImpl) GetFolders(ctx context.Context, q folder.GetFoldersFromStoreQuery) ([]*folder.Folder, error) {
if q.BatchSize == 0 { if q.BatchSize == 0 {
q.BatchSize = DEFAULT_BATCH_SIZE q.BatchSize = DEFAULT_BATCH_SIZE
} }
@ -467,7 +467,7 @@ func (ss *sqlStore) GetFolders(ctx context.Context, q getFoldersQuery) ([]*folde
} }
s.WriteString(` FROM folder f0`) s.WriteString(` FROM folder f0`)
// join the same table multiple times to compute the full path of a folder // join the same table multiple times to compute the full path of a folder
if q.WithFullpath || q.WithFullpathUIDs || len(q.ancestorUIDs) > 0 { if q.WithFullpath || q.WithFullpathUIDs || len(q.AncestorUIDs) > 0 {
s.WriteString(getFullpathJoinsSQL()) s.WriteString(getFullpathJoinsSQL())
} }
// covered by UQE_folder_org_id_uid // covered by UQE_folder_org_id_uid
@ -489,7 +489,7 @@ func (ss *sqlStore) GetFolders(ctx context.Context, q getFoldersQuery) ([]*folde
args = append(args, accesscontrol.K6FolderUID, accesscontrol.K6FolderUID) args = append(args, accesscontrol.K6FolderUID, accesscontrol.K6FolderUID)
} }
if len(q.ancestorUIDs) == 0 { if len(q.AncestorUIDs) == 0 {
if q.OrderByTitle { if q.OrderByTitle {
s.WriteString(` ORDER BY f0.title ASC`) s.WriteString(` ORDER BY f0.title ASC`)
} }
@ -503,8 +503,8 @@ func (ss *sqlStore) GetFolders(ctx context.Context, q getFoldersQuery) ([]*folde
} }
// filter out folders if they are not in the subtree of the given ancestor folders // filter out folders if they are not in the subtree of the given ancestor folders
if err := batch(len(q.ancestorUIDs), int(q.BatchSize), func(start2, end2 int) error { if err := batch(len(q.AncestorUIDs), int(q.BatchSize), func(start2, end2 int) error {
s2, args2 := getAncestorsSQL(ss.db.GetDialect(), q.ancestorUIDs, start2, end2, s.String(), args) s2, args2 := getAncestorsSQL(ss.db.GetDialect(), q.AncestorUIDs, start2, end2, s.String(), args)
if q.OrderByTitle { if q.OrderByTitle {
s2 += " ORDER BY f0.title ASC" s2 += " ORDER BY f0.title ASC"
} }
@ -533,7 +533,7 @@ func (ss *sqlStore) GetFolders(ctx context.Context, q getFoldersQuery) ([]*folde
return folders, nil return folders, nil
} }
func (ss *sqlStore) GetDescendants(ctx context.Context, orgID int64, ancestor_uid string) ([]*folder.Folder, error) { func (ss *FolderStoreImpl) GetDescendants(ctx context.Context, orgID int64, ancestor_uid string) ([]*folder.Folder, error) {
var folders []*folder.Folder var folders []*folder.Folder
recursiveQueriesAreSupported, err := ss.db.RecursiveQueriesAreSupported() recursiveQueriesAreSupported, err := ss.db.RecursiveQueriesAreSupported()

View File

@ -865,7 +865,7 @@ func TestIntegrationGetFolders(t *testing.T) {
}) })
t.Run("get folders by UIDs should succeed", func(t *testing.T) { t.Run("get folders by UIDs should succeed", func(t *testing.T) {
actualFolders, err := folderStore.GetFolders(context.Background(), NewGetFoldersQuery(folder.GetFoldersQuery{OrgID: orgID, UIDs: uids[1:]})) actualFolders, err := folderStore.GetFolders(context.Background(), folder.NewGetFoldersQuery(folder.GetFoldersQuery{OrgID: orgID, UIDs: uids[1:]}))
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, len(uids[1:]), len(actualFolders)) assert.Equal(t, len(uids[1:]), len(actualFolders))
for _, f := range folders[1:] { for _, f := range folders[1:] {
@ -885,7 +885,7 @@ func TestIntegrationGetFolders(t *testing.T) {
}) })
t.Run("get folders by UIDs batching should work as expected", func(t *testing.T) { t.Run("get folders by UIDs batching should work as expected", func(t *testing.T) {
q := NewGetFoldersQuery(folder.GetFoldersQuery{OrgID: orgID, UIDs: uids[1:], BatchSize: 3}) q := folder.NewGetFoldersQuery(folder.GetFoldersQuery{OrgID: orgID, UIDs: uids[1:], BatchSize: 3})
actualFolders, err := folderStore.GetFolders(context.Background(), q) actualFolders, err := folderStore.GetFolders(context.Background(), q)
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, len(uids[1:]), len(actualFolders)) assert.Equal(t, len(uids[1:]), len(actualFolders))
@ -906,7 +906,7 @@ func TestIntegrationGetFolders(t *testing.T) {
}) })
t.Run("get folders by UIDs with fullpath should succeed", func(t *testing.T) { t.Run("get folders by UIDs with fullpath should succeed", func(t *testing.T) {
q := NewGetFoldersQuery(folder.GetFoldersQuery{OrgID: orgID, UIDs: uids[1:], WithFullpath: true}) q := folder.NewGetFoldersQuery(folder.GetFoldersQuery{OrgID: orgID, UIDs: uids[1:], WithFullpath: true})
q.BatchSize = 3 q.BatchSize = 3
actualFolders, err := folderStore.GetFolders(context.Background(), q) actualFolders, err := folderStore.GetFolders(context.Background(), q)
require.NoError(t, err) require.NoError(t, err)
@ -929,12 +929,12 @@ func TestIntegrationGetFolders(t *testing.T) {
}) })
t.Run("get folders by UIDs and ancestor UIDs should work as expected", func(t *testing.T) { t.Run("get folders by UIDs and ancestor UIDs should work as expected", func(t *testing.T) {
q := NewGetFoldersQuery(folder.GetFoldersQuery{OrgID: orgID, UIDs: uids[1:], BatchSize: 3}) q := folder.NewGetFoldersQuery(folder.GetFoldersQuery{OrgID: orgID, UIDs: uids[1:], BatchSize: 3})
q.ancestorUIDs = make([]string, 0, int(q.BatchSize)+1) q.AncestorUIDs = make([]string, 0, int(q.BatchSize)+1)
for i := 0; i < int(q.BatchSize); i++ { for i := 0; i < int(q.BatchSize); i++ {
q.ancestorUIDs = append(q.ancestorUIDs, uuid.New().String()) q.AncestorUIDs = append(q.AncestorUIDs, uuid.New().String())
} }
q.ancestorUIDs = append(q.ancestorUIDs, folders[len(folders)-1].UID) q.AncestorUIDs = append(q.AncestorUIDs, folders[len(folders)-1].UID)
actualFolders, err := folderStore.GetFolders(context.Background(), q) actualFolders, err := folderStore.GetFolders(context.Background(), q)
require.NoError(t, err) require.NoError(t, err)
@ -967,7 +967,7 @@ func CreateOrg(t *testing.T, db db.DB, cfg *setting.Cfg) int64 {
return orgID return orgID
} }
func CreateSubtree(t *testing.T, store *sqlStore, orgID int64, parentUID string, depth int, prefix string) []string { func CreateSubtree(t *testing.T, store *FolderStoreImpl, orgID int64, parentUID string, depth int, prefix string) []string {
t.Helper() t.Helper()
ancestorUIDs := []string{} ancestorUIDs := []string{}
@ -1006,7 +1006,7 @@ func CreateSubtree(t *testing.T, store *sqlStore, orgID int64, parentUID string,
return ancestorUIDs return ancestorUIDs
} }
func CreateLeaves(t *testing.T, store *sqlStore, parent *folder.Folder, num int) []string { func CreateLeaves(t *testing.T, store *FolderStoreImpl, parent *folder.Folder, num int) []string {
t.Helper() t.Helper()
leaves := make([]string, 0) leaves := make([]string, 0)
@ -1024,7 +1024,7 @@ func CreateLeaves(t *testing.T, store *sqlStore, parent *folder.Folder, num int)
return leaves return leaves
} }
func assertAncestorUIDs(t *testing.T, store *sqlStore, f *folder.Folder, expected []string) { func assertAncestorUIDs(t *testing.T, store *FolderStoreImpl, f *folder.Folder, expected []string) {
t.Helper() t.Helper()
ancestors, err := store.GetParents(context.Background(), folder.GetParentsQuery{ ancestors, err := store.GetParents(context.Background(), folder.GetParentsQuery{
@ -1039,7 +1039,7 @@ func assertAncestorUIDs(t *testing.T, store *sqlStore, f *folder.Folder, expecte
assert.Equal(t, expected, actualAncestorsUIDs) assert.Equal(t, expected, actualAncestorsUIDs)
} }
func assertChildrenUIDs(t *testing.T, store *sqlStore, f *folder.Folder, expected []string) { func assertChildrenUIDs(t *testing.T, store *FolderStoreImpl, f *folder.Folder, expected []string) {
t.Helper() t.Helper()
ancestors, err := store.GetChildren(context.Background(), folder.GetChildrenQuery{ ancestors, err := store.GetChildren(context.Background(), folder.GetChildrenQuery{

View File

@ -1,66 +0,0 @@
package folderimpl
import (
"context"
"github.com/grafana/grafana/pkg/services/folder"
)
type fakeStore struct {
ExpectedChildFolders []*folder.Folder
ExpectedParentFolders []*folder.Folder
ExpectedFolders []*folder.Folder
ExpectedFolder *folder.Folder
ExpectedError error
ExpectedFolderHeight int
CreateCalled bool
DeleteCalled bool
}
func NewFakeStore() *fakeStore {
return &fakeStore{}
}
var _ store = (*fakeStore)(nil)
func (f *fakeStore) Create(ctx context.Context, cmd folder.CreateFolderCommand) (*folder.Folder, error) {
f.CreateCalled = true
return f.ExpectedFolder, f.ExpectedError
}
func (f *fakeStore) Delete(ctx context.Context, UIDs []string, orgID int64) error {
f.DeleteCalled = true
return f.ExpectedError
}
func (f *fakeStore) Update(ctx context.Context, cmd folder.UpdateFolderCommand) (*folder.Folder, error) {
return f.ExpectedFolder, f.ExpectedError
}
func (f *fakeStore) Move(ctx context.Context, cmd folder.MoveFolderCommand) error {
return f.ExpectedError
}
func (f *fakeStore) Get(ctx context.Context, cmd folder.GetFolderQuery) (*folder.Folder, error) {
return f.ExpectedFolder, f.ExpectedError
}
func (f *fakeStore) GetParents(ctx context.Context, q folder.GetParentsQuery) ([]*folder.Folder, error) {
return f.ExpectedParentFolders, f.ExpectedError
}
func (f *fakeStore) GetChildren(ctx context.Context, cmd folder.GetChildrenQuery) ([]*folder.Folder, error) {
return f.ExpectedChildFolders, f.ExpectedError
}
func (f *fakeStore) GetHeight(ctx context.Context, folderUID string, orgID int64, parentUID *string) (int, error) {
return f.ExpectedFolderHeight, f.ExpectedError
}
func (f *fakeStore) GetFolders(ctx context.Context, q getFoldersQuery) ([]*folder.Folder, error) {
return f.ExpectedFolders, f.ExpectedError
}
func (f *fakeStore) GetDescendants(ctx context.Context, orgID int64, ancestor_uid string) ([]*folder.Folder, error) {
return f.ExpectedFolders, f.ExpectedError
}

View File

@ -1,27 +1,25 @@
package folderimpl package folder
import ( import (
"context" "context"
"github.com/grafana/grafana/pkg/services/folder"
) )
type getFoldersQuery struct { type GetFoldersFromStoreQuery struct {
folder.GetFoldersQuery GetFoldersQuery
ancestorUIDs []string AncestorUIDs []string
} }
func NewGetFoldersQuery(q folder.GetFoldersQuery) getFoldersQuery { func NewGetFoldersQuery(q GetFoldersQuery) GetFoldersFromStoreQuery {
return getFoldersQuery{ return GetFoldersFromStoreQuery{
GetFoldersQuery: q, GetFoldersQuery: q,
ancestorUIDs: []string{}, AncestorUIDs: []string{},
} }
} }
// store is the interface which a folder store must implement. // Store is the interface which a folder Store must implement.
type store interface { type Store interface {
// Create creates a folder and returns the newly-created folder. // Create creates a folder and returns the newly-created folder.
Create(ctx context.Context, cmd folder.CreateFolderCommand) (*folder.Folder, error) Create(ctx context.Context, cmd CreateFolderCommand) (*Folder, error)
// Delete folders with the specified UIDs and orgID from the folder store. // Delete folders with the specified UIDs and orgID from the folder store.
Delete(ctx context.Context, UIDs []string, orgID int64) error Delete(ctx context.Context, UIDs []string, orgID int64) error
@ -30,24 +28,24 @@ type store interface {
// If the NewParentUID field is not nil, it updates also the parent UID (move mode). // If the NewParentUID field is not nil, it updates also the parent UID (move mode).
// If it's a non empty string, it moves the folder under the folder with the specific UID // If it's a non empty string, it moves the folder under the folder with the specific UID
// otherwise, it moves the folder under the root folder (parent_uid column is set to NULL). // otherwise, it moves the folder under the root folder (parent_uid column is set to NULL).
Update(ctx context.Context, cmd folder.UpdateFolderCommand) (*folder.Folder, error) Update(ctx context.Context, cmd UpdateFolderCommand) (*Folder, error)
// Get returns a folder. // Get returns a folder.
Get(ctx context.Context, q folder.GetFolderQuery) (*folder.Folder, error) Get(ctx context.Context, q GetFolderQuery) (*Folder, error)
// GetParents returns an ordered list of parent folder of the given folder. // GetParents returns an ordered list of parent folder of the given folder.
GetParents(ctx context.Context, q folder.GetParentsQuery) ([]*folder.Folder, error) GetParents(ctx context.Context, q GetParentsQuery) ([]*Folder, error)
// GetChildren returns the set of immediate children folders (depth=1) of the // GetChildren returns the set of immediate children folders (depth=1) of the
// given folder. // given folder.
GetChildren(ctx context.Context, q folder.GetChildrenQuery) ([]*folder.Folder, error) GetChildren(ctx context.Context, q GetChildrenQuery) ([]*Folder, error)
// GetHeight returns the height of the folder tree. When parentUID is set, the function would // GetHeight returns the height of the folder tree. When parentUID is set, the function would
// verify in the meanwhile that parentUID is not present in the subtree of the folder with the given UID. // verify in the meanwhile that parentUID is not present in the subtree of the folder with the given UID.
GetHeight(ctx context.Context, foldrUID string, orgID int64, parentUID *string) (int, error) GetHeight(ctx context.Context, foldrUID string, orgID int64, parentUID *string) (int, error)
// GetFolders returns folders with given uids // GetFolders returns folders with given uids
GetFolders(ctx context.Context, q getFoldersQuery) ([]*folder.Folder, error) GetFolders(ctx context.Context, q GetFoldersFromStoreQuery) ([]*Folder, error)
// GetDescendants returns all descendants of a folder // GetDescendants returns all descendants of a folder
GetDescendants(ctx context.Context, orgID int64, anchestor_uid string) ([]*folder.Folder, error) GetDescendants(ctx context.Context, orgID int64, anchestor_uid string) ([]*Folder, error)
} }

View File

@ -0,0 +1,64 @@
package folder
import (
"context"
)
type fakeStore struct {
ExpectedChildFolders []*Folder
ExpectedParentFolders []*Folder
ExpectedFolders []*Folder
ExpectedFolder *Folder
ExpectedError error
ExpectedFolderHeight int
CreateCalled bool
DeleteCalled bool
}
func NewFakeStore() *fakeStore {
return &fakeStore{}
}
var _ Store = (*fakeStore)(nil)
func (f *fakeStore) Create(ctx context.Context, cmd CreateFolderCommand) (*Folder, error) {
f.CreateCalled = true
return f.ExpectedFolder, f.ExpectedError
}
func (f *fakeStore) Delete(ctx context.Context, UIDs []string, orgID int64) error {
f.DeleteCalled = true
return f.ExpectedError
}
func (f *fakeStore) Update(ctx context.Context, cmd UpdateFolderCommand) (*Folder, error) {
return f.ExpectedFolder, f.ExpectedError
}
func (f *fakeStore) Move(ctx context.Context, cmd MoveFolderCommand) error {
return f.ExpectedError
}
func (f *fakeStore) Get(ctx context.Context, cmd GetFolderQuery) (*Folder, error) {
return f.ExpectedFolder, f.ExpectedError
}
func (f *fakeStore) GetParents(ctx context.Context, q GetParentsQuery) ([]*Folder, error) {
return f.ExpectedParentFolders, f.ExpectedError
}
func (f *fakeStore) GetChildren(ctx context.Context, cmd GetChildrenQuery) ([]*Folder, error) {
return f.ExpectedChildFolders, f.ExpectedError
}
func (f *fakeStore) GetHeight(ctx context.Context, folderUID string, orgID int64, parentUID *string) (int, error) {
return f.ExpectedFolderHeight, f.ExpectedError
}
func (f *fakeStore) GetFolders(ctx context.Context, q GetFoldersFromStoreQuery) ([]*Folder, error) {
return f.ExpectedFolders, f.ExpectedError
}
func (f *fakeStore) GetDescendants(ctx context.Context, orgID int64, ancestor_uid string) ([]*Folder, error) {
return f.ExpectedFolders, f.ExpectedError
}

View File

@ -308,6 +308,7 @@ func createDashboard(t *testing.T, sqlStore db.DB, user user.SignedInUser, dash
cfg, dashboardStore, folderStore, cfg, dashboardStore, folderStore,
features, folderPermissions, dashboardPermissions, ac, features, folderPermissions, dashboardPermissions, ac,
foldertest.NewFakeService(), foldertest.NewFakeService(),
folder.NewFakeStore(),
nil, nil,
) )
require.NoError(t, err) require.NoError(t, err)
@ -328,7 +329,9 @@ func createFolder(t *testing.T, sc scenarioContext, title string) *folder.Folder
require.NoError(t, err) require.NoError(t, err)
folderStore := folderimpl.ProvideDashboardFolderStore(sc.sqlStore) folderStore := folderimpl.ProvideDashboardFolderStore(sc.sqlStore)
s := folderimpl.ProvideService(ac, bus.ProvideBus(tracing.InitializeTracerForTest()), dashboardStore, folderStore, sc.sqlStore, features, supportbundlestest.NewFakeBundleService(), nil, tracing.InitializeTracerForTest()) store := folderimpl.ProvideStore(sc.sqlStore)
s := folderimpl.ProvideService(store, ac, bus.ProvideBus(tracing.InitializeTracerForTest()), dashboardStore, folderStore, sc.sqlStore,
features, supportbundlestest.NewFakeBundleService(), nil, tracing.InitializeTracerForTest())
t.Logf("Creating folder with title and UID %q", title) t.Logf("Creating folder with title and UID %q", title)
ctx := identity.WithRequester(context.Background(), &sc.user) ctx := identity.WithRequester(context.Background(), &sc.user)
folder, err := s.Create(ctx, &folder.CreateFolderCommand{ folder, err := s.Create(ctx, &folder.CreateFolderCommand{
@ -391,7 +394,7 @@ func scenarioWithPanel(t *testing.T, desc string, fn func(t *testing.T, sc scena
dashboardService, svcErr := dashboardservice.ProvideDashboardServiceImpl( dashboardService, svcErr := dashboardservice.ProvideDashboardServiceImpl(
cfg, dashboardStore, folderStore, cfg, dashboardStore, folderStore,
features, folderPermissions, dashboardPermissions, ac, features, folderPermissions, dashboardPermissions, ac,
foldertest.NewFakeService(), foldertest.NewFakeService(), folder.NewFakeStore(),
nil, nil,
) )
require.NoError(t, svcErr) require.NoError(t, svcErr)
@ -453,16 +456,19 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo
dashService, dashSvcErr := dashboardservice.ProvideDashboardServiceImpl( dashService, dashSvcErr := dashboardservice.ProvideDashboardServiceImpl(
cfg, dashboardStore, folderStore, cfg, dashboardStore, folderStore,
features, folderPermissions, dashboardPermissions, ac, features, folderPermissions, dashboardPermissions, ac,
foldertest.NewFakeService(), foldertest.NewFakeService(), folder.NewFakeStore(),
nil, nil,
) )
require.NoError(t, dashSvcErr) require.NoError(t, dashSvcErr)
guardian.InitAccessControlGuardian(cfg, ac, dashService) guardian.InitAccessControlGuardian(cfg, ac, dashService)
fStore := folderimpl.ProvideStore(sqlStore)
folderSrv := folderimpl.ProvideService(fStore, ac, bus.ProvideBus(tracer), dashboardStore, folderStore, sqlStore,
features, supportbundlestest.NewFakeBundleService(), nil, tracing.InitializeTracerForTest())
service := LibraryElementService{ service := LibraryElementService{
Cfg: cfg, Cfg: cfg,
features: featuremgmt.WithFeatures(), features: featuremgmt.WithFeatures(),
SQLStore: sqlStore, SQLStore: sqlStore,
folderService: folderimpl.ProvideService(ac, bus.ProvideBus(tracer), dashboardStore, folderStore, sqlStore, features, supportbundlestest.NewFakeBundleService(), nil, tracing.InitializeTracerForTest()), folderService: folderSrv,
} }
// deliberate difference between signed in user and user in db to make it crystal clear // deliberate difference between signed in user and user in db to make it crystal clear

View File

@ -732,7 +732,7 @@ func createDashboard(t *testing.T, sqlStore db.DB, user *user.SignedInUser, dash
service, err := dashboardservice.ProvideDashboardServiceImpl( service, err := dashboardservice.ProvideDashboardServiceImpl(
cfg, dashboardStore, folderStore, cfg, dashboardStore, folderStore,
featuremgmt.WithFeatures(), acmock.NewMockedPermissionsService(), dashPermissionService, ac, featuremgmt.WithFeatures(), acmock.NewMockedPermissionsService(), dashPermissionService, ac,
foldertest.NewFakeService(), foldertest.NewFakeService(), folder.NewFakeStore(),
nil, nil,
) )
require.NoError(t, err) require.NoError(t, err)
@ -752,7 +752,9 @@ func createFolder(t *testing.T, sc scenarioContext, title string) *folder.Folder
dashboardStore, err := database.ProvideDashboardStore(sc.sqlStore, cfg, features, tagimpl.ProvideService(sc.sqlStore), quotaService) dashboardStore, err := database.ProvideDashboardStore(sc.sqlStore, cfg, features, tagimpl.ProvideService(sc.sqlStore), quotaService)
require.NoError(t, err) require.NoError(t, err)
folderStore := folderimpl.ProvideDashboardFolderStore(sc.sqlStore) folderStore := folderimpl.ProvideDashboardFolderStore(sc.sqlStore)
s := folderimpl.ProvideService(ac, bus.ProvideBus(tracing.InitializeTracerForTest()), dashboardStore, folderStore, sc.sqlStore, features, supportbundlestest.NewFakeBundleService(), nil, tracing.InitializeTracerForTest()) fStore := folderimpl.ProvideStore(sc.sqlStore)
s := folderimpl.ProvideService(fStore, ac, bus.ProvideBus(tracing.InitializeTracerForTest()), dashboardStore, folderStore, sc.sqlStore,
features, supportbundlestest.NewFakeBundleService(), nil, tracing.InitializeTracerForTest())
t.Logf("Creating folder with title and UID %q", title) t.Logf("Creating folder with title and UID %q", title)
ctx := identity.WithRequester(context.Background(), sc.user) ctx := identity.WithRequester(context.Background(), sc.user)
@ -816,6 +818,7 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo
role := org.RoleAdmin role := org.RoleAdmin
sqlStore, cfg := db.InitTestDBWithCfg(t) sqlStore, cfg := db.InitTestDBWithCfg(t)
quotaService := quotatest.New(false, nil) quotaService := quotatest.New(false, nil)
features := featuremgmt.WithFeatures()
ac := actest.FakeAccessControl{ExpectedEvaluate: true} ac := actest.FakeAccessControl{ExpectedEvaluate: true}
dashStore := &dashboards.FakeDashboardStore{} dashStore := &dashboards.FakeDashboardStore{}
@ -823,20 +826,22 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo
folderStore := folderimpl.ProvideDashboardFolderStore(sqlStore) folderStore := folderimpl.ProvideDashboardFolderStore(sqlStore)
dashPermissionService := acmock.NewMockedPermissionsService() dashPermissionService := acmock.NewMockedPermissionsService()
dashService, err := dashboardservice.ProvideDashboardServiceImpl( dashService, err := dashboardservice.ProvideDashboardServiceImpl(
setting.NewCfg(), dashStore, folderStore, cfg, dashStore, folderStore,
featuremgmt.WithFeatures(), acmock.NewMockedPermissionsService(), dashPermissionService, ac, features, acmock.NewMockedPermissionsService(), dashPermissionService, ac,
foldertest.NewFakeService(), foldertest.NewFakeService(), folder.NewFakeStore(),
nil, nil,
) )
require.NoError(t, err) require.NoError(t, err)
guardian.InitAccessControlGuardian(setting.NewCfg(), ac, dashService) guardian.InitAccessControlGuardian(cfg, ac, dashService)
dashboardStore, err := database.ProvideDashboardStore(sqlStore, cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore), quotaService) dashboardStore, err := database.ProvideDashboardStore(sqlStore, cfg, features, tagimpl.ProvideService(sqlStore), quotaService)
require.NoError(t, err) require.NoError(t, err)
features := featuremgmt.WithFeatures() fStore := folderimpl.ProvideStore(sqlStore)
folderService := folderimpl.ProvideService(ac, bus.ProvideBus(tracing.InitializeTracerForTest()), dashboardStore, folderStore, sqlStore, features, supportbundlestest.NewFakeBundleService(), nil, tracing.InitializeTracerForTest())
elementService := libraryelements.ProvideService(cfg, sqlStore, routing.NewRouteRegister(), folderService, featuremgmt.WithFeatures(), ac) folderService := folderimpl.ProvideService(fStore, ac, bus.ProvideBus(tracing.InitializeTracerForTest()), dashboardStore, folderStore, sqlStore,
features, supportbundlestest.NewFakeBundleService(), nil, tracing.InitializeTracerForTest())
elementService := libraryelements.ProvideService(cfg, sqlStore, routing.NewRouteRegister(), folderService, features, ac)
service := LibraryPanelService{ service := LibraryPanelService{
Cfg: cfg, Cfg: cfg,
SQLStore: sqlStore, SQLStore: sqlStore,

View File

@ -1821,7 +1821,9 @@ func createTestEnv(t *testing.T, testConfig string) testEnvironment {
require.NoError(t, err) require.NoError(t, err)
folderStore := folderimpl.ProvideDashboardFolderStore(sqlStore) folderStore := folderimpl.ProvideDashboardFolderStore(sqlStore)
folderService := folderimpl.ProvideService(actest.FakeAccessControl{ExpectedEvaluate: true}, bus.ProvideBus(tracing.InitializeTracerForTest()), dashboardStore, folderStore, sqlStore, featuremgmt.WithFeatures(), supportbundlestest.NewFakeBundleService(), nil, tracing.InitializeTracerForTest()) fStore := folderimpl.ProvideStore(sqlStore)
folderService := folderimpl.ProvideService(fStore, actest.FakeAccessControl{ExpectedEvaluate: true}, bus.ProvideBus(tracing.InitializeTracerForTest()), dashboardStore, folderStore, sqlStore,
featuremgmt.WithFeatures(), supportbundlestest.NewFakeBundleService(), nil, tracing.InitializeTracerForTest())
store := store.DBstore{ store := store.DBstore{
Logger: log, Logger: log,
SQLStore: sqlStore, SQLStore: sqlStore,

View File

@ -1542,13 +1542,14 @@ func TestDeleteRuleGroup(t *testing.T) {
func TestProvisiongWithFullpath(t *testing.T) { func TestProvisiongWithFullpath(t *testing.T) {
tracer := tracing.InitializeTracerForTest() tracer := tracing.InitializeTracerForTest()
inProcBus := bus.ProvideBus(tracer) inProcBus := bus.ProvideBus(tracer)
sqlStore := db.InitTestDB(t) sqlStore, cfg := db.InitTestDBWithCfg(t)
cfg := setting.NewCfg()
folderStore := folderimpl.ProvideDashboardFolderStore(sqlStore) folderStore := folderimpl.ProvideDashboardFolderStore(sqlStore)
_, dashboardStore := testutil.SetupDashboardService(t, sqlStore, folderStore, cfg) _, dashboardStore := testutil.SetupDashboardService(t, sqlStore, folderStore, cfg)
ac := acmock.New() ac := acmock.New()
features := featuremgmt.WithFeatures(featuremgmt.FlagNestedFolders) features := featuremgmt.WithFeatures(featuremgmt.FlagNestedFolders)
folderService := folderimpl.ProvideService(ac, inProcBus, dashboardStore, folderStore, sqlStore, features, supportbundlestest.NewFakeBundleService(), nil, tracing.InitializeTracerForTest()) fStore := folderimpl.ProvideStore(sqlStore)
folderService := folderimpl.ProvideService(fStore, ac, inProcBus, dashboardStore, folderStore, sqlStore,
features, supportbundlestest.NewFakeBundleService(), nil, tracing.InitializeTracerForTest())
ruleService := createAlertRuleService(t, folderService) ruleService := createAlertRuleService(t, folderService)
var orgID int64 = 1 var orgID int64 = 1

View File

@ -27,7 +27,9 @@ import (
func SetupFolderService(tb testing.TB, cfg *setting.Cfg, db db.DB, dashboardStore dashboards.Store, folderStore *folderimpl.DashboardFolderStoreImpl, bus *bus.InProcBus, features featuremgmt.FeatureToggles, ac accesscontrol.AccessControl) folder.Service { func SetupFolderService(tb testing.TB, cfg *setting.Cfg, db db.DB, dashboardStore dashboards.Store, folderStore *folderimpl.DashboardFolderStoreImpl, bus *bus.InProcBus, features featuremgmt.FeatureToggles, ac accesscontrol.AccessControl) folder.Service {
tb.Helper() tb.Helper()
return folderimpl.ProvideService(ac, bus, dashboardStore, folderStore, db, features, supportbundlestest.NewFakeBundleService(), nil, tracing.InitializeTracerForTest()) fStore := folderimpl.ProvideStore(db)
return folderimpl.ProvideService(fStore, ac, bus, dashboardStore, folderStore, db,
features, supportbundlestest.NewFakeBundleService(), nil, tracing.InitializeTracerForTest())
} }
func SetupDashboardService(tb testing.TB, sqlStore db.DB, fs *folderimpl.DashboardFolderStoreImpl, cfg *setting.Cfg) (*dashboardservice.DashboardServiceImpl, dashboards.Store) { func SetupDashboardService(tb testing.TB, sqlStore db.DB, fs *folderimpl.DashboardFolderStoreImpl, cfg *setting.Cfg) (*dashboardservice.DashboardServiceImpl, dashboards.Store) {
@ -57,7 +59,7 @@ func SetupDashboardService(tb testing.TB, sqlStore db.DB, fs *folderimpl.Dashboa
dashboardService, err := dashboardservice.ProvideDashboardServiceImpl( dashboardService, err := dashboardservice.ProvideDashboardServiceImpl(
cfg, dashboardStore, fs, cfg, dashboardStore, fs,
features, folderPermissions, dashboardPermissions, ac, features, folderPermissions, dashboardPermissions, ac,
foldertest.NewFakeService(), foldertest.NewFakeService(), folder.NewFakeStore(),
nil, nil,
) )
require.NoError(tb, err) require.NoError(tb, err)

View File

@ -31,6 +31,7 @@ import (
"github.com/grafana/grafana/pkg/services/datasources/guardian" "github.com/grafana/grafana/pkg/services/datasources/guardian"
datasourcesService "github.com/grafana/grafana/pkg/services/datasources/service" datasourcesService "github.com/grafana/grafana/pkg/services/datasources/service"
"github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/folder"
"github.com/grafana/grafana/pkg/services/folder/folderimpl" "github.com/grafana/grafana/pkg/services/folder/folderimpl"
"github.com/grafana/grafana/pkg/services/folder/foldertest" "github.com/grafana/grafana/pkg/services/folder/foldertest"
"github.com/grafana/grafana/pkg/services/licensing/licensingtest" "github.com/grafana/grafana/pkg/services/licensing/licensingtest"
@ -323,7 +324,7 @@ func TestIntegrationUnauthenticatedUserCanGetPubdashPanelQueryData(t *testing.T)
dashService, err := service.ProvideDashboardServiceImpl( dashService, err := service.ProvideDashboardServiceImpl(
cfg, dashboardStoreService, folderStore, cfg, dashboardStoreService, folderStore,
featuremgmt.WithFeatures(), acmock.NewMockedPermissionsService(), dashPermissionService, ac, featuremgmt.WithFeatures(), acmock.NewMockedPermissionsService(), dashPermissionService, ac,
foldertest.NewFakeService(), nil, foldertest.NewFakeService(), folder.NewFakeStore(), nil,
) )
require.NoError(t, err) require.NoError(t, err)

View File

@ -822,7 +822,9 @@ func setupNestedTest(t *testing.T, usr *user.SignedInUser, perms []accesscontrol
dashStore, err := database.ProvideDashboardStore(db, cfg, features, tagimpl.ProvideService(db), quotatest.New(false, nil)) dashStore, err := database.ProvideDashboardStore(db, cfg, features, tagimpl.ProvideService(db), quotatest.New(false, nil))
require.NoError(t, err) require.NoError(t, err)
folderSvc := folderimpl.ProvideService(actest.FakeAccessControl{ExpectedEvaluate: true}, bus.ProvideBus(tracing.InitializeTracerForTest()), dashStore, folderimpl.ProvideDashboardFolderStore(db), db, features, supportbundlestest.NewFakeBundleService(), nil, tracing.InitializeTracerForTest()) fStore := folderimpl.ProvideStore(db)
folderSvc := folderimpl.ProvideService(fStore, actest.FakeAccessControl{ExpectedEvaluate: true}, bus.ProvideBus(tracing.InitializeTracerForTest()), dashStore,
folderimpl.ProvideDashboardFolderStore(db), db, features, supportbundlestest.NewFakeBundleService(), nil, tracing.InitializeTracerForTest())
// create parent folder // create parent folder
parent, err := folderSvc.Create(context.Background(), &folder.CreateFolderCommand{ parent, err := folderSvc.Create(context.Background(), &folder.CreateFolderCommand{

View File

@ -81,7 +81,9 @@ func setupBenchMark(b *testing.B, usr user.SignedInUser, features featuremgmt.Fe
dashboardWriteStore, err := database.ProvideDashboardStore(store, cfg, features, tagimpl.ProvideService(store), quotaService) dashboardWriteStore, err := database.ProvideDashboardStore(store, cfg, features, tagimpl.ProvideService(store), quotaService)
require.NoError(b, err) require.NoError(b, err)
folderSvc := folderimpl.ProvideService(mock.New(), bus.ProvideBus(tracing.InitializeTracerForTest()), dashboardWriteStore, folderimpl.ProvideDashboardFolderStore(store), store, features, supportbundlestest.NewFakeBundleService(), nil, tracing.InitializeTracerForTest()) fStore := folderimpl.ProvideStore(store)
folderSvc := folderimpl.ProvideService(fStore, mock.New(), bus.ProvideBus(tracing.InitializeTracerForTest()), dashboardWriteStore, folderimpl.ProvideDashboardFolderStore(store),
store, features, supportbundlestest.NewFakeBundleService(), nil, tracing.InitializeTracerForTest())
origNewGuardian := guardian.New origNewGuardian := guardian.New
guardian.MockDashboardGuardian(&guardian.FakeDashboardGuardian{CanViewValue: true, CanSaveValue: true}) guardian.MockDashboardGuardian(&guardian.FakeDashboardGuardian{CanViewValue: true, CanSaveValue: true})