UNPKG

@yoroi/portfolio

Version:

The Portfolio package of Yoroi SDK

214 lines (207 loc) 8.53 kB
"use strict"; var _common = require("@yoroi/common"); var _types = require("@yoroi/types"); var _tokenManager = require("./token-manager"); var _tokenStorageMaker = require("./adapters/mmkv-storage/token-storage-maker"); var _apiMaker = require("./adapters/dullahan-api/api-maker.mocks"); var _tokenInfo = require("./adapters/token-info.mocks"); var _createCachedUnknownTokenInfo = require("./helpers/create-cached-unknown-token-info"); describe('portfolioTokenManagerMaker', () => { const tokenInfoStorage = (0, _common.observableStorageMaker)((0, _common.mountMMKVStorage)({ path: `/test/token-info/` })); const storage = (0, _tokenStorageMaker.portfolioTokenStorageMaker)({ tokenInfoStorage }); afterEach(() => { jest.resetAllMocks(); storage.clear(); }); it('should hydrate the cache', () => { const api = _apiMaker.portfolioApiMock.success; const manager = (0, _tokenManager.portfolioTokenManagerMaker)({ api, storage }); const subscriber = jest.fn(); manager.subscribe(subscriber); manager.hydrate({ sourceId: 'sourceId' }); expect(subscriber).toHaveBeenCalledTimes(1); expect(subscriber).toHaveBeenCalledWith({ on: _types.Portfolio.Event.ManagerOn.Hydrate, sourceId: 'sourceId' }); }); it('should sync token infos with unknowns', async () => { storage.token.infos.save(_tokenInfo.tokenInfoMocks.storage.notModified); const api = _apiMaker.portfolioApiMock.success; const manager = (0, _tokenManager.portfolioTokenManagerMaker)({ api, storage }); const unknownTokenId = 'unknown.id'; const secondaryTokenIds = [_tokenInfo.tokenInfoMocks.rnftWhatever.id, _tokenInfo.tokenInfoMocks.nftCryptoKitty.id, unknownTokenId]; manager.hydrate({ sourceId: 'sourceId' }); const subscriber = jest.fn(); manager.subscribe(subscriber); const unknownCachedTokenInfo = (0, _createCachedUnknownTokenInfo.createCachedUnknownTokenInfo)(unknownTokenId); const result = await manager.sync({ secondaryTokenIds, sourceId: 'sourceId' }); expect(subscriber).toHaveBeenCalledTimes(1); expect(subscriber).toHaveBeenCalledWith({ on: _types.Portfolio.Event.ManagerOn.Sync, ids: expect.arrayContaining(secondaryTokenIds.slice(1)), sourceId: 'sourceId' }); expect(result.size).toBe(3); // should update the stale cache records with api data and refresh cache info const resultNftCryptoKitty = result.get(_tokenInfo.tokenInfoMocks.nftCryptoKitty.id); if (!resultNftCryptoKitty) fail(); expect(resultNftCryptoKitty.expires).toBeGreaterThan(Date.now()); expect(resultNftCryptoKitty.hash).toBe('hash2-1'); expect(resultNftCryptoKitty.record).toEqual(_tokenInfo.tokenInfoMocks.nftCryptoKitty); // should create unknown token info when api doesn't return it // creates expired so it will always hit the api when syncing const resultUnknownToken = result.get(unknownTokenId); if (!resultUnknownToken) fail(); expect(resultUnknownToken.expires).toBe(0); expect(resultUnknownToken.hash).toBe(''); expect(resultUnknownToken.record).toEqual(unknownCachedTokenInfo.record); // should return the cached record when api returns NotModified // yet, should update the expires but not the hash const resultRnftWhatever = result.get(_tokenInfo.tokenInfoMocks.rnftWhatever.id); if (!resultRnftWhatever) fail(); expect(resultRnftWhatever.expires).toBeGreaterThan(Date.now()); expect(resultRnftWhatever.hash).toBe('hash3'); expect(resultRnftWhatever.record).toEqual(_tokenInfo.tokenInfoMocks.rnftWhatever); manager.destroy(); }); it('should read all from cache', async () => { storage.token.infos.save(_tokenInfo.tokenInfoMocks.storage.cached); const api = _apiMaker.portfolioApiMock.success; const manager = (0, _tokenManager.portfolioTokenManagerMaker)({ api, storage }); const secondaryTokenIds = [_tokenInfo.tokenInfoMocks.rnftWhatever.id]; const result = await manager.sync({ secondaryTokenIds, sourceId: 'sourceId' }); expect(result.size).toBe(1); // should return the cached record and not hit the api const resultRnftWhatever = result.get(_tokenInfo.tokenInfoMocks.rnftWhatever.id); if (!resultRnftWhatever) fail(); expect(resultRnftWhatever.expires).toBeGreaterThan(Date.now()); expect(resultRnftWhatever.hash).toBe('hash3'); expect(resultRnftWhatever.record).toEqual(_tokenInfo.tokenInfoMocks.rnftWhatever); }); it('should create as unknwon when api error', async () => { const api = _apiMaker.portfolioApiMock.error; const manager = (0, _tokenManager.portfolioTokenManagerMaker)({ api, storage }); const secondaryTokenIds = [_tokenInfo.tokenInfoMocks.rnftWhatever.id]; const unknownCachedTokenInfo = (0, _createCachedUnknownTokenInfo.createCachedUnknownTokenInfo)(_tokenInfo.tokenInfoMocks.rnftWhatever.id); const result = await manager.sync({ secondaryTokenIds, sourceId: 'sourceId' }); expect(result.size).toBe(1); // should return the unknown record const resultRnftWhatever = result.get(_tokenInfo.tokenInfoMocks.rnftWhatever.id); if (!resultRnftWhatever) fail(); expect(resultRnftWhatever).toEqual(unknownCachedTokenInfo); }); it('should call destroy (coverage) observer is not exposed', () => { const api = _apiMaker.portfolioApiMock.success; const manager = (0, _tokenManager.portfolioTokenManagerMaker)({ api, storage }); manager.destroy(); }); it('should revalidate cache', async () => { const api = _apiMaker.portfolioApiMock.success; storage.token.infos.save(_tokenInfo.tokenInfoMocks.storage.notModified); const manager = (0, _tokenManager.portfolioTokenManagerMaker)({ api, storage }); const secondaryTokenIds = [_tokenInfo.tokenInfoMocks.rnftWhatever.id]; const result = await manager.sync({ secondaryTokenIds, sourceId: 'sourceId' }); expect(result.size).toBe(1); // should return the unknown record const resultRnftWhatever = result.get(_tokenInfo.tokenInfoMocks.rnftWhatever.id); if (!resultRnftWhatever) fail(); expect(resultRnftWhatever.expires).toBeGreaterThan(Date.now()); expect(resultRnftWhatever.hash).toBe('hash3'); expect(resultRnftWhatever.record).toEqual(_tokenInfo.tokenInfoMocks.rnftWhatever); }); it('should sync empty', async () => { const api = _apiMaker.portfolioApiMock.success; storage.token.infos.save(_tokenInfo.tokenInfoMocks.storage.notModified); const manager = (0, _tokenManager.portfolioTokenManagerMaker)({ api, storage }); const secondaryTokenIds = []; const result = await manager.sync({ secondaryTokenIds, sourceId: 'sourceId' }); expect(result.size).toBe(0); }); it('should sync empty to revalidate', async () => { const api = _apiMaker.portfolioApiMock.success; const manager = (0, _tokenManager.portfolioTokenManagerMaker)({ api, storage }); const secondaryTokenIds = [_tokenInfo.tokenInfoMocks.rnftWhatever.id]; const unknownCachedTokenInfo = (0, _createCachedUnknownTokenInfo.createCachedUnknownTokenInfo)(_tokenInfo.tokenInfoMocks.rnftWhatever.id); const result = await manager.sync({ secondaryTokenIds, sourceId: 'sourceId' }); expect(result.size).toBe(1); const resultRnftWhatever = result.get(_tokenInfo.tokenInfoMocks.rnftWhatever.id); if (!resultRnftWhatever) fail(); expect(resultRnftWhatever).toEqual(unknownCachedTokenInfo); }); it('should clear all data in the storage', async () => { const api = _apiMaker.portfolioApiMock.success; const manager = (0, _tokenManager.portfolioTokenManagerMaker)({ api, storage }); const secondaryTokenIds = [_tokenInfo.tokenInfoMocks.rnftWhatever.id]; await manager.sync({ secondaryTokenIds, sourceId: 'sourceId' }); expect(storage.token.infos.read([_tokenInfo.tokenInfoMocks.rnftWhatever.id]).length).toBe(1); const subscriber = jest.fn(); manager.subscribe(subscriber); manager.clear({ sourceId: 'sourceId' }); expect(storage.token.infos.all().length).toBe(0); expect(subscriber).toHaveBeenCalledWith({ on: _types.Portfolio.Event.ManagerOn.Clear, sourceId: 'sourceId' }); manager.destroy(); }); }); //# sourceMappingURL=token-manager.test.js.map