import { describe, it, expect, vi, beforeEach } from 'vitest' import { mount } from '@vue/test-utils' import { setActivePinia, createPinia } from 'pinia' import SettingsView from '@/views/SettingsView.vue' import { useAuthStore } from '@/stores/auth' import { THEMES } from '@/composables/useTheme' describe('SettingsView', () => { beforeEach(() => { setActivePinia(createPinia()) }) it('renders one swatch per theme and the user email', () => { const auth = useAuthStore() auth.setUser({ id: 1, email: 'matt@example.com', roles: [], theme: 'warm-craft', timezone: 'UTC' }) const wrapper = mount(SettingsView) expect(wrapper.findAll('.theme-swatch')).toHaveLength(THEMES.length) expect(wrapper.text()).toContain('matt@example.com') }) it('marks the user current theme as the active swatch', () => { const auth = useAuthStore() auth.setUser({ id: 1, email: 'm@e', roles: [], theme: 'ocean-dusk', timezone: 'UTC' }) const wrapper = mount(SettingsView) const active = wrapper.find('.theme-swatch--active') expect(active.attributes('aria-label')).toBe('Ocean Dusk') expect(active.attributes('aria-checked')).toBe('true') }) it('falls back to warm-craft as active when user has no theme set', () => { const auth = useAuthStore() auth.setUser({ id: 1, email: 'm@e', roles: [], theme: null, timezone: 'UTC' }) const wrapper = mount(SettingsView) expect(wrapper.find('.theme-swatch--active').attributes('aria-label')).toBe('Warm Craft') }) it('clicking a swatch saves the theme via PATCH /api/user/theme', async () => { const auth = useAuthStore() auth.setUser({ id: 1, email: 'm@e', roles: [], theme: 'warm-craft', timezone: 'UTC' }) const fetchMock = vi.fn().mockResolvedValue({ ok: true }) vi.stubGlobal('fetch', fetchMock) const wrapper = mount(SettingsView) const swatch = wrapper.findAll('.theme-swatch').find(s => s.attributes('aria-label') === 'Sage & Cream')! await swatch.trigger('click') expect(fetchMock).toHaveBeenCalledWith( '/api/user/theme', expect.objectContaining({ method: 'PATCH', body: JSON.stringify({ theme: 'sage-cream' }), }), ) vi.unstubAllGlobals() }) it('renders a Sign out link to /logout', () => { const auth = useAuthStore() auth.setUser({ id: 1, email: 'm@e', roles: [], theme: 'warm-craft', timezone: 'UTC' }) const wrapper = mount(SettingsView) const logout = wrapper.find('a.settings__logout') expect(logout.text()).toBe('Sign out') expect(logout.attributes('href')).toBe('/logout') }) })