unit tests fixin
Some checks failed
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Failing after 58s
Some checks failed
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Failing after 58s
This commit is contained in:
@@ -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();
|
||||
});
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user