unit tests fixin
Some checks failed
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Failing after 58s

This commit is contained in:
2025-11-21 20:20:28 -08:00
parent 4f6d07ac7d
commit 7f24ef1790
2 changed files with 37 additions and 9 deletions

View File

@@ -112,10 +112,11 @@ describe('ProfileManager Authentication Flows', () => {
fireEvent.click(screen.getByRole('button', { name: /^sign in$/i }));
await waitFor(() => {
expect(apiClient.loginUser).toHaveBeenCalledWith('user@test.com', 'securepassword');
expect(apiClient.loginUser).toHaveBeenCalledWith('user@test.com', 'securepassword', false);
expect(mockOnLoginSuccess).toHaveBeenCalledWith(
{ id: '123', email: 'test@example.com' },
'mock-token'
'mock-token',
false
);
expect(mockOnClose).toHaveBeenCalled();
});
@@ -129,7 +130,7 @@ describe('ProfileManager Authentication Flows', () => {
fireEvent.change(screen.getByLabelText(/^Password$/i), { target: { value: 'wrongpassword' } });
fireEvent.click(screen.getByRole('button', { name: /^sign in$/i }));
await waitFor(() => {
await waitFor(() => {
expect(screen.getByText('Invalid credentials')).toBeInTheDocument();
});
expect(mockOnLoginSuccess).not.toHaveBeenCalled();
@@ -142,7 +143,11 @@ describe('ProfileManager Authentication Flows', () => {
fireEvent.click(screen.getByRole('button', { name: /^sign in$/i }));
expect(screen.getByTestId('loading-spinner')).toBeInTheDocument();
await waitFor(() => {
const button = screen.getByRole('button', { name: /^Sign In$/i });
expect(button).toBeDisabled();
expect(button.querySelector('svg.animate-spin')).toBeInTheDocument();
});
});
// --- Registration Functionality ---
@@ -165,10 +170,11 @@ describe('ProfileManager Authentication Flows', () => {
fireEvent.click(screen.getByRole('button', { name: /register/i })); // Submit register form
await waitFor(() => {
expect(apiClient.registerUser).toHaveBeenCalledWith('newuser@test.com', 'newsecurepassword');
expect(apiClient.registerUser).toHaveBeenCalledWith('newuser@test.com', 'newsecurepassword', '', '');
expect(mockOnLoginSuccess).toHaveBeenCalledWith(
{ id: '123', email: 'test@example.com' },
'mock-token'
'mock-token',
false
);
expect(mockOnClose).toHaveBeenCalled();
});
@@ -193,7 +199,8 @@ describe('ProfileManager Authentication Flows', () => {
expect(apiClient.registerUser).toHaveBeenCalledWith('newuser@test.com', 'newsecurepassword', 'New Test User', 'http://example.com/new.png');
expect(mockOnLoginSuccess).toHaveBeenCalledWith(
{ id: '123', email: 'test@example.com' },
'mock-token'
'mock-token',
false
);
expect(mockOnClose).toHaveBeenCalled();
});

View File

@@ -53,6 +53,7 @@ export const ProfileManager: React.FC<ProfileManagerProps> = ({ isOpen, onClose,
const [authLoading, setAuthLoading] = useState(false);
const [authError, setAuthError] = useState('');
const [isForgotPassword, setIsForgotPassword] = useState(false);
const [resetSuccessMessage, setResetSuccessMessage] = useState('');
const [rememberMe, setRememberMe] = useState(false);
@@ -72,6 +73,7 @@ export const ProfileManager: React.FC<ProfileManagerProps> = ({ isOpen, onClose,
setAuthError('');
setIsRegistering(false);
setIsForgotPassword(false);
setResetSuccessMessage('');
setRememberMe(false); // Reset on open
}
}, [isOpen, profile]); // Depend on isOpen and profile
@@ -255,8 +257,9 @@ export const ProfileManager: React.FC<ProfileManagerProps> = ({ isOpen, onClose,
e.preventDefault();
setAuthLoading(true);
try {
const response = await requestPasswordReset(authEmail);
notifySuccess(response.message);
const { message } = await requestPasswordReset(authEmail);
// Instead of a toast, show an inline success message.
setResetSuccessMessage(message);
logger.info('Password reset email sent successfully.', { email: authEmail });
} catch (error) {
const errorMessage = error instanceof Error ? error.message : 'An unknown error occurred.';
@@ -321,6 +324,11 @@ export const ProfileManager: React.FC<ProfileManagerProps> = ({ isOpen, onClose,
<label htmlFor="resetEmail" className="block text-sm font-medium text-gray-700 dark:text-gray-300">Email Address</label>
<input id="resetEmail" type="email" value={authEmail} onChange={e => setAuthEmail(e.target.value)} required className="mt-1 block w-full px-3 py-2 bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm" />
</div>
{resetSuccessMessage && (
<div className="text-center text-sm text-green-600 dark:text-green-400 bg-green-50 dark:bg-green-900/20 p-3 rounded-md">
{resetSuccessMessage}
</div>
</div>
<div className="pt-2">
<button type="submit" disabled={authLoading} className="w-full bg-brand-secondary hover:bg-brand-dark disabled:bg-gray-400 text-white font-bold py-2.5 px-4 rounded-lg flex justify-center">
{authLoading ? <div className="w-5 h-5"><LoadingSpinner /></div> : 'Send Reset Link'}
@@ -337,6 +345,19 @@ export const ProfileManager: React.FC<ProfileManagerProps> = ({ isOpen, onClose,
<div className="p-8">
<h2 className="text-2xl font-bold text-gray-800 dark:text-white mb-1">{isRegistering ? 'Create an Account' : 'Sign In'}</h2>
<p className="text-sm text-gray-500 dark:text-gray-400 mb-6">{isRegistering ? 'to get started.' : 'to access your account.'}</p>
{/* When registering, show optional fields for full name and avatar URL */}
{isRegistering && (
<div className="space-y-4 mb-4">
<div>
<label htmlFor="authFullName" className="block text-sm font-medium text-gray-700 dark:text-gray-300">Full Name</label>
<input id="authFullName" type="text" value={authFullName} onChange={e => setAuthFullName(e.target.value)} className="mt-1 block w-full px-3 py-2 bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm" placeholder="Optional" />
</div>
<div>
<label htmlFor="authAvatarUrl" className="block text-sm font-medium text-gray-700 dark:text-gray-300">Avatar URL</label>
<input id="authAvatarUrl" type="url" value={authAvatarUrl} onChange={e => setAuthAvatarUrl(e.target.value)} className="mt-1 block w-full px-3 py-2 bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm" placeholder="Optional, e.g., http://example.com/avatar.png" />
</div>
</div>
)}
<form onSubmit={handleAuthSubmit} className="space-y-4">
<div>
<label htmlFor="authEmail" className="block text-sm font-medium text-gray-700 dark:text-gray-300">Email Address</label>