Navigation: Introduce a preferences table to store Navbar preferences (#44914)

* First attempt at creating new navbar_preferences table in db

* Apply to every nav item instead of just home

* user essentials mob! 🔱

* user essentials mob! 🔱

* user essentials mob! 🔱

* user essentials mob! 🔱

* user essentials mob! 🔱

* user essentials mob! 🔱

* user essentials mob! 🔱

* user essentials mob! 🔱

* user essentials mob! 🔱

* user essentials mob! 🔱

* user essentials mob! 🔱

* user essentials mob! 🔱

* user essentials mob! 🔱

* user essentials mob! 🔱

* user essentials mob! 🔱

* user essentials mob! 🔱

* user essentials mob! 🔱

* user essentials mob! 🔱

* user essentials mob! 🔱

* user essentials mob! 🔱

* user essentials mob! 🔱

* user essentials mob! 🔱

* user essentials mob! 🔱

* user essentials mob! 🔱

* user essentials mob! 🔱

* user essentials mob! 🔱

* user essentials mob! 🔱

* user essentials mob! 🔱

* Chore: introduce initTestDB options for features

* fix unit tests

* Add another unit test and some logic for detecting if a preference already exists

* tidy up

* Only override IsFeatureToggleEnabled if it's defined

* Extract setNavPreferences out into it's own function, initialise features correctly

* Make the linter happy

* Use new structure

* user essentials mob! 🔱

* user essentials mob! 🔱

* Split NavbarPreferences from Preferences

* user essentials mob! 🔱

* user essentials mob! 🔱

* Fix lint error

* Start adding tests

* Change internal db structure to be a generic json object

* GetJsonData -> GetPreferencesJsonData

* Stop using simplejson + add some more unit tests

* Update pkg/api/preferences.go

Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com>

* Updates following review comments

* user essentials mob! 🔱

* user essentials mob! 🔱

* user essentials mob! 🔱

* user essentials mob! 🔱

* Change patch to upsert, add a unit test

* remove commented out code

* introduce patch user/org preferences methods

* Return Navbar preferences in the get call

* Fix integration test by instantiating JsonData

* Address review comments

* Rename HideFromNavbar -> Hide

* add swagger:model comment

* Add patch to the preferences documentation

* Add openapi annotations

* Add a short description

* user essentials mob! 🔱

* user essentials mob! 🔱

* user essentials mob! 🔱

* user essentials mob! 🔱

* Update unit tests

* remove unneeded url

* remove outdated comment

* Update integration tests

* update generated swagger

Co-authored-by: Alexandra Vargas <alexa1866@gmail.com>
Co-authored-by: Hugo Häggmark <hugo.haggmark@gmail.com>
Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com>
This commit is contained in:
Ashley Harrison
2022-03-17 12:07:20 +00:00
committed by GitHub
co-authored by Marcus Efraimsson Alexandra Vargas Hugo Häggmark
parent 60af3af92c
commit 586272e5f0
17 changed files with 6474 additions and 16 deletions
+161 -1
View File
@@ -15,6 +15,48 @@ import (
func TestPreferencesDataAccess(t *testing.T) {
ss := InitTestDB(t)
emptyNavbarPreferences := models.NavbarPreference{}
userNavbarPreferences := models.NavbarPreference{
SavedItems: []models.NavLink{{
Id: "explore",
Text: "Explore",
Url: "/explore",
}},
}
orgNavbarPreferences := models.NavbarPreference{
SavedItems: []models.NavLink{{
Id: "alerting",
Text: "Alerting",
Url: "/alerting",
}},
}
team1NavbarPreferences := models.NavbarPreference{
SavedItems: []models.NavLink{{
Id: "dashboards",
Text: "Dashboards",
Url: "/dashboards",
}},
}
team2NavbarPreferences := models.NavbarPreference{
SavedItems: []models.NavLink{{
Id: "home",
Text: "Home",
Url: "/home",
}},
}
emptyPreferencesJsonData := models.PreferencesJsonData{
Navbar: emptyNavbarPreferences,
}
userPreferencesJsonData := models.PreferencesJsonData{
Navbar: userNavbarPreferences,
}
orgPreferencesJsonData := models.PreferencesJsonData{
Navbar: orgNavbarPreferences,
}
team2PreferencesJsonData := models.PreferencesJsonData{
Navbar: team2NavbarPreferences,
}
t.Run("GetPreferencesWithDefaults with no saved preferences should return defaults", func(t *testing.T) {
ss.Cfg.DefaultTheme = "light"
@@ -26,6 +68,7 @@ func TestPreferencesDataAccess(t *testing.T) {
require.Equal(t, "light", query.Result.Theme)
require.Equal(t, "UTC", query.Result.Timezone)
require.Equal(t, int64(0), query.Result.HomeDashboardId)
require.Equal(t, &emptyPreferencesJsonData, query.Result.JsonData)
})
t.Run("GetPreferencesWithDefaults with saved org and user home dashboard should return user home dashboard", func(t *testing.T) {
@@ -118,8 +161,98 @@ func TestPreferencesDataAccess(t *testing.T) {
require.Equal(t, int64(1), query.Result.HomeDashboardId)
})
t.Run("GetPreferencesWithDefaults with saved org and user json data should return user json data", func(t *testing.T) {
err := ss.SavePreferences(context.Background(), &models.SavePreferencesCommand{OrgId: 1, Navbar: &orgNavbarPreferences})
require.NoError(t, err)
err = ss.SavePreferences(context.Background(), &models.SavePreferencesCommand{OrgId: 1, UserId: 1, Navbar: &userNavbarPreferences})
require.NoError(t, err)
query := &models.GetPreferencesWithDefaultsQuery{User: &models.SignedInUser{OrgId: 1, UserId: 1}}
err = ss.GetPreferencesWithDefaults(context.Background(), query)
require.NoError(t, err)
require.Equal(t, &userPreferencesJsonData, query.Result.JsonData)
})
t.Run("GetPreferencesWithDefaults with saved org and other user json data should return org json data", func(t *testing.T) {
err := ss.SavePreferences(context.Background(), &models.SavePreferencesCommand{OrgId: 1, Navbar: &orgNavbarPreferences})
require.NoError(t, err)
err = ss.SavePreferences(context.Background(), &models.SavePreferencesCommand{OrgId: 1, UserId: 1, Navbar: &userNavbarPreferences})
require.NoError(t, err)
query := &models.GetPreferencesWithDefaultsQuery{User: &models.SignedInUser{OrgId: 1, UserId: 2}}
err = ss.GetPreferencesWithDefaults(context.Background(), query)
require.NoError(t, err)
require.Equal(t, &orgPreferencesJsonData, query.Result.JsonData)
})
t.Run("GetPreferencesWithDefaults with saved org and teams json data should return last team json data", func(t *testing.T) {
err := ss.SavePreferences(context.Background(), &models.SavePreferencesCommand{OrgId: 1, Navbar: &orgNavbarPreferences})
require.NoError(t, err)
err = ss.SavePreferences(context.Background(), &models.SavePreferencesCommand{OrgId: 1, TeamId: 2, Navbar: &team1NavbarPreferences})
require.NoError(t, err)
err = ss.SavePreferences(context.Background(), &models.SavePreferencesCommand{OrgId: 1, TeamId: 3, Navbar: &team2NavbarPreferences})
require.NoError(t, err)
query := &models.GetPreferencesWithDefaultsQuery{
User: &models.SignedInUser{OrgId: 1, Teams: []int64{2, 3}},
}
err = ss.GetPreferencesWithDefaults(context.Background(), query)
require.NoError(t, err)
require.Equal(t, &team2PreferencesJsonData, query.Result.JsonData)
})
t.Run("GetPreferencesWithDefaults with saved org and other teams json data should return org json data", func(t *testing.T) {
err := ss.SavePreferences(context.Background(), &models.SavePreferencesCommand{OrgId: 1, Navbar: &orgNavbarPreferences})
require.NoError(t, err)
err = ss.SavePreferences(context.Background(), &models.SavePreferencesCommand{OrgId: 1, TeamId: 2, Navbar: &team1NavbarPreferences})
require.NoError(t, err)
err = ss.SavePreferences(context.Background(), &models.SavePreferencesCommand{OrgId: 1, TeamId: 3, Navbar: &team2NavbarPreferences})
require.NoError(t, err)
query := &models.GetPreferencesWithDefaultsQuery{User: &models.SignedInUser{OrgId: 1}}
err = ss.GetPreferencesWithDefaults(context.Background(), query)
require.NoError(t, err)
require.Equal(t, &orgPreferencesJsonData, query.Result.JsonData)
})
t.Run("GetPreferencesWithDefaults with saved org, teams and user json data should return user json data", func(t *testing.T) {
err := ss.SavePreferences(context.Background(), &models.SavePreferencesCommand{OrgId: 1, Navbar: &orgNavbarPreferences})
require.NoError(t, err)
err = ss.SavePreferences(context.Background(), &models.SavePreferencesCommand{OrgId: 1, TeamId: 2, Navbar: &team1NavbarPreferences})
require.NoError(t, err)
err = ss.SavePreferences(context.Background(), &models.SavePreferencesCommand{OrgId: 1, TeamId: 3, Navbar: &team2NavbarPreferences})
require.NoError(t, err)
err = ss.SavePreferences(context.Background(), &models.SavePreferencesCommand{OrgId: 1, UserId: 1, Navbar: &userNavbarPreferences})
require.NoError(t, err)
query := &models.GetPreferencesWithDefaultsQuery{
User: &models.SignedInUser{OrgId: 1, UserId: 1, Teams: []int64{2, 3}},
}
err = ss.GetPreferencesWithDefaults(context.Background(), query)
require.NoError(t, err)
require.Equal(t, &userPreferencesJsonData, query.Result.JsonData)
})
t.Run("GetPreferencesWithDefaults with saved org, other teams and user json data should return org json data", func(t *testing.T) {
err := ss.SavePreferences(context.Background(), &models.SavePreferencesCommand{OrgId: 1, Navbar: &orgNavbarPreferences})
require.NoError(t, err)
err = ss.SavePreferences(context.Background(), &models.SavePreferencesCommand{OrgId: 1, TeamId: 2, Navbar: &team1NavbarPreferences})
require.NoError(t, err)
err = ss.SavePreferences(context.Background(), &models.SavePreferencesCommand{OrgId: 1, TeamId: 3, Navbar: &team2NavbarPreferences})
require.NoError(t, err)
err = ss.SavePreferences(context.Background(), &models.SavePreferencesCommand{OrgId: 1, UserId: 1, Navbar: &userNavbarPreferences})
require.NoError(t, err)
query := &models.GetPreferencesWithDefaultsQuery{
User: &models.SignedInUser{OrgId: 1, UserId: 2},
}
err = ss.GetPreferencesWithDefaults(context.Background(), query)
require.NoError(t, err)
require.Equal(t, &orgPreferencesJsonData, query.Result.JsonData)
})
t.Run("SavePreferences for a user should store correct values", func(t *testing.T) {
err := ss.SavePreferences(context.Background(), &models.SavePreferencesCommand{UserId: models.SignedInUser{}.UserId, Theme: "dark", Timezone: "browser", HomeDashboardId: 5, WeekStart: "1"})
err := ss.SavePreferences(context.Background(), &models.SavePreferencesCommand{UserId: models.SignedInUser{}.UserId, Theme: "dark", Timezone: "browser", HomeDashboardId: 5, WeekStart: "1", Navbar: &userNavbarPreferences})
require.NoError(t, err)
query := &models.GetPreferencesWithDefaultsQuery{User: &models.SignedInUser{}}
@@ -132,6 +265,33 @@ func TestPreferencesDataAccess(t *testing.T) {
Timezone: "browser",
WeekStart: "1",
Theme: "dark",
JsonData: &userPreferencesJsonData,
Created: query.Result.Created,
Updated: query.Result.Updated,
}
if diff := cmp.Diff(expected, query.Result); diff != "" {
t.Fatalf("Result mismatch (-want +got):\n%s", diff)
}
})
t.Run("PatchPreferences for a user should only modify a single value", func(t *testing.T) {
err := ss.SavePreferences(context.Background(), &models.SavePreferencesCommand{UserId: models.SignedInUser{}.UserId, Theme: "dark", Timezone: "browser", HomeDashboardId: 5, WeekStart: "1", Navbar: &orgNavbarPreferences})
require.NoError(t, err)
err = ss.PatchPreferences(context.Background(), &models.PatchPreferencesCommand{UserId: models.SignedInUser{}.UserId, Navbar: &userNavbarPreferences})
require.NoError(t, err)
query := &models.GetPreferencesWithDefaultsQuery{User: &models.SignedInUser{}}
err = ss.GetPreferencesWithDefaults(context.Background(), query)
require.NoError(t, err)
expected := &models.Preferences{
Id: query.Result.Id,
Version: query.Result.Version,
HomeDashboardId: 5,
Timezone: "browser",
WeekStart: "1",
Theme: "dark",
JsonData: &userPreferencesJsonData,
Created: query.Result.Created,
Updated: query.Result.Updated,
}