diff --git a/public/app/core/components/SharedPreferences/SharedPreferences.test.tsx b/public/app/core/components/SharedPreferences/SharedPreferences.test.tsx
new file mode 100644
index 00000000000..7ab303c8800
--- /dev/null
+++ b/public/app/core/components/SharedPreferences/SharedPreferences.test.tsx
@@ -0,0 +1,153 @@
+import { render, screen, waitFor } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
+import React from 'react';
+import TestProvider from 'test/helpers/TestProvider';
+import { assertInstanceOf } from 'test/helpers/asserts';
+import { getSelectParent, selectOptionInTest } from 'test/helpers/selectOptionInTest';
+
+import { UserPreferencesDTO } from 'app/types';
+
+import SharedPreferences from './SharedPreferences';
+
+jest.mock('app/core/services/backend_srv', () => {
+ return {
+ backendSrv: {
+ search: jest.fn().mockResolvedValue([
+ {
+ id: 2,
+ title: 'My Dashboard',
+ tags: [],
+ type: '',
+ uid: '',
+ uri: '',
+ url: '',
+ folderId: 0,
+ folderTitle: '',
+ folderUid: '',
+ folderUrl: '',
+ isStarred: false,
+ slug: '',
+ items: [],
+ },
+ {
+ id: 3,
+ title: 'Another Dashboard',
+ tags: [],
+ type: '',
+ uid: '',
+ uri: '',
+ url: '',
+ folderId: 0,
+ folderTitle: '',
+ folderUid: '',
+ folderUrl: '',
+ isStarred: false,
+ slug: '',
+ items: [],
+ },
+ ]),
+ },
+ };
+});
+
+const mockPreferences: UserPreferencesDTO = {
+ timezone: 'browser',
+ weekStart: 'monday',
+ theme: 'light',
+ homeDashboardId: 2,
+ queryHistory: {
+ homeTab: '',
+ },
+};
+
+const mockPrefsPatch = jest.fn();
+const mockPrefsUpdate = jest.fn();
+const mockPrefsLoad = jest.fn().mockResolvedValue(mockPreferences);
+
+jest.mock('app/core/services/PreferencesService', () => ({
+ PreferencesService: function () {
+ return {
+ patch: mockPrefsPatch,
+ update: mockPrefsUpdate,
+ load: mockPrefsLoad,
+ };
+ },
+}));
+
+const props = {
+ resourceUri: '/fake-api/user/1',
+};
+
+describe('SharedPreferences', () => {
+ const original = window.location;
+ const mockReload = jest.fn();
+
+ beforeAll(() => {
+ Object.defineProperty(window, 'location', {
+ configurable: true,
+ value: { reload: mockReload },
+ });
+ });
+
+ afterAll(() => {
+ Object.defineProperty(window, 'location', { configurable: true, value: original });
+ });
+
+ beforeEach(async () => {
+ mockReload.mockReset();
+ mockPrefsUpdate.mockReset();
+
+ render(
+
+
+
+ );
+
+ await waitFor(() => expect(mockPrefsLoad).toHaveBeenCalled());
+ });
+
+ it('renders the theme preference', () => {
+ const lightThemeRadio = assertInstanceOf(screen.getByLabelText('Light'), HTMLInputElement);
+ expect(lightThemeRadio.checked).toBeTruthy();
+ });
+
+ it('renders the home dashboard preference', () => {
+ const dashboardSelect = getSelectParent(screen.getByLabelText('Home Dashboard'));
+ expect(dashboardSelect).toHaveTextContent('My Dashboard');
+ });
+
+ it('renders the timezone preference', () => {
+ const tzSelect = getSelectParent(screen.getByLabelText('Timezone'));
+ expect(tzSelect).toHaveTextContent('Browser Time');
+ });
+
+ it('renders the week start preference', async () => {
+ const weekSelect = getSelectParent(screen.getByLabelText('Week start'));
+ expect(weekSelect).toHaveTextContent('Monday');
+ });
+
+ it("saves the user's new preferences", async () => {
+ const darkThemeRadio = assertInstanceOf(screen.getByLabelText('Dark'), HTMLInputElement);
+ await userEvent.click(darkThemeRadio);
+
+ await selectOptionInTest(screen.getByLabelText('Home Dashboard'), 'Another Dashboard');
+ await selectOptionInTest(screen.getByLabelText('Timezone'), 'Australia/Sydney');
+ await selectOptionInTest(screen.getByLabelText('Week start'), 'Saturday');
+
+ await userEvent.click(screen.getByText('Save'));
+ expect(mockPrefsUpdate).toHaveBeenCalledWith({
+ timezone: 'Australia/Sydney',
+ weekStart: 'saturday',
+ theme: 'dark',
+ homeDashboardId: 3,
+ queryHistory: {
+ homeTab: '',
+ },
+ });
+ });
+
+ it('refreshes the page after saving preferences', async () => {
+ await userEvent.click(screen.getByText('Save'));
+ expect(mockReload).toHaveBeenCalled();
+ });
+});
diff --git a/public/app/features/profile/UserProfileEditPage.test.tsx b/public/app/features/profile/UserProfileEditPage.test.tsx
index 83ada3e7937..905c9d4f77c 100644
--- a/public/app/features/profile/UserProfileEditPage.test.tsx
+++ b/public/app/features/profile/UserProfileEditPage.test.tsx
@@ -90,8 +90,6 @@ const defaultProps: Props = {
};
function getSelectors() {
- const dashboardSelect = () => screen.getByTestId('User preferences home dashboard drop down');
- const timepickerSelect = () => screen.getByTestId(selectors.components.TimeZonePicker.containerV2);
const teamsTable = () => screen.getByRole('table', { name: /user teams table/i });
const orgsTable = () => screen.getByTestId(selectors.components.UserProfile.orgsTable);
const sessionsTable = () => screen.getByTestId(selectors.components.UserProfile.sessionsTable);
@@ -100,10 +98,6 @@ function getSelectors() {
email: () => screen.getByRole('textbox', { name: /email/i }),
username: () => screen.getByRole('textbox', { name: /username/i }),
saveProfile: () => screen.getByTestId(selectors.components.UserProfile.profileSaveButton),
- dashboardSelect,
- dashboardValue: () => within(dashboardSelect()).getByText(/default/i),
- timepickerSelect,
- timepickerValue: () => within(timepickerSelect()).getByText(/coordinated universal time/i),
savePreferences: () => screen.getByTestId(selectors.components.UserProfile.preferencesSaveButton),
teamsTable,
teamsRow: () => within(teamsTable()).getByRole('row', { name: /team one team.one@test\.com 2000/i }),
@@ -166,16 +160,8 @@ describe('UserProfileEditPage', () => {
it('should show shared preferences', async () => {
await getTestContext();
- const { dashboardSelect, dashboardValue, timepickerSelect, timepickerValue, savePreferences } = getSelectors();
- expect(screen.getByRole('group', { name: /preferences/i })).toBeInTheDocument();
- expect(screen.getByRole('radio', { name: /default/i })).toBeInTheDocument();
- expect(screen.getByRole('radio', { name: /dark/i })).toBeInTheDocument();
- expect(screen.getByRole('radio', { name: /light/i })).toBeInTheDocument();
- expect(dashboardSelect()).toBeInTheDocument();
- expect(dashboardValue()).toBeInTheDocument();
- expect(timepickerSelect()).toBeInTheDocument();
- expect(timepickerValue()).toBeInTheDocument();
- expect(savePreferences()).toBeInTheDocument();
+ // SharedPreferences itself is tested, so here just make sure it's being rendered
+ expect(screen.getByLabelText('Home Dashboard')).toBeInTheDocument();
});
describe('and teams are loading', () => {
diff --git a/public/test/helpers/asserts.ts b/public/test/helpers/asserts.ts
new file mode 100644
index 00000000000..994741e0137
--- /dev/null
+++ b/public/test/helpers/asserts.ts
@@ -0,0 +1,10 @@
+export function assertInstanceOf }>(
+ value: unknown,
+ type: T
+): InstanceType {
+ if (!(value instanceof type)) {
+ throw new Error(`Expected value to be an instanceof ${typeof type} but got ${typeof value}`);
+ }
+
+ return value;
+}