import { jest } from '@jest/globals'; const findOne = jest.fn(); const findOneAndUpdate = jest.fn(); jest.unstable_mockModule( '../database/schemas/misc/usersettings.schema.js', () => ({ userSettingsModel: { findOne, findOneAndUpdate } }) ); const { UserSettingsManager, createEmptySettings, isSafeSettingsKey } = await import('./usersettingsmanager.js'); const queryResult = value => ({ select: jest.fn().mockReturnValue({ lean: jest.fn().mockResolvedValue(value) }) }); describe('UserSettingsManager', () => { let manager; beforeEach(() => { jest.clearAllMocks(); manager = new UserSettingsManager({ authenticated: true, user: { _id: 'user-id' } }); }); it('returns empty defaults when the user has no settings document', async () => { findOne.mockReturnValue(queryResult(null)); await expect(manager.getUserSettings()).resolves.toEqual( createEmptySettings() ); expect(findOne).toHaveBeenCalledWith({ user: 'user-id' }); }); it('atomically upserts only the requested category and key', async () => { const defaults = { ...createEmptySettings(), viewMode: { payments: 'cards' } }; findOneAndUpdate.mockReturnValue(queryResult({ defaults })); await expect( manager.updateUserSettings({ category: 'viewMode', key: 'payments', value: 'cards' }) ).resolves.toEqual(defaults); expect(findOneAndUpdate).toHaveBeenCalledWith( { user: 'user-id' }, expect.objectContaining({ $set: expect.objectContaining({ 'defaults.viewMode.payments': 'cards' }), $setOnInsert: expect.objectContaining({ user: 'user-id' }) }), { new: true, upsert: true, setDefaultsOnInsert: true } ); }); it('writes pageLayout at the top level, not under defaults', async () => { const pageLayout = { InventoryOverview: { sectionOrder: ['partStockStats'], statsOrder: {} } }; findOneAndUpdate.mockReturnValue( queryResult({ defaults: createEmptySettings(), pageLayout }) ); await expect( manager.updateUserSettings({ category: 'pageLayout', key: 'InventoryOverview', value: pageLayout.InventoryOverview }) ).resolves.toEqual({ ...createEmptySettings(), pageLayout }); expect(findOneAndUpdate).toHaveBeenCalledWith( { user: 'user-id' }, expect.objectContaining({ $set: expect.objectContaining({ 'pageLayout.InventoryOverview': pageLayout.InventoryOverview }) }), expect.anything() ); expect(findOneAndUpdate.mock.calls[0][1].$set).not.toHaveProperty( 'defaults.pageLayout.InventoryOverview' ); }); it('rejects invalid categories and unsafe keys', async () => { await expect( manager.updateUserSettings({ category: 'unknown', key: 'payments', value: true }) ).rejects.toThrow('Invalid user settings category'); await expect( manager.updateUserSettings({ category: 'viewMode', key: 'payments.value', value: true }) ).rejects.toThrow('Invalid user settings key'); expect(isSafeSettingsKey('$payments')).toBe(false); expect(findOneAndUpdate).not.toHaveBeenCalled(); }); it('rejects unauthenticated access', async () => { manager = new UserSettingsManager({ authenticated: false, user: { _id: 'user-id' } }); await expect(manager.getUserSettings()).rejects.toThrow( 'User is not authenticated' ); }); });