Anvil/tests/components/molecules/SettingsAppearance.test.ts
André Jaenisch 5af877bcaa
feat: add Appearance panel to Settings modal
This features two knobs: theming and indent.
I was curious whether I could actually hand the theme switching to the
parent, so I created an event dispatcher for it.

It works! But I had to hack the Svelte component a little.
I also need to sync it two the theme switcher in the popup and go over
every component that is focused on light mode only at the moment. To
limit the work I will constraint myself to the Profile page here. If the
theme is meant to apply to other pages as well, we will need to persist
the setting. That means a database in Anvil, I guess. I'm not willing to
take that step right now. It must come at some point (e.g. when talking
to Vervis to actually inform about changes made in Anvil).

Signed-off-by: André Jaenisch <andre.jaenisch@posteo.de>
2024-08-09 08:32:15 +02:00

82 lines
2.7 KiB
TypeScript

/* Component test for SettingsAppearance molecule.
* Copyright (C) 2024 André Jaenisch
* SPDX-FileCopyrightText: 2024 André Jaenisch
* SPDX-License-Identifier: AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import '@testing-library/jest-dom';
import { render, screen } from '@testing-library/svelte';
import { init, locale, register } from 'svelte-i18n';
import SettingsAppearance from '../../../src/lib/components/molecules/SettingsAppearance.svelte';
import enMessages from '../../../src/lib/i18n/locales/en.json';
describe('SettingsAppearance.svelte', () => {
beforeEach(() => {
register('en', () => import('../../../src/lib/i18n/locales/en.json'));
init({ fallbackLocale: 'en', initialLocale: 'en' });
locale.set('en');
});
it('should mount', () => {
// Arrange
// Nothing to prepare
// Act
const { container } = render(SettingsAppearance);
// Assert
expect(container).toBeTruthy();
});
it('should have a radio group for themes', () => {
// Arrange
// Nothing to prepare
// Act
render(SettingsAppearance);
// Assert
expect(screen.getByLabelText(enMessages.settings.appearance.theme.light)).toBeInTheDocument();
expect(screen.getByLabelText(enMessages.settings.appearance.theme.dark)).toBeInTheDocument();
expect(screen.getByLabelText(enMessages.settings.appearance.theme.auto)).toBeInTheDocument();
});
describe('when clicking a theme', () => {
it('should dispatch a switch-theme event', () => {
// Arrange
const listener = vi.fn();
// Act
const { component } = render(SettingsAppearance);
component.$on('switch-theme', listener);
const darkTheme = screen.getByLabelText(enMessages.settings.appearance.theme.dark);
darkTheme.click();
const ev = new CustomEvent({ detail: 'dark' });
// Assert
expect(listener).toHaveBeenCalledOnce();
expect(listener).toHaveBeenCalledWith(ev);
});
});
// TODO: Mark up proper label and input
it.skip('should have a tab indent input', () => {
// Arrange
// Nothing to prepare
// Act
render(SettingsAppearance);
// Assert
expect(
screen.getByPlaceholderText(enMessages.settings.appearance.tab_indent.label)
).toBeInTheDocument();
});
});