mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-30 23:14:37 +00:00
test: expand unit + e2e coverage from test-map across core domains (#1724)
This commit is contained in:
@@ -2,9 +2,10 @@ import { configureStore } from '@reduxjs/toolkit';
|
||||
import { fireEvent, render, screen } from '@testing-library/react';
|
||||
import { Provider } from 'react-redux';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { REHYDRATE } from 'redux-persist';
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import mascotReducer, { setMascotColor } from '../../../../store/mascotSlice';
|
||||
import mascotReducer, { DEFAULT_MASCOT_COLOR, setMascotColor } from '../../../../store/mascotSlice';
|
||||
import MascotPanel from '../MascotPanel';
|
||||
|
||||
const { mockNavigateBack } = vi.hoisted(() => ({ mockNavigateBack: vi.fn() }));
|
||||
@@ -77,3 +78,52 @@ describe('MascotPanel', () => {
|
||||
expect(mockNavigateBack).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
||||
// Batch-5: rehydrate cases + unknown-color fallback (issue#1651, pr#1667)
|
||||
describe('MascotPanel — mascotSlice rehydrate guard', () => {
|
||||
it('restores a known persisted color from a REHYDRATE action', () => {
|
||||
const store = configureStore({ reducer: { mascot: mascotReducer } });
|
||||
store.dispatch({ type: REHYDRATE, key: 'mascot', payload: { color: 'burgundy' } });
|
||||
expect(store.getState().mascot.color).toBe('burgundy');
|
||||
});
|
||||
|
||||
it('falls back to yellow when REHYDRATE contains an unknown color string', () => {
|
||||
const store = configureStore({ reducer: { mascot: mascotReducer } });
|
||||
store.dispatch({ type: REHYDRATE, key: 'mascot', payload: { color: 'hot-pink' } });
|
||||
expect(store.getState().mascot.color).toBe(DEFAULT_MASCOT_COLOR);
|
||||
});
|
||||
|
||||
it('falls back to yellow when REHYDRATE payload is missing the color field', () => {
|
||||
const store = configureStore({ reducer: { mascot: mascotReducer } });
|
||||
store.dispatch({ type: REHYDRATE, key: 'mascot', payload: {} });
|
||||
expect(store.getState().mascot.color).toBe(DEFAULT_MASCOT_COLOR);
|
||||
});
|
||||
|
||||
it('falls back to yellow when REHYDRATE payload is null', () => {
|
||||
const store = configureStore({ reducer: { mascot: mascotReducer } });
|
||||
store.dispatch({ type: REHYDRATE, key: 'mascot', payload: null });
|
||||
expect(store.getState().mascot.color).toBe(DEFAULT_MASCOT_COLOR);
|
||||
});
|
||||
|
||||
it('ignores REHYDRATE actions for other slice keys', () => {
|
||||
const store = configureStore({ reducer: { mascot: mascotReducer } });
|
||||
store.dispatch(setMascotColor('navy'));
|
||||
store.dispatch({ type: REHYDRATE, key: 'someOtherSlice', payload: { color: 'green' } });
|
||||
// Should remain navy — we only handle key === 'mascot'.
|
||||
expect(store.getState().mascot.color).toBe('navy');
|
||||
});
|
||||
|
||||
it('renders the rehydrated color as selected in the panel', () => {
|
||||
const store = configureStore({ reducer: { mascot: mascotReducer } });
|
||||
store.dispatch({ type: REHYDRATE, key: 'mascot', payload: { color: 'green' } });
|
||||
render(
|
||||
<Provider store={store}>
|
||||
<MemoryRouter>
|
||||
<MascotPanel />
|
||||
</MemoryRouter>
|
||||
</Provider>
|
||||
);
|
||||
expect(screen.getByRole('radio', { name: 'Green' })).toHaveAttribute('aria-checked', 'true');
|
||||
expect(screen.getByRole('radio', { name: 'Yellow' })).toHaveAttribute('aria-checked', 'false');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,6 +4,8 @@ import { describe, expect, it, vi } from 'vitest';
|
||||
import { renderWithProviders } from '../../../../test/test-utils';
|
||||
import RecoveryPhrasePanel from '../RecoveryPhrasePanel';
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
|
||||
vi.mock('../../../../providers/CoreStateProvider', () => ({
|
||||
useCoreState: () => ({
|
||||
snapshot: { currentUser: null },
|
||||
@@ -47,3 +49,45 @@ describe('RecoveryPhrasePanel — trust-surface polish', () => {
|
||||
expect(container).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
// Batch-5: recovery/mnemonic mode-switch state reset (pr#1646)
|
||||
describe('RecoveryPhrasePanel — mode-switch state reset', () => {
|
||||
it('switches to import mode and shows import-mode UI', () => {
|
||||
renderWithProviders(<RecoveryPhrasePanel />);
|
||||
// Default: generate mode — amber callout visible
|
||||
expect(screen.getByText(/can never be recovered if lost/i)).toBeTruthy();
|
||||
|
||||
// Switch to import mode
|
||||
fireEvent.click(screen.getByText(/I already have a recovery phrase/i));
|
||||
expect(screen.getByText(/Enter your recovery phrase below/i)).toBeTruthy();
|
||||
});
|
||||
|
||||
it('resets confirmed checkbox when switching from generate to import', () => {
|
||||
renderWithProviders(<RecoveryPhrasePanel />);
|
||||
|
||||
// Check the confirmed checkbox in generate mode
|
||||
const checkbox = screen.getByRole('checkbox');
|
||||
fireEvent.click(checkbox);
|
||||
expect(checkbox).toBeChecked();
|
||||
|
||||
// Switch to import mode — confirmed should reset
|
||||
fireEvent.click(screen.getByText(/I already have a recovery phrase/i));
|
||||
// In import mode the "consent" checkbox is not shown, so confirmed state is reset
|
||||
expect(screen.queryByRole('checkbox')).toBeNull();
|
||||
|
||||
// Switch back to generate — checkbox should be unchecked (reset to false)
|
||||
fireEvent.click(screen.getByText(/Generate a new recovery phrase instead/i));
|
||||
const regeneratedCheckbox = screen.getByRole('checkbox');
|
||||
expect(regeneratedCheckbox).not.toBeChecked();
|
||||
});
|
||||
|
||||
it('shows generate-mode UI again after switching back from import', () => {
|
||||
renderWithProviders(<RecoveryPhrasePanel />);
|
||||
fireEvent.click(screen.getByText(/I already have a recovery phrase/i));
|
||||
expect(screen.getByText(/Enter your recovery phrase below/i)).toBeTruthy();
|
||||
|
||||
fireEvent.click(screen.getByText(/Generate a new recovery phrase instead/i));
|
||||
// Back in generate mode
|
||||
expect(screen.getByText(/can never be recovered if lost/i)).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user