-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Scheduled post Actions #8603
base: list-scheduled-post
Are you sure you want to change the base?
Scheduled post Actions #8603
Conversation
ad1c32e
to
10b0d66
Compare
de2b148
to
3a6f367
Compare
cd6e159
to
2bd8672
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some comments to address, but in general it looks good.
app/screens/draft_scheduled_post_options/draft_scheduled_post_options.test.tsx
Outdated
Show resolved
Hide resolved
app/components/post_draft/send_handler/__tests__/send_handler.test.tsx
Outdated
Show resolved
Hide resolved
app/components/post_draft/send_handler/__tests__/send_handler.test.tsx
Outdated
Show resolved
Hide resolved
app/components/post_draft/send_handler/__tests__/send_handler.test.tsx
Outdated
Show resolved
Hide resolved
app/components/post_draft/send_handler/__tests__/send_handler.test.tsx
Outdated
Show resolved
Hide resolved
68bf2da
to
63d31e5
Compare
2bd8672
to
5517875
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few more things to look at in the tests.
// Mock implementation to capture the sendMessageHandler | ||
let capturedHandler: Function; | ||
(sendMessageWithAlert as jest.Mock).mockImplementation((params) => { | ||
capturedHandler = params.sendMessageHandler; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Personal opinion) This is one way to do it, but I think it is more elegant to inspect the mock calls instead of trying to set this variable. 0/5.
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, []); | ||
|
||
const toggleSaveButton = useCallback(preventDoubleTap((enabled = true) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a hook called usePreventDoubleTap, use that one instead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
} | ||
}, [intl, onClose]); | ||
|
||
const onSavePostMessage = useCallback(async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should have the prevent double tap has well, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! A couple more comments, but really minor things.
|
||
it('calls dismissBottomSheet and showModal when pressed', async () => { | ||
// Mock implementation to resolve immediately | ||
(dismissBottomSheet as jest.Mock).mockResolvedValue(undefined); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One last jest.Mock
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
cancelButton.onPress?.(); | ||
|
||
// Verify swipeable close is called | ||
expect(baseProps.swipeable?.current?.close).toHaveBeenCalled(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be nice to verify the delete
has not been called in this scenario.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
const buttons = alertMock.mock.calls[0]?.[2] ?? []; // Ensure buttons array exists | ||
const cancelButton = buttons[0]; | ||
expect(cancelButton).toBeDefined(); | ||
const onPress = cancelButton.onPress ?? (() => {}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is weird. If the ?? (() => {})
part is just to keep typescript happy, you can use the non-null assertion operator (!
the exclamation mark) to tell TS that you are sure it is never going to be undefined.
The non-null assertion operator is dangerous and should be used scarcely, but in this scenario should be fine.
// Check that the component registered with proper navigation handler | ||
const registerCall = jest.mocked(Navigation.events().registerComponentListener).mock.calls[0][0]; | ||
expect(registerCall).toBeDefined(); | ||
expect(registerCall.navigationButtonPressed).toBeDefined(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We check it exist. Do we want to check if it does what it has to do? I would expect something similar to what you have in the last test of this file, but also for other buttons (not only the close one).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added what happens when it clicked on save button.
const setButtonsMock = jest.mocked(setButtons); | ||
const mockCalls = setButtonsMock.mock.calls; | ||
|
||
const lastCallIndex = mockCalls.length - 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can clear the mocks (setButtonsMock.clearMocks) before performing the action that will trigger this.
If there are more than one call because of executing the action, could mean you are calling it more than needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure
import {Screens} from '@constants'; | ||
import {dismissBottomSheet, showModal} from '@screens/navigation'; | ||
import {renderWithIntlAndTheme} from '@test/intl-test-helper'; | ||
import test_helper from '@test/test_helper'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Import this as TestHelper
, please.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
const draftInput = wrapper.getByTestId('test_send_handler'); | ||
expect(draftInput).toBeTruthy(); | ||
const priority = wrapper.getByText('URGENT'); | ||
expect(priority).toBeTruthy(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
0/5 for simplicity
const draftInput = wrapper.getByTestId('test_send_handler'); | |
expect(draftInput).toBeTruthy(); | |
const priority = wrapper.getByText('URGENT'); | |
expect(priority).toBeTruthy(); | |
expect( wrapper.getByTestId('test_send_handler')).toBeTruthy(); | |
expect(wrapper.getByText('URGENT')).toBeTruthy(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
body: { | ||
flex: 1, | ||
}, | ||
container: { | ||
flex: 1, | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there is no point of having two styles that do the same.. keep one, remove the other one
import Loading from '@components/loading'; | ||
import {useServerUrl} from '@context/server'; | ||
import {useTheme} from '@context/theme'; | ||
import DatabaseManager from '@database/manager'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this looks very wrong here
const theme = useTheme(); | ||
const intl = useIntl(); | ||
const serverUrl = useServerUrl(); | ||
const {database} = DatabaseManager.getServerDatabaseAndOperator(serverUrl); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this can throw an error and crash the entire thing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved it to updateSchedulePost
function.
setErrorLine(errorMessage); | ||
return; | ||
} | ||
const draftPayload = await draft.toApi(database); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
consider doing this at updateSchedulePost
action instead of doing it here, you can allow the two types as the draftPayload argument and check the type, convert if needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a blocker but you should use the correct type instead of any
); | ||
} | ||
|
||
export const isScheduledPostModel = (obj: any): obj is ScheduledPostModel => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why any?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is a guard, instead of any, it is more idiomatic to use "unknown".
That being said, that is to verify it is a scheduled post model from any kind of object (for example, the result of a JSON.parse). The body of this function doesn't seem to do that, so I guess it will be used to distinguish from the "api" version of a scheduled post and the "model version" of a scheduled post. If that is the case, it makes sense to have it typed as such (i.e. (obj: ScheduledPostModel | ScheduledPost): obj is ScheduledPostModel
)
Summary
Ticket Link
Checklist
E2E iOS tests for PR
.Device Information
This PR was tested on:
Screenshots
Release Note