mirror of
https://github.com/jkingsman/Remote-Terminal-for-MeshCore.git
synced 2026-08-07 17:23:05 +02:00
Add password-remember + warning on save
This commit is contained in:
@@ -7,6 +7,10 @@ describe('RepeaterLogin', () => {
|
||||
repeaterName: 'TestRepeater',
|
||||
loading: false,
|
||||
error: null as string | null,
|
||||
password: '',
|
||||
onPasswordChange: vi.fn(),
|
||||
rememberPassword: false,
|
||||
onRememberPasswordChange: vi.fn(),
|
||||
onLogin: vi.fn(),
|
||||
onLoginAsGuest: vi.fn(),
|
||||
};
|
||||
@@ -26,20 +30,45 @@ describe('RepeaterLogin', () => {
|
||||
render(<RepeaterLogin {...defaultProps} />);
|
||||
|
||||
expect(screen.getByPlaceholderText('Repeater password...')).toBeInTheDocument();
|
||||
expect(screen.getByText('Remember password')).toBeInTheDocument();
|
||||
expect(screen.getByText('Login with Password')).toBeInTheDocument();
|
||||
expect(screen.getByText('Login as Guest / ACLs')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('calls onLogin with trimmed password on submit', () => {
|
||||
render(<RepeaterLogin {...defaultProps} />);
|
||||
|
||||
const input = screen.getByPlaceholderText('Repeater password...');
|
||||
fireEvent.change(input, { target: { value: ' secret ' } });
|
||||
render(<RepeaterLogin {...defaultProps} password=" secret " />);
|
||||
fireEvent.submit(screen.getByText('Login with Password').closest('form')!);
|
||||
|
||||
expect(defaultProps.onLogin).toHaveBeenCalledWith('secret');
|
||||
});
|
||||
|
||||
it('propagates password changes', () => {
|
||||
render(<RepeaterLogin {...defaultProps} />);
|
||||
|
||||
const input = screen.getByPlaceholderText('Repeater password...');
|
||||
fireEvent.change(input, { target: { value: 'new secret' } });
|
||||
|
||||
expect(defaultProps.onPasswordChange).toHaveBeenCalledWith('new secret');
|
||||
});
|
||||
|
||||
it('toggles remember password checkbox', () => {
|
||||
render(<RepeaterLogin {...defaultProps} />);
|
||||
|
||||
fireEvent.click(screen.getByLabelText('Remember password'));
|
||||
|
||||
expect(defaultProps.onRememberPasswordChange).toHaveBeenCalledWith(true);
|
||||
});
|
||||
|
||||
it('shows storage warning when remember password is enabled', () => {
|
||||
render(<RepeaterLogin {...defaultProps} rememberPassword={true} />);
|
||||
|
||||
expect(
|
||||
screen.getByText(
|
||||
/Passwords are stored unencrypted in local browser storage for this domain\./
|
||||
)
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('calls onLoginAsGuest when guest button clicked', () => {
|
||||
render(<RepeaterLogin {...defaultProps} />);
|
||||
|
||||
|
||||
@@ -1 +1,9 @@
|
||||
import '@testing-library/jest-dom';
|
||||
|
||||
class ResizeObserver {
|
||||
observe() {}
|
||||
unobserve() {}
|
||||
disconnect() {}
|
||||
}
|
||||
|
||||
globalThis.ResizeObserver = ResizeObserver;
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
import { act, renderHook } from '@testing-library/react';
|
||||
import { beforeEach, describe, expect, it } from 'vitest';
|
||||
|
||||
import { useRememberedServerPassword } from '../hooks/useRememberedServerPassword';
|
||||
|
||||
describe('useRememberedServerPassword', () => {
|
||||
beforeEach(() => {
|
||||
localStorage.clear();
|
||||
});
|
||||
|
||||
it('loads remembered passwords from localStorage', () => {
|
||||
localStorage.setItem(
|
||||
'remoteterm-server-password:repeater:abc123',
|
||||
JSON.stringify({ password: 'stored-secret' })
|
||||
);
|
||||
|
||||
const { result } = renderHook(() => useRememberedServerPassword('repeater', 'abc123'));
|
||||
|
||||
expect(result.current.password).toBe('stored-secret');
|
||||
expect(result.current.rememberPassword).toBe(true);
|
||||
});
|
||||
|
||||
it('stores passwords after login when remember is enabled', () => {
|
||||
const { result } = renderHook(() => useRememberedServerPassword('room', 'room-key'));
|
||||
|
||||
act(() => {
|
||||
result.current.setRememberPassword(true);
|
||||
});
|
||||
|
||||
act(() => {
|
||||
result.current.persistAfterLogin(' hello ');
|
||||
});
|
||||
|
||||
expect(localStorage.getItem('remoteterm-server-password:room:room-key')).toBe(
|
||||
JSON.stringify({ password: 'hello' })
|
||||
);
|
||||
expect(result.current.password).toBe('hello');
|
||||
});
|
||||
|
||||
it('clears stored passwords when login is done with remember disabled', () => {
|
||||
localStorage.setItem(
|
||||
'remoteterm-server-password:repeater:abc123',
|
||||
JSON.stringify({ password: 'stored-secret' })
|
||||
);
|
||||
|
||||
const { result } = renderHook(() => useRememberedServerPassword('repeater', 'abc123'));
|
||||
|
||||
act(() => {
|
||||
result.current.setRememberPassword(false);
|
||||
});
|
||||
|
||||
act(() => {
|
||||
result.current.persistAfterLogin('new-secret');
|
||||
});
|
||||
|
||||
expect(localStorage.getItem('remoteterm-server-password:repeater:abc123')).toBeNull();
|
||||
expect(result.current.password).toBe('');
|
||||
});
|
||||
|
||||
it('preserves remembered passwords on guest login when remember stays enabled', () => {
|
||||
localStorage.setItem(
|
||||
'remoteterm-server-password:room:room-key',
|
||||
JSON.stringify({ password: 'stored-secret' })
|
||||
);
|
||||
|
||||
const { result } = renderHook(() => useRememberedServerPassword('room', 'room-key'));
|
||||
|
||||
act(() => {
|
||||
result.current.persistAfterLogin('');
|
||||
});
|
||||
|
||||
expect(localStorage.getItem('remoteterm-server-password:room:room-key')).toBe(
|
||||
JSON.stringify({ password: 'stored-secret' })
|
||||
);
|
||||
expect(result.current.password).toBe('stored-secret');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user