diff options
Diffstat (limited to 'src/state/persisted/__tests__/migrate.test.ts')
-rw-r--r-- | src/state/persisted/__tests__/migrate.test.ts | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/src/state/persisted/__tests__/migrate.test.ts b/src/state/persisted/__tests__/migrate.test.ts new file mode 100644 index 000000000..d42580efd --- /dev/null +++ b/src/state/persisted/__tests__/migrate.test.ts @@ -0,0 +1,93 @@ +import {jest, expect, test, afterEach} from '@jest/globals' +import AsyncStorage from '@react-native-async-storage/async-storage' + +import {defaults, schema} from '#/state/persisted/schema' +import {transform, migrate} from '#/state/persisted/legacy' +import * as store from '#/state/persisted/store' +import {logger} from '#/logger' +import * as fixtures from '#/state/persisted/__tests__/fixtures' + +const write = jest.mocked(store.write) +const read = jest.mocked(store.read) + +jest.mock('#/logger') +jest.mock('#/state/persisted/store', () => ({ + write: jest.fn(), + read: jest.fn(), +})) + +afterEach(() => { + jest.clearAllMocks() + AsyncStorage.clear() +}) + +test('migrate: fresh install', async () => { + await migrate() + + expect(AsyncStorage.getItem).toHaveBeenCalledWith('root') + expect(read).toHaveBeenCalledTimes(1) + expect(logger.log).toHaveBeenCalledWith( + 'persisted state: no migration needed', + ) +}) + +test('migrate: fresh install, existing new storage', async () => { + read.mockResolvedValueOnce(defaults) + + await migrate() + + expect(AsyncStorage.getItem).toHaveBeenCalledWith('root') + expect(read).toHaveBeenCalledTimes(1) + expect(logger.log).toHaveBeenCalledWith( + 'persisted state: no migration needed', + ) +}) + +test('migrate: fresh install, AsyncStorage error', async () => { + const prevGetItem = AsyncStorage.getItem + + const error = new Error('test error') + + AsyncStorage.getItem = jest.fn(() => { + throw error + }) + + await migrate() + + expect(AsyncStorage.getItem).toHaveBeenCalledWith('root') + expect(logger.error).toHaveBeenCalledWith(error, { + message: 'persisted state: error migrating legacy storage', + }) + + AsyncStorage.getItem = prevGetItem +}) + +test('migrate: has legacy data', async () => { + await AsyncStorage.setItem('root', JSON.stringify(fixtures.LEGACY_DATA_DUMP)) + + await migrate() + + expect(write).toHaveBeenCalledWith(transform(fixtures.LEGACY_DATA_DUMP)) + expect(logger.log).toHaveBeenCalledWith( + 'persisted state: migrated legacy storage', + ) +}) + +test('migrate: has legacy data, fails validation', async () => { + const legacy = fixtures.LEGACY_DATA_DUMP + // @ts-ignore + legacy.shell.colorMode = 'invalid' + await AsyncStorage.setItem('root', JSON.stringify(legacy)) + + await migrate() + + const transformed = transform(legacy) + const validate = schema.safeParse(transformed) + + expect(write).not.toHaveBeenCalled() + expect(logger.error).toHaveBeenCalledWith( + 'persisted state: legacy data failed validation', + // @ts-ignore + {error: validate.error}, + ) +}) |