mirror of
https://github.com/grafana/grafana.git
synced 2025-02-12 00:25:46 -06:00
* 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>
226 lines
7.9 KiB
Go
226 lines
7.9 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/grafana/grafana/pkg/components/simplejson"
|
|
"github.com/grafana/grafana/pkg/models"
|
|
"github.com/grafana/grafana/pkg/services/dashboardimport"
|
|
"github.com/grafana/grafana/pkg/services/dashboards"
|
|
"github.com/grafana/grafana/pkg/services/folder"
|
|
"github.com/grafana/grafana/pkg/services/folder/foldertest"
|
|
"github.com/grafana/grafana/pkg/services/librarypanels"
|
|
"github.com/grafana/grafana/pkg/services/org"
|
|
"github.com/grafana/grafana/pkg/services/plugindashboards"
|
|
"github.com/grafana/grafana/pkg/services/user"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestImportDashboardService(t *testing.T) {
|
|
t.Run("When importing a plugin dashboard should save dashboard and sync library panels", func(t *testing.T) {
|
|
pluginDashboardService := &pluginDashboardServiceMock{
|
|
loadPluginDashboardFunc: loadTestDashboard,
|
|
}
|
|
|
|
var importDashboardArg *dashboards.SaveDashboardDTO
|
|
dashboardService := &dashboardServiceMock{
|
|
importDashboardFunc: func(ctx context.Context, dto *dashboards.SaveDashboardDTO) (*models.Dashboard, error) {
|
|
importDashboardArg = dto
|
|
return &models.Dashboard{
|
|
Id: 4,
|
|
Uid: dto.Dashboard.Uid,
|
|
Slug: dto.Dashboard.Slug,
|
|
OrgId: 3,
|
|
Version: dto.Dashboard.Version,
|
|
PluginId: "prometheus",
|
|
FolderId: dto.Dashboard.FolderId,
|
|
Title: dto.Dashboard.Title,
|
|
Data: dto.Dashboard.Data,
|
|
}, nil
|
|
},
|
|
}
|
|
|
|
importLibraryPanelsForDashboard := false
|
|
connectLibraryPanelsForDashboardCalled := false
|
|
libraryPanelService := &libraryPanelServiceMock{
|
|
importLibraryPanelsForDashboardFunc: func(ctx context.Context, signedInUser *user.SignedInUser, libraryPanels *simplejson.Json, panels []interface{}, folderID int64) error {
|
|
importLibraryPanelsForDashboard = true
|
|
return nil
|
|
},
|
|
connectLibraryPanelsForDashboardFunc: func(ctx context.Context, signedInUser *user.SignedInUser, dash *models.Dashboard) error {
|
|
connectLibraryPanelsForDashboardCalled = true
|
|
return nil
|
|
},
|
|
}
|
|
folderService := &foldertest.FakeService{
|
|
ExpectedFolder: &folder.Folder{
|
|
ID: 5,
|
|
UID: "123",
|
|
},
|
|
}
|
|
|
|
s := &ImportDashboardService{
|
|
pluginDashboardService: pluginDashboardService,
|
|
dashboardService: dashboardService,
|
|
libraryPanelService: libraryPanelService,
|
|
folderService: folderService,
|
|
}
|
|
|
|
req := &dashboardimport.ImportDashboardRequest{
|
|
PluginId: "prometheus",
|
|
Path: "dashboard.json",
|
|
Inputs: []dashboardimport.ImportDashboardInput{
|
|
{Name: "*", Type: "datasource", Value: "prom"},
|
|
},
|
|
User: &user.SignedInUser{UserID: 2, OrgRole: org.RoleAdmin, OrgID: 3},
|
|
FolderId: 5,
|
|
}
|
|
resp, err := s.ImportDashboard(context.Background(), req)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, resp)
|
|
require.Equal(t, "UDdpyzz7z", resp.UID)
|
|
|
|
require.NotNil(t, importDashboardArg)
|
|
require.Equal(t, int64(3), importDashboardArg.OrgId)
|
|
require.Equal(t, int64(2), importDashboardArg.User.UserID)
|
|
require.Equal(t, "prometheus", importDashboardArg.Dashboard.PluginId)
|
|
require.Equal(t, int64(5), importDashboardArg.Dashboard.FolderId)
|
|
|
|
panel := importDashboardArg.Dashboard.Data.Get("panels").GetIndex(0)
|
|
require.Equal(t, "prom", panel.Get("datasource").MustString())
|
|
|
|
require.True(t, importLibraryPanelsForDashboard)
|
|
require.True(t, connectLibraryPanelsForDashboardCalled)
|
|
})
|
|
|
|
t.Run("When importing a non-plugin dashboard should save dashboard and sync library panels", func(t *testing.T) {
|
|
var importDashboardArg *dashboards.SaveDashboardDTO
|
|
dashboardService := &dashboardServiceMock{
|
|
importDashboardFunc: func(ctx context.Context, dto *dashboards.SaveDashboardDTO) (*models.Dashboard, error) {
|
|
importDashboardArg = dto
|
|
return &models.Dashboard{
|
|
Id: 4,
|
|
Uid: dto.Dashboard.Uid,
|
|
Slug: dto.Dashboard.Slug,
|
|
OrgId: 3,
|
|
Version: dto.Dashboard.Version,
|
|
PluginId: "prometheus",
|
|
FolderId: dto.Dashboard.FolderId,
|
|
Title: dto.Dashboard.Title,
|
|
Data: dto.Dashboard.Data,
|
|
}, nil
|
|
},
|
|
}
|
|
libraryPanelService := &libraryPanelServiceMock{}
|
|
folderService := &foldertest.FakeService{
|
|
ExpectedFolder: &folder.Folder{
|
|
ID: 5,
|
|
UID: "123",
|
|
},
|
|
}
|
|
s := &ImportDashboardService{
|
|
dashboardService: dashboardService,
|
|
libraryPanelService: libraryPanelService,
|
|
folderService: folderService,
|
|
}
|
|
|
|
loadResp, err := loadTestDashboard(context.Background(), &plugindashboards.LoadPluginDashboardRequest{
|
|
PluginID: "",
|
|
Reference: "dashboard.json",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
req := &dashboardimport.ImportDashboardRequest{
|
|
Dashboard: loadResp.Dashboard.Data,
|
|
Path: "plugin_dashboard.json",
|
|
Inputs: []dashboardimport.ImportDashboardInput{
|
|
{Name: "*", Type: "datasource", Value: "prom"},
|
|
},
|
|
User: &user.SignedInUser{UserID: 2, OrgRole: org.RoleAdmin, OrgID: 3},
|
|
FolderId: 5,
|
|
}
|
|
resp, err := s.ImportDashboard(context.Background(), req)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, resp)
|
|
require.Equal(t, "UDdpyzz7z", resp.UID)
|
|
|
|
require.NotNil(t, importDashboardArg)
|
|
require.Equal(t, int64(3), importDashboardArg.OrgId)
|
|
require.Equal(t, int64(2), importDashboardArg.User.UserID)
|
|
require.Equal(t, "", importDashboardArg.Dashboard.PluginId)
|
|
require.Equal(t, int64(5), importDashboardArg.Dashboard.FolderId)
|
|
|
|
panel := importDashboardArg.Dashboard.Data.Get("panels").GetIndex(0)
|
|
require.Equal(t, "prom", panel.Get("datasource").MustString())
|
|
})
|
|
}
|
|
|
|
func loadTestDashboard(ctx context.Context, req *plugindashboards.LoadPluginDashboardRequest) (*plugindashboards.LoadPluginDashboardResponse, error) {
|
|
// It's safe to ignore gosec warning G304 since this is a test and arguments comes from test configuration.
|
|
// nolint:gosec
|
|
bytes, err := os.ReadFile(filepath.Join("testdata", req.Reference))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
dashboardJSON, err := simplejson.NewJson(bytes)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &plugindashboards.LoadPluginDashboardResponse{
|
|
Dashboard: models.NewDashboardFromJson(dashboardJSON),
|
|
}, nil
|
|
}
|
|
|
|
type pluginDashboardServiceMock struct {
|
|
plugindashboards.Service
|
|
loadPluginDashboardFunc func(ctx context.Context, req *plugindashboards.LoadPluginDashboardRequest) (*plugindashboards.LoadPluginDashboardResponse, error)
|
|
}
|
|
|
|
func (m *pluginDashboardServiceMock) LoadPluginDashboard(ctx context.Context, req *plugindashboards.LoadPluginDashboardRequest) (*plugindashboards.LoadPluginDashboardResponse, error) {
|
|
if m.loadPluginDashboardFunc != nil {
|
|
return m.loadPluginDashboardFunc(ctx, req)
|
|
}
|
|
|
|
return nil, nil
|
|
}
|
|
|
|
type dashboardServiceMock struct {
|
|
dashboards.DashboardService
|
|
importDashboardFunc func(ctx context.Context, dto *dashboards.SaveDashboardDTO) (*models.Dashboard, error)
|
|
}
|
|
|
|
func (s *dashboardServiceMock) ImportDashboard(ctx context.Context, dto *dashboards.SaveDashboardDTO) (*models.Dashboard, error) {
|
|
if s.importDashboardFunc != nil {
|
|
return s.importDashboardFunc(ctx, dto)
|
|
}
|
|
|
|
return nil, nil
|
|
}
|
|
|
|
type libraryPanelServiceMock struct {
|
|
librarypanels.Service
|
|
connectLibraryPanelsForDashboardFunc func(c context.Context, signedInUser *user.SignedInUser, dash *models.Dashboard) error
|
|
importLibraryPanelsForDashboardFunc func(c context.Context, signedInUser *user.SignedInUser, libraryPanels *simplejson.Json, panels []interface{}, folderID int64) error
|
|
}
|
|
|
|
func (s *libraryPanelServiceMock) ConnectLibraryPanelsForDashboard(ctx context.Context, signedInUser *user.SignedInUser, dash *models.Dashboard) error {
|
|
if s.connectLibraryPanelsForDashboardFunc != nil {
|
|
return s.connectLibraryPanelsForDashboardFunc(ctx, signedInUser, dash)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *libraryPanelServiceMock) ImportLibraryPanelsForDashboard(ctx context.Context, signedInUser *user.SignedInUser, libraryPanels *simplejson.Json, panels []interface{}, folderID int64) error {
|
|
if s.importLibraryPanelsForDashboardFunc != nil {
|
|
return s.importLibraryPanelsForDashboardFunc(ctx, signedInUser, libraryPanels, panels, folderID)
|
|
}
|
|
|
|
return nil
|
|
}
|