PublicDashboards: move methods from store to service (#57599)
This commit is contained in:
committed by
GitHub
parent
c27aac0d38
commit
c5e420a94c
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/annotations"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/publicdashboards"
|
||||
"github.com/grafana/grafana/pkg/services/publicdashboards/internal/tokens"
|
||||
. "github.com/grafana/grafana/pkg/services/publicdashboards/models"
|
||||
"github.com/grafana/grafana/pkg/services/publicdashboards/validation"
|
||||
"github.com/grafana/grafana/pkg/services/query"
|
||||
@@ -19,6 +20,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/tsdb/intervalv2"
|
||||
"github.com/grafana/grafana/pkg/tsdb/legacydata"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
)
|
||||
|
||||
// PublicDashboardServiceImpl Define the Service Implementation. We're generating mock implementation
|
||||
@@ -153,15 +155,47 @@ func (pd *PublicDashboardServiceImpl) SavePublicDashboard(ctx context.Context, u
|
||||
return newPubdash, err
|
||||
}
|
||||
|
||||
// GenerateNewPublicDashboardUid Generates a unique uid to create a public dashboard. Will make 3 attempts and fail if it cannot find an unused uid
|
||||
func (pd *PublicDashboardServiceImpl) GenerateNewPublicDashboardUid(ctx context.Context) (string, error) {
|
||||
var uid string
|
||||
for i := 0; i < 3; i++ {
|
||||
uid = util.GenerateShortUID()
|
||||
|
||||
pubdash, _ := pd.store.GetPublicDashboardByUid(ctx, uid)
|
||||
if pubdash == nil {
|
||||
return uid, nil
|
||||
}
|
||||
}
|
||||
return "", ErrPublicDashboardFailedGenerateUniqueUid
|
||||
}
|
||||
|
||||
// GenerateNewPublicDashboardAccessToken Generates a unique accessToken to create a public dashboard. Will make 3 attempts and fail if it cannot find an unused access token
|
||||
func (pd *PublicDashboardServiceImpl) GenerateNewPublicDashboardAccessToken(ctx context.Context) (string, error) {
|
||||
var accessToken string
|
||||
for i := 0; i < 3; i++ {
|
||||
var err error
|
||||
accessToken, err = tokens.GenerateAccessToken()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
pubdash, _ := pd.store.GetPublicDashboardByAccessToken(ctx, accessToken)
|
||||
if pubdash == nil {
|
||||
return accessToken, nil
|
||||
}
|
||||
}
|
||||
return "", ErrPublicDashboardFailedGenerateAccessToken
|
||||
}
|
||||
|
||||
// Called by SavePublicDashboard this handles business logic
|
||||
// to generate token and calls create at the database layer
|
||||
func (pd *PublicDashboardServiceImpl) savePublicDashboard(ctx context.Context, dto *SavePublicDashboardConfigDTO) (string, error) {
|
||||
uid, err := pd.store.GenerateNewPublicDashboardUid(ctx)
|
||||
uid, err := pd.GenerateNewPublicDashboardUid(ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
accessToken, err := pd.store.GenerateNewPublicDashboardAccessToken(ctx)
|
||||
accessToken, err := pd.GenerateNewPublicDashboardAccessToken(ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package service
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -22,11 +23,13 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
. "github.com/grafana/grafana/pkg/services/publicdashboards"
|
||||
"github.com/grafana/grafana/pkg/services/publicdashboards/database"
|
||||
"github.com/grafana/grafana/pkg/services/publicdashboards/internal/tokens"
|
||||
. "github.com/grafana/grafana/pkg/services/publicdashboards/models"
|
||||
"github.com/grafana/grafana/pkg/services/serviceaccounts/tests"
|
||||
"github.com/grafana/grafana/pkg/services/tag/tagimpl"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
"github.com/grafana/grafana/pkg/tsdb/intervalv2"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
)
|
||||
|
||||
var timeSettings = &TimeSettings{From: "now-12h", To: "now"}
|
||||
@@ -224,12 +227,19 @@ func TestSavePublicDashboard(t *testing.T) {
|
||||
|
||||
t.Run("Pubdash access token generation throws an error and pubdash is not persisted", func(t *testing.T) {
|
||||
dashboard := models.NewDashboard("testDashie")
|
||||
pubdash := &PublicDashboard{
|
||||
IsEnabled: true,
|
||||
AnnotationsEnabled: false,
|
||||
DashboardUid: "NOTTHESAME",
|
||||
OrgId: 9999999,
|
||||
TimeSettings: timeSettings,
|
||||
}
|
||||
|
||||
publicDashboardStore := &FakePublicDashboardStore{}
|
||||
publicDashboardStore.On("GetDashboard", mock.Anything, mock.Anything).Return(dashboard, nil)
|
||||
publicDashboardStore.On("GetPublicDashboardByUid", mock.Anything, mock.Anything).Return(nil, nil)
|
||||
publicDashboardStore.On("GetPublicDashboardByAccessToken", mock.Anything, mock.Anything).Return(pubdash, nil)
|
||||
publicDashboardStore.On("GenerateNewPublicDashboardUid", mock.Anything).Return("an-uid", nil)
|
||||
publicDashboardStore.On("GenerateNewPublicDashboardAccessToken", mock.Anything).Return("", ErrPublicDashboardFailedGenerateAccessToken)
|
||||
|
||||
service := &PublicDashboardServiceImpl{
|
||||
log: log.New("test.logger"),
|
||||
@@ -782,3 +792,131 @@ func TestPublicDashboardServiceImpl_ListPublicDashboards(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPublicDashboardServiceImpl_GenerateNewPublicDashboardUid(t *testing.T) {
|
||||
mockedDashboard := &PublicDashboard{
|
||||
IsEnabled: true,
|
||||
AnnotationsEnabled: false,
|
||||
DashboardUid: "NOTTHESAME",
|
||||
OrgId: 9999999,
|
||||
TimeSettings: timeSettings,
|
||||
}
|
||||
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
type mockResponse struct {
|
||||
PublicDashboard *PublicDashboard
|
||||
Err error
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
mockStore *mockResponse
|
||||
want string
|
||||
wantErr assert.ErrorAssertionFunc
|
||||
}{
|
||||
{
|
||||
name: "should return a new uid",
|
||||
args: args{ctx: context.Background()},
|
||||
mockStore: &mockResponse{nil, nil},
|
||||
want: "NOTTHESAME",
|
||||
wantErr: assert.NoError,
|
||||
},
|
||||
{
|
||||
name: "should return an error if the generated uid exists 3 times",
|
||||
args: args{ctx: context.Background()},
|
||||
mockStore: &mockResponse{mockedDashboard, nil},
|
||||
want: "",
|
||||
wantErr: assert.Error,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
store := NewFakePublicDashboardStore(t)
|
||||
store.On("GetPublicDashboardByUid", mock.Anything, mock.Anything).
|
||||
Return(tt.mockStore.PublicDashboard, tt.mockStore.Err)
|
||||
|
||||
pd := &PublicDashboardServiceImpl{store: store}
|
||||
|
||||
got, err := pd.GenerateNewPublicDashboardUid(tt.args.ctx)
|
||||
if !tt.wantErr(t, err, fmt.Sprintf("GenerateNewPublicDashboardUid(%v)", tt.args.ctx)) {
|
||||
return
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
assert.NotEqual(t, got, tt.want, "GenerateNewPublicDashboardUid(%v)", tt.args.ctx)
|
||||
assert.True(t, util.IsValidShortUID(got), "GenerateNewPublicDashboardUid(%v)", tt.args.ctx)
|
||||
store.AssertNumberOfCalls(t, "GetPublicDashboardByUid", 1)
|
||||
} else {
|
||||
store.AssertNumberOfCalls(t, "GetPublicDashboardByUid", 3)
|
||||
assert.True(t, errors.Is(err, ErrPublicDashboardFailedGenerateUniqueUid))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPublicDashboardServiceImpl_GenerateNewPublicDashboardAccessToken(t *testing.T) {
|
||||
mockedDashboard := &PublicDashboard{
|
||||
IsEnabled: true,
|
||||
AnnotationsEnabled: false,
|
||||
DashboardUid: "NOTTHESAME",
|
||||
OrgId: 9999999,
|
||||
TimeSettings: timeSettings,
|
||||
}
|
||||
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
type mockResponse struct {
|
||||
PublicDashboard *PublicDashboard
|
||||
Err error
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
mockStore *mockResponse
|
||||
want string
|
||||
wantErr assert.ErrorAssertionFunc
|
||||
}{
|
||||
{
|
||||
name: "should return a new access token",
|
||||
args: args{ctx: context.Background()},
|
||||
mockStore: &mockResponse{nil, nil},
|
||||
want: "6522e152530f4ee76522e152530f4ee7",
|
||||
wantErr: assert.NoError,
|
||||
},
|
||||
{
|
||||
name: "should return an error if the generated access token exists 3 times",
|
||||
args: args{ctx: context.Background()},
|
||||
mockStore: &mockResponse{mockedDashboard, nil},
|
||||
want: "",
|
||||
wantErr: assert.Error,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
store := NewFakePublicDashboardStore(t)
|
||||
store.On("GetPublicDashboardByAccessToken", mock.Anything, mock.Anything).
|
||||
Return(tt.mockStore.PublicDashboard, tt.mockStore.Err)
|
||||
|
||||
pd := &PublicDashboardServiceImpl{store: store}
|
||||
|
||||
got, err := pd.GenerateNewPublicDashboardAccessToken(tt.args.ctx)
|
||||
if !tt.wantErr(t, err, fmt.Sprintf("GenerateNewPublicDashboardAccessToken(%v)", tt.args.ctx)) {
|
||||
return
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
assert.NotEqual(t, got, tt.want, "GenerateNewPublicDashboardAccessToken(%v)", tt.args.ctx)
|
||||
assert.True(t, tokens.IsValidAccessToken(got), "GenerateNewPublicDashboardAccessToken(%v)", tt.args.ctx)
|
||||
store.AssertNumberOfCalls(t, "GetPublicDashboardByAccessToken", 1)
|
||||
} else {
|
||||
store.AssertNumberOfCalls(t, "GetPublicDashboardByAccessToken", 3)
|
||||
assert.True(t, errors.Is(err, ErrPublicDashboardFailedGenerateAccessToken))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user