mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
PanelLibrary: Adds library panel meta information to dashboard json (#30770)
This commit is contained in:
parent
07e7f47d62
commit
179f35a537
@ -12,6 +12,21 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/util"
|
"github.com/grafana/grafana/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
sqlStatmentLibrayPanelDTOWithMeta = `
|
||||||
|
SELECT lp.id, lp.org_id, lp.folder_id, lp.uid, lp.name, lp.model, lp.created, lp.created_by, lp.updated, lp.updated_by
|
||||||
|
, 0 AS can_edit
|
||||||
|
, u1.login AS created_by_name
|
||||||
|
, u1.email AS created_by_email
|
||||||
|
, u2.login AS updated_by_name
|
||||||
|
, u2.email AS updated_by_email
|
||||||
|
, (SELECT COUNT(dashboard_id) FROM library_panel_dashboard WHERE librarypanel_id = lp.id) AS connected_dashboards
|
||||||
|
FROM library_panel AS lp
|
||||||
|
LEFT JOIN user AS u1 ON lp.created_by = u1.id
|
||||||
|
LEFT JOIN user AS u2 ON lp.updated_by = u2.id
|
||||||
|
`
|
||||||
|
)
|
||||||
|
|
||||||
// createLibraryPanel adds a Library Panel.
|
// createLibraryPanel adds a Library Panel.
|
||||||
func (lps *LibraryPanelService) createLibraryPanel(c *models.ReqContext, cmd createLibraryPanelCommand) (LibraryPanelDTO, error) {
|
func (lps *LibraryPanelService) createLibraryPanel(c *models.ReqContext, cmd createLibraryPanelCommand) (LibraryPanelDTO, error) {
|
||||||
libraryPanel := LibraryPanel{
|
libraryPanel := LibraryPanel{
|
||||||
@ -45,9 +60,10 @@ func (lps *LibraryPanelService) createLibraryPanel(c *models.ReqContext, cmd cre
|
|||||||
Name: libraryPanel.Name,
|
Name: libraryPanel.Name,
|
||||||
Model: libraryPanel.Model,
|
Model: libraryPanel.Model,
|
||||||
Meta: LibraryPanelDTOMeta{
|
Meta: LibraryPanelDTOMeta{
|
||||||
CanEdit: true,
|
CanEdit: true,
|
||||||
Created: libraryPanel.Created,
|
ConnectedDashboards: 0,
|
||||||
Updated: libraryPanel.Updated,
|
Created: libraryPanel.Created,
|
||||||
|
Updated: libraryPanel.Updated,
|
||||||
CreatedBy: LibraryPanelDTOMetaUser{
|
CreatedBy: LibraryPanelDTOMetaUser{
|
||||||
ID: libraryPanel.CreatedBy,
|
ID: libraryPanel.CreatedBy,
|
||||||
Name: c.SignedInUser.Login,
|
Name: c.SignedInUser.Login,
|
||||||
@ -179,18 +195,7 @@ func (lps *LibraryPanelService) disconnectLibraryPanelsForDashboard(dashboardID
|
|||||||
|
|
||||||
func getLibraryPanel(session *sqlstore.DBSession, uid string, orgID int64) (LibraryPanelWithMeta, error) {
|
func getLibraryPanel(session *sqlstore.DBSession, uid string, orgID int64) (LibraryPanelWithMeta, error) {
|
||||||
libraryPanels := make([]LibraryPanelWithMeta, 0)
|
libraryPanels := make([]LibraryPanelWithMeta, 0)
|
||||||
sql := `SELECT
|
sql := sqlStatmentLibrayPanelDTOWithMeta + "WHERE lp.uid=? AND lp.org_id=?"
|
||||||
lp.id, lp.org_id, lp.folder_id, lp.uid, lp.name, lp.model, lp.created, lp.created_by, lp.updated, lp.updated_by
|
|
||||||
, 0 AS can_edit
|
|
||||||
, u1.login AS created_by_name
|
|
||||||
, u1.email AS created_by_email
|
|
||||||
, u2.login AS updated_by_name
|
|
||||||
, u2.email AS updated_by_email
|
|
||||||
FROM library_panel AS lp
|
|
||||||
LEFT JOIN user AS u1 ON lp.created_by = u1.id
|
|
||||||
LEFT JOIN user AS u2 ON lp.updated_by = u2.id
|
|
||||||
WHERE lp.uid=? AND lp.org_id=?`
|
|
||||||
|
|
||||||
sess := session.SQL(sql, uid, orgID)
|
sess := session.SQL(sql, uid, orgID)
|
||||||
err := sess.Find(&libraryPanels)
|
err := sess.Find(&libraryPanels)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -223,9 +228,10 @@ func (lps *LibraryPanelService) getLibraryPanel(c *models.ReqContext, uid string
|
|||||||
Name: libraryPanel.Name,
|
Name: libraryPanel.Name,
|
||||||
Model: libraryPanel.Model,
|
Model: libraryPanel.Model,
|
||||||
Meta: LibraryPanelDTOMeta{
|
Meta: LibraryPanelDTOMeta{
|
||||||
CanEdit: true,
|
CanEdit: true,
|
||||||
Created: libraryPanel.Created,
|
ConnectedDashboards: libraryPanel.ConnectedDashboards,
|
||||||
Updated: libraryPanel.Updated,
|
Created: libraryPanel.Created,
|
||||||
|
Updated: libraryPanel.Updated,
|
||||||
CreatedBy: LibraryPanelDTOMetaUser{
|
CreatedBy: LibraryPanelDTOMetaUser{
|
||||||
ID: libraryPanel.CreatedBy,
|
ID: libraryPanel.CreatedBy,
|
||||||
Name: libraryPanel.CreatedByName,
|
Name: libraryPanel.CreatedByName,
|
||||||
@ -247,18 +253,7 @@ func (lps *LibraryPanelService) getAllLibraryPanels(c *models.ReqContext) ([]Lib
|
|||||||
orgID := c.SignedInUser.OrgId
|
orgID := c.SignedInUser.OrgId
|
||||||
libraryPanels := make([]LibraryPanelWithMeta, 0)
|
libraryPanels := make([]LibraryPanelWithMeta, 0)
|
||||||
err := lps.SQLStore.WithDbSession(context.Background(), func(session *sqlstore.DBSession) error {
|
err := lps.SQLStore.WithDbSession(context.Background(), func(session *sqlstore.DBSession) error {
|
||||||
sql := `SELECT
|
sql := sqlStatmentLibrayPanelDTOWithMeta + "WHERE lp.org_id=?"
|
||||||
lp.id, lp.org_id, lp.folder_id, lp.uid, lp.name, lp.model, lp.created, lp.created_by, lp.updated, lp.updated_by
|
|
||||||
, 0 AS can_edit
|
|
||||||
, u1.login AS created_by_name
|
|
||||||
, u1.email AS created_by_email
|
|
||||||
, u2.login AS updated_by_name
|
|
||||||
, u2.email AS updated_by_email
|
|
||||||
FROM library_panel AS lp
|
|
||||||
LEFT JOIN user AS u1 ON lp.created_by = u1.id
|
|
||||||
LEFT JOIN user AS u2 ON lp.updated_by = u2.id
|
|
||||||
WHERE lp.org_id=?`
|
|
||||||
|
|
||||||
sess := session.SQL(sql, orgID)
|
sess := session.SQL(sql, orgID)
|
||||||
err := sess.Find(&libraryPanels)
|
err := sess.Find(&libraryPanels)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -278,9 +273,10 @@ func (lps *LibraryPanelService) getAllLibraryPanels(c *models.ReqContext) ([]Lib
|
|||||||
Name: panel.Name,
|
Name: panel.Name,
|
||||||
Model: panel.Model,
|
Model: panel.Model,
|
||||||
Meta: LibraryPanelDTOMeta{
|
Meta: LibraryPanelDTOMeta{
|
||||||
CanEdit: true,
|
CanEdit: true,
|
||||||
Created: panel.Created,
|
ConnectedDashboards: panel.ConnectedDashboards,
|
||||||
Updated: panel.Updated,
|
Created: panel.Created,
|
||||||
|
Updated: panel.Updated,
|
||||||
CreatedBy: LibraryPanelDTOMetaUser{
|
CreatedBy: LibraryPanelDTOMetaUser{
|
||||||
ID: panel.CreatedBy,
|
ID: panel.CreatedBy,
|
||||||
Name: panel.CreatedByName,
|
Name: panel.CreatedByName,
|
||||||
@ -325,17 +321,11 @@ func (lps *LibraryPanelService) getConnectedDashboards(c *models.ReqContext, uid
|
|||||||
return connectedDashboardIDs, err
|
return connectedDashboardIDs, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lps *LibraryPanelService) getLibraryPanelsForDashboardID(dashboardID int64) (map[string]LibraryPanel, error) {
|
func (lps *LibraryPanelService) getLibraryPanelsForDashboardID(dashboardID int64) (map[string]LibraryPanelDTO, error) {
|
||||||
libraryPanelMap := make(map[string]LibraryPanel)
|
libraryPanelMap := make(map[string]LibraryPanelDTO)
|
||||||
err := lps.SQLStore.WithDbSession(context.Background(), func(session *sqlstore.DBSession) error {
|
err := lps.SQLStore.WithDbSession(context.Background(), func(session *sqlstore.DBSession) error {
|
||||||
sql := `SELECT
|
var libraryPanels []LibraryPanelWithMeta
|
||||||
lp.id, lp.org_id, lp.folder_id, lp.uid, lp.name, lp.model, lp.created, lp.created_by, lp.updated, lp.updated_by
|
sql := sqlStatmentLibrayPanelDTOWithMeta + "INNER JOIN library_panel_dashboard AS lpd ON lpd.librarypanel_id = lp.id AND lpd.dashboard_id=?"
|
||||||
FROM
|
|
||||||
library_panel_dashboard AS lpd
|
|
||||||
INNER JOIN
|
|
||||||
library_panel AS lp ON lpd.librarypanel_id = lp.id AND lpd.dashboard_id=?`
|
|
||||||
|
|
||||||
var libraryPanels []LibraryPanel
|
|
||||||
sess := session.SQL(sql, dashboardID)
|
sess := session.SQL(sql, dashboardID)
|
||||||
err := sess.Find(&libraryPanels)
|
err := sess.Find(&libraryPanels)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -343,7 +333,30 @@ func (lps *LibraryPanelService) getLibraryPanelsForDashboardID(dashboardID int64
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, panel := range libraryPanels {
|
for _, panel := range libraryPanels {
|
||||||
libraryPanelMap[panel.UID] = panel
|
libraryPanelMap[panel.UID] = LibraryPanelDTO{
|
||||||
|
ID: panel.ID,
|
||||||
|
OrgID: panel.OrgID,
|
||||||
|
FolderID: panel.FolderID,
|
||||||
|
UID: panel.UID,
|
||||||
|
Name: panel.Name,
|
||||||
|
Model: panel.Model,
|
||||||
|
Meta: LibraryPanelDTOMeta{
|
||||||
|
CanEdit: panel.CanEdit,
|
||||||
|
ConnectedDashboards: panel.ConnectedDashboards,
|
||||||
|
Created: panel.Created,
|
||||||
|
Updated: panel.Updated,
|
||||||
|
CreatedBy: LibraryPanelDTOMetaUser{
|
||||||
|
ID: panel.CreatedBy,
|
||||||
|
Name: panel.CreatedByName,
|
||||||
|
AvatarUrl: dtos.GetGravatarUrl(panel.CreatedByEmail),
|
||||||
|
},
|
||||||
|
UpdatedBy: LibraryPanelDTOMetaUser{
|
||||||
|
ID: panel.UpdatedBy,
|
||||||
|
Name: panel.UpdatedByName,
|
||||||
|
AvatarUrl: dtos.GetGravatarUrl(panel.UpdatedByEmail),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -401,11 +414,12 @@ func (lps *LibraryPanelService) patchLibraryPanel(c *models.ReqContext, cmd patc
|
|||||||
Name: libraryPanel.Name,
|
Name: libraryPanel.Name,
|
||||||
Model: libraryPanel.Model,
|
Model: libraryPanel.Model,
|
||||||
Meta: LibraryPanelDTOMeta{
|
Meta: LibraryPanelDTOMeta{
|
||||||
CanEdit: true,
|
CanEdit: true,
|
||||||
Created: libraryPanel.Created,
|
ConnectedDashboards: panelInDB.ConnectedDashboards,
|
||||||
Updated: libraryPanel.Updated,
|
Created: libraryPanel.Created,
|
||||||
|
Updated: libraryPanel.Updated,
|
||||||
CreatedBy: LibraryPanelDTOMetaUser{
|
CreatedBy: LibraryPanelDTOMetaUser{
|
||||||
ID: libraryPanel.CreatedBy,
|
ID: panelInDB.CreatedBy,
|
||||||
Name: panelInDB.CreatedByName,
|
Name: panelInDB.CreatedByName,
|
||||||
AvatarUrl: dtos.GetGravatarUrl(panelInDB.CreatedByEmail),
|
AvatarUrl: dtos.GetGravatarUrl(panelInDB.CreatedByEmail),
|
||||||
},
|
},
|
||||||
|
@ -104,6 +104,22 @@ func (lps *LibraryPanelService) LoadLibraryPanelsForDashboard(dash *models.Dashb
|
|||||||
elem.Set("libraryPanel", map[string]interface{}{
|
elem.Set("libraryPanel", map[string]interface{}{
|
||||||
"uid": libraryPanelInDB.UID,
|
"uid": libraryPanelInDB.UID,
|
||||||
"name": libraryPanelInDB.Name,
|
"name": libraryPanelInDB.Name,
|
||||||
|
"meta": map[string]interface{}{
|
||||||
|
"canEdit": libraryPanelInDB.Meta.CanEdit,
|
||||||
|
"connectedDashboards": libraryPanelInDB.Meta.ConnectedDashboards,
|
||||||
|
"created": libraryPanelInDB.Meta.Created,
|
||||||
|
"updated": libraryPanelInDB.Meta.Updated,
|
||||||
|
"createdBy": map[string]interface{}{
|
||||||
|
"id": libraryPanelInDB.Meta.CreatedBy.ID,
|
||||||
|
"name": libraryPanelInDB.Meta.CreatedBy.Name,
|
||||||
|
"avatarUrl": libraryPanelInDB.Meta.CreatedBy.AvatarUrl,
|
||||||
|
},
|
||||||
|
"updatedBy": map[string]interface{}{
|
||||||
|
"id": libraryPanelInDB.Meta.UpdatedBy.ID,
|
||||||
|
"name": libraryPanelInDB.Meta.UpdatedBy.Name,
|
||||||
|
"avatarUrl": libraryPanelInDB.Meta.UpdatedBy.AvatarUrl,
|
||||||
|
},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
package librarypanels
|
package librarypanels
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
|
||||||
|
|
||||||
"github.com/google/go-cmp/cmp"
|
"github.com/google/go-cmp/cmp"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"gopkg.in/macaron.v1"
|
"gopkg.in/macaron.v1"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||||
"github.com/grafana/grafana/pkg/models"
|
"github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/registry"
|
"github.com/grafana/grafana/pkg/registry"
|
||||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||||
@ -28,6 +28,51 @@ func TestCreateLibraryPanel(t *testing.T) {
|
|||||||
response = sc.service.createHandler(sc.reqContext, command)
|
response = sc.service.createHandler(sc.reqContext, command)
|
||||||
require.Equal(t, 400, response.Status())
|
require.Equal(t, 400, response.Status())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
testScenario(t, "When an admin tries to create a library panel that does not exists, it should succeed",
|
||||||
|
func(t *testing.T, sc scenarioContext) {
|
||||||
|
command := getCreateCommand(1, "Text - Library Panel")
|
||||||
|
response := sc.service.createHandler(sc.reqContext, command)
|
||||||
|
require.Equal(t, 200, response.Status())
|
||||||
|
|
||||||
|
var result libraryPanelResult
|
||||||
|
err := json.Unmarshal(response.Body(), &result)
|
||||||
|
require.NoError(t, err)
|
||||||
|
var expected = libraryPanelResult{
|
||||||
|
Result: libraryPanel{
|
||||||
|
ID: 1,
|
||||||
|
OrgID: 1,
|
||||||
|
FolderID: 1,
|
||||||
|
UID: result.Result.UID,
|
||||||
|
Name: "Text - Library Panel",
|
||||||
|
Model: map[string]interface{}{
|
||||||
|
"datasource": "${DS_GDEV-TESTDATA}",
|
||||||
|
"id": float64(1),
|
||||||
|
"title": "Text - Library Panel",
|
||||||
|
"type": "text",
|
||||||
|
},
|
||||||
|
Meta: LibraryPanelDTOMeta{
|
||||||
|
CanEdit: true,
|
||||||
|
ConnectedDashboards: 0,
|
||||||
|
Created: result.Result.Meta.Created,
|
||||||
|
Updated: result.Result.Meta.Updated,
|
||||||
|
CreatedBy: LibraryPanelDTOMetaUser{
|
||||||
|
ID: 1,
|
||||||
|
Name: "signed_in_user",
|
||||||
|
AvatarUrl: "/avatar/37524e1eb8b3e32850b57db0a19af93b",
|
||||||
|
},
|
||||||
|
UpdatedBy: LibraryPanelDTOMetaUser{
|
||||||
|
ID: 1,
|
||||||
|
Name: "signed_in_user",
|
||||||
|
AvatarUrl: "/avatar/37524e1eb8b3e32850b57db0a19af93b",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if diff := cmp.Diff(expected, result, getCompareOptions()...); diff != "" {
|
||||||
|
t.Fatalf("Result mismatch (-want +got):\n%s", diff)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConnectLibraryPanel(t *testing.T) {
|
func TestConnectLibraryPanel(t *testing.T) {
|
||||||
@ -161,8 +206,40 @@ func TestGetLibraryPanel(t *testing.T) {
|
|||||||
require.Equal(t, 200, response.Status())
|
require.Equal(t, 200, response.Status())
|
||||||
err = json.Unmarshal(response.Body(), &result)
|
err = json.Unmarshal(response.Body(), &result)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, int64(1), result.Result.FolderID)
|
var expected = libraryPanelResult{
|
||||||
require.Equal(t, "Text - Library Panel", result.Result.Name)
|
Result: libraryPanel{
|
||||||
|
ID: 1,
|
||||||
|
OrgID: 1,
|
||||||
|
FolderID: 1,
|
||||||
|
UID: result.Result.UID,
|
||||||
|
Name: "Text - Library Panel",
|
||||||
|
Model: map[string]interface{}{
|
||||||
|
"datasource": "${DS_GDEV-TESTDATA}",
|
||||||
|
"id": float64(1),
|
||||||
|
"title": "Text - Library Panel",
|
||||||
|
"type": "text",
|
||||||
|
},
|
||||||
|
Meta: LibraryPanelDTOMeta{
|
||||||
|
CanEdit: true,
|
||||||
|
ConnectedDashboards: 0,
|
||||||
|
Created: result.Result.Meta.Created,
|
||||||
|
Updated: result.Result.Meta.Updated,
|
||||||
|
CreatedBy: LibraryPanelDTOMetaUser{
|
||||||
|
ID: 1,
|
||||||
|
Name: "user_in_db",
|
||||||
|
AvatarUrl: "/avatar/402d08de060496d6b6874495fe20f5ad",
|
||||||
|
},
|
||||||
|
UpdatedBy: LibraryPanelDTOMetaUser{
|
||||||
|
ID: 1,
|
||||||
|
Name: "user_in_db",
|
||||||
|
AvatarUrl: "/avatar/402d08de060496d6b6874495fe20f5ad",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if diff := cmp.Diff(expected, result, getCompareOptions()...); diff != "" {
|
||||||
|
t.Fatalf("Result mismatch (-want +got):\n%s", diff)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
testScenario(t, "When an admin tries to get a library panel that exists in an other org, it should fail",
|
testScenario(t, "When an admin tries to get a library panel that exists in an other org, it should fail",
|
||||||
@ -181,6 +258,31 @@ func TestGetLibraryPanel(t *testing.T) {
|
|||||||
response = sc.service.getHandler(sc.reqContext)
|
response = sc.service.getHandler(sc.reqContext)
|
||||||
require.Equal(t, 404, response.Status())
|
require.Equal(t, 404, response.Status())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
testScenario(t, "When an admin tries to get a library panel with 2 connected dashboards, it should succeed and return correct connected dashboards",
|
||||||
|
func(t *testing.T, sc scenarioContext) {
|
||||||
|
command := getCreateCommand(1, "Text - Library Panel")
|
||||||
|
response := sc.service.createHandler(sc.reqContext, command)
|
||||||
|
require.Equal(t, 200, response.Status())
|
||||||
|
|
||||||
|
var result libraryPanelResult
|
||||||
|
err := json.Unmarshal(response.Body(), &result)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
sc.reqContext.ReplaceAllParams(map[string]string{":uid": result.Result.UID, ":dashboardId": "1"})
|
||||||
|
response = sc.service.connectHandler(sc.reqContext)
|
||||||
|
require.Equal(t, 200, response.Status())
|
||||||
|
sc.reqContext.ReplaceAllParams(map[string]string{":uid": result.Result.UID, ":dashboardId": "2"})
|
||||||
|
response = sc.service.connectHandler(sc.reqContext)
|
||||||
|
require.Equal(t, 200, response.Status())
|
||||||
|
|
||||||
|
sc.reqContext.ReplaceAllParams(map[string]string{":uid": result.Result.UID})
|
||||||
|
response = sc.service.getHandler(sc.reqContext)
|
||||||
|
require.Equal(t, 200, response.Status())
|
||||||
|
err = json.Unmarshal(response.Body(), &result)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, int64(2), result.Result.Meta.ConnectedDashboards)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetAllLibraryPanels(t *testing.T) {
|
func TestGetAllLibraryPanels(t *testing.T) {
|
||||||
@ -196,7 +298,7 @@ func TestGetAllLibraryPanels(t *testing.T) {
|
|||||||
require.Equal(t, 0, len(result.Result))
|
require.Equal(t, 0, len(result.Result))
|
||||||
})
|
})
|
||||||
|
|
||||||
testScenario(t, "When an admin tries to get all library panels and two exist, it should work",
|
testScenario(t, "When an admin tries to get all library panels and two exist, it should succeed",
|
||||||
func(t *testing.T, sc scenarioContext) {
|
func(t *testing.T, sc scenarioContext) {
|
||||||
command := getCreateCommand(1, "Text - Library Panel")
|
command := getCreateCommand(1, "Text - Library Panel")
|
||||||
response := sc.service.createHandler(sc.reqContext, command)
|
response := sc.service.createHandler(sc.reqContext, command)
|
||||||
@ -212,11 +314,102 @@ func TestGetAllLibraryPanels(t *testing.T) {
|
|||||||
var result libraryPanelsResult
|
var result libraryPanelsResult
|
||||||
err := json.Unmarshal(response.Body(), &result)
|
err := json.Unmarshal(response.Body(), &result)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, 2, len(result.Result))
|
var expected = libraryPanelsResult{
|
||||||
require.Equal(t, int64(1), result.Result[0].FolderID)
|
Result: []libraryPanel{
|
||||||
require.Equal(t, "Text - Library Panel", result.Result[0].Name)
|
{
|
||||||
require.Equal(t, int64(1), result.Result[1].FolderID)
|
ID: 1,
|
||||||
require.Equal(t, "Text - Library Panel2", result.Result[1].Name)
|
OrgID: 1,
|
||||||
|
FolderID: 1,
|
||||||
|
UID: result.Result[0].UID,
|
||||||
|
Name: "Text - Library Panel",
|
||||||
|
Model: map[string]interface{}{
|
||||||
|
"datasource": "${DS_GDEV-TESTDATA}",
|
||||||
|
"id": float64(1),
|
||||||
|
"title": "Text - Library Panel",
|
||||||
|
"type": "text",
|
||||||
|
},
|
||||||
|
Meta: LibraryPanelDTOMeta{
|
||||||
|
CanEdit: true,
|
||||||
|
ConnectedDashboards: 0,
|
||||||
|
Created: result.Result[0].Meta.Created,
|
||||||
|
Updated: result.Result[0].Meta.Updated,
|
||||||
|
CreatedBy: LibraryPanelDTOMetaUser{
|
||||||
|
ID: 1,
|
||||||
|
Name: "user_in_db",
|
||||||
|
AvatarUrl: "/avatar/402d08de060496d6b6874495fe20f5ad",
|
||||||
|
},
|
||||||
|
UpdatedBy: LibraryPanelDTOMetaUser{
|
||||||
|
ID: 1,
|
||||||
|
Name: "user_in_db",
|
||||||
|
AvatarUrl: "/avatar/402d08de060496d6b6874495fe20f5ad",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: 2,
|
||||||
|
OrgID: 1,
|
||||||
|
FolderID: 1,
|
||||||
|
UID: result.Result[1].UID,
|
||||||
|
Name: "Text - Library Panel2",
|
||||||
|
Model: map[string]interface{}{
|
||||||
|
"datasource": "${DS_GDEV-TESTDATA}",
|
||||||
|
"id": float64(1),
|
||||||
|
"title": "Text - Library Panel",
|
||||||
|
"type": "text",
|
||||||
|
},
|
||||||
|
Meta: LibraryPanelDTOMeta{
|
||||||
|
CanEdit: true,
|
||||||
|
ConnectedDashboards: 0,
|
||||||
|
Created: result.Result[1].Meta.Created,
|
||||||
|
Updated: result.Result[1].Meta.Updated,
|
||||||
|
CreatedBy: LibraryPanelDTOMetaUser{
|
||||||
|
ID: 1,
|
||||||
|
Name: "user_in_db",
|
||||||
|
AvatarUrl: "/avatar/402d08de060496d6b6874495fe20f5ad",
|
||||||
|
},
|
||||||
|
UpdatedBy: LibraryPanelDTOMetaUser{
|
||||||
|
ID: 1,
|
||||||
|
Name: "user_in_db",
|
||||||
|
AvatarUrl: "/avatar/402d08de060496d6b6874495fe20f5ad",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if diff := cmp.Diff(expected, result, getCompareOptions()...); diff != "" {
|
||||||
|
t.Fatalf("Result mismatch (-want +got):\n%s", diff)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
testScenario(t, "When an admin tries to get all library panels and two exist but only one is connected, it should succeed and return correct connected dashboards",
|
||||||
|
func(t *testing.T, sc scenarioContext) {
|
||||||
|
command := getCreateCommand(1, "Text - Library Panel")
|
||||||
|
response := sc.service.createHandler(sc.reqContext, command)
|
||||||
|
require.Equal(t, 200, response.Status())
|
||||||
|
|
||||||
|
command = getCreateCommand(1, "Text - Library Panel2")
|
||||||
|
response = sc.service.createHandler(sc.reqContext, command)
|
||||||
|
require.Equal(t, 200, response.Status())
|
||||||
|
|
||||||
|
var result libraryPanelResult
|
||||||
|
err := json.Unmarshal(response.Body(), &result)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
sc.reqContext.ReplaceAllParams(map[string]string{":uid": result.Result.UID, ":dashboardId": "1"})
|
||||||
|
response = sc.service.connectHandler(sc.reqContext)
|
||||||
|
require.Equal(t, 200, response.Status())
|
||||||
|
sc.reqContext.ReplaceAllParams(map[string]string{":uid": result.Result.UID, ":dashboardId": "2"})
|
||||||
|
response = sc.service.connectHandler(sc.reqContext)
|
||||||
|
require.Equal(t, 200, response.Status())
|
||||||
|
|
||||||
|
response = sc.service.getAllHandler(sc.reqContext)
|
||||||
|
require.Equal(t, 200, response.Status())
|
||||||
|
|
||||||
|
var results libraryPanelsResult
|
||||||
|
err = json.Unmarshal(response.Body(), &results)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, int64(0), results.Result[0].Meta.ConnectedDashboards)
|
||||||
|
require.Equal(t, int64(2), results.Result[1].Meta.ConnectedDashboards)
|
||||||
})
|
})
|
||||||
|
|
||||||
testScenario(t, "When an admin tries to get all library panels in a different org, none should be returned",
|
testScenario(t, "When an admin tries to get all library panels in a different org, none should be returned",
|
||||||
@ -326,6 +519,13 @@ func TestPatchLibraryPanel(t *testing.T) {
|
|||||||
err := json.Unmarshal(response.Body(), &existing)
|
err := json.Unmarshal(response.Body(), &existing)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
sc.reqContext.ReplaceAllParams(map[string]string{":uid": existing.Result.UID, ":dashboardId": "1"})
|
||||||
|
response = sc.service.connectHandler(sc.reqContext)
|
||||||
|
require.Equal(t, 200, response.Status())
|
||||||
|
sc.reqContext.ReplaceAllParams(map[string]string{":uid": existing.Result.UID, ":dashboardId": "2"})
|
||||||
|
response = sc.service.connectHandler(sc.reqContext)
|
||||||
|
require.Equal(t, 200, response.Status())
|
||||||
|
|
||||||
cmd := patchLibraryPanelCommand{
|
cmd := patchLibraryPanelCommand{
|
||||||
FolderID: 2,
|
FolderID: 2,
|
||||||
Name: "Panel - New name",
|
Name: "Panel - New name",
|
||||||
@ -345,10 +545,38 @@ func TestPatchLibraryPanel(t *testing.T) {
|
|||||||
var result libraryPanelResult
|
var result libraryPanelResult
|
||||||
err = json.Unmarshal(response.Body(), &result)
|
err = json.Unmarshal(response.Body(), &result)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
existing.Result.FolderID = int64(2)
|
var expected = libraryPanelResult{
|
||||||
existing.Result.Name = "Panel - New name"
|
Result: libraryPanel{
|
||||||
existing.Result.Model["title"] = "Model - New name"
|
ID: 1,
|
||||||
if diff := cmp.Diff(existing.Result, result.Result, getCompareOptions()...); diff != "" {
|
OrgID: 1,
|
||||||
|
FolderID: 2,
|
||||||
|
UID: existing.Result.UID,
|
||||||
|
Name: "Panel - New name",
|
||||||
|
Model: map[string]interface{}{
|
||||||
|
"datasource": "${DS_GDEV-TESTDATA}",
|
||||||
|
"id": float64(1),
|
||||||
|
"title": "Model - New name",
|
||||||
|
"type": "text",
|
||||||
|
},
|
||||||
|
Meta: LibraryPanelDTOMeta{
|
||||||
|
CanEdit: true,
|
||||||
|
ConnectedDashboards: 2,
|
||||||
|
Created: existing.Result.Meta.Created,
|
||||||
|
Updated: result.Result.Meta.Updated,
|
||||||
|
CreatedBy: LibraryPanelDTOMetaUser{
|
||||||
|
ID: 1,
|
||||||
|
Name: "user_in_db",
|
||||||
|
AvatarUrl: "/avatar/402d08de060496d6b6874495fe20f5ad",
|
||||||
|
},
|
||||||
|
UpdatedBy: LibraryPanelDTOMetaUser{
|
||||||
|
ID: 1,
|
||||||
|
Name: "signed_in_user",
|
||||||
|
AvatarUrl: "/avatar/37524e1eb8b3e32850b57db0a19af93b",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if diff := cmp.Diff(expected, result, getCompareOptions()...); diff != "" {
|
||||||
t.Fatalf("Result mismatch (-want +got):\n%s", diff)
|
t.Fatalf("Result mismatch (-want +got):\n%s", diff)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -374,6 +602,8 @@ func TestPatchLibraryPanel(t *testing.T) {
|
|||||||
err = json.Unmarshal(response.Body(), &result)
|
err = json.Unmarshal(response.Body(), &result)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
existing.Result.FolderID = int64(100)
|
existing.Result.FolderID = int64(100)
|
||||||
|
existing.Result.Meta.CreatedBy.Name = "user_in_db"
|
||||||
|
existing.Result.Meta.CreatedBy.AvatarUrl = "/avatar/402d08de060496d6b6874495fe20f5ad"
|
||||||
if diff := cmp.Diff(existing.Result, result.Result, getCompareOptions()...); diff != "" {
|
if diff := cmp.Diff(existing.Result, result.Result, getCompareOptions()...); diff != "" {
|
||||||
t.Fatalf("Result mismatch (-want +got):\n%s", diff)
|
t.Fatalf("Result mismatch (-want +got):\n%s", diff)
|
||||||
}
|
}
|
||||||
@ -399,6 +629,8 @@ func TestPatchLibraryPanel(t *testing.T) {
|
|||||||
err = json.Unmarshal(response.Body(), &result)
|
err = json.Unmarshal(response.Body(), &result)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
existing.Result.Name = "New Name"
|
existing.Result.Name = "New Name"
|
||||||
|
existing.Result.Meta.CreatedBy.Name = "user_in_db"
|
||||||
|
existing.Result.Meta.CreatedBy.AvatarUrl = "/avatar/402d08de060496d6b6874495fe20f5ad"
|
||||||
if diff := cmp.Diff(existing.Result, result.Result, getCompareOptions()...); diff != "" {
|
if diff := cmp.Diff(existing.Result, result.Result, getCompareOptions()...); diff != "" {
|
||||||
t.Fatalf("Result mismatch (-want +got):\n%s", diff)
|
t.Fatalf("Result mismatch (-want +got):\n%s", diff)
|
||||||
}
|
}
|
||||||
@ -426,6 +658,8 @@ func TestPatchLibraryPanel(t *testing.T) {
|
|||||||
existing.Result.Model = map[string]interface{}{
|
existing.Result.Model = map[string]interface{}{
|
||||||
"name": "New Model Name",
|
"name": "New Model Name",
|
||||||
}
|
}
|
||||||
|
existing.Result.Meta.CreatedBy.Name = "user_in_db"
|
||||||
|
existing.Result.Meta.CreatedBy.AvatarUrl = "/avatar/402d08de060496d6b6874495fe20f5ad"
|
||||||
if diff := cmp.Diff(existing.Result, result.Result, getCompareOptions()...); diff != "" {
|
if diff := cmp.Diff(existing.Result, result.Result, getCompareOptions()...); diff != "" {
|
||||||
t.Fatalf("Result mismatch (-want +got):\n%s", diff)
|
t.Fatalf("Result mismatch (-want +got):\n%s", diff)
|
||||||
}
|
}
|
||||||
@ -450,6 +684,8 @@ func TestPatchLibraryPanel(t *testing.T) {
|
|||||||
err = json.Unmarshal(response.Body(), &result)
|
err = json.Unmarshal(response.Body(), &result)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
existing.Result.Meta.UpdatedBy.ID = int64(2)
|
existing.Result.Meta.UpdatedBy.ID = int64(2)
|
||||||
|
existing.Result.Meta.CreatedBy.Name = "user_in_db"
|
||||||
|
existing.Result.Meta.CreatedBy.AvatarUrl = "/avatar/402d08de060496d6b6874495fe20f5ad"
|
||||||
if diff := cmp.Diff(existing.Result, result.Result, getCompareOptions()...); diff != "" {
|
if diff := cmp.Diff(existing.Result, result.Result, getCompareOptions()...); diff != "" {
|
||||||
t.Fatalf("Result mismatch (-want +got):\n%s", diff)
|
t.Fatalf("Result mismatch (-want +got):\n%s", diff)
|
||||||
}
|
}
|
||||||
@ -590,6 +826,22 @@ func TestLoadLibraryPanelsForDashboard(t *testing.T) {
|
|||||||
"libraryPanel": map[string]interface{}{
|
"libraryPanel": map[string]interface{}{
|
||||||
"uid": existing.Result.UID,
|
"uid": existing.Result.UID,
|
||||||
"name": existing.Result.Name,
|
"name": existing.Result.Name,
|
||||||
|
"meta": map[string]interface{}{
|
||||||
|
"canEdit": false,
|
||||||
|
"connectedDashboards": int64(1),
|
||||||
|
"created": existing.Result.Meta.Created,
|
||||||
|
"updated": existing.Result.Meta.Updated,
|
||||||
|
"createdBy": map[string]interface{}{
|
||||||
|
"id": existing.Result.Meta.CreatedBy.ID,
|
||||||
|
"name": "user_in_db",
|
||||||
|
"avatarUrl": "/avatar/402d08de060496d6b6874495fe20f5ad",
|
||||||
|
},
|
||||||
|
"updatedBy": map[string]interface{}{
|
||||||
|
"id": existing.Result.Meta.UpdatedBy.ID,
|
||||||
|
"name": "user_in_db",
|
||||||
|
"avatarUrl": "/avatar/402d08de060496d6b6874495fe20f5ad",
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"title": "Text - Library Panel",
|
"title": "Text - Library Panel",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
@ -1214,10 +1466,24 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo
|
|||||||
|
|
||||||
user := models.SignedInUser{
|
user := models.SignedInUser{
|
||||||
UserId: 1,
|
UserId: 1,
|
||||||
|
Name: "Signed In User",
|
||||||
|
Login: "signed_in_user",
|
||||||
|
Email: "signed.in.user@test.com",
|
||||||
OrgId: orgID,
|
OrgId: orgID,
|
||||||
OrgRole: role,
|
OrgRole: role,
|
||||||
LastSeenAt: time.Now(),
|
LastSeenAt: time.Now(),
|
||||||
}
|
}
|
||||||
|
// deliberate difference between signed in user and user in db to make it crystal clear
|
||||||
|
// what to expect in the tests
|
||||||
|
// In the real world these are identical
|
||||||
|
cmd := &models.CreateUserCommand{
|
||||||
|
Email: "user.in.db@test.com",
|
||||||
|
Name: "User In DB",
|
||||||
|
Login: "user_in_db",
|
||||||
|
}
|
||||||
|
err := sqlstore.CreateUser(context.Background(), cmd)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
sc := scenarioContext{
|
sc := scenarioContext{
|
||||||
user: user,
|
user: user,
|
||||||
ctx: &ctx,
|
ctx: &ctx,
|
||||||
|
@ -34,13 +34,14 @@ type LibraryPanelWithMeta struct {
|
|||||||
Created time.Time
|
Created time.Time
|
||||||
Updated time.Time
|
Updated time.Time
|
||||||
|
|
||||||
CanEdit bool
|
CanEdit bool
|
||||||
CreatedBy int64
|
ConnectedDashboards int64
|
||||||
UpdatedBy int64
|
CreatedBy int64
|
||||||
CreatedByName string
|
UpdatedBy int64
|
||||||
CreatedByEmail string
|
CreatedByName string
|
||||||
UpdatedByName string
|
CreatedByEmail string
|
||||||
UpdatedByEmail string
|
UpdatedByName string
|
||||||
|
UpdatedByEmail string
|
||||||
}
|
}
|
||||||
|
|
||||||
// LibraryPanelDTO is the frontend DTO for library panels.
|
// LibraryPanelDTO is the frontend DTO for library panels.
|
||||||
@ -56,7 +57,8 @@ type LibraryPanelDTO struct {
|
|||||||
|
|
||||||
// LibraryPanelDTOMeta is the meta information for LibraryPanelDTO.
|
// LibraryPanelDTOMeta is the meta information for LibraryPanelDTO.
|
||||||
type LibraryPanelDTOMeta struct {
|
type LibraryPanelDTOMeta struct {
|
||||||
CanEdit bool `json:"canEdit"`
|
CanEdit bool `json:"canEdit"`
|
||||||
|
ConnectedDashboards int64 `json:"connectedDashboards"`
|
||||||
|
|
||||||
Created time.Time `json:"created"`
|
Created time.Time `json:"created"`
|
||||||
Updated time.Time `json:"updated"`
|
Updated time.Time `json:"updated"`
|
||||||
|
Loading…
Reference in New Issue
Block a user