Add unit tests to Utils buttonStyles and categories (#8015)

* utils/buttonStyles tests

* utils/categories tests
This commit is contained in:
Elias Nahum 2024-06-14 17:11:36 +08:00 committed by GitHub
parent f17d4872ce
commit aea670745f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 903 additions and 94 deletions

View file

@ -0,0 +1,142 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import Preferences from '@constants/preferences';
import {buttonBackgroundStyle, buttonStyles, getBackgroundStyles, buttonSizeStyles, buttonTextStyle, buttonTextStyles, buttonTextSizeStyles} from './buttonStyles';
import {changeOpacity} from './theme';
describe('get the style of a button', () => {
const defaultStyle = buttonStyles.main;
const theme = Preferences.THEMES.denim;
const bgStyles = getBackgroundStyles(theme);
test('button default values', () => {
const tests = [{
getStyle: () => buttonBackgroundStyle(theme),
expected: [
defaultStyle,
buttonSizeStyles.m,
bgStyles.primary.default.default,
],
}, {
getStyle: () => buttonBackgroundStyle(theme, 'xs'),
expected: [
defaultStyle,
buttonSizeStyles.xs,
bgStyles.primary.default.default,
],
}, {
getStyle: () => buttonBackgroundStyle(theme, 'lg', 'secondary'),
expected: [
defaultStyle,
buttonSizeStyles.lg,
bgStyles.secondary.default.default,
],
}];
tests.forEach((t) => {
const style = t.getStyle();
expect(style).toEqual(t.expected);
});
});
test('button style', () => {
const btnEnphasis: ButtonEmphasis[] = ['primary', 'secondary', 'tertiary', 'link'];
const btnSizes: ButtonSize[] = ['lg', 'm', 's', 'xs'];
const btnTypes: ButtonType[] = ['default', 'destructive', 'disabled', 'inverted'];
const btnState: ButtonState[] = ['active', 'default', 'focus', 'hover'];
btnEnphasis.forEach((emphasis) => {
btnSizes.forEach((size) => {
btnTypes.forEach((type) => {
btnState.forEach((state) => {
const style = buttonBackgroundStyle(theme, size, emphasis, type, state);
expect(style).toEqual([
defaultStyle,
buttonSizeStyles[size],
bgStyles[emphasis][type][state],
]);
});
});
});
});
});
});
describe('get the text style of a button', () => {
const defaultTextStyle = buttonTextStyles.main;
const theme = Preferences.THEMES.denim;
test('button text default values', () => {
const tests = [{
getStyle: () => buttonTextStyle(theme),
expected: [
defaultTextStyle,
buttonTextSizeStyles.m,
{color: theme.buttonColor},
],
}, {
getStyle: () => buttonTextStyle(theme, 'xs'),
expected: [
defaultTextStyle,
buttonTextSizeStyles.xs,
{color: theme.buttonColor},
],
}, {
getStyle: () => buttonTextStyle(theme, 'lg', 'secondary'),
expected: [
defaultTextStyle,
buttonTextSizeStyles.lg,
{color: theme.buttonBg},
],
}];
tests.forEach((t) => {
const style = t.getStyle();
expect(style).toEqual(t.expected);
});
});
test('button style', () => {
const btnEnphasis: ButtonEmphasis[] = ['primary', 'secondary', 'tertiary', 'link'];
const btnSizes: ButtonSize[] = ['lg', 'm', 's', 'xs'];
const btnTypes: ButtonType[] = ['default', 'destructive', 'disabled', 'inverted'];
const getColor = (type: ButtonType, emphasis: ButtonEmphasis) => {
let color: string = theme.buttonColor;
if (type === 'disabled') {
color = changeOpacity(theme.centerChannelColor, 0.32);
}
if ((type === 'destructive' && emphasis !== 'primary')) {
color = theme.errorTextColor;
}
if ((type === 'inverted' && emphasis === 'primary') ||
(type !== 'inverted' && emphasis !== 'primary')) {
color = theme.buttonBg;
}
if (type === 'inverted' && emphasis === 'tertiary') {
color = theme.sidebarText;
}
return color;
};
btnEnphasis.forEach((emphasis) => {
btnSizes.forEach((size) => {
btnTypes.forEach((type) => {
const style = buttonTextStyle(theme, size, emphasis, type);
expect(style).toEqual([
defaultTextStyle,
buttonTextSizeStyles[size],
{color: getColor(type, emphasis)},
]);
});
});
});
});
});

View file

@ -5,37 +5,8 @@ import {type StyleProp, StyleSheet, type TextStyle, type ViewStyle} from 'react-
import {blendColors, changeOpacity} from '@utils/theme';
/**
* Returns the appropriate Style object for <View style={} />
*
*
* @param theme
* @param size
* @param emphasis
* @param type
* @param state
* @returns
*/
export const buttonBackgroundStyle = (
theme: Theme,
size: ButtonSize = 'm',
emphasis: ButtonEmphasis = 'primary',
type: ButtonType = 'default',
state: ButtonState = 'default',
): StyleProp<ViewStyle> => {
const styles = StyleSheet.create({
main: {
flex: 0,
alignItems: 'center',
justifyContent: 'center',
borderRadius: 4,
},
fullWidth: {
width: '100%',
},
});
const backgroundStyles: BackgroundStyles = {
export const getBackgroundStyles = (theme: Theme): BackgroundStyles => {
return {
primary: {
default: {
default: {
@ -313,31 +284,102 @@ export const buttonBackgroundStyle = (
},
},
};
};
const sizes: ButtonSizes = StyleSheet.create({
xs: {
height: 24,
paddingVertical: 6,
paddingHorizontal: 10,
},
s: {
height: 32,
paddingVertical: 10,
paddingHorizontal: 16,
},
m: {
height: 40,
paddingVertical: 12,
paddingHorizontal: 20,
},
lg: {
height: 48,
paddingVertical: 14,
paddingHorizontal: 24,
},
});
export const buttonSizeStyles: ButtonSizes = StyleSheet.create({
xs: {
height: 24,
paddingVertical: 6,
paddingHorizontal: 10,
},
s: {
height: 32,
paddingVertical: 10,
paddingHorizontal: 16,
},
m: {
height: 40,
paddingVertical: 12,
paddingHorizontal: 20,
},
lg: {
height: 48,
paddingVertical: 14,
paddingHorizontal: 24,
},
});
return [styles.main, sizes[size], backgroundStyles[emphasis][type][state]];
export const buttonStyles = StyleSheet.create({
main: {
flex: 0,
alignItems: 'center',
justifyContent: 'center',
borderRadius: 4,
},
fullWidth: {
width: '100%',
},
});
export const buttonTextStyles = StyleSheet.create({
main: {
fontFamily: 'OpenSans-SemiBold',
fontWeight: '600',
textAlignVertical: 'center',
alignItems: 'center',
justifyContent: 'center',
padding: 1,
},
underline: {
textDecorationLine: 'underline',
},
});
export const buttonTextSizeStyles = StyleSheet.create({
xs: {
fontSize: 11,
lineHeight: 10,
letterSpacing: 0.02,
marginTop: 2,
},
s: {
fontSize: 12,
lineHeight: 12,
marginTop: 1,
},
m: {
fontSize: 14,
lineHeight: 14,
marginTop: 3,
},
lg: {
fontSize: 16,
lineHeight: 18,
marginTop: 1,
},
});
/**
* Returns the appropriate Style object for <View style={} />
*
*
* @param theme
* @param size
* @param emphasis
* @param type
* @param state
* @returns
*/
export const buttonBackgroundStyle = (
theme: Theme,
size: ButtonSize = 'm',
emphasis: ButtonEmphasis = 'primary',
type: ButtonType = 'default',
state: ButtonState = 'default',
): StyleProp<ViewStyle> => {
const backgroundStyles = getBackgroundStyles(theme);
return [buttonStyles.main, buttonSizeStyles[size], backgroundStyles[emphasis][type][state]];
};
/**
@ -376,43 +418,5 @@ export const buttonTextStyle = (
color = theme.sidebarText;
}
const styles = StyleSheet.create({
main: {
fontFamily: 'OpenSans-SemiBold',
fontWeight: '600',
textAlignVertical: 'center',
alignItems: 'center',
justifyContent: 'center',
padding: 1,
},
underline: {
textDecorationLine: 'underline',
},
});
const sizes = StyleSheet.create({
xs: {
fontSize: 11,
lineHeight: 10,
letterSpacing: 0.02,
marginTop: 2,
},
s: {
fontSize: 12,
lineHeight: 12,
marginTop: 1,
},
m: {
fontSize: 14,
lineHeight: 14,
marginTop: 3,
},
lg: {
fontSize: 16,
lineHeight: 18,
marginTop: 1,
},
});
return [styles.main, sizes[size], {color}];
return [buttonTextStyles.main, buttonTextSizeStyles[size], {color}];
};

View file

@ -0,0 +1,663 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
/* eslint-disable max-lines */
import {Preferences} from '@constants';
import DatabaseManager from '@database/manager';
import {
makeCategoryChannelId,
isUnreadChannel,
filterArchivedChannels,
filterAutoclosedDMs,
filterManuallyClosedDms,
sortChannels,
getUnreadIds,
type ChannelWithMyChannel,
} from './categories';
import type {ServerDatabase} from '@typings/database/database';
import type MyChannelModel from '@typings/database/models/servers/my_channel';
import type PreferenceModel from '@typings/database/models/servers/preference';
import type UserModel from '@typings/database/models/servers/user';
describe('Categories utils', () => {
const serverUrl = 'baseHandler.test.com';
const buildChannelsData = () => {
const dt1 = Date.now();
const dt2 = Date.now() - (24 * 60 * 60 * 1000);
const dt3 = Date.now() - (2 * 24 * 60 * 60 * 1000);
const dt4 = Date.now() - (3 * 24 * 60 * 60 * 1000);
const channels: Channel[] = [{
id: 'dm1',
name: 'me__other1',
display_name: 'DM 1',
type: 'D',
create_at: dt2,
update_at: dt2,
delete_at: 0,
team_id: '123',
header: '',
purpose: '',
last_post_at: dt2,
creator_id: 'me',
total_msg_count: 20,
extra_update_at: 0,
shared: false,
scheme_id: null,
group_constrained: false,
}, {
id: 'dm2',
name: 'me__other2',
display_name: 'Zandoval 2',
type: 'D',
create_at: dt4,
update_at: dt4,
delete_at: 0,
team_id: '123',
header: '',
purpose: '',
last_post_at: dt4,
creator_id: 'me',
total_msg_count: 20,
extra_update_at: 0,
shared: false,
scheme_id: null,
group_constrained: false,
}, {
id: 'open-channel',
name: 'open-channel',
display_name: 'Open Channel',
type: 'O',
create_at: dt1,
update_at: dt1,
delete_at: 0,
team_id: '123',
header: '',
purpose: '',
last_post_at: dt1,
creator_id: 'me',
total_msg_count: 20,
extra_update_at: 0,
shared: false,
scheme_id: null,
group_constrained: false,
}, {
id: 'gm1',
name: 'the_gm_channel_name',
display_name: 'Mario, Persona 2, Persona 3',
type: 'G',
create_at: dt3,
update_at: dt3,
delete_at: 0,
team_id: '123',
header: '',
purpose: '',
last_post_at: dt3,
creator_id: 'me',
total_msg_count: 20,
extra_update_at: 0,
shared: false,
scheme_id: null,
group_constrained: false,
}];
const myChannels: ChannelMembership[] = [
{
id: 'dm1',
user_id: 'me',
channel_id: 'dm1',
last_post_at: dt2,
last_viewed_at: dt2,
last_update_at: dt2,
mention_count: 0,
msg_count: 20,
roles: 'user',
notify_props: {
desktop: 'default',
email: 'default',
mark_unread: 'mention',
push: 'mention',
ignore_channel_mentions: 'default',
},
},
{
id: 'dm2',
user_id: 'me',
channel_id: 'dm2',
last_post_at: dt4,
last_viewed_at: dt4,
last_update_at: dt4,
mention_count: 3,
msg_count: 23,
roles: 'user',
notify_props: {
desktop: 'default',
email: 'default',
mark_unread: 'mention',
push: 'mention',
ignore_channel_mentions: 'default',
},
}, {
id: 'open-channel',
user_id: 'me',
channel_id: 'open-channel',
last_post_at: dt1,
last_viewed_at: dt1,
last_update_at: dt1,
mention_count: 1,
msg_count: 21,
roles: 'user',
notify_props: {
desktop: 'default',
email: 'default',
mark_unread: 'all',
push: 'mention',
ignore_channel_mentions: 'default',
},
}, {
id: 'gm1',
user_id: 'me',
channel_id: 'gm1',
last_post_at: dt3,
last_viewed_at: dt3,
last_update_at: dt3,
mention_count: 0,
msg_count: 0,
roles: 'user',
notify_props: {
desktop: 'default',
email: 'default',
mark_unread: 'mention',
push: 'mention',
ignore_channel_mentions: 'default',
},
},
];
return {channels, myChannels};
};
const createChannelsDbRecords = async (db: ServerDatabase, channels: Channel[], myChannels: ChannelMembership[]): Promise<ChannelWithMyChannel[]> => {
const channelModels = await db.operator.handleChannel({channels, prepareRecordsOnly: false});
const myChannelModels = await db.operator.handleMyChannel({channels, myChannels, prepareRecordsOnly: false});
return channelModels.map((channel, index) => {
const myChannel = myChannelModels[index];
return {
channel,
myChannel,
sortOrder: index,
};
});
};
beforeEach(async () => {
await DatabaseManager.init([serverUrl]);
});
afterEach(() => {
DatabaseManager.destroyServerDatabase(serverUrl);
});
test('makeCategoryChannelId', () => {
const teamId = 'my-team-id';
const channelId = 'my-channel-id';
const category = makeCategoryChannelId(teamId, channelId);
expect(category).toBe(`${teamId}_${channelId}`);
});
test('isUnreadChannel', async () => {
const db = DatabaseManager.getServerDatabaseAndOperator(serverUrl);
const channels: Channel[] = [{
id: 'c',
name: 'channel',
display_name: 'Channel',
type: 'O',
create_at: 1,
update_at: 1,
delete_at: 0,
team_id: '123',
header: '',
purpose: '',
last_post_at: 2,
creator_id: 'me',
total_msg_count: 20,
extra_update_at: 0,
shared: false,
scheme_id: null,
group_constrained: false,
}];
const myChannels: ChannelMembership[] = [
{
id: 'c',
user_id: 'me',
channel_id: 'c',
last_post_at: 1617311494451,
last_viewed_at: 1617311494451,
last_update_at: 1617311494451,
mention_count: 3,
msg_count: 10,
roles: 'guest',
notify_props: {
desktop: 'default',
email: 'default',
mark_unread: 'mention',
push: 'mention',
ignore_channel_mentions: 'default',
},
},
];
const models = await db.operator.handleMyChannel({channels, myChannels, isCRTEnabled: false, prepareRecordsOnly: false});
expect(models).toHaveLength(1);
const myChannel = models[0];
let isUnread = isUnreadChannel(myChannel);
expect(isUnread).toBe(true);
await db.database.write(async () => {
await myChannel.update((record) => {
record.mentionsCount = 0;
});
});
isUnread = isUnreadChannel(myChannel);
expect(isUnread).toBe(true);
const notifyProps: Partial<ChannelNotifyProps> = {mark_unread: 'mention'};
isUnread = isUnreadChannel(myChannel, notifyProps);
expect(isUnread).toBe(false);
isUnread = isUnreadChannel(myChannel, notifyProps, myChannel.id);
expect(isUnread).toBe(true);
});
test('filterArchivedChannels', async () => {
const db = DatabaseManager.getServerDatabaseAndOperator(serverUrl);
const channels: Channel[] = [{
id: 'channel_1',
name: 'channel_1',
display_name: 'Channel 1',
type: 'O',
create_at: 1,
update_at: 1,
delete_at: 0,
team_id: '123',
header: '',
purpose: '',
last_post_at: 2,
creator_id: 'me',
total_msg_count: 20,
extra_update_at: 0,
shared: false,
scheme_id: null,
group_constrained: false,
}, {
id: 'channel_2',
name: 'channel_2',
display_name: 'Channel 2',
type: 'O',
create_at: 1,
update_at: 1,
delete_at: 123,
team_id: '123',
header: '',
purpose: '',
last_post_at: 2,
creator_id: 'me',
total_msg_count: 20,
extra_update_at: 0,
shared: false,
scheme_id: null,
group_constrained: false,
}];
const myChannels: ChannelMembership[] = [
{
id: 'channel_1',
user_id: 'me',
channel_id: 'channel_1',
last_post_at: 1617311494451,
last_viewed_at: 1617311494451,
last_update_at: 1617311494451,
mention_count: 3,
msg_count: 10,
roles: 'user',
notify_props: {
desktop: 'default',
email: 'default',
mark_unread: 'mention',
push: 'mention',
ignore_channel_mentions: 'default',
},
},
{
id: 'channel_2',
user_id: 'me',
channel_id: 'channel_2',
last_post_at: 1617311494451,
last_viewed_at: 1617311494451,
last_update_at: 1617311494451,
mention_count: 3,
msg_count: 10,
roles: 'user',
notify_props: {
desktop: 'default',
email: 'default',
mark_unread: 'mention',
push: 'mention',
ignore_channel_mentions: 'default',
},
},
];
const channelModels = await db.operator.handleChannel({channels, prepareRecordsOnly: false});
const myChannelModels = await db.operator.handleMyChannel({channels, myChannels, prepareRecordsOnly: false});
const data: ChannelWithMyChannel[] = [{
channel: channelModels[0],
myChannel: myChannelModels[0],
sortOrder: 0,
}, {
channel: channelModels[1],
myChannel: myChannelModels[1],
sortOrder: 1,
}];
let archived = filterArchivedChannels(data, '');
expect(archived).toHaveLength(1);
archived = filterArchivedChannels(data, channels[1].id);
expect(archived).toHaveLength(2);
});
test('filterAutoclosedDMs', async () => {
const db = DatabaseManager.getServerDatabaseAndOperator(serverUrl);
let result = filterAutoclosedDMs('channels', 3, 'me', '', [], [], {});
expect(result).toEqual([]);
const now = Date.now();
const dt_chan1 = now - (3 * 24 * 60 * 60 * 1000);
const dt_chan2 = now - (2 * 24 * 60 * 60 * 1000);
const autoclosePrefs = [{
id: 'pref1',
userId: 'me',
category: Preferences.CATEGORIES.CHANNEL_APPROXIMATE_VIEW_TIME,
name: 'dm1',
value: `${dt_chan1}`,
}, {
id: 'pref2',
userId: 'me',
category: Preferences.CATEGORIES.CHANNEL_APPROXIMATE_VIEW_TIME,
name: 'dm2',
value: `${dt_chan2}`,
}] as PreferenceModel[];
const channels: Channel[] = [{
id: 'dm1',
name: 'me__other1',
display_name: 'DM 1',
type: 'D',
create_at: 1,
update_at: 1,
delete_at: 0,
team_id: '123',
header: '',
purpose: '',
last_post_at: dt_chan1,
creator_id: 'me',
total_msg_count: 20,
extra_update_at: 0,
shared: false,
scheme_id: null,
group_constrained: false,
}, {
id: 'dm2',
name: 'me__other2',
display_name: 'DM 2',
type: 'D',
create_at: 1,
update_at: 1,
delete_at: 0,
team_id: '123',
header: '',
purpose: '',
last_post_at: dt_chan2,
creator_id: 'me',
total_msg_count: 20,
extra_update_at: 0,
shared: false,
scheme_id: null,
group_constrained: false,
}];
const myChannels: ChannelMembership[] = [
{
id: 'dm1',
user_id: 'me',
channel_id: 'dm1',
last_post_at: dt_chan1,
last_viewed_at: dt_chan1,
last_update_at: dt_chan1,
mention_count: 0,
msg_count: 20,
roles: 'user',
notify_props: {
desktop: 'default',
email: 'default',
mark_unread: 'mention',
push: 'mention',
ignore_channel_mentions: 'default',
},
},
{
id: 'dm2',
user_id: 'me',
channel_id: 'dm2',
last_post_at: dt_chan2,
last_viewed_at: dt_chan2,
last_update_at: dt_chan2,
mention_count: 3,
msg_count: 10,
roles: 'user',
notify_props: {
desktop: 'default',
email: 'default',
mark_unread: 'mention',
push: 'mention',
ignore_channel_mentions: 'default',
},
},
];
const channelModels = await db.operator.handleChannel({channels, prepareRecordsOnly: false});
const myChannelModels = await db.operator.handleMyChannel({channels, myChannels, prepareRecordsOnly: false});
const data: ChannelWithMyChannel[] = [{
channel: channelModels[0],
myChannel: myChannelModels[0],
sortOrder: 0,
}, {
channel: channelModels[1],
myChannel: myChannelModels[1],
sortOrder: 0,
}];
result = filterAutoclosedDMs('direct_messages', 3, 'me', '', data, autoclosePrefs, {});
expect(result.length).toEqual(2);
result = filterAutoclosedDMs('direct_messages', 3, 'me', 'dm1', data, autoclosePrefs, {});
expect(result.length).toEqual(2);
result = filterAutoclosedDMs('direct_messages', 3, 'me', 'dm2', data, autoclosePrefs, {});
expect(result.length).toEqual(2);
const lastViewedData: ChannelWithMyChannel[] = [{
...data[0],
myChannel: {
...data[0].myChannel,
lastViewedAt: 0,
} as MyChannelModel,
}, data[1]];
const autoclosePrefsNotViewed = [autoclosePrefs[1]];
result = filterAutoclosedDMs('direct_messages', 3, 'me', '', lastViewedData, autoclosePrefsNotViewed, {});
expect(result.length).toEqual(1);
const deactivated = new Map<string, UserModel>();
deactivated.set('other1', {
id: 'other1',
deleteAt: dt_chan1 + 1,
} as UserModel);
result = filterAutoclosedDMs('direct_messages', 3, 'me', '', data, autoclosePrefs, {}, deactivated);
expect(result.length).toEqual(1);
result = filterAutoclosedDMs('direct_messages', 3, 'me', '', data, autoclosePrefs, {}, undefined, 'dm2');
expect(result[0].channel.id).toEqual('dm2');
const mockNotUnread: ChannelWithMyChannel[] = [data[0], {
...data[1],
myChannel: {
id: data[1].myChannel.id,
lastViewedAt: 0,
isUnread: false,
} as MyChannelModel,
}];
result = filterAutoclosedDMs('direct_messages', 3, 'me', '', mockNotUnread, autoclosePrefs, {}, undefined, 'dm1');
expect(result[0].channel.id).toEqual('dm1');
const mockRecent1: ChannelWithMyChannel[] = [{
...data[0],
myChannel: {
id: data[0].myChannel.id,
lastViewedAt: 2,
isUnread: false,
} as MyChannelModel,
}, {
...data[1],
myChannel: {
id: data[1].myChannel.id,
lastViewedAt: 1,
isUnread: false,
} as MyChannelModel,
}];
result = filterAutoclosedDMs('direct_messages', 3, 'me', '', mockRecent1, [], {});
expect(result[0].channel.id).toEqual('dm1');
const mockRecent2: ChannelWithMyChannel[] = [{
...data[0],
myChannel: {
id: data[0].myChannel.id,
lastViewedAt: 1,
isUnread: false,
} as MyChannelModel,
}, {
...data[1],
myChannel: {
id: data[1].myChannel.id,
lastViewedAt: 2,
isUnread: false,
} as MyChannelModel,
}];
result = filterAutoclosedDMs('direct_messages', 3, 'me', '', mockRecent2, [], {});
expect(result[0].channel.id).toEqual('dm2');
const mockSameLastViewed: ChannelWithMyChannel[] = [{
...data[0],
myChannel: {
id: data[0].myChannel.id,
lastViewedAt: 1,
isUnread: false,
} as MyChannelModel,
}, {
...data[1],
myChannel: {
id: data[1].myChannel.id,
lastViewedAt: 1,
isUnread: false,
} as MyChannelModel,
}];
result = filterAutoclosedDMs('direct_messages', 3, 'me', '', mockSameLastViewed, [], {});
expect(result[0].channel.id).toEqual('dm1');
});
test('filterManuallyClosedDms', async () => {
const db = DatabaseManager.getServerDatabaseAndOperator(serverUrl);
const closedDMsPrefs = [{
id: 'pref1',
userId: 'me',
category: Preferences.CATEGORIES.DIRECT_CHANNEL_SHOW,
name: 'dm1',
value: 'true',
}, {
id: 'pref2',
userId: 'me',
category: Preferences.CATEGORIES.DIRECT_CHANNEL_SHOW,
name: 'dm2',
value: 'true',
}, {
id: 'pref3',
userId: 'me',
category: Preferences.CATEGORIES.GROUP_CHANNEL_SHOW,
name: 'gm1',
value: 'false',
}] as PreferenceModel[];
const {channels, myChannels} = buildChannelsData();
const data = await createChannelsDbRecords(db, channels, myChannels);
const notifyProps = myChannels.reduce<Record<string, Partial<ChannelNotifyProps>>>((obj, m) => {
obj[m.channel_id] = m.notify_props;
return obj;
}, {});
const result = filterManuallyClosedDms(data, notifyProps, closedDMsPrefs, 'me');
expect(result.length).toEqual(3);
});
test('sortChannels', async () => {
const db = DatabaseManager.getServerDatabaseAndOperator(serverUrl);
const {channels, myChannels} = buildChannelsData();
const data = await createChannelsDbRecords(db, channels, myChannels);
const notifyProps = myChannels.reduce<Record<string, Partial<ChannelNotifyProps>>>((obj, m) => {
obj[m.channel_id] = m.notify_props;
return obj;
}, {});
let result = sortChannels('recent', data, notifyProps, 'en');
const recentIds = result.map((r) => r.id);
expect(recentIds).toEqual(['open-channel', 'dm1', 'gm1', 'dm2']);
result = sortChannels('manual', data, notifyProps, 'en');
const manualIds = result.map((r) => r.id);
expect(manualIds).toEqual(['dm1', 'dm2', 'open-channel', 'gm1']);
result = sortChannels('alpha', data, notifyProps, 'en');
const alphaIds = result.map((r) => r.id);
expect(alphaIds).toEqual(['open-channel', 'dm1', 'gm1', 'dm2']);
});
test('getUnreadIds', async () => {
const db = DatabaseManager.getServerDatabaseAndOperator(serverUrl);
const {channels, myChannels} = buildChannelsData();
const data = await createChannelsDbRecords(db, channels, myChannels);
const notifyProps = myChannels.reduce<Record<string, Partial<ChannelNotifyProps>>>((obj, m) => {
obj[m.channel_id] = m.notify_props;
return obj;
}, {});
let result = getUnreadIds(data, notifyProps);
let ids = Array.from(result);
expect(ids).toEqual(['dm2', 'open-channel']);
result = getUnreadIds(data, notifyProps, 'dm1');
ids = Array.from(result);
expect(ids).toEqual(['dm1', 'dm2', 'open-channel']);
});
});

View file

@ -24,7 +24,7 @@ export function makeCategoryChannelId(teamId: string, channelId: string) {
export const isUnreadChannel = (myChannel: MyChannelModel, notifyProps?: Partial<ChannelNotifyProps>, lastUnreadChannelId?: string) => {
const isMuted = notifyProps?.mark_unread === General.MENTION;
return myChannel.mentionsCount || (!isMuted && myChannel.isUnread) || (myChannel.id === lastUnreadChannelId);
return Boolean(myChannel.mentionsCount) || (!isMuted && myChannel.isUnread) || (myChannel.id === lastUnreadChannelId);
};
export const filterArchivedChannels = (channelsWithMyChannel: ChannelWithMyChannel[], currentChannelId: string) => {