Chore: SharedPreferences tests (#51132)

* Add a test assertion function to make testing a little bit easier

* Add tests for SharedPreferences

* Remove some tests from UserProfileEditPage because we're testing SharedPreferences directly now
This commit is contained in:
Josh Hunt 2022-06-21 09:36:34 +01:00 committed by GitHub
parent 05fbfdaa13
commit 47abf44224
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 165 additions and 16 deletions

View File

@ -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(
<TestProvider>
<SharedPreferences {...props} />
</TestProvider>
);
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();
});
});

View File

@ -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', () => {

View File

@ -0,0 +1,10 @@
export function assertInstanceOf<T extends { new (...args: unknown[]): InstanceType<T> }>(
value: unknown,
type: T
): InstanceType<T> {
if (!(value instanceof type)) {
throw new Error(`Expected value to be an instanceof ${typeof type} but got ${typeof value}`);
}
return value;
}