mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
API: Support creating a nested folder (#58508)
* API: Support nested folder creation * Update swagger * fixup * Update pkg/api/dtos/folder.go Co-authored-by: Serge Zaitsev <serge.zaitsev@grafana.com> * Fix some tests * create legacy folder url from title and uid Co-authored-by: idafurjes <36131195+idafurjes@users.noreply.github.com> Co-authored-by: Serge Zaitsev <serge.zaitsev@grafana.com> Co-authored-by: Ida Furjesova <ida.furjesova@grafana.com>
This commit is contained in:
committed by
GitHub
parent
b5388bb080
commit
bf5a08e039
@@ -524,11 +524,11 @@ func TestGetAllLibraryElements(t *testing.T) {
|
||||
scenarioWithPanel(t, "When an admin tries to get all library panels and two exist and folderFilter is set to existing folders, it should succeed and the result should be correct",
|
||||
func(t *testing.T, sc scenarioContext) {
|
||||
newFolder := createFolderWithACL(t, sc.sqlStore, "NewFolder", sc.user, []folderACLItem{})
|
||||
command := getCreatePanelCommand(newFolder.Id, "Text - Library Panel2")
|
||||
command := getCreatePanelCommand(newFolder.ID, "Text - Library Panel2")
|
||||
sc.reqContext.Req.Body = mockRequestBody(command)
|
||||
resp := sc.service.createHandler(sc.reqContext)
|
||||
require.Equal(t, 200, resp.Status())
|
||||
folderFilter := strconv.FormatInt(newFolder.Id, 10)
|
||||
folderFilter := strconv.FormatInt(newFolder.ID, 10)
|
||||
|
||||
err := sc.reqContext.Req.ParseForm()
|
||||
require.NoError(t, err)
|
||||
@@ -548,7 +548,7 @@ func TestGetAllLibraryElements(t *testing.T) {
|
||||
{
|
||||
ID: 2,
|
||||
OrgID: 1,
|
||||
FolderID: newFolder.Id,
|
||||
FolderID: newFolder.ID,
|
||||
UID: result.Result.Elements[0].UID,
|
||||
Name: "Text - Library Panel2",
|
||||
Kind: int64(models.PanelElement),
|
||||
@@ -564,7 +564,7 @@ func TestGetAllLibraryElements(t *testing.T) {
|
||||
Version: 1,
|
||||
Meta: LibraryElementDTOMeta{
|
||||
FolderName: "NewFolder",
|
||||
FolderUID: newFolder.Uid,
|
||||
FolderUID: newFolder.UID,
|
||||
ConnectedDashboards: 0,
|
||||
Created: result.Result.Elements[0].Meta.Created,
|
||||
Updated: result.Result.Elements[0].Meta.Updated,
|
||||
@@ -591,7 +591,7 @@ func TestGetAllLibraryElements(t *testing.T) {
|
||||
scenarioWithPanel(t, "When an admin tries to get all library panels and two exist and folderFilter is set to a nonexistent folders, it should succeed and the result should be correct",
|
||||
func(t *testing.T, sc scenarioContext) {
|
||||
newFolder := createFolderWithACL(t, sc.sqlStore, "NewFolder", sc.user, []folderACLItem{})
|
||||
command := getCreatePanelCommand(newFolder.Id, "Text - Library Panel2")
|
||||
command := getCreatePanelCommand(newFolder.ID, "Text - Library Panel2")
|
||||
sc.reqContext.Req.Body = mockRequestBody(command)
|
||||
resp := sc.service.createHandler(sc.reqContext)
|
||||
require.Equal(t, 200, resp.Status())
|
||||
|
||||
@@ -25,7 +25,7 @@ func TestPatchLibraryElement(t *testing.T) {
|
||||
func(t *testing.T, sc scenarioContext) {
|
||||
newFolder := createFolderWithACL(t, sc.sqlStore, "NewFolder", sc.user, []folderACLItem{})
|
||||
cmd := PatchLibraryElementCommand{
|
||||
FolderID: newFolder.Id,
|
||||
FolderID: newFolder.ID,
|
||||
Name: "Panel - New name",
|
||||
Model: []byte(`
|
||||
{
|
||||
@@ -48,7 +48,7 @@ func TestPatchLibraryElement(t *testing.T) {
|
||||
Result: libraryElement{
|
||||
ID: 1,
|
||||
OrgID: 1,
|
||||
FolderID: newFolder.Id,
|
||||
FolderID: newFolder.ID,
|
||||
UID: sc.initialResult.Result.UID,
|
||||
Name: "Panel - New name",
|
||||
Kind: int64(models.PanelElement),
|
||||
@@ -90,7 +90,7 @@ func TestPatchLibraryElement(t *testing.T) {
|
||||
func(t *testing.T, sc scenarioContext) {
|
||||
newFolder := createFolderWithACL(t, sc.sqlStore, "NewFolder", sc.user, []folderACLItem{})
|
||||
cmd := PatchLibraryElementCommand{
|
||||
FolderID: newFolder.Id,
|
||||
FolderID: newFolder.ID,
|
||||
Kind: int64(models.PanelElement),
|
||||
Version: 1,
|
||||
}
|
||||
@@ -99,7 +99,7 @@ func TestPatchLibraryElement(t *testing.T) {
|
||||
resp := sc.service.patchHandler(sc.reqContext)
|
||||
require.Equal(t, 200, resp.Status())
|
||||
var result = validateAndUnMarshalResponse(t, resp)
|
||||
sc.initialResult.Result.FolderID = newFolder.Id
|
||||
sc.initialResult.Result.FolderID = newFolder.ID
|
||||
sc.initialResult.Result.Meta.CreatedBy.Name = userInDbName
|
||||
sc.initialResult.Result.Meta.CreatedBy.AvatarURL = userInDbAvatar
|
||||
sc.initialResult.Result.Meta.Updated = result.Result.Meta.Updated
|
||||
@@ -325,7 +325,7 @@ func TestPatchLibraryElement(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 := createFolderWithACL(t, sc.sqlStore, "NewFolder", sc.user, []folderACLItem{})
|
||||
command := getCreatePanelCommand(newFolder.Id, "Text - Library Panel")
|
||||
command := getCreatePanelCommand(newFolder.ID, "Text - Library Panel")
|
||||
sc.ctx.Req.Body = mockRequestBody(command)
|
||||
resp := sc.service.createHandler(sc.reqContext)
|
||||
var result = validateAndUnMarshalResponse(t, resp)
|
||||
|
||||
@@ -73,7 +73,7 @@ func TestLibraryElementPermissions(t *testing.T) {
|
||||
folder := createFolderWithACL(t, sc.sqlStore, "Folder", sc.user, testCase.items)
|
||||
sc.reqContext.SignedInUser.OrgRole = testCase.role
|
||||
|
||||
command := getCreatePanelCommand(folder.Id, "Library Panel Name")
|
||||
command := getCreatePanelCommand(folder.ID, "Library Panel Name")
|
||||
sc.reqContext.Req.Body = mockRequestBody(command)
|
||||
resp := sc.service.createHandler(sc.reqContext)
|
||||
require.Equal(t, testCase.status, resp.Status())
|
||||
@@ -82,14 +82,14 @@ func TestLibraryElementPermissions(t *testing.T) {
|
||||
testScenario(t, fmt.Sprintf("When %s tries to patch a library panel by moving it to a folder with %s, it should return correct status", testCase.role, testCase.desc),
|
||||
func(t *testing.T, sc scenarioContext) {
|
||||
fromFolder := createFolderWithACL(t, sc.sqlStore, "Everyone", sc.user, everyonePermissions)
|
||||
command := getCreatePanelCommand(fromFolder.Id, "Library Panel Name")
|
||||
command := getCreatePanelCommand(fromFolder.ID, "Library Panel Name")
|
||||
sc.reqContext.Req.Body = mockRequestBody(command)
|
||||
resp := sc.service.createHandler(sc.reqContext)
|
||||
result := validateAndUnMarshalResponse(t, resp)
|
||||
toFolder := createFolderWithACL(t, sc.sqlStore, "Folder", sc.user, testCase.items)
|
||||
sc.reqContext.SignedInUser.OrgRole = testCase.role
|
||||
|
||||
cmd := PatchLibraryElementCommand{FolderID: toFolder.Id, Version: 1, Kind: int64(models.PanelElement)}
|
||||
cmd := PatchLibraryElementCommand{FolderID: toFolder.ID, Version: 1, Kind: int64(models.PanelElement)}
|
||||
sc.ctx.Req = web.SetURLParams(sc.ctx.Req, map[string]string{":uid": result.Result.UID})
|
||||
sc.reqContext.Req.Body = mockRequestBody(cmd)
|
||||
resp = sc.service.patchHandler(sc.reqContext)
|
||||
@@ -99,14 +99,14 @@ func TestLibraryElementPermissions(t *testing.T) {
|
||||
testScenario(t, fmt.Sprintf("When %s tries to patch a library panel by moving it from a folder with %s, it should return correct status", testCase.role, testCase.desc),
|
||||
func(t *testing.T, sc scenarioContext) {
|
||||
fromFolder := createFolderWithACL(t, sc.sqlStore, "Everyone", sc.user, testCase.items)
|
||||
command := getCreatePanelCommand(fromFolder.Id, "Library Panel Name")
|
||||
command := getCreatePanelCommand(fromFolder.ID, "Library Panel Name")
|
||||
sc.reqContext.Req.Body = mockRequestBody(command)
|
||||
resp := sc.service.createHandler(sc.reqContext)
|
||||
result := validateAndUnMarshalResponse(t, resp)
|
||||
toFolder := createFolderWithACL(t, sc.sqlStore, "Folder", sc.user, everyonePermissions)
|
||||
sc.reqContext.SignedInUser.OrgRole = testCase.role
|
||||
|
||||
cmd := PatchLibraryElementCommand{FolderID: toFolder.Id, Version: 1, Kind: int64(models.PanelElement)}
|
||||
cmd := PatchLibraryElementCommand{FolderID: toFolder.ID, Version: 1, Kind: int64(models.PanelElement)}
|
||||
sc.ctx.Req = web.SetURLParams(sc.ctx.Req, map[string]string{":uid": result.Result.UID})
|
||||
sc.reqContext.Req.Body = mockRequestBody(cmd)
|
||||
resp = sc.service.patchHandler(sc.reqContext)
|
||||
@@ -116,7 +116,7 @@ func TestLibraryElementPermissions(t *testing.T) {
|
||||
testScenario(t, fmt.Sprintf("When %s tries to delete a library panel in a folder with %s, it should return correct status", testCase.role, testCase.desc),
|
||||
func(t *testing.T, sc scenarioContext) {
|
||||
folder := createFolderWithACL(t, sc.sqlStore, "Folder", sc.user, testCase.items)
|
||||
cmd := getCreatePanelCommand(folder.Id, "Library Panel Name")
|
||||
cmd := getCreatePanelCommand(folder.ID, "Library Panel Name")
|
||||
sc.reqContext.Req.Body = mockRequestBody(cmd)
|
||||
resp := sc.service.createHandler(sc.reqContext)
|
||||
result := validateAndUnMarshalResponse(t, resp)
|
||||
@@ -151,7 +151,7 @@ func TestLibraryElementPermissions(t *testing.T) {
|
||||
testScenario(t, fmt.Sprintf("When %s tries to patch a library panel by moving it to the General folder, it should return correct status", testCase.role),
|
||||
func(t *testing.T, sc scenarioContext) {
|
||||
folder := createFolderWithACL(t, sc.sqlStore, "Folder", sc.user, everyonePermissions)
|
||||
command := getCreatePanelCommand(folder.Id, "Library Panel Name")
|
||||
command := getCreatePanelCommand(folder.ID, "Library Panel Name")
|
||||
sc.reqContext.Req.Body = mockRequestBody(command)
|
||||
resp := sc.service.createHandler(sc.reqContext)
|
||||
result := validateAndUnMarshalResponse(t, resp)
|
||||
@@ -173,7 +173,7 @@ func TestLibraryElementPermissions(t *testing.T) {
|
||||
result := validateAndUnMarshalResponse(t, resp)
|
||||
sc.reqContext.SignedInUser.OrgRole = testCase.role
|
||||
|
||||
cmd := PatchLibraryElementCommand{FolderID: folder.Id, Version: 1, Kind: int64(models.PanelElement)}
|
||||
cmd := PatchLibraryElementCommand{FolderID: folder.ID, Version: 1, Kind: int64(models.PanelElement)}
|
||||
sc.ctx.Req = web.SetURLParams(sc.ctx.Req, map[string]string{":uid": result.Result.UID})
|
||||
sc.ctx.Req.Body = mockRequestBody(cmd)
|
||||
resp = sc.service.patchHandler(sc.reqContext)
|
||||
@@ -216,7 +216,7 @@ func TestLibraryElementPermissions(t *testing.T) {
|
||||
testScenario(t, fmt.Sprintf("When %s tries to patch a library panel by moving it to a folder that doesn't exist, it should fail", testCase.role),
|
||||
func(t *testing.T, sc scenarioContext) {
|
||||
folder := createFolderWithACL(t, sc.sqlStore, "Folder", sc.user, everyonePermissions)
|
||||
command := getCreatePanelCommand(folder.Id, "Library Panel Name")
|
||||
command := getCreatePanelCommand(folder.ID, "Library Panel Name")
|
||||
sc.reqContext.Req.Body = mockRequestBody(command)
|
||||
resp := sc.service.createHandler(sc.reqContext)
|
||||
result := validateAndUnMarshalResponse(t, resp)
|
||||
@@ -245,7 +245,7 @@ func TestLibraryElementPermissions(t *testing.T) {
|
||||
var results []libraryElement
|
||||
for i, folderCase := range folderCases {
|
||||
folder := createFolderWithACL(t, sc.sqlStore, fmt.Sprintf("Folder%v", i), sc.user, folderCase)
|
||||
cmd := getCreatePanelCommand(folder.Id, fmt.Sprintf("Library Panel in Folder%v", i))
|
||||
cmd := getCreatePanelCommand(folder.ID, fmt.Sprintf("Library Panel in Folder%v", i))
|
||||
sc.reqContext.Req.Body = mockRequestBody(cmd)
|
||||
resp := sc.service.createHandler(sc.reqContext)
|
||||
result := validateAndUnMarshalResponse(t, resp)
|
||||
@@ -254,7 +254,7 @@ func TestLibraryElementPermissions(t *testing.T) {
|
||||
result.Result.Meta.UpdatedBy.Name = userInDbName
|
||||
result.Result.Meta.UpdatedBy.AvatarURL = userInDbAvatar
|
||||
result.Result.Meta.FolderName = folder.Title
|
||||
result.Result.Meta.FolderUID = folder.Uid
|
||||
result.Result.Meta.FolderUID = folder.UID
|
||||
results = append(results, result.Result)
|
||||
}
|
||||
sc.reqContext.SignedInUser.OrgRole = testCase.role
|
||||
@@ -308,7 +308,7 @@ func TestLibraryElementPermissions(t *testing.T) {
|
||||
var results []libraryElement
|
||||
for i, folderCase := range folderCases {
|
||||
folder := createFolderWithACL(t, sc.sqlStore, fmt.Sprintf("Folder%v", i), sc.user, folderCase)
|
||||
cmd := getCreatePanelCommand(folder.Id, fmt.Sprintf("Library Panel in Folder%v", i))
|
||||
cmd := getCreatePanelCommand(folder.ID, fmt.Sprintf("Library Panel in Folder%v", i))
|
||||
sc.reqContext.Req.Body = mockRequestBody(cmd)
|
||||
resp := sc.service.createHandler(sc.reqContext)
|
||||
result := validateAndUnMarshalResponse(t, resp)
|
||||
@@ -317,7 +317,7 @@ func TestLibraryElementPermissions(t *testing.T) {
|
||||
result.Result.Meta.UpdatedBy.Name = userInDbName
|
||||
result.Result.Meta.UpdatedBy.AvatarURL = userInDbAvatar
|
||||
result.Result.Meta.FolderName = folder.Title
|
||||
result.Result.Meta.FolderUID = folder.Uid
|
||||
result.Result.Meta.FolderUID = folder.UID
|
||||
results = append(results, result.Result)
|
||||
}
|
||||
sc.reqContext.SignedInUser.OrgRole = testCase.role
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/api/response"
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/infra/appcontext"
|
||||
"github.com/grafana/grafana/pkg/infra/db"
|
||||
"github.com/grafana/grafana/pkg/infra/db/dbtest"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
@@ -25,6 +26,7 @@ import (
|
||||
"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/guardian"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
@@ -294,7 +296,7 @@ func createDashboard(t *testing.T, sqlStore db.DB, user user.SignedInUser, dash
|
||||
}
|
||||
|
||||
func createFolderWithACL(t *testing.T, sqlStore db.DB, title string, user user.SignedInUser,
|
||||
items []folderACLItem) *models.Folder {
|
||||
items []folderACLItem) *folder.Folder {
|
||||
t.Helper()
|
||||
|
||||
cfg := setting.NewCfg()
|
||||
@@ -312,10 +314,13 @@ func createFolderWithACL(t *testing.T, sqlStore db.DB, title string, user user.S
|
||||
)
|
||||
s := folderimpl.ProvideService(ac, bus.ProvideBus(tracing.InitializeTracerForTest()), cfg, d, dashboardStore, nil, features, folderPermissions, nil)
|
||||
t.Logf("Creating folder with title and UID %q", title)
|
||||
folder, err := s.CreateFolder(context.Background(), &user, user.OrgID, title, title)
|
||||
ctx := appcontext.WithUser(context.Background(), &user)
|
||||
folder, err := s.Create(ctx, &folder.CreateFolderCommand{
|
||||
OrgID: user.OrgID, Title: title, UID: title,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
updateFolderACL(t, dashboardStore, folder.Id, items)
|
||||
updateFolderACL(t, dashboardStore, folder.ID, items)
|
||||
|
||||
return folder
|
||||
}
|
||||
@@ -456,7 +461,7 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo
|
||||
},
|
||||
}
|
||||
|
||||
sc.folder = createFolderWithACL(t, sc.sqlStore, "ScenarioFolder", sc.user, []folderACLItem{})
|
||||
sc.folder = createFolderWithACL(t, sc.sqlStore, "ScenarioFolder", sc.user, []folderACLItem{}).ToLegacyModel()
|
||||
|
||||
fn(t, sc)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user