K8s: Remove kubernetesClientDashboardsFolders feature flag (#108626)

This commit is contained in:
Stephanie Hingtgen
2025-07-29 16:52:57 -05:00
committed by GitHub
parent e3cb84bef8
commit 1f025fe1a3
69 changed files with 1585 additions and 3235 deletions
+8 -27
View File
@@ -893,39 +893,20 @@ func getFoldersWithMatchingTitles(c context.Context, l *LibraryElementService, s
return nil, nil
}
if l.features.IsEnabled(c, featuremgmt.FlagKubernetesClientDashboardsFolders) {
searchQuery := folder.SearchFoldersQuery{
OrgID: signedInUser.GetOrgID(),
Title: query.SearchString,
SignedInUser: signedInUser,
}
folderHits, err := l.folderService.SearchFolders(c, searchQuery)
if err != nil {
return nil, err
}
foldersWithMatchingTitles := make([]string, 0, len(folderHits))
for _, hit := range folderHits {
foldersWithMatchingTitles = append(foldersWithMatchingTitles, hit.UID)
}
return foldersWithMatchingTitles, nil
searchQuery := folder.SearchFoldersQuery{
OrgID: signedInUser.GetOrgID(),
Title: query.SearchString,
SignedInUser: signedInUser,
}
// Fallback to GetFolders
fs, err := l.folderService.GetFolders(c, folder.GetFoldersQuery{
OrgID: signedInUser.GetOrgID(),
SignedInUser: signedInUser,
})
folderHits, err := l.folderService.SearchFolders(c, searchQuery)
if err != nil {
return nil, err
}
foldersWithMatchingTitles := make([]string, 0, len(fs))
for _, f := range fs {
if strings.Contains(strings.ToLower(f.Title), strings.ToLower(query.SearchString)) {
foldersWithMatchingTitles = append(foldersWithMatchingTitles, f.UID)
}
foldersWithMatchingTitles := make([]string, 0, len(folderHits))
for _, hit := range folderHits {
foldersWithMatchingTitles = append(foldersWithMatchingTitles, hit.UID)
}
return foldersWithMatchingTitles, nil
}
@@ -46,8 +46,8 @@ func TestIntegration_CreateLibraryElement(t *testing.T) {
},
Version: 1,
Meta: model.LibraryElementDTOMeta{
FolderName: "ScenarioFolder",
FolderUID: "uid_for_ScenarioFolder",
FolderName: sc.folder.Title,
FolderUID: sc.folder.UID,
ConnectedDashboards: 0,
Created: sc.initialResult.Result.Meta.Created,
Updated: sc.initialResult.Result.Meta.Updated,
@@ -97,8 +97,8 @@ func TestIntegration_CreateLibraryElement(t *testing.T) {
},
Version: 1,
Meta: model.LibraryElementDTOMeta{
FolderName: "ScenarioFolder",
FolderUID: "uid_for_ScenarioFolder",
FolderName: sc.folder.Title,
FolderUID: sc.folder.UID,
ConnectedDashboards: 0,
Created: result.Result.Meta.Created,
Updated: result.Result.Meta.Updated,
@@ -176,8 +176,8 @@ func TestIntegration_CreateLibraryElement(t *testing.T) {
},
Version: 1,
Meta: model.LibraryElementDTOMeta{
FolderName: "ScenarioFolder",
FolderUID: "uid_for_ScenarioFolder",
FolderName: sc.folder.Title,
FolderUID: sc.folder.UID,
ConnectedDashboards: 0,
Created: result.Result.Meta.Created,
Updated: result.Result.Meta.Updated,
@@ -4,9 +4,9 @@ import (
"encoding/json"
"testing"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/libraryelements/model"
"github.com/grafana/grafana/pkg/services/org"
@@ -25,6 +25,7 @@ func TestIntegration_DeleteLibraryElement(t *testing.T) {
scenarioWithPanel(t, "When an admin tries to delete a library panel that exists, it should succeed and return correct ID",
func(t *testing.T, sc scenarioContext) {
sc.dashboardSvc.On("FindDashboards", mock.Anything, mock.Anything).Return([]dashboards.DashboardSearchProjection{}, nil)
sc.ctx.Req = web.SetURLParams(sc.ctx.Req, map[string]string{":uid": sc.initialResult.Result.UID})
resp := sc.service.deleteHandler(sc.reqContext)
require.Equal(t, 200, resp.Status())
@@ -47,39 +48,14 @@ func TestIntegration_DeleteLibraryElement(t *testing.T) {
scenarioWithPanel(t, "When an admin tries to delete a library panel that is connected, it should fail",
func(t *testing.T, sc scenarioContext) {
dashJSON := map[string]any{
"panels": []any{
map[string]any{
"id": int64(1),
"gridPos": map[string]any{
"h": 6,
"w": 6,
"x": 0,
"y": 0,
},
},
map[string]any{
"id": int64(2),
"gridPos": map[string]any{
"h": 6,
"w": 6,
"x": 6,
"y": 0,
},
"libraryPanel": map[string]any{
"uid": sc.initialResult.Result.UID,
"name": sc.initialResult.Result.Name,
},
},
sc.dashboardSvc.On("FindDashboards", mock.Anything, mock.Anything).Return([]dashboards.DashboardSearchProjection{
{
ID: 1,
UID: "test",
},
}
dash := dashboards.Dashboard{
Title: "Testing deleteHandler ",
Data: simplejson.NewFromAny(dashJSON),
}
}, nil)
// nolint:staticcheck
dashInDB := createDashboard(t, sc.sqlStore, sc.user, &dash, sc.folder.ID, sc.folder.UID)
err := sc.service.ConnectElementsToDashboard(sc.reqContext.Req.Context(), sc.reqContext.SignedInUser, []string{sc.initialResult.Result.UID}, dashInDB.ID)
err := sc.service.ConnectElementsToDashboard(sc.reqContext.Req.Context(), sc.reqContext.SignedInUser, []string{sc.initialResult.Result.UID}, 1)
require.NoError(t, err)
sc.ctx.Req = web.SetURLParams(sc.ctx.Req, map[string]string{":uid": sc.initialResult.Result.UID})
@@ -89,6 +65,7 @@ func TestIntegration_DeleteLibraryElement(t *testing.T) {
scenarioWithPanel(t, "When an admin tries to delete a library panel that is connected to a non-existent dashboard, it should succeed",
func(t *testing.T, sc scenarioContext) {
sc.dashboardSvc.On("FindDashboards", mock.Anything, mock.Anything).Return([]dashboards.DashboardSearchProjection{}, nil)
err := sc.service.ConnectElementsToDashboard(sc.reqContext.Req.Context(), sc.reqContext.SignedInUser, []string{sc.initialResult.Result.UID}, 9999999)
require.NoError(t, err)
@@ -8,8 +8,10 @@ import (
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/kinds/librarypanel"
"github.com/grafana/grafana/pkg/services/folder"
"github.com/grafana/grafana/pkg/services/libraryelements/model"
"github.com/grafana/grafana/pkg/services/org"
searchmodel "github.com/grafana/grafana/pkg/services/search/model"
"github.com/grafana/grafana/pkg/services/search/sort"
)
@@ -406,7 +408,14 @@ func TestIntegration_GetAllLibraryElements(t *testing.T) {
scenarioWithPanel(t, "When an admin tries to get all library panels and two exist and folderFilterUIDs is set to existing folders, it should succeed and the result should be correct",
func(t *testing.T, sc scenarioContext) {
newFolder := createFolder(t, sc, "NewFolder", sc.folderSvc)
newFolder := &folder.Folder{
ID: 2,
OrgID: 1,
UID: "uid_for_NewFolder",
Title: "NewFolder",
}
sc.folderSvc.ExpectedFolder = newFolder
sc.folderSvc.ExpectedFolders = []*folder.Folder{newFolder}
// nolint:staticcheck
command := getCreatePanelCommand(newFolder.ID, newFolder.UID, "Text - Library Panel2")
sc.reqContext.Req.Body = mockRequestBody(command)
@@ -448,7 +457,7 @@ func TestIntegration_GetAllLibraryElements(t *testing.T) {
},
Version: 1,
Meta: model.LibraryElementDTOMeta{
FolderName: "NewFolder",
FolderName: newFolder.Title,
FolderUID: newFolder.UID,
ConnectedDashboards: 0,
Created: result.Result.Elements[0].Meta.Created,
@@ -1171,6 +1180,14 @@ func TestIntegration_GetAllLibraryElements(t *testing.T) {
// Folder name search integration tests
scenarioWithPanel(t, "When searching by folder name, it should return panels in that folder",
func(t *testing.T, sc scenarioContext) {
sc.folderSvc.ExpectedHitList = searchmodel.HitList{
{
UID: sc.folder.UID,
Title: sc.folder.Title,
Type: searchmodel.DashHitFolder,
},
}
// Create a panel in the existing folder
// nolint:staticcheck
command := getCreatePanelCommand(sc.folder.ID, sc.folder.UID, "Panel in ScenarioFolder")
@@ -1275,6 +1292,14 @@ func TestIntegration_GetAllLibraryElements(t *testing.T) {
scenarioWithPanel(t, "When searching by partial folder name, it should return panels in matching folders",
func(t *testing.T, sc scenarioContext) {
sc.folderSvc.ExpectedHitList = searchmodel.HitList{
{
UID: sc.folder.UID,
Title: sc.folder.Title,
Type: searchmodel.DashHitFolder,
},
}
// Create a panel in the existing folder
// nolint:staticcheck
command := getCreatePanelCommand(sc.folder.ID, sc.folder.UID, "Test Panel")
@@ -7,7 +7,6 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/infra/db"
"github.com/grafana/grafana/pkg/kinds/librarypanel"
"github.com/grafana/grafana/pkg/services/dashboards"
@@ -57,7 +56,7 @@ func TestIntegration_GetLibraryElement(t *testing.T) {
},
Version: 1,
Meta: model.LibraryElementDTOMeta{
FolderName: "ScenarioFolder",
FolderName: sc.folder.Title,
FolderUID: sc.folder.UID,
ConnectedDashboards: 0,
Created: res.Result.Meta.Created,
@@ -120,6 +119,8 @@ func TestIntegration_GetLibraryElement(t *testing.T) {
SignedInUser: sc.reqContext.SignedInUser,
})
require.NoError(t, err)
sc.folderSvc.ExpectedFolder = nil
sc.folderSvc.ExpectedError = folder.ErrFolderNotFound
err = sc.sqlStore.WithDbSession(sc.reqContext.Req.Context(), func(session *db.Session) error {
elem, err := sc.service.GetLibraryElement(sc.reqContext.Req.Context(), sc.reqContext.SignedInUser, session, result.UID)
require.NoError(t, err)
@@ -131,39 +132,7 @@ func TestIntegration_GetLibraryElement(t *testing.T) {
scenarioWithPanel(t, "When an admin tries to get a connected library panel, it should succeed and return correct connected dashboards",
func(t *testing.T, sc scenarioContext) {
dashJSON := map[string]any{
"panels": []any{
map[string]any{
"id": int64(1),
"gridPos": map[string]any{
"h": 6,
"w": 6,
"x": 0,
"y": 0,
},
},
map[string]any{
"id": int64(2),
"gridPos": map[string]any{
"h": 6,
"w": 6,
"x": 6,
"y": 0,
},
"libraryPanel": map[string]any{
"uid": sc.initialResult.Result.UID,
"name": sc.initialResult.Result.Name,
},
},
},
}
dash := dashboards.Dashboard{
Title: "Testing getHandler",
Data: simplejson.NewFromAny(dashJSON),
}
// nolint:staticcheck
dashInDB := createDashboard(t, sc.sqlStore, sc.user, &dash, sc.folder.ID, sc.folder.UID)
err := sc.service.ConnectElementsToDashboard(sc.reqContext.Req.Context(), sc.reqContext.SignedInUser, []string{sc.initialResult.Result.UID}, dashInDB.ID)
err := sc.service.ConnectElementsToDashboard(sc.reqContext.Req.Context(), sc.reqContext.SignedInUser, []string{sc.initialResult.Result.UID}, 1)
require.NoError(t, err)
expected := func(res libraryElementResult) libraryElementResult {
@@ -187,7 +156,7 @@ func TestIntegration_GetLibraryElement(t *testing.T) {
},
Version: 1,
Meta: model.LibraryElementDTOMeta{
FolderName: "ScenarioFolder",
FolderName: sc.folder.Title,
FolderUID: sc.folder.UID,
ConnectedDashboards: 1,
Created: res.Result.Meta.Created,
@@ -4,6 +4,7 @@ import (
"testing"
"github.com/grafana/grafana/pkg/kinds/librarypanel"
"github.com/grafana/grafana/pkg/services/folder"
"github.com/grafana/grafana/pkg/services/libraryelements/model"
"github.com/grafana/grafana/pkg/util"
@@ -28,7 +29,14 @@ func TestIntegration_PatchLibraryElement(t *testing.T) {
scenarioWithPanel(t, "When an admin tries to patch a library panel that exists, it should succeed",
func(t *testing.T, sc scenarioContext) {
newFolder := createFolder(t, sc, "NewFolder", sc.folderSvc)
newFolder := &folder.Folder{
ID: 2,
OrgID: 1,
UID: "uid_for_NewFolder",
Title: "NewFolder",
}
sc.folderSvc.ExpectedFolder = newFolder
sc.folderSvc.ExpectedFolders = []*folder.Folder{newFolder}
cmd := model.PatchLibraryElementCommand{
FolderID: newFolder.ID, // nolint:staticcheck
FolderUID: &newFolder.UID,
@@ -95,7 +103,14 @@ func TestIntegration_PatchLibraryElement(t *testing.T) {
scenarioWithPanel(t, "When an admin tries to patch a library panel with folder only, it should change folder successfully and return correct result",
func(t *testing.T, sc scenarioContext) {
newFolder := createFolder(t, sc, "NewFolder", sc.folderSvc)
newFolder := &folder.Folder{
ID: 2,
OrgID: 1,
UID: "uid_for_NewFolder",
Title: "NewFolder",
}
sc.folderSvc.ExpectedFolder = newFolder
sc.folderSvc.ExpectedFolders = []*folder.Folder{newFolder}
cmd := model.PatchLibraryElementCommand{
FolderID: newFolder.ID, // nolint:staticcheck
FolderUID: &newFolder.UID,
@@ -340,26 +355,35 @@ func TestIntegration_PatchLibraryElement(t *testing.T) {
scenarioWithPanel(t, "When an admin tries to patch a library panel with a folder where a library panel with the same name already exists, it should fail",
func(t *testing.T, sc scenarioContext) {
newFolder := createFolder(t, sc, "NewFolder", sc.folderSvc)
newFolder := &folder.Folder{
ID: 2,
OrgID: 1,
UID: "uid_for_NewFolder",
Title: "NewFolder",
}
sc.folderSvc.ExpectedFolder = newFolder
sc.folderSvc.ExpectedFolders = []*folder.Folder{newFolder}
// nolint:staticcheck
command := getCreatePanelCommand(newFolder.ID, newFolder.UID, "Text - Library Panel")
sc.ctx.Req.Body = mockRequestBody(command)
resp := sc.service.createHandler(sc.reqContext)
var result = validateAndUnMarshalResponse(t, resp)
sc.service.createHandler(sc.reqContext)
cmd := model.PatchLibraryElementCommand{
FolderID: 1, // nolint:staticcheck
FolderUID: &sc.folder.UID,
FolderID: newFolder.ID, // nolint:staticcheck
FolderUID: &newFolder.UID,
Version: 1,
Kind: int64(model.PanelElement),
}
sc.ctx.Req = web.SetURLParams(sc.ctx.Req, map[string]string{":uid": result.Result.UID})
sc.ctx.Req = web.SetURLParams(sc.ctx.Req, map[string]string{":uid": sc.initialResult.Result.UID})
sc.ctx.Req.Body = mockRequestBody(cmd)
resp = sc.service.patchHandler(sc.reqContext)
resp := sc.service.patchHandler(sc.reqContext)
require.Equal(t, 400, resp.Status())
})
scenarioWithPanel(t, "When an admin tries to patch a library panel in another org, it should fail",
func(t *testing.T, sc scenarioContext) {
sc.folderSvc.ExpectedFolder = nil
sc.folderSvc.ExpectedError = folder.ErrFolderNotFound
cmd := model.PatchLibraryElementCommand{
FolderID: sc.folder.ID, // nolint:staticcheck
FolderUID: &sc.folder.UID,
@@ -16,26 +16,17 @@ import (
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/apimachinery/identity"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/infra/db"
"github.com/grafana/grafana/pkg/infra/kvstore"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/infra/serverlock"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/kinds/librarypanel"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/accesscontrol/acimpl"
"github.com/grafana/grafana/pkg/services/accesscontrol/actest"
acmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
"github.com/grafana/grafana/pkg/services/apiserver"
"github.com/grafana/grafana/pkg/services/apiserver/client"
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/dashboards/database"
dashboardservice "github.com/grafana/grafana/pkg/services/dashboards/service"
"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/foldertest"
"github.com/grafana/grafana/pkg/services/libraryelements/model"
ngstore "github.com/grafana/grafana/pkg/services/ngalert/store"
@@ -43,13 +34,9 @@ import (
"github.com/grafana/grafana/pkg/services/org/orgimpl"
"github.com/grafana/grafana/pkg/services/publicdashboards"
"github.com/grafana/grafana/pkg/services/quota/quotatest"
"github.com/grafana/grafana/pkg/services/search/sort"
"github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest"
"github.com/grafana/grafana/pkg/services/tag/tagimpl"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/services/user/userimpl"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/storage/legacysql/dualwrite"
"github.com/grafana/grafana/pkg/tests/testsuite"
"github.com/grafana/grafana/pkg/web"
)
@@ -67,39 +54,7 @@ func TestIntegration_DeleteLibraryPanelsInFolder(t *testing.T) {
}
scenarioWithPanel(t, "When an admin tries to delete a folder that contains connected library elements, it should fail",
func(t *testing.T, sc scenarioContext) {
dashJSON := map[string]any{
"panels": []any{
map[string]any{
"id": int64(1),
"gridPos": map[string]any{
"h": 6,
"w": 6,
"x": 0,
"y": 0,
},
},
map[string]any{
"id": int64(2),
"gridPos": map[string]any{
"h": 6,
"w": 6,
"x": 6,
"y": 0,
},
"libraryPanel": map[string]any{
"uid": sc.initialResult.Result.UID,
"name": sc.initialResult.Result.Name,
},
},
},
}
dash := dashboards.Dashboard{
Title: "Testing DeleteLibraryElementsInFolder",
Data: simplejson.NewFromAny(dashJSON),
}
// nolint:staticcheck
dashInDB := createDashboard(t, sc.sqlStore, sc.user, &dash, sc.folder.ID, sc.folder.UID)
err := sc.service.ConnectElementsToDashboard(sc.reqContext.Req.Context(), sc.reqContext.SignedInUser, []string{sc.initialResult.Result.UID}, dashInDB.ID)
err := sc.service.ConnectElementsToDashboard(sc.reqContext.Req.Context(), sc.reqContext.SignedInUser, []string{sc.initialResult.Result.UID}, 1)
require.NoError(t, err)
err = sc.service.DeleteLibraryElementsInFolder(sc.reqContext.Req.Context(), sc.reqContext.SignedInUser, sc.folder.UID)
@@ -148,39 +103,7 @@ func TestIntegration_GetLibraryPanelConnections(t *testing.T) {
}
scenarioWithPanel(t, "When an admin tries to get connections of library panel, it should succeed and return correct result",
func(t *testing.T, sc scenarioContext) {
dashJSON := map[string]any{
"panels": []any{
map[string]any{
"id": int64(1),
"gridPos": map[string]any{
"h": 6,
"w": 6,
"x": 0,
"y": 0,
},
},
map[string]any{
"id": int64(2),
"gridPos": map[string]any{
"h": 6,
"w": 6,
"x": 6,
"y": 0,
},
"libraryPanel": map[string]any{
"uid": sc.initialResult.Result.UID,
"name": sc.initialResult.Result.Name,
},
},
},
}
dash := dashboards.Dashboard{
Title: "Testing GetLibraryPanelConnections",
Data: simplejson.NewFromAny(dashJSON),
}
// nolint:staticcheck
dashInDB := createDashboard(t, sc.sqlStore, sc.user, &dash, sc.folder.ID, sc.folder.UID)
err := sc.service.ConnectElementsToDashboard(sc.reqContext.Req.Context(), sc.reqContext.SignedInUser, []string{sc.initialResult.Result.UID}, dashInDB.ID)
err := sc.service.ConnectElementsToDashboard(sc.reqContext.Req.Context(), sc.reqContext.SignedInUser, []string{sc.initialResult.Result.UID}, 1)
require.NoError(t, err)
// add a connection where the dashboard doesn't exist. Shouldn't be returned in the list
@@ -191,12 +114,11 @@ func TestIntegration_GetLibraryPanelConnections(t *testing.T) {
return model.LibraryElementConnectionsResponse{
Result: []model.LibraryElementConnectionDTO{
{
ID: sc.initialResult.Result.ID,
Kind: sc.initialResult.Result.Kind,
ElementID: 1,
ConnectionID: dashInDB.ID,
ConnectionUID: dashInDB.UID,
Created: res.Result[0].Created,
ID: sc.initialResult.Result.ID,
Kind: sc.initialResult.Result.Kind,
ElementID: 1,
ConnectionID: 1,
Created: res.Result[0].Created,
CreatedBy: librarypanel.LibraryElementDTOMetaUser{
Id: 1,
Name: userInDbName,
@@ -207,6 +129,13 @@ func TestIntegration_GetLibraryPanelConnections(t *testing.T) {
}
}
sc.dashboardSvc.On("GetDashboardsByLibraryPanelUID", mock.Anything, mock.Anything, mock.Anything).Return([]*dashboards.DashboardRef{
{
ID: 1,
UID: "",
},
}, nil)
sc.ctx.Req = web.SetURLParams(sc.ctx.Req, map[string]string{":uid": sc.initialResult.Result.UID})
resp := sc.service.getConnectionsHandler(sc.reqContext)
var result = validateAndUnMarshalConnectionResponse(t, resp)
@@ -239,13 +168,7 @@ func TestIntegration_GetLibraryPanelConnections(t *testing.T) {
})
require.NoError(t, err)
dash := dashboards.Dashboard{
Title: "Testing create element",
Data: simplejson.NewFromAny(map[string]any{}),
}
// nolint:staticcheck
dashInDB := createDashboard(t, sc.sqlStore, sc.user, &dash, sc.folder.ID, sc.folder.UID)
err = sc.service.ConnectElementsToDashboard(sc.reqContext.Req.Context(), sc.reqContext.SignedInUser, []string{sc.initialResult.Result.UID}, dashInDB.ID)
err = sc.service.ConnectElementsToDashboard(sc.reqContext.Req.Context(), sc.reqContext.SignedInUser, []string{sc.initialResult.Result.UID}, 1)
require.NoError(t, err)
})
}
@@ -319,77 +242,26 @@ type scenarioContext struct {
initialResult libraryElementResult
sqlStore db.DB
log log.Logger
folderSvc folder.Service
folderSvc *foldertest.FakeService
dashboardSvc *dashboards.FakeDashboardService
}
func createDashboard(t *testing.T, sqlStore db.DB, user user.SignedInUser, dash *dashboards.Dashboard, folderID int64, folderUID string) *dashboards.Dashboard {
// nolint:staticcheck
dash.FolderID = folderID
dash.FolderUID = folderUID
dashItem := &dashboards.SaveDashboardDTO{
Dashboard: dash,
Message: "",
OrgID: user.OrgID,
User: &user,
Overwrite: false,
}
features := featuremgmt.WithFeatures()
cfg := setting.NewCfg()
quotaService := quotatest.New(false, nil)
dashboardStore, err := database.ProvideDashboardStore(sqlStore, cfg, features, tagimpl.ProvideService(sqlStore))
require.NoError(t, err)
ac := actest.FakeAccessControl{ExpectedEvaluate: true}
folderPermissions := acmock.NewMockedPermissionsService()
folderPermissions.On("SetPermissions", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]accesscontrol.ResourcePermission{}, nil)
dashboardPermissions := acmock.NewMockedPermissionsService()
dashboardPermissions.On("SetPermissions", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]accesscontrol.ResourcePermission{}, nil)
folderStore := folderimpl.ProvideDashboardFolderStore(sqlStore)
fStore := folderimpl.ProvideStore(sqlStore)
folderSvc := folderimpl.ProvideService(
fStore, ac, bus.ProvideBus(tracing.InitializeTracerForTest()), dashboardStore, folderStore,
nil, sqlStore, features, supportbundlestest.NewFakeBundleService(), nil, cfg, nil, tracing.InitializeTracerForTest(), nil, dualwrite.ProvideTestService(), sort.ProvideService(), apiserver.WithoutRestConfig)
_, err = folderSvc.Create(context.Background(), &folder.CreateFolderCommand{UID: folderUID, SignedInUser: &user, Title: folderUID + "-title"})
require.NoError(t, err)
service, err := dashboardservice.ProvideDashboardServiceImpl(
cfg, dashboardStore, folderStore,
features, folderPermissions, ac,
actest.FakeService{},
folderSvc,
nil,
client.MockTestRestConfig{},
nil,
quotaService,
nil,
nil,
nil,
dualwrite.ProvideTestService(),
sort.ProvideService(),
serverlock.ProvideService(sqlStore, tracing.InitializeTracerForTest()),
kvstore.NewFakeKVStore(),
)
require.NoError(t, err)
service.RegisterDashboardPermissions(dashboardPermissions)
dashboard, err := service.SaveDashboard(context.Background(), dashItem, true)
require.NoError(t, err)
return dashboard
}
func createFolder(t *testing.T, sc scenarioContext, title string, folderSvc folder.Service) *folder.Folder {
func createFolder(t *testing.T, sc scenarioContext, title string, folderSvc *foldertest.FakeService) *folder.Folder {
t.Helper()
ctx := identity.WithRequester(context.Background(), &sc.user)
folder, err := folderSvc.Create(ctx, &folder.CreateFolderCommand{
f, err := folderSvc.Create(ctx, &folder.CreateFolderCommand{
OrgID: sc.user.OrgID, Title: title, UID: "uid_for_" + title, SignedInUser: &sc.user,
})
require.NoError(t, err)
folderSvc.ExpectedFolder = f
folderSvc.ExpectedFolders = append(folderSvc.ExpectedFolders, f)
// Set user permissions on the newly created folder so that they can interact with library elements stored in it
sc.reqContext.Permissions[sc.user.OrgID][dashboards.ActionFoldersWrite] = append(sc.reqContext.Permissions[sc.user.OrgID][dashboards.ActionFoldersWrite], dashboards.ScopeFoldersProvider.GetResourceScopeUID(folder.UID))
sc.reqContext.Permissions[sc.user.OrgID][dashboards.ActionFoldersRead] = append(sc.reqContext.Permissions[sc.user.OrgID][dashboards.ActionFoldersRead], dashboards.ScopeFoldersProvider.GetResourceScopeUID(folder.UID))
sc.reqContext.Permissions[sc.user.OrgID][dashboards.ActionDashboardsCreate] = append(sc.reqContext.Permissions[sc.user.OrgID][dashboards.ActionDashboardsCreate], dashboards.ScopeFoldersProvider.GetResourceScopeUID(folder.UID))
sc.reqContext.Permissions[sc.user.OrgID][dashboards.ActionFoldersWrite] = append(sc.reqContext.Permissions[sc.user.OrgID][dashboards.ActionFoldersWrite], dashboards.ScopeFoldersProvider.GetResourceScopeUID(f.UID))
sc.reqContext.Permissions[sc.user.OrgID][dashboards.ActionFoldersRead] = append(sc.reqContext.Permissions[sc.user.OrgID][dashboards.ActionFoldersRead], dashboards.ScopeFoldersProvider.GetResourceScopeUID(f.UID))
sc.reqContext.Permissions[sc.user.OrgID][dashboards.ActionDashboardsCreate] = append(sc.reqContext.Permissions[sc.user.OrgID][dashboards.ActionDashboardsCreate], dashboards.ScopeFoldersProvider.GetResourceScopeUID(f.UID))
return folder
return f
}
func validateAndUnMarshalResponse(t *testing.T, resp response.Response) libraryElementResult {
@@ -465,32 +337,28 @@ func setupTestScenario(t *testing.T) scenarioContext {
sqlStore, cfg := db.InitTestDBWithCfg(t)
t.Cleanup(db.CleanupTestDB)
quotaService := quotatest.New(false, nil)
dashboardStore, err := database.ProvideDashboardStore(sqlStore, cfg, features, tagimpl.ProvideService(sqlStore))
require.NoError(t, err)
ac := acimpl.ProvideAccessControl(features)
folderPermissions := acmock.NewMockedPermissionsService()
folderPermissions.On("SetPermissions", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]accesscontrol.ResourcePermission{}, nil)
dashboardPermissions := acmock.NewMockedPermissionsService()
folderStore := folderimpl.ProvideDashboardFolderStore(sqlStore)
fStore := folderimpl.ProvideStore(sqlStore)
publicDash := &publicdashboards.FakePublicDashboardServiceWrapper{}
publicDash.On("DeleteByDashboardUIDs", mock.Anything, mock.Anything, mock.Anything).Return(nil)
folderSvc := folderimpl.ProvideService(
fStore, ac, bus.ProvideBus(tracing.InitializeTracerForTest()), dashboardStore, folderStore,
nil, sqlStore, features, supportbundlestest.NewFakeBundleService(), publicDash, cfg, nil, tracing.InitializeTracerForTest(), nil, dualwrite.ProvideTestService(), sort.ProvideService(), apiserver.WithoutRestConfig)
folderSvc := foldertest.NewFakeService()
f := &folder.Folder{
ID: 1,
OrgID: 1,
UID: "uid_for_ScenarioFolder",
Title: "ScenarioFolder",
}
folderSvc.ExpectedFolder = f
folderSvc.ExpectedFolders = []*folder.Folder{f}
dashService := dashboards.NewFakeDashboardService(t)
alertStore, err := ngstore.ProvideDBStore(cfg, features, sqlStore, &foldertest.FakeService{}, &dashboards.FakeDashboardService{}, ac, bus.ProvideBus(tracing.InitializeTracerForTest()))
require.NoError(t, err)
err = folderSvc.RegisterService(alertStore)
require.NoError(t, err)
dashService, dashSvcErr := dashboardservice.ProvideDashboardServiceImpl(
cfg, dashboardStore, folderStore,
features, folderPermissions, ac, actest.FakeService{}, folderSvc,
nil, client.MockTestRestConfig{}, nil, quotaService, nil, nil, nil, dualwrite.ProvideTestService(), sort.ProvideService(),
serverlock.ProvideService(sqlStore, tracing.InitializeTracerForTest()),
kvstore.NewFakeKVStore(),
)
require.NoError(t, dashSvcErr)
dashService.RegisterDashboardPermissions(dashboardPermissions)
service := LibraryElementService{
Cfg: cfg,
features: featuremgmt.WithFeatures(),
@@ -530,7 +398,8 @@ func setupTestScenario(t *testing.T) scenarioContext {
Context: &webCtx,
SignedInUser: &usr,
},
folderSvc: folderSvc,
folderSvc: folderSvc,
dashboardSvc: dashService,
}
sc.folder = createFolder(t, sc, "ScenarioFolder", folderSvc)