MM-59787 Add tests for preference query functions (#8530)

* test: Add tests for preference query functions

* sync test changes

---------

Co-authored-by: Rahim Rahman <rahim.rahman@mattermost.com>
This commit is contained in:
Joram Wilander 2025-01-29 17:10:21 -05:00 committed by GitHub
parent 0bac4b96f0
commit 1d254d4529
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -0,0 +1,408 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Preferences} from '@constants';
import {CATEGORIES_TO_KEEP} from '@constants/preferences';
import DatabaseManager from '@database/manager';
import {
prepareMyPreferences,
queryPreferencesByCategoryAndName,
getThemeForCurrentTeam,
deletePreferences,
differsFromLocalNameFormat,
getHasCRTChanged,
queryDisplayNamePreferences,
querySavedPostsPreferences,
queryThemePreferences,
querySidebarPreferences,
queryEmojiPreferences,
queryAdvanceSettingsPreferences,
} from './preference';
import type ServerDataOperator from '@database/operator/server_data_operator';
import type {Database} from '@nozbe/watermelondb';
describe('Preference Queries', () => {
const serverUrl = 'baseHandler.test.com';
let database: Database;
let operator: ServerDataOperator;
beforeEach(async () => {
await DatabaseManager.init([serverUrl]);
const serverDatabaseAndOperator = DatabaseManager.getServerDatabaseAndOperator(serverUrl);
database = serverDatabaseAndOperator.database;
operator = serverDatabaseAndOperator.operator;
});
afterEach(async () => {
await DatabaseManager.destroyServerDatabase(serverUrl);
});
describe('prepareMyPreferences', () => {
it('should prepare preference records', async () => {
const preferences = [
{
user_id: 'user1',
category: Preferences.CATEGORIES.DISPLAY_SETTINGS,
name: 'name_format',
value: 'username',
},
{
user_id: 'user1',
category: Preferences.CATEGORIES.THEME,
name: 'theme',
value: '{"type":"dark"}',
},
];
const records = await prepareMyPreferences(operator, preferences);
expect(records.length).toBe(2);
expect(records[0].name).toBe('name_format');
expect(records[0]._preparedState).toBe('create');
expect(records[1].name).toBe('theme');
expect(records[1]._preparedState).toBe('create');
});
it('should handle sync flag', async () => {
const oldValue = 'username';
const newValue = 'username-new';
const preferences = [{
user_id: 'user1',
category: Preferences.CATEGORIES.DISPLAY_SETTINGS,
name: 'name_format',
value: newValue,
}];
await operator.handlePreferences({
preferences: [
{
user_id: 'user1',
category: Preferences.CATEGORIES.DISPLAY_SETTINGS,
name: 'name_format',
value: oldValue,
},
// with sync, this record will be deleted since it's not in the preferences array
{
user_id: 'user1',
category: Preferences.CATEGORIES.THEME,
name: 'theme',
value: '{"type":"dark"}',
},
],
prepareRecordsOnly: false,
});
await database.write(async () => {
const records = await prepareMyPreferences(operator, preferences, true);
expect(records[0]._preparedState).toBe('update');
expect(records[1]._preparedState).toBe('destroyPermanently');
// without this, the test will fail because of this error:
// Diagnostic error: record.prepareUpdate was called on Preference#xxxx but wasn't sent to batch() synchronously -- this is bad!
await database.batch(...records);
});
const storedPrefs = await queryDisplayNamePreferences(database).fetch();
expect(storedPrefs.length).toBe(1);
expect(storedPrefs[0].value).toEqual(newValue);
const themePrefs = await queryThemePreferences(database).fetch();
expect(themePrefs.length).toBe(0);
});
});
describe('queryPreferencesByCategoryAndName', () => {
it('should query by category only', async () => {
await operator.handlePreferences({
preferences: [
{
user_id: 'user1',
category: CATEGORIES_TO_KEEP.ADVANCED_SETTINGS,
name: 'test1',
value: 'value1',
},
{
user_id: 'user1',
category: CATEGORIES_TO_KEEP.ADVANCED_SETTINGS,
name: 'test2',
value: 'value2',
},
{
user_id: 'user1',
category: Preferences.CATEGORIES.DISPLAY_SETTINGS,
name: 'name_format',
value: 'username',
},
],
prepareRecordsOnly: false,
});
const prefs = await queryPreferencesByCategoryAndName(database, CATEGORIES_TO_KEEP.ADVANCED_SETTINGS).fetch();
expect(prefs.length).toBe(2);
});
it('should query by category and name', async () => {
await operator.handlePreferences({
preferences: [
{
user_id: 'user1',
category: CATEGORIES_TO_KEEP.ADVANCED_SETTINGS,
name: 'test1',
value: 'value1',
},
{
user_id: 'user1',
category: CATEGORIES_TO_KEEP.ADVANCED_SETTINGS,
name: 'test2',
value: 'value2',
},
],
prepareRecordsOnly: false,
});
const prefs = await queryPreferencesByCategoryAndName(database, CATEGORIES_TO_KEEP.ADVANCED_SETTINGS, 'test1').fetch();
expect(prefs.length).toBe(1);
expect(prefs[0].name).toBe('test1');
});
it('should query by category, name and value', async () => {
await operator.handlePreferences({
preferences: [
{
user_id: 'user1',
category: CATEGORIES_TO_KEEP.ADVANCED_SETTINGS,
name: 'test1',
value: 'value1',
},
{
user_id: 'user1',
category: CATEGORIES_TO_KEEP.ADVANCED_SETTINGS,
name: 'test1',
value: 'value2',
},
],
prepareRecordsOnly: false,
});
const prefs = await queryPreferencesByCategoryAndName(database, CATEGORIES_TO_KEEP.ADVANCED_SETTINGS, 'test1', 'value1').fetch();
expect(prefs.length).toBe(1);
expect(prefs[0].value).toBe('value1');
});
});
describe('getThemeForCurrentTeam', () => {
it('should return undefined if no theme exists', async () => {
const theme = await getThemeForCurrentTeam(database);
expect(theme).toBeUndefined();
});
it('should return theme for current team', async () => {
const teamId = 'team1';
const themeValue = {
type: 'dark',
sidebarBg: '#000000',
};
await operator.handleSystem({
systems: [{id: 'currentTeamId', value: teamId}],
prepareRecordsOnly: false,
});
await operator.handlePreferences({
preferences: [{
user_id: 'user1',
category: Preferences.CATEGORIES.THEME,
name: teamId,
value: JSON.stringify(themeValue),
}],
prepareRecordsOnly: false,
});
const theme = await getThemeForCurrentTeam(database);
expect(theme).toEqual(themeValue);
});
});
describe('deletePreferences', () => {
it('should delete preferences', async () => {
const pref1 = {
user_id: 'user1',
category: CATEGORIES_TO_KEEP.ADVANCED_SETTINGS,
name: 'test1',
value: 'value1',
};
await operator.handlePreferences({
preferences: [
pref1,
{
user_id: 'user1',
category: CATEGORIES_TO_KEEP.ADVANCED_SETTINGS,
name: 'test2',
value: 'value2',
},
],
prepareRecordsOnly: false,
});
const prefsToDelete = [pref1];
const success = await deletePreferences({database, operator}, prefsToDelete);
expect(success).toBe(true);
const remaining = await queryPreferencesByCategoryAndName(database, CATEGORIES_TO_KEEP.ADVANCED_SETTINGS).fetch();
expect(remaining.length).toBe(1);
expect(remaining[0].name).toBe('test2');
});
it('should handle empty prefs gracefully', async () => {
const success = await deletePreferences({database, operator}, []);
expect(success).toBe(true);
});
});
describe('differsFromLocalNameFormat', () => {
it('should detect when name format differs', async () => {
await operator.handlePreferences({
preferences: [{
user_id: 'user1',
category: Preferences.CATEGORIES.DISPLAY_SETTINGS,
name: Preferences.NAME_NAME_FORMAT,
value: 'username',
}],
prepareRecordsOnly: false,
});
const newPrefs = [{
user_id: 'user1',
category: Preferences.CATEGORIES.DISPLAY_SETTINGS,
name: Preferences.NAME_NAME_FORMAT,
value: 'nickname',
}];
const differs = await differsFromLocalNameFormat(database, newPrefs);
expect(differs).toBe(true);
});
it('should handle empty preferences', async () => {
const differs = await differsFromLocalNameFormat(database, []);
expect(differs).toBe(false);
});
});
describe('getHasCRTChanged', () => {
it('should detect CRT changes', async () => {
await operator.handlePreferences({
preferences: [{
user_id: 'user1',
category: Preferences.CATEGORIES.DISPLAY_SETTINGS,
name: Preferences.COLLAPSED_REPLY_THREADS,
value: 'off',
}],
prepareRecordsOnly: false,
});
const newPrefs = [{
user_id: 'user1',
category: Preferences.CATEGORIES.DISPLAY_SETTINGS,
name: Preferences.COLLAPSED_REPLY_THREADS,
value: 'on',
}];
const changed = await getHasCRTChanged(database, newPrefs);
expect(changed).toBe(true);
});
it('should handle no CRT preference', async () => {
const changed = await getHasCRTChanged(database, []);
expect(changed).toBe(false);
});
});
describe('category-specific queries', () => {
beforeEach(async () => {
await operator.handlePreferences({
preferences: [
{
user_id: 'user1',
category: Preferences.CATEGORIES.DISPLAY_SETTINGS,
name: 'display_test',
value: 'display_value',
},
{
user_id: 'user1',
category: Preferences.CATEGORIES.SAVED_POST,
name: 'post1',
value: 'saved',
},
{
user_id: 'user1',
category: Preferences.CATEGORIES.THEME,
name: 'theme1',
value: '{"type":"dark"}',
},
{
user_id: 'user1',
category: Preferences.CATEGORIES.SIDEBAR_SETTINGS,
name: 'sidebar_test',
value: 'sidebar_value',
},
{
user_id: 'user1',
category: Preferences.CATEGORIES.EMOJI,
name: 'emoji_test',
value: 'emoji_value',
},
{
user_id: 'user1',
category: Preferences.CATEGORIES.ADVANCED_SETTINGS,
name: 'advanced_test',
value: 'advanced_value',
},
],
prepareRecordsOnly: false,
});
});
it('should query display name preferences', async () => {
const prefs = await queryDisplayNamePreferences(database).fetch();
expect(prefs.length).toBe(1);
expect(prefs[0].category).toBe(Preferences.CATEGORIES.DISPLAY_SETTINGS);
});
it('should query saved posts preferences', async () => {
const prefs = await querySavedPostsPreferences(database).fetch();
expect(prefs.length).toBe(1);
expect(prefs[0].category).toBe(Preferences.CATEGORIES.SAVED_POST);
});
it('should query theme preferences', async () => {
const prefs = await queryThemePreferences(database).fetch();
expect(prefs.length).toBe(1);
expect(prefs[0].category).toBe(Preferences.CATEGORIES.THEME);
});
it('should query sidebar preferences', async () => {
const prefs = await querySidebarPreferences(database).fetch();
expect(prefs.length).toBe(1);
expect(prefs[0].category).toBe(Preferences.CATEGORIES.SIDEBAR_SETTINGS);
});
it('should query emoji preferences', async () => {
const prefs = await queryEmojiPreferences(database, 'emoji_test').fetch();
expect(prefs.length).toBe(1);
expect(prefs[0].category).toBe(Preferences.CATEGORIES.EMOJI);
});
it('should query advanced settings preferences', async () => {
const prefs = await queryAdvanceSettingsPreferences(database).fetch();
expect(prefs.length).toBe(1);
expect(prefs[0].category).toBe(Preferences.CATEGORIES.ADVANCED_SETTINGS);
});
});
});