Split preference store (#46843)
* Split preference store * Chore: Add tests to pref * Fix preference in wire * Rename and adjust * Add pref service test * Rename methods, add tests * Rename Preferences to Preference, names IDs correctly * Fix lint * Refactor Save * Refactor upsert Add new logic for QueryHistory Rename some fields according to go naming conventions Refactore tests * Roll back ID that breaks tests * Rename Id to ID in UpdatePreferenceQuery * Use preference as a model to modify store * Move pref store fakes to pref test file * Add integration tag for store tests * Adjust test Co-authored-by: yangkb09 <yangkb09@gmail.com>
This commit is contained in:
+2
-1
@@ -65,13 +65,13 @@ import (
|
|||||||
plugindashboardsservice "github.com/grafana/grafana/pkg/services/plugindashboards/service"
|
plugindashboardsservice "github.com/grafana/grafana/pkg/services/plugindashboards/service"
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsettings"
|
"github.com/grafana/grafana/pkg/services/pluginsettings"
|
||||||
pluginSettings "github.com/grafana/grafana/pkg/services/pluginsettings/service"
|
pluginSettings "github.com/grafana/grafana/pkg/services/pluginsettings/service"
|
||||||
|
"github.com/grafana/grafana/pkg/services/preference/prefimpl"
|
||||||
"github.com/grafana/grafana/pkg/services/query"
|
"github.com/grafana/grafana/pkg/services/query"
|
||||||
"github.com/grafana/grafana/pkg/services/queryhistory"
|
"github.com/grafana/grafana/pkg/services/queryhistory"
|
||||||
"github.com/grafana/grafana/pkg/services/quota"
|
"github.com/grafana/grafana/pkg/services/quota"
|
||||||
"github.com/grafana/grafana/pkg/services/rendering"
|
"github.com/grafana/grafana/pkg/services/rendering"
|
||||||
"github.com/grafana/grafana/pkg/services/schemaloader"
|
"github.com/grafana/grafana/pkg/services/schemaloader"
|
||||||
"github.com/grafana/grafana/pkg/services/search"
|
"github.com/grafana/grafana/pkg/services/search"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/services/searchV2"
|
"github.com/grafana/grafana/pkg/services/searchV2"
|
||||||
"github.com/grafana/grafana/pkg/services/secrets"
|
"github.com/grafana/grafana/pkg/services/secrets"
|
||||||
secretsDatabase "github.com/grafana/grafana/pkg/services/secrets/database"
|
secretsDatabase "github.com/grafana/grafana/pkg/services/secrets/database"
|
||||||
@@ -235,6 +235,7 @@ var wireBasicSet = wire.NewSet(
|
|||||||
wire.Bind(new(alerting.DashAlertExtractor), new(*alerting.DashAlertExtractorService)),
|
wire.Bind(new(alerting.DashAlertExtractor), new(*alerting.DashAlertExtractorService)),
|
||||||
comments.ProvideService,
|
comments.ProvideService,
|
||||||
guardian.ProvideService,
|
guardian.ProvideService,
|
||||||
|
prefimpl.ProvideService,
|
||||||
avatar.ProvideAvatarCacheServer,
|
avatar.ProvideAvatarCacheServer,
|
||||||
authproxy.ProvideAuthProxy,
|
authproxy.ProvideAuthProxy,
|
||||||
statscollector.ProvideService,
|
statscollector.ProvideService,
|
||||||
|
|||||||
@@ -0,0 +1,100 @@
|
|||||||
|
package pref
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var ErrPrefNotFound = errors.New("preference not found")
|
||||||
|
|
||||||
|
type Preference struct {
|
||||||
|
ID int64 `xorm:"pk autoincr 'id'"`
|
||||||
|
OrgID int64 `xorm:"org_id"`
|
||||||
|
UserID int64 `xorm:"user_id"`
|
||||||
|
TeamID int64 `xorm:"team_id"`
|
||||||
|
Teams []int64 `xorm:"extends"`
|
||||||
|
Version int
|
||||||
|
HomeDashboardID int64 `xorm:"home_dashboard_id"`
|
||||||
|
Timezone string
|
||||||
|
WeekStart string
|
||||||
|
Theme string
|
||||||
|
Created time.Time
|
||||||
|
Updated time.Time
|
||||||
|
JSONData *PreferenceJSONData `xorm:"json_data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetPreferenceWithDefaultsQuery struct {
|
||||||
|
Teams []int64
|
||||||
|
OrgID int64
|
||||||
|
UserID int64
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetPreferenceQuery struct {
|
||||||
|
OrgID int64
|
||||||
|
UserID int64
|
||||||
|
TeamID int64
|
||||||
|
}
|
||||||
|
|
||||||
|
type SavePreferenceCommand struct {
|
||||||
|
UserID int64
|
||||||
|
OrgID int64
|
||||||
|
TeamID int64
|
||||||
|
|
||||||
|
HomeDashboardID int64 `json:"homeDashboardId,omitempty"`
|
||||||
|
Timezone string `json:"timezone,omitempty"`
|
||||||
|
WeekStart string `json:"weekStart,omitempty"`
|
||||||
|
Theme string `json:"theme,omitempty"`
|
||||||
|
Navbar *NavbarPreference `json:"navbar,omitempty"`
|
||||||
|
QueryHistory *QueryHistoryPreference `json:"queryHistory,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PatchPreferenceCommand struct {
|
||||||
|
UserID int64
|
||||||
|
OrgID int64
|
||||||
|
TeamID int64
|
||||||
|
|
||||||
|
HomeDashboardID *int64 `json:"homeDashboardId,omitempty"`
|
||||||
|
Timezone *string `json:"timezone,omitempty"`
|
||||||
|
WeekStart *string `json:"weekStart,omitempty"`
|
||||||
|
Theme *string `json:"theme,omitempty"`
|
||||||
|
Navbar *NavbarPreference `json:"navbar,omitempty"`
|
||||||
|
QueryHistory *QueryHistoryPreference `json:"queryHistory,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type NavLink struct {
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
Text string `json:"text,omitempty"`
|
||||||
|
Url string `json:"url,omitempty"`
|
||||||
|
Target string `json:"target,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type NavbarPreference struct {
|
||||||
|
SavedItems []NavLink `json:"savedItems"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PreferenceJSONData struct {
|
||||||
|
Navbar NavbarPreference `json:"navbar"`
|
||||||
|
QueryHistory QueryHistoryPreference `json:"queryHistory"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type QueryHistoryPreference struct {
|
||||||
|
HomeTab string `json:"homeTab"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (j *PreferenceJSONData) FromDB(data []byte) error {
|
||||||
|
dec := json.NewDecoder(bytes.NewBuffer(data))
|
||||||
|
dec.UseNumber()
|
||||||
|
return dec.Decode(j)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (j *PreferenceJSONData) ToDB() ([]byte, error) {
|
||||||
|
if j == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return json.Marshal(j)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p Preference) TableName() string { return "preferences" }
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package pref
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Service interface {
|
||||||
|
GetWithDefaults(context.Context, *GetPreferenceWithDefaultsQuery) (*Preference, error)
|
||||||
|
Get(context.Context, *GetPreferenceQuery) (*Preference, error)
|
||||||
|
Save(context.Context, *SavePreferenceCommand) error
|
||||||
|
Patch(ctx context.Context, cmd *PatchPreferenceCommand) error
|
||||||
|
GetDefaults() *Preference
|
||||||
|
}
|
||||||
@@ -0,0 +1,203 @@
|
|||||||
|
package prefimpl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
pref "github.com/grafana/grafana/pkg/services/preference"
|
||||||
|
"github.com/grafana/grafana/pkg/services/sqlstore/db"
|
||||||
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Service struct {
|
||||||
|
store store
|
||||||
|
cfg *setting.Cfg
|
||||||
|
}
|
||||||
|
|
||||||
|
func ProvideService(db db.DB, cfg *setting.Cfg) *Service {
|
||||||
|
return &Service{
|
||||||
|
store: &sqlStore{
|
||||||
|
db: db,
|
||||||
|
},
|
||||||
|
cfg: cfg,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) GetWithDefaults(ctx context.Context, query *pref.GetPreferenceWithDefaultsQuery) (*pref.Preference, error) {
|
||||||
|
listQuery := &pref.Preference{
|
||||||
|
Teams: query.Teams,
|
||||||
|
OrgID: query.OrgID,
|
||||||
|
UserID: query.UserID,
|
||||||
|
}
|
||||||
|
prefs, err := s.store.List(ctx, listQuery)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
res := s.GetDefaults()
|
||||||
|
for _, p := range prefs {
|
||||||
|
if p.Theme != "" {
|
||||||
|
res.Theme = p.Theme
|
||||||
|
}
|
||||||
|
if p.Timezone != "" {
|
||||||
|
res.Timezone = p.Timezone
|
||||||
|
}
|
||||||
|
if p.WeekStart != "" {
|
||||||
|
res.WeekStart = p.WeekStart
|
||||||
|
}
|
||||||
|
if p.HomeDashboardID != 0 {
|
||||||
|
res.HomeDashboardID = p.HomeDashboardID
|
||||||
|
}
|
||||||
|
if p.JSONData != nil {
|
||||||
|
res.JSONData = p.JSONData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) Get(ctx context.Context, query *pref.GetPreferenceQuery) (*pref.Preference, error) {
|
||||||
|
getPref := &pref.Preference{
|
||||||
|
OrgID: query.OrgID,
|
||||||
|
UserID: query.UserID,
|
||||||
|
TeamID: query.TeamID,
|
||||||
|
}
|
||||||
|
prefs, err := s.store.Get(ctx, getPref)
|
||||||
|
if err != nil && !errors.Is(err, pref.ErrPrefNotFound) {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return prefs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) Save(ctx context.Context, cmd *pref.SavePreferenceCommand) error {
|
||||||
|
preference, err := s.store.Get(ctx, &pref.Preference{
|
||||||
|
OrgID: cmd.OrgID,
|
||||||
|
UserID: cmd.UserID,
|
||||||
|
TeamID: cmd.TeamID,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, pref.ErrPrefNotFound) {
|
||||||
|
preference := &pref.Preference{
|
||||||
|
UserID: cmd.UserID,
|
||||||
|
OrgID: cmd.OrgID,
|
||||||
|
TeamID: cmd.TeamID,
|
||||||
|
HomeDashboardID: cmd.HomeDashboardID,
|
||||||
|
Timezone: cmd.Timezone,
|
||||||
|
WeekStart: cmd.WeekStart,
|
||||||
|
Theme: cmd.Theme,
|
||||||
|
Created: time.Now(),
|
||||||
|
Updated: time.Now(),
|
||||||
|
}
|
||||||
|
_, err = s.store.Insert(ctx, preference)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
preference.Timezone = cmd.Timezone
|
||||||
|
preference.WeekStart = cmd.WeekStart
|
||||||
|
preference.Theme = cmd.Theme
|
||||||
|
preference.Updated = time.Now()
|
||||||
|
preference.Version += 1
|
||||||
|
preference.JSONData = &pref.PreferenceJSONData{}
|
||||||
|
|
||||||
|
if cmd.Navbar != nil {
|
||||||
|
preference.JSONData.Navbar = *cmd.Navbar
|
||||||
|
}
|
||||||
|
if cmd.QueryHistory != nil {
|
||||||
|
preference.JSONData.QueryHistory = *cmd.QueryHistory
|
||||||
|
}
|
||||||
|
return s.store.Update(ctx, preference)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) Patch(ctx context.Context, cmd *pref.PatchPreferenceCommand) error {
|
||||||
|
var exists bool
|
||||||
|
preference, err := s.store.Get(ctx, &pref.Preference{
|
||||||
|
OrgID: cmd.OrgID,
|
||||||
|
UserID: cmd.UserID,
|
||||||
|
TeamID: cmd.TeamID,
|
||||||
|
})
|
||||||
|
if err != nil && !errors.Is(err, pref.ErrPrefNotFound) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if errors.Is(err, pref.ErrPrefNotFound) {
|
||||||
|
preference = &pref.Preference{
|
||||||
|
UserID: cmd.UserID,
|
||||||
|
OrgID: cmd.OrgID,
|
||||||
|
TeamID: cmd.TeamID,
|
||||||
|
Created: time.Now(),
|
||||||
|
JSONData: &pref.PreferenceJSONData{},
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
exists = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if cmd.Navbar != nil {
|
||||||
|
if preference.JSONData == nil {
|
||||||
|
preference.JSONData = &pref.PreferenceJSONData{}
|
||||||
|
}
|
||||||
|
if cmd.Navbar.SavedItems != nil {
|
||||||
|
preference.JSONData.Navbar.SavedItems = cmd.Navbar.SavedItems
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if cmd.QueryHistory != nil {
|
||||||
|
if preference.JSONData == nil {
|
||||||
|
preference.JSONData = &pref.PreferenceJSONData{}
|
||||||
|
}
|
||||||
|
if cmd.QueryHistory.HomeTab != "" {
|
||||||
|
preference.JSONData.QueryHistory.HomeTab = cmd.QueryHistory.HomeTab
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if cmd.HomeDashboardID != nil {
|
||||||
|
preference.HomeDashboardID = *cmd.HomeDashboardID
|
||||||
|
}
|
||||||
|
|
||||||
|
if cmd.Timezone != nil {
|
||||||
|
preference.Timezone = *cmd.Timezone
|
||||||
|
}
|
||||||
|
|
||||||
|
if cmd.WeekStart != nil {
|
||||||
|
preference.WeekStart = *cmd.WeekStart
|
||||||
|
}
|
||||||
|
|
||||||
|
if cmd.Theme != nil {
|
||||||
|
preference.Theme = *cmd.Theme
|
||||||
|
}
|
||||||
|
|
||||||
|
preference.Updated = time.Now()
|
||||||
|
preference.Version += 1
|
||||||
|
|
||||||
|
// Wrap this in an if statement to maintain backwards compatibility
|
||||||
|
if cmd.Navbar != nil {
|
||||||
|
if preference.JSONData == nil {
|
||||||
|
preference.JSONData = &pref.PreferenceJSONData{}
|
||||||
|
}
|
||||||
|
if cmd.Navbar.SavedItems != nil {
|
||||||
|
preference.JSONData.Navbar.SavedItems = cmd.Navbar.SavedItems
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if exists {
|
||||||
|
err = s.store.Update(ctx, preference)
|
||||||
|
} else {
|
||||||
|
_, err = s.store.Insert(ctx, preference)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) GetDefaults() *pref.Preference {
|
||||||
|
defaults := &pref.Preference{
|
||||||
|
Theme: s.cfg.DefaultTheme,
|
||||||
|
Timezone: s.cfg.DateFormats.DefaultTimezone,
|
||||||
|
WeekStart: s.cfg.DateFormats.DefaultWeekStart,
|
||||||
|
HomeDashboardID: 0,
|
||||||
|
JSONData: &pref.PreferenceJSONData{},
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaults
|
||||||
|
}
|
||||||
@@ -0,0 +1,446 @@
|
|||||||
|
package prefimpl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/google/go-cmp/cmp"
|
||||||
|
pref "github.com/grafana/grafana/pkg/services/preference"
|
||||||
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPreferencesService(t *testing.T) {
|
||||||
|
prefStoreFake := newPreferenceStoreFake()
|
||||||
|
prefService := &Service{
|
||||||
|
store: prefStoreFake,
|
||||||
|
}
|
||||||
|
|
||||||
|
emptyNavbarPreferences := pref.NavbarPreference{}
|
||||||
|
userNavbarPreferences := pref.NavbarPreference{
|
||||||
|
SavedItems: []pref.NavLink{{
|
||||||
|
ID: "explore",
|
||||||
|
Text: "Explore",
|
||||||
|
Url: "/explore",
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
orgNavbarPreferences := pref.NavbarPreference{
|
||||||
|
SavedItems: []pref.NavLink{{
|
||||||
|
ID: "alerting",
|
||||||
|
Text: "Alerting",
|
||||||
|
Url: "/alerting",
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
team1NavbarPreferences := pref.NavbarPreference{
|
||||||
|
SavedItems: []pref.NavLink{{
|
||||||
|
ID: "dashboards",
|
||||||
|
Text: "Dashboards",
|
||||||
|
Url: "/dashboards",
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
team2NavbarPreferences := pref.NavbarPreference{
|
||||||
|
SavedItems: []pref.NavLink{{
|
||||||
|
ID: "home",
|
||||||
|
Text: "Home",
|
||||||
|
Url: "/home",
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
|
||||||
|
emptyQueryPreference := pref.QueryHistoryPreference{}
|
||||||
|
|
||||||
|
queryPreference := pref.QueryHistoryPreference{
|
||||||
|
HomeTab: "hometab",
|
||||||
|
}
|
||||||
|
|
||||||
|
queryPreference2 := pref.QueryHistoryPreference{
|
||||||
|
HomeTab: "hometab",
|
||||||
|
}
|
||||||
|
|
||||||
|
emptyPreferencesJsonData := pref.PreferenceJSONData{
|
||||||
|
Navbar: emptyNavbarPreferences,
|
||||||
|
}
|
||||||
|
userPreferencesJsonData := pref.PreferenceJSONData{
|
||||||
|
Navbar: userNavbarPreferences,
|
||||||
|
QueryHistory: queryPreference,
|
||||||
|
}
|
||||||
|
orgPreferencesJsonData := pref.PreferenceJSONData{
|
||||||
|
Navbar: orgNavbarPreferences,
|
||||||
|
}
|
||||||
|
team2PreferencesJsonData := pref.PreferenceJSONData{
|
||||||
|
Navbar: team2NavbarPreferences,
|
||||||
|
}
|
||||||
|
team1PreferencesJsonData := pref.PreferenceJSONData{
|
||||||
|
Navbar: team1NavbarPreferences,
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("GetDefaults should return defaults", func(t *testing.T) {
|
||||||
|
prefService.cfg = setting.NewCfg()
|
||||||
|
prefService.cfg.DefaultTheme = "light"
|
||||||
|
prefService.cfg.DateFormats.DefaultTimezone = "UTC"
|
||||||
|
|
||||||
|
preferences := prefService.GetDefaults()
|
||||||
|
expected := &pref.Preference{
|
||||||
|
Theme: "light",
|
||||||
|
Timezone: "UTC",
|
||||||
|
HomeDashboardID: 0,
|
||||||
|
JSONData: &pref.PreferenceJSONData{},
|
||||||
|
}
|
||||||
|
if diff := cmp.Diff(expected, preferences); diff != "" {
|
||||||
|
t.Fatalf("Result mismatch (-want +got):\n%s", diff)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("GetDefaults with no saved preferences should return defaults", func(t *testing.T) {
|
||||||
|
prefStoreFake.ExpectedPreference = &pref.Preference{
|
||||||
|
Theme: "light",
|
||||||
|
Timezone: "UTC",
|
||||||
|
}
|
||||||
|
query := &pref.GetPreferenceWithDefaultsQuery{}
|
||||||
|
preferences, err := prefService.GetWithDefaults(context.Background(), query)
|
||||||
|
require.NoError(t, err)
|
||||||
|
expected := &pref.Preference{
|
||||||
|
Theme: "light",
|
||||||
|
Timezone: "UTC",
|
||||||
|
HomeDashboardID: 0,
|
||||||
|
JSONData: &emptyPreferencesJsonData,
|
||||||
|
}
|
||||||
|
if diff := cmp.Diff(expected, preferences); diff != "" {
|
||||||
|
t.Fatalf("Result mismatch (-want +got):\n%s", diff)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("GetWithDefaults with saved org and user home dashboard should return user home dashboard", func(t *testing.T) {
|
||||||
|
prefStoreFake.ExpectedPreference = &pref.Preference{}
|
||||||
|
prefStoreFake.ExpectedListPreferences = []*pref.Preference{
|
||||||
|
{
|
||||||
|
OrgID: 1,
|
||||||
|
HomeDashboardID: 1,
|
||||||
|
Theme: "dark",
|
||||||
|
Timezone: "UTC",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
OrgID: 1,
|
||||||
|
UserID: 1,
|
||||||
|
HomeDashboardID: 4,
|
||||||
|
Theme: "light",
|
||||||
|
WeekStart: "1",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
query := &pref.GetPreferenceWithDefaultsQuery{OrgID: 1, UserID: 1}
|
||||||
|
preferences, err := prefService.GetWithDefaults(context.Background(), query)
|
||||||
|
require.NoError(t, err)
|
||||||
|
expected := &pref.Preference{
|
||||||
|
Theme: "light",
|
||||||
|
Timezone: "UTC",
|
||||||
|
WeekStart: "1",
|
||||||
|
HomeDashboardID: 4,
|
||||||
|
JSONData: &pref.PreferenceJSONData{},
|
||||||
|
}
|
||||||
|
if diff := cmp.Diff(expected, preferences); diff != "" {
|
||||||
|
t.Fatalf("Result mismatch (-want +got):\n%s", diff)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("GetWithDefaults with saved org and other user home dashboard should return org home dashboard", func(t *testing.T) {
|
||||||
|
prefStoreFake.ExpectedPreference = &pref.Preference{}
|
||||||
|
prefStoreFake.ExpectedListPreferences = []*pref.Preference{
|
||||||
|
{
|
||||||
|
OrgID: 1,
|
||||||
|
HomeDashboardID: 1,
|
||||||
|
Theme: "dark",
|
||||||
|
Timezone: "UTC",
|
||||||
|
WeekStart: "1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
OrgID: 1,
|
||||||
|
UserID: 1,
|
||||||
|
HomeDashboardID: 4,
|
||||||
|
Theme: "light",
|
||||||
|
Timezone: "browser",
|
||||||
|
WeekStart: "2",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
prefService.GetDefaults().HomeDashboardID = 1
|
||||||
|
query := &pref.GetPreferenceWithDefaultsQuery{OrgID: 1, UserID: 2}
|
||||||
|
preferences, err := prefService.GetWithDefaults(context.Background(), query)
|
||||||
|
require.NoError(t, err)
|
||||||
|
expected := &pref.Preference{
|
||||||
|
Theme: "light",
|
||||||
|
Timezone: "browser",
|
||||||
|
WeekStart: "2",
|
||||||
|
HomeDashboardID: 4,
|
||||||
|
JSONData: &pref.PreferenceJSONData{},
|
||||||
|
}
|
||||||
|
if diff := cmp.Diff(expected, preferences); diff != "" {
|
||||||
|
t.Fatalf("Result mismatch (-want +got):\n%s", diff)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("GetPreferencesWithDefaults with saved org and user json data should return user json data", func(t *testing.T) {
|
||||||
|
prefStoreFake.ExpectedPreference = &pref.Preference{}
|
||||||
|
prefStoreFake.ExpectedListPreferences = []*pref.Preference{
|
||||||
|
{
|
||||||
|
OrgID: 1,
|
||||||
|
JSONData: &orgPreferencesJsonData,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
OrgID: 1,
|
||||||
|
UserID: 1,
|
||||||
|
JSONData: &userPreferencesJsonData,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
query := &pref.GetPreferenceWithDefaultsQuery{OrgID: 1, UserID: 1}
|
||||||
|
preference, err := prefService.GetWithDefaults(context.Background(), query)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, &pref.Preference{
|
||||||
|
Theme: "light",
|
||||||
|
JSONData: &userPreferencesJsonData,
|
||||||
|
Timezone: "UTC",
|
||||||
|
}, preference)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("GetWithDefaults with saved org and teams json data should return last team json data", func(t *testing.T) {
|
||||||
|
prefStoreFake.ExpectedPreference = &pref.Preference{}
|
||||||
|
prefStoreFake.ExpectedListPreferences = []*pref.Preference{
|
||||||
|
{
|
||||||
|
OrgID: 1,
|
||||||
|
JSONData: &orgPreferencesJsonData,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
OrgID: 1,
|
||||||
|
TeamID: 2,
|
||||||
|
JSONData: &team1PreferencesJsonData,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
OrgID: 1,
|
||||||
|
TeamID: 3,
|
||||||
|
JSONData: &team2PreferencesJsonData,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
query := &pref.GetPreferenceWithDefaultsQuery{
|
||||||
|
OrgID: 1, Teams: []int64{2, 3},
|
||||||
|
}
|
||||||
|
preference, err := prefService.GetWithDefaults(context.Background(), query)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, &pref.Preference{
|
||||||
|
Timezone: "UTC",
|
||||||
|
Theme: "light",
|
||||||
|
JSONData: &team2PreferencesJsonData,
|
||||||
|
}, preference)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("GetWithDefaults with saved org and teams home dashboard should return last team home dashboard", func(t *testing.T) {
|
||||||
|
prefStoreFake.ExpectedPreference = &pref.Preference{
|
||||||
|
Theme: "dark",
|
||||||
|
Timezone: "UTC",
|
||||||
|
}
|
||||||
|
prefStoreFake.ExpectedListPreferences = []*pref.Preference{
|
||||||
|
{
|
||||||
|
OrgID: 1,
|
||||||
|
HomeDashboardID: 1,
|
||||||
|
Theme: "light",
|
||||||
|
Timezone: "browser",
|
||||||
|
WeekStart: "1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
OrgID: 1,
|
||||||
|
UserID: 1,
|
||||||
|
HomeDashboardID: 4,
|
||||||
|
Theme: "light",
|
||||||
|
Timezone: "browser",
|
||||||
|
WeekStart: "2",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
query := &pref.GetPreferenceWithDefaultsQuery{OrgID: 1, Teams: []int64{2, 3}}
|
||||||
|
preferences, err := prefService.GetWithDefaults(context.Background(), query)
|
||||||
|
require.NoError(t, err)
|
||||||
|
expected := &pref.Preference{
|
||||||
|
Theme: "light",
|
||||||
|
Timezone: "browser",
|
||||||
|
WeekStart: "2",
|
||||||
|
HomeDashboardID: 4,
|
||||||
|
JSONData: &pref.PreferenceJSONData{},
|
||||||
|
}
|
||||||
|
if diff := cmp.Diff(expected, preferences); diff != "" {
|
||||||
|
t.Fatalf("Result mismatch (-want +got):\n%s", diff)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("SavePreferences for a user should store correct values", func(t *testing.T) {
|
||||||
|
prefStoreFake.ExpectedPreference = &pref.Preference{
|
||||||
|
ID: 1,
|
||||||
|
OrgID: 1,
|
||||||
|
UserID: 3,
|
||||||
|
TeamID: 6,
|
||||||
|
HomeDashboardID: 5,
|
||||||
|
Timezone: "browser",
|
||||||
|
WeekStart: "1",
|
||||||
|
Theme: "dark",
|
||||||
|
}
|
||||||
|
err := prefService.Save(context.Background(),
|
||||||
|
&pref.SavePreferenceCommand{
|
||||||
|
Theme: "dark",
|
||||||
|
Timezone: "browser",
|
||||||
|
HomeDashboardID: 5,
|
||||||
|
WeekStart: "1"},
|
||||||
|
)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("SavePreferences for a user should store correct values, when preference not found", func(t *testing.T) {
|
||||||
|
prefStoreFake.ExpectedGetError = pref.ErrPrefNotFound
|
||||||
|
prefStoreFake.ExpectedPreference = &pref.Preference{
|
||||||
|
ID: 1,
|
||||||
|
OrgID: 1,
|
||||||
|
UserID: 3,
|
||||||
|
TeamID: 6,
|
||||||
|
HomeDashboardID: 5,
|
||||||
|
Timezone: "browser",
|
||||||
|
WeekStart: "1",
|
||||||
|
Theme: "dark",
|
||||||
|
}
|
||||||
|
err := prefService.Save(context.Background(),
|
||||||
|
&pref.SavePreferenceCommand{
|
||||||
|
Theme: "dark",
|
||||||
|
Timezone: "browser",
|
||||||
|
HomeDashboardID: 5,
|
||||||
|
WeekStart: "1",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
require.NoError(t, err)
|
||||||
|
prefStoreFake.ExpectedGetError = nil
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("SavePreferences for a user should store correct values with nav and query history", func(t *testing.T) {
|
||||||
|
prefStoreFake.ExpectedPreference = &pref.Preference{
|
||||||
|
ID: 1,
|
||||||
|
OrgID: 1,
|
||||||
|
UserID: 3,
|
||||||
|
TeamID: 6,
|
||||||
|
HomeDashboardID: 5,
|
||||||
|
Timezone: "browser",
|
||||||
|
WeekStart: "1",
|
||||||
|
Theme: "dark",
|
||||||
|
JSONData: &userPreferencesJsonData,
|
||||||
|
}
|
||||||
|
err := prefService.Save(context.Background(),
|
||||||
|
&pref.SavePreferenceCommand{
|
||||||
|
Theme: "dark",
|
||||||
|
Timezone: "browser",
|
||||||
|
HomeDashboardID: 5,
|
||||||
|
WeekStart: "1",
|
||||||
|
Navbar: &userNavbarPreferences,
|
||||||
|
QueryHistory: &emptyQueryPreference,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Get for a user should store correct values", func(t *testing.T) {
|
||||||
|
prefStoreFake.ExpectedPreference = &pref.Preference{
|
||||||
|
HomeDashboardID: 5,
|
||||||
|
Timezone: "browser",
|
||||||
|
WeekStart: "1",
|
||||||
|
Theme: "dark",
|
||||||
|
}
|
||||||
|
preference, err := prefService.Get(context.Background(), &pref.GetPreferenceQuery{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
expected := &pref.Preference{
|
||||||
|
ID: preference.ID,
|
||||||
|
Version: preference.Version,
|
||||||
|
HomeDashboardID: 5,
|
||||||
|
Timezone: "browser",
|
||||||
|
WeekStart: "1",
|
||||||
|
Theme: "dark",
|
||||||
|
Created: preference.Created,
|
||||||
|
Updated: preference.Updated,
|
||||||
|
}
|
||||||
|
if diff := cmp.Diff(expected, preference); diff != "" {
|
||||||
|
t.Fatalf("Result mismatch (-want +got):\n%s", diff)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Patch for a user should store correct values", func(t *testing.T) {
|
||||||
|
darkTheme := "dark"
|
||||||
|
prefStoreFake.ExpectedPreference = &pref.Preference{
|
||||||
|
HomeDashboardID: 5,
|
||||||
|
Timezone: "browser",
|
||||||
|
WeekStart: "1",
|
||||||
|
Theme: "dark",
|
||||||
|
JSONData: &userPreferencesJsonData,
|
||||||
|
}
|
||||||
|
err := prefService.Patch(context.Background(),
|
||||||
|
&pref.PatchPreferenceCommand{
|
||||||
|
Theme: &darkTheme,
|
||||||
|
Navbar: &userNavbarPreferences,
|
||||||
|
QueryHistory: &queryPreference2,
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Patch for a user should store correct values, without navbar and query history", func(t *testing.T) {
|
||||||
|
darkTheme := "dark"
|
||||||
|
prefStoreFake.ExpectedPreference = &pref.Preference{
|
||||||
|
HomeDashboardID: 5,
|
||||||
|
Timezone: "browser",
|
||||||
|
WeekStart: "1",
|
||||||
|
Theme: "dark",
|
||||||
|
}
|
||||||
|
err := prefService.Patch(context.Background(),
|
||||||
|
&pref.PatchPreferenceCommand{
|
||||||
|
Theme: &darkTheme,
|
||||||
|
Navbar: &userNavbarPreferences,
|
||||||
|
QueryHistory: &queryPreference2,
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Patch for a user should store correct values, when preference not found", func(t *testing.T) {
|
||||||
|
timezone := "browser"
|
||||||
|
weekStart := "1"
|
||||||
|
homeDashboardID := int64(5)
|
||||||
|
prefStoreFake.ExpectedGetError = pref.ErrPrefNotFound
|
||||||
|
prefStoreFake.ExpectedPreference = nil
|
||||||
|
|
||||||
|
err := prefService.Patch(context.Background(),
|
||||||
|
&pref.PatchPreferenceCommand{
|
||||||
|
HomeDashboardID: &homeDashboardID,
|
||||||
|
Timezone: &timezone,
|
||||||
|
WeekStart: &weekStart,
|
||||||
|
Navbar: &emptyNavbarPreferences,
|
||||||
|
QueryHistory: &emptyQueryPreference,
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
prefStoreFake.ExpectedGetError = nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type FakePreferenceStore struct {
|
||||||
|
ExpectedPreference *pref.Preference
|
||||||
|
ExpectedListPreferences []*pref.Preference
|
||||||
|
ExpectedID int64
|
||||||
|
ExpectedError error
|
||||||
|
ExpectedGetError error
|
||||||
|
}
|
||||||
|
|
||||||
|
func newPreferenceStoreFake() *FakePreferenceStore {
|
||||||
|
return &FakePreferenceStore{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FakePreferenceStore) List(ctx context.Context, query *pref.Preference) ([]*pref.Preference, error) {
|
||||||
|
return f.ExpectedListPreferences, f.ExpectedError
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FakePreferenceStore) Get(ctx context.Context, query *pref.Preference) (*pref.Preference, error) {
|
||||||
|
return f.ExpectedPreference, f.ExpectedGetError
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FakePreferenceStore) Insert(ctx context.Context, cmd *pref.Preference) (int64, error) {
|
||||||
|
return f.ExpectedID, f.ExpectedError
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FakePreferenceStore) Update(ctx context.Context, cmd *pref.Preference) error {
|
||||||
|
return f.ExpectedError
|
||||||
|
}
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
package prefimpl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
pref "github.com/grafana/grafana/pkg/services/preference"
|
||||||
|
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||||
|
"github.com/grafana/grafana/pkg/services/sqlstore/db"
|
||||||
|
)
|
||||||
|
|
||||||
|
type store interface {
|
||||||
|
Get(context.Context, *pref.Preference) (*pref.Preference, error)
|
||||||
|
List(context.Context, *pref.Preference) ([]*pref.Preference, error)
|
||||||
|
Insert(context.Context, *pref.Preference) (int64, error)
|
||||||
|
Update(context.Context, *pref.Preference) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type sqlStore struct {
|
||||||
|
db db.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *sqlStore) Get(ctx context.Context, query *pref.Preference) (*pref.Preference, error) {
|
||||||
|
var prefs pref.Preference
|
||||||
|
err := s.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
||||||
|
exist, err := sess.Where("org_id=? AND user_id=? AND team_id=?", query.OrgID, query.UserID, query.TeamID).Get(&prefs)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !exist {
|
||||||
|
return pref.ErrPrefNotFound
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &prefs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *sqlStore) List(ctx context.Context, query *pref.Preference) ([]*pref.Preference, error) {
|
||||||
|
prefs := make([]*pref.Preference, 0)
|
||||||
|
params := make([]interface{}, 0)
|
||||||
|
filter := ""
|
||||||
|
|
||||||
|
if len(query.Teams) > 0 {
|
||||||
|
filter = "(org_id=? AND team_id IN (?" + strings.Repeat(",?", len(query.Teams)-1) + ")) OR "
|
||||||
|
params = append(params, query.OrgID)
|
||||||
|
for _, v := range query.Teams {
|
||||||
|
params = append(params, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
filter += "(org_id=? AND user_id=? AND team_id=0) OR (org_id=? AND team_id=0 AND user_id=0)"
|
||||||
|
params = append(params, query.OrgID)
|
||||||
|
params = append(params, query.UserID)
|
||||||
|
params = append(params, query.OrgID)
|
||||||
|
|
||||||
|
err := s.db.WithDbSession(ctx, func(dbSession *sqlstore.DBSession) error {
|
||||||
|
err := dbSession.Where(filter, params...).
|
||||||
|
OrderBy("user_id ASC, team_id ASC").
|
||||||
|
Find(&prefs)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
return prefs, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *sqlStore) Update(ctx context.Context, cmd *pref.Preference) error {
|
||||||
|
return s.db.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
||||||
|
_, err := sess.ID(cmd.ID).AllCols().Update(cmd)
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *sqlStore) Insert(ctx context.Context, cmd *pref.Preference) (int64, error) {
|
||||||
|
var ID int64
|
||||||
|
var err error
|
||||||
|
err = s.db.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
||||||
|
ID, err = sess.Insert(cmd)
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
return ID, err
|
||||||
|
}
|
||||||
@@ -0,0 +1,170 @@
|
|||||||
|
//go:build integration
|
||||||
|
// +build integration
|
||||||
|
|
||||||
|
package prefimpl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/go-cmp/cmp"
|
||||||
|
"github.com/grafana/grafana/pkg/models"
|
||||||
|
pref "github.com/grafana/grafana/pkg/services/preference"
|
||||||
|
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPreferencesDataAccess(t *testing.T) {
|
||||||
|
ss := sqlstore.InitTestDB(t)
|
||||||
|
prefStore := sqlStore{db: ss}
|
||||||
|
orgNavbarPreferences := pref.NavbarPreference{
|
||||||
|
SavedItems: []pref.NavLink{{
|
||||||
|
ID: "alerting",
|
||||||
|
Text: "Alerting",
|
||||||
|
Url: "/alerting",
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("Get with saved org and user home dashboard returns not found", func(t *testing.T) {
|
||||||
|
query := &pref.Preference{OrgID: 1, UserID: 1, TeamID: 2}
|
||||||
|
prefs, err := prefStore.Get(context.Background(), query)
|
||||||
|
require.EqualError(t, err, pref.ErrPrefNotFound.Error())
|
||||||
|
require.Nil(t, prefs)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Get with saved org and user home dashboard should return user home dashboard", func(t *testing.T) {
|
||||||
|
_, err := prefStore.Insert(context.Background(),
|
||||||
|
&pref.Preference{
|
||||||
|
OrgID: 1,
|
||||||
|
UserID: 1,
|
||||||
|
HomeDashboardID: 4,
|
||||||
|
TeamID: 2,
|
||||||
|
Created: time.Now(),
|
||||||
|
Updated: time.Now(),
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
query := &pref.Preference{OrgID: 1, UserID: 1, TeamID: 2}
|
||||||
|
prefs, err := prefStore.Get(context.Background(), query)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, int64(4), prefs.HomeDashboardID)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("List with saved org and user home dashboard should return user home dashboard", func(t *testing.T) {
|
||||||
|
_, err := prefStore.Insert(context.Background(),
|
||||||
|
&pref.Preference{
|
||||||
|
OrgID: 1,
|
||||||
|
UserID: 1,
|
||||||
|
TeamID: 3,
|
||||||
|
HomeDashboardID: 1,
|
||||||
|
Created: time.Now(),
|
||||||
|
Updated: time.Now(),
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
query := &pref.Preference{OrgID: 1, UserID: 1, Teams: []int64{2}}
|
||||||
|
prefs, err := prefStore.List(context.Background(), query)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, int64(4), prefs[0].HomeDashboardID)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("List with saved org and other user home dashboard should return org home dashboard", func(t *testing.T) {
|
||||||
|
_, err := prefStore.Insert(context.Background(),
|
||||||
|
&pref.Preference{
|
||||||
|
OrgID: 1,
|
||||||
|
UserID: 2,
|
||||||
|
TeamID: 3,
|
||||||
|
HomeDashboardID: 1,
|
||||||
|
Created: time.Now(),
|
||||||
|
Updated: time.Now(),
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
query := &pref.Preference{OrgID: 1, UserID: 1, Teams: []int64{3}}
|
||||||
|
prefs, err := prefStore.List(context.Background(), query)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, int64(1), prefs[0].HomeDashboardID)
|
||||||
|
require.Equal(t, int64(1), prefs[1].HomeDashboardID)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("List with saved org and teams home dashboard should return last team home dashboard", func(t *testing.T) {
|
||||||
|
query := &pref.Preference{
|
||||||
|
OrgID: 1, Teams: []int64{2, 3},
|
||||||
|
}
|
||||||
|
prefs, err := prefStore.List(context.Background(), query)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, int64(4), prefs[0].HomeDashboardID)
|
||||||
|
require.Equal(t, int64(1), prefs[1].HomeDashboardID)
|
||||||
|
require.Equal(t, int64(1), prefs[2].HomeDashboardID)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("List with saved org and other teams home dashboard should return org home dashboard", func(t *testing.T) {
|
||||||
|
_, err := prefStore.Insert(context.Background(), &pref.Preference{OrgID: 1, HomeDashboardID: 1, Created: time.Now(), Updated: time.Now()})
|
||||||
|
require.NoError(t, err)
|
||||||
|
_, err = prefStore.Insert(context.Background(), &pref.Preference{OrgID: 1, TeamID: 2, HomeDashboardID: 2, Created: time.Now(), Updated: time.Now()})
|
||||||
|
require.NoError(t, err)
|
||||||
|
_, err = prefStore.Insert(context.Background(), &pref.Preference{OrgID: 1, TeamID: 3, HomeDashboardID: 3, Created: time.Now(), Updated: time.Now()})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
query := &pref.Preference{OrgID: 1}
|
||||||
|
prefs, err := prefStore.List(context.Background(), query)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, int64(1), prefs[0].HomeDashboardID)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Update for a user should only modify a single value", func(t *testing.T) {
|
||||||
|
ss := sqlstore.InitTestDB(t)
|
||||||
|
prefStore := sqlStore{db: ss}
|
||||||
|
id, err := prefStore.Insert(context.Background(), &pref.Preference{
|
||||||
|
UserID: models.SignedInUser{}.UserId,
|
||||||
|
Theme: "dark",
|
||||||
|
Timezone: "browser",
|
||||||
|
HomeDashboardID: 5,
|
||||||
|
WeekStart: "1",
|
||||||
|
JSONData: &pref.PreferenceJSONData{Navbar: orgNavbarPreferences},
|
||||||
|
Created: time.Now(),
|
||||||
|
Updated: time.Now(),
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
err = prefStore.Update(context.Background(), &pref.Preference{
|
||||||
|
ID: id,
|
||||||
|
Theme: "dark",
|
||||||
|
HomeDashboardID: 5,
|
||||||
|
Timezone: "browser",
|
||||||
|
WeekStart: "1",
|
||||||
|
Created: time.Now(),
|
||||||
|
Updated: time.Now(),
|
||||||
|
JSONData: &pref.PreferenceJSONData{},
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
query := &pref.Preference{}
|
||||||
|
prefs, err := prefStore.List(context.Background(), query)
|
||||||
|
require.NoError(t, err)
|
||||||
|
expected := &pref.Preference{
|
||||||
|
ID: prefs[0].ID,
|
||||||
|
Version: prefs[0].Version,
|
||||||
|
HomeDashboardID: 5,
|
||||||
|
Timezone: "browser",
|
||||||
|
WeekStart: "1",
|
||||||
|
Theme: "dark",
|
||||||
|
JSONData: prefs[0].JSONData,
|
||||||
|
Created: prefs[0].Created,
|
||||||
|
Updated: prefs[0].Updated,
|
||||||
|
}
|
||||||
|
if diff := cmp.Diff(expected, prefs[0]); diff != "" {
|
||||||
|
t.Fatalf("Result mismatch (-want +got):\n%s", diff)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.Run("insert preference that does not exist", func(t *testing.T) {
|
||||||
|
_, err := prefStore.Insert(context.Background(),
|
||||||
|
&pref.Preference{
|
||||||
|
UserID: models.SignedInUser{}.UserId,
|
||||||
|
Created: time.Now(),
|
||||||
|
Updated: time.Now(),
|
||||||
|
JSONData: &pref.PreferenceJSONData{},
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package preftest
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
pref "github.com/grafana/grafana/pkg/services/preference"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FakePreferenceService struct {
|
||||||
|
ExpectedPreference *pref.Preference
|
||||||
|
ExpectedError error
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPreferenceServiceFake() *FakePreferenceService {
|
||||||
|
return &FakePreferenceService{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FakePreferenceService) GetWithDefaults(ctx context.Context, query *pref.GetPreferenceWithDefaultsQuery) (*pref.Preference, error) {
|
||||||
|
return f.ExpectedPreference, f.ExpectedError
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FakePreferenceService) Get(ctx context.Context, query *pref.GetPreferenceQuery) (*pref.Preference, error) {
|
||||||
|
return f.ExpectedPreference, f.ExpectedError
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FakePreferenceService) Save(ctx context.Context, cmd *pref.SavePreferenceCommand) error {
|
||||||
|
return f.ExpectedError
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FakePreferenceService) GetDefaults() *pref.Preference {
|
||||||
|
return f.ExpectedPreference
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user