PanelLibrary: Adds library panel meta information to dashboard json (#30770)

This commit is contained in:
Hugo Häggmark 2021-02-02 06:25:35 +01:00 committed by GitHub
parent 07e7f47d62
commit 179f35a537
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 368 additions and 70 deletions

View File

@ -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),
}, },

View File

@ -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,
},
},
}) })
} }

View File

@ -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,

View File

@ -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"`