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

Added rest client and local/remote/WebSocket handling for Scheduled Post #8526

Open
wants to merge 28 commits into
base: feature_schedule_posts
Choose a base branch
from

Conversation

Rajat-Dabade
Copy link
Contributor

Summary

This PR handles the rest clients, local/remote/WebSocket handling of scheduled posts.

Ticket Link

https://mattermost.atlassian.net/browse/MM-62763

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.

Release Note

NONE

@Rajat-Dabade Rajat-Dabade self-assigned this Jan 28, 2025
@Rajat-Dabade Rajat-Dabade added the 2: Dev Review Requires review by a core commiter label Jan 28, 2025
@rahimrahman
Copy link
Contributor

@Rajat-Dabade it would be beneficial to write unit test as we need to hit 80% of code coverage by the end of January.

app/client/rest/base.ts Outdated Show resolved Hide resolved
app/actions/websocket/event.ts Show resolved Hide resolved
app/actions/local/scheduled_post.ts Show resolved Hide resolved
app/actions/local/scheduled_post.ts Outdated Show resolved Hide resolved
app/actions/local/scheduled_post.ts Outdated Show resolved Hide resolved
app/actions/local/scheduled_post.ts Outdated Show resolved Hide resolved
@Rajat-Dabade Rajat-Dabade force-pushed the rest-client-schedule-post branch from b3ba535 to aeecc3d Compare February 3, 2025 04:11
@Rajat-Dabade
Copy link
Contributor Author

@rahimrahman I have added a test, can you please review this PR? Thank you.

@Rajat-Dabade Rajat-Dabade force-pushed the rest-client-schedule-post branch 2 times, most recently from aaba87d to 98ef776 Compare February 3, 2025 16:44
Copy link
Contributor

@larkox larkox left a comment

Choose a reason for hiding this comment

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

There is a couple of things I would like moved around, but apart of that it looks great.

await DatabaseManager.destroyServerDatabase(serverUrl);
});

describe('handleScheduledPosts', () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

I would prefer to have a describe for each function.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

}
}

export async function handleCreateOrUpdateScheduledPost(serverUrl: string, msg: WebSocketMessage<ScheduledPostWebsocketEventPayload>, prepareRecordsOnly = false) {
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 off. If this handles the websocket message, it should be in the websocket folder. If it is a generic local function (to be used by the websocket and the remote actions, for example), it should be agnostic to the websocket message (and for sure, not do the parsing).

0/5 on where this should be.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I initially referred to channelBookmarks, but after reviewing other files, I found your point valid. I've now moved it to the WebSocket folder.

Comment on lines 79 to 87
const mockScheduledPost = {
...scheduledPosts[0],
toApi: jest.fn().mockResolvedValue(scheduledPosts[0]), // Mock `toApi`
};
jest.spyOn(database, 'get').mockImplementation(() => ({
query: jest.fn().mockReturnValue({
fetch: jest.fn().mockResolvedValue([mockScheduledPost]),
}),
}) as any);
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of mocking all this, you can just add the element to the database, and see if it gets deleted.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

await DatabaseManager.destroyServerDatabase(serverUrl);
});

describe('fetch and delete scheduled posts', () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Use one describe for each function. That way the name of the test also can be simplified without so much repetition.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated the file.

@Rajat-Dabade Rajat-Dabade requested a review from larkox February 3, 2025 20:09
@Rajat-Dabade Rajat-Dabade force-pushed the rest-client-schedule-post branch from 6bece54 to 9d62952 Compare February 3, 2025 21:12
Copy link
Contributor

@rahimrahman rahimrahman left a comment

Choose a reason for hiding this comment

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

Excellent work adding your tests.

There's a few patterns that I thought was unnecessary and repeated multiple times.

You can check your coverage and add the output as markdown as a screenshot so you know you coverage is above 80%. I think there's a guidance of that somewhere (I'll look for it)

Comment on lines 77 to 127
expect(result).toBeDefined();
expect(result.error).toBeTruthy();
Copy link
Contributor

Choose a reason for hiding this comment

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

Should you need to check result.toBeDefined(), when (result.error).toBeTrurthy()?

Would it be beneficial to know if what result.error.toEqual(something) instead of toBeTruthy()?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

Comment on lines +85 to +135
expect(result).toBeDefined();
expect(result.error).toBeTruthy();
Copy link
Contributor

Choose a reason for hiding this comment

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

Same as above and in other test cases in this file. Knowing that the result.xyz is equal to something pretty much (result).toBeDefined().

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

describe('handleCreateOrUpdateSchedulePost', () => {
it('handleCreateOrUpdateScheduledPost - handle not found database', async () => {
const {error} = await handleCreateOrUpdateScheduledPost('foo', {} as WebSocketMessage) as {error: unknown};
expect(error).toBeTruthy();
Copy link
Contributor

Choose a reason for hiding this comment

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

Does the error message says "Database not found?"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup, updated the test case.

Comment on lines +92 to +93
expect(deletedRecord).toBeTruthy();
expect(deletedRecord.models).toBeTruthy();
Copy link
Contributor

Choose a reason for hiding this comment

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

Are these beneficial as models.length is asserted to 1?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, as such, removed it and updated the test.

Comment on lines +66 to +67
expect(models).toBeTruthy();
expect(models?.length).toBe(1);
Copy link
Contributor

Choose a reason for hiding this comment

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

Might be more beneficials to know what the models that came back to equal to or a few elements matches the scheduled_post.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.


await client.getScheduledPostsForTeam(teamId, includeDirectChannels, groupLabel);

expect(client.doFetch).toHaveBeenCalledWith(expectedUrl, expectedOptions);
Copy link
Contributor

Choose a reason for hiding this comment

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

Excellent!


it('fetch Schedule post - handle scheduled post enabled', async () => {
mockedGetConfigValue.mockResolvedValueOnce('true');
jest.spyOn(operator, 'handleScheduledPosts').mockResolvedValueOnce([]);
Copy link
Contributor

Choose a reason for hiding this comment

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

Should you mock this or should you check that handleScheduledPosts() .toHaveBeenCalledWith() properly?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

import DatabaseManager from '@database/manager';
import {logError} from '@utils/log';

export async function handleScheduledPosts(serverUrl: string, actionType: string, scheduledPosts: ScheduledPost[], prepareRecordsOnly = false) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Missing test?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added

});

it('delete Schedule post - handle scheduled post enabled', async () => {
jest.spyOn(operator, 'handleScheduledPosts').mockResolvedValueOnce([]);
Copy link
Contributor

Choose a reason for hiding this comment

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

Same as above, should we mock or check that it was calledWith() properly?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

const mockClient = {
getScheduledPostsForTeam: jest.fn(() => Promise.resolve({...scheduledPostsResponse})),
deleteScheduledPost: jest.fn((scheduledPostId) => {
return Promise.resolve(scheduledPostsResponse.bar.find((post) => post.id === scheduledPostId));
Copy link
Contributor

Choose a reason for hiding this comment

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

Curious: when you send deleteScheduledPost, you get the post that you deleted back?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup, I know this is of no use, but the handler is written in this way (as we batch all the records for create/update/delete actions together and return Promise of Scheduled posts). It causes no harm but comes with benefits to test which record was actually deleted.

@amyblais amyblais modified the milestone: v2.26.0 Feb 4, 2025
Base automatically changed from migration-scheduled-post to feature_schedule_posts February 4, 2025 14:43
@Rajat-Dabade Rajat-Dabade force-pushed the rest-client-schedule-post branch from 9d62952 to e045d63 Compare February 4, 2025 15:36
@Rajat-Dabade Rajat-Dabade force-pushed the rest-client-schedule-post branch from e045d63 to 3b3c02a Compare February 4, 2025 15:52
@Rajat-Dabade
Copy link
Contributor Author

local/scheduled_post.test.ts
Screenshot 2025-02-05 at 12 42 27 AM

websocket/scheduled_post.test.ts
Screenshot 2025-02-05 at 12 44 51 AM

remote/scheduled_post.test.ts
Screenshot 2025-02-05 at 12 46 04 AM

client/rest/scheduled_post.test.ts
Screenshot 2025-02-05 at 12 47 42 AM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2: Dev Review Requires review by a core commiter release-note
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants