Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions __mocks__/services/palshub/AuthService.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,16 @@ const mockAuthService = {
isInitialized: true,

// Methods
signInWithEmail: jest.fn().mockResolvedValue(undefined),
signInWithEmail: jest.fn().mockResolvedValue(true),

signUpWithEmail: jest.fn().mockResolvedValue(undefined),
signUpWithEmail: jest.fn().mockResolvedValue(true),

signInWithGoogle: jest.fn().mockResolvedValue({
success: true,
user: mockProfile,
}),

resetPassword: jest.fn().mockResolvedValue(undefined),
resetPassword: jest.fn().mockResolvedValue(true),

signOut: jest.fn().mockResolvedValue({
success: true,
Expand Down
38 changes: 22 additions & 16 deletions src/components/PalsHub/AuthSheet/AuthSheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,21 +58,25 @@ export const AuthSheet: React.FC<AuthSheetProps> = observer(
authService.clearError();

if (isSignUp) {
await authService.signUpWithEmail(
const ok = await authService.signUpWithEmail(
email.trim(),
password,
fullName.trim(),
);
Alert.alert(
'Account Created',
'Please check your email to verify your account.',
[{text: 'OK', onPress: onClose}],
);
if (ok) {
Alert.alert(
'Account Created',
'Please check your email to verify your account.',
[{text: 'OK', onPress: onClose}],
);
}
} else {
await authService.signInWithEmail(email.trim(), password);
Alert.alert('Welcome Back!', 'You have successfully signed in.', [
{text: 'OK', onPress: onClose},
]);
const ok = await authService.signInWithEmail(email.trim(), password);
if (ok) {
Alert.alert('Welcome Back!', 'You have successfully signed in.', [
{text: 'OK', onPress: onClose},
]);
}
}
} catch (error) {
const errorInfo = PalsHubErrorHandler.handle(error);
Expand Down Expand Up @@ -105,12 +109,14 @@ export const AuthSheet: React.FC<AuthSheetProps> = observer(

try {
setIsLoading(true);
await authService.resetPassword(email.trim());
Alert.alert(
'Password Reset',
'Check your email for password reset instructions.',
[{text: 'OK'}],
);
const ok = await authService.resetPassword(email.trim());
if (ok) {
Alert.alert(
'Password Reset',
'Check your email for password reset instructions.',
[{text: 'OK'}],
);
}
} catch (error) {
const errorInfo = PalsHubErrorHandler.handle(error);
Alert.alert('Error', errorInfo.userMessage);
Expand Down
40 changes: 40 additions & 0 deletions src/components/PalsHub/AuthSheet/__tests__/AuthSheet.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,25 @@ describe('AuthSheet', () => {
});
});

it('does not show "Welcome Back!" when sign-in fails', async () => {
(authService.signInWithEmail as jest.Mock).mockResolvedValueOnce(false);

const {getByTestId, getByText} = render(<AuthSheet {...defaultProps} />);

fireEvent.changeText(getByTestId('email-input'), 'test@example.com');
fireEvent.changeText(getByTestId('password-input'), 'wrongpass');
fireEvent.press(getByText('Sign In'));

await waitFor(() => {
expect(authService.signInWithEmail).toHaveBeenCalled();
});
expect(Alert.alert).not.toHaveBeenCalledWith(
'Welcome Back!',
expect.anything(),
expect.anything(),
);
});

it('shows error alert when email is empty', async () => {
const {getByTestId, getByText} = render(<AuthSheet {...defaultProps} />);

Expand Down Expand Up @@ -265,6 +284,27 @@ describe('AuthSheet', () => {
});
});

it('does not show "Account Created" when sign-up fails', async () => {
(authService.signUpWithEmail as jest.Mock).mockResolvedValueOnce(false);

const {getByTestId, getByText} = render(<AuthSheet {...defaultProps} />);
fireEvent.press(getByText('Sign Up'));

fireEvent.changeText(getByTestId('full-name-input'), 'Test User');
fireEvent.changeText(getByTestId('email-input'), 'test@example.com');
fireEvent.changeText(getByTestId('password-input'), '123');
fireEvent.press(getByText('Create Account'));

await waitFor(() => {
expect(authService.signUpWithEmail).toHaveBeenCalled();
});
expect(Alert.alert).not.toHaveBeenCalledWith(
'Account Created',
expect.anything(),
expect.anything(),
);
});

it('shows error alert when full name is empty during sign up', async () => {
const {getByTestId, getByText} = render(<AuthSheet {...defaultProps} />);

Expand Down
25 changes: 19 additions & 6 deletions src/services/palshub/AuthService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -288,12 +288,12 @@ class AuthService {
}
}

async signInWithEmail(email: string, password: string) {
async signInWithEmail(email: string, password: string): Promise<boolean> {
if (!this.isSupabaseConfigured()) {
runInAction(() => {
this.error = 'Authentication not configured';
});
return;
return false;
}

try {
Expand All @@ -312,25 +312,32 @@ class AuthService {
this.error = error.message;
});
console.error('Email sign-in error:', error);
return false;
}
return true;
} catch (error) {
runInAction(() => {
this.error = 'Failed to sign in with email';
});
console.error('Email sign-in error:', error);
return false;
} finally {
runInAction(() => {
this.isLoading = false;
});
}
}

async signUpWithEmail(email: string, password: string, fullName?: string) {
async signUpWithEmail(
email: string,
password: string,
fullName?: string,
): Promise<boolean> {
if (!this.isSupabaseConfigured()) {
runInAction(() => {
this.error = 'Authentication not configured';
});
return;
return false;
}

try {
Expand All @@ -354,12 +361,15 @@ class AuthService {
this.error = error.message;
});
console.error('Email sign-up error:', error);
return false;
}
return true;
} catch (error) {
runInAction(() => {
this.error = 'Failed to sign up with email';
});
console.error('Email sign-up error:', error);
return false;
} finally {
runInAction(() => {
this.isLoading = false;
Expand Down Expand Up @@ -401,12 +411,12 @@ class AuthService {
}
}

async resetPassword(email: string) {
async resetPassword(email: string): Promise<boolean> {
if (!this.isSupabaseConfigured()) {
runInAction(() => {
this.error = 'Authentication not configured';
});
return;
return false;
}

try {
Expand All @@ -424,12 +434,15 @@ class AuthService {
this.error = error.message;
});
console.error('Password reset error:', error);
return false;
}
return true;
} catch (error) {
runInAction(() => {
this.error = 'Failed to send password reset email';
});
console.error('Password reset error:', error);
return false;
} finally {
runInAction(() => {
this.isLoading = false;
Expand Down
Loading