feat(release): prepare 1.1.0 candidate
This commit is contained in:
parent
5a34f66981
commit
5205dcdfa9
736 changed files with 115667 additions and 12203 deletions
114
apps/mobile-rn/__tests__/preferences.test.ts
Normal file
114
apps/mobile-rn/__tests__/preferences.test.ts
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
import {
|
||||
applyPreferencesPatch,
|
||||
clearAllUserPreferenceCaches,
|
||||
normalizePreferences,
|
||||
normalizePreferencesPatch,
|
||||
} from '../src/lib/preferences-context'
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage'
|
||||
import {
|
||||
getMobileThemePalette,
|
||||
resolveEffectiveTheme,
|
||||
} from '../src/theme/mobile-theme'
|
||||
|
||||
describe('mobile preferences model', () => {
|
||||
test('rejects malformed cached values and restores safe defaults', () => {
|
||||
const normalized = normalizePreferences({
|
||||
themeMode: 'neon',
|
||||
locale: 'unknown',
|
||||
hapticEnabled: 'yes',
|
||||
autoPolishEnabled: false,
|
||||
onboardingVersion: -4,
|
||||
tutorialCompletedAt: 'not-a-date',
|
||||
revision: 0,
|
||||
})
|
||||
|
||||
expect(normalized).toMatchObject({
|
||||
themeMode: 'system',
|
||||
locale: 'ko',
|
||||
hapticEnabled: true,
|
||||
autoPolishEnabled: false,
|
||||
onboardingVersion: 0,
|
||||
tutorialCompletedAt: null,
|
||||
revision: 1,
|
||||
})
|
||||
})
|
||||
|
||||
test('accepts only supported fields in a pending patch', () => {
|
||||
expect(normalizePreferencesPatch({
|
||||
themeMode: 'light',
|
||||
locale: 'en',
|
||||
hapticEnabled: false,
|
||||
preferredSttModel: ' cloud-default ',
|
||||
revision: 999,
|
||||
unknownSetting: true,
|
||||
})).toEqual({
|
||||
themeMode: 'light',
|
||||
locale: 'en',
|
||||
hapticEnabled: false,
|
||||
preferredSttModel: 'cloud-default',
|
||||
})
|
||||
})
|
||||
|
||||
test('applies an offline patch without discarding server metadata', () => {
|
||||
const original = normalizePreferences({
|
||||
themeMode: 'dark',
|
||||
locale: 'ko',
|
||||
hapticEnabled: true,
|
||||
autoPolishEnabled: true,
|
||||
preferredSttModel: 'cloud-default',
|
||||
preferredLlmModel: 'claude',
|
||||
onboardingVersion: 1,
|
||||
tutorialCompletedAt: '2026-08-21T01:00:00.000Z',
|
||||
revision: 8,
|
||||
updatedAt: '2026-08-21T01:05:00.000Z',
|
||||
})
|
||||
const updated = applyPreferencesPatch(original, {
|
||||
themeMode: 'light',
|
||||
hapticEnabled: false,
|
||||
})
|
||||
|
||||
expect(updated.themeMode).toBe('light')
|
||||
expect(updated.hapticEnabled).toBe(false)
|
||||
expect(updated.preferredSttModel).toBe('cloud-default')
|
||||
expect(updated.preferredLlmModel).toBe('claude')
|
||||
expect(updated.revision).toBe(8)
|
||||
expect(updated.updatedAt).toBe('2026-08-21T01:05:00.000Z')
|
||||
})
|
||||
|
||||
test('logout purge removes account caches but preserves installation settings', async () => {
|
||||
const getAllKeys = AsyncStorage.getAllKeys as jest.MockedFunction<
|
||||
typeof AsyncStorage.getAllKeys
|
||||
>
|
||||
const multiRemove = AsyncStorage.multiRemove as jest.MockedFunction<
|
||||
typeof AsyncStorage.multiRemove
|
||||
>
|
||||
getAllKeys.mockResolvedValueOnce([
|
||||
'@d3ro/mobile/preferences/installation-v1',
|
||||
'@d3ro/mobile/preferences/user-v1/account-a',
|
||||
'@d3ro/mobile/preferences/user-v1/account-b',
|
||||
'@another/app/key',
|
||||
])
|
||||
|
||||
await clearAllUserPreferenceCaches()
|
||||
|
||||
expect(multiRemove).toHaveBeenCalledWith([
|
||||
'@d3ro/mobile/preferences/user-v1/account-a',
|
||||
'@d3ro/mobile/preferences/user-v1/account-b',
|
||||
])
|
||||
})
|
||||
})
|
||||
|
||||
describe('mobile theme resolution', () => {
|
||||
test('system mode follows the device and falls back to dark', () => {
|
||||
expect(resolveEffectiveTheme('system', 'light')).toBe('light')
|
||||
expect(resolveEffectiveTheme('system', 'dark')).toBe('dark')
|
||||
expect(resolveEffectiveTheme('system', null)).toBe('dark')
|
||||
})
|
||||
|
||||
test('an explicit theme does not change with the device setting', () => {
|
||||
expect(resolveEffectiveTheme('light', 'dark')).toBe('light')
|
||||
expect(resolveEffectiveTheme('dark', 'light')).toBe('dark')
|
||||
expect(getMobileThemePalette('light').bg.app)
|
||||
.not.toBe(getMobileThemePalette('dark').bg.app)
|
||||
})
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue