mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Remove bus from dashboard api (#44923)
* Remove bus from dashboard api * Polish api dashboard tests * Remove Delete Slug method * Fix sqlstore dashboard test * Remove bus from dashboard permission * Remove GetDashboardsBySlug from sqlstore
This commit is contained in:
@@ -341,11 +341,11 @@ func (hs *HTTPServer) registerRoutes() {
|
||||
|
||||
dashboardRoute.Post("/db", routing.Wrap(hs.PostDashboard))
|
||||
dashboardRoute.Get("/home", routing.Wrap(hs.GetHomeDashboard))
|
||||
dashboardRoute.Get("/tags", GetDashboardTags)
|
||||
dashboardRoute.Get("/tags", hs.GetDashboardTags)
|
||||
|
||||
dashboardRoute.Group("/id/:dashboardId", func(dashIdRoute routing.RouteRegister) {
|
||||
dashIdRoute.Get("/versions", routing.Wrap(GetDashboardVersions))
|
||||
dashIdRoute.Get("/versions/:id", routing.Wrap(GetDashboardVersion))
|
||||
dashIdRoute.Get("/versions", routing.Wrap(hs.GetDashboardVersions))
|
||||
dashIdRoute.Get("/versions/:id", routing.Wrap(hs.GetDashboardVersion))
|
||||
dashIdRoute.Post("/restore", routing.Wrap(hs.RestoreDashboardVersion))
|
||||
|
||||
dashIdRoute.Group("/permissions", func(dashboardPermissionRoute routing.RouteRegister) {
|
||||
|
||||
@@ -13,7 +13,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/api/apierrors"
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
"github.com/grafana/grafana/pkg/api/response"
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/components/dashdiffs"
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||
@@ -29,13 +28,13 @@ const (
|
||||
anonString = "Anonymous"
|
||||
)
|
||||
|
||||
func isDashboardStarredByUser(c *models.ReqContext, dashID int64) (bool, error) {
|
||||
func (hs *HTTPServer) isDashboardStarredByUser(c *models.ReqContext, dashID int64) (bool, error) {
|
||||
if !c.IsSignedIn {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
query := models.IsStarredByUserQuery{UserId: c.UserId, DashboardId: dashID}
|
||||
if err := bus.Dispatch(c.Req.Context(), &query); err != nil {
|
||||
if err := hs.SQLStore.IsStarredByUserCtx(c.Req.Context(), &query); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
@@ -46,7 +45,6 @@ func dashboardGuardianResponse(err error) response.Response {
|
||||
if err != nil {
|
||||
return response.Error(500, "Error while checking dashboard permissions", err)
|
||||
}
|
||||
|
||||
return response.Error(403, "Access denied to this dashboard", nil)
|
||||
}
|
||||
|
||||
@@ -78,11 +76,10 @@ func (hs *HTTPServer) TrimDashboard(c *models.ReqContext) response.Response {
|
||||
|
||||
func (hs *HTTPServer) GetDashboard(c *models.ReqContext) response.Response {
|
||||
uid := web.Params(c.Req)[":uid"]
|
||||
dash, rsp := getDashboardHelper(c.Req.Context(), c.OrgId, 0, uid)
|
||||
dash, rsp := hs.getDashboardHelper(c.Req.Context(), c.OrgId, 0, uid)
|
||||
if rsp != nil {
|
||||
return rsp
|
||||
}
|
||||
|
||||
// When dash contains only keys id, uid that means dashboard data is not valid and json decode failed.
|
||||
if dash.Data != nil {
|
||||
isEmptyData := true
|
||||
@@ -96,28 +93,25 @@ func (hs *HTTPServer) GetDashboard(c *models.ReqContext) response.Response {
|
||||
return response.Error(500, "Error while loading dashboard, dashboard data is invalid", nil)
|
||||
}
|
||||
}
|
||||
|
||||
guardian := guardian.New(c.Req.Context(), dash.Id, c.OrgId, c.SignedInUser)
|
||||
if canView, err := guardian.CanView(); err != nil || !canView {
|
||||
return dashboardGuardianResponse(err)
|
||||
}
|
||||
|
||||
canEdit, _ := guardian.CanEdit()
|
||||
canSave, _ := guardian.CanSave()
|
||||
canAdmin, _ := guardian.CanAdmin()
|
||||
|
||||
isStarred, err := isDashboardStarredByUser(c, dash.Id)
|
||||
isStarred, err := hs.isDashboardStarredByUser(c, dash.Id)
|
||||
if err != nil {
|
||||
return response.Error(500, "Error while checking if dashboard was starred by user", err)
|
||||
}
|
||||
|
||||
// Finding creator and last updater of the dashboard
|
||||
updater, creator := anonString, anonString
|
||||
if dash.UpdatedBy > 0 {
|
||||
updater = getUserLogin(c.Req.Context(), dash.UpdatedBy)
|
||||
updater = hs.getUserLogin(c.Req.Context(), dash.UpdatedBy)
|
||||
}
|
||||
if dash.CreatedBy > 0 {
|
||||
creator = getUserLogin(c.Req.Context(), dash.CreatedBy)
|
||||
creator = hs.getUserLogin(c.Req.Context(), dash.CreatedBy)
|
||||
}
|
||||
|
||||
meta := dtos.DashboardMeta{
|
||||
@@ -143,7 +137,7 @@ func (hs *HTTPServer) GetDashboard(c *models.ReqContext) response.Response {
|
||||
// lookup folder title
|
||||
if dash.FolderId > 0 {
|
||||
query := models.GetDashboardQuery{Id: dash.FolderId, OrgId: c.OrgId}
|
||||
if err := bus.Dispatch(c.Req.Context(), &query); err != nil {
|
||||
if err := hs.SQLStore.GetDashboard(c.Req.Context(), &query); err != nil {
|
||||
if errors.Is(err, models.ErrFolderNotFound) {
|
||||
return response.Error(404, "Folder not found", err)
|
||||
}
|
||||
@@ -195,16 +189,16 @@ func (hs *HTTPServer) GetDashboard(c *models.ReqContext) response.Response {
|
||||
return response.JSON(200, dto)
|
||||
}
|
||||
|
||||
func getUserLogin(ctx context.Context, userID int64) string {
|
||||
func (hs *HTTPServer) getUserLogin(ctx context.Context, userID int64) string {
|
||||
query := models.GetUserByIdQuery{Id: userID}
|
||||
err := bus.Dispatch(ctx, &query)
|
||||
err := hs.SQLStore.GetUserById(ctx, &query)
|
||||
if err != nil {
|
||||
return anonString
|
||||
}
|
||||
return query.Result.Login
|
||||
}
|
||||
|
||||
func getDashboardHelper(ctx context.Context, orgID int64, id int64, uid string) (*models.Dashboard, response.Response) {
|
||||
func (hs *HTTPServer) getDashboardHelper(ctx context.Context, orgID int64, id int64, uid string) (*models.Dashboard, response.Response) {
|
||||
var query models.GetDashboardQuery
|
||||
|
||||
if len(uid) > 0 {
|
||||
@@ -213,37 +207,22 @@ func getDashboardHelper(ctx context.Context, orgID int64, id int64, uid string)
|
||||
query = models.GetDashboardQuery{Id: id, OrgId: orgID}
|
||||
}
|
||||
|
||||
if err := bus.Dispatch(ctx, &query); err != nil {
|
||||
if err := hs.SQLStore.GetDashboard(ctx, &query); err != nil {
|
||||
return nil, response.Error(404, "Dashboard not found", err)
|
||||
}
|
||||
|
||||
return query.Result, nil
|
||||
}
|
||||
|
||||
func (hs *HTTPServer) DeleteDashboardBySlug(c *models.ReqContext) response.Response {
|
||||
query := models.GetDashboardsBySlugQuery{OrgId: c.OrgId, Slug: web.Params(c.Req)[":slug"]}
|
||||
|
||||
if err := bus.Dispatch(c.Req.Context(), &query); err != nil {
|
||||
return response.Error(500, "Failed to retrieve dashboards by slug", err)
|
||||
}
|
||||
|
||||
if len(query.Result) > 1 {
|
||||
return response.JSON(412, util.DynMap{"status": "multiple-slugs-exists", "message": models.ErrDashboardsWithSameSlugExists.Error()})
|
||||
}
|
||||
|
||||
return hs.deleteDashboard(c)
|
||||
}
|
||||
|
||||
func (hs *HTTPServer) DeleteDashboardByUID(c *models.ReqContext) response.Response {
|
||||
return hs.deleteDashboard(c)
|
||||
}
|
||||
|
||||
func (hs *HTTPServer) deleteDashboard(c *models.ReqContext) response.Response {
|
||||
dash, rsp := getDashboardHelper(c.Req.Context(), c.OrgId, 0, web.Params(c.Req)[":uid"])
|
||||
dash, rsp := hs.getDashboardHelper(c.Req.Context(), c.OrgId, 0, web.Params(c.Req)[":uid"])
|
||||
if rsp != nil {
|
||||
return rsp
|
||||
}
|
||||
|
||||
guardian := guardian.New(c.Req.Context(), dash.Id, c.OrgId, c.SignedInUser)
|
||||
if canSave, err := guardian.CanSave(); err != nil || !canSave {
|
||||
return dashboardGuardianResponse(err)
|
||||
@@ -254,7 +233,6 @@ func (hs *HTTPServer) deleteDashboard(c *models.ReqContext) response.Response {
|
||||
if err != nil {
|
||||
hs.log.Error("Failed to disconnect library elements", "dashboard", dash.Id, "user", c.SignedInUser.UserId, "error", err)
|
||||
}
|
||||
|
||||
svc := dashboards.NewService(hs.SQLStore)
|
||||
err = svc.DeleteDashboard(c.Req.Context(), dash.Id, c.OrgId)
|
||||
if err != nil {
|
||||
@@ -264,17 +242,14 @@ func (hs *HTTPServer) deleteDashboard(c *models.ReqContext) response.Response {
|
||||
return response.Error(dashboardErr.StatusCode, dashboardErr.Error(), err)
|
||||
}
|
||||
}
|
||||
|
||||
return response.Error(500, "Failed to delete dashboard", err)
|
||||
}
|
||||
|
||||
if hs.Live != nil {
|
||||
err := hs.Live.GrafanaScope.Dashboards.DashboardDeleted(c.OrgId, c.ToUserDisplayDTO(), dash.Uid)
|
||||
if err != nil {
|
||||
hs.log.Error("Failed to broadcast delete info", "dashboard", dash.Uid, "error", err)
|
||||
}
|
||||
}
|
||||
|
||||
return response.JSON(200, util.DynMap{
|
||||
"title": dash.Title,
|
||||
"message": fmt.Sprintf("Dashboard %s deleted", dash.Title),
|
||||
@@ -415,7 +390,7 @@ func (hs *HTTPServer) GetHomeDashboard(c *models.ReqContext) response.Response {
|
||||
prefsQuery := models.GetPreferencesWithDefaultsQuery{User: c.SignedInUser}
|
||||
homePage := hs.Cfg.HomePage
|
||||
|
||||
if err := hs.Bus.Dispatch(c.Req.Context(), &prefsQuery); err != nil {
|
||||
if err := hs.SQLStore.GetPreferencesWithDefaults(c.Req.Context(), &prefsQuery); err != nil {
|
||||
return response.Error(500, "Failed to get preferences", err)
|
||||
}
|
||||
|
||||
@@ -426,7 +401,7 @@ func (hs *HTTPServer) GetHomeDashboard(c *models.ReqContext) response.Response {
|
||||
|
||||
if prefsQuery.Result.HomeDashboardId != 0 {
|
||||
slugQuery := models.GetDashboardRefByIdQuery{Id: prefsQuery.Result.HomeDashboardId}
|
||||
err := hs.Bus.Dispatch(c.Req.Context(), &slugQuery)
|
||||
err := hs.SQLStore.GetDashboardUIDById(c.Req.Context(), &slugQuery)
|
||||
if err == nil {
|
||||
url := models.GetDashboardUrl(slugQuery.Result.Uid, slugQuery.Result.Slug)
|
||||
dashRedirect := dtos.DashboardRedirect{RedirectUri: url}
|
||||
@@ -495,7 +470,7 @@ func (hs *HTTPServer) addGettingStartedPanelToHomeDashboard(c *models.ReqContext
|
||||
}
|
||||
|
||||
// GetDashboardVersions returns all dashboard versions as JSON
|
||||
func GetDashboardVersions(c *models.ReqContext) response.Response {
|
||||
func (hs *HTTPServer) GetDashboardVersions(c *models.ReqContext) response.Response {
|
||||
dashID, err := strconv.ParseInt(web.Params(c.Req)[":dashboardId"], 10, 64)
|
||||
if err != nil {
|
||||
return response.Error(http.StatusBadRequest, "dashboardId is invalid", err)
|
||||
@@ -513,7 +488,7 @@ func GetDashboardVersions(c *models.ReqContext) response.Response {
|
||||
Start: c.QueryInt("start"),
|
||||
}
|
||||
|
||||
if err := bus.Dispatch(c.Req.Context(), &query); err != nil {
|
||||
if err := hs.SQLStore.GetDashboardVersions(c.Req.Context(), &query); err != nil {
|
||||
return response.Error(404, fmt.Sprintf("No versions found for dashboardId %d", dashID), err)
|
||||
}
|
||||
|
||||
@@ -537,7 +512,7 @@ func GetDashboardVersions(c *models.ReqContext) response.Response {
|
||||
}
|
||||
|
||||
// GetDashboardVersion returns the dashboard version with the given ID.
|
||||
func GetDashboardVersion(c *models.ReqContext) response.Response {
|
||||
func (hs *HTTPServer) GetDashboardVersion(c *models.ReqContext) response.Response {
|
||||
dashID, err := strconv.ParseInt(web.Params(c.Req)[":dashboardId"], 10, 64)
|
||||
if err != nil {
|
||||
return response.Error(http.StatusBadRequest, "dashboardId is invalid", err)
|
||||
@@ -555,13 +530,13 @@ func GetDashboardVersion(c *models.ReqContext) response.Response {
|
||||
Version: int(version),
|
||||
}
|
||||
|
||||
if err := bus.Dispatch(c.Req.Context(), &query); err != nil {
|
||||
if err := hs.SQLStore.GetDashboardVersion(c.Req.Context(), &query); err != nil {
|
||||
return response.Error(500, fmt.Sprintf("Dashboard version %d not found for dashboardId %d", query.Version, dashID), err)
|
||||
}
|
||||
|
||||
creator := anonString
|
||||
if query.Result.CreatedBy > 0 {
|
||||
creator = getUserLogin(c.Req.Context(), query.Result.CreatedBy)
|
||||
creator = hs.getUserLogin(c.Req.Context(), query.Result.CreatedBy)
|
||||
}
|
||||
|
||||
dashVersionMeta := &models.DashboardVersionMeta{
|
||||
@@ -638,7 +613,7 @@ func (hs *HTTPServer) RestoreDashboardVersion(c *models.ReqContext) response.Res
|
||||
return response.Error(http.StatusBadRequest, "dashboardId is invalid", err)
|
||||
}
|
||||
|
||||
dash, rsp := getDashboardHelper(c.Req.Context(), c.OrgId, dashboardId, "")
|
||||
dash, rsp := hs.getDashboardHelper(c.Req.Context(), c.OrgId, dashboardId, "")
|
||||
if rsp != nil {
|
||||
return rsp
|
||||
}
|
||||
@@ -649,7 +624,7 @@ func (hs *HTTPServer) RestoreDashboardVersion(c *models.ReqContext) response.Res
|
||||
}
|
||||
|
||||
versionQuery := models.GetDashboardVersionQuery{DashboardId: dash.Id, Version: apiCmd.Version, OrgId: c.OrgId}
|
||||
if err := bus.Dispatch(c.Req.Context(), &versionQuery); err != nil {
|
||||
if err := hs.SQLStore.GetDashboardVersion(c.Req.Context(), &versionQuery); err != nil {
|
||||
return response.Error(404, "Dashboard version not found", nil)
|
||||
}
|
||||
|
||||
@@ -668,9 +643,9 @@ func (hs *HTTPServer) RestoreDashboardVersion(c *models.ReqContext) response.Res
|
||||
return hs.postDashboard(c, saveCmd)
|
||||
}
|
||||
|
||||
func GetDashboardTags(c *models.ReqContext) {
|
||||
func (hs *HTTPServer) GetDashboardTags(c *models.ReqContext) {
|
||||
query := models.GetDashboardTagsQuery{OrgId: c.OrgId}
|
||||
err := bus.Dispatch(c.Req.Context(), &query)
|
||||
err := hs.SQLStore.GetDashboardTags(c.Req.Context(), &query)
|
||||
if err != nil {
|
||||
c.JsonApiErr(500, "Failed to get tags from database", err)
|
||||
return
|
||||
|
||||
@@ -19,7 +19,7 @@ func (hs *HTTPServer) GetDashboardPermissionList(c *models.ReqContext) response.
|
||||
return response.Error(http.StatusBadRequest, "dashboardId is invalid", err)
|
||||
}
|
||||
|
||||
_, rsp := getDashboardHelper(c.Req.Context(), c.OrgId, dashID, "")
|
||||
_, rsp := hs.getDashboardHelper(c.Req.Context(), c.OrgId, dashID, "")
|
||||
if rsp != nil {
|
||||
return rsp
|
||||
}
|
||||
@@ -70,7 +70,7 @@ func (hs *HTTPServer) UpdateDashboardPermissions(c *models.ReqContext) response.
|
||||
return response.Error(http.StatusBadRequest, "dashboardId is invalid", err)
|
||||
}
|
||||
|
||||
_, rsp := getDashboardHelper(c.Req.Context(), c.OrgId, dashID, "")
|
||||
_, rsp := hs.getDashboardHelper(c.Req.Context(), c.OrgId, dashID, "")
|
||||
if rsp != nil {
|
||||
return rsp
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
"github.com/grafana/grafana/pkg/api/response"
|
||||
"github.com/grafana/grafana/pkg/api/routing"
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/dashboards"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/guardian"
|
||||
@@ -23,21 +22,19 @@ import (
|
||||
func TestDashboardPermissionAPIEndpoint(t *testing.T) {
|
||||
t.Run("Dashboard permissions test", func(t *testing.T) {
|
||||
settings := setting.NewCfg()
|
||||
hs := &HTTPServer{Cfg: settings}
|
||||
mockSQLStore := mockstore.NewSQLStoreMock()
|
||||
hs := &HTTPServer{
|
||||
Cfg: settings,
|
||||
SQLStore: mockSQLStore,
|
||||
}
|
||||
|
||||
t.Run("Given dashboard not exists", func(t *testing.T) {
|
||||
setUp := func() {
|
||||
bus.AddHandler("test", func(ctx context.Context, query *models.GetDashboardQuery) error {
|
||||
return models.ErrDashboardNotFound
|
||||
})
|
||||
}
|
||||
mock := mockstore.NewSQLStoreMock()
|
||||
mockSQLStore.ExpectedError = models.ErrDashboardNotFound
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/id/1/permissions",
|
||||
"/api/dashboards/id/:dashboardId/permissions", models.ROLE_EDITOR, func(sc *scenarioContext) {
|
||||
setUp()
|
||||
callGetDashboardPermissions(sc, hs)
|
||||
assert.Equal(t, 404, sc.resp.Code)
|
||||
}, mock)
|
||||
}, mockSQLStore)
|
||||
|
||||
cmd := dtos.UpdateDashboardAclCommand{
|
||||
Items: []dtos.DashboardAclUpdateItem{
|
||||
@@ -51,7 +48,6 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
|
||||
routePattern: "/api/dashboards/id/:dashboardId/permissions",
|
||||
cmd: cmd,
|
||||
fn: func(sc *scenarioContext) {
|
||||
setUp()
|
||||
callUpdateDashboardPermissions(t, sc)
|
||||
assert.Equal(t, 404, sc.resp.Code)
|
||||
},
|
||||
@@ -68,19 +64,15 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
|
||||
|
||||
getDashboardQueryResult := models.NewDashboard("Dash")
|
||||
|
||||
setUp := func() {
|
||||
bus.AddHandler("test", func(ctx context.Context, query *models.GetDashboardQuery) error {
|
||||
query.Result = getDashboardQueryResult
|
||||
return nil
|
||||
})
|
||||
}
|
||||
mock := mockstore.NewSQLStoreMock()
|
||||
mockSQLStore := mockstore.NewSQLStoreMock()
|
||||
mockSQLStore.ExpectedDashboard = getDashboardQueryResult
|
||||
mockSQLStore.ExpectedError = nil
|
||||
hs.SQLStore = mockSQLStore
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/id/1/permissions",
|
||||
"/api/dashboards/id/:dashboardId/permissions", models.ROLE_EDITOR, func(sc *scenarioContext) {
|
||||
setUp()
|
||||
callGetDashboardPermissions(sc, hs)
|
||||
assert.Equal(t, 403, sc.resp.Code)
|
||||
}, mock)
|
||||
}, mockSQLStore)
|
||||
|
||||
cmd := dtos.UpdateDashboardAclCommand{
|
||||
Items: []dtos.DashboardAclUpdateItem{
|
||||
@@ -94,7 +86,6 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
|
||||
routePattern: "/api/dashboards/id/:dashboardId/permissions",
|
||||
cmd: cmd,
|
||||
fn: func(sc *scenarioContext) {
|
||||
setUp()
|
||||
callUpdateDashboardPermissions(t, sc)
|
||||
assert.Equal(t, 403, sc.resp.Code)
|
||||
},
|
||||
@@ -119,18 +110,12 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
|
||||
},
|
||||
})
|
||||
|
||||
setUp := func() {
|
||||
getDashboardQueryResult := models.NewDashboard("Dash")
|
||||
bus.AddHandler("test", func(ctx context.Context, query *models.GetDashboardQuery) error {
|
||||
query.Result = getDashboardQueryResult
|
||||
return nil
|
||||
})
|
||||
}
|
||||
mock := mockstore.NewSQLStoreMock()
|
||||
mockSQLStore := mockstore.NewSQLStoreMock()
|
||||
mockSQLStore.ExpectedDashboard = models.NewDashboard("Dash")
|
||||
hs.SQLStore = mockSQLStore
|
||||
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/id/1/permissions",
|
||||
"/api/dashboards/id/:dashboardId/permissions", models.ROLE_ADMIN, func(sc *scenarioContext) {
|
||||
setUp()
|
||||
callGetDashboardPermissions(sc, hs)
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
|
||||
@@ -141,7 +126,7 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
|
||||
assert.Len(t, resp, 5)
|
||||
assert.Equal(t, int64(2), resp[0].UserId)
|
||||
assert.Equal(t, models.PERMISSION_VIEW, resp[0].Permission)
|
||||
}, mock)
|
||||
}, mockSQLStore)
|
||||
|
||||
cmd := dtos.UpdateDashboardAclCommand{
|
||||
Items: []dtos.DashboardAclUpdateItem{
|
||||
@@ -155,7 +140,6 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
|
||||
routePattern: "/api/dashboards/id/:dashboardId/permissions",
|
||||
cmd: cmd,
|
||||
fn: func(sc *scenarioContext) {
|
||||
setUp()
|
||||
callUpdateDashboardPermissions(t, sc)
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
},
|
||||
@@ -173,14 +157,6 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
|
||||
CheckPermissionBeforeUpdateValue: true,
|
||||
})
|
||||
|
||||
setUp := func() {
|
||||
getDashboardQueryResult := models.NewDashboard("Dash")
|
||||
bus.AddHandler("test", func(ctx context.Context, query *models.GetDashboardQuery) error {
|
||||
query.Result = getDashboardQueryResult
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
cmd := dtos.UpdateDashboardAclCommand{
|
||||
Items: []dtos.DashboardAclUpdateItem{
|
||||
{UserID: 1000, TeamID: 1, Permission: models.PERMISSION_ADMIN},
|
||||
@@ -193,7 +169,6 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
|
||||
routePattern: "/api/dashboards/id/:dashboardId/permissions",
|
||||
cmd: cmd,
|
||||
fn: func(sc *scenarioContext) {
|
||||
setUp()
|
||||
callUpdateDashboardPermissions(t, sc)
|
||||
assert.Equal(t, 400, sc.resp.Code)
|
||||
respJSON, err := jsonMap(sc.resp.Body.Bytes())
|
||||
@@ -214,14 +189,6 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
|
||||
CheckPermissionBeforeUpdateError: guardian.ErrGuardianPermissionExists,
|
||||
})
|
||||
|
||||
setUp := func() {
|
||||
getDashboardQueryResult := models.NewDashboard("Dash")
|
||||
bus.AddHandler("test", func(ctx context.Context, query *models.GetDashboardQuery) error {
|
||||
query.Result = getDashboardQueryResult
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
cmd := dtos.UpdateDashboardAclCommand{
|
||||
Items: []dtos.DashboardAclUpdateItem{
|
||||
{UserID: 1000, Permission: models.PERMISSION_ADMIN},
|
||||
@@ -234,7 +201,6 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
|
||||
routePattern: "/api/dashboards/id/:dashboardId/permissions",
|
||||
cmd: cmd,
|
||||
fn: func(sc *scenarioContext) {
|
||||
setUp()
|
||||
callUpdateDashboardPermissions(t, sc)
|
||||
assert.Equal(t, 400, sc.resp.Code)
|
||||
},
|
||||
@@ -285,14 +251,6 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
|
||||
CheckPermissionBeforeUpdateError: guardian.ErrGuardianOverride},
|
||||
)
|
||||
|
||||
setUp := func() {
|
||||
getDashboardQueryResult := models.NewDashboard("Dash")
|
||||
bus.AddHandler("test", func(ctx context.Context, query *models.GetDashboardQuery) error {
|
||||
query.Result = getDashboardQueryResult
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
cmd := dtos.UpdateDashboardAclCommand{
|
||||
Items: []dtos.DashboardAclUpdateItem{
|
||||
{UserID: 1000, Permission: models.PERMISSION_ADMIN},
|
||||
@@ -305,7 +263,6 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
|
||||
routePattern: "/api/dashboards/id/:dashboardId/permissions",
|
||||
cmd: cmd,
|
||||
fn: func(sc *scenarioContext) {
|
||||
setUp()
|
||||
callUpdateDashboardPermissions(t, sc)
|
||||
assert.Equal(t, 400, sc.resp.Code)
|
||||
},
|
||||
@@ -336,14 +293,7 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
|
||||
},
|
||||
})
|
||||
|
||||
setUp := func() {
|
||||
getDashboardQueryResult := models.NewDashboard("Dash")
|
||||
bus.AddHandler("test", func(ctx context.Context, query *models.GetDashboardQuery) error {
|
||||
query.Result = getDashboardQueryResult
|
||||
return nil
|
||||
})
|
||||
}
|
||||
mock := mockstore.NewSQLStoreMock()
|
||||
mockSQLStore := mockstore.NewSQLStoreMock()
|
||||
var resp []*models.DashboardAclInfoDTO
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/id/1/permissions",
|
||||
"/api/dashboards/id/:dashboardId/permissions", models.ROLE_ADMIN, func(sc *scenarioContext) {
|
||||
@@ -359,7 +309,7 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
|
||||
assert.Equal(t, models.PERMISSION_EDIT, resp[0].Permission)
|
||||
assert.Equal(t, int64(4), resp[1].UserId)
|
||||
assert.Equal(t, models.PERMISSION_ADMIN, resp[1].Permission)
|
||||
}, mock)
|
||||
}, mockSQLStore)
|
||||
|
||||
cmd := dtos.UpdateDashboardAclCommand{
|
||||
Items: []dtos.DashboardAclUpdateItem{
|
||||
@@ -380,7 +330,6 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
|
||||
routePattern: "/api/dashboards/id/:dashboardId/permissions",
|
||||
cmd: cmd,
|
||||
fn: func(sc *scenarioContext) {
|
||||
setUp()
|
||||
// TODO: Replace this fake with a fake SQLStore instead (once we can use an interface in its stead)
|
||||
origUpdateDashboardACL := updateDashboardACL
|
||||
t.Cleanup(func() {
|
||||
@@ -430,8 +379,6 @@ type updatePermissionContext struct {
|
||||
|
||||
func updateDashboardPermissionScenario(t *testing.T, ctx updatePermissionContext, hs *HTTPServer) {
|
||||
t.Run(fmt.Sprintf("%s %s", ctx.desc, ctx.url), func(t *testing.T) {
|
||||
t.Cleanup(bus.ClearBusHandlers)
|
||||
|
||||
sc := setupScenarioContext(t, ctx.url)
|
||||
|
||||
sc.defaultHandler = routing.Wrap(func(c *models.ReqContext) response.Response {
|
||||
|
||||
@@ -43,13 +43,8 @@ func TestGetHomeDashboard(t *testing.T) {
|
||||
hs := &HTTPServer{
|
||||
Cfg: cfg, Bus: bus.New(),
|
||||
pluginStore: &fakePluginStore{},
|
||||
SQLStore: mockstore.NewSQLStoreMock(),
|
||||
}
|
||||
hs.Bus.AddHandler(func(_ context.Context, query *models.GetPreferencesWithDefaultsQuery) error {
|
||||
query.Result = &models.Preferences{
|
||||
HomeDashboardId: 0,
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -85,10 +80,6 @@ func TestGetHomeDashboard(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
type testState struct {
|
||||
dashQueries []*models.GetDashboardQuery
|
||||
}
|
||||
|
||||
func newTestLive(t *testing.T) *live.GrafanaLive {
|
||||
features := featuremgmt.WithFeatures()
|
||||
cfg := &setting.Cfg{AppURL: "http://localhost:3000/"}
|
||||
@@ -113,26 +104,23 @@ func newTestLive(t *testing.T) *live.GrafanaLive {
|
||||
|
||||
func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
t.Run("Given a dashboard with a parent folder which does not have an ACL", func(t *testing.T) {
|
||||
setUp := func() *testState {
|
||||
fakeDash := models.NewDashboard("Child dash")
|
||||
fakeDash.Id = 1
|
||||
fakeDash.FolderId = 1
|
||||
fakeDash.HasAcl = false
|
||||
fakeDash := models.NewDashboard("Child dash")
|
||||
fakeDash.Id = 1
|
||||
fakeDash.FolderId = 1
|
||||
fakeDash.HasAcl = false
|
||||
|
||||
bus.AddHandler("test", func(ctx context.Context, query *models.GetDashboardsBySlugQuery) error {
|
||||
dashboards := []*models.Dashboard{fakeDash}
|
||||
query.Result = dashboards
|
||||
return nil
|
||||
})
|
||||
mockSQLStore := mockstore.NewSQLStoreMock()
|
||||
mockSQLStore.ExpectedDashboard = fakeDash
|
||||
mockSQLStore.ExpectedDashboardVersion = &models.DashboardVersion{}
|
||||
|
||||
state := &testState{}
|
||||
|
||||
bus.AddHandler("test", func(ctx context.Context, query *models.GetDashboardQuery) error {
|
||||
query.Result = fakeDash
|
||||
state.dashQueries = append(state.dashQueries, query)
|
||||
return nil
|
||||
})
|
||||
hs := &HTTPServer{
|
||||
Cfg: setting.NewCfg(),
|
||||
pluginStore: &fakePluginStore{},
|
||||
SQLStore: mockSQLStore,
|
||||
}
|
||||
hs.SQLStore = mockSQLStore
|
||||
|
||||
setUp := func() {
|
||||
viewerRole := models.ROLE_VIEWER
|
||||
editorRole := models.ROLE_EDITOR
|
||||
|
||||
@@ -145,13 +133,6 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
query.Result = aclMockResp
|
||||
return nil
|
||||
})
|
||||
|
||||
bus.AddHandler("test", func(ctx context.Context, query *models.GetTeamsByUserQuery) error {
|
||||
query.Result = []*models.TeamDTO{}
|
||||
return nil
|
||||
})
|
||||
|
||||
return state
|
||||
}
|
||||
|
||||
// This tests two scenarios:
|
||||
@@ -160,127 +141,94 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
|
||||
t.Run("When user is an Org Viewer", func(t *testing.T) {
|
||||
role := models.ROLE_VIEWER
|
||||
mock := mockstore.NewSQLStoreMock()
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/uid/abcdefghi",
|
||||
"/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
|
||||
state := setUp()
|
||||
|
||||
setUp()
|
||||
sc.sqlStore = mockSQLStore
|
||||
dash := getDashboardShouldReturn200(sc)
|
||||
|
||||
assert.Equal(t, "abcdefghi", state.dashQueries[0].Uid)
|
||||
|
||||
assert.False(t, dash.Meta.CanEdit)
|
||||
assert.False(t, dash.Meta.CanSave)
|
||||
assert.False(t, dash.Meta.CanAdmin)
|
||||
}, mock)
|
||||
|
||||
loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/uid/abcdefghi",
|
||||
"/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
|
||||
state := setUp()
|
||||
|
||||
callDeleteDashboardBySlug(sc, &HTTPServer{
|
||||
Cfg: setting.NewCfg(),
|
||||
LibraryPanelService: &mockLibraryPanelService{},
|
||||
LibraryElementService: &mockLibraryElementService{},
|
||||
})
|
||||
assert.Equal(t, 403, sc.resp.Code)
|
||||
|
||||
assert.Equal(t, "abcdefghi", state.dashQueries[0].Uid)
|
||||
}, mock)
|
||||
}, mockSQLStore)
|
||||
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/id/2/versions/1",
|
||||
"/api/dashboards/id/:dashboardId/versions/:id", role, func(sc *scenarioContext) {
|
||||
setUp()
|
||||
sc.sqlStore = mockSQLStore
|
||||
|
||||
callGetDashboardVersion(sc)
|
||||
hs.callGetDashboardVersion(sc)
|
||||
assert.Equal(t, 403, sc.resp.Code)
|
||||
}, mock)
|
||||
}, mockSQLStore)
|
||||
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/id/2/versions",
|
||||
"/api/dashboards/id/:dashboardId/versions", role, func(sc *scenarioContext) {
|
||||
setUp()
|
||||
sc.sqlStore = mockSQLStore
|
||||
|
||||
callGetDashboardVersions(sc)
|
||||
hs.callGetDashboardVersions(sc)
|
||||
assert.Equal(t, 403, sc.resp.Code)
|
||||
}, mock)
|
||||
}, mockSQLStore)
|
||||
})
|
||||
|
||||
t.Run("When user is an Org Editor", func(t *testing.T) {
|
||||
role := models.ROLE_EDITOR
|
||||
mock := mockstore.NewSQLStoreMock()
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/uid/abcdefghi",
|
||||
"/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
|
||||
state := setUp()
|
||||
|
||||
setUp()
|
||||
sc.sqlStore = mockSQLStore
|
||||
dash := getDashboardShouldReturn200(sc)
|
||||
|
||||
assert.Equal(t, "abcdefghi", state.dashQueries[0].Uid)
|
||||
assert.True(t, dash.Meta.CanEdit)
|
||||
assert.True(t, dash.Meta.CanSave)
|
||||
assert.False(t, dash.Meta.CanAdmin)
|
||||
}, mock)
|
||||
|
||||
loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/uid/abcdefghi",
|
||||
"/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
|
||||
state := setUp()
|
||||
|
||||
callDeleteDashboardBySlug(sc, &HTTPServer{
|
||||
Cfg: setting.NewCfg(),
|
||||
LibraryPanelService: &mockLibraryPanelService{},
|
||||
LibraryElementService: &mockLibraryElementService{},
|
||||
SQLStore: mock,
|
||||
})
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
assert.Equal(t, "abcdefghi", state.dashQueries[0].Uid)
|
||||
}, mock)
|
||||
}, mockSQLStore)
|
||||
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/id/2/versions/1",
|
||||
"/api/dashboards/id/:dashboardId/versions/:id", role, func(sc *scenarioContext) {
|
||||
setUp()
|
||||
sc.sqlStore = mockSQLStore
|
||||
hs.callGetDashboardVersion(sc)
|
||||
|
||||
callGetDashboardVersion(sc)
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
}, mock)
|
||||
}, mockSQLStore)
|
||||
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/id/2/versions",
|
||||
"/api/dashboards/id/:dashboardId/versions", role, func(sc *scenarioContext) {
|
||||
setUp()
|
||||
hs.callGetDashboardVersions(sc)
|
||||
|
||||
callGetDashboardVersions(sc)
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
}, mock)
|
||||
}, mockSQLStore)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("Given a dashboard with a parent folder which has an ACL", func(t *testing.T) {
|
||||
fakeDash := models.NewDashboard("Child dash")
|
||||
fakeDash.Id = 1
|
||||
fakeDash.FolderId = 1
|
||||
fakeDash.HasAcl = true
|
||||
|
||||
mockSQLStore := mockstore.NewSQLStoreMock()
|
||||
mockSQLStore.ExpectedDashboard = fakeDash
|
||||
mockSQLStore.ExpectedDashboardVersion = &models.DashboardVersion{}
|
||||
|
||||
hs := &HTTPServer{
|
||||
Cfg: setting.NewCfg(),
|
||||
Live: newTestLive(t),
|
||||
LibraryPanelService: &mockLibraryPanelService{},
|
||||
LibraryElementService: &mockLibraryElementService{},
|
||||
SQLStore: mockstore.NewSQLStoreMock(),
|
||||
SQLStore: mockSQLStore,
|
||||
}
|
||||
hs.SQLStore = mockSQLStore
|
||||
|
||||
setUp := func() *testState {
|
||||
state := &testState{}
|
||||
|
||||
fakeDash := models.NewDashboard("Child dash")
|
||||
fakeDash.Id = 1
|
||||
fakeDash.FolderId = 1
|
||||
fakeDash.HasAcl = true
|
||||
|
||||
setUp := func() {
|
||||
origCanEdit := setting.ViewersCanEdit
|
||||
t.Cleanup(func() {
|
||||
setting.ViewersCanEdit = origCanEdit
|
||||
})
|
||||
setting.ViewersCanEdit = false
|
||||
|
||||
bus.AddHandler("test", func(ctx context.Context, query *models.GetDashboardsBySlugQuery) error {
|
||||
dashboards := []*models.Dashboard{fakeDash}
|
||||
query.Result = dashboards
|
||||
return nil
|
||||
})
|
||||
|
||||
aclMockResp := []*models.DashboardAclInfoDTO{
|
||||
{
|
||||
DashboardId: 1,
|
||||
@@ -293,19 +241,6 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
query.Result = aclMockResp
|
||||
return nil
|
||||
})
|
||||
|
||||
bus.AddHandler("test", func(ctx context.Context, query *models.GetDashboardQuery) error {
|
||||
query.Result = fakeDash
|
||||
state.dashQueries = append(state.dashQueries, query)
|
||||
return nil
|
||||
})
|
||||
|
||||
bus.AddHandler("test", func(ctx context.Context, query *models.GetTeamsByUserQuery) error {
|
||||
query.Result = []*models.TeamDTO{}
|
||||
return nil
|
||||
})
|
||||
|
||||
return state
|
||||
}
|
||||
|
||||
// This tests six scenarios:
|
||||
@@ -318,81 +253,78 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
|
||||
t.Run("When user is an Org Viewer and has no permissions for this dashboard", func(t *testing.T) {
|
||||
role := models.ROLE_VIEWER
|
||||
mock := mockstore.NewSQLStoreMock()
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/uid/abcdefghi",
|
||||
"/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
|
||||
state := setUp()
|
||||
|
||||
setUp()
|
||||
sc.sqlStore = mockSQLStore
|
||||
sc.handlerFunc = hs.GetDashboard
|
||||
sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec()
|
||||
assert.Equal(t, "abcdefghi", state.dashQueries[0].Uid)
|
||||
|
||||
assert.Equal(t, 403, sc.resp.Code)
|
||||
}, mock)
|
||||
}, mockSQLStore)
|
||||
|
||||
loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/uid/abcdefghi",
|
||||
"/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
|
||||
state := setUp()
|
||||
setUp()
|
||||
sc.sqlStore = mockSQLStore
|
||||
hs.callDeleteDashboardByUID(t, sc, nil)
|
||||
|
||||
callDeleteDashboardByUID(sc, hs)
|
||||
assert.Equal(t, 403, sc.resp.Code)
|
||||
assert.Equal(t, "abcdefghi", state.dashQueries[0].Uid)
|
||||
}, mock)
|
||||
}, mockSQLStore)
|
||||
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/id/2/versions/1",
|
||||
"/api/dashboards/id/:dashboardId/versions/:id", role, func(sc *scenarioContext) {
|
||||
setUp()
|
||||
sc.sqlStore = mockSQLStore
|
||||
hs.callGetDashboardVersion(sc)
|
||||
|
||||
callGetDashboardVersion(sc)
|
||||
assert.Equal(t, 403, sc.resp.Code)
|
||||
}, mock)
|
||||
}, mockSQLStore)
|
||||
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/id/2/versions",
|
||||
"/api/dashboards/id/:dashboardId/versions", role, func(sc *scenarioContext) {
|
||||
setUp()
|
||||
hs.callGetDashboardVersions(sc)
|
||||
|
||||
callGetDashboardVersions(sc)
|
||||
assert.Equal(t, 403, sc.resp.Code)
|
||||
}, mock)
|
||||
}, mockSQLStore)
|
||||
})
|
||||
|
||||
t.Run("When user is an Org Editor and has no permissions for this dashboard", func(t *testing.T) {
|
||||
role := models.ROLE_EDITOR
|
||||
mock := mockstore.NewSQLStoreMock()
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/uid/abcdefghi",
|
||||
"/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
|
||||
state := setUp()
|
||||
|
||||
setUp()
|
||||
sc.sqlStore = mockSQLStore
|
||||
sc.handlerFunc = hs.GetDashboard
|
||||
sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec()
|
||||
|
||||
assert.Equal(t, "abcdefghi", state.dashQueries[0].Uid)
|
||||
assert.Equal(t, 403, sc.resp.Code)
|
||||
}, mock)
|
||||
}, mockSQLStore)
|
||||
|
||||
loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/uid/abcdefghi",
|
||||
"/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
|
||||
state := setUp()
|
||||
setUp()
|
||||
hs.callDeleteDashboardByUID(t, sc, nil)
|
||||
|
||||
callDeleteDashboardByUID(sc, hs)
|
||||
assert.Equal(t, 403, sc.resp.Code)
|
||||
assert.Equal(t, "abcdefghi", state.dashQueries[0].Uid)
|
||||
}, mock)
|
||||
}, mockSQLStore)
|
||||
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/id/2/versions/1",
|
||||
"/api/dashboards/id/:dashboardId/versions/:id", role, func(sc *scenarioContext) {
|
||||
setUp()
|
||||
hs.callGetDashboardVersion(sc)
|
||||
|
||||
callGetDashboardVersion(sc)
|
||||
assert.Equal(t, 403, sc.resp.Code)
|
||||
}, mock)
|
||||
}, mockSQLStore)
|
||||
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/id/2/versions",
|
||||
"/api/dashboards/id/:dashboardId/versions", role, func(sc *scenarioContext) {
|
||||
setUp()
|
||||
hs.callGetDashboardVersions(sc)
|
||||
|
||||
callGetDashboardVersions(sc)
|
||||
assert.Equal(t, 403, sc.resp.Code)
|
||||
}, mock)
|
||||
}, mockSQLStore)
|
||||
})
|
||||
|
||||
t.Run("When user is an Org Viewer but has an edit permission", func(t *testing.T) {
|
||||
@@ -402,54 +334,64 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
{OrgId: 1, DashboardId: 2, UserId: 1, Permission: models.PERMISSION_EDIT},
|
||||
}
|
||||
|
||||
setUpInner := func() *testState {
|
||||
state := setUp()
|
||||
setUpInner := func() {
|
||||
setUp()
|
||||
bus.AddHandler("test", func(ctx context.Context, query *models.GetDashboardAclInfoListQuery) error {
|
||||
query.Result = mockResult
|
||||
return nil
|
||||
})
|
||||
return state
|
||||
}
|
||||
mock := mockstore.NewSQLStoreMock()
|
||||
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/uid/abcdefghi",
|
||||
"/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
|
||||
state := setUpInner()
|
||||
|
||||
setUpInner()
|
||||
sc.sqlStore = mockSQLStore
|
||||
dash := getDashboardShouldReturn200(sc)
|
||||
|
||||
assert.Equal(t, "abcdefghi", state.dashQueries[0].Uid)
|
||||
assert.True(t, dash.Meta.CanEdit)
|
||||
assert.True(t, dash.Meta.CanSave)
|
||||
assert.False(t, dash.Meta.CanAdmin)
|
||||
}, mock)
|
||||
}, mockSQLStore)
|
||||
|
||||
loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
|
||||
state := setUpInner()
|
||||
callDeleteDashboardByUID(sc, hs)
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
assert.Equal(t, "abcdefghi", state.dashQueries[0].Uid)
|
||||
}, mock)
|
||||
setUpInner()
|
||||
mockDashboard := &dashboards.FakeDashboardService{
|
||||
SaveDashboardResult: &models.Dashboard{
|
||||
Id: fakeDash.Id,
|
||||
Uid: "uid",
|
||||
Title: "Dash",
|
||||
Slug: "dash",
|
||||
Version: 2,
|
||||
},
|
||||
}
|
||||
|
||||
hs.callDeleteDashboardByUID(t, sc, mockDashboard)
|
||||
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
}, mockSQLStore)
|
||||
|
||||
mockSQLStore.ExpectedDashboardVersion = &models.DashboardVersion{}
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/id/2/versions/1", "/api/dashboards/id/:dashboardId/versions/:id", role, func(sc *scenarioContext) {
|
||||
setUpInner()
|
||||
sc.sqlStore = mockSQLStore
|
||||
hs.callGetDashboardVersion(sc)
|
||||
|
||||
callGetDashboardVersion(sc)
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
}, mock)
|
||||
}, mockSQLStore)
|
||||
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/id/2/versions", "/api/dashboards/id/:dashboardId/versions", role, func(sc *scenarioContext) {
|
||||
setUpInner()
|
||||
hs.callGetDashboardVersions(sc)
|
||||
|
||||
callGetDashboardVersions(sc)
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
}, mock)
|
||||
}, mockSQLStore)
|
||||
})
|
||||
|
||||
t.Run("When user is an Org Viewer and viewers can edit", func(t *testing.T) {
|
||||
role := models.ROLE_VIEWER
|
||||
|
||||
setUpInner := func() *testState {
|
||||
state := setUp()
|
||||
setUpInner := func() {
|
||||
setUp()
|
||||
|
||||
mockResult := []*models.DashboardAclInfoDTO{
|
||||
{OrgId: 1, DashboardId: 2, UserId: 1, Permission: models.PERMISSION_VIEW},
|
||||
@@ -465,36 +407,33 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
setting.ViewersCanEdit = origCanEdit
|
||||
})
|
||||
setting.ViewersCanEdit = true
|
||||
|
||||
return state
|
||||
}
|
||||
mock := mockstore.NewSQLStoreMock()
|
||||
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
|
||||
state := setUpInner()
|
||||
setUpInner()
|
||||
|
||||
require.True(t, setting.ViewersCanEdit)
|
||||
sc.sqlStore = mockSQLStore
|
||||
dash := getDashboardShouldReturn200(sc)
|
||||
|
||||
assert.Equal(t, "abcdefghi", state.dashQueries[0].Uid)
|
||||
assert.True(t, dash.Meta.CanEdit)
|
||||
assert.False(t, dash.Meta.CanSave)
|
||||
assert.False(t, dash.Meta.CanAdmin)
|
||||
}, mock)
|
||||
}, mockSQLStore)
|
||||
|
||||
loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
|
||||
state := setUpInner()
|
||||
setUpInner()
|
||||
|
||||
callDeleteDashboardByUID(sc, hs)
|
||||
hs.callDeleteDashboardByUID(t, sc, nil)
|
||||
assert.Equal(t, 403, sc.resp.Code)
|
||||
assert.Equal(t, "abcdefghi", state.dashQueries[0].Uid)
|
||||
}, mock)
|
||||
}, mockSQLStore)
|
||||
})
|
||||
|
||||
t.Run("When user is an Org Viewer but has an admin permission", func(t *testing.T) {
|
||||
role := models.ROLE_VIEWER
|
||||
|
||||
setUpInner := func() *testState {
|
||||
state := setUp()
|
||||
setUpInner := func() {
|
||||
setUp()
|
||||
|
||||
mockResult := []*models.DashboardAclInfoDTO{
|
||||
{OrgId: 1, DashboardId: 2, UserId: 1, Permission: models.PERMISSION_ADMIN},
|
||||
@@ -503,48 +442,46 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
query.Result = mockResult
|
||||
return nil
|
||||
})
|
||||
return state
|
||||
}
|
||||
mock := mockstore.NewSQLStoreMock()
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
|
||||
state := setUpInner()
|
||||
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
|
||||
setUpInner()
|
||||
sc.sqlStore = mockSQLStore
|
||||
dash := getDashboardShouldReturn200(sc)
|
||||
|
||||
assert.Equal(t, "abcdefghi", state.dashQueries[0].Uid)
|
||||
assert.True(t, dash.Meta.CanEdit)
|
||||
assert.True(t, dash.Meta.CanSave)
|
||||
assert.True(t, dash.Meta.CanAdmin)
|
||||
}, mock)
|
||||
}, mockSQLStore)
|
||||
|
||||
loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
|
||||
state := setUpInner()
|
||||
setUpInner()
|
||||
sc.sqlStore = mockSQLStore
|
||||
hs.callDeleteDashboardByUID(t, sc, &dashboards.FakeDashboardService{})
|
||||
|
||||
callDeleteDashboardByUID(sc, hs)
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
assert.Equal(t, "abcdefghi", state.dashQueries[0].Uid)
|
||||
}, mock)
|
||||
}, mockSQLStore)
|
||||
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/id/2/versions/1", "/api/dashboards/id/:dashboardId/versions/:id", role, func(sc *scenarioContext) {
|
||||
setUpInner()
|
||||
|
||||
callGetDashboardVersion(sc)
|
||||
hs.callGetDashboardVersion(sc)
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
}, mock)
|
||||
}, mockSQLStore)
|
||||
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/id/2/versions", "/api/dashboards/id/:dashboardId/versions", role, func(sc *scenarioContext) {
|
||||
setUpInner()
|
||||
|
||||
callGetDashboardVersions(sc)
|
||||
hs.callGetDashboardVersions(sc)
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
}, mock)
|
||||
}, mockSQLStore)
|
||||
})
|
||||
|
||||
t.Run("When user is an Org Editor but has a view permission", func(t *testing.T) {
|
||||
role := models.ROLE_EDITOR
|
||||
|
||||
setUpInner := func() *testState {
|
||||
state := setUp()
|
||||
setUpInner := func() {
|
||||
setUp()
|
||||
|
||||
mockResult := []*models.DashboardAclInfoDTO{
|
||||
{OrgId: 1, DashboardId: 2, UserId: 1, Permission: models.PERMISSION_VIEW},
|
||||
@@ -553,39 +490,37 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
query.Result = mockResult
|
||||
return nil
|
||||
})
|
||||
return state
|
||||
}
|
||||
mock := mockstore.NewSQLStoreMock()
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
|
||||
state := setUpInner()
|
||||
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
|
||||
setUpInner()
|
||||
sc.sqlStore = mockSQLStore
|
||||
dash := getDashboardShouldReturn200(sc)
|
||||
assert.Equal(t, "abcdefghi", state.dashQueries[0].Uid)
|
||||
|
||||
assert.False(t, dash.Meta.CanEdit)
|
||||
assert.False(t, dash.Meta.CanSave)
|
||||
}, mock)
|
||||
}, mockSQLStore)
|
||||
|
||||
loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
|
||||
state := setUpInner()
|
||||
setUpInner()
|
||||
hs.callDeleteDashboardByUID(t, sc, nil)
|
||||
|
||||
callDeleteDashboardByUID(sc, hs)
|
||||
assert.Equal(t, 403, sc.resp.Code)
|
||||
assert.Equal(t, "abcdefghi", state.dashQueries[0].Uid)
|
||||
}, mock)
|
||||
}, mockSQLStore)
|
||||
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/id/2/versions/1", "/api/dashboards/id/:dashboardId/versions/:id", role, func(sc *scenarioContext) {
|
||||
setUpInner()
|
||||
hs.callGetDashboardVersion(sc)
|
||||
|
||||
callGetDashboardVersion(sc)
|
||||
assert.Equal(t, 403, sc.resp.Code)
|
||||
}, mock)
|
||||
}, mockSQLStore)
|
||||
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/id/2/versions", "/api/dashboards/id/:dashboardId/versions", role, func(sc *scenarioContext) {
|
||||
setUpInner()
|
||||
hs.callGetDashboardVersions(sc)
|
||||
|
||||
callGetDashboardVersions(sc)
|
||||
assert.Equal(t, 403, sc.resp.Code)
|
||||
}, mock)
|
||||
}, mockSQLStore)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -599,12 +534,6 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
dashTwo.Id = 4
|
||||
dashTwo.FolderId = 3
|
||||
dashTwo.HasAcl = false
|
||||
|
||||
bus.AddHandler("test", func(ctx context.Context, query *models.GetDashboardsBySlugQuery) error {
|
||||
dashboards := []*models.Dashboard{dashOne, dashTwo}
|
||||
query.Result = dashboards
|
||||
return nil
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("Post dashboard response tests", func(t *testing.T) {
|
||||
@@ -842,26 +771,10 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
|
||||
t.Run("Given dashboard in folder being restored should restore to folder", func(t *testing.T) {
|
||||
const folderID int64 = 1
|
||||
setUp := func() {
|
||||
fakeDash := models.NewDashboard("Child dash")
|
||||
fakeDash.Id = 2
|
||||
fakeDash.FolderId = folderID
|
||||
fakeDash.HasAcl = false
|
||||
|
||||
bus.AddHandler("test", func(ctx context.Context, query *models.GetDashboardQuery) error {
|
||||
query.Result = fakeDash
|
||||
return nil
|
||||
})
|
||||
|
||||
bus.AddHandler("test", func(ctx context.Context, query *models.GetDashboardVersionQuery) error {
|
||||
query.Result = &models.DashboardVersion{
|
||||
DashboardId: 2,
|
||||
Version: 1,
|
||||
Data: fakeDash.Data,
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
fakeDash := models.NewDashboard("Child dash")
|
||||
fakeDash.Id = 2
|
||||
fakeDash.FolderId = folderID
|
||||
fakeDash.HasAcl = false
|
||||
|
||||
mock := &dashboards.FakeDashboardService{
|
||||
SaveDashboardResult: &models.Dashboard{
|
||||
@@ -876,40 +789,29 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
cmd := dtos.RestoreDashboardVersionCommand{
|
||||
Version: 1,
|
||||
}
|
||||
|
||||
mockSQLStore := mockstore.NewSQLStoreMock()
|
||||
mockSQLStore.ExpectedDashboard = fakeDash
|
||||
mockSQLStore.ExpectedDashboardVersion = &models.DashboardVersion{
|
||||
DashboardId: 2,
|
||||
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) {
|
||||
setUp()
|
||||
|
||||
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)
|
||||
})
|
||||
|
||||
t.Run("Given dashboard in general folder being restored should restore to general folder", func(t *testing.T) {
|
||||
setUp := func() {
|
||||
fakeDash := models.NewDashboard("Child dash")
|
||||
fakeDash.Id = 2
|
||||
fakeDash.HasAcl = false
|
||||
|
||||
bus.AddHandler("test", func(ctx context.Context, query *models.GetDashboardQuery) error {
|
||||
query.Result = fakeDash
|
||||
return nil
|
||||
})
|
||||
|
||||
bus.AddHandler("test", func(ctx context.Context, query *models.GetDashboardVersionQuery) error {
|
||||
query.Result = &models.DashboardVersion{
|
||||
DashboardId: 2,
|
||||
Version: 1,
|
||||
Data: fakeDash.Data,
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
fakeDash := models.NewDashboard("Child dash")
|
||||
fakeDash.Id = 2
|
||||
fakeDash.HasAcl = false
|
||||
|
||||
mock := &dashboards.FakeDashboardService{
|
||||
SaveDashboardResult: &models.Dashboard{
|
||||
@@ -924,33 +826,27 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
cmd := dtos.RestoreDashboardVersionCommand{
|
||||
Version: 1,
|
||||
}
|
||||
|
||||
mockSQLStore := mockstore.NewSQLStoreMock()
|
||||
mockSQLStore.ExpectedDashboard = fakeDash
|
||||
mockSQLStore.ExpectedDashboardVersion = &models.DashboardVersion{
|
||||
DashboardId: 2,
|
||||
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) {
|
||||
setUp()
|
||||
|
||||
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)
|
||||
})
|
||||
|
||||
t.Run("Given provisioned dashboard", func(t *testing.T) {
|
||||
setUp := func() {
|
||||
bus.AddHandler("test", func(ctx context.Context, query *models.GetDashboardsBySlugQuery) error {
|
||||
query.Result = []*models.Dashboard{{}}
|
||||
return nil
|
||||
})
|
||||
bus.AddHandler("test", func(ctx context.Context, query *models.GetDashboardQuery) error {
|
||||
dataValue, err := simplejson.NewJson([]byte(`{"id": 1, "editable": true, "style": "dark"}`))
|
||||
require.NoError(t, err)
|
||||
query.Result = &models.Dashboard{Id: 1, Data: dataValue}
|
||||
return nil
|
||||
})
|
||||
|
||||
origGetProvisionedData := dashboards.GetProvisionedData
|
||||
t.Cleanup(func() {
|
||||
dashboards.GetProvisionedData = origGetProvisionedData
|
||||
@@ -966,25 +862,17 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
return nil
|
||||
})
|
||||
}
|
||||
mock := mockstore.NewSQLStoreMock()
|
||||
loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/db/abcdefghi", "/api/dashboards/db/:uid", models.ROLE_EDITOR, func(sc *scenarioContext) {
|
||||
setUp()
|
||||
|
||||
callDeleteDashboardBySlug(sc, &HTTPServer{
|
||||
Cfg: setting.NewCfg(),
|
||||
LibraryPanelService: &mockLibraryPanelService{},
|
||||
LibraryElementService: &mockLibraryElementService{},
|
||||
SQLStore: mock,
|
||||
})
|
||||
|
||||
assert.Equal(t, 400, sc.resp.Code)
|
||||
result := sc.ToJSON()
|
||||
assert.Equal(t, models.ErrDashboardCannotDeleteProvisionedDashboard.Error(), result.Get("error").MustString())
|
||||
}, mock)
|
||||
mockSQLStore := mockstore.NewSQLStoreMock()
|
||||
dataValue, err := simplejson.NewJson([]byte(`{"id": 1, "editable": true, "style": "dark"}`))
|
||||
require.NoError(t, err)
|
||||
mockSQLStore.ExpectedDashboard = &models.Dashboard{Id: 1, Data: dataValue}
|
||||
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/uid/dash", "/api/dashboards/uid/:uid", models.ROLE_EDITOR, func(sc *scenarioContext) {
|
||||
setUp()
|
||||
|
||||
dataValue, err := simplejson.NewJson([]byte(`{"id": 1, "editable": true, "style": "dark"}`))
|
||||
require.NoError(t, err)
|
||||
mockSQLStore.ExpectedDashboard = &models.Dashboard{Id: 1, Data: dataValue}
|
||||
sc.sqlStore = mockSQLStore
|
||||
mock := provisioning.NewProvisioningServiceMock(context.Background())
|
||||
mock.GetDashboardProvisionerResolvedPathFunc = func(name string) string {
|
||||
return "/tmp/grafana/dashboards"
|
||||
@@ -993,9 +881,8 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
dash := getDashboardShouldReturn200WithConfig(sc, mock)
|
||||
|
||||
assert.Equal(t, filepath.Join("test", "dashboard1.json"), dash.Meta.ProvisionedExternalId)
|
||||
}, mock)
|
||||
}, mockSQLStore)
|
||||
|
||||
mockSQLStore := mockstore.NewSQLStoreMock()
|
||||
loggedInUserScenarioWithRole(t, "When allowUiUpdates is true and calling GET on", "GET", "/api/dashboards/uid/dash", "/api/dashboards/uid/:uid", models.ROLE_EDITOR, func(sc *scenarioContext) {
|
||||
setUp()
|
||||
|
||||
@@ -1014,7 +901,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
LibraryElementService: &mockLibraryElementService{},
|
||||
SQLStore: mockSQLStore,
|
||||
}
|
||||
callGetDashboard(sc, hs)
|
||||
hs.callGetDashboard(sc)
|
||||
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
|
||||
@@ -1023,7 +910,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, false, dash.Meta.Provisioned)
|
||||
}, mock)
|
||||
}, mockSQLStore)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1044,7 +931,7 @@ func getDashboardShouldReturn200WithConfig(sc *scenarioContext, provisioningServ
|
||||
SQLStore: sc.sqlStore,
|
||||
}
|
||||
|
||||
callGetDashboard(sc, hs)
|
||||
hs.callGetDashboard(sc)
|
||||
|
||||
require.Equal(sc.t, 200, sc.resp.Code)
|
||||
|
||||
@@ -1059,44 +946,41 @@ func getDashboardShouldReturn200(sc *scenarioContext) dtos.DashboardFullWithMeta
|
||||
return getDashboardShouldReturn200WithConfig(sc, nil)
|
||||
}
|
||||
|
||||
func callGetDashboard(sc *scenarioContext, hs *HTTPServer) {
|
||||
func (hs *HTTPServer) callGetDashboard(sc *scenarioContext) {
|
||||
sc.handlerFunc = hs.GetDashboard
|
||||
sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec()
|
||||
}
|
||||
|
||||
func callGetDashboardVersion(sc *scenarioContext) {
|
||||
func (hs *HTTPServer) callGetDashboardVersion(sc *scenarioContext) {
|
||||
bus.AddHandler("test", func(ctx context.Context, query *models.GetDashboardVersionQuery) error {
|
||||
query.Result = &models.DashboardVersion{}
|
||||
return nil
|
||||
})
|
||||
|
||||
sc.handlerFunc = GetDashboardVersion
|
||||
sc.handlerFunc = hs.GetDashboardVersion
|
||||
sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec()
|
||||
}
|
||||
|
||||
func callGetDashboardVersions(sc *scenarioContext) {
|
||||
func (hs *HTTPServer) callGetDashboardVersions(sc *scenarioContext) {
|
||||
bus.AddHandler("test", func(ctx context.Context, query *models.GetDashboardVersionsQuery) error {
|
||||
query.Result = []*models.DashboardVersionDTO{}
|
||||
return nil
|
||||
})
|
||||
|
||||
sc.handlerFunc = GetDashboardVersions
|
||||
sc.handlerFunc = hs.GetDashboardVersions
|
||||
sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec()
|
||||
}
|
||||
|
||||
func callDeleteDashboardBySlug(sc *scenarioContext, hs *HTTPServer) {
|
||||
func (hs *HTTPServer) callDeleteDashboardByUID(t *testing.T, sc *scenarioContext, mockDashboard *dashboards.FakeDashboardService) {
|
||||
bus.AddHandler("test", func(ctx context.Context, cmd *models.DeleteDashboardCommand) error {
|
||||
return nil
|
||||
})
|
||||
|
||||
sc.handlerFunc = hs.DeleteDashboardBySlug
|
||||
sc.fakeReqWithParams("DELETE", sc.url, map[string]string{}).exec()
|
||||
}
|
||||
|
||||
func callDeleteDashboardByUID(sc *scenarioContext, hs *HTTPServer) {
|
||||
bus.AddHandler("test", func(ctx context.Context, cmd *models.DeleteDashboardCommand) error {
|
||||
return nil
|
||||
origNewDashboardService := dashboards.NewService
|
||||
t.Cleanup(func() {
|
||||
dashboards.NewService = origNewDashboardService
|
||||
})
|
||||
dashboards.MockDashboardService(mockDashboard)
|
||||
|
||||
sc.handlerFunc = hs.DeleteDashboardByUID
|
||||
sc.fakeReqWithParams("DELETE", sc.url, map[string]string{}).exec()
|
||||
@@ -1189,11 +1073,13 @@ func postDiffScenario(t *testing.T, desc string, url string, routePattern string
|
||||
}
|
||||
|
||||
func restoreDashboardVersionScenario(t *testing.T, desc string, url string, routePattern string,
|
||||
mock *dashboards.FakeDashboardService, cmd dtos.RestoreDashboardVersionCommand, fn scenarioFunc) {
|
||||
mock *dashboards.FakeDashboardService, cmd dtos.RestoreDashboardVersionCommand, fn scenarioFunc,
|
||||
sqlStore sqlstore.Store) {
|
||||
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
|
||||
defer bus.ClearBusHandlers()
|
||||
|
||||
cfg := setting.NewCfg()
|
||||
mockSQLStore := mockstore.NewSQLStoreMock()
|
||||
hs := HTTPServer{
|
||||
Cfg: cfg,
|
||||
Bus: bus.GetBus(),
|
||||
@@ -1202,9 +1088,11 @@ func restoreDashboardVersionScenario(t *testing.T, desc string, url string, rout
|
||||
QuotaService: "a.QuotaService{Cfg: cfg},
|
||||
LibraryPanelService: &mockLibraryPanelService{},
|
||||
LibraryElementService: &mockLibraryElementService{},
|
||||
SQLStore: sqlStore,
|
||||
}
|
||||
|
||||
sc := setupScenarioContext(t, url)
|
||||
sc.sqlStore = mockSQLStore
|
||||
sc.defaultHandler = routing.Wrap(func(c *models.ReqContext) response.Response {
|
||||
c.Req.Body = mockRequestBody(cmd)
|
||||
sc.context = c
|
||||
|
||||
@@ -47,7 +47,7 @@ func (hs *HTTPServer) GetFolderByUID(c *models.ReqContext) response.Response {
|
||||
}
|
||||
|
||||
g := guardian.New(c.Req.Context(), folder.Id, c.OrgId, c.SignedInUser)
|
||||
return response.JSON(200, toFolderDto(c.Req.Context(), g, folder))
|
||||
return response.JSON(200, hs.toFolderDto(c.Req.Context(), g, folder))
|
||||
}
|
||||
|
||||
func (hs *HTTPServer) GetFolderByID(c *models.ReqContext) response.Response {
|
||||
@@ -64,7 +64,7 @@ func (hs *HTTPServer) GetFolderByID(c *models.ReqContext) response.Response {
|
||||
}
|
||||
|
||||
g := guardian.New(c.Req.Context(), folder.Id, c.OrgId, c.SignedInUser)
|
||||
return response.JSON(200, toFolderDto(c.Req.Context(), g, folder))
|
||||
return response.JSON(200, hs.toFolderDto(c.Req.Context(), g, folder))
|
||||
}
|
||||
|
||||
func (hs *HTTPServer) CreateFolder(c *models.ReqContext) response.Response {
|
||||
@@ -86,7 +86,7 @@ func (hs *HTTPServer) CreateFolder(c *models.ReqContext) response.Response {
|
||||
}
|
||||
|
||||
g := guardian.New(c.Req.Context(), folder.Id, c.OrgId, c.SignedInUser)
|
||||
return response.JSON(200, toFolderDto(c.Req.Context(), g, folder))
|
||||
return response.JSON(200, hs.toFolderDto(c.Req.Context(), g, folder))
|
||||
}
|
||||
|
||||
func (hs *HTTPServer) UpdateFolder(c *models.ReqContext) response.Response {
|
||||
@@ -101,7 +101,7 @@ func (hs *HTTPServer) UpdateFolder(c *models.ReqContext) response.Response {
|
||||
}
|
||||
|
||||
g := guardian.New(c.Req.Context(), cmd.Result.Id, c.OrgId, c.SignedInUser)
|
||||
return response.JSON(200, toFolderDto(c.Req.Context(), g, cmd.Result))
|
||||
return response.JSON(200, hs.toFolderDto(c.Req.Context(), g, cmd.Result))
|
||||
}
|
||||
|
||||
func (hs *HTTPServer) DeleteFolder(c *models.ReqContext) response.Response { // temporarily adding this function to HTTPServer, will be removed from HTTPServer when librarypanels featuretoggle is removed
|
||||
@@ -126,7 +126,7 @@ func (hs *HTTPServer) DeleteFolder(c *models.ReqContext) response.Response { //
|
||||
})
|
||||
}
|
||||
|
||||
func toFolderDto(ctx context.Context, g guardian.DashboardGuardian, folder *models.Folder) dtos.Folder {
|
||||
func (hs *HTTPServer) toFolderDto(ctx context.Context, g guardian.DashboardGuardian, folder *models.Folder) dtos.Folder {
|
||||
canEdit, _ := g.CanEdit()
|
||||
canSave, _ := g.CanSave()
|
||||
canAdmin, _ := g.CanAdmin()
|
||||
@@ -134,10 +134,10 @@ func toFolderDto(ctx context.Context, g guardian.DashboardGuardian, folder *mode
|
||||
// Finding creator and last updater of the folder
|
||||
updater, creator := anonString, anonString
|
||||
if folder.CreatedBy > 0 {
|
||||
creator = getUserLogin(ctx, folder.CreatedBy)
|
||||
creator = hs.getUserLogin(ctx, folder.CreatedBy)
|
||||
}
|
||||
if folder.UpdatedBy > 0 {
|
||||
updater = getUserLogin(ctx, folder.UpdatedBy)
|
||||
updater = hs.getUserLogin(ctx, folder.UpdatedBy)
|
||||
}
|
||||
|
||||
return dtos.Folder{
|
||||
|
||||
@@ -27,11 +27,9 @@ var shadowSearchCounter = prometheus.NewCounterVec(
|
||||
)
|
||||
|
||||
func init() {
|
||||
bus.AddHandler("sql", GetDashboardTags)
|
||||
bus.AddHandler("sql", GetDashboardSlugById)
|
||||
bus.AddHandler("sql", GetDashboardsByPluginId)
|
||||
bus.AddHandler("sql", GetDashboardPermissionsForUser)
|
||||
bus.AddHandler("sql", GetDashboardsBySlug)
|
||||
bus.AddHandler("sql", HasAdminPermissionInFolders)
|
||||
|
||||
prometheus.MustRegister(shadowSearchCounter)
|
||||
@@ -40,6 +38,7 @@ func init() {
|
||||
func (ss *SQLStore) addDashboardQueryAndCommandHandlers() {
|
||||
bus.AddHandler("sql", ss.GetDashboard)
|
||||
bus.AddHandler("sql", ss.GetDashboardUIDById)
|
||||
bus.AddHandler("sql", ss.GetDashboardTags)
|
||||
bus.AddHandler("sql", ss.SearchDashboards)
|
||||
bus.AddHandler("sql", ss.DeleteDashboard)
|
||||
bus.AddHandler("sql", ss.GetDashboards)
|
||||
@@ -375,7 +374,7 @@ func makeQueryResult(query *search.FindPersistedDashboardsQuery, res []Dashboard
|
||||
}
|
||||
}
|
||||
|
||||
func GetDashboardTags(ctx context.Context, query *models.GetDashboardTagsQuery) error {
|
||||
func (ss *SQLStore) GetDashboardTags(ctx context.Context, query *models.GetDashboardTagsQuery) error {
|
||||
sql := `SELECT
|
||||
COUNT(*) as count,
|
||||
term
|
||||
@@ -601,17 +600,6 @@ func GetDashboardSlugById(ctx context.Context, query *models.GetDashboardSlugByI
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetDashboardsBySlug(ctx context.Context, query *models.GetDashboardsBySlugQuery) error {
|
||||
var dashboards []*models.Dashboard
|
||||
|
||||
if err := x.Where("org_id=? AND slug=?", query.OrgId, query.Slug).Find(&dashboards); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
query.Result = dashboards
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ss *SQLStore) GetDashboardUIDById(ctx context.Context, query *models.GetDashboardRefByIdQuery) error {
|
||||
return ss.WithDbSession(ctx, func(dbSession *DBSession) error {
|
||||
var rawSQL = `SELECT uid, slug from dashboard WHERE Id=?`
|
||||
|
||||
@@ -292,7 +292,7 @@ func TestDashboardDataAccess(t *testing.T) {
|
||||
setup()
|
||||
query := models.GetDashboardTagsQuery{OrgId: 1}
|
||||
|
||||
err := GetDashboardTags(context.Background(), &query)
|
||||
err := sqlStore.GetDashboardTags(context.Background(), &query)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, len(query.Result), 2)
|
||||
|
||||
@@ -12,10 +12,14 @@ type SQLStoreMock struct {
|
||||
LastGetAlertsQuery *models.GetAlertsQuery
|
||||
LatestUserId int64
|
||||
|
||||
ExpectedUser *models.User
|
||||
ExpectedDatasource *models.DataSource
|
||||
ExpectedAlert *models.Alert
|
||||
ExpectedPluginSetting *models.PluginSetting
|
||||
ExpectedUser *models.User
|
||||
ExpectedDatasource *models.DataSource
|
||||
ExpectedAlert *models.Alert
|
||||
ExpectedPluginSetting *models.PluginSetting
|
||||
ExpectedDashboard *models.Dashboard
|
||||
ExpectedDashboards []*models.Dashboard
|
||||
ExpectedDashboardVersion *models.DashboardVersion
|
||||
ExpectedDashboardAclInfoList []*models.DashboardAclInfoDTO
|
||||
|
||||
ExpectedError error
|
||||
}
|
||||
@@ -73,7 +77,7 @@ func (m *SQLStoreMock) DeleteOrg(ctx context.Context, cmd *models.DeleteOrgComma
|
||||
}
|
||||
|
||||
func (m *SQLStoreMock) GetProvisionedDataByDashboardID(dashboardID int64) (*models.DashboardProvisioning, error) {
|
||||
return nil, m.ExpectedError
|
||||
return &models.DashboardProvisioning{}, m.ExpectedError
|
||||
}
|
||||
|
||||
func (m *SQLStoreMock) GetProvisionedDataByDashboardUID(orgID int64, dashboardUID string) (*models.DashboardProvisioning, error) {
|
||||
@@ -204,6 +208,7 @@ func (m *SQLStoreMock) GetTeamById(ctx context.Context, query *models.GetTeamByI
|
||||
}
|
||||
|
||||
func (m *SQLStoreMock) GetTeamsByUser(ctx context.Context, query *models.GetTeamsByUserQuery) error {
|
||||
query.Result = []*models.TeamDTO{}
|
||||
return m.ExpectedError
|
||||
}
|
||||
|
||||
@@ -236,6 +241,7 @@ func (m *SQLStoreMock) WithDbSession(ctx context.Context, callback sqlstore.DBTr
|
||||
}
|
||||
|
||||
func (m *SQLStoreMock) GetPreferencesWithDefaults(ctx context.Context, query *models.GetPreferencesWithDefaultsQuery) error {
|
||||
query.Result = &models.Preferences{}
|
||||
return m.ExpectedError
|
||||
}
|
||||
|
||||
@@ -265,6 +271,7 @@ func (m *SQLStoreMock) UpdatePluginSettingVersion(ctx context.Context, cmd *mode
|
||||
}
|
||||
|
||||
func (m *SQLStoreMock) IsStarredByUserCtx(ctx context.Context, query *models.IsStarredByUserQuery) error {
|
||||
query.Result = false
|
||||
return m.ExpectedError
|
||||
}
|
||||
|
||||
@@ -317,6 +324,7 @@ func (m *SQLStoreMock) InTransaction(ctx context.Context, fn func(ctx context.Co
|
||||
}
|
||||
|
||||
func (m *SQLStoreMock) GetDashboardVersion(ctx context.Context, query *models.GetDashboardVersionQuery) error {
|
||||
query.Result = m.ExpectedDashboardVersion
|
||||
return m.ExpectedError
|
||||
}
|
||||
|
||||
@@ -337,6 +345,7 @@ func (m *SQLStoreMock) UpdateDashboardACLCtx(ctx context.Context, dashboardID in
|
||||
}
|
||||
|
||||
func (m *SQLStoreMock) GetDashboardAclInfoList(ctx context.Context, query *models.GetDashboardAclInfoListQuery) error {
|
||||
query.Result = m.ExpectedDashboardAclInfoList
|
||||
return m.ExpectedError
|
||||
}
|
||||
|
||||
@@ -423,9 +432,14 @@ func (m *SQLStoreMock) SaveDashboard(cmd models.SaveDashboardCommand) (*models.D
|
||||
}
|
||||
|
||||
func (m *SQLStoreMock) GetDashboard(ctx context.Context, query *models.GetDashboardQuery) error {
|
||||
query.Result = m.ExpectedDashboard
|
||||
return m.ExpectedError
|
||||
}
|
||||
|
||||
func (m *SQLStoreMock) GetDashboardTags(ctx context.Context, query *models.GetDashboardTagsQuery) error {
|
||||
return nil // TODO: Implement
|
||||
}
|
||||
|
||||
func (m *SQLStoreMock) GetFolderByTitle(orgID int64, title string) (*models.Dashboard, error) {
|
||||
return nil, m.ExpectedError
|
||||
}
|
||||
@@ -435,6 +449,8 @@ func (m *SQLStoreMock) SearchDashboards(ctx context.Context, query *search.FindP
|
||||
}
|
||||
|
||||
func (m *SQLStoreMock) DeleteDashboard(ctx context.Context, cmd *models.DeleteDashboardCommand) error {
|
||||
cmd.Id = m.ExpectedDashboard.Id
|
||||
cmd.OrgId = m.ExpectedDashboard.OrgId
|
||||
return m.ExpectedError
|
||||
}
|
||||
|
||||
|
||||
@@ -106,6 +106,7 @@ type Store interface {
|
||||
RemoveOrgUser(ctx context.Context, cmd *models.RemoveOrgUserCommand) error
|
||||
SaveDashboard(cmd models.SaveDashboardCommand) (*models.Dashboard, error)
|
||||
GetDashboard(ctx context.Context, query *models.GetDashboardQuery) error
|
||||
GetDashboardTags(ctx context.Context, query *models.GetDashboardTagsQuery) error
|
||||
GetFolderByTitle(orgID int64, title string) (*models.Dashboard, error)
|
||||
SearchDashboards(ctx context.Context, query *search.FindPersistedDashboardsQuery) error
|
||||
DeleteDashboard(ctx context.Context, cmd *models.DeleteDashboardCommand) error
|
||||
|
||||
Reference in New Issue
Block a user