mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
chore: replace artisanal FakeDashboardService with generated mock (#49276)
* chore: replace handmade FakeDashboardService with generated mock Maintaining a handcrafted FakeDashboardService is not sustainable now that we are in the process of moving the dashboard-related functions out of sqlstore. * remove dialect global variable
This commit is contained in:
parent
ccd160a75e
commit
8c753999df
@ -8,6 +8,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
@ -51,7 +52,7 @@ func TestAnnotationsAPIEndpoint(t *testing.T) {
|
||||
role := models.ROLE_VIEWER
|
||||
t.Run("Should not be allowed to save an annotation", func(t *testing.T) {
|
||||
postAnnotationScenario(t, "When calling POST on", "/api/annotations", "/api/annotations", role,
|
||||
cmd, store, func(sc *scenarioContext) {
|
||||
cmd, store, nil, func(sc *scenarioContext) {
|
||||
sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec()
|
||||
assert.Equal(t, 403, sc.resp.Code)
|
||||
})
|
||||
@ -84,7 +85,7 @@ func TestAnnotationsAPIEndpoint(t *testing.T) {
|
||||
role := models.ROLE_EDITOR
|
||||
t.Run("Should be able to save an annotation", func(t *testing.T) {
|
||||
postAnnotationScenario(t, "When calling POST on", "/api/annotations", "/api/annotations", role,
|
||||
cmd, store, func(sc *scenarioContext) {
|
||||
cmd, store, nil, func(sc *scenarioContext) {
|
||||
sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec()
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
})
|
||||
@ -155,7 +156,7 @@ func TestAnnotationsAPIEndpoint(t *testing.T) {
|
||||
t.Run("When user is an Org Viewer", func(t *testing.T) {
|
||||
role := models.ROLE_VIEWER
|
||||
t.Run("Should not be allowed to save an annotation", func(t *testing.T) {
|
||||
postAnnotationScenario(t, "When calling POST on", "/api/annotations", "/api/annotations", role, cmd, store, func(sc *scenarioContext) {
|
||||
postAnnotationScenario(t, "When calling POST on", "/api/annotations", "/api/annotations", role, cmd, store, nil, func(sc *scenarioContext) {
|
||||
setUpACL()
|
||||
sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec()
|
||||
assert.Equal(t, 403, sc.resp.Code)
|
||||
@ -188,7 +189,7 @@ func TestAnnotationsAPIEndpoint(t *testing.T) {
|
||||
t.Run("When user is an Org Editor", func(t *testing.T) {
|
||||
role := models.ROLE_EDITOR
|
||||
t.Run("Should be able to save an annotation", func(t *testing.T) {
|
||||
postAnnotationScenario(t, "When calling POST on", "/api/annotations", "/api/annotations", role, cmd, store, func(sc *scenarioContext) {
|
||||
postAnnotationScenario(t, "When calling POST on", "/api/annotations", "/api/annotations", role, cmd, store, nil, func(sc *scenarioContext) {
|
||||
setUpACL()
|
||||
sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec()
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
@ -221,19 +222,28 @@ func TestAnnotationsAPIEndpoint(t *testing.T) {
|
||||
t.Run("When user is an Admin", func(t *testing.T) {
|
||||
role := models.ROLE_ADMIN
|
||||
|
||||
mock := mockstore.NewSQLStoreMock()
|
||||
mockStore := mockstore.NewSQLStoreMock()
|
||||
|
||||
t.Run("Should be able to do anything", func(t *testing.T) {
|
||||
postAnnotationScenario(t, "When calling POST on", "/api/annotations", "/api/annotations", role, cmd, store, func(sc *scenarioContext) {
|
||||
postAnnotationScenario(t, "When calling POST on", "/api/annotations", "/api/annotations", role, cmd, store, nil, func(sc *scenarioContext) {
|
||||
setUpACL()
|
||||
sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec()
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
})
|
||||
|
||||
postAnnotationScenario(t, "When calling POST on", "/api/annotations", "/api/annotations", role, dashboardUIDCmd, mock, func(sc *scenarioContext) {
|
||||
dashSvc := dashboards.NewFakeDashboardService(t)
|
||||
dashSvc.On("GetDashboard", mock.Anything, mock.AnythingOfType("*models.GetDashboardQuery")).Run(func(args mock.Arguments) {
|
||||
q := args.Get(1).(*models.GetDashboardQuery)
|
||||
q.Result = &models.Dashboard{
|
||||
Id: q.Id,
|
||||
Uid: q.Uid,
|
||||
}
|
||||
}).Return(nil)
|
||||
postAnnotationScenario(t, "When calling POST on", "/api/annotations", "/api/annotations", role, dashboardUIDCmd, mockStore, dashSvc, func(sc *scenarioContext) {
|
||||
setUpACL()
|
||||
sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec()
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
dashSvc.AssertCalled(t, "GetDashboard", mock.Anything, mock.AnythingOfType("*models.GetDashboardQuery"))
|
||||
})
|
||||
|
||||
putAnnotationScenario(t, "When calling PUT on", "/api/annotations/1", "/api/annotations/:annotationId", role, updateCmd, func(sc *scenarioContext) {
|
||||
@ -249,17 +259,26 @@ func TestAnnotationsAPIEndpoint(t *testing.T) {
|
||||
})
|
||||
|
||||
deleteAnnotationsScenario(t, "When calling POST on", "/api/annotations/mass-delete",
|
||||
"/api/annotations/mass-delete", role, deleteCmd, store, func(sc *scenarioContext) {
|
||||
"/api/annotations/mass-delete", role, deleteCmd, store, nil, func(sc *scenarioContext) {
|
||||
setUpACL()
|
||||
sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec()
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
})
|
||||
|
||||
dashSvc = dashboards.NewFakeDashboardService(t)
|
||||
dashSvc.On("GetDashboard", mock.Anything, mock.AnythingOfType("*models.GetDashboardQuery")).Run(func(args mock.Arguments) {
|
||||
q := args.Get(1).(*models.GetDashboardQuery)
|
||||
q.Result = &models.Dashboard{
|
||||
Id: 1,
|
||||
Uid: deleteWithDashboardUIDCmd.DashboardUID,
|
||||
}
|
||||
}).Return(nil)
|
||||
deleteAnnotationsScenario(t, "When calling POST with dashboardUID on", "/api/annotations/mass-delete",
|
||||
"/api/annotations/mass-delete", role, deleteWithDashboardUIDCmd, mock, func(sc *scenarioContext) {
|
||||
"/api/annotations/mass-delete", role, deleteWithDashboardUIDCmd, mockStore, dashSvc, func(sc *scenarioContext) {
|
||||
setUpACL()
|
||||
sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec()
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
dashSvc.AssertCalled(t, "GetDashboard", mock.Anything, mock.AnythingOfType("*models.GetDashboardQuery"))
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -320,11 +339,11 @@ func (repo *fakeAnnotationsRepo) LoadItems() {
|
||||
var fakeAnnoRepo *fakeAnnotationsRepo
|
||||
|
||||
func postAnnotationScenario(t *testing.T, desc string, url string, routePattern string, role models.RoleType,
|
||||
cmd dtos.PostAnnotationsCmd, store sqlstore.Store, fn scenarioFunc) {
|
||||
cmd dtos.PostAnnotationsCmd, store sqlstore.Store, dashSvc dashboards.DashboardService, fn scenarioFunc) {
|
||||
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
|
||||
hs := setupSimpleHTTPServer(nil)
|
||||
hs.SQLStore = store
|
||||
hs.dashboardService = &dashboards.FakeDashboardService{}
|
||||
hs.dashboardService = dashSvc
|
||||
|
||||
sc := setupScenarioContext(t, url)
|
||||
sc.defaultHandler = routing.Wrap(func(c *models.ReqContext) response.Response {
|
||||
@ -405,11 +424,11 @@ func patchAnnotationScenario(t *testing.T, desc string, url string, routePattern
|
||||
}
|
||||
|
||||
func deleteAnnotationsScenario(t *testing.T, desc string, url string, routePattern string, role models.RoleType,
|
||||
cmd dtos.MassDeleteAnnotationsCmd, store sqlstore.Store, fn scenarioFunc) {
|
||||
cmd dtos.MassDeleteAnnotationsCmd, store sqlstore.Store, dashSvc dashboards.DashboardService, fn scenarioFunc) {
|
||||
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
|
||||
hs := setupSimpleHTTPServer(nil)
|
||||
hs.SQLStore = store
|
||||
hs.dashboardService = &dashboards.FakeDashboardService{}
|
||||
hs.dashboardService = dashSvc
|
||||
|
||||
sc := setupScenarioContext(t, url)
|
||||
sc.defaultHandler = routing.Wrap(func(c *models.ReqContext) response.Response {
|
||||
|
@ -7,12 +7,14 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestApiRetrieveConfig(t *testing.T) {
|
||||
@ -51,11 +53,10 @@ func TestApiRetrieveConfig(t *testing.T) {
|
||||
for _, test := range testCases {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
sc := setupHTTPServerWithMockDb(t, false, false, featuremgmt.WithFeatures(featuremgmt.FlagPublicDashboards))
|
||||
|
||||
sc.hs.dashboardService = &dashboards.FakeDashboardService{
|
||||
PublicDashboardConfigResult: test.publicDashboardConfigResult,
|
||||
PublicDashboardConfigError: test.publicDashboardConfigError,
|
||||
}
|
||||
dashSvc := dashboards.NewFakeDashboardService(t)
|
||||
dashSvc.On("GetPublicDashboardConfig", mock.Anything, mock.AnythingOfType("int64"), mock.AnythingOfType("string")).
|
||||
Return(test.publicDashboardConfigResult, test.publicDashboardConfigError)
|
||||
sc.hs.dashboardService = dashSvc
|
||||
|
||||
setInitCtxSignedInViewer(sc.initCtx)
|
||||
response := callAPI(
|
||||
@ -106,11 +107,10 @@ func TestApiPersistsValue(t *testing.T) {
|
||||
for _, test := range testCases {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
sc := setupHTTPServerWithMockDb(t, false, false, featuremgmt.WithFeatures(featuremgmt.FlagPublicDashboards))
|
||||
|
||||
sc.hs.dashboardService = &dashboards.FakeDashboardService{
|
||||
PublicDashboardConfigResult: &models.PublicDashboardConfig{IsPublic: true},
|
||||
PublicDashboardConfigError: test.saveDashboardError,
|
||||
}
|
||||
dashSvc := dashboards.NewFakeDashboardService(t)
|
||||
dashSvc.On("SavePublicDashboardConfig", mock.Anything, mock.AnythingOfType("*dashboards.SavePublicDashboardConfigDTO")).
|
||||
Return(&models.PublicDashboardConfig{IsPublic: true}, test.saveDashboardError)
|
||||
sc.hs.dashboardService = dashSvc
|
||||
|
||||
setInitCtxSignedInViewer(sc.initCtx)
|
||||
response := callAPI(
|
||||
|
@ -9,9 +9,6 @@ import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/coremodel/dashboard"
|
||||
"github.com/grafana/grafana/pkg/cuectx"
|
||||
"github.com/grafana/grafana/pkg/framework/coremodel"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
@ -20,6 +17,9 @@ import (
|
||||
"github.com/grafana/grafana/pkg/api/response"
|
||||
"github.com/grafana/grafana/pkg/api/routing"
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/coremodel/dashboard"
|
||||
"github.com/grafana/grafana/pkg/cuectx"
|
||||
"github.com/grafana/grafana/pkg/framework/coremodel"
|
||||
"github.com/grafana/grafana/pkg/infra/usagestats"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
accesscontrolmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
|
||||
@ -122,11 +122,11 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
fakeDash.Id = 1
|
||||
fakeDash.FolderId = 1
|
||||
fakeDash.HasAcl = false
|
||||
dashboardService := &dashboards.FakeDashboardService{}
|
||||
dashboardService.GetDashboardFn = func(ctx context.Context, cmd *models.GetDashboardQuery) error {
|
||||
cmd.Result = fakeDash
|
||||
return nil
|
||||
}
|
||||
dashboardService := dashboards.NewFakeDashboardService(t)
|
||||
dashboardService.On("GetDashboard", mock.Anything, mock.AnythingOfType("*models.GetDashboardQuery")).Run(func(args mock.Arguments) {
|
||||
q := args.Get(1).(*models.GetDashboardQuery)
|
||||
q.Result = fakeDash
|
||||
}).Return(nil)
|
||||
|
||||
mockSQLStore := mockstore.NewSQLStoreMock()
|
||||
|
||||
@ -225,11 +225,11 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
fakeDash.Id = 1
|
||||
fakeDash.FolderId = 1
|
||||
fakeDash.HasAcl = true
|
||||
dashboardService := &dashboards.FakeDashboardService{}
|
||||
dashboardService.GetDashboardFn = func(ctx context.Context, cmd *models.GetDashboardQuery) error {
|
||||
cmd.Result = fakeDash
|
||||
return nil
|
||||
}
|
||||
dashboardService := dashboards.NewFakeDashboardService(t)
|
||||
dashboardService.On("GetDashboard", mock.Anything, mock.AnythingOfType("*models.GetDashboardQuery")).Run(func(args mock.Arguments) {
|
||||
q := args.Get(1).(*models.GetDashboardQuery)
|
||||
q.Result = fakeDash
|
||||
}).Return(nil)
|
||||
|
||||
mockSQLStore := mockstore.NewSQLStoreMock()
|
||||
cfg := setting.NewCfg()
|
||||
@ -289,7 +289,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
"/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
|
||||
setUp()
|
||||
sc.sqlStore = mockSQLStore
|
||||
hs.callDeleteDashboardByUID(t, sc, &dashboards.FakeDashboardService{})
|
||||
hs.callDeleteDashboardByUID(t, sc, dashboardService)
|
||||
|
||||
assert.Equal(t, 403, sc.resp.Code)
|
||||
}, mockSQLStore)
|
||||
@ -327,7 +327,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/uid/abcdefghi",
|
||||
"/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
|
||||
setUp()
|
||||
hs.callDeleteDashboardByUID(t, sc, &dashboards.FakeDashboardService{})
|
||||
hs.callDeleteDashboardByUID(t, sc, dashboardService)
|
||||
|
||||
assert.Equal(t, 403, sc.resp.Code)
|
||||
}, mockSQLStore)
|
||||
@ -374,17 +374,14 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
|
||||
loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
|
||||
setUpInner()
|
||||
mockDashboard := &dashboards.FakeDashboardService{
|
||||
SaveDashboardResult: &models.Dashboard{
|
||||
Id: fakeDash.Id,
|
||||
Uid: "uid",
|
||||
Title: "Dash",
|
||||
Slug: "dash",
|
||||
Version: 2,
|
||||
},
|
||||
}
|
||||
dashboardService := dashboards.NewFakeDashboardService(t)
|
||||
dashboardService.On("GetDashboard", mock.Anything, mock.AnythingOfType("*models.GetDashboardQuery")).Run(func(args mock.Arguments) {
|
||||
q := args.Get(1).(*models.GetDashboardQuery)
|
||||
q.Result = models.NewDashboard("test")
|
||||
}).Return(nil)
|
||||
dashboardService.On("DeleteDashboard", mock.Anything, mock.AnythingOfType("int64"), mock.AnythingOfType("int64")).Return(nil)
|
||||
|
||||
hs.callDeleteDashboardByUID(t, sc, mockDashboard)
|
||||
hs.callDeleteDashboardByUID(t, sc, dashboardService)
|
||||
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
}, mockSQLStore)
|
||||
@ -468,7 +465,13 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
|
||||
setUpInner()
|
||||
sc.sqlStore = mockSQLStore
|
||||
hs.callDeleteDashboardByUID(t, sc, &dashboards.FakeDashboardService{})
|
||||
dashboardService := dashboards.NewFakeDashboardService(t)
|
||||
dashboardService.On("GetDashboard", mock.Anything, mock.AnythingOfType("*models.GetDashboardQuery")).Run(func(args mock.Arguments) {
|
||||
q := args.Get(1).(*models.GetDashboardQuery)
|
||||
q.Result = models.NewDashboard("test")
|
||||
}).Return(nil)
|
||||
dashboardService.On("DeleteDashboard", mock.Anything, mock.AnythingOfType("int64"), mock.AnythingOfType("int64")).Return(nil)
|
||||
hs.callDeleteDashboardByUID(t, sc, dashboardService)
|
||||
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
}, mockSQLStore)
|
||||
@ -564,27 +567,13 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
Message: "msg",
|
||||
}
|
||||
|
||||
mock := &dashboards.FakeDashboardService{
|
||||
SaveDashboardResult: &models.Dashboard{
|
||||
Id: dashID,
|
||||
Uid: "uid",
|
||||
Title: "Dash",
|
||||
Slug: "dash",
|
||||
Version: 2,
|
||||
},
|
||||
}
|
||||
dashboardService := dashboards.NewFakeDashboardService(t)
|
||||
dashboardService.On("SaveDashboard", mock.Anything, mock.AnythingOfType("*dashboards.SaveDashboardDTO"), mock.AnythingOfType("bool")).
|
||||
Return(&models.Dashboard{Id: dashID, Uid: "uid", Title: "Dash", Slug: "dash", Version: 2}, nil)
|
||||
|
||||
postDashboardScenario(t, "When calling POST on", "/api/dashboards", "/api/dashboards", cmd, mock, nil, func(sc *scenarioContext) {
|
||||
postDashboardScenario(t, "When calling POST on", "/api/dashboards", "/api/dashboards", cmd, dashboardService, nil, func(sc *scenarioContext) {
|
||||
callPostDashboardShouldReturnSuccess(sc)
|
||||
|
||||
dto := mock.SavedDashboards[0]
|
||||
assert.Equal(t, cmd.OrgId, dto.OrgId)
|
||||
assert.Equal(t, cmd.UserId, dto.User.UserId)
|
||||
assert.Equal(t, folderID, dto.Dashboard.FolderId)
|
||||
assert.Equal(t, "Dash", dto.Dashboard.Title)
|
||||
assert.True(t, dto.Overwrite)
|
||||
assert.Equal(t, "msg", dto.Message)
|
||||
|
||||
result := sc.ToJSON()
|
||||
assert.Equal(t, "success", result.Get("status").MustString())
|
||||
assert.Equal(t, dashID, result.Get("id").MustInt64())
|
||||
@ -610,30 +599,17 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
Message: "msg",
|
||||
}
|
||||
|
||||
mock := &dashboards.FakeDashboardService{
|
||||
SaveDashboardResult: &models.Dashboard{
|
||||
Id: dashID,
|
||||
Uid: "uid",
|
||||
Title: "Dash",
|
||||
Slug: "dash",
|
||||
Version: 2,
|
||||
},
|
||||
}
|
||||
dashboardService := dashboards.NewFakeDashboardService(t)
|
||||
dashboardService.On("SaveDashboard", mock.Anything, mock.AnythingOfType("*dashboards.SaveDashboardDTO"), mock.AnythingOfType("bool")).
|
||||
Return(&models.Dashboard{Id: dashID, Uid: "uid", Title: "Dash", Slug: "dash", Version: 2}, nil)
|
||||
|
||||
mockFolder := &fakeFolderService{
|
||||
GetFolderByUIDResult: &models.Folder{Id: 1, Uid: "folderUID", Title: "Folder"},
|
||||
}
|
||||
|
||||
postDashboardScenario(t, "When calling POST on", "/api/dashboards", "/api/dashboards", cmd, mock, mockFolder, func(sc *scenarioContext) {
|
||||
postDashboardScenario(t, "When calling POST on", "/api/dashboards", "/api/dashboards", cmd, dashboardService, mockFolder, func(sc *scenarioContext) {
|
||||
callPostDashboardShouldReturnSuccess(sc)
|
||||
|
||||
dto := mock.SavedDashboards[0]
|
||||
assert.Equal(t, cmd.OrgId, dto.OrgId)
|
||||
assert.Equal(t, cmd.UserId, dto.User.UserId)
|
||||
assert.Equal(t, "Dash", dto.Dashboard.Title)
|
||||
assert.True(t, dto.Overwrite)
|
||||
assert.Equal(t, "msg", dto.Message)
|
||||
|
||||
result := sc.ToJSON()
|
||||
assert.Equal(t, "success", result.Get("status").MustString())
|
||||
assert.Equal(t, dashID, result.Get("id").MustInt64())
|
||||
@ -644,9 +620,6 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Given a request with incorrect folder uid for creating a dashboard with", func(t *testing.T) {
|
||||
const folderUid string = "folderUID"
|
||||
const dashID int64 = 2
|
||||
|
||||
cmd := models.SaveDashboardCommand{
|
||||
OrgId: 1,
|
||||
UserId: 5,
|
||||
@ -654,26 +627,18 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
"title": "Dash",
|
||||
}),
|
||||
Overwrite: true,
|
||||
FolderUid: folderUid,
|
||||
FolderUid: "folderUID",
|
||||
IsFolder: false,
|
||||
Message: "msg",
|
||||
}
|
||||
|
||||
mock := &dashboards.FakeDashboardService{
|
||||
SaveDashboardResult: &models.Dashboard{
|
||||
Id: dashID,
|
||||
Uid: "uid",
|
||||
Title: "Dash",
|
||||
Slug: "dash",
|
||||
Version: 2,
|
||||
},
|
||||
}
|
||||
dashboardService := dashboards.NewFakeDashboardService(t)
|
||||
|
||||
mockFolder := &fakeFolderService{
|
||||
GetFolderByUIDError: errors.New("Error while searching Folder ID"),
|
||||
}
|
||||
|
||||
postDashboardScenario(t, "When calling POST on", "/api/dashboards", "/api/dashboards", cmd, mock, mockFolder, func(sc *scenarioContext) {
|
||||
postDashboardScenario(t, "When calling POST on", "/api/dashboards", "/api/dashboards", cmd, dashboardService, mockFolder, func(sc *scenarioContext) {
|
||||
callPostDashboard(sc)
|
||||
assert.Equal(t, 500, sc.resp.Code)
|
||||
})
|
||||
@ -713,12 +678,11 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
mock := &dashboards.FakeDashboardService{
|
||||
SaveDashboardError: tc.SaveError,
|
||||
}
|
||||
dashboardService := dashboards.NewFakeDashboardService(t)
|
||||
dashboardService.On("SaveDashboard", mock.Anything, mock.AnythingOfType("*dashboards.SaveDashboardDTO"), mock.AnythingOfType("bool")).Return(nil, tc.SaveError)
|
||||
|
||||
postDashboardScenario(t, fmt.Sprintf("Expect '%s' error when calling POST on", tc.SaveError.Error()),
|
||||
"/api/dashboards", "/api/dashboards", cmd, mock, nil, func(sc *scenarioContext) {
|
||||
"/api/dashboards", "/api/dashboards", cmd, dashboardService, nil, func(sc *scenarioContext) {
|
||||
callPostDashboard(sc)
|
||||
assert.Equal(t, tc.ExpectedStatusCode, sc.resp.Code)
|
||||
})
|
||||
@ -788,21 +752,17 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
fakeDash.FolderId = folderID
|
||||
fakeDash.HasAcl = false
|
||||
|
||||
saved := &models.Dashboard{
|
||||
Id: 2,
|
||||
Uid: "uid",
|
||||
Title: "Dash",
|
||||
Slug: "dash",
|
||||
Version: 1,
|
||||
}
|
||||
|
||||
mock := &dashboards.FakeDashboardService{
|
||||
SaveDashboardResult: saved,
|
||||
GetDashboardFn: func(ctx context.Context, cmd *models.GetDashboardQuery) error {
|
||||
cmd.Result = fakeDash
|
||||
return nil
|
||||
},
|
||||
}
|
||||
dashboardService := dashboards.NewFakeDashboardService(t)
|
||||
dashboardService.On("GetDashboard", mock.Anything, mock.AnythingOfType("*models.GetDashboardQuery")).Run(func(args mock.Arguments) {
|
||||
q := args.Get(1).(*models.GetDashboardQuery)
|
||||
q.Result = fakeDash
|
||||
}).Return(nil)
|
||||
dashboardService.On("SaveDashboard", mock.Anything, mock.AnythingOfType("*dashboards.SaveDashboardDTO"), mock.AnythingOfType("bool")).Run(func(args mock.Arguments) {
|
||||
cmd := args.Get(1).(*dashboards.SaveDashboardDTO)
|
||||
cmd.Dashboard = &models.Dashboard{
|
||||
Id: 2, Uid: "uid", Title: "Dash", Slug: "dash", Version: 1,
|
||||
}
|
||||
}).Return(nil, nil)
|
||||
|
||||
cmd := dtos.RestoreDashboardVersionCommand{
|
||||
Version: 1,
|
||||
@ -814,15 +774,11 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
Version: 1,
|
||||
Data: fakeDash.Data,
|
||||
}}
|
||||
|
||||
restoreDashboardVersionScenario(t, "When calling POST on", "/api/dashboards/id/1/restore",
|
||||
"/api/dashboards/id/:dashboardId/restore", mock, cmd, func(sc *scenarioContext) {
|
||||
"/api/dashboards/id/:dashboardId/restore", dashboardService, cmd, func(sc *scenarioContext) {
|
||||
callRestoreDashboardVersion(sc)
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
dto := mock.SavedDashboards[0]
|
||||
|
||||
assert.Equal(t, folderID, dto.Dashboard.FolderId)
|
||||
assert.Equal(t, "Child dash", dto.Dashboard.Title)
|
||||
assert.Equal(t, "Restored from version 1", dto.Message)
|
||||
}, mockSQLStore)
|
||||
})
|
||||
|
||||
@ -831,21 +787,17 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
fakeDash.Id = 2
|
||||
fakeDash.HasAcl = false
|
||||
|
||||
saved := &models.Dashboard{
|
||||
Id: 2,
|
||||
Uid: "uid",
|
||||
Title: "Dash",
|
||||
Slug: "dash",
|
||||
Version: 1,
|
||||
}
|
||||
|
||||
mock := &dashboards.FakeDashboardService{
|
||||
SaveDashboardResult: saved,
|
||||
GetDashboardFn: func(ctx context.Context, cmd *models.GetDashboardQuery) error {
|
||||
cmd.Result = fakeDash
|
||||
return nil
|
||||
},
|
||||
}
|
||||
dashboardService := dashboards.NewFakeDashboardService(t)
|
||||
dashboardService.On("GetDashboard", mock.Anything, mock.AnythingOfType("*models.GetDashboardQuery")).Run(func(args mock.Arguments) {
|
||||
q := args.Get(1).(*models.GetDashboardQuery)
|
||||
q.Result = fakeDash
|
||||
}).Return(nil)
|
||||
dashboardService.On("SaveDashboard", mock.Anything, mock.AnythingOfType("*dashboards.SaveDashboardDTO"), mock.AnythingOfType("bool")).Run(func(args mock.Arguments) {
|
||||
cmd := args.Get(1).(*dashboards.SaveDashboardDTO)
|
||||
cmd.Dashboard = &models.Dashboard{
|
||||
Id: 2, Uid: "uid", Title: "Dash", Slug: "dash", Version: 1,
|
||||
}
|
||||
}).Return(nil, nil)
|
||||
|
||||
cmd := dtos.RestoreDashboardVersionCommand{
|
||||
Version: 1,
|
||||
@ -858,14 +810,9 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
Data: fakeDash.Data,
|
||||
}}
|
||||
restoreDashboardVersionScenario(t, "When calling POST on", "/api/dashboards/id/1/restore",
|
||||
"/api/dashboards/id/:dashboardId/restore", mock, cmd, func(sc *scenarioContext) {
|
||||
"/api/dashboards/id/:dashboardId/restore", dashboardService, cmd, func(sc *scenarioContext) {
|
||||
callRestoreDashboardVersion(sc)
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
dto := mock.SavedDashboards[0]
|
||||
|
||||
assert.Equal(t, int64(0), dto.Dashboard.FolderId)
|
||||
assert.Equal(t, "Child dash", dto.Dashboard.Title)
|
||||
assert.Equal(t, "Restored from version 1", dto.Message)
|
||||
}, mockSQLStore)
|
||||
})
|
||||
|
||||
@ -879,12 +826,12 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
|
||||
dataValue, err := simplejson.NewJson([]byte(`{"id": 1, "editable": true, "style": "dark"}`))
|
||||
require.NoError(t, err)
|
||||
dashboardService := &dashboards.FakeDashboardService{
|
||||
GetDashboardFn: func(ctx context.Context, cmd *models.GetDashboardQuery) error {
|
||||
cmd.Result = &models.Dashboard{Id: 1, Data: dataValue}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
dashboardService := dashboards.NewFakeDashboardService(t)
|
||||
dashboardService.On("GetDashboard", mock.Anything, mock.AnythingOfType("*models.GetDashboardQuery")).Run(func(args mock.Arguments) {
|
||||
q := args.Get(1).(*models.GetDashboardQuery)
|
||||
q.Result = &models.Dashboard{Id: 1, Data: dataValue}
|
||||
}).Return(nil)
|
||||
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/uid/dash", "/api/dashboards/uid/:uid", models.ROLE_EDITOR, func(sc *scenarioContext) {
|
||||
setUp()
|
||||
@ -950,15 +897,15 @@ func getDashboardShouldReturn200WithConfig(t *testing.T, sc *scenarioContext, pr
|
||||
dashboardStore = database.ProvideDashboardStore(sql)
|
||||
}
|
||||
|
||||
if dashboardService == nil {
|
||||
dashboardService = &dashboards.FakeDashboardService{}
|
||||
}
|
||||
|
||||
libraryPanelsService := mockLibraryPanelService{}
|
||||
libraryElementsService := mockLibraryElementService{}
|
||||
cfg := setting.NewCfg()
|
||||
features := featuremgmt.WithFeatures()
|
||||
|
||||
if dashboardService == nil {
|
||||
dashboardService = service.ProvideDashboardService(cfg, dashboardStore, nil, features, nil, accesscontrolmock.NewMockedPermissionsService())
|
||||
}
|
||||
|
||||
hs := &HTTPServer{
|
||||
Cfg: cfg,
|
||||
LibraryPanelService: &libraryPanelsService,
|
||||
|
@ -1,7 +1,6 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
@ -9,6 +8,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
@ -34,12 +34,12 @@ var (
|
||||
|
||||
func TestAPIEndpoint_GetCurrentOrgPreferences_LegacyAccessControl(t *testing.T) {
|
||||
sc := setupHTTPServer(t, true, false)
|
||||
dashSvc := &dashboards.FakeDashboardService{
|
||||
GetDashboardFn: func(ctx context.Context, cmd *models.GetDashboardQuery) error {
|
||||
cmd.Result = &models.Dashboard{Uid: "home", Id: 1}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
dashSvc := dashboards.NewFakeDashboardService(t)
|
||||
dashSvc.On("GetDashboard", mock.Anything, mock.AnythingOfType("*models.GetDashboardQuery")).Run(func(args mock.Arguments) {
|
||||
q := args.Get(1).(*models.GetDashboardQuery)
|
||||
q.Result = &models.Dashboard{Uid: "home", Id: 1}
|
||||
}).Return(nil)
|
||||
|
||||
sc.hs.dashboardService = dashSvc
|
||||
|
||||
prefService := preftest.NewPreferenceServiceFake()
|
||||
@ -164,7 +164,11 @@ func TestAPIEndpoint_PatchUserPreferences(t *testing.T) {
|
||||
assert.Equal(t, http.StatusBadRequest, response.Code)
|
||||
})
|
||||
input = strings.NewReader(testUpdateOrgPreferencesWithHomeDashboardUIDCmd)
|
||||
dashSvc := &dashboards.FakeDashboardService{}
|
||||
dashSvc := dashboards.NewFakeDashboardService(t)
|
||||
dashSvc.On("GetDashboard", mock.Anything, mock.AnythingOfType("*models.GetDashboardQuery")).Run(func(args mock.Arguments) {
|
||||
q := args.Get(1).(*models.GetDashboardQuery)
|
||||
q.Result = &models.Dashboard{Uid: "home", Id: 1}
|
||||
}).Return(nil)
|
||||
sc.hs.dashboardService = dashSvc
|
||||
t.Run("Returns 200 on success", func(t *testing.T) {
|
||||
response := callAPI(sc.server, http.MethodPatch, patchUserPreferencesUrl, input, t)
|
||||
|
@ -6,17 +6,12 @@ import (
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
)
|
||||
|
||||
// Generating mocks is handled by vektra/mockery
|
||||
// 1. install go mockery https://github.com/vektra/mockery#go-install
|
||||
// 2. add your method to the relevant services
|
||||
// 3. from the same directory as this file run `go generate` and it will update the mock
|
||||
// If you don't see any output, this most likely means your OS can't find the mockery binary
|
||||
// `which mockery` to confirm and follow one of the installation methods
|
||||
|
||||
//go:generate mockery --name DashboardService --structname FakeDashboardService --inpackage --filename dashboard_service_mock.go
|
||||
// DashboardService is a service for operating on dashboards.
|
||||
type DashboardService interface {
|
||||
BuildSaveDashboardCommand(ctx context.Context, dto *SaveDashboardDTO, shouldValidateAlerts bool, validateProvisionedDashboard bool) (*models.SaveDashboardCommand, error)
|
||||
DeleteDashboard(ctx context.Context, dashboardId int64, orgId int64) error
|
||||
FindDashboards(ctx context.Context, query *models.FindPersistedDashboardsQuery) ([]DashboardSearchProjection, error)
|
||||
GetDashboard(ctx context.Context, query *models.GetDashboardQuery) error
|
||||
GetDashboards(ctx context.Context, query *models.GetDashboardsQuery) error
|
||||
GetDashboardUIDById(ctx context.Context, query *models.GetDashboardRefByIdQuery) error
|
||||
@ -25,6 +20,7 @@ type DashboardService interface {
|
||||
MakeUserAdmin(ctx context.Context, orgID int64, userID, dashboardID int64, setViewAndEditPermissions bool) error
|
||||
SaveDashboard(ctx context.Context, dto *SaveDashboardDTO, allowUiUpdate bool) (*models.Dashboard, error)
|
||||
SavePublicDashboardConfig(ctx context.Context, dto *SavePublicDashboardConfigDTO) (*models.PublicDashboardConfig, error)
|
||||
SearchDashboards(ctx context.Context, query *models.FindPersistedDashboardsQuery) error
|
||||
UpdateDashboardACL(ctx context.Context, uid int64, items []*models.DashboardAcl) error
|
||||
}
|
||||
|
||||
@ -51,6 +47,7 @@ type DashboardProvisioningService interface {
|
||||
type Store interface {
|
||||
DeleteDashboard(ctx context.Context, cmd *models.DeleteDashboardCommand) error
|
||||
DeleteOrphanedProvisionedDashboards(ctx context.Context, cmd *models.DeleteOrphanedProvisionedDashboardsCommand) error
|
||||
FindDashboards(ctx context.Context, query *models.FindPersistedDashboardsQuery) ([]DashboardSearchProjection, error)
|
||||
GetDashboard(ctx context.Context, query *models.GetDashboardQuery) error
|
||||
GetDashboardUIDById(ctx context.Context, query *models.GetDashboardRefByIdQuery) error
|
||||
GetDashboards(ctx context.Context, query *models.GetDashboardsQuery) error
|
||||
@ -65,6 +62,7 @@ type Store interface {
|
||||
SaveDashboard(cmd models.SaveDashboardCommand) (*models.Dashboard, error)
|
||||
SaveProvisionedDashboard(cmd models.SaveDashboardCommand, provisioning *models.DashboardProvisioning) (*models.Dashboard, error)
|
||||
SavePublicDashboardConfig(cmd models.SavePublicDashboardConfigCommand) (*models.PublicDashboardConfig, error)
|
||||
SearchDashboards(ctx context.Context, query *models.FindPersistedDashboardsQuery) error
|
||||
UnprovisionDashboard(ctx context.Context, id int64) error
|
||||
UpdateDashboardACL(ctx context.Context, uid int64, items []*models.DashboardAcl) error
|
||||
// ValidateDashboardBeforeSave validates a dashboard before save.
|
||||
|
@ -1,79 +1,263 @@
|
||||
// Code generated by mockery v2.12.2. DO NOT EDIT.
|
||||
|
||||
package dashboards
|
||||
|
||||
import (
|
||||
"context"
|
||||
context "context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
models "github.com/grafana/grafana/pkg/models"
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
|
||||
testing "testing"
|
||||
)
|
||||
|
||||
// FakeDashboardService is an autogenerated mock type for the DashboardService type
|
||||
type FakeDashboardService struct {
|
||||
DashboardService
|
||||
|
||||
SaveDashboardResult *models.Dashboard
|
||||
SavedDashboards []*SaveDashboardDTO
|
||||
ProvisionedDashData *models.DashboardProvisioning
|
||||
|
||||
PublicDashboardConfigResult *models.PublicDashboardConfig
|
||||
PublicDashboardConfigError error
|
||||
SaveDashboardError error
|
||||
GetDashboardFn func(ctx context.Context, cmd *models.GetDashboardQuery) error
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
func (s *FakeDashboardService) SaveDashboard(ctx context.Context, dto *SaveDashboardDTO, allowUiUpdate bool) (*models.Dashboard, error) {
|
||||
s.SavedDashboards = append(s.SavedDashboards, dto)
|
||||
// BuildSaveDashboardCommand provides a mock function with given fields: ctx, dto, shouldValidateAlerts, validateProvisionedDashboard
|
||||
func (_m *FakeDashboardService) BuildSaveDashboardCommand(ctx context.Context, dto *SaveDashboardDTO, shouldValidateAlerts bool, validateProvisionedDashboard bool) (*models.SaveDashboardCommand, error) {
|
||||
ret := _m.Called(ctx, dto, shouldValidateAlerts, validateProvisionedDashboard)
|
||||
|
||||
if s.SaveDashboardResult == nil && s.SaveDashboardError == nil {
|
||||
s.SaveDashboardResult = dto.Dashboard
|
||||
}
|
||||
|
||||
return s.SaveDashboardResult, s.SaveDashboardError
|
||||
}
|
||||
|
||||
func (s *FakeDashboardService) GetPublicDashboardConfig(ctx context.Context, orgId int64, dashboardUid string) (*models.PublicDashboardConfig, error) {
|
||||
return s.PublicDashboardConfigResult, s.PublicDashboardConfigError
|
||||
}
|
||||
|
||||
func (s *FakeDashboardService) SavePublicDashboardConfig(ctx context.Context, dto *SavePublicDashboardConfigDTO) (*models.PublicDashboardConfig, error) {
|
||||
return s.PublicDashboardConfigResult, s.PublicDashboardConfigError
|
||||
}
|
||||
|
||||
func (s *FakeDashboardService) ImportDashboard(ctx context.Context, dto *SaveDashboardDTO) (*models.Dashboard, error) {
|
||||
return s.SaveDashboard(ctx, dto, true)
|
||||
}
|
||||
|
||||
func (s *FakeDashboardService) DeleteDashboard(ctx context.Context, dashboardId int64, orgId int64) error {
|
||||
for index, dash := range s.SavedDashboards {
|
||||
if dash.Dashboard.Id == dashboardId && dash.OrgId == orgId {
|
||||
s.SavedDashboards = append(s.SavedDashboards[:index], s.SavedDashboards[index+1:]...)
|
||||
break
|
||||
var r0 *models.SaveDashboardCommand
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *SaveDashboardDTO, bool, bool) *models.SaveDashboardCommand); ok {
|
||||
r0 = rf(ctx, dto, shouldValidateAlerts, validateProvisionedDashboard)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*models.SaveDashboardCommand)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *FakeDashboardService) GetProvisionedDashboardDataByDashboardID(id int64) (*models.DashboardProvisioning, error) {
|
||||
return s.ProvisionedDashData, nil
|
||||
}
|
||||
func (s *FakeDashboardService) DeleteOrphanedProvisionedDashboards(ctx context.Context, cmd *models.DeleteOrphanedProvisionedDashboardsCommand) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *FakeDashboardService) GetDashboard(ctx context.Context, cmd *models.GetDashboardQuery) error {
|
||||
if s.GetDashboardFn != nil {
|
||||
return s.GetDashboardFn(ctx, cmd)
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *SaveDashboardDTO, bool, bool) error); ok {
|
||||
r1 = rf(ctx, dto, shouldValidateAlerts, validateProvisionedDashboard)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
// A minimal result for tests that need a valid result, but don't care what's in it.
|
||||
d := models.NewDashboard("mocked")
|
||||
d.Id = 1
|
||||
d.Uid = "1"
|
||||
cmd.Result = d
|
||||
return nil
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
func (s *FakeDashboardService) GetDashboardUIDById(ctx context.Context, query *models.GetDashboardRefByIdQuery) error {
|
||||
return nil
|
||||
// DeleteDashboard provides a mock function with given fields: ctx, dashboardId, orgId
|
||||
func (_m *FakeDashboardService) DeleteDashboard(ctx context.Context, dashboardId int64, orgId int64) error {
|
||||
ret := _m.Called(ctx, dashboardId, orgId)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, int64, int64) error); ok {
|
||||
r0 = rf(ctx, dashboardId, orgId)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
func (s *FakeDashboardService) GetDashboards(ctx context.Context, query *models.GetDashboardsQuery) error {
|
||||
return nil
|
||||
// FindDashboards provides a mock function with given fields: ctx, query
|
||||
func (_m *FakeDashboardService) FindDashboards(ctx context.Context, query *models.FindPersistedDashboardsQuery) ([]DashboardSearchProjection, error) {
|
||||
ret := _m.Called(ctx, query)
|
||||
|
||||
var r0 []DashboardSearchProjection
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *models.FindPersistedDashboardsQuery) []DashboardSearchProjection); ok {
|
||||
r0 = rf(ctx, query)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]DashboardSearchProjection)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *models.FindPersistedDashboardsQuery) error); ok {
|
||||
r1 = rf(ctx, query)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetDashboard provides a mock function with given fields: ctx, query
|
||||
func (_m *FakeDashboardService) GetDashboard(ctx context.Context, query *models.GetDashboardQuery) error {
|
||||
ret := _m.Called(ctx, query)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *models.GetDashboardQuery) error); ok {
|
||||
r0 = rf(ctx, query)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// GetDashboardUIDById provides a mock function with given fields: ctx, query
|
||||
func (_m *FakeDashboardService) GetDashboardUIDById(ctx context.Context, query *models.GetDashboardRefByIdQuery) error {
|
||||
ret := _m.Called(ctx, query)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *models.GetDashboardRefByIdQuery) error); ok {
|
||||
r0 = rf(ctx, query)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// GetDashboards provides a mock function with given fields: ctx, query
|
||||
func (_m *FakeDashboardService) GetDashboards(ctx context.Context, query *models.GetDashboardsQuery) error {
|
||||
ret := _m.Called(ctx, query)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *models.GetDashboardsQuery) error); ok {
|
||||
r0 = rf(ctx, query)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// GetPublicDashboardConfig provides a mock function with given fields: ctx, orgId, dashboardUid
|
||||
func (_m *FakeDashboardService) GetPublicDashboardConfig(ctx context.Context, orgId int64, dashboardUid string) (*models.PublicDashboardConfig, error) {
|
||||
ret := _m.Called(ctx, orgId, dashboardUid)
|
||||
|
||||
var r0 *models.PublicDashboardConfig
|
||||
if rf, ok := ret.Get(0).(func(context.Context, int64, string) *models.PublicDashboardConfig); ok {
|
||||
r0 = rf(ctx, orgId, dashboardUid)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*models.PublicDashboardConfig)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, int64, string) error); ok {
|
||||
r1 = rf(ctx, orgId, dashboardUid)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// ImportDashboard provides a mock function with given fields: ctx, dto
|
||||
func (_m *FakeDashboardService) ImportDashboard(ctx context.Context, dto *SaveDashboardDTO) (*models.Dashboard, error) {
|
||||
ret := _m.Called(ctx, dto)
|
||||
|
||||
var r0 *models.Dashboard
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *SaveDashboardDTO) *models.Dashboard); ok {
|
||||
r0 = rf(ctx, dto)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*models.Dashboard)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *SaveDashboardDTO) error); ok {
|
||||
r1 = rf(ctx, dto)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// MakeUserAdmin provides a mock function with given fields: ctx, orgID, userID, dashboardID, setViewAndEditPermissions
|
||||
func (_m *FakeDashboardService) MakeUserAdmin(ctx context.Context, orgID int64, userID int64, dashboardID int64, setViewAndEditPermissions bool) error {
|
||||
ret := _m.Called(ctx, orgID, userID, dashboardID, setViewAndEditPermissions)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, int64, int64, int64, bool) error); ok {
|
||||
r0 = rf(ctx, orgID, userID, dashboardID, setViewAndEditPermissions)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// SaveDashboard provides a mock function with given fields: ctx, dto, allowUiUpdate
|
||||
func (_m *FakeDashboardService) SaveDashboard(ctx context.Context, dto *SaveDashboardDTO, allowUiUpdate bool) (*models.Dashboard, error) {
|
||||
ret := _m.Called(ctx, dto, allowUiUpdate)
|
||||
|
||||
var r0 *models.Dashboard
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *SaveDashboardDTO, bool) *models.Dashboard); ok {
|
||||
r0 = rf(ctx, dto, allowUiUpdate)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*models.Dashboard)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *SaveDashboardDTO, bool) error); ok {
|
||||
r1 = rf(ctx, dto, allowUiUpdate)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// SavePublicDashboardConfig provides a mock function with given fields: ctx, dto
|
||||
func (_m *FakeDashboardService) SavePublicDashboardConfig(ctx context.Context, dto *SavePublicDashboardConfigDTO) (*models.PublicDashboardConfig, error) {
|
||||
ret := _m.Called(ctx, dto)
|
||||
|
||||
var r0 *models.PublicDashboardConfig
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *SavePublicDashboardConfigDTO) *models.PublicDashboardConfig); ok {
|
||||
r0 = rf(ctx, dto)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*models.PublicDashboardConfig)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *SavePublicDashboardConfigDTO) error); ok {
|
||||
r1 = rf(ctx, dto)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// SearchDashboards provides a mock function with given fields: ctx, query
|
||||
func (_m *FakeDashboardService) SearchDashboards(ctx context.Context, query *models.FindPersistedDashboardsQuery) error {
|
||||
ret := _m.Called(ctx, query)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *models.FindPersistedDashboardsQuery) error); ok {
|
||||
r0 = rf(ctx, query)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// UpdateDashboardACL provides a mock function with given fields: ctx, uid, items
|
||||
func (_m *FakeDashboardService) UpdateDashboardACL(ctx context.Context, uid int64, items []*models.DashboardAcl) error {
|
||||
ret := _m.Called(ctx, uid, items)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, int64, []*models.DashboardAcl) error); ok {
|
||||
r0 = rf(ctx, uid, items)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// NewFakeDashboardService creates a new instance of FakeDashboardService. It also registers the testing.TB interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
func NewFakeDashboardService(t testing.TB) *FakeDashboardService {
|
||||
mock := &FakeDashboardService{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
||||
|
@ -15,19 +15,22 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/permissions"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/searchstore"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
)
|
||||
|
||||
type DashboardStore struct {
|
||||
sqlStore *sqlstore.SQLStore
|
||||
log log.Logger
|
||||
dialect migrator.Dialect
|
||||
}
|
||||
|
||||
// DashboardStore implements the Store interface
|
||||
var _ dashboards.Store = (*DashboardStore)(nil)
|
||||
|
||||
func ProvideDashboardStore(sqlStore *sqlstore.SQLStore) *DashboardStore {
|
||||
return &DashboardStore{sqlStore: sqlStore, log: log.New("dashboard-store")}
|
||||
return &DashboardStore{sqlStore: sqlStore, log: log.New("dashboard-store"), dialect: sqlStore.Dialect}
|
||||
}
|
||||
|
||||
func (d *DashboardStore) ValidateDashboardBeforeSave(dashboard *models.Dashboard, overwrite bool) (bool, error) {
|
||||
@ -926,3 +929,143 @@ func (d *DashboardStore) GetDashboards(ctx context.Context, query *models.GetDas
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
func (d *DashboardStore) SearchDashboards(ctx context.Context, query *models.FindPersistedDashboardsQuery) error {
|
||||
res, err := d.FindDashboards(ctx, query)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
makeQueryResult(query, res)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getHitType(item dashboards.DashboardSearchProjection) models.HitType {
|
||||
var hitType models.HitType
|
||||
if item.IsFolder {
|
||||
hitType = models.DashHitFolder
|
||||
} else {
|
||||
hitType = models.DashHitDB
|
||||
}
|
||||
|
||||
return hitType
|
||||
}
|
||||
|
||||
func makeQueryResult(query *models.FindPersistedDashboardsQuery, res []dashboards.DashboardSearchProjection) {
|
||||
query.Result = make([]*models.Hit, 0)
|
||||
hits := make(map[int64]*models.Hit)
|
||||
|
||||
for _, item := range res {
|
||||
hit, exists := hits[item.ID]
|
||||
if !exists {
|
||||
hit = &models.Hit{
|
||||
ID: item.ID,
|
||||
UID: item.UID,
|
||||
Title: item.Title,
|
||||
URI: "db/" + item.Slug,
|
||||
URL: models.GetDashboardFolderUrl(item.IsFolder, item.UID, item.Slug),
|
||||
Type: getHitType(item),
|
||||
FolderID: item.FolderID,
|
||||
FolderUID: item.FolderUID,
|
||||
FolderTitle: item.FolderTitle,
|
||||
Tags: []string{},
|
||||
}
|
||||
|
||||
if item.FolderID > 0 {
|
||||
hit.FolderURL = models.GetFolderUrl(item.FolderUID, item.FolderSlug)
|
||||
}
|
||||
|
||||
if query.Sort.MetaName != "" {
|
||||
hit.SortMeta = item.SortMeta
|
||||
hit.SortMetaName = query.Sort.MetaName
|
||||
}
|
||||
|
||||
query.Result = append(query.Result, hit)
|
||||
hits[item.ID] = hit
|
||||
}
|
||||
if len(item.Term) > 0 {
|
||||
hit.Tags = append(hit.Tags, item.Term)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DashboardStore) FindDashboards(ctx context.Context, query *models.FindPersistedDashboardsQuery) ([]dashboards.DashboardSearchProjection, error) {
|
||||
filters := []interface{}{
|
||||
permissions.DashboardPermissionFilter{
|
||||
OrgRole: query.SignedInUser.OrgRole,
|
||||
OrgId: query.SignedInUser.OrgId,
|
||||
Dialect: d.dialect,
|
||||
UserId: query.SignedInUser.UserId,
|
||||
PermissionLevel: query.Permission,
|
||||
},
|
||||
}
|
||||
|
||||
if !ac.IsDisabled(d.sqlStore.Cfg) {
|
||||
// if access control is enabled, overwrite the filters so far
|
||||
filters = []interface{}{
|
||||
permissions.NewAccessControlDashboardPermissionFilter(query.SignedInUser, query.Permission, query.Type),
|
||||
}
|
||||
}
|
||||
|
||||
for _, filter := range query.Sort.Filter {
|
||||
filters = append(filters, filter)
|
||||
}
|
||||
|
||||
filters = append(filters, query.Filters...)
|
||||
|
||||
if query.OrgId != 0 {
|
||||
filters = append(filters, searchstore.OrgFilter{OrgId: query.OrgId})
|
||||
} else if query.SignedInUser.OrgId != 0 {
|
||||
filters = append(filters, searchstore.OrgFilter{OrgId: query.SignedInUser.OrgId})
|
||||
}
|
||||
|
||||
if len(query.Tags) > 0 {
|
||||
filters = append(filters, searchstore.TagsFilter{Tags: query.Tags})
|
||||
}
|
||||
|
||||
if len(query.DashboardIds) > 0 {
|
||||
filters = append(filters, searchstore.DashboardFilter{IDs: query.DashboardIds})
|
||||
}
|
||||
|
||||
if query.IsStarred {
|
||||
filters = append(filters, searchstore.StarredFilter{UserId: query.SignedInUser.UserId})
|
||||
}
|
||||
|
||||
if len(query.Title) > 0 {
|
||||
filters = append(filters, searchstore.TitleFilter{Dialect: d.dialect, Title: query.Title})
|
||||
}
|
||||
|
||||
if len(query.Type) > 0 {
|
||||
filters = append(filters, searchstore.TypeFilter{Dialect: d.dialect, Type: query.Type})
|
||||
}
|
||||
|
||||
if len(query.FolderIds) > 0 {
|
||||
filters = append(filters, searchstore.FolderFilter{IDs: query.FolderIds})
|
||||
}
|
||||
|
||||
var res []dashboards.DashboardSearchProjection
|
||||
sb := &searchstore.Builder{Dialect: d.dialect, Filters: filters}
|
||||
|
||||
limit := query.Limit
|
||||
if limit < 1 {
|
||||
limit = 1000
|
||||
}
|
||||
|
||||
page := query.Page
|
||||
if page < 1 {
|
||||
page = 1
|
||||
}
|
||||
|
||||
sql, params := sb.ToSQL(limit, page)
|
||||
|
||||
err := d.sqlStore.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
||||
return sess.SQL(sql, params...).Find(&res)
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
@ -242,7 +242,7 @@ func TestDashboardDataAccess(t *testing.T) {
|
||||
SignedInUser: &models.SignedInUser{},
|
||||
}
|
||||
|
||||
err = sqlStore.SearchDashboards(context.Background(), &query)
|
||||
err = dashboardStore.SearchDashboards(context.Background(), &query)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, len(query.Result), 0)
|
||||
@ -315,7 +315,7 @@ func TestDashboardDataAccess(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
err := sqlStore.SearchDashboards(context.Background(), &query)
|
||||
err := dashboardStore.SearchDashboards(context.Background(), &query)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, len(query.Result), 1)
|
||||
@ -339,7 +339,7 @@ func TestDashboardDataAccess(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
err := sqlStore.SearchDashboards(context.Background(), &query)
|
||||
err := dashboardStore.SearchDashboards(context.Background(), &query)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, len(query.Result), 1)
|
||||
@ -364,7 +364,7 @@ func TestDashboardDataAccess(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
err := sqlStore.SearchDashboards(context.Background(), &query)
|
||||
err := dashboardStore.SearchDashboards(context.Background(), &query)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, len(query.Result), 1)
|
||||
@ -386,7 +386,7 @@ func TestDashboardDataAccess(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
err := sqlStore.SearchDashboards(context.Background(), &query)
|
||||
err := dashboardStore.SearchDashboards(context.Background(), &query)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, len(query.Result), 3)
|
||||
@ -407,7 +407,7 @@ func TestDashboardDataAccess(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
err := sqlStore.SearchDashboards(context.Background(), &query)
|
||||
err := dashboardStore.SearchDashboards(context.Background(), &query)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, len(query.Result), 2)
|
||||
@ -433,7 +433,7 @@ func TestDashboardDataAccess(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
err := sqlStore.SearchDashboards(context.Background(), &query)
|
||||
err := dashboardStore.SearchDashboards(context.Background(), &query)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, len(query.Result), 2)
|
||||
@ -471,7 +471,7 @@ func TestDashboardDataAccess(t *testing.T) {
|
||||
},
|
||||
IsStarred: true,
|
||||
}
|
||||
err = sqlStore.SearchDashboards(context.Background(), &query)
|
||||
err = dashboardStore.SearchDashboards(context.Background(), &query)
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, len(query.Result), 1)
|
||||
|
@ -20,3 +20,17 @@ type SavePublicDashboardConfigDTO struct {
|
||||
OrgId int64
|
||||
PublicDashboardConfig models.PublicDashboardConfig
|
||||
}
|
||||
|
||||
type DashboardSearchProjection struct {
|
||||
ID int64 `xorm:"id"`
|
||||
UID string `xorm:"uid"`
|
||||
Title string
|
||||
Slug string
|
||||
Term string
|
||||
IsFolder bool
|
||||
FolderID int64 `xorm:"folder_id"`
|
||||
FolderUID string `xorm:"folder_uid"`
|
||||
FolderSlug string
|
||||
FolderTitle string
|
||||
SortMeta int64
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/alerting"
|
||||
m "github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/guardian"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
@ -22,19 +22,19 @@ import (
|
||||
|
||||
var (
|
||||
provisionerPermissions = map[string][]string{
|
||||
m.ActionFoldersCreate: {},
|
||||
m.ActionFoldersWrite: {m.ScopeFoldersAll},
|
||||
m.ActionDashboardsCreate: {m.ScopeFoldersAll},
|
||||
m.ActionDashboardsWrite: {m.ScopeFoldersAll},
|
||||
dashboards.ActionFoldersCreate: {},
|
||||
dashboards.ActionFoldersWrite: {dashboards.ScopeFoldersAll},
|
||||
dashboards.ActionDashboardsCreate: {dashboards.ScopeFoldersAll},
|
||||
dashboards.ActionDashboardsWrite: {dashboards.ScopeFoldersAll},
|
||||
}
|
||||
// DashboardServiceImpl implements the DashboardService interface
|
||||
_ m.DashboardService = (*DashboardServiceImpl)(nil)
|
||||
_ dashboards.DashboardService = (*DashboardServiceImpl)(nil)
|
||||
)
|
||||
|
||||
type DashboardServiceImpl struct {
|
||||
cfg *setting.Cfg
|
||||
log log.Logger
|
||||
dashboardStore m.Store
|
||||
dashboardStore dashboards.Store
|
||||
dashAlertExtractor alerting.DashAlertExtractor
|
||||
features featuremgmt.FeatureToggles
|
||||
folderPermissions accesscontrol.FolderPermissionsService
|
||||
@ -42,7 +42,7 @@ type DashboardServiceImpl struct {
|
||||
}
|
||||
|
||||
func ProvideDashboardService(
|
||||
cfg *setting.Cfg, store m.Store, dashAlertExtractor alerting.DashAlertExtractor,
|
||||
cfg *setting.Cfg, store dashboards.Store, dashAlertExtractor alerting.DashAlertExtractor,
|
||||
features featuremgmt.FeatureToggles, folderPermissionsService accesscontrol.FolderPermissionsService,
|
||||
dashboardPermissionsService accesscontrol.DashboardPermissionsService,
|
||||
) *DashboardServiceImpl {
|
||||
@ -69,7 +69,7 @@ func (dr *DashboardServiceImpl) GetProvisionedDashboardDataByDashboardUID(orgID
|
||||
return dr.dashboardStore.GetProvisionedDataByDashboardUID(orgID, dashboardUID)
|
||||
}
|
||||
|
||||
func (dr *DashboardServiceImpl) BuildSaveDashboardCommand(ctx context.Context, dto *m.SaveDashboardDTO, shouldValidateAlerts bool,
|
||||
func (dr *DashboardServiceImpl) BuildSaveDashboardCommand(ctx context.Context, dto *dashboards.SaveDashboardDTO, shouldValidateAlerts bool,
|
||||
validateProvisionedDashboard bool) (*models.SaveDashboardCommand, error) {
|
||||
dash := dto.Dashboard
|
||||
|
||||
@ -204,7 +204,7 @@ func validateDashboardRefreshInterval(dash *models.Dashboard) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dr *DashboardServiceImpl) SaveProvisionedDashboard(ctx context.Context, dto *m.SaveDashboardDTO,
|
||||
func (dr *DashboardServiceImpl) SaveProvisionedDashboard(ctx context.Context, dto *dashboards.SaveDashboardDTO,
|
||||
provisioning *models.DashboardProvisioning) (*models.Dashboard, error) {
|
||||
if err := validateDashboardRefreshInterval(dto.Dashboard); err != nil {
|
||||
dr.log.Warn("Changing refresh interval for provisioned dashboard to minimum refresh interval", "dashboardUid",
|
||||
@ -258,7 +258,7 @@ func (dr *DashboardServiceImpl) SaveProvisionedDashboard(ctx context.Context, dt
|
||||
return dash, nil
|
||||
}
|
||||
|
||||
func (dr *DashboardServiceImpl) SaveFolderForProvisionedDashboards(ctx context.Context, dto *m.SaveDashboardDTO) (*models.Dashboard, error) {
|
||||
func (dr *DashboardServiceImpl) SaveFolderForProvisionedDashboards(ctx context.Context, dto *dashboards.SaveDashboardDTO) (*models.Dashboard, error) {
|
||||
dto.User = &models.SignedInUser{
|
||||
UserId: 0,
|
||||
OrgRole: models.ROLE_ADMIN,
|
||||
@ -299,7 +299,7 @@ func (dr *DashboardServiceImpl) SaveFolderForProvisionedDashboards(ctx context.C
|
||||
return dash, nil
|
||||
}
|
||||
|
||||
func (dr *DashboardServiceImpl) SaveDashboard(ctx context.Context, dto *m.SaveDashboardDTO,
|
||||
func (dr *DashboardServiceImpl) SaveDashboard(ctx context.Context, dto *dashboards.SaveDashboardDTO,
|
||||
allowUiUpdate bool) (*models.Dashboard, error) {
|
||||
if err := validateDashboardRefreshInterval(dto.Dashboard); err != nil {
|
||||
dr.log.Warn("Changing refresh interval for imported dashboard to minimum refresh interval",
|
||||
@ -356,7 +356,7 @@ func (dr *DashboardServiceImpl) GetPublicDashboardConfig(ctx context.Context, or
|
||||
|
||||
// SavePublicDashboardConfig is a helper method to persist the sharing config
|
||||
// to the database. It handles validations for sharing config and persistence
|
||||
func (dr *DashboardServiceImpl) SavePublicDashboardConfig(ctx context.Context, dto *m.SavePublicDashboardConfigDTO) (*models.PublicDashboardConfig, error) {
|
||||
func (dr *DashboardServiceImpl) SavePublicDashboardConfig(ctx context.Context, dto *dashboards.SavePublicDashboardConfigDTO) (*models.PublicDashboardConfig, error) {
|
||||
cmd := models.SavePublicDashboardConfigCommand{
|
||||
Uid: dto.Uid,
|
||||
OrgId: dto.OrgId,
|
||||
@ -440,7 +440,7 @@ func (dr *DashboardServiceImpl) deleteDashboard(ctx context.Context, dashboardId
|
||||
return dr.dashboardStore.DeleteDashboard(ctx, cmd)
|
||||
}
|
||||
|
||||
func (dr *DashboardServiceImpl) ImportDashboard(ctx context.Context, dto *m.SaveDashboardDTO) (
|
||||
func (dr *DashboardServiceImpl) ImportDashboard(ctx context.Context, dto *dashboards.SaveDashboardDTO) (
|
||||
*models.Dashboard, error) {
|
||||
if err := validateDashboardRefreshInterval(dto.Dashboard); err != nil {
|
||||
dr.log.Warn("Changing refresh interval for imported dashboard to minimum refresh interval",
|
||||
@ -476,7 +476,7 @@ func (dr *DashboardServiceImpl) GetDashboardsByPluginID(ctx context.Context, que
|
||||
return dr.dashboardStore.GetDashboardsByPluginID(ctx, query)
|
||||
}
|
||||
|
||||
func (dr *DashboardServiceImpl) setDefaultPermissions(ctx context.Context, dto *m.SaveDashboardDTO, dash *models.Dashboard, provisioned bool) error {
|
||||
func (dr *DashboardServiceImpl) setDefaultPermissions(ctx context.Context, dto *dashboards.SaveDashboardDTO, dash *models.Dashboard, provisioned bool) error {
|
||||
inFolder := dash.FolderId > 0
|
||||
if !accesscontrol.IsDisabled(dr.cfg) {
|
||||
var permissions []accesscontrol.SetResourcePermissionCommand
|
||||
@ -522,3 +522,11 @@ func (dr *DashboardServiceImpl) GetDashboardUIDById(ctx context.Context, query *
|
||||
func (dr *DashboardServiceImpl) GetDashboards(ctx context.Context, query *models.GetDashboardsQuery) error {
|
||||
return dr.dashboardStore.GetDashboards(ctx, query)
|
||||
}
|
||||
|
||||
func (dr *DashboardServiceImpl) FindDashboards(ctx context.Context, query *models.FindPersistedDashboardsQuery) ([]dashboards.DashboardSearchProjection, error) {
|
||||
return dr.dashboardStore.FindDashboards(ctx, query)
|
||||
}
|
||||
|
||||
func (dr *DashboardServiceImpl) SearchDashboards(ctx context.Context, query *models.FindPersistedDashboardsQuery) error {
|
||||
return dr.dashboardStore.SearchDashboards(ctx, query)
|
||||
}
|
||||
|
@ -37,8 +37,7 @@ func TestProvideFolderService(t *testing.T) {
|
||||
ac := acmock.New()
|
||||
|
||||
ProvideFolderService(
|
||||
cfg, &dashboards.FakeDashboardService{DashboardService: dashboardService},
|
||||
store, nil, features, folderPermissions, ac,
|
||||
cfg, dashboardService, store, nil, features, folderPermissions, ac,
|
||||
)
|
||||
|
||||
require.Len(t, ac.Calls.RegisterAttributeScopeResolver, 2)
|
||||
|
@ -44,6 +44,29 @@ func (_m *FakeDashboardStore) DeleteOrphanedProvisionedDashboards(ctx context.Co
|
||||
return r0
|
||||
}
|
||||
|
||||
// FindDashboards provides a mock function with given fields: ctx, query
|
||||
func (_m *FakeDashboardStore) FindDashboards(ctx context.Context, query *models.FindPersistedDashboardsQuery) ([]DashboardSearchProjection, error) {
|
||||
ret := _m.Called(ctx, query)
|
||||
|
||||
var r0 []DashboardSearchProjection
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *models.FindPersistedDashboardsQuery) []DashboardSearchProjection); ok {
|
||||
r0 = rf(ctx, query)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]DashboardSearchProjection)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *models.FindPersistedDashboardsQuery) error); ok {
|
||||
r1 = rf(ctx, query)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetDashboard provides a mock function with given fields: ctx, query
|
||||
func (_m *FakeDashboardStore) GetDashboard(ctx context.Context, query *models.GetDashboardQuery) error {
|
||||
ret := _m.Called(ctx, query)
|
||||
@ -344,6 +367,20 @@ func (_m *FakeDashboardStore) SavePublicDashboardConfig(cmd models.SavePublicDas
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// SearchDashboards provides a mock function with given fields: ctx, query
|
||||
func (_m *FakeDashboardStore) SearchDashboards(ctx context.Context, query *models.FindPersistedDashboardsQuery) error {
|
||||
ret := _m.Called(ctx, query)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *models.FindPersistedDashboardsQuery) error); ok {
|
||||
r0 = rf(ctx, query)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// UnprovisionDashboard provides a mock function with given fields: ctx, id
|
||||
func (_m *FakeDashboardStore) UnprovisionDashboard(ctx context.Context, id int64) error {
|
||||
ret := _m.Called(ctx, id)
|
||||
|
@ -101,8 +101,7 @@ func TestAccessControlDashboardGuardian_CanSave(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.desc, func(t *testing.T) {
|
||||
guardian, _ := setupAccessControlGuardianTest(t, tt.dashUID, tt.permissions)
|
||||
|
||||
guardian, _ := setupAccessControlGuardianTest(t, tt.dashUID, tt.permissions, testDashSvc(t))
|
||||
can, err := guardian.CanSave()
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, tt.expected, can)
|
||||
@ -193,7 +192,7 @@ func TestAccessControlDashboardGuardian_CanEdit(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.desc, func(t *testing.T) {
|
||||
guardian, _ := setupAccessControlGuardianTest(t, tt.dashUID, tt.permissions)
|
||||
guardian, _ := setupAccessControlGuardianTest(t, tt.dashUID, tt.permissions, testDashSvc(t))
|
||||
|
||||
if tt.viewersCanEdit {
|
||||
setting.ViewersCanEdit = true
|
||||
@ -277,7 +276,7 @@ func TestAccessControlDashboardGuardian_CanView(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.desc, func(t *testing.T) {
|
||||
guardian, _ := setupAccessControlGuardianTest(t, tt.dashUID, tt.permissions)
|
||||
guardian, _ := setupAccessControlGuardianTest(t, tt.dashUID, tt.permissions, testDashSvc(t))
|
||||
|
||||
can, err := guardian.CanView()
|
||||
require.NoError(t, err)
|
||||
@ -381,7 +380,7 @@ func TestAccessControlDashboardGuardian_CanAdmin(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.desc, func(t *testing.T) {
|
||||
guardian, _ := setupAccessControlGuardianTest(t, tt.dashUID, tt.permissions)
|
||||
guardian, _ := setupAccessControlGuardianTest(t, tt.dashUID, tt.permissions, testDashSvc(t))
|
||||
|
||||
can, err := guardian.CanAdmin()
|
||||
require.NoError(t, err)
|
||||
@ -461,7 +460,7 @@ func TestAccessControlDashboardGuardian_CanDelete(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.desc, func(t *testing.T) {
|
||||
guardian, _ := setupAccessControlGuardianTest(t, tt.dashUID, tt.permissions)
|
||||
guardian, _ := setupAccessControlGuardianTest(t, tt.dashUID, tt.permissions, testDashSvc(t))
|
||||
|
||||
can, err := guardian.CanDelete()
|
||||
require.NoError(t, err)
|
||||
@ -525,7 +524,7 @@ func TestAccessControlDashboardGuardian_CanCreate(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.desc, func(t *testing.T) {
|
||||
guardian, _ := setupAccessControlGuardianTest(t, "0", tt.permissions)
|
||||
guardian, _ := setupAccessControlGuardianTest(t, "0", tt.permissions, nil)
|
||||
|
||||
can, err := guardian.CanCreate(tt.folderID, tt.isFolder)
|
||||
require.NoError(t, err)
|
||||
@ -557,7 +556,7 @@ func TestAccessControlDashboardGuardian_GetHiddenACL(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.desc, func(t *testing.T) {
|
||||
guardian, _ := setupAccessControlGuardianTest(t, "1", nil)
|
||||
guardian, _ := setupAccessControlGuardianTest(t, "1", nil, testDashSvc(t))
|
||||
|
||||
mocked := accesscontrolmock.NewMockedPermissionsService()
|
||||
guardian.dashboardPermissionsService = mocked
|
||||
@ -579,7 +578,7 @@ func TestAccessControlDashboardGuardian_GetHiddenACL(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func setupAccessControlGuardianTest(t *testing.T, uid string, permissions []*accesscontrol.Permission) (*AccessControlDashboardGuardian, *models.Dashboard) {
|
||||
func setupAccessControlGuardianTest(t *testing.T, uid string, permissions []*accesscontrol.Permission, dashboardSvc dashboards.DashboardService) (*AccessControlDashboardGuardian, *models.Dashboard) {
|
||||
t.Helper()
|
||||
store := sqlstore.InitTestDB(t)
|
||||
|
||||
@ -601,6 +600,20 @@ func setupAccessControlGuardianTest(t *testing.T, uid string, permissions []*acc
|
||||
dashboardPermissions, err := ossaccesscontrol.ProvideDashboardPermissions(
|
||||
setting.NewCfg(), routing.NewRouteRegister(), store, ac, database.ProvideService(store), &dashboards.FakeDashboardStore{})
|
||||
require.NoError(t, err)
|
||||
|
||||
return NewAccessControlDashboardGuardian(context.Background(), dash.Id, &models.SignedInUser{OrgId: 1}, store, ac, folderPermissions, dashboardPermissions, &dashboards.FakeDashboardService{}), dash
|
||||
if dashboardSvc == nil {
|
||||
dashboardSvc = &dashboards.FakeDashboardService{}
|
||||
}
|
||||
return NewAccessControlDashboardGuardian(context.Background(), dash.Id, &models.SignedInUser{OrgId: 1}, store, ac, folderPermissions, dashboardPermissions, dashboardSvc), dash
|
||||
}
|
||||
|
||||
func testDashSvc(t *testing.T) dashboards.DashboardService {
|
||||
dashSvc := dashboards.NewFakeDashboardService(t)
|
||||
dashSvc.On("GetDashboard", mock.Anything, mock.AnythingOfType("*models.GetDashboardQuery")).Run(func(args mock.Arguments) {
|
||||
q := args.Get(1).(*models.GetDashboardQuery)
|
||||
d := models.NewDashboard("mocked")
|
||||
d.Id = 1
|
||||
d.Uid = "1"
|
||||
q.Result = d
|
||||
}).Return(nil)
|
||||
return dashSvc
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/imguploader"
|
||||
@ -78,19 +79,17 @@ func TestBrowserScreenshotService(t *testing.T) {
|
||||
s := NewBrowserScreenshotService(&d, r)
|
||||
|
||||
// a non-existent dashboard should return error
|
||||
d.GetDashboardFn = func(ctx context.Context, cmd *models.GetDashboardQuery) error {
|
||||
return models.ErrDashboardNotFound
|
||||
}
|
||||
d.On("GetDashboard", mock.Anything, mock.AnythingOfType("*models.GetDashboardQuery")).Return(models.ErrDashboardNotFound).Once()
|
||||
ctx := context.Background()
|
||||
opts := ScreenshotOptions{}
|
||||
screenshot, err := s.Take(ctx, opts)
|
||||
assert.EqualError(t, err, "Dashboard not found")
|
||||
assert.Nil(t, screenshot)
|
||||
|
||||
d.GetDashboardFn = func(ctx context.Context, cmd *models.GetDashboardQuery) error {
|
||||
cmd.Result = &models.Dashboard{Id: 1, Uid: "foo", Slug: "bar", OrgId: 2}
|
||||
return nil
|
||||
}
|
||||
d.On("GetDashboard", mock.Anything, mock.AnythingOfType("*models.GetDashboardQuery")).Run(func(args mock.Arguments) {
|
||||
q := args.Get(1).(*models.GetDashboardQuery)
|
||||
q.Result = &models.Dashboard{Id: 1, Uid: "foo", Slug: "bar", OrgId: 2}
|
||||
}).Return(nil)
|
||||
|
||||
renderOpts := rendering.Opts{
|
||||
AuthOpts: rendering.AuthOpts{
|
||||
|
Loading…
Reference in New Issue
Block a user