| 
									
										
										
										
											2022-10-11 03:47:53 +08:00
										 |  |  | package folderimpl | 
					
						
							| 
									
										
										
										
											2018-02-20 20:55:43 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2021-09-14 22:08:04 +08:00
										 |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2022-11-08 21:59:55 +08:00
										 |  |  | 	"errors" | 
					
						
							| 
									
										
										
										
											2022-03-14 23:21:42 +08:00
										 |  |  | 	"math/rand" | 
					
						
							| 
									
										
										
										
											2018-02-20 20:55:43 +08:00
										 |  |  | 	"testing" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-11 01:19:50 +08:00
										 |  |  | 	"github.com/stretchr/testify/assert" | 
					
						
							|  |  |  | 	"github.com/stretchr/testify/mock" | 
					
						
							|  |  |  | 	"github.com/stretchr/testify/require" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-18 21:31:56 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/bus" | 
					
						
							| 
									
										
										
										
											2022-11-08 21:59:55 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/infra/appcontext" | 
					
						
							| 
									
										
										
										
											2022-03-14 23:21:42 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/infra/log" | 
					
						
							| 
									
										
										
										
											2022-10-18 21:31:56 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/infra/tracing" | 
					
						
							| 
									
										
										
										
											2018-02-20 20:55:43 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/models" | 
					
						
							| 
									
										
										
										
											2022-11-11 21:28:24 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/accesscontrol/actest" | 
					
						
							| 
									
										
										
										
											2022-03-10 19:58:18 +08:00
										 |  |  | 	acmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock" | 
					
						
							| 
									
										
										
										
											2022-02-16 21:15:44 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/dashboards" | 
					
						
							| 
									
										
										
										
											2022-10-11 03:47:53 +08:00
										 |  |  | 	dashboardsvc "github.com/grafana/grafana/pkg/services/dashboards/service" | 
					
						
							| 
									
										
										
										
											2022-03-10 19:58:18 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/featuremgmt" | 
					
						
							| 
									
										
										
										
											2022-11-08 18:33:13 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/folder" | 
					
						
							| 
									
										
										
										
											2022-02-16 21:15:44 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/guardian" | 
					
						
							| 
									
										
										
										
											2022-11-08 21:59:55 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/sqlstore" | 
					
						
							| 
									
										
										
										
											2022-08-10 17:56:48 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/user" | 
					
						
							| 
									
										
										
										
											2022-03-10 19:58:18 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/setting" | 
					
						
							| 
									
										
										
										
											2022-03-14 23:21:42 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/util" | 
					
						
							| 
									
										
										
										
											2018-02-20 20:55:43 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-16 21:15:44 +08:00
										 |  |  | var orgID = int64(1) | 
					
						
							| 
									
										
										
										
											2022-11-10 16:42:32 +08:00
										 |  |  | var usr = &user.SignedInUser{UserID: 1, OrgID: orgID} | 
					
						
							| 
									
										
										
										
											2022-02-16 21:15:44 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-24 17:04:03 +08:00
										 |  |  | func TestIntegrationProvideFolderService(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-06-10 23:46:21 +08:00
										 |  |  | 	if testing.Short() { | 
					
						
							|  |  |  | 		t.Skip("skipping integration test") | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-03-14 23:21:42 +08:00
										 |  |  | 	t.Run("should register scope resolvers", func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-03-10 19:58:18 +08:00
										 |  |  | 		cfg := setting.NewCfg() | 
					
						
							| 
									
										
										
										
											2022-03-11 01:19:50 +08:00
										 |  |  | 		ac := acmock.New() | 
					
						
							| 
									
										
										
										
											2022-11-08 21:59:55 +08:00
										 |  |  | 		ProvideService(ac, bus.ProvideBus(tracing.InitializeTracerForTest()), cfg, nil, nil, nil, &featuremgmt.FeatureManager{}, nil, nil) | 
					
						
							| 
									
										
										
										
											2018-02-20 20:55:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-15 22:37:16 +08:00
										 |  |  | 		require.Len(t, ac.Calls.RegisterAttributeScopeResolver, 2) | 
					
						
							| 
									
										
										
										
											2022-03-14 23:21:42 +08:00
										 |  |  | 	}) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-24 17:04:03 +08:00
										 |  |  | func TestIntegrationFolderService(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-06-10 23:46:21 +08:00
										 |  |  | 	if testing.Short() { | 
					
						
							|  |  |  | 		t.Skip("skipping integration test") | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-03-14 23:21:42 +08:00
										 |  |  | 	t.Run("Folder service tests", func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-11-08 21:59:55 +08:00
										 |  |  | 		dashStore := &dashboards.FakeDashboardStore{} | 
					
						
							|  |  |  | 		db := sqlstore.InitTestDB(t) | 
					
						
							|  |  |  | 		store := ProvideStore(db, db.Cfg, featuremgmt.WithFeatures([]interface{}{"nestedFolders"})) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-14 23:21:42 +08:00
										 |  |  | 		cfg := setting.NewCfg() | 
					
						
							| 
									
										
										
										
											2022-08-11 21:37:31 +08:00
										 |  |  | 		cfg.RBACEnabled = false | 
					
						
							| 
									
										
										
										
											2022-03-14 23:21:42 +08:00
										 |  |  | 		features := featuremgmt.WithFeatures() | 
					
						
							| 
									
										
										
										
											2022-05-05 23:31:14 +08:00
										 |  |  | 		cfg.IsFeatureToggleEnabled = features.IsEnabled | 
					
						
							| 
									
										
										
										
											2022-05-10 21:48:47 +08:00
										 |  |  | 		folderPermissions := acmock.NewMockedPermissionsService() | 
					
						
							|  |  |  | 		dashboardPermissions := acmock.NewMockedPermissionsService() | 
					
						
							| 
									
										
										
										
											2022-11-08 21:59:55 +08:00
										 |  |  | 		dashboardService := dashboardsvc.ProvideDashboardService(cfg, dashStore, nil, features, folderPermissions, dashboardPermissions, acmock.New()) | 
					
						
							| 
									
										
										
										
											2022-03-14 23:21:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-11 03:47:53 +08:00
										 |  |  | 		service := &Service{ | 
					
						
							| 
									
										
										
										
											2022-03-14 23:21:42 +08:00
										 |  |  | 			cfg:              cfg, | 
					
						
							|  |  |  | 			log:              log.New("test-folder-service"), | 
					
						
							|  |  |  | 			dashboardService: dashboardService, | 
					
						
							| 
									
										
										
										
											2022-11-08 21:59:55 +08:00
										 |  |  | 			dashboardStore:   dashStore, | 
					
						
							|  |  |  | 			store:            store, | 
					
						
							| 
									
										
										
										
											2022-03-14 23:21:42 +08:00
										 |  |  | 			searchService:    nil, | 
					
						
							|  |  |  | 			features:         features, | 
					
						
							| 
									
										
										
										
											2022-05-10 21:48:47 +08:00
										 |  |  | 			permissions:      folderPermissions, | 
					
						
							| 
									
										
										
										
											2022-10-18 21:31:56 +08:00
										 |  |  | 			bus:              bus.ProvideBus(tracing.InitializeTracerForTest()), | 
					
						
							| 
									
										
										
										
											2022-03-14 23:21:42 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2022-03-11 01:19:50 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-01 16:40:38 +08:00
										 |  |  | 		t.Run("Given user has no permissions", func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2018-02-20 20:55:43 +08:00
										 |  |  | 			origNewGuardian := guardian.New | 
					
						
							| 
									
										
										
										
											2018-02-21 01:08:19 +08:00
										 |  |  | 			guardian.MockDashboardGuardian(&guardian.FakeDashboardGuardian{}) | 
					
						
							| 
									
										
										
										
											2018-02-20 20:55:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-14 23:21:42 +08:00
										 |  |  | 			folderId := rand.Int63() | 
					
						
							|  |  |  | 			folderUID := util.GenerateShortUID() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-11 21:28:24 +08:00
										 |  |  | 			f := folder.NewFolder("Folder", "") | 
					
						
							|  |  |  | 			f.ID = folderId | 
					
						
							|  |  |  | 			f.UID = folderUID | 
					
						
							| 
									
										
										
										
											2022-03-14 23:21:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-10 17:41:03 +08:00
										 |  |  | 			dashStore.On("GetFolderByID", mock.Anything, orgID, folderId).Return(f, nil) | 
					
						
							|  |  |  | 			dashStore.On("GetFolderByUID", mock.Anything, orgID, folderUID).Return(f, nil) | 
					
						
							| 
									
										
										
										
											2018-02-20 20:55:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-01 16:40:38 +08:00
										 |  |  | 			t.Run("When get folder by id should return access denied error", func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-11-11 21:28:24 +08:00
										 |  |  | 				_, err := service.getFolderByID(context.Background(), usr, folderId, orgID) | 
					
						
							| 
									
										
										
										
											2022-06-30 21:31:54 +08:00
										 |  |  | 				require.Equal(t, err, dashboards.ErrFolderAccessDenied) | 
					
						
							| 
									
										
										
										
											2021-07-01 16:40:38 +08:00
										 |  |  | 			}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			t.Run("When get folder by id, with id = 0 should return default folder", func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-11-11 21:28:24 +08:00
										 |  |  | 				foldr, err := service.getFolderByID(context.Background(), usr, 0, orgID) | 
					
						
							| 
									
										
										
										
											2021-07-01 16:40:38 +08:00
										 |  |  | 				require.NoError(t, err) | 
					
						
							| 
									
										
										
										
											2022-11-11 21:28:24 +08:00
										 |  |  | 				require.Equal(t, foldr, &folder.Folder{ID: 0, Title: "General"}) | 
					
						
							| 
									
										
										
										
											2018-02-20 20:55:43 +08:00
										 |  |  | 			}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-01 16:40:38 +08:00
										 |  |  | 			t.Run("When get folder by uid should return access denied error", func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-11-11 21:28:24 +08:00
										 |  |  | 				_, err := service.getFolderByUID(context.Background(), usr, orgID, folderUID) | 
					
						
							| 
									
										
										
										
											2022-06-30 21:31:54 +08:00
										 |  |  | 				require.Equal(t, err, dashboards.ErrFolderAccessDenied) | 
					
						
							| 
									
										
										
										
											2018-02-20 20:55:43 +08:00
										 |  |  | 			}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-01 16:40:38 +08:00
										 |  |  | 			t.Run("When creating folder should return access denied error", func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-11-08 21:59:55 +08:00
										 |  |  | 				dashStore.On("ValidateDashboardBeforeSave", mock.Anything, mock.AnythingOfType("*models.Dashboard"), mock.AnythingOfType("bool")).Return(true, nil).Times(2) | 
					
						
							| 
									
										
										
										
											2022-11-10 17:41:03 +08:00
										 |  |  | 				ctx := appcontext.WithUser(context.Background(), usr) | 
					
						
							|  |  |  | 				_, err := service.Create(ctx, &folder.CreateFolderCommand{ | 
					
						
							|  |  |  | 					OrgID: orgID, | 
					
						
							|  |  |  | 					Title: f.Title, | 
					
						
							|  |  |  | 					UID:   folderUID, | 
					
						
							|  |  |  | 				}) | 
					
						
							| 
									
										
										
										
											2022-06-30 21:31:54 +08:00
										 |  |  | 				require.Equal(t, err, dashboards.ErrFolderAccessDenied) | 
					
						
							| 
									
										
										
										
											2018-02-20 20:55:43 +08:00
										 |  |  | 			}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-01 16:40:38 +08:00
										 |  |  | 			t.Run("When updating folder should return access denied error", func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-11-08 21:59:55 +08:00
										 |  |  | 				dashStore.On("GetDashboard", mock.Anything, mock.AnythingOfType("*models.GetDashboardQuery")).Run(func(args mock.Arguments) { | 
					
						
							| 
									
										
										
										
											2022-05-18 02:52:22 +08:00
										 |  |  | 					folder := args.Get(1).(*models.GetDashboardQuery) | 
					
						
							|  |  |  | 					folder.Result = models.NewDashboard("dashboard-test") | 
					
						
							|  |  |  | 					folder.Result.IsFolder = true | 
					
						
							| 
									
										
										
										
											2022-06-07 17:02:20 +08:00
										 |  |  | 				}).Return(&models.Dashboard{}, nil) | 
					
						
							| 
									
										
										
										
											2022-11-10 21:28:55 +08:00
										 |  |  | 				_, err := service.Update(context.Background(), usr, orgID, folderUID, &models.UpdateFolderCommand{ | 
					
						
							| 
									
										
										
										
											2022-03-14 23:21:42 +08:00
										 |  |  | 					Uid:   folderUID, | 
					
						
							|  |  |  | 					Title: "Folder-TEST", | 
					
						
							| 
									
										
										
										
											2018-02-20 20:55:43 +08:00
										 |  |  | 				}) | 
					
						
							| 
									
										
										
										
											2022-06-30 21:31:54 +08:00
										 |  |  | 				require.Equal(t, err, dashboards.ErrFolderAccessDenied) | 
					
						
							| 
									
										
										
										
											2018-02-20 20:55:43 +08:00
										 |  |  | 			}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-01 16:40:38 +08:00
										 |  |  | 			t.Run("When deleting folder by uid should return access denied error", func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-11-10 16:42:32 +08:00
										 |  |  | 				ctx := context.Background() | 
					
						
							|  |  |  | 				ctx = appcontext.WithUser(ctx, usr) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				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) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				err := service.DeleteFolder(ctx, &folder.DeleteFolderCommand{ | 
					
						
							|  |  |  | 					UID:              folderUID, | 
					
						
							|  |  |  | 					OrgID:            orgID, | 
					
						
							|  |  |  | 					ForceDeleteRules: false, | 
					
						
							|  |  |  | 				}) | 
					
						
							| 
									
										
										
										
											2021-07-01 16:40:38 +08:00
										 |  |  | 				require.Error(t, err) | 
					
						
							| 
									
										
										
										
											2022-06-30 21:31:54 +08:00
										 |  |  | 				require.Equal(t, err, dashboards.ErrFolderAccessDenied) | 
					
						
							| 
									
										
										
										
											2018-02-20 20:55:43 +08:00
										 |  |  | 			}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-01 16:40:38 +08:00
										 |  |  | 			t.Cleanup(func() { | 
					
						
							| 
									
										
										
										
											2018-02-20 20:55:43 +08:00
										 |  |  | 				guardian.New = origNewGuardian | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-01 16:40:38 +08:00
										 |  |  | 		t.Run("Given user has permission to save", func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2018-02-20 20:55:43 +08:00
										 |  |  | 			origNewGuardian := guardian.New | 
					
						
							| 
									
										
										
										
											2018-02-21 01:08:19 +08:00
										 |  |  | 			guardian.MockDashboardGuardian(&guardian.FakeDashboardGuardian{CanSaveValue: true}) | 
					
						
							| 
									
										
										
										
											2018-02-20 20:55:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-14 23:21:42 +08:00
										 |  |  | 			t.Run("When creating folder should not return access denied error", func(t *testing.T) { | 
					
						
							|  |  |  | 				dash := models.NewDashboardFolder("Test-Folder") | 
					
						
							|  |  |  | 				dash.Id = rand.Int63() | 
					
						
							| 
									
										
										
										
											2022-11-11 21:28:24 +08:00
										 |  |  | 				f := folder.FromDashboard(dash) | 
					
						
							| 
									
										
										
										
											2018-02-20 20:55:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-08 21:59:55 +08:00
										 |  |  | 				dashStore.On("ValidateDashboardBeforeSave", mock.Anything, mock.AnythingOfType("*models.Dashboard"), mock.AnythingOfType("bool")).Return(true, nil) | 
					
						
							|  |  |  | 				dashStore.On("SaveDashboard", mock.Anything, mock.AnythingOfType("models.SaveDashboardCommand")).Return(dash, nil).Once() | 
					
						
							|  |  |  | 				dashStore.On("GetFolderByID", mock.Anything, orgID, dash.Id).Return(f, nil) | 
					
						
							| 
									
										
										
										
											2018-02-20 20:55:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-10 17:41:03 +08:00
										 |  |  | 				ctx := appcontext.WithUser(context.Background(), usr) | 
					
						
							|  |  |  | 				actualFolder, err := service.Create(ctx, &folder.CreateFolderCommand{ | 
					
						
							|  |  |  | 					OrgID: orgID, | 
					
						
							|  |  |  | 					Title: dash.Title, | 
					
						
							|  |  |  | 					UID:   "someuid", | 
					
						
							|  |  |  | 				}) | 
					
						
							| 
									
										
										
										
											2021-07-01 16:40:38 +08:00
										 |  |  | 				require.NoError(t, err) | 
					
						
							| 
									
										
										
										
											2022-11-11 21:28:24 +08:00
										 |  |  | 				require.Equal(t, f, actualFolder) | 
					
						
							| 
									
										
										
										
											2018-02-20 20:55:43 +08:00
										 |  |  | 			}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-30 21:14:26 +08:00
										 |  |  | 			t.Run("When creating folder should return error if uid is general", func(t *testing.T) { | 
					
						
							|  |  |  | 				dash := models.NewDashboardFolder("Test-Folder") | 
					
						
							|  |  |  | 				dash.Id = rand.Int63() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-10 17:41:03 +08:00
										 |  |  | 				ctx := appcontext.WithUser(context.Background(), usr) | 
					
						
							|  |  |  | 				_, err := service.Create(ctx, &folder.CreateFolderCommand{ | 
					
						
							|  |  |  | 					OrgID: orgID, | 
					
						
							|  |  |  | 					Title: dash.Title, | 
					
						
							|  |  |  | 					UID:   "general", | 
					
						
							|  |  |  | 				}) | 
					
						
							| 
									
										
										
										
											2022-06-30 21:31:54 +08:00
										 |  |  | 				require.ErrorIs(t, err, dashboards.ErrFolderInvalidUID) | 
					
						
							| 
									
										
										
										
											2022-03-30 21:14:26 +08:00
										 |  |  | 			}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-01 16:40:38 +08:00
										 |  |  | 			t.Run("When updating folder should not return access denied error", func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-03-14 23:21:42 +08:00
										 |  |  | 				dashboardFolder := models.NewDashboardFolder("Folder") | 
					
						
							|  |  |  | 				dashboardFolder.Id = rand.Int63() | 
					
						
							|  |  |  | 				dashboardFolder.Uid = util.GenerateShortUID() | 
					
						
							| 
									
										
										
										
											2022-11-11 21:28:24 +08:00
										 |  |  | 				f := folder.FromDashboard(dashboardFolder) | 
					
						
							| 
									
										
										
										
											2022-03-14 23:21:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-08 21:59:55 +08:00
										 |  |  | 				dashStore.On("ValidateDashboardBeforeSave", mock.Anything, mock.AnythingOfType("*models.Dashboard"), mock.AnythingOfType("bool")).Return(true, nil) | 
					
						
							|  |  |  | 				dashStore.On("SaveDashboard", mock.Anything, mock.AnythingOfType("models.SaveDashboardCommand")).Return(dashboardFolder, nil) | 
					
						
							|  |  |  | 				dashStore.On("GetFolderByID", mock.Anything, orgID, dashboardFolder.Id).Return(f, nil) | 
					
						
							| 
									
										
										
										
											2022-03-14 23:21:42 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				req := &models.UpdateFolderCommand{ | 
					
						
							|  |  |  | 					Uid:   dashboardFolder.Uid, | 
					
						
							|  |  |  | 					Title: "TEST-Folder", | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-10 21:28:55 +08:00
										 |  |  | 				reqResult, err := service.Update(context.Background(), usr, orgID, dashboardFolder.Uid, req) | 
					
						
							| 
									
										
										
										
											2021-07-01 16:40:38 +08:00
										 |  |  | 				require.NoError(t, err) | 
					
						
							| 
									
										
										
										
											2022-11-10 21:28:55 +08:00
										 |  |  | 				require.Equal(t, f, reqResult) | 
					
						
							| 
									
										
										
										
											2018-02-20 20:55:43 +08:00
										 |  |  | 			}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-01 16:40:38 +08:00
										 |  |  | 			t.Run("When deleting folder by uid should not return access denied error", func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-11-11 21:28:24 +08:00
										 |  |  | 				f := folder.NewFolder(util.GenerateShortUID(), "") | 
					
						
							|  |  |  | 				f.ID = rand.Int63() | 
					
						
							|  |  |  | 				f.UID = util.GenerateShortUID() | 
					
						
							|  |  |  | 				dashStore.On("GetFolderByUID", mock.Anything, orgID, f.UID).Return(f, nil) | 
					
						
							| 
									
										
										
										
											2022-03-22 21:36:50 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-14 23:21:42 +08:00
										 |  |  | 				var actualCmd *models.DeleteDashboardCommand | 
					
						
							| 
									
										
										
										
											2022-11-08 21:59:55 +08:00
										 |  |  | 				dashStore.On("DeleteDashboard", mock.Anything, mock.Anything).Run(func(args mock.Arguments) { | 
					
						
							| 
									
										
										
										
											2022-03-22 21:36:50 +08:00
										 |  |  | 					actualCmd = args.Get(1).(*models.DeleteDashboardCommand) | 
					
						
							|  |  |  | 				}).Return(nil).Once() | 
					
						
							| 
									
										
										
										
											2022-03-14 23:21:42 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				expectedForceDeleteRules := rand.Int63()%2 == 0 | 
					
						
							| 
									
										
										
										
											2022-11-10 16:42:32 +08:00
										 |  |  | 				ctx := context.Background() | 
					
						
							|  |  |  | 				ctx = appcontext.WithUser(ctx, usr) | 
					
						
							|  |  |  | 				err := service.DeleteFolder(ctx, &folder.DeleteFolderCommand{ | 
					
						
							| 
									
										
										
										
											2022-11-11 21:28:24 +08:00
										 |  |  | 					UID:              f.UID, | 
					
						
							| 
									
										
										
										
											2022-11-10 16:42:32 +08:00
										 |  |  | 					OrgID:            orgID, | 
					
						
							|  |  |  | 					ForceDeleteRules: expectedForceDeleteRules, | 
					
						
							|  |  |  | 				}) | 
					
						
							| 
									
										
										
										
											2021-07-01 16:40:38 +08:00
										 |  |  | 				require.NoError(t, err) | 
					
						
							| 
									
										
										
										
											2022-03-14 23:21:42 +08:00
										 |  |  | 				require.NotNil(t, actualCmd) | 
					
						
							| 
									
										
										
										
											2022-11-11 21:28:24 +08:00
										 |  |  | 				require.Equal(t, f.ID, actualCmd.Id) | 
					
						
							| 
									
										
										
										
											2022-03-14 23:21:42 +08:00
										 |  |  | 				require.Equal(t, orgID, actualCmd.OrgId) | 
					
						
							|  |  |  | 				require.Equal(t, expectedForceDeleteRules, actualCmd.ForceDeleteFolderRules) | 
					
						
							| 
									
										
										
										
											2018-02-20 20:55:43 +08:00
										 |  |  | 			}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-01 16:40:38 +08:00
										 |  |  | 			t.Cleanup(func() { | 
					
						
							| 
									
										
										
										
											2018-02-20 20:55:43 +08:00
										 |  |  | 				guardian.New = origNewGuardian | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-01 16:40:38 +08:00
										 |  |  | 		t.Run("Given user has permission to view", func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2018-02-20 20:55:43 +08:00
										 |  |  | 			origNewGuardian := guardian.New | 
					
						
							| 
									
										
										
										
											2018-02-21 01:08:19 +08:00
										 |  |  | 			guardian.MockDashboardGuardian(&guardian.FakeDashboardGuardian{CanViewValue: true}) | 
					
						
							| 
									
										
										
										
											2018-02-20 20:55:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-14 23:21:42 +08:00
										 |  |  | 			t.Run("When get folder by id should return folder", func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-11-11 21:28:24 +08:00
										 |  |  | 				expected := folder.NewFolder(util.GenerateShortUID(), "") | 
					
						
							|  |  |  | 				expected.ID = rand.Int63() | 
					
						
							| 
									
										
										
										
											2022-03-14 23:21:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-11 21:28:24 +08:00
										 |  |  | 				dashStore.On("GetFolderByID", mock.Anything, orgID, expected.ID).Return(expected, nil) | 
					
						
							| 
									
										
										
										
											2018-02-20 20:55:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-11 21:28:24 +08:00
										 |  |  | 				actual, err := service.getFolderByID(context.Background(), usr, expected.ID, orgID) | 
					
						
							| 
									
										
										
										
											2022-03-14 23:21:42 +08:00
										 |  |  | 				require.Equal(t, expected, actual) | 
					
						
							|  |  |  | 				require.NoError(t, err) | 
					
						
							| 
									
										
										
										
											2018-02-20 20:55:43 +08:00
										 |  |  | 			}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-14 23:21:42 +08:00
										 |  |  | 			t.Run("When get folder by uid should return folder", func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-11-11 21:28:24 +08:00
										 |  |  | 				expected := folder.NewFolder(util.GenerateShortUID(), "") | 
					
						
							|  |  |  | 				expected.UID = util.GenerateShortUID() | 
					
						
							| 
									
										
										
										
											2022-03-14 23:21:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-11 21:28:24 +08:00
										 |  |  | 				dashStore.On("GetFolderByUID", mock.Anything, orgID, expected.UID).Return(expected, nil) | 
					
						
							| 
									
										
										
										
											2022-03-14 23:21:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-11 21:28:24 +08:00
										 |  |  | 				actual, err := service.getFolderByUID(context.Background(), usr, orgID, expected.UID) | 
					
						
							| 
									
										
										
										
											2022-03-14 23:21:42 +08:00
										 |  |  | 				require.Equal(t, expected, actual) | 
					
						
							|  |  |  | 				require.NoError(t, err) | 
					
						
							| 
									
										
										
										
											2018-02-20 20:55:43 +08:00
										 |  |  | 			}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-14 23:21:42 +08:00
										 |  |  | 			t.Run("When get folder by title should return folder", func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-11-11 21:28:24 +08:00
										 |  |  | 				expected := folder.NewFolder("TEST-"+util.GenerateShortUID(), "") | 
					
						
							| 
									
										
										
										
											2022-03-14 23:21:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-08 21:59:55 +08:00
										 |  |  | 				dashStore.On("GetFolderByTitle", mock.Anything, orgID, expected.Title).Return(expected, nil) | 
					
						
							| 
									
										
										
										
											2022-03-14 23:21:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-11 21:28:24 +08:00
										 |  |  | 				actual, err := service.getFolderByTitle(context.Background(), usr, orgID, expected.Title) | 
					
						
							| 
									
										
										
										
											2022-03-14 23:21:42 +08:00
										 |  |  | 				require.Equal(t, expected, actual) | 
					
						
							|  |  |  | 				require.NoError(t, err) | 
					
						
							| 
									
										
										
										
											2018-02-20 20:55:43 +08:00
										 |  |  | 			}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-01 16:40:38 +08:00
										 |  |  | 			t.Cleanup(func() { | 
					
						
							| 
									
										
										
										
											2018-02-20 20:55:43 +08:00
										 |  |  | 				guardian.New = origNewGuardian | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2018-02-21 18:25:21 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-01 16:40:38 +08:00
										 |  |  | 		t.Run("Should map errors correct", func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2018-02-21 18:25:21 +08:00
										 |  |  | 			testCases := []struct { | 
					
						
							|  |  |  | 				ActualError   error | 
					
						
							|  |  |  | 				ExpectedError error | 
					
						
							|  |  |  | 			}{ | 
					
						
							| 
									
										
										
										
											2022-06-30 21:31:54 +08:00
										 |  |  | 				{ActualError: dashboards.ErrDashboardTitleEmpty, ExpectedError: dashboards.ErrFolderTitleEmpty}, | 
					
						
							|  |  |  | 				{ActualError: dashboards.ErrDashboardUpdateAccessDenied, ExpectedError: dashboards.ErrFolderAccessDenied}, | 
					
						
							|  |  |  | 				{ActualError: dashboards.ErrDashboardWithSameNameInFolderExists, ExpectedError: dashboards.ErrFolderSameNameExists}, | 
					
						
							|  |  |  | 				{ActualError: dashboards.ErrDashboardWithSameUIDExists, ExpectedError: dashboards.ErrFolderWithSameUIDExists}, | 
					
						
							|  |  |  | 				{ActualError: dashboards.ErrDashboardVersionMismatch, ExpectedError: dashboards.ErrFolderVersionMismatch}, | 
					
						
							|  |  |  | 				{ActualError: dashboards.ErrDashboardNotFound, ExpectedError: dashboards.ErrFolderNotFound}, | 
					
						
							|  |  |  | 				{ActualError: dashboards.ErrDashboardFailedGenerateUniqueUid, ExpectedError: dashboards.ErrFolderFailedGenerateUniqueUid}, | 
					
						
							|  |  |  | 				{ActualError: dashboards.ErrDashboardInvalidUid, ExpectedError: dashboards.ErrDashboardInvalidUid}, | 
					
						
							| 
									
										
										
										
											2018-02-21 18:25:21 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			for _, tc := range testCases { | 
					
						
							|  |  |  | 				actualError := toFolderError(tc.ActualError) | 
					
						
							| 
									
										
										
										
											2020-11-19 21:47:17 +08:00
										 |  |  | 				assert.EqualErrorf(t, actualError, tc.ExpectedError.Error(), | 
					
						
							|  |  |  | 					"For error '%s' expected error '%s', actual '%s'", tc.ActualError, tc.ExpectedError, actualError) | 
					
						
							| 
									
										
										
										
											2018-02-21 18:25:21 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2018-02-20 20:55:43 +08:00
										 |  |  | 	}) | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-11-08 18:33:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-10 17:41:03 +08:00
										 |  |  | func TestNestedFolderServiceFeatureToggle(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-11-08 18:33:13 +08:00
										 |  |  | 	folderStore := NewFakeStore() | 
					
						
							| 
									
										
										
										
											2022-11-10 17:41:03 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	dashboardsvc := dashboards.FakeDashboardService{} | 
					
						
							|  |  |  | 	dashboardsvc.On("BuildSaveDashboardCommand", | 
					
						
							|  |  |  | 		mock.Anything, mock.AnythingOfType("*dashboards.SaveDashboardDTO"), | 
					
						
							|  |  |  | 		mock.AnythingOfType("bool"), mock.AnythingOfType("bool")).Return(&models.SaveDashboardCommand{}, nil) | 
					
						
							|  |  |  | 	dashStore := dashboards.FakeDashboardStore{} | 
					
						
							|  |  |  | 	dashStore.On("SaveDashboard", mock.Anything, mock.AnythingOfType("models.SaveDashboardCommand")).Return(&models.Dashboard{}, nil) | 
					
						
							| 
									
										
										
										
											2022-11-11 21:28:24 +08:00
										 |  |  | 	dashStore.On("GetFolderByID", mock.Anything, mock.AnythingOfType("int64"), mock.AnythingOfType("int64")).Return(&folder.Folder{}, nil) | 
					
						
							| 
									
										
										
										
											2022-11-10 17:41:03 +08:00
										 |  |  | 	cfg := setting.NewCfg() | 
					
						
							|  |  |  | 	cfg.RBACEnabled = false | 
					
						
							|  |  |  | 	nestedFoldersEnabled := true | 
					
						
							|  |  |  | 	features := featuremgmt.WithFeatures() | 
					
						
							|  |  |  | 	cfg.IsFeatureToggleEnabled = func(key string) bool { | 
					
						
							|  |  |  | 		if key == featuremgmt.FlagNestedFolders { | 
					
						
							|  |  |  | 			return nestedFoldersEnabled | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return false | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	cfg.IsFeatureToggleEnabled = features.IsEnabled | 
					
						
							| 
									
										
										
										
											2022-11-08 18:33:13 +08:00
										 |  |  | 	folderService := &Service{ | 
					
						
							| 
									
										
										
										
											2022-11-10 17:41:03 +08:00
										 |  |  | 		cfg:              cfg, | 
					
						
							|  |  |  | 		store:            folderStore, | 
					
						
							|  |  |  | 		dashboardStore:   &dashStore, | 
					
						
							|  |  |  | 		dashboardService: &dashboardsvc, | 
					
						
							|  |  |  | 		features:         features, | 
					
						
							| 
									
										
										
										
											2022-11-08 18:33:13 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	t.Run("create folder", func(t *testing.T) { | 
					
						
							|  |  |  | 		folderStore.ExpectedFolder = &folder.Folder{} | 
					
						
							| 
									
										
										
										
											2022-11-10 17:41:03 +08:00
										 |  |  | 		ctx := appcontext.WithUser(context.Background(), usr) | 
					
						
							|  |  |  | 		res, err := folderService.Create(ctx, &folder.CreateFolderCommand{}) | 
					
						
							| 
									
										
										
										
											2022-11-08 18:33:13 +08:00
										 |  |  | 		require.NoError(t, err) | 
					
						
							|  |  |  | 		require.NotNil(t, res.UID) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	t.Run("get parents folder", func(t *testing.T) { | 
					
						
							|  |  |  | 		folderStore.ExpectedFolder = &folder.Folder{} | 
					
						
							|  |  |  | 		_, err := folderService.GetParents(context.Background(), &folder.GetParentsQuery{}) | 
					
						
							|  |  |  | 		require.NoError(t, err) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	t.Run("get children folder", func(t *testing.T) { | 
					
						
							|  |  |  | 		folderStore.ExpectedFolders = []*folder.Folder{ | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				UID: "test", | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				UID: "test2", | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				UID: "test3", | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				UID: "test4", | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		res, err := folderService.GetTree(context.Background(), | 
					
						
							|  |  |  | 			&folder.GetTreeQuery{ | 
					
						
							|  |  |  | 				UID: "test", | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 		require.NoError(t, err) | 
					
						
							|  |  |  | 		require.Equal(t, 4, len(res)) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-11-08 21:59:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-10 16:42:32 +08:00
										 |  |  | func TestNestedFolderService(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-11-08 21:59:55 +08:00
										 |  |  | 	t.Run("with feature flag unset", func(t *testing.T) { | 
					
						
							|  |  |  | 		ctx := appcontext.WithUser(context.Background(), usr) | 
					
						
							|  |  |  | 		store := &FakeStore{} | 
					
						
							|  |  |  | 		dashStore := dashboards.FakeDashboardStore{} | 
					
						
							|  |  |  | 		dashboardsvc := dashboards.FakeDashboardService{} | 
					
						
							|  |  |  | 		// nothing enabled yet
 | 
					
						
							|  |  |  | 		cfg := setting.NewCfg() | 
					
						
							|  |  |  | 		cfg.RBACEnabled = false | 
					
						
							|  |  |  | 		features := featuremgmt.WithFeatures() | 
					
						
							|  |  |  | 		cfg.IsFeatureToggleEnabled = features.IsEnabled | 
					
						
							|  |  |  | 		foldersvc := &Service{ | 
					
						
							|  |  |  | 			cfg:              cfg, | 
					
						
							|  |  |  | 			log:              log.New("test-folder-service"), | 
					
						
							|  |  |  | 			dashboardService: &dashboardsvc, | 
					
						
							|  |  |  | 			dashboardStore:   &dashStore, | 
					
						
							|  |  |  | 			store:            store, | 
					
						
							|  |  |  | 			features:         features, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-10 16:42:32 +08:00
										 |  |  | 		t.Run("When create folder, no create in folder table done", func(t *testing.T) { | 
					
						
							|  |  |  | 			// dashboard store & service commands that should be called.
 | 
					
						
							|  |  |  | 			dashboardsvc.On("BuildSaveDashboardCommand", | 
					
						
							|  |  |  | 				mock.Anything, mock.AnythingOfType("*dashboards.SaveDashboardDTO"), | 
					
						
							|  |  |  | 				mock.AnythingOfType("bool"), mock.AnythingOfType("bool")).Return(&models.SaveDashboardCommand{}, nil) | 
					
						
							|  |  |  | 			dashStore.On("SaveDashboard", mock.Anything, mock.AnythingOfType("models.SaveDashboardCommand")).Return(&models.Dashboard{}, nil) | 
					
						
							| 
									
										
										
										
											2022-11-11 21:28:24 +08:00
										 |  |  | 			dashStore.On("GetFolderByID", mock.Anything, mock.AnythingOfType("int64"), mock.AnythingOfType("int64")).Return(&folder.Folder{}, nil) | 
					
						
							| 
									
										
										
										
											2022-11-10 16:42:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-10 17:41:03 +08:00
										 |  |  | 			ctx = appcontext.WithUser(ctx, usr) | 
					
						
							|  |  |  | 			_, err := foldersvc.Create(ctx, &folder.CreateFolderCommand{ | 
					
						
							|  |  |  | 				OrgID: orgID, | 
					
						
							|  |  |  | 				Title: "myFolder", | 
					
						
							|  |  |  | 				UID:   "myFolder", | 
					
						
							|  |  |  | 			}) | 
					
						
							| 
									
										
										
										
											2022-11-10 16:42:32 +08:00
										 |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 			// CreateFolder should not call the folder store create if the feature toggle is not enabled.
 | 
					
						
							|  |  |  | 			require.False(t, store.CreateCalled) | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		t.Run("When delete folder, no delete in folder table done", func(t *testing.T) { | 
					
						
							|  |  |  | 			var actualCmd *models.DeleteDashboardCommand | 
					
						
							|  |  |  | 			dashStore.On("DeleteDashboard", mock.Anything, mock.Anything).Run(func(args mock.Arguments) { | 
					
						
							|  |  |  | 				actualCmd = args.Get(1).(*models.DeleteDashboardCommand) | 
					
						
							|  |  |  | 			}).Return(nil).Once() | 
					
						
							| 
									
										
										
										
											2022-11-11 21:28:24 +08:00
										 |  |  | 			dashStore.On("GetFolderByUID", mock.Anything, mock.AnythingOfType("int64"), mock.AnythingOfType("string")).Return(&folder.Folder{}, nil) | 
					
						
							| 
									
										
										
										
											2022-11-08 21:59:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-10 16:42:32 +08:00
										 |  |  | 			g := guardian.New | 
					
						
							|  |  |  | 			guardian.MockDashboardGuardian(&guardian.FakeDashboardGuardian{CanSaveValue: true}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			err := foldersvc.DeleteFolder(ctx, &folder.DeleteFolderCommand{UID: "myFolder", OrgID: orgID}) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 			require.NotNil(t, actualCmd) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			t.Cleanup(func() { | 
					
						
							|  |  |  | 				guardian.New = g | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 			require.False(t, store.DeleteCalled) | 
					
						
							|  |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2022-11-08 21:59:55 +08:00
										 |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	t.Run("with nested folder feature flag on", func(t *testing.T) { | 
					
						
							|  |  |  | 		ctx := appcontext.WithUser(context.Background(), usr) | 
					
						
							|  |  |  | 		store := &FakeStore{} | 
					
						
							|  |  |  | 		dashStore := &dashboards.FakeDashboardStore{} | 
					
						
							|  |  |  | 		dashboardsvc := &dashboards.FakeDashboardService{} | 
					
						
							|  |  |  | 		// nothing enabled yet
 | 
					
						
							|  |  |  | 		cfg := setting.NewCfg() | 
					
						
							|  |  |  | 		cfg.RBACEnabled = false | 
					
						
							|  |  |  | 		features := featuremgmt.WithFeatures("nestedFolders") | 
					
						
							|  |  |  | 		cfg.IsFeatureToggleEnabled = features.IsEnabled | 
					
						
							|  |  |  | 		foldersvc := &Service{ | 
					
						
							|  |  |  | 			cfg:              cfg, | 
					
						
							|  |  |  | 			log:              log.New("test-folder-service"), | 
					
						
							|  |  |  | 			dashboardService: dashboardsvc, | 
					
						
							|  |  |  | 			dashboardStore:   dashStore, | 
					
						
							|  |  |  | 			store:            store, | 
					
						
							|  |  |  | 			features:         features, | 
					
						
							| 
									
										
										
										
											2022-11-11 21:28:24 +08:00
										 |  |  | 			accessControl: actest.FakeAccessControl{ | 
					
						
							|  |  |  | 				ExpectedEvaluate: true, | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2022-11-08 21:59:55 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		t.Run("create, no error", func(t *testing.T) { | 
					
						
							|  |  |  | 			// dashboard store & service commands that should be called.
 | 
					
						
							|  |  |  | 			dashboardsvc.On("BuildSaveDashboardCommand", | 
					
						
							|  |  |  | 				mock.Anything, mock.AnythingOfType("*dashboards.SaveDashboardDTO"), | 
					
						
							|  |  |  | 				mock.AnythingOfType("bool"), mock.AnythingOfType("bool")).Return(&models.SaveDashboardCommand{}, nil) | 
					
						
							|  |  |  | 			dashStore.On("SaveDashboard", mock.Anything, mock.AnythingOfType("models.SaveDashboardCommand")).Return(&models.Dashboard{}, nil) | 
					
						
							| 
									
										
										
										
											2022-11-11 21:28:24 +08:00
										 |  |  | 			dashStore.On("GetFolderByID", mock.Anything, mock.AnythingOfType("int64"), mock.AnythingOfType("int64")).Return(&folder.Folder{}, nil) | 
					
						
							| 
									
										
										
										
											2022-11-10 17:41:03 +08:00
										 |  |  | 			ctx = appcontext.WithUser(ctx, usr) | 
					
						
							|  |  |  | 			_, err := foldersvc.Create(ctx, &folder.CreateFolderCommand{ | 
					
						
							|  |  |  | 				OrgID: orgID, | 
					
						
							|  |  |  | 				Title: "myFolder", | 
					
						
							|  |  |  | 				UID:   "myFolder", | 
					
						
							|  |  |  | 			}) | 
					
						
							| 
									
										
										
										
											2022-11-08 21:59:55 +08:00
										 |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 			// CreateFolder should also call the folder store's create method.
 | 
					
						
							|  |  |  | 			require.True(t, store.CreateCalled) | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		t.Run("create returns error from nested folder service", func(t *testing.T) { | 
					
						
							|  |  |  | 			// This test creates and deletes the dashboard, so needs some extra setup.
 | 
					
						
							|  |  |  | 			g := guardian.New | 
					
						
							|  |  |  | 			guardian.MockDashboardGuardian(&guardian.FakeDashboardGuardian{}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// dashboard store & service commands that should be called.
 | 
					
						
							|  |  |  | 			dashboardsvc.On("BuildSaveDashboardCommand", | 
					
						
							|  |  |  | 				mock.Anything, mock.AnythingOfType("*dashboards.SaveDashboardDTO"), | 
					
						
							|  |  |  | 				mock.AnythingOfType("bool"), mock.AnythingOfType("bool")).Return(&models.SaveDashboardCommand{}, nil) | 
					
						
							|  |  |  | 			dashStore.On("SaveDashboard", mock.Anything, mock.AnythingOfType("models.SaveDashboardCommand")).Return(&models.Dashboard{}, nil) | 
					
						
							| 
									
										
										
										
											2022-11-11 21:28:24 +08:00
										 |  |  | 			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) | 
					
						
							| 
									
										
										
										
											2022-11-08 21:59:55 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// return an error from the folder store
 | 
					
						
							|  |  |  | 			store.ExpectedError = errors.New("FAILED") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// the service return success as long as the legacy create succeeds
 | 
					
						
							| 
									
										
										
										
											2022-11-10 17:41:03 +08:00
										 |  |  | 			ctx = appcontext.WithUser(ctx, usr) | 
					
						
							|  |  |  | 			_, err := foldersvc.Create(ctx, &folder.CreateFolderCommand{ | 
					
						
							|  |  |  | 				OrgID: orgID, | 
					
						
							|  |  |  | 				Title: "myFolder", | 
					
						
							|  |  |  | 				UID:   "myFolder", | 
					
						
							|  |  |  | 			}) | 
					
						
							| 
									
										
										
										
											2022-11-08 21:59:55 +08:00
										 |  |  | 			require.Error(t, err, "FAILED") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// CreateFolder should also call the folder store's create method.
 | 
					
						
							|  |  |  | 			require.True(t, store.CreateCalled) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			t.Cleanup(func() { | 
					
						
							|  |  |  | 				guardian.New = g | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2022-11-10 16:42:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-10 22:06:52 +08:00
										 |  |  | 		t.Run("move, no error", func(t *testing.T) { | 
					
						
							|  |  |  | 			store.ExpectedError = nil | 
					
						
							|  |  |  | 			store.ExpectedFolder = &folder.Folder{UID: "myFolder", ParentUID: "newFolder"} | 
					
						
							|  |  |  | 			f, err := foldersvc.Move(ctx, &folder.MoveFolderCommand{UID: "myFolder", NewParentUID: "newFolder", OrgID: orgID}) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 			require.NotNil(t, f) | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-10 16:42:32 +08:00
										 |  |  | 		t.Run("delete with success", func(t *testing.T) { | 
					
						
							|  |  |  | 			var actualCmd *models.DeleteDashboardCommand | 
					
						
							|  |  |  | 			dashStore.On("DeleteDashboard", mock.Anything, mock.Anything).Run(func(args mock.Arguments) { | 
					
						
							|  |  |  | 				actualCmd = args.Get(1).(*models.DeleteDashboardCommand) | 
					
						
							|  |  |  | 			}).Return(nil).Once() | 
					
						
							|  |  |  | 			dashStore.On("GetFolderByUID", mock.Anything, mock.AnythingOfType("int64"), mock.AnythingOfType("string")).Return(&models.Folder{}, nil) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			g := guardian.New | 
					
						
							|  |  |  | 			guardian.MockDashboardGuardian(&guardian.FakeDashboardGuardian{CanSaveValue: true}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			err := foldersvc.DeleteFolder(ctx, &folder.DeleteFolderCommand{UID: "myFolder", OrgID: orgID}) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 			require.NotNil(t, actualCmd) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			t.Cleanup(func() { | 
					
						
							|  |  |  | 				guardian.New = g | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 			require.True(t, store.DeleteCalled) | 
					
						
							|  |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2022-11-08 21:59:55 +08:00
										 |  |  | 	}) | 
					
						
							|  |  |  | } |