Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error handling for API call fails for Scheduled post #8634

Open
wants to merge 8 commits into
base: scheduled_post_error_map
Choose a base branch
from

Conversation

Rajat-Dabade
Copy link
Contributor

Summary

Ticket Link

Checklist

  • Added or updated unit tests (required for all new features)
  • Has UI changes
  • Includes text changes and localization file updates
  • Have tested against the 5 core themes to ensure consistency between them.
  • Have run E2E tests by adding label E2E iOS tests for PR.

Device Information

This PR was tested on:

Screenshots

Release Note


@Rajat-Dabade Rajat-Dabade force-pushed the scheduled-post-disconnected-erro branch from d53d2d5 to 2b68e34 Compare February 26, 2025 05:08
@Rajat-Dabade Rajat-Dabade marked this pull request as ready for review February 26, 2025 07:07
@Rajat-Dabade Rajat-Dabade self-assigned this Feb 26, 2025
@@ -847,6 +847,7 @@
"msg_typing.areTyping": "{users} and {last} are typing...",
"msg_typing.isTyping": "{user} is typing...",
"native.ios.notifications.not_verified": "We could not verify this notification with the server",
"network_connection.not_connected": "No internet connection",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not factually correct. You can have internet connection but not being in the same VPN as the server, or the server may be down.

@abhijit-singh @cwarnermm @enahum We should come up with a messaging that we are comfortable with, and use it in all similar places, and somehow document it so we know for sure what is the messaging we want to give.

My proposal here is:
"Cannot reach the server"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

100000% agree!! In fact I added some commets about this in the PR

if (res?.error) {
showSnackBar({
barType: SNACK_BAR_TYPE.DELETE_SCHEDULED_POST_ERROR,
customMessage: (res.error as Error).message,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have an tuil function to deal with this: getErrorMessage. Use that instead.

@@ -108,6 +116,27 @@ describe('deleteScheduledPostConfirmation', () => {
// Should not throw when swipeable.current is null
expect(() => cancelButton.onPress()).not.toThrow();
});

it('shows error snackbar when deleteScheduledPost fails', async () => {
const showSnackBar = require('@utils/snack_bar').showSnackBar;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we use require here instead of a normal import?

it('shows error snackbar when deleteScheduledPost fails', async () => {
const showSnackBar = require('@utils/snack_bar').showSnackBar;
const errorMessage = 'Failed to delete scheduled post';
(deleteScheduledPost as jest.Mock).mockResolvedValueOnce({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use jest.mocked instead of as jest.Mock.

deleteScheduledPostConfirmation(baseProps);

// Get the confirm button callback
const confirmButton = (Alert.alert as jest.Mock).mock.calls[0][2][1];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use jest.mocked instead of as jest.Mock.

Comment on lines +25 to +38
// We need to directly mock the fireEvent.press to make it work
const originalFireEvent = fireEvent.press;
fireEvent.press = jest.fn((element) => {
const result = originalFireEvent(element);

// If this is the send button, trigger the sendMessageWithAlert mock
if (element.props.testID === 'send_draft_button') {
setTimeout(() => {
sendMessageWithAlert({} as Parameters<typeof sendMessageWithAlert>[0]);
}, 0);
}

return result;
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels really wrong. We should find a way to do this without mocking the fire event. If you want, schedule some time with me and we can look at how to handle this.

await waitFor(() => expect(sendMessageWithAlert).toHaveBeenCalled());

// Use a simple timeout instead of waitFor
await new Promise((resolve) => setTimeout(resolve, 100));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use TestHelper wait for this.

fireEvent.press(sendDraftButton);
await waitFor(() => expect(sendMessageWithAlert).toHaveBeenCalled());

// Use a simple timeout instead of waitFor
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(For my own knowledge) Why waitFor doesn't work here?

return Promise.resolve();
});
// Reset the mock first
(sendMessageWithAlert as jest.Mock).mockReset();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jest.mocked instead of as jest.mock

Comment on lines +245 to +247
// Manually call clearDraft to verify it works
props.clearDraft();
expect(mockClearDraft).toHaveBeenCalled();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is testing nothing. If you call it of course it has been called.

Copy link
Contributor

@enahum enahum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Daniel review

Comment on lines -183 to -194
await act(async () => {
fireEvent.press(sendButton);
});

await waitFor(() => {
expect(sendMessageWithAlert).toHaveBeenCalledWith(expect.objectContaining({
channelName: 'test-channel',
title: expect.any(String),
intl: expect.any(Object),
sendMessageHandler: expect.any(Function),
}));
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I know, this is the proper way of doing it

if (websocketState !== 'connected') {
showSnackBar({
barType: SNACK_BAR_TYPE.CONNECTION_ERROR,
customMessage: intl.formatMessage({id: 'network_connection.not_connected', defaultMessage: 'No internet connection'}),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really bad error message, this should definitely be changed, device may have internet but the connection to the websocket fails for whatever reason. Also, why rely on the WS connection state here?

if (websocketState !== 'connected') {
showSnackBar({
barType: SNACK_BAR_TYPE.CONNECTION_ERROR,
customMessage: intl.formatMessage({id: 'network_connection.not_connected', defaultMessage: 'No internet connection'}),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment and question as before

import {useTheme} from '@context/theme';
import {useHandleSendMessage} from '@hooks/handle_send_message';
import {usePersistentNotificationProps} from '@hooks/persistent_notification_props';
import websocket_manager from '@managers/websocket_manager';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree

if (websocketState !== 'connected') {
showSnackBar({
barType: SNACK_BAR_TYPE.CONNECTION_ERROR,
customMessage: intl.formatMessage({id: 'network_connection.not_connected', defaultMessage: 'No internet connection'}),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

@@ -847,6 +847,7 @@
"msg_typing.areTyping": "{users} and {last} are typing...",
"msg_typing.isTyping": "{user} is typing...",
"native.ios.notifications.not_verified": "We could not verify this notification with the server",
"network_connection.not_connected": "No internet connection",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

100000% agree!! In fact I added some commets about this in the PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants