The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
grafana/pkg/api/plugin_dashboards_test.go

140 lines
4.4 KiB

package api
import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"testing"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/plugindashboards"
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
"github.com/grafana/grafana/pkg/services/quota/quotatest"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/web/webtest"
)
func TestGetPluginDashboards(t *testing.T) {
const existingPluginID = "existing-plugin"
pluginDashboardService := &pluginDashboardServiceMock{
pluginDashboards: map[string][]*plugindashboards.PluginDashboard{
existingPluginID: {
{
PluginId: existingPluginID,
UID: "a",
Title: "A",
},
{
PluginId: existingPluginID,
UID: "b",
Title: "B",
},
},
},
unexpectedErrors: map[string]error{
"boom": errors.New("BOOM"),
},
}
s := SetupAPITestServer(t, func(hs *HTTPServer) {
hs.pluginDashboardService = pluginDashboardService
hs.QuotaService = quotatest.New(false, nil)
hs.pluginStore = &pluginstore.FakePluginStore{
PluginList: []pluginstore.Plugin{
{JSONData: plugins.JSONData{ID: existingPluginID}},
{JSONData: plugins.JSONData{ID: "boom"}},
},
}
})
t.Run("Not signed in should return 404 Not Found", func(t *testing.T) {
req := s.NewGetRequest("/api/plugins/test/dashboards")
resp, err := s.Send(req)
require.NoError(t, err)
require.NoError(t, resp.Body.Close())
require.Equal(t, http.StatusUnauthorized, resp.StatusCode)
})
t.Run("Signed in and not org admin should return 403 Forbidden", func(t *testing.T) {
user := &user.SignedInUser{
UserID: 1,
OrgRole: org.RoleEditor,
}
resp, err := sendGetPluginDashboardsRequestForSignedInUser(t, s, existingPluginID, user)
require.NoError(t, err)
require.NoError(t, resp.Body.Close())
require.Equal(t, http.StatusForbidden, resp.StatusCode)
})
t.Run("Signed in and org admin", func(t *testing.T) {
user := &user.SignedInUser{
UserID: 1,
OrgID: 1,
OrgRole: org.RoleAdmin,
}
t.Run("When plugin doesn't exist should return 404 Not Found", func(t *testing.T) {
resp, err := sendGetPluginDashboardsRequestForSignedInUser(t, s, "not-exists", user)
require.NoError(t, err)
require.NoError(t, resp.Body.Close())
require.Equal(t, http.StatusNotFound, resp.StatusCode)
})
t.Run("When result is unexpected error should return 500 Internal Server Error", func(t *testing.T) {
resp, err := sendGetPluginDashboardsRequestForSignedInUser(t, s, "boom", user)
require.NoError(t, err)
require.NoError(t, resp.Body.Close())
require.Equal(t, http.StatusInternalServerError, resp.StatusCode)
})
t.Run("When plugin exists should return 200 OK with expected payload", func(t *testing.T) {
resp, err := sendGetPluginDashboardsRequestForSignedInUser(t, s, existingPluginID, user)
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
bytes, err := io.ReadAll(resp.Body)
require.NoError(t, err)
require.NoError(t, resp.Body.Close())
var listResp []*plugindashboards.PluginDashboard
err = json.Unmarshal(bytes, &listResp)
require.NoError(t, err)
require.NotNil(t, listResp)
require.Len(t, listResp, 2)
require.Equal(t, pluginDashboardService.pluginDashboards[existingPluginID], listResp)
})
})
}
func sendGetPluginDashboardsRequestForSignedInUser(t *testing.T, s *webtest.Server, pluginID string, user *user.SignedInUser) (*http.Response, error) {
t.Helper()
req := s.NewGetRequest(fmt.Sprintf("/api/plugins/%s/dashboards", pluginID))
webtest.RequestWithSignedInUser(req, user)
return s.Send(req)
}
type pluginDashboardServiceMock struct {
plugindashboards.Service
pluginDashboards map[string][]*plugindashboards.PluginDashboard
unexpectedErrors map[string]error
}
func (m *pluginDashboardServiceMock) ListPluginDashboards(ctx context.Context, req *plugindashboards.ListPluginDashboardsRequest) (*plugindashboards.ListPluginDashboardsResponse, error) {
if pluginDashboards, exists := m.pluginDashboards[req.PluginID]; exists {
return &plugindashboards.ListPluginDashboardsResponse{
Items: pluginDashboards,
}, nil
}
if err, exists := m.unexpectedErrors[req.PluginID]; exists {
return nil, err
}
return nil, plugins.NotFoundError{PluginID: req.PluginID}
}