Refactor: Adds repository

pull/29642/head
Hugo Häggmark 5 years ago
parent 2dbc3811df
commit 4c46e8a6c4
No known key found for this signature in database
GPG Key ID: A7D79FCDEC1EE5EF
  1. 34
      pkg/services/librarypanels/api.go
  2. 82
      pkg/services/librarypanels/database_test.go
  3. 24
      pkg/services/librarypanels/librarypanels.go
  4. 30
      pkg/services/librarypanels/repository.go
  5. 118
      pkg/services/librarypanels/repository_test.go

@ -6,25 +6,47 @@ import (
"github.com/grafana/grafana/pkg/api/routing" "github.com/grafana/grafana/pkg/api/routing"
"github.com/grafana/grafana/pkg/middleware" "github.com/grafana/grafana/pkg/middleware"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util" "github.com/grafana/grafana/pkg/util"
) )
func (lps *LibraryPanelService) registerAPIEndpoints() { type LibraryPanelApi interface {
if !lps.IsEnabled() { registerAPIEndpoints()
addLibraryPanelEndpoint(c *models.ReqContext, cmd addLibraryPanelCommand) api.Response
}
type LibraryPanelApiImpl struct {
Cfg *setting.Cfg
RouteRegister routing.RouteRegister
repository LibraryPanelRepository
}
func NewApi(routeRegister routing.RouteRegister, cfg *setting.Cfg, repository LibraryPanelRepository) LibraryPanelApi {
impl := &LibraryPanelApiImpl{
Cfg: cfg,
RouteRegister: routeRegister,
repository: repository,
}
return impl
}
func (lpa *LibraryPanelApiImpl) registerAPIEndpoints() {
if !lpa.Cfg.IsPanelLibraryEnabled() {
return return
} }
lps.RouteRegister.Group("/api/library-panels", func(libraryPanels routing.RouteRegister) { lpa.RouteRegister.Group("/api/library-panels", func(libraryPanels routing.RouteRegister) {
libraryPanels.Post("/", middleware.ReqSignedIn, binding.Bind(addLibraryPanelCommand{}), api.Wrap(lps.addLibraryPanelEndpoint)) libraryPanels.Post("/", middleware.ReqSignedIn, binding.Bind(addLibraryPanelCommand{}), api.Wrap(lpa.addLibraryPanelEndpoint))
}) })
} }
// addLibraryPanelEndpoint handles POST /api/library-panels. // addLibraryPanelEndpoint handles POST /api/library-panels.
func (lps *LibraryPanelService) addLibraryPanelEndpoint(c *models.ReqContext, cmd addLibraryPanelCommand) api.Response { func (lpa *LibraryPanelApiImpl) addLibraryPanelEndpoint(c *models.ReqContext, cmd addLibraryPanelCommand) api.Response {
cmd.OrgId = c.SignedInUser.OrgId cmd.OrgId = c.SignedInUser.OrgId
cmd.SignedInUser = c.SignedInUser cmd.SignedInUser = c.SignedInUser
if err := lps.addLibraryPanel(&cmd); err != nil { if err := lpa.repository.addLibraryPanel(&cmd); err != nil {
return api.Error(500, "Failed to create library panel", err) return api.Error(500, "Failed to create library panel", err)
} }

@ -1,82 +0,0 @@
package librarypanels
import (
"testing"
"time"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/registry"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/setting"
"github.com/stretchr/testify/require"
)
func TestAddLibraryPanel(t *testing.T) {
t.Run("should fail if library panel already exists", func(t *testing.T) {
lps, user := setupTestEnv(t, models.ROLE_EDITOR)
command := addLibraryPanelCommand{
OrgId: 1,
FolderId: 1,
SignedInUser: &user,
Title: "Text - Library Panel",
Model: []byte(`
{
"datasource": "${DS_GDEV-TESTDATA}",
"id": 1,
"title": "Text - Library Panel",
"type": "text"
}
`),
}
noErr := lps.addLibraryPanel(&command)
require.NoError(t, noErr)
err := lps.addLibraryPanel(&command)
require.Error(t, err)
})
}
func setupTestEnv(t *testing.T, orgRole models.RoleType) (LibraryPanelService, models.SignedInUser) {
cfg := setting.NewCfg()
cfg.FeatureToggles = map[string]bool{"panelLibrary": true}
lps := LibraryPanelService{
SQLStore: nil,
Cfg: cfg,
}
overrideServiceFunc := func(d registry.Descriptor) (*registry.Descriptor, bool) {
descriptor := registry.Descriptor{
Name: "LibraryPanelService",
Instance: &lps,
InitPriority: 0,
}
return &descriptor, true
}
registry.RegisterOverride(overrideServiceFunc)
sqlStore := sqlstore.InitTestDB(t)
lps.SQLStore = sqlStore
user := models.SignedInUser{
UserId: 1,
OrgId: 1,
OrgName: "",
OrgRole: orgRole,
Login: "",
Name: "",
Email: "",
ApiKeyId: 0,
OrgCount: 0,
IsGrafanaAdmin: false,
IsAnonymous: false,
HelpFlags1: 0,
LastSeenAt: time.Now(),
Teams: nil,
}
return lps, user
}

@ -14,6 +14,8 @@ type LibraryPanelService struct {
Cfg *setting.Cfg `inject:""` Cfg *setting.Cfg `inject:""`
SQLStore *sqlstore.SQLStore `inject:""` SQLStore *sqlstore.SQLStore `inject:""`
RouteRegister routing.RouteRegister `inject:""` RouteRegister routing.RouteRegister `inject:""`
api LibraryPanelApi
repository LibraryPanelRepository
log log.Logger log log.Logger
} }
@ -22,27 +24,19 @@ func init() {
} }
// Init initializes the LibraryPanel service // Init initializes the LibraryPanel service
func (lps *LibraryPanelService) Init() error { func (service *LibraryPanelService) Init() error {
lps.log = log.New("librarypanels") service.log = log.New("libraryPanels")
service.repository = NewRepository(service.Cfg, service.SQLStore)
lps.registerAPIEndpoints() service.api = NewApi(service.RouteRegister, service.Cfg, service.repository)
service.api.registerAPIEndpoints()
return nil return nil
} }
// IsEnabled returns true if the Panel Library feature is enabled for this instance.
func (lps *LibraryPanelService) IsEnabled() bool {
if lps.Cfg == nil {
return false
}
return lps.Cfg.IsPanelLibraryEnabled()
}
// AddMigration defines database migrations. // AddMigration defines database migrations.
// If Panel Library is not enabled does nothing. // If Panel Library is not enabled does nothing.
func (lps *LibraryPanelService) AddMigration(mg *migrator.Migrator) { func (service *LibraryPanelService) AddMigration(mg *migrator.Migrator) {
if !lps.IsEnabled() { if !service.Cfg.IsPanelLibraryEnabled() {
return return
} }

@ -4,12 +4,36 @@ import (
"context" "context"
"time" "time"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/services/sqlstore" "github.com/grafana/grafana/pkg/services/sqlstore"
) )
// AddLibraryPanel function adds a LibraryPanel type LibraryPanelRepository interface {
func (lps *LibraryPanelService) addLibraryPanel(cmd *addLibraryPanelCommand) error { addLibraryPanel(cmd *addLibraryPanelCommand) error
return lps.SQLStore.WithTransactionalDbSession(context.Background(), func(session *sqlstore.DBSession) error { }
type SQLLibraryPanelRepository struct {
cfg *setting.Cfg
sqlStore *sqlstore.SQLStore
}
func NewRepository(cfg *setting.Cfg, sqlStore *sqlstore.SQLStore) LibraryPanelRepository {
repository := SQLLibraryPanelRepository{
cfg: cfg,
sqlStore: sqlStore,
}
return &repository
}
// addLibraryPanel function adds a LibraryPanel
func (repo *SQLLibraryPanelRepository) addLibraryPanel(cmd *addLibraryPanelCommand) error {
if !repo.cfg.IsPanelLibraryEnabled() {
return nil
}
return repo.sqlStore.WithTransactionalDbSession(context.Background(), func(session *sqlstore.DBSession) error {
libraryPanel := &LibraryPanel{ libraryPanel := &LibraryPanel{
OrgId: cmd.OrgId, OrgId: cmd.OrgId,
FolderId: cmd.FolderId, FolderId: cmd.FolderId,

@ -0,0 +1,118 @@
package librarypanels
import (
"testing"
"time"
"github.com/grafana/grafana/pkg/registry"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/setting"
)
func TestAddLibraryPanel(t *testing.T) {
t.Run("should fail if library panel already exists", func(t *testing.T) {
repository, user := setupTestEnv(t, true, models.ROLE_EDITOR)
command := addLibraryPanelCommand{
OrgId: 1,
FolderId: 1,
SignedInUser: &user,
Title: "Text - Library Panel",
Model: []byte(`
{
"datasource": "${DS_GDEV-TESTDATA}",
"id": 1,
"title": "Text - Library Panel",
"type": "text"
}
`),
}
noErr := repository.addLibraryPanel(&command)
require.NoError(t, noErr)
err := repository.addLibraryPanel(&command)
require.EqualError(t, err, errLibraryPanelAlreadyAdded.Error())
})
}
func TestAddLibraryPanelWhenFeatureToggleIsOff(t *testing.T) {
t.Run("should return nil", func(t *testing.T) {
repository, user := setupTestEnv(t, false, models.ROLE_EDITOR)
command := addLibraryPanelCommand{
OrgId: 1,
FolderId: 1,
SignedInUser: &user,
Title: "Text - Library Panel",
Model: []byte(`
{
"datasource": "${DS_GDEV-TESTDATA}",
"id": 1,
"title": "Text - Library Panel",
"type": "text"
}
`),
}
err := repository.addLibraryPanel(&command)
require.NoError(t, err)
require.Nil(t, command.Result)
})
}
// setupMigration overrides LibraryPanelService so that the AddMigration is run before tests
// this is necessary because our migration is controlled by a feature toggle
func setupMigration(cfg *setting.Cfg) {
lps := LibraryPanelService{
SQLStore: nil,
Cfg: cfg,
}
overrideServiceFunc := func(d registry.Descriptor) (*registry.Descriptor, bool) {
descriptor := registry.Descriptor{
Name: "LibraryPanelService",
Instance: &lps,
InitPriority: 0,
}
return &descriptor, true
}
registry.RegisterOverride(overrideServiceFunc)
}
func setupTestEnv(t *testing.T, featureToggle bool, orgRole models.RoleType) (*SQLLibraryPanelRepository, models.SignedInUser) {
cfg := setting.NewCfg()
cfg.FeatureToggles = map[string]bool{"panelLibrary": featureToggle}
setupMigration(cfg)
sqlStore := sqlstore.InitTestDB(t)
repository := &SQLLibraryPanelRepository{
cfg: cfg,
sqlStore: sqlStore,
}
user := models.SignedInUser{
UserId: 1,
OrgId: 1,
OrgName: "",
OrgRole: orgRole,
Login: "",
Name: "",
Email: "",
ApiKeyId: 0,
OrgCount: 0,
IsGrafanaAdmin: false,
IsAnonymous: false,
HelpFlags1: 0,
LastSeenAt: time.Now(),
Teams: nil,
}
return repository, user
}
Loading…
Cancel
Save