UNPKG

mattermost-redux

Version:

Common code (API client, Redux stores, logic, utility functions) for building a Mattermost client

824 lines (727 loc) 29.5 kB
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. import assert from 'assert'; import {General, Preferences} from '../../constants'; import * as Selectors from 'selectors/entities/preferences'; import mergeObjects from 'test/merge_objects'; import deepFreezeAndThrowOnMutation from 'utils/deep_freeze'; import {getPreferenceKey} from 'utils/preference_utils'; describe('Selectors.Preferences', () => { const category1 = 'testcategory1'; const category2 = 'testcategory2'; const directCategory = Preferences.CATEGORY_DIRECT_CHANNEL_SHOW; const groupCategory = Preferences.CATEGORY_GROUP_CHANNEL_SHOW; const favCategory = Preferences.CATEGORY_FAVORITE_CHANNEL; const name1 = 'testname1'; const value1 = 'true'; const pref1 = {category: category1, name: name1, value: value1}; const name2 = 'testname2'; const value2 = '42'; const pref2 = {category: category2, name: name2, value: value2}; const dm1 = 'teammate1'; const dmPref1 = {category: directCategory, name: dm1, value: 'true'}; const dm2 = 'teammate2'; const dmPref2 = {category: directCategory, name: dm2, value: 'false'}; const gp1 = 'group1'; const prefGp1 = {category: groupCategory, name: gp1, value: 'true'}; const gp2 = 'group2'; const prefGp2 = {category: groupCategory, name: gp2, value: 'false'}; const fav1 = 'favorite1'; const favPref1 = {category1: favCategory, name: fav1, value: 'true'}; const fav2 = 'favorite2'; const favPref2 = {category1: favCategory, name: fav2, value: 'false'}; const currentUserId = 'currentuserid'; const myPreferences = {}; myPreferences[`${category1}--${name1}`] = pref1; myPreferences[`${category2}--${name2}`] = pref2; myPreferences[`${directCategory}--${dm1}`] = dmPref1; myPreferences[`${directCategory}--${dm2}`] = dmPref2; myPreferences[`${groupCategory}--${gp1}`] = prefGp1; myPreferences[`${groupCategory}--${gp2}`] = prefGp2; myPreferences[`${favCategory}--${fav1}`] = favPref1; myPreferences[`${favCategory}--${fav2}`] = favPref2; const testState = deepFreezeAndThrowOnMutation({ entities: { users: { currentUserId, }, preferences: { myPreferences, }, }, }); describe('get preference', () => { it('should return the requested value', () => { assert.deepEqual(Selectors.get(testState, category1, name1), 'true'); }); describe('should fallback to the default', () => { it('if name unknown', () => { assert.deepEqual(Selectors.get(testState, category1, 'unknown name'), ''); }); it('if category unknown', () => { assert.deepEqual(Selectors.get(testState, 'unknown category', name1), ''); }); }); describe('should fallback to the overridden default', () => { it('if name unknown', () => { assert.deepEqual(Selectors.get(testState, category1, 'unknown name', 'fallback'), 'fallback'); }); it('if category unknown', () => { assert.deepEqual(Selectors.get(testState, 'unknown category', name1, 'fallback'), 'fallback'); }); }); }); describe('get bool preference', () => { it('should return the requested value', () => { assert.deepEqual(Selectors.getBool(testState, category1, name1), value1 === 'true'); }); describe('should fallback to the default', () => { it('if name unknown', () => { assert.deepEqual(Selectors.getBool(testState, category1, 'unknown name'), false); }); it('if category unknown', () => { assert.deepEqual(Selectors.getBool(testState, 'unknown category', name1), false); }); }); describe('should fallback to the overridden default', () => { it('if name unknown', () => { assert.deepEqual(Selectors.getBool(testState, category1, 'unknown name', true), true); }); it('if category unknown', () => { assert.deepEqual(Selectors.getBool(testState, 'unknown category', name1, true), true); }); }); }); describe('get int preference', () => { it('should return the requested value', () => { assert.deepEqual(Selectors.getInt(testState, category2, name2), value2); }); describe('should fallback to the default', () => { it('if name unknown', () => { assert.deepEqual(Selectors.getInt(testState, category2, 'unknown name'), 0); }); it('if category unknown', () => { assert.deepEqual(Selectors.getInt(testState, 'unknown category', name2), 0); }); }); describe('should fallback to the overridden default', () => { it('if name unknown', () => { assert.deepEqual(Selectors.getInt(testState, category2, 'unknown name', 100), 100); }); it('if category unknown', () => { assert.deepEqual(Selectors.getInt(testState, 'unknown category', name2, 100), 100); }); }); }); it('get preferences by category', () => { const getCategory = Selectors.makeGetCategory(); assert.deepEqual(getCategory(testState, category1), [pref1]); }); it('get direct channel show preferences', () => { assert.deepEqual(Selectors.getDirectShowPreferences(testState), [dmPref1, dmPref2]); }); it('get group channel show preferences', () => { assert.deepEqual(Selectors.getGroupShowPreferences(testState), [prefGp1, prefGp2]); }); it('get teammate name display setting', () => { assert.equal( Selectors.getTeammateNameDisplaySetting({ entities: { general: { config: { TeammateNameDisplay: General.TEAMMATE_NAME_DISPLAY.SHOW_NICKNAME_FULLNAME, }, }, preferences: { myPreferences: {}, }, }, }), General.TEAMMATE_NAME_DISPLAY.SHOW_NICKNAME_FULLNAME, ); }); describe('get theme', () => { it('default theme', () => { const currentTeamId = '1234'; assert.equal(Selectors.getTheme({ entities: { general: { config: { DefaultTheme: 'default', }, }, teams: { currentTeamId, }, preferences: { myPreferences: { }, }, }, }), Preferences.THEMES.default); }); it('custom theme', () => { const currentTeamId = '1234'; const theme = {sidebarBg: '#ff0000'}; assert.equal(Selectors.getTheme({ entities: { general: { config: { DefaultTheme: 'default', }, }, teams: { currentTeamId, }, preferences: { myPreferences: { [getPreferenceKey(Preferences.CATEGORY_THEME, '')]: { category: Preferences.CATEGORY_THEME, name: '', value: JSON.stringify(theme), }, }, }, }, }).sidebarBg, theme.sidebarBg); }); it('team-specific theme', () => { const currentTeamId = '1234'; const otherTeamId = 'abcd'; const theme = {sidebarBg: '#ff0000'}; assert.deepEqual(Selectors.getTheme({ entities: { general: { config: { DefaultTheme: 'default', }, }, teams: { currentTeamId, }, preferences: { myPreferences: { [getPreferenceKey(Preferences.CATEGORY_THEME, '')]: { category: Preferences.CATEGORY_THEME, name: '', value: JSON.stringify({}), }, [getPreferenceKey(Preferences.CATEGORY_THEME, currentTeamId)]: { category: Preferences.CATEGORY_THEME, name: currentTeamId, value: JSON.stringify(theme), }, [getPreferenceKey(Preferences.CATEGORY_THEME, otherTeamId)]: { category: Preferences.CATEGORY_THEME, name: otherTeamId, value: JSON.stringify({}), }, }, }, }, }).sidebarBg, theme.sidebarBg); }); it('mentionBj backwards compatability theme', () => { const currentTeamId = '1234'; const theme = {mentionBj: '#ff0000'}; assert.equal(Selectors.getTheme({ entities: { general: { config: { DefaultTheme: 'default', }, }, teams: { currentTeamId, }, preferences: { myPreferences: { [getPreferenceKey(Preferences.CATEGORY_THEME, '')]: { category: Preferences.CATEGORY_THEME, name: '', value: JSON.stringify(theme), }, }, }, }, }).mentionBg, theme.mentionBj); theme.mentionBg = '#ff0001'; assert.equal(Selectors.getTheme({ entities: { general: { config: { DefaultTheme: 'default', }, }, teams: { currentTeamId, }, preferences: { myPreferences: { [getPreferenceKey(Preferences.CATEGORY_THEME, '')]: { category: Preferences.CATEGORY_THEME, name: '', value: JSON.stringify(theme), }, }, }, }, }).mentionBg, theme.mentionBg); }); it('memoization', () => { const currentTeamId = '1234'; const otherTeamId = 'abcd'; let state = { entities: { general: { config: { DefaultTheme: 'default', }, }, teams: { currentTeamId, }, preferences: { myPreferences: { [getPreferenceKey(Preferences.CATEGORY_THEME, '')]: { category: Preferences.CATEGORY_THEME, name: '', value: JSON.stringify({}), }, [getPreferenceKey(Preferences.CATEGORY_THEME, currentTeamId)]: { category: Preferences.CATEGORY_THEME, name: currentTeamId, value: JSON.stringify({sidebarBg: '#ff0000'}), }, [getPreferenceKey(Preferences.CATEGORY_THEME, otherTeamId)]: { category: Preferences.CATEGORY_THEME, name: otherTeamId, value: JSON.stringify({}), }, }, }, }, }; const before = Selectors.getTheme(state); assert.equal(before, Selectors.getTheme(state)); state = { ...state, entities: { ...state.entities, preferences: { ...state.entities.preferences, myPreferences: { ...state.entities.preferences.myPreferences, somethingUnrelated: { category: 'somethingUnrelated', name: '', value: JSON.stringify({}), }, }, }, }, }; assert.equal(before, Selectors.getTheme(state)); state = { ...state, entities: { ...state.entities, preferences: { ...state.entities.preferences, myPreferences: { ...state.entities.preferences.myPreferences, [getPreferenceKey(Preferences.CATEGORY_THEME, currentTeamId)]: { category: Preferences.CATEGORY_THEME, name: currentTeamId, value: JSON.stringify({sidebarBg: '#0000ff'}), }, }, }, }, }; assert.notEqual(before, Selectors.getTheme(state)); assert.notDeepEqual(before, Selectors.getTheme(state)); }); it('custom theme with upper case colours', () => { const currentTeamId = '1234'; const theme = {sidebarBg: '#FF0000'}; assert.deepEqual(Selectors.getTheme({ entities: { general: { config: { DefaultTheme: 'default', }, }, teams: { currentTeamId, }, preferences: { myPreferences: { [getPreferenceKey(Preferences.CATEGORY_THEME, '')]: { category: Preferences.CATEGORY_THEME, name: '', value: JSON.stringify(theme), }, }, }, }, }).sidebarBg, theme.sidebarBg.toLowerCase()); }); it('custom theme with missing colours', () => { const currentTeamId = '1234'; const theme = {sidebarBg: '#ff0000'}; assert.equal(Selectors.getTheme({ entities: { general: { config: { DefaultTheme: 'default', }, }, teams: { currentTeamId, }, preferences: { myPreferences: { [getPreferenceKey(Preferences.CATEGORY_THEME, '')]: { category: Preferences.CATEGORY_THEME, name: '', value: JSON.stringify(theme), }, }, }, }, }).mentionHighlightLink, Preferences.THEMES.default.mentionHighlightLink); }); it('system theme with missing colours', () => { const currentTeamId = '1234'; const theme = { type: Preferences.THEMES.mattermostDark.type, sidebarBg: '#ff0000', }; assert.equal(Selectors.getTheme({ entities: { general: { config: { DefaultTheme: 'default', }, }, teams: { currentTeamId, }, preferences: { myPreferences: { [getPreferenceKey(Preferences.CATEGORY_THEME, '')]: { category: Preferences.CATEGORY_THEME, name: '', value: JSON.stringify(theme), }, }, }, }, }).sidebarText, Preferences.THEMES.mattermostDark.sidebarText); }); it('non-default system theme', () => { const currentTeamId = '1234'; const theme = { type: Preferences.THEMES.windows10.type, }; assert.equal(Selectors.getTheme({ entities: { general: { config: { DefaultTheme: 'default', }, }, teams: { currentTeamId, }, preferences: { myPreferences: { [getPreferenceKey(Preferences.CATEGORY_THEME, '')]: { category: Preferences.CATEGORY_THEME, name: '', value: JSON.stringify(theme), }, }, }, }, }).codeTheme, Preferences.THEMES.windows10.codeTheme); }); it('should return the server-configured theme by default', () => { assert.equal(Selectors.getTheme({ entities: { general: { config: { DefaultTheme: 'mattermostDark', }, }, teams: { currentTeamId: null, }, preferences: { myPreferences: { [getPreferenceKey(Preferences.CATEGORY_THEME, '')]: null, }, }, }, }).codeTheme, Preferences.THEMES.mattermostDark.codeTheme); // Opposite case assert.notEqual(Selectors.getTheme({ entities: { general: { config: { DefaultTheme: 'windows10', }, }, teams: { currentTeamId: null, }, preferences: { myPreferences: { [getPreferenceKey(Preferences.CATEGORY_THEME, '')]: null, }, }, }, }).codeTheme, Preferences.THEMES.mattermostDark.codeTheme); }); it('returns the "default" theme if the server-configured value is not present', () => { assert.equal(Selectors.getTheme({ entities: { general: { config: { DefaultTheme: 'fakedoesnotexist', }, }, teams: { currentTeamId: null, }, preferences: { myPreferences: { [getPreferenceKey(Preferences.CATEGORY_THEME, '')]: null, }, }, }, }).codeTheme, Preferences.THEMES.default.codeTheme); }); }); it('get theme from style', () => { const theme = {themeColor: '#ffffff'}; const currentTeamId = '1234'; const state = { entities: { general: { config: { DefaultTheme: 'default', }, }, teams: { currentTeamId, }, preferences: { myPreferences: { [getPreferenceKey(Preferences.CATEGORY_THEME, '')]: { category: Preferences.CATEGORY_THEME, name: '', value: JSON.stringify(theme), }, }, }, }, }; function testStyleFunction(myTheme) { return { container: { backgroundColor: myTheme.themeColor, height: 100, }, }; } const expected = { container: { backgroundColor: theme.themeColor, height: 100, }, }; const getStyleFromTheme = Selectors.makeGetStyleFromTheme(); assert.deepEqual(getStyleFromTheme(state, testStyleFunction), expected); }); it('get favorites names', () => { assert.deepEqual(Selectors.getFavoritesPreferences(testState), [fav1]); }); it('get visible teammates', () => { assert.deepEqual(Selectors.getVisibleTeammate(testState), [dm1]); }); it('get visible groups', () => { assert.deepEqual(Selectors.getVisibleGroupIds(testState), [gp1]); }); }); describe('shouldShowUnreadsCategory', () => { test('should return value from the preference if set', () => { const state = { entities: { general: { config: {}, }, preferences: { myPreferences: { [getPreferenceKey(Preferences.CATEGORY_SIDEBAR_SETTINGS, Preferences.SHOW_UNREAD_SECTION)]: {value: 'true'}, }, }, }, }; expect(Selectors.shouldShowUnreadsCategory(state)).toBe(true); }); test('should fall back properly from the new preference to the old one and then to the server default', () => { // With the new preference set let state = { entities: { general: { config: { ExperimentalChannelSidebarOrganization: 'default_on', ExperimentalGroupUnreadChannels: 'default_off', }, }, preferences: { myPreferences: { [getPreferenceKey(Preferences.CATEGORY_SIDEBAR_SETTINGS, Preferences.SHOW_UNREAD_SECTION)]: {value: 'true'}, [getPreferenceKey(Preferences.CATEGORY_SIDEBAR_SETTINGS, '')]: {value: JSON.stringify({unreads_at_top: 'false'})}, }, }, }, }; expect(Selectors.shouldShowUnreadsCategory(state)).toBe(true); state = mergeObjects(state, { entities: { preferences: { myPreferences: { [getPreferenceKey(Preferences.CATEGORY_SIDEBAR_SETTINGS, Preferences.SHOW_UNREAD_SECTION)]: {value: 'false'}, }, }, }, }); expect(Selectors.shouldShowUnreadsCategory(state)).toBe(false); // With only the old preference set state = { entities: { general: { config: { ExperimentalChannelSidebarOrganization: 'default_on', ExperimentalGroupUnreadChannels: 'default_off', }, }, preferences: { myPreferences: { [getPreferenceKey(Preferences.CATEGORY_SIDEBAR_SETTINGS, '')]: {value: JSON.stringify({unreads_at_top: 'true'})}, }, }, }, }; expect(Selectors.shouldShowUnreadsCategory(state)).toBe(true); state = mergeObjects(state, { entities: { preferences: { myPreferences: { [getPreferenceKey(Preferences.CATEGORY_SIDEBAR_SETTINGS, '')]: {value: JSON.stringify({unreads_at_top: 'false'})}, }, }, }, }); expect(Selectors.shouldShowUnreadsCategory(state)).toBe(false); // Fall back from there to the server default state = { entities: { general: { config: { ExperimentalChannelSidebarOrganization: 'default_on', ExperimentalGroupUnreadChannels: 'default_on', }, }, preferences: { myPreferences: {}, }, }, }; expect(Selectors.shouldShowUnreadsCategory(state)).toBe(true); state = mergeObjects(state, { entities: { general: { config: { ExperimentalGroupUnreadChannels: 'default_off', }, }, }, }); expect(Selectors.shouldShowUnreadsCategory(state)).toBe(false); }); test('should not let admins fully disable the unread section', () => { // With the old sidebar, setting ExperimentalGroupUnreadChannels to disabled has an effect const state = { entities: { general: { config: { ExperimentalChannelSidebarOrganization: 'default_on', ExperimentalGroupUnreadChannels: 'disabled', }, }, preferences: { myPreferences: { [getPreferenceKey(Preferences.CATEGORY_SIDEBAR_SETTINGS, Preferences.SHOW_UNREAD_SECTION)]: {value: 'true'}, [getPreferenceKey(Preferences.CATEGORY_SIDEBAR_SETTINGS, '')]: {value: JSON.stringify({unreads_at_top: 'true'})}, }, }, }, }; expect(Selectors.shouldShowUnreadsCategory(state)).toBe(true); }); }); describe('shouldAutocloseDMs', () => { test('should return false by default', () => { const state = { entities: { general: { config: { CloseUnusedDirectMessages: 'false', }, }, preferences: { myPreferences: {}, }, }, }; expect(Selectors.shouldAutocloseDMs(state)).toBe(false); }); test('should return true when enabled by server but not set by user', () => { const state = { entities: { general: { config: { CloseUnusedDirectMessages: 'true', }, }, preferences: { myPreferences: {}, }, }, }; expect(Selectors.shouldAutocloseDMs(state)).toBe(true); }); test('should return true when enabled by both server and user', () => { const state = { entities: { general: { config: { CloseUnusedDirectMessages: 'true', }, }, preferences: { myPreferences: { [getPreferenceKey(Preferences.CATEGORY_SIDEBAR_SETTINGS, Preferences.CHANNEL_SIDEBAR_AUTOCLOSE_DMS)]: {value: Preferences.AUTOCLOSE_DMS_ENABLED}, }, }, }, }; expect(Selectors.shouldAutocloseDMs(state)).toBe(true); }); test('should return false when enabled by server but disabled by user', () => { const state = { entities: { general: { config: { CloseUnusedDirectMessages: 'true', }, }, preferences: { myPreferences: { [getPreferenceKey(Preferences.CATEGORY_SIDEBAR_SETTINGS, Preferences.CHANNEL_SIDEBAR_AUTOCLOSE_DMS)]: {value: ''}, }, }, }, }; expect(Selectors.shouldAutocloseDMs(state)).toBe(false); }); test('should return false when enabled by user but disabled by server', () => { const state = { entities: { general: { config: { CloseUnusedDirectMessages: 'false', }, }, preferences: { myPreferences: { [getPreferenceKey(Preferences.CATEGORY_SIDEBAR_SETTINGS, Preferences.CHANNEL_SIDEBAR_AUTOCLOSE_DMS)]: {value: Preferences.AUTOCLOSE_DMS_ENABLED}, }, }, }, }; expect(Selectors.shouldAutocloseDMs(state)).toBe(false); }); });