import migration48 from './048'; const localhostNetwork = { rpcUrl: 'http://localhost:8545', chainId: '0x539', ticker: 'ETH', nickname: 'Localhost 8545', rpcPrefs: {}, }; const expectedPreferencesState = { PreferencesController: { frequentRpcListDetail: [ { ...localhostNetwork, }, ], }, }; describe('migration #48', () => { it('should update the version metadata', async () => { const oldStorage = { meta: { version: 47, }, data: {}, }; const newStorage = await migration48.migrate(oldStorage); expect(newStorage.meta).toStrictEqual({ version: 48, }); }); it('should delete NetworkController.settings', async () => { const oldStorage = { meta: {}, data: { NetworkController: { settings: { fizz: 'buzz', }, provider: { type: 'notRpc', }, }, foo: 'bar', }, }; const newStorage = await migration48.migrate(oldStorage); expect(newStorage.data).toStrictEqual({ ...expectedPreferencesState, NetworkController: { provider: { type: 'notRpc', }, }, foo: 'bar', }); }); it('should migrate NetworkController.provider to Rinkeby if the type is "rpc" and the chainId is invalid (1)', async () => { const oldStorage = { meta: {}, data: { NetworkController: { provider: { type: 'rpc', chainId: 'foo', fizz: 'buzz', }, foo: 'bar', }, foo: 'bar', }, }; const newStorage = await migration48.migrate(oldStorage); expect(newStorage.data).toStrictEqual({ ...expectedPreferencesState, NetworkController: { provider: { type: 'rinkeby', rpcUrl: '', chainId: '0x4', nickname: '', rpcPrefs: {}, ticker: 'ETH', }, foo: 'bar', }, foo: 'bar', }); }); it('should migrate NetworkController.provider to Rinkeby if the type is "rpc" and the chainId is invalid (2)', async () => { const oldStorage = { meta: {}, data: { NetworkController: { provider: { type: 'rpc', chainId: '0x01', fizz: 'buzz', }, foo: 'bar', }, foo: 'bar', }, }; const newStorage = await migration48.migrate(oldStorage); expect(newStorage.data).toStrictEqual({ ...expectedPreferencesState, NetworkController: { provider: { type: 'rinkeby', rpcUrl: '', chainId: '0x4', nickname: '', rpcPrefs: {}, ticker: 'ETH', }, foo: 'bar', }, foo: 'bar', }); }); it('should not migrate NetworkController.provider to Rinkeby if the type is "rpc" and the chainId is valid', async () => { const oldStorage = { meta: {}, data: { NetworkController: { provider: { type: 'rpc', chainId: '0x1', fizz: 'buzz', }, foo: 'bar', }, foo: 'bar', }, }; const newStorage = await migration48.migrate(oldStorage); expect(newStorage.data).toStrictEqual({ ...expectedPreferencesState, NetworkController: { provider: { type: 'rpc', chainId: '0x1', fizz: 'buzz', }, foo: 'bar', }, foo: 'bar', }); }); it('should migrate NetworkController.provider to Rinkeby if the type is "localhost"', async () => { const oldStorage = { meta: {}, data: { NetworkController: { provider: { type: 'localhost', fizz: 'buzz', }, foo: 'bar', }, foo: 'bar', }, }; const newStorage = await migration48.migrate(oldStorage); expect(newStorage.data).toStrictEqual({ ...expectedPreferencesState, NetworkController: { provider: { type: 'rinkeby', rpcUrl: '', chainId: '0x4', nickname: '', rpcPrefs: {}, ticker: 'ETH', }, foo: 'bar', }, foo: 'bar', }); }); it('should re-key NetworkController.provider.rpcTarget to rpcUrl if the type is not "rpc" or "localhost"', async () => { const oldStorage = { meta: {}, data: { NetworkController: { provider: { type: 'someType', rpcTarget: 'foo.xyz', fizz: 'buzz', }, foo: 'bar', }, foo: 'bar', }, }; const newStorage = await migration48.migrate(oldStorage); expect(newStorage.data).toStrictEqual({ ...expectedPreferencesState, NetworkController: { foo: 'bar', provider: { type: 'someType', rpcUrl: 'foo.xyz', fizz: 'buzz', }, }, foo: 'bar', }); }); it('should do nothing to NetworkController if affected state does not exist', async () => { const oldStorage = { meta: {}, data: { NetworkController: { provider: { type: 'notRpc', }, }, foo: 'bar', }, }; const newStorage = await migration48.migrate(oldStorage); expect({ ...expectedPreferencesState, ...oldStorage.data }).toStrictEqual({ ...expectedPreferencesState, ...newStorage.data, }); }); it('should add frequentRpcListDetail item to beginning of list', async () => { const existingList = [ { rpcUrl: 'foo', chainId: '0x1' }, { rpcUrl: 'bar', chainId: '0x2' }, ]; const oldStorage = { meta: {}, data: { PreferencesController: { frequentRpcListDetail: [...existingList], }, foo: 'bar', }, }; const newStorage = await migration48.migrate(oldStorage); expect(newStorage.data).toStrictEqual({ PreferencesController: { frequentRpcListDetail: [{ ...localhostNetwork }, ...existingList], }, foo: 'bar', }); }); it('should delete CachedBalancesController.cachedBalances', async () => { const oldStorage = { meta: {}, data: { CachedBalancesController: { cachedBalances: { fizz: 'buzz', }, bar: { baz: 'buzz', }, }, foo: 'bar', }, }; const newStorage = await migration48.migrate(oldStorage); expect(newStorage.data).toStrictEqual({ ...expectedPreferencesState, CachedBalancesController: { bar: { baz: 'buzz', }, }, foo: 'bar', }); }); it('should convert hex transaction metamaskNetworkId values to decimal', async () => { const oldStorage = { meta: {}, data: { TransactionController: { transactions: [ { fizz: 'buzz' }, null, undefined, 0, '', { foo: 'bar', metamaskNetworkId: '1' }, { foo: 'bar', metamaskNetworkId: '0x1' }, { foo: 'bar', metamaskNetworkId: 'kaplar' }, { foo: 'bar', metamaskNetworkId: '0X2a' }, { foo: 'bar', metamaskNetworkId: '3' }, ], bar: { baz: 'buzz', }, }, foo: 'bar', }, }; const newStorage = await migration48.migrate(oldStorage); expect(newStorage.data).toStrictEqual({ ...expectedPreferencesState, TransactionController: { transactions: [ { fizz: 'buzz' }, null, undefined, 0, '', { foo: 'bar', metamaskNetworkId: '1' }, { foo: 'bar', metamaskNetworkId: '1' }, { foo: 'bar', metamaskNetworkId: 'kaplar' }, { foo: 'bar', metamaskNetworkId: '42' }, { foo: 'bar', metamaskNetworkId: '3' }, ], bar: { baz: 'buzz', }, }, foo: 'bar', }); }); it('should migrate the address book', async () => { const oldStorage = { meta: {}, data: { AddressBookController: { addressBook: { 1: { address1: { chainId: '1', foo: 'bar', }, }, 100: { address1: { chainId: '100', foo: 'bar', }, }, '0x2': { address2: { chainId: '0x2', foo: 'bar', }, }, }, bar: { baz: 'buzz', }, }, foo: 'bar', }, }; const newStorage = await migration48.migrate(oldStorage); expect(newStorage.data).toStrictEqual({ ...expectedPreferencesState, AddressBookController: { addressBook: { '0x1': { address1: { chainId: '0x1', foo: 'bar', }, }, '0x64': { address1: { chainId: '0x64', foo: 'bar', }, }, '0x2': { address2: { chainId: '0x2', foo: 'bar', }, }, }, bar: { baz: 'buzz', }, }, foo: 'bar', }); }); it('should migrate the address book and merge entries', async () => { const oldStorage = { meta: {}, data: { AddressBookController: { addressBook: { 2: { address1: { chainId: '2', key2: 'kaplar', key3: 'value3', key4: null, foo: 'bar', }, address2: { chainId: '2', foo: 'bar', }, }, '0x2': { address1: { chainId: '0x2', key1: 'value1', key2: 'value2', foo: 'bar', }, address3: { chainId: '0x2', foo: 'bar', }, }, }, bar: { baz: 'buzz', }, }, foo: 'bar', }, }; const newStorage = await migration48.migrate(oldStorage); expect(newStorage.data).toStrictEqual({ ...expectedPreferencesState, AddressBookController: { addressBook: { '0x2': { address1: { chainId: '0x2', key1: 'value1', key2: 'value2', key3: 'value3', key4: '', foo: 'bar', }, address2: { chainId: '0x2', foo: 'bar', }, address3: { chainId: '0x2', foo: 'bar', }, }, }, bar: { baz: 'buzz', }, }, foo: 'bar', }); }); it('should not modify address book if all entries are valid or un-parseable', async () => { const oldStorage = { meta: {}, data: { AddressBookController: { addressBook: { '0x1': { foo: { bar: 'baz' } }, kaplar: { foo: { bar: 'baz' } }, }, bar: { baz: 'buzz', }, }, foo: 'bar', }, }; const newStorage = await migration48.migrate(oldStorage); expect(newStorage.data).toStrictEqual({ ...expectedPreferencesState, AddressBookController: { addressBook: { '0x1': { foo: { bar: 'baz' } }, kaplar: { foo: { bar: 'baz' } }, }, bar: { baz: 'buzz', }, }, foo: 'bar', }); }); it('should delete localhost key in IncomingTransactionsController', async () => { const oldStorage = { meta: {}, data: { IncomingTransactionsController: { incomingTxLastFetchedBlocksByNetwork: { fizz: 'buzz', localhost: {}, }, bar: 'baz', }, foo: 'bar', }, }; const newStorage = await migration48.migrate(oldStorage); expect(newStorage.data).toStrictEqual({ ...expectedPreferencesState, IncomingTransactionsController: { incomingTxLastFetchedBlocksByNetwork: { fizz: 'buzz', }, bar: 'baz', }, foo: 'bar', }); }); it('should not modify IncomingTransactionsController state if affected key is missing', async () => { const oldStorage = { meta: {}, data: { IncomingTransactionsController: { incomingTxLastFetchedBlocksByNetwork: { fizz: 'buzz', rpc: {}, }, bar: 'baz', }, foo: 'bar', }, }; const newStorage = await migration48.migrate(oldStorage); expect(newStorage.data).toStrictEqual({ ...expectedPreferencesState, IncomingTransactionsController: { incomingTxLastFetchedBlocksByNetwork: { fizz: 'buzz', rpc: {}, }, bar: 'baz', }, foo: 'bar', }); }); it('should merge localhost token list into rpc token list', async () => { const oldStorage = { meta: {}, data: { PreferencesController: { accountTokens: { address1: { localhost: [ { address: '1', data1: 'stuff1' }, { address: '2', a: 'X', b: 'B' }, ], rpc: [ { address: '2', a: 'A', c: 'C' }, { address: '3', data3: 'stuff3' }, ], foo: [], }, address2: { localhost: [], rpc: [], foo: [], }, address3: {}, }, bar: 'baz', }, foo: 'bar', }, }; const newStorage = await migration48.migrate(oldStorage); expect(newStorage.data).toStrictEqual({ PreferencesController: { accountTokens: { address1: { rpc: [ { address: '1', data1: 'stuff1' }, { address: '2', a: 'A', b: 'B', c: 'C' }, { address: '3', data3: 'stuff3' }, ], foo: [], }, address2: { rpc: [], foo: [], }, address3: {}, }, bar: 'baz', // from other migration frequentRpcListDetail: [ { ...localhostNetwork, }, ], }, foo: 'bar', }); }); });