UNPKG

@yoroi/portfolio

Version:

The Portfolio package of Yoroi SDK

547 lines (546 loc) 19.7 kB
"use strict"; var _types = require("@yoroi/types"); var _apiMaker = require("./api-maker"); var _tokenDiscovery = require("../token-discovery.mocks"); var _token = require("../token.mocks"); var _tokenActivity = require("../token-activity.mocks"); var _tokenImageInvalidate = require("../token-image-invalidate.mocks"); var _tokenHistory = require("../token-history.mocks"); describe('portfolioApiMaker', () => { const mockNetwork = _types.Chain.Network.Mainnet; const mockRequest = jest.fn(); beforeEach(() => { jest.resetAllMocks(); }); it('should return a PortfolioApi object', () => { const api = (0, _apiMaker.portfolioApiMaker)({ network: mockNetwork, request: mockRequest, maxIdsPerRequest: 10, maxConcurrentRequests: 10 }); expect(Object.isFrozen(api)).toBe(true); expect(api).toBeDefined(); expect(api).toHaveProperty('tokenDiscovery'); expect(api).toHaveProperty('tokenInfos'); expect(api).toHaveProperty('tokenTraits'); expect(api).toHaveProperty('tokenActivity'); expect(api).toHaveProperty('tokenHistory'); expect(api).toHaveProperty('tokenImageInvalidate'); }); it('should return a PortfolioApi object with default fetchData (coverage)', () => { const api = (0, _apiMaker.portfolioApiMaker)({ network: mockNetwork, maxIdsPerRequest: 10, maxConcurrentRequests: 10 }); expect(api).toBeDefined(); expect(api).toHaveProperty('tokenDiscovery'); expect(api).toHaveProperty('tokenInfos'); expect(api).toHaveProperty('tokenTraits'); expect(api).toHaveProperty('tokenActivity'); expect(api).toHaveProperty('tokenHistory'); expect(api).toHaveProperty('tokenImageInvalidate'); }); it('should call the fetchData function with the correct arguments', async () => { mockRequest.mockResolvedValue({ tag: 'right', value: { status: _types.Api.HttpStatusCode.Ok, data: {} } }); const api = (0, _apiMaker.portfolioApiMaker)({ network: mockNetwork, request: mockRequest, maxIdsPerRequest: 10, maxConcurrentRequests: 10 }); const mockTokenIdsWithCache = [['token.id', 'etag-hash']]; const mockTokenIdsWithCacheRequest = ['token.id:etag-hash']; await api.tokenDiscovery(_tokenDiscovery.tokenDiscoveryMocks.nftCryptoKitty.id); await api.tokenInfos(mockTokenIdsWithCache); await api.tokenTraits(_token.tokenMocks.nftCryptoKitty.info.id); await api.tokenInfo(_token.tokenMocks.nftCryptoKitty.info.id); await api.tokenActivity(_tokenActivity.tokenActivityMocks.api.request, _types.Portfolio.Token.ActivityWindow.OneDay); await api.tokenHistory(_tokenHistory.tokenHistoryMocks.api.request.tokenId, _tokenHistory.tokenHistoryMocks.api.request.period); expect(mockRequest).toHaveBeenCalledTimes(6); expect(mockRequest).toHaveBeenCalledWith({ method: 'get', url: _apiMaker.apiConfig[_types.Chain.Network.Mainnet].tokenDiscovery + '/' + _tokenDiscovery.tokenDiscoveryMocks.nftCryptoKitty.id, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' } }); expect(mockRequest).toHaveBeenCalledWith({ method: 'post', url: _apiMaker.apiConfig[_types.Chain.Network.Mainnet].tokenInfos, data: mockTokenIdsWithCacheRequest, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' } }); expect(mockRequest).toHaveBeenCalledWith({ method: 'get', url: _apiMaker.apiConfig[_types.Chain.Network.Mainnet].tokenTraits + '/' + _token.tokenMocks.nftCryptoKitty.info.id, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' } }); expect(mockRequest).toHaveBeenCalledWith({ method: 'get', url: _apiMaker.apiConfig[_types.Chain.Network.Mainnet].tokenInfo + '/' + _token.tokenMocks.nftCryptoKitty.info.id, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' } }); expect(mockRequest).toHaveBeenCalledWith({ method: 'post', url: `${_apiMaker.apiConfig[_types.Chain.Network.Mainnet].tokenActivity}/${_types.Portfolio.Token.ActivityWindow.OneDay}`, data: _tokenActivity.tokenActivityMocks.api.request, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' } }); expect(mockRequest).toHaveBeenCalledWith({ method: 'post', url: _apiMaker.apiConfig[_types.Chain.Network.Mainnet].tokenHistory, data: _tokenHistory.tokenHistoryMocks.api.request, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' } }); }); it('should return error when returning data is malformed', async () => { mockRequest.mockResolvedValue({ tag: 'right', value: { status: _types.Api.HttpStatusCode.Ok, data: { ['wrong']: [200, 'data'] } } }); const api = (0, _apiMaker.portfolioApiMaker)({ network: mockNetwork, request: mockRequest, maxIdsPerRequest: 10, maxConcurrentRequests: 10 }); const resultDiscovery = await api.tokenDiscovery(_tokenDiscovery.tokenDiscoveryMocks.nftCryptoKitty.id); expect(mockRequest).toHaveBeenCalledTimes(1); expect(mockRequest).toHaveBeenCalledWith({ method: 'get', url: _apiMaker.apiConfig[_types.Chain.Network.Mainnet].tokenDiscovery + '/' + _tokenDiscovery.tokenDiscoveryMocks.nftCryptoKitty.id, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' } }); expect(resultDiscovery).toEqual({ tag: 'left', error: { status: -3, message: 'Failed to transform token discovery response', responseData: { ['wrong']: [200, 'data'] } } }); const resultInfo = await api.tokenInfo(_token.tokenMocks.nftCryptoKitty.info.id); expect(mockRequest).toHaveBeenCalledTimes(2); expect(mockRequest).toHaveBeenCalledWith({ method: 'get', url: _apiMaker.apiConfig[_types.Chain.Network.Mainnet].tokenInfo + '/' + _token.tokenMocks.nftCryptoKitty.info.id, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' } }); expect(resultInfo).toEqual({ tag: 'left', error: { status: -3, message: 'Failed to transform token info response', responseData: { ['wrong']: [200, 'data'] } } }); const resultTokenActivity = await api.tokenActivity(_tokenActivity.tokenActivityMocks.api.request, _types.Portfolio.Token.ActivityWindow.OneDay); expect(mockRequest).toHaveBeenCalledTimes(3); expect(mockRequest).toHaveBeenCalledWith({ method: 'post', url: `${_apiMaker.apiConfig[_types.Chain.Network.Mainnet].tokenActivity}/${_types.Portfolio.Token.ActivityWindow.OneDay}`, data: _tokenActivity.tokenActivityMocks.api.request, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' } }); expect(resultTokenActivity).toEqual({ tag: 'right', value: { status: 200, data: {} } }); const resultTokenHistory = await api.tokenHistory(_tokenHistory.tokenHistoryMocks.api.request.tokenId, _tokenHistory.tokenHistoryMocks.api.request.period); expect(mockRequest).toHaveBeenCalledTimes(4); expect(mockRequest).toHaveBeenCalledWith({ method: 'post', url: _apiMaker.apiConfig[_types.Chain.Network.Mainnet].tokenHistory, data: _tokenHistory.tokenHistoryMocks.api.request, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' } }); expect(resultTokenHistory).toEqual({ tag: 'left', error: { status: -3, message: 'Failed to transform token history response', responseData: { ['wrong']: [200, 'data'] } } }); }); it('should return the error and not throw', async () => { mockRequest.mockResolvedValue({ tag: 'left', value: { status: _types.Api.HttpStatusCode.InternalServerError, message: 'Internal Server Error', responseData: {} } }); const api = (0, _apiMaker.portfolioApiMaker)({ network: mockNetwork, request: mockRequest, maxIdsPerRequest: 10, maxConcurrentRequests: 10 }); const mockTokenIdsWithCache = [['token.id', 'etag-hash']]; const mockTokenIdsWithCacheRequest = ['token.id:etag-hash']; await expect(api.tokenInfos(mockTokenIdsWithCache)).resolves.toEqual({ tag: 'left', value: { status: _types.Api.HttpStatusCode.InternalServerError, message: 'Internal Server Error', responseData: {} } }); expect(mockRequest).toHaveBeenCalledTimes(1); expect(mockRequest).toHaveBeenCalledWith({ method: 'post', url: _apiMaker.apiConfig[_types.Chain.Network.Mainnet].tokenInfos, data: mockTokenIdsWithCacheRequest, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' } }); await expect(api.tokenDiscovery(_tokenDiscovery.tokenDiscoveryMocks.nftCryptoKitty.id)).resolves.toEqual({ tag: 'left', value: { status: _types.Api.HttpStatusCode.InternalServerError, message: 'Internal Server Error', responseData: {} } }); expect(mockRequest).toHaveBeenCalledTimes(2); expect(mockRequest).toHaveBeenCalledWith({ method: 'get', url: _apiMaker.apiConfig[_types.Chain.Network.Mainnet].tokenDiscovery + '/' + _tokenDiscovery.tokenDiscoveryMocks.nftCryptoKitty.id, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' } }); await expect(api.tokenTraits(_token.tokenMocks.nftCryptoKitty.info.id)).resolves.toEqual({ tag: 'left', value: { status: _types.Api.HttpStatusCode.InternalServerError, message: 'Internal Server Error', responseData: {} } }); expect(mockRequest).toHaveBeenCalledTimes(3); expect(mockRequest).toHaveBeenCalledWith({ method: 'get', url: _apiMaker.apiConfig[_types.Chain.Network.Mainnet].tokenTraits + '/' + _token.tokenMocks.nftCryptoKitty.info.id, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' } }); await expect(api.tokenInfo(_token.tokenMocks.nftCryptoKitty.info.id)).resolves.toEqual({ tag: 'left', value: { status: _types.Api.HttpStatusCode.InternalServerError, message: 'Internal Server Error', responseData: {} } }); expect(mockRequest).toHaveBeenCalledTimes(4); expect(mockRequest).toHaveBeenCalledWith({ method: 'get', url: _apiMaker.apiConfig[_types.Chain.Network.Mainnet].tokenInfo + '/' + _token.tokenMocks.nftCryptoKitty.info.id, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' } }); await expect(api.tokenActivity(_tokenActivity.tokenActivityMocks.api.request, _types.Portfolio.Token.ActivityWindow.OneDay)).resolves.toEqual({ tag: 'left', value: { status: _types.Api.HttpStatusCode.InternalServerError, message: 'Internal Server Error', responseData: {} } }); expect(mockRequest).toHaveBeenCalledTimes(5); expect(mockRequest).toHaveBeenCalledWith({ method: 'post', url: `${_apiMaker.apiConfig[_types.Chain.Network.Mainnet].tokenActivity}/${_types.Portfolio.Token.ActivityWindow.OneDay}`, data: _tokenActivity.tokenActivityMocks.api.request, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' } }); await expect(api.tokenHistory(_tokenHistory.tokenHistoryMocks.api.request.tokenId, _tokenHistory.tokenHistoryMocks.api.request.period)).resolves.toEqual({ tag: 'left', value: { status: _types.Api.HttpStatusCode.InternalServerError, message: 'Internal Server Error', responseData: {} } }); expect(mockRequest).toHaveBeenCalledTimes(6); expect(mockRequest).toHaveBeenCalledWith({ method: 'post', url: _apiMaker.apiConfig[_types.Chain.Network.Mainnet].tokenHistory, data: _tokenHistory.tokenHistoryMocks.api.request, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' } }); }); it('should return the data on success (traits)', async () => { mockRequest.mockResolvedValue({ tag: 'right', value: { status: _types.Api.HttpStatusCode.Ok, data: _token.tokenMocks.nftCryptoKitty.traits } }); const api = (0, _apiMaker.portfolioApiMaker)({ network: mockNetwork, request: mockRequest, maxIdsPerRequest: 10, maxConcurrentRequests: 10 }); const result = await api.tokenTraits(_token.tokenMocks.nftCryptoKitty.info.id); expect(mockRequest).toHaveBeenCalledTimes(1); expect(mockRequest).toHaveBeenCalledWith({ method: 'get', url: _apiMaker.apiConfig[_types.Chain.Network.Mainnet].tokenTraits + '/' + _token.tokenMocks.nftCryptoKitty.info.id, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' } }); expect(result).toEqual({ tag: 'right', value: { status: _types.Api.HttpStatusCode.Ok, data: _token.tokenMocks.nftCryptoKitty.traits } }); }); it('should return the data on success (tokenInfo)', async () => { mockRequest.mockResolvedValue({ tag: 'right', value: { status: _types.Api.HttpStatusCode.Ok, data: _token.tokenMocks.nftCryptoKitty.info } }); const api = (0, _apiMaker.portfolioApiMaker)({ network: mockNetwork, request: mockRequest, maxIdsPerRequest: 10, maxConcurrentRequests: 10 }); const result = await api.tokenInfo(_token.tokenMocks.nftCryptoKitty.info.id); expect(mockRequest).toHaveBeenCalledTimes(1); expect(mockRequest).toHaveBeenCalledWith({ method: 'get', url: _apiMaker.apiConfig[_types.Chain.Network.Mainnet].tokenInfo + '/' + _token.tokenMocks.nftCryptoKitty.info.id, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' } }); expect(result).toEqual({ tag: 'right', value: { status: _types.Api.HttpStatusCode.Ok, data: _token.tokenMocks.nftCryptoKitty.info } }); }); it('should return the data on success (tokenActivity)', async () => { mockRequest.mockResolvedValue(_tokenActivity.tokenActivityMocks.api.responses.success); const api = (0, _apiMaker.portfolioApiMaker)({ network: mockNetwork, request: mockRequest, maxIdsPerRequest: 10, maxConcurrentRequests: 10 }); const result = await api.tokenActivity(_tokenActivity.tokenActivityMocks.api.request, _types.Portfolio.Token.ActivityWindow.OneDay); expect(mockRequest).toHaveBeenCalledTimes(1); expect(mockRequest).toHaveBeenCalledWith({ method: 'post', url: `${_apiMaker.apiConfig[_types.Chain.Network.Mainnet].tokenActivity}/${_types.Portfolio.Token.ActivityWindow.OneDay}`, data: _tokenActivity.tokenActivityMocks.api.request, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' } }); expect(result).toEqual({ tag: 'right', value: { status: _types.Api.HttpStatusCode.Ok, data: _tokenActivity.tokenActivityMocks.api.responseDataOnly } }); }); it('should return the data on success (tokenHistory)', async () => { mockRequest.mockResolvedValue(_tokenHistory.tokenHistoryMocks.api.responses.success); const api = (0, _apiMaker.portfolioApiMaker)({ network: mockNetwork, request: mockRequest, maxIdsPerRequest: 10, maxConcurrentRequests: 10 }); const result = await api.tokenHistory(_tokenHistory.tokenHistoryMocks.api.request.tokenId, _tokenHistory.tokenHistoryMocks.api.request.period); expect(mockRequest).toHaveBeenCalledTimes(1); expect(mockRequest).toHaveBeenCalledWith({ method: 'post', url: _apiMaker.apiConfig[_types.Chain.Network.Mainnet].tokenHistory, data: _tokenHistory.tokenHistoryMocks.api.request, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' } }); expect(result).toEqual({ tag: 'right', value: { status: _types.Api.HttpStatusCode.Ok, data: _tokenHistory.tokenHistoryMocks.api.responseDataOnly } }); }); it('should return error when returning data is malformed token-discovery', async () => { mockRequest.mockResolvedValue({ tag: 'right', value: { status: _types.Api.HttpStatusCode.Ok, data: 0 } }); const api = (0, _apiMaker.portfolioApiMaker)({ network: mockNetwork, request: mockRequest, maxIdsPerRequest: 10, maxConcurrentRequests: 10 }); const wrong = await api.tokenDiscovery(_tokenDiscovery.tokenDiscoveryMocks.nftCryptoKitty.id); expect(mockRequest).toHaveBeenCalledTimes(1); expect(mockRequest).toHaveBeenCalledWith({ method: 'get', url: _apiMaker.apiConfig[_types.Chain.Network.Mainnet].tokenDiscovery + '/' + _tokenDiscovery.tokenDiscoveryMocks.nftCryptoKitty.id, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' } }); expect(wrong).toEqual({ tag: 'left', error: { status: -3, message: 'Failed to transform token discovery response', responseData: 0 } }); mockRequest.mockResolvedValue({ tag: 'right', value: { status: _types.Api.HttpStatusCode.Ok, data: { ..._tokenDiscovery.tokenDiscoveryMocks.nftCryptoKitty, supply: undefined } } }); const missing = await api.tokenDiscovery(_tokenDiscovery.tokenDiscoveryMocks.nftCryptoKitty.id); expect(missing).toEqual({ tag: 'left', error: { status: -3, message: 'Failed to transform token discovery response', responseData: { ..._tokenDiscovery.tokenDiscoveryMocks.nftCryptoKitty, supply: undefined } } }); expect(mockRequest).toHaveBeenCalledTimes(2); mockRequest.mockResolvedValue({ tag: 'right', value: { status: _types.Api.HttpStatusCode.Ok, data: _tokenDiscovery.tokenDiscoveryMocks.nftCryptoKitty } }); const right = await api.tokenDiscovery(_tokenDiscovery.tokenDiscoveryMocks.nftCryptoKitty.id); expect(right).toEqual({ tag: 'right', value: { status: _types.Api.HttpStatusCode.Ok, data: _tokenDiscovery.tokenDiscoveryMocks.nftCryptoKitty } }); }); it('should return nothing when invalidating image', async () => { mockRequest.mockResolvedValue({ tag: 'right', value: { status: _types.Api.HttpStatusCode.Ok, data: {} } }); const api = (0, _apiMaker.portfolioApiMaker)({ network: mockNetwork, request: mockRequest, maxIdsPerRequest: 10, maxConcurrentRequests: 10 }); await api.tokenImageInvalidate(_tokenImageInvalidate.tokenImageInvalidateMocks.api.request); expect(mockRequest).toHaveBeenCalledTimes(1); }); }); //# sourceMappingURL=api-maker.test.js.map