mattermost-mobile/app/utils/bor.test.ts
Harshil Sharma 2fb2e9d899
Burn On Read Posts (#9307)
* Added scaffolding for unrevealed BoR post

* Displayed reveal UI

* Displayed expiry timer

* WIP

* Displayed own post indicator and blur text

* restored button

* Ungrouped BoR posts

* WIP

* WIP

* DIsplayed error message on revealing

* Added last run check on mobile app cleanup job

* Cleanup

* lint fix

* i18n-fix

* Added tests

* test: add test suite for revealBoRPost function

* test: add unrevealed burn on read post test file

* feat: add tests for UnrevealedBurnOnReadPost component

* test: update UnrevealedBurnOnReadPost test with PostModel type

* test: replace toBeTruthy with toBeVisible for component visibility assertions

* test: add initial test file for expiry timer component

* test: add comprehensive tests for ExpiryCountdown component

* refactor: clean up test formatting and remove redundant test case

* fix: adjust test timing for ExpiryCountdown onExpiry callback

* test: fix timer test by advancing timers in smaller increments

* Added tests

* Updated tests

* fixed accidental change

* restored package.resolved

* WIP review fixes

* Review fixes

* Review fixes

* Fixed tests

* restored package.resolved

* WIP

* test: add test for skipping BoR post cleanup within 15 minutes

* test: add comprehensive test cases for expiredBoRPostCleanup

* WIP

* WIP

* test: add bor.test.ts placeholder file

* test: add comprehensive tests for BoR utility functions

* test: add comprehensive tests for formatTime function

* WIP

* test: add comprehensive tests for getLastBoRPostCleanupRun function

* Added tests

* removed a commented code

* post list optimization

* test: add test case for updating unrevealed burn-on-read post

* fix: handle error logging in expiredBoRPostCleanup test

* test: add test case for updateLastBoRCleanupRun error handling

* review fixes

* lint fixes

* Added WS event handling (#9320)

* Added WS event handling

* test: add burn on read websocket action test

* test: add tests for handleBoRPostRevealedEvent in burn_on_read

* Added tests

* test: add comprehensive error handling test cases for burn on read

* Added tests and error handling

* BoR post - restricted actions (#9315)

* Restricted post actions for BoR post type

* Prevent opening thread fr nBoR post

* WIP

* fix: remove redundant observable wrapping in post options

* fixed a change

* removed broken

* restored package.resolved

* Added tests

* Awaiting for last run to be set

* Added tests for validating expiry timer behaviour (#9338)

* Added tests for validating expiry timer behaviour

* No need of use event setup

* Bor ux fixes (#9336)

* WIP

* UI and delete fixes

* lint fixes

* fixed tests

* Improved mocking

* Improved test
2025-12-11 09:42:16 +05:30

208 lines
6.9 KiB
TypeScript

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Post} from '@constants';
import {
isBoRPost,
isUnrevealedBoRPost,
isOwnBoRPost,
isExpiredBoRPost,
} from './bor';
import type PostModel from '@typings/database/models/servers/post';
import type UserModel from '@typings/database/models/servers/user';
describe('BoR utility functions', () => {
const mockUser: UserModel = {
id: 'user123',
} as UserModel;
describe('isBoRPost', () => {
it('should return true for BoR posts', () => {
const borPost: PostModel = {
type: Post.POST_TYPES.BURN_ON_READ,
} as PostModel;
expect(isBoRPost(borPost)).toBe(true);
});
it('should return false for non-BoR posts', () => {
const regularPost: PostModel = {
type: Post.POST_TYPES.CHANNEL_DELETED,
} as PostModel;
expect(isBoRPost(regularPost)).toBe(false);
});
it('should return false for posts without type', () => {
const postWithoutType: PostModel = {} as PostModel;
expect(isBoRPost(postWithoutType)).toBe(false);
});
});
describe('isUnrevealedBoRPost', () => {
it('should return true for BoR posts without expire_at in metadata', () => {
const unrevealedBorPost: PostModel = {
type: Post.POST_TYPES.BURN_ON_READ,
metadata: {},
} as PostModel;
expect(isUnrevealedBoRPost(unrevealedBorPost)).toBe(true);
});
it('should return true for BoR posts with null metadata', () => {
const borPostWithNullMetadata: PostModel = {
type: Post.POST_TYPES.BURN_ON_READ,
metadata: null,
} as PostModel;
expect(isUnrevealedBoRPost(borPostWithNullMetadata)).toBe(true);
});
it('should return false for BoR posts with expire_at in metadata', () => {
const revealedBorPost: PostModel = {
type: Post.POST_TYPES.BURN_ON_READ,
metadata: {
expire_at: Date.now() + 10000,
},
} as PostModel;
expect(isUnrevealedBoRPost(revealedBorPost)).toBe(false);
});
it('should return true for BoR posts with expire_at in the past', () => {
const revealedBorPost: PostModel = {
type: Post.POST_TYPES.BURN_ON_READ,
metadata: {
expire_at: Date.now() - 10000,
},
} as PostModel;
expect(isUnrevealedBoRPost(revealedBorPost)).toBe(false);
});
it('should return false for non-BoR posts', () => {
const regularPost: PostModel = {
type: '',
metadata: {},
} as PostModel;
expect(isUnrevealedBoRPost(regularPost)).toBe(false);
});
});
describe('isOwnBoRPost', () => {
it('should return true for BoR posts owned by current user', () => {
const ownBorPost: PostModel = {
type: Post.POST_TYPES.BURN_ON_READ,
userId: 'user123',
} as PostModel;
expect(isOwnBoRPost(ownBorPost, mockUser)).toBe(true);
});
it('should return false for BoR posts not owned by current user', () => {
const othersBorPost: PostModel = {
type: Post.POST_TYPES.BURN_ON_READ,
userId: 'user456',
} as PostModel;
expect(isOwnBoRPost(othersBorPost, mockUser)).toBe(false);
});
it('should return false for non-BoR posts', () => {
const ownRegularPost: PostModel = {
type: '',
userId: 'user123',
} as PostModel;
expect(isOwnBoRPost(ownRegularPost, mockUser)).toBe(false);
});
it('should return false when no current user is provided', () => {
const borPost: PostModel = {
type: Post.POST_TYPES.BURN_ON_READ,
userId: 'user123',
} as PostModel;
expect(isOwnBoRPost(borPost)).toBe(false);
expect(isOwnBoRPost(borPost, undefined)).toBe(false);
});
});
describe('isExpiredBoRPost', () => {
const pastTime = Date.now() - 10000;
const futureTime = Date.now() + 10000;
it('should return true for BoR posts expired for all users (props.expire_at)', () => {
const expiredBorPost: PostModel = {
type: Post.POST_TYPES.BURN_ON_READ,
props: {
expire_at: pastTime,
} as PostMetadata,
} as PostModel;
expect(isExpiredBoRPost(expiredBorPost)).toBe(true);
});
it('should return true for BoR posts expired for current user (metadata.expire_at)', () => {
const expiredBorPost: PostModel = {
type: Post.POST_TYPES.BURN_ON_READ,
metadata: {
expire_at: pastTime,
},
} as PostModel;
expect(isExpiredBoRPost(expiredBorPost)).toBe(true);
});
it('should return false for BoR posts not yet expired', () => {
const activeBorPost: PostModel = {
type: Post.POST_TYPES.BURN_ON_READ,
props: {
expire_at: futureTime,
} as Record<string, unknown>,
metadata: {
expire_at: futureTime,
} as PostMetadata,
} as PostModel;
expect(isExpiredBoRPost(activeBorPost)).toBe(false);
});
it('should return false for non-BoR posts even with expired timestamps', () => {
const expiredRegularPost: PostModel = {
type: '',
props: {
expire_at: pastTime,
} as Record<string, unknown>,
metadata: {
expire_at: pastTime,
} as PostMetadata,
} as PostModel;
expect(isExpiredBoRPost(expiredRegularPost)).toBe(false);
});
it('should return false for BoR posts without expiration data', () => {
const borPostWithoutExpiration: PostModel = {
type: Post.POST_TYPES.BURN_ON_READ,
} as PostModel;
expect(isExpiredBoRPost(borPostWithoutExpiration)).toBe(false);
});
it('should handle string expire_at values in props', () => {
const expiredBorPostWithStringTime: PostModel = {
type: Post.POST_TYPES.BURN_ON_READ,
props: {
expire_at: pastTime.toString(),
} as Record<string, unknown>,
} as PostModel;
expect(isExpiredBoRPost(expiredBorPostWithStringTime)).toBe(true);
});
});
});