Chore: Split folder store and dashboard store interfaces (#61655)

* update folder store mock

* Split folder store and dashboard store interfaces
This commit is contained in:
Sofia Papagiannaki
2023-01-19 18:38:07 +02:00
committed by GitHub
parent a6102105af
commit c104cc7020
19 changed files with 238 additions and 268 deletions
+28 -25
View File
@@ -30,13 +30,14 @@ import (
type Service struct {
store store
log log.Logger
cfg *setting.Cfg
dashboardStore dashboards.Store
searchService *search.SearchService
features featuremgmt.FeatureToggles
permissions accesscontrol.FolderPermissionsService
accessControl accesscontrol.AccessControl
log log.Logger
cfg *setting.Cfg
dashboardStore dashboards.Store
dashboardFolderStore dashboards.FolderStore
searchService *search.SearchService
features featuremgmt.FeatureToggles
permissions accesscontrol.FolderPermissionsService
accessControl accesscontrol.AccessControl
// bus is currently used to publish events that cause scheduler to update rules.
bus bus.Bus
@@ -47,24 +48,26 @@ func ProvideService(
bus bus.Bus,
cfg *setting.Cfg,
dashboardStore dashboards.Store,
folderStore dashboards.FolderStore,
db db.DB, // DB for the (new) nested folder store
features featuremgmt.FeatureToggles,
folderPermissionsService accesscontrol.FolderPermissionsService,
searchService *search.SearchService,
) folder.Service {
ac.RegisterScopeAttributeResolver(dashboards.NewFolderNameScopeResolver(dashboardStore))
ac.RegisterScopeAttributeResolver(dashboards.NewFolderIDScopeResolver(dashboardStore))
ac.RegisterScopeAttributeResolver(dashboards.NewFolderNameScopeResolver(dashboardStore, folderStore))
ac.RegisterScopeAttributeResolver(dashboards.NewFolderIDScopeResolver(dashboardStore, folderStore))
store := ProvideStore(db, cfg, features)
svr := &Service{
cfg: cfg,
log: log.New("folder-service"),
dashboardStore: dashboardStore,
store: store,
searchService: searchService,
features: features,
permissions: folderPermissionsService,
accessControl: ac,
bus: bus,
cfg: cfg,
log: log.New("folder-service"),
dashboardStore: dashboardStore,
dashboardFolderStore: folderStore,
store: store,
searchService: searchService,
features: features,
permissions: folderPermissionsService,
accessControl: ac,
bus: bus,
}
if features.IsEnabled(featuremgmt.FlagNestedFolders) {
svr.DBMigration(db)
@@ -166,7 +169,7 @@ func (s *Service) GetChildren(ctx context.Context, cmd *folder.GetChildrenQuery)
filtered := make([]*folder.Folder, 0, len(children))
for _, f := range children {
// fetch folder from dashboard store
dashFolder, err := s.dashboardStore.GetFolderByUID(ctx, f.OrgID, f.UID)
dashFolder, err := s.dashboardFolderStore.GetFolderByUID(ctx, f.OrgID, f.UID)
if err != nil {
s.log.Error("failed to fetch folder by UID: %s from dashboard store", f.UID, err)
continue
@@ -220,7 +223,7 @@ func (s *Service) getFolderByID(ctx context.Context, user *user.SignedInUser, id
return &folder.Folder{ID: id, Title: "General"}, nil
}
dashFolder, err := s.dashboardStore.GetFolderByID(ctx, orgID, id)
dashFolder, err := s.dashboardFolderStore.GetFolderByID(ctx, orgID, id)
if err != nil {
return nil, err
}
@@ -244,7 +247,7 @@ func (s *Service) getFolderByID(ctx context.Context, user *user.SignedInUser, id
}
func (s *Service) getFolderByUID(ctx context.Context, user *user.SignedInUser, orgID int64, uid string) (*folder.Folder, error) {
dashFolder, err := s.dashboardStore.GetFolderByUID(ctx, orgID, uid)
dashFolder, err := s.dashboardFolderStore.GetFolderByUID(ctx, orgID, uid)
if err != nil {
return nil, err
}
@@ -268,7 +271,7 @@ func (s *Service) getFolderByUID(ctx context.Context, user *user.SignedInUser, o
}
func (s *Service) getFolderByTitle(ctx context.Context, user *user.SignedInUser, orgID int64, title string) (*folder.Folder, error) {
dashFolder, err := s.dashboardStore.GetFolderByTitle(ctx, orgID, title)
dashFolder, err := s.dashboardFolderStore.GetFolderByTitle(ctx, orgID, title)
if err != nil {
return nil, err
}
@@ -330,7 +333,7 @@ func (s *Service) Create(ctx context.Context, cmd *folder.CreateFolderCommand) (
}
var createdFolder *folder.Folder
createdFolder, err = s.dashboardStore.GetFolderByID(ctx, cmd.OrgID, dash.ID)
createdFolder, err = s.dashboardFolderStore.GetFolderByID(ctx, cmd.OrgID, dash.ID)
if err != nil {
return nil, err
}
@@ -475,7 +478,7 @@ func (s *Service) legacyUpdate(ctx context.Context, cmd *folder.UpdateFolderComm
}
var foldr *folder.Folder
foldr, err = s.dashboardStore.GetFolderByID(ctx, cmd.OrgID, dash.ID)
foldr, err = s.dashboardFolderStore.GetFolderByID(ctx, cmd.OrgID, dash.ID)
if err != nil {
return nil, err
}
@@ -534,7 +537,7 @@ func (s *Service) Delete(ctx context.Context, cmd *folder.DeleteFolderCommand) e
}
}
dashFolder, err := s.dashboardStore.GetFolderByUID(ctx, cmd.OrgID, cmd.UID)
dashFolder, err := s.dashboardFolderStore.GetFolderByUID(ctx, cmd.OrgID, cmd.UID)
if err != nil {
return err
}
+124 -96
View File
@@ -38,7 +38,7 @@ func TestIntegrationProvideFolderService(t *testing.T) {
t.Run("should register scope resolvers", func(t *testing.T) {
cfg := setting.NewCfg()
ac := acmock.New()
ProvideService(ac, bus.ProvideBus(tracing.InitializeTracerForTest()), cfg, nil, nil, &featuremgmt.FeatureManager{}, nil, nil)
ProvideService(ac, bus.ProvideBus(tracing.InitializeTracerForTest()), cfg, nil, nil, nil, &featuremgmt.FeatureManager{}, nil, nil)
require.Len(t, ac.Calls.RegisterAttributeScopeResolver, 2)
})
@@ -51,7 +51,9 @@ func TestIntegrationFolderService(t *testing.T) {
t.Run("Folder service tests", func(t *testing.T) {
dashStore := &dashboards.FakeDashboardStore{}
db := sqlstore.InitTestDB(t)
store := ProvideStore(db, db.Cfg, featuremgmt.WithFeatures([]interface{}{"nestedFolders"}))
nestedFolderStore := ProvideStore(db, db.Cfg, featuremgmt.WithFeatures([]interface{}{"nestedFolders"}))
folderStore := dashboards.NewFakeFolderStore(t)
cfg := setting.NewCfg()
cfg.RBACEnabled = false
@@ -59,14 +61,15 @@ func TestIntegrationFolderService(t *testing.T) {
folderPermissions := acmock.NewMockedPermissionsService()
service := &Service{
cfg: cfg,
log: log.New("test-folder-service"),
dashboardStore: dashStore,
store: store,
searchService: nil,
features: features,
permissions: folderPermissions,
bus: bus.ProvideBus(tracing.InitializeTracerForTest()),
cfg: cfg,
log: log.New("test-folder-service"),
dashboardStore: dashStore,
dashboardFolderStore: folderStore,
store: nestedFolderStore,
searchService: nil,
features: features,
permissions: folderPermissions,
bus: bus.ProvideBus(tracing.InitializeTracerForTest()),
}
t.Run("Given user has no permissions", func(t *testing.T) {
@@ -80,8 +83,8 @@ func TestIntegrationFolderService(t *testing.T) {
f.ID = folderId
f.UID = folderUID
dashStore.On("GetFolderByID", mock.Anything, orgID, folderId).Return(f, nil)
dashStore.On("GetFolderByUID", mock.Anything, orgID, folderUID).Return(f, nil)
folderStore.On("GetFolderByID", mock.Anything, orgID, folderId).Return(f, nil)
folderStore.On("GetFolderByUID", mock.Anything, orgID, folderUID).Return(f, nil)
t.Run("When get folder by id should return access denied error", func(t *testing.T) {
_, err := service.Get(context.Background(), &folder.GetFolderQuery{
@@ -143,8 +146,8 @@ func TestIntegrationFolderService(t *testing.T) {
newFolder := models.NewFolder("Folder")
newFolder.Uid = folderUID
dashStore.On("GetFolderByID", mock.Anything, orgID, folderId).Return(newFolder, nil)
dashStore.On("GetFolderByUID", mock.Anything, orgID, folderUID).Return(newFolder, nil)
folderStore.On("GetFolderByID", mock.Anything, orgID, folderId).Return(newFolder, nil)
folderStore.On("GetFolderByUID", mock.Anything, orgID, folderUID).Return(newFolder, nil)
err := service.Delete(context.Background(), &folder.DeleteFolderCommand{
UID: folderUID,
@@ -172,7 +175,7 @@ func TestIntegrationFolderService(t *testing.T) {
dashStore.On("ValidateDashboardBeforeSave", mock.Anything, mock.AnythingOfType("*dashboards.Dashboard"), mock.AnythingOfType("bool")).Return(true, nil)
dashStore.On("SaveDashboard", mock.Anything, mock.AnythingOfType("dashboards.SaveDashboardCommand")).Return(dash, nil).Once()
dashStore.On("GetFolderByID", mock.Anything, orgID, dash.ID).Return(f, nil)
folderStore.On("GetFolderByID", mock.Anything, orgID, dash.ID).Return(f, nil)
actualFolder, err := service.Create(context.Background(), &folder.CreateFolderCommand{
OrgID: orgID,
@@ -205,7 +208,7 @@ func TestIntegrationFolderService(t *testing.T) {
dashStore.On("ValidateDashboardBeforeSave", mock.Anything, mock.AnythingOfType("*dashboards.Dashboard"), mock.AnythingOfType("bool")).Return(true, nil)
dashStore.On("SaveDashboard", mock.Anything, mock.AnythingOfType("dashboards.SaveDashboardCommand")).Return(dashboardFolder, nil)
dashStore.On("GetFolderByID", mock.Anything, orgID, dashboardFolder.ID).Return(f, nil)
folderStore.On("GetFolderByID", mock.Anything, orgID, dashboardFolder.ID).Return(f, nil)
title := "TEST-Folder"
req := &folder.UpdateFolderCommand{
@@ -224,7 +227,7 @@ func TestIntegrationFolderService(t *testing.T) {
f := folder.NewFolder(util.GenerateShortUID(), "")
f.ID = rand.Int63()
f.UID = util.GenerateShortUID()
dashStore.On("GetFolderByUID", mock.Anything, orgID, f.UID).Return(f, nil)
folderStore.On("GetFolderByUID", mock.Anything, orgID, f.UID).Return(f, nil)
var actualCmd *dashboards.DeleteDashboardCommand
dashStore.On("DeleteDashboard", mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
@@ -258,7 +261,7 @@ func TestIntegrationFolderService(t *testing.T) {
expected := folder.NewFolder(util.GenerateShortUID(), "")
expected.ID = rand.Int63()
dashStore.On("GetFolderByID", mock.Anything, orgID, expected.ID).Return(expected, nil)
folderStore.On("GetFolderByID", mock.Anything, orgID, expected.ID).Return(expected, nil)
actual, err := service.getFolderByID(context.Background(), usr, expected.ID, orgID)
require.Equal(t, expected, actual)
@@ -269,7 +272,7 @@ func TestIntegrationFolderService(t *testing.T) {
expected := folder.NewFolder(util.GenerateShortUID(), "")
expected.UID = util.GenerateShortUID()
dashStore.On("GetFolderByUID", mock.Anything, orgID, expected.UID).Return(expected, nil)
folderStore.On("GetFolderByUID", mock.Anything, orgID, expected.UID).Return(expected, nil)
actual, err := service.getFolderByUID(context.Background(), usr, orgID, expected.UID)
require.Equal(t, expected, actual)
@@ -279,7 +282,7 @@ func TestIntegrationFolderService(t *testing.T) {
t.Run("When get folder by title should return folder", func(t *testing.T) {
expected := folder.NewFolder("TEST-"+util.GenerateShortUID(), "")
dashStore.On("GetFolderByTitle", mock.Anything, orgID, expected.Title).Return(expected, nil)
folderStore.On("GetFolderByTitle", mock.Anything, orgID, expected.Title).Return(expected, nil)
actual, err := service.getFolderByTitle(context.Background(), usr, orgID, expected.Title)
require.Equal(t, expected, actual)
@@ -322,23 +325,27 @@ func TestNestedFolderServiceFeatureToggle(t *testing.T) {
guardian.New = g
})
folderStore := NewFakeStore()
nestedFolderStore := NewFakeStore()
dashStore := dashboards.FakeDashboardStore{}
dashStore.On("ValidateDashboardBeforeSave", mock.Anything, mock.AnythingOfType("*dashboards.Dashboard"), mock.AnythingOfType("bool")).Return(true, nil)
dashStore.On("SaveDashboard", mock.Anything, mock.AnythingOfType("dashboards.SaveDashboardCommand")).Return(&dashboards.Dashboard{}, nil)
dashStore.On("GetFolderByID", mock.Anything, mock.AnythingOfType("int64"), mock.AnythingOfType("int64")).Return(&folder.Folder{}, nil)
dashboardFolderStore := dashboards.NewFakeFolderStore(t)
dashboardFolderStore.On("GetFolderByID", mock.Anything, mock.AnythingOfType("int64"), mock.AnythingOfType("int64")).Return(&folder.Folder{}, nil)
cfg := setting.NewCfg()
cfg.RBACEnabled = false
folderService := &Service{
cfg: cfg,
store: folderStore,
dashboardStore: &dashStore,
features: featuremgmt.WithFeatures(featuremgmt.FlagNestedFolders),
log: log.New("test-folder-service"),
cfg: cfg,
store: nestedFolderStore,
dashboardStore: &dashStore,
dashboardFolderStore: dashboardFolderStore,
features: featuremgmt.WithFeatures(featuremgmt.FlagNestedFolders),
log: log.New("test-folder-service"),
}
t.Run("create folder", func(t *testing.T) {
folderStore.ExpectedFolder = &folder.Folder{ParentUID: util.GenerateShortUID()}
nestedFolderStore.ExpectedFolder = &folder.Folder{ParentUID: util.GenerateShortUID()}
res, err := folderService.Create(context.Background(), &folder.CreateFolderCommand{SignedInUser: usr, Title: "my folder"})
require.NoError(t, err)
require.NotNil(t, res.UID)
@@ -359,11 +366,13 @@ func TestNestedFolderService(t *testing.T) {
dashStore := &dashboards.FakeDashboardStore{}
dashStore.On("ValidateDashboardBeforeSave", mock.Anything, mock.AnythingOfType("*dashboards.Dashboard"), mock.AnythingOfType("bool")).Return(true, nil)
dashStore.On("SaveDashboard", mock.Anything, mock.AnythingOfType("dashboards.SaveDashboardCommand")).Return(&dashboards.Dashboard{}, nil)
dashStore.On("GetFolderByID", mock.Anything, mock.AnythingOfType("int64"), mock.AnythingOfType("int64")).Return(&folder.Folder{}, nil)
folderStore := NewFakeStore()
dashboardFolderStore := dashboards.NewFakeFolderStore(t)
dashboardFolderStore.On("GetFolderByID", mock.Anything, mock.AnythingOfType("int64"), mock.AnythingOfType("int64")).Return(&folder.Folder{}, nil)
folderSvc := setup(t, dashStore, folderStore, featuremgmt.WithFeatures(), nil)
nestedFolderStore := NewFakeStore()
folderSvc := setup(t, dashStore, dashboardFolderStore, nestedFolderStore, featuremgmt.WithFeatures(), nil)
_, err := folderSvc.Create(context.Background(), &folder.CreateFolderCommand{
OrgID: orgID,
Title: "myFolder",
@@ -372,7 +381,7 @@ func TestNestedFolderService(t *testing.T) {
})
require.NoError(t, err)
// CreateFolder should not call the folder store create if the feature toggle is not enabled.
require.False(t, folderStore.CreateCalled)
require.False(t, nestedFolderStore.CreateCalled)
})
t.Run("When delete folder, no delete in folder table done", func(t *testing.T) {
@@ -381,16 +390,18 @@ func TestNestedFolderService(t *testing.T) {
dashStore.On("DeleteDashboard", mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
actualCmd = args.Get(1).(*dashboards.DeleteDashboardCommand)
}).Return(nil).Once()
dashStore.On("GetFolderByUID", mock.Anything, mock.AnythingOfType("int64"), mock.AnythingOfType("string")).Return(&folder.Folder{}, nil)
folderStore := NewFakeStore()
dashboardFolderStore := dashboards.NewFakeFolderStore(t)
dashboardFolderStore.On("GetFolderByUID", mock.Anything, mock.AnythingOfType("int64"), mock.AnythingOfType("string")).Return(&folder.Folder{}, nil)
folderSvc := setup(t, dashStore, folderStore, featuremgmt.WithFeatures(), nil)
nestedFolderStore := NewFakeStore()
folderSvc := setup(t, dashStore, dashboardFolderStore, nestedFolderStore, featuremgmt.WithFeatures(), nil)
err := folderSvc.Delete(context.Background(), &folder.DeleteFolderCommand{UID: "myFolder", OrgID: orgID, SignedInUser: usr})
require.NoError(t, err)
require.NotNil(t, actualCmd)
require.False(t, folderStore.DeleteCalled)
require.False(t, nestedFolderStore.DeleteCalled)
})
})
@@ -406,11 +417,13 @@ func TestNestedFolderService(t *testing.T) {
dashStore := &dashboards.FakeDashboardStore{}
dashStore.On("ValidateDashboardBeforeSave", mock.Anything, mock.AnythingOfType("*dashboards.Dashboard"), mock.AnythingOfType("bool")).Return(true, nil)
dashStore.On("SaveDashboard", mock.Anything, mock.AnythingOfType("dashboards.SaveDashboardCommand")).Return(&dashboards.Dashboard{}, nil)
dashStore.On("GetFolderByID", mock.Anything, mock.AnythingOfType("int64"), mock.AnythingOfType("int64")).Return(&folder.Folder{}, nil)
folderStore := NewFakeStore()
dashboardFolderStore := dashboards.NewFakeFolderStore(t)
dashboardFolderStore.On("GetFolderByID", mock.Anything, mock.AnythingOfType("int64"), mock.AnythingOfType("int64")).Return(&folder.Folder{}, nil)
folderSvc := setup(t, dashStore, folderStore, featuremgmt.WithFeatures("nestedFolders"), actest.FakeAccessControl{
nestedFolderStore := NewFakeStore()
folderSvc := setup(t, dashStore, dashboardFolderStore, nestedFolderStore, featuremgmt.WithFeatures("nestedFolders"), actest.FakeAccessControl{
ExpectedEvaluate: true,
})
_, err := folderSvc.Create(context.Background(), &folder.CreateFolderCommand{
@@ -421,7 +434,7 @@ func TestNestedFolderService(t *testing.T) {
})
require.NoError(t, err)
// CreateFolder should also call the folder store's create method.
require.True(t, folderStore.CreateCalled)
require.True(t, nestedFolderStore.CreateCalled)
})
t.Run("create without UID, no error", func(t *testing.T) {
@@ -435,11 +448,13 @@ func TestNestedFolderService(t *testing.T) {
dashStore := &dashboards.FakeDashboardStore{}
dashStore.On("ValidateDashboardBeforeSave", mock.Anything, mock.AnythingOfType("*dashboards.Dashboard"), mock.AnythingOfType("bool")).Return(true, nil)
dashStore.On("SaveDashboard", mock.Anything, mock.AnythingOfType("dashboards.SaveDashboardCommand")).Return(&dashboards.Dashboard{UID: "newUID"}, nil)
dashStore.On("GetFolderByID", mock.Anything, mock.AnythingOfType("int64"), mock.AnythingOfType("int64")).Return(&folder.Folder{}, nil)
folderStore := NewFakeStore()
dashboardFolderStore := dashboards.NewFakeFolderStore(t)
dashboardFolderStore.On("GetFolderByID", mock.Anything, mock.AnythingOfType("int64"), mock.AnythingOfType("int64")).Return(&folder.Folder{}, nil)
folderSvc := setup(t, dashStore, folderStore, featuremgmt.WithFeatures("nestedFolders"), actest.FakeAccessControl{
nestedFolderStore := NewFakeStore()
folderSvc := setup(t, dashStore, dashboardFolderStore, nestedFolderStore, featuremgmt.WithFeatures("nestedFolders"), actest.FakeAccessControl{
ExpectedEvaluate: true,
})
f, err := folderSvc.Create(context.Background(), &folder.CreateFolderCommand{
@@ -449,7 +464,7 @@ func TestNestedFolderService(t *testing.T) {
})
require.NoError(t, err)
// CreateFolder should also call the folder store's create method.
require.True(t, folderStore.CreateCalled)
require.True(t, nestedFolderStore.CreateCalled)
require.Equal(t, "newUID", f.UID)
})
@@ -469,14 +484,16 @@ func TestNestedFolderService(t *testing.T) {
dashStore := &dashboards.FakeDashboardStore{}
dashStore.On("ValidateDashboardBeforeSave", mock.Anything, mock.AnythingOfType("*dashboards.Dashboard"), mock.AnythingOfType("bool")).Return(true, nil)
dashStore.On("SaveDashboard", mock.Anything, mock.AnythingOfType("dashboards.SaveDashboardCommand")).Return(dashboardFolder, nil)
dashStore.On("GetFolderByID", mock.Anything, orgID, dashboardFolder.ID).Return(f, nil)
var actualCmd *dashboards.DeleteDashboardCommand
dashStore.On("DeleteDashboard", mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
actualCmd = args.Get(1).(*dashboards.DeleteDashboardCommand)
}).Return(nil).Once()
folderStore := NewFakeStore()
folderStore.ExpectedParentFolders = []*folder.Folder{
dashboardFolderStore := dashboards.NewFakeFolderStore(t)
dashboardFolderStore.On("GetFolderByID", mock.Anything, orgID, dashboardFolder.ID).Return(f, nil)
nestedFolderStore := NewFakeStore()
nestedFolderStore.ExpectedParentFolders = []*folder.Folder{
{UID: "newFolder", ParentUID: "newFolder"},
{UID: "newFolder2", ParentUID: "newFolder2"},
{UID: "newFolder3", ParentUID: "newFolder3"},
@@ -491,13 +508,13 @@ func TestNestedFolderService(t *testing.T) {
SignedInUser: usr,
}
folderSvc := setup(t, dashStore, folderStore, featuremgmt.WithFeatures("nestedFolders"), actest.FakeAccessControl{
folderSvc := setup(t, dashStore, dashboardFolderStore, nestedFolderStore, featuremgmt.WithFeatures("nestedFolders"), actest.FakeAccessControl{
ExpectedEvaluate: true,
})
_, err := folderSvc.Create(context.Background(), &cmd)
require.Error(t, err, folder.ErrCircularReference)
// CreateFolder should not call the folder store's create method.
require.False(t, folderStore.CreateCalled)
require.False(t, nestedFolderStore.CreateCalled)
require.NotNil(t, actualCmd)
})
@@ -513,19 +530,20 @@ func TestNestedFolderService(t *testing.T) {
dashStore := &dashboards.FakeDashboardStore{}
dashStore.On("ValidateDashboardBeforeSave", mock.Anything, mock.AnythingOfType("*dashboards.Dashboard"), mock.AnythingOfType("bool")).Return(true, nil)
dashStore.On("SaveDashboard", mock.Anything, mock.AnythingOfType("dashboards.SaveDashboardCommand")).Return(&dashboards.Dashboard{}, nil)
dashStore.On("GetFolderByID", mock.Anything, mock.AnythingOfType("int64"), mock.AnythingOfType("int64")).Return(&folder.Folder{}, nil)
dashStore.On("GetFolderByUID", mock.Anything, mock.AnythingOfType("int64"), mock.AnythingOfType("string")).Return(&folder.Folder{}, nil)
var actualCmd *dashboards.DeleteDashboardCommand
dashStore.On("DeleteDashboard", mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
actualCmd = args.Get(1).(*dashboards.DeleteDashboardCommand)
}).Return(nil).Once()
dashboardFolderStore := dashboards.NewFakeFolderStore(t)
dashboardFolderStore.On("GetFolderByID", mock.Anything, mock.AnythingOfType("int64"), mock.AnythingOfType("int64")).Return(&folder.Folder{}, nil)
// return an error from the folder store
folderStore := NewFakeStore()
folderStore.ExpectedError = errors.New("FAILED")
nestedFolderStore := NewFakeStore()
nestedFolderStore.ExpectedError = errors.New("FAILED")
// the service return success as long as the legacy create succeeds
folderSvc := setup(t, dashStore, folderStore, featuremgmt.WithFeatures("nestedFolders"), actest.FakeAccessControl{
folderSvc := setup(t, dashStore, dashboardFolderStore, nestedFolderStore, featuremgmt.WithFeatures("nestedFolders"), actest.FakeAccessControl{
ExpectedEvaluate: true,
})
_, err := folderSvc.Create(context.Background(), &folder.CreateFolderCommand{
@@ -537,7 +555,7 @@ func TestNestedFolderService(t *testing.T) {
require.Error(t, err, "FAILED")
// CreateFolder should also call the folder store's create method.
require.True(t, folderStore.CreateCalled)
require.True(t, nestedFolderStore.CreateCalled)
require.NotNil(t, actualCmd)
})
@@ -550,11 +568,12 @@ func TestNestedFolderService(t *testing.T) {
})
dashStore := &dashboards.FakeDashboardStore{}
dashboardFolderStore := dashboards.NewFakeFolderStore(t)
folderStore := NewFakeStore()
folderStore.ExpectedFolder = &folder.Folder{UID: "myFolder", ParentUID: "newFolder"}
nestedFolderStore := NewFakeStore()
nestedFolderStore.ExpectedFolder = &folder.Folder{UID: "myFolder", ParentUID: "newFolder"}
folderSvc := setup(t, dashStore, folderStore, featuremgmt.WithFeatures("nestedFolders"), actest.FakeAccessControl{
folderSvc := setup(t, dashStore, dashboardFolderStore, nestedFolderStore, featuremgmt.WithFeatures("nestedFolders"), actest.FakeAccessControl{
ExpectedEvaluate: true,
})
_, err := folderSvc.Move(context.Background(), &folder.MoveFolderCommand{UID: "myFolder", NewParentUID: "newFolder", OrgID: orgID, SignedInUser: usr})
@@ -570,11 +589,12 @@ func TestNestedFolderService(t *testing.T) {
})
dashStore := &dashboards.FakeDashboardStore{}
dashboardFolderStore := dashboards.NewFakeFolderStore(t)
folderStore := NewFakeStore()
folderStore.ExpectedFolder = &folder.Folder{UID: "myFolder", ParentUID: "newFolder"}
nestedFolderStore := NewFakeStore()
nestedFolderStore.ExpectedFolder = &folder.Folder{UID: "myFolder", ParentUID: "newFolder"}
folderSvc := setup(t, dashStore, folderStore, featuremgmt.WithFeatures("nestedFolders"), actest.FakeAccessControl{
folderSvc := setup(t, dashStore, dashboardFolderStore, nestedFolderStore, featuremgmt.WithFeatures("nestedFolders"), actest.FakeAccessControl{
ExpectedEvaluate: true,
})
_, err := folderSvc.Move(context.Background(), &folder.MoveFolderCommand{UID: "myFolder", NewParentUID: "newFolder", OrgID: orgID, SignedInUser: usr})
@@ -590,16 +610,17 @@ func TestNestedFolderService(t *testing.T) {
})
dashStore := &dashboards.FakeDashboardStore{}
dashboardFolderStore := dashboards.NewFakeFolderStore(t)
folderStore := NewFakeStore()
folderStore.ExpectedFolder = &folder.Folder{UID: "myFolder", ParentUID: "newFolder"}
folderStore.ExpectedParentFolders = []*folder.Folder{
nestedFolderStore := NewFakeStore()
nestedFolderStore.ExpectedFolder = &folder.Folder{UID: "myFolder", ParentUID: "newFolder"}
nestedFolderStore.ExpectedParentFolders = []*folder.Folder{
{UID: "newFolder", ParentUID: "newFolder"},
{UID: "newFolder2", ParentUID: "newFolder2"},
{UID: "newFolder3", ParentUID: "newFolder3"},
}
folderSvc := setup(t, dashStore, folderStore, featuremgmt.WithFeatures("nestedFolders"), actest.FakeAccessControl{
folderSvc := setup(t, dashStore, dashboardFolderStore, nestedFolderStore, featuremgmt.WithFeatures("nestedFolders"), actest.FakeAccessControl{
ExpectedEvaluate: true,
})
f, err := folderSvc.Move(context.Background(), &folder.MoveFolderCommand{UID: "myFolder", NewParentUID: "newFolder", OrgID: orgID, SignedInUser: usr})
@@ -615,12 +636,13 @@ func TestNestedFolderService(t *testing.T) {
})
dashStore := &dashboards.FakeDashboardStore{}
dashboardFolderStore := dashboards.NewFakeFolderStore(t)
folderStore := NewFakeStore()
folderStore.ExpectedFolder = &folder.Folder{UID: "myFolder", ParentUID: "newFolder"}
folderStore.ExpectedError = folder.ErrCircularReference
nestedFolderStore := NewFakeStore()
nestedFolderStore.ExpectedFolder = &folder.Folder{UID: "myFolder", ParentUID: "newFolder"}
nestedFolderStore.ExpectedError = folder.ErrCircularReference
folderSvc := setup(t, dashStore, folderStore, featuremgmt.WithFeatures("nestedFolders"), actest.FakeAccessControl{
folderSvc := setup(t, dashStore, dashboardFolderStore, nestedFolderStore, featuremgmt.WithFeatures("nestedFolders"), actest.FakeAccessControl{
ExpectedEvaluate: true,
})
f, err := folderSvc.Move(context.Background(), &folder.MoveFolderCommand{UID: "myFolder", NewParentUID: "newFolder", OrgID: orgID, SignedInUser: usr})
@@ -636,16 +658,17 @@ func TestNestedFolderService(t *testing.T) {
})
dashStore := &dashboards.FakeDashboardStore{}
dashboardFolderStore := dashboards.NewFakeFolderStore(t)
folderStore := NewFakeStore()
folderStore.ExpectedFolder = &folder.Folder{UID: "myFolder", ParentUID: "newFolder"}
folderStore.ExpectedParentFolders = []*folder.Folder{
nestedFolderStore := NewFakeStore()
nestedFolderStore.ExpectedFolder = &folder.Folder{UID: "myFolder", ParentUID: "newFolder"}
nestedFolderStore.ExpectedParentFolders = []*folder.Folder{
{UID: "newFolder", ParentUID: "newFolder"},
{UID: "newFolder2", ParentUID: "newFolder2"},
}
folderStore.ExpectedFolderHeight = 5
nestedFolderStore.ExpectedFolderHeight = 5
folderSvc := setup(t, dashStore, folderStore, featuremgmt.WithFeatures("nestedFolders"), actest.FakeAccessControl{
folderSvc := setup(t, dashStore, dashboardFolderStore, nestedFolderStore, featuremgmt.WithFeatures("nestedFolders"), actest.FakeAccessControl{
ExpectedEvaluate: true,
})
f, err := folderSvc.Move(context.Background(), &folder.MoveFolderCommand{UID: "myFolder", NewParentUID: "newFolder2", OrgID: orgID, SignedInUser: usr})
@@ -661,12 +684,13 @@ func TestNestedFolderService(t *testing.T) {
})
dashStore := &dashboards.FakeDashboardStore{}
dashboardFolderStore := dashboards.NewFakeFolderStore(t)
folderStore := NewFakeStore()
folderStore.ExpectedFolder = &folder.Folder{UID: "myFolder", ParentUID: "newFolder"}
folderStore.ExpectedParentFolders = []*folder.Folder{{UID: "myFolder", ParentUID: "12345"}, {UID: "12345", ParentUID: ""}}
nestedFolderStore := NewFakeStore()
nestedFolderStore.ExpectedFolder = &folder.Folder{UID: "myFolder", ParentUID: "newFolder"}
nestedFolderStore.ExpectedParentFolders = []*folder.Folder{{UID: "myFolder", ParentUID: "12345"}, {UID: "12345", ParentUID: ""}}
folderSvc := setup(t, dashStore, folderStore, featuremgmt.WithFeatures("nestedFolders"), actest.FakeAccessControl{
folderSvc := setup(t, dashStore, dashboardFolderStore, nestedFolderStore, featuremgmt.WithFeatures("nestedFolders"), actest.FakeAccessControl{
ExpectedEvaluate: true,
})
f, err := folderSvc.Move(context.Background(), &folder.MoveFolderCommand{UID: "myFolder", NewParentUID: "newFolder2", OrgID: orgID, SignedInUser: usr})
@@ -686,19 +710,21 @@ func TestNestedFolderService(t *testing.T) {
dashStore.On("DeleteDashboard", mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
actualCmd = args.Get(1).(*dashboards.DeleteDashboardCommand)
}).Return(nil).Once()
dashStore.On("GetFolderByUID", mock.Anything, mock.AnythingOfType("int64"), mock.AnythingOfType("string")).Return(&folder.Folder{}, nil)
folderStore := NewFakeStore()
folderStore.ExpectedFolder = &folder.Folder{UID: "myFolder", ParentUID: "newFolder"}
dashboardFolderStore := dashboards.NewFakeFolderStore(t)
dashboardFolderStore.On("GetFolderByUID", mock.Anything, mock.AnythingOfType("int64"), mock.AnythingOfType("string")).Return(&folder.Folder{}, nil)
folderSvc := setup(t, dashStore, folderStore, featuremgmt.WithFeatures("nestedFolders"), actest.FakeAccessControl{
nestedFolderStore := NewFakeStore()
nestedFolderStore.ExpectedFolder = &folder.Folder{UID: "myFolder", ParentUID: "newFolder"}
folderSvc := setup(t, dashStore, dashboardFolderStore, nestedFolderStore, featuremgmt.WithFeatures("nestedFolders"), actest.FakeAccessControl{
ExpectedEvaluate: true,
})
err := folderSvc.Delete(context.Background(), &folder.DeleteFolderCommand{UID: "myFolder", OrgID: orgID, SignedInUser: usr})
require.NoError(t, err)
require.NotNil(t, actualCmd)
require.True(t, folderStore.DeleteCalled)
require.True(t, nestedFolderStore.DeleteCalled)
})
t.Run("create returns error if maximum depth reached", func(t *testing.T) {
@@ -713,23 +739,24 @@ func TestNestedFolderService(t *testing.T) {
dashStore := &dashboards.FakeDashboardStore{}
dashStore.On("ValidateDashboardBeforeSave", mock.Anything, mock.AnythingOfType("*dashboards.Dashboard"), mock.AnythingOfType("bool")).Return(true, nil).Times(2)
dashStore.On("SaveDashboard", mock.Anything, mock.AnythingOfType("dashboards.SaveDashboardCommand")).Return(&dashboards.Dashboard{}, nil)
dashStore.On("GetFolderByID", mock.Anything, mock.AnythingOfType("int64"), mock.AnythingOfType("int64")).Return(&folder.Folder{}, nil)
dashStore.On("GetFolderByUID", mock.Anything, mock.AnythingOfType("int64"), mock.AnythingOfType("string")).Return(&folder.Folder{}, nil)
var actualCmd *dashboards.DeleteDashboardCommand
dashStore.On("DeleteDashboard", mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
actualCmd = args.Get(1).(*dashboards.DeleteDashboardCommand)
}).Return(nil).Once()
dashboardFolderStore := dashboards.NewFakeFolderStore(t)
dashboardFolderStore.On("GetFolderByID", mock.Anything, mock.AnythingOfType("int64"), mock.AnythingOfType("int64")).Return(&folder.Folder{}, nil)
parents := make([]*folder.Folder, 0, folder.MaxNestedFolderDepth)
for i := 0; i < folder.MaxNestedFolderDepth; i++ {
parents = append(parents, &folder.Folder{UID: fmt.Sprintf("folder%d", i)})
}
folderStore := NewFakeStore()
//folderStore.ExpectedFolder = &folder.Folder{UID: "myFolder", ParentUID: "newFolder"}
folderStore.ExpectedParentFolders = parents
nestedFolderStore := NewFakeStore()
//nestedFolderStore.ExpectedFolder = &folder.Folder{UID: "myFolder", ParentUID: "newFolder"}
nestedFolderStore.ExpectedParentFolders = parents
folderSvc := setup(t, dashStore, folderStore, featuremgmt.WithFeatures("nestedFolders"), actest.FakeAccessControl{
folderSvc := setup(t, dashStore, dashboardFolderStore, nestedFolderStore, featuremgmt.WithFeatures("nestedFolders"), actest.FakeAccessControl{
ExpectedEvaluate: true,
})
_, err := folderSvc.Create(context.Background(), &folder.CreateFolderCommand{
@@ -745,18 +772,19 @@ func TestNestedFolderService(t *testing.T) {
})
}
func setup(t *testing.T, dashStore dashboards.Store, folderStore store, features featuremgmt.FeatureToggles, ac accesscontrol.AccessControl) folder.Service {
func setup(t *testing.T, dashStore dashboards.Store, dashboardFolderStore dashboards.FolderStore, nestedFolderStore store, features featuremgmt.FeatureToggles, ac accesscontrol.AccessControl) folder.Service {
t.Helper()
// nothing enabled yet
cfg := setting.NewCfg()
cfg.RBACEnabled = false
return &Service{
cfg: cfg,
log: log.New("test-folder-service"),
dashboardStore: dashStore,
store: folderStore,
features: features,
accessControl: ac,
cfg: cfg,
log: log.New("test-folder-service"),
dashboardStore: dashStore,
dashboardFolderStore: dashboardFolderStore,
store: nestedFolderStore,
features: features,
accessControl: ac,
}
}