@yoroi/portfolio
Version:
The Portfolio package of Yoroi SDK
164 lines (163 loc) • 6.64 kB
JavaScript
import { storageSerializer } from '@yoroi/common';
import { portfolioBalanceStorageMaker } from './balance-storage-maker';
import { tokenMocks } from '../token.mocks';
import { deserializers } from '../../transformers/deserializers';
import { tokenBalanceMocks } from '../token-balance.mocks';
describe('portfolioBalanceStorageMaker', () => {
let balanceStorage;
let primaryBreakdownStorage;
beforeEach(() => {
balanceStorage = createMockStorage('v2/wallets/id/balance/', deserializers.tokenAmount);
primaryBreakdownStorage = createMockStorage('v2/wallets/id/primary-breakdown/', deserializers.primaryBreakdown);
balanceStorage.clear();
primaryBreakdownStorage.clear();
jest.clearAllMocks();
});
it('should instantiate storage', () => {
const storage = portfolioBalanceStorageMaker({
balanceStorage,
primaryBreakdownStorage,
primaryTokenId: tokenMocks.primaryETH.info.id
});
expect(storage).toBeDefined();
expect(Object.isFrozen(storage)).toBe(true);
});
it('should save balances entries', () => {
const {
balances
} = portfolioBalanceStorageMaker({
balanceStorage,
primaryBreakdownStorage,
primaryTokenId: tokenMocks.primaryETH.info.id
});
balances.save(tokenBalanceMocks.storage.entries1);
expect(balanceStorage.multiSet).toHaveBeenCalledWith(tokenBalanceMocks.storage.entries1, storageSerializer);
});
it('should read balances entries', () => {
const nftCryptoKitty = tokenMocks.nftCryptoKitty.info;
const rnftWhatever = tokenMocks.rnftWhatever.info;
const {
balances
} = portfolioBalanceStorageMaker({
balanceStorage,
primaryBreakdownStorage,
primaryTokenId: tokenMocks.primaryETH.info.id
});
balances.save(tokenBalanceMocks.storage.entries1);
const keys = [nftCryptoKitty.id, rnftWhatever.id];
const result = balances.read(keys);
expect(result).toEqual([[nftCryptoKitty.id, tokenBalanceMocks.nftCryptoKitty], [rnftWhatever.id, tokenBalanceMocks.rnftWhatever]]);
expect(balanceStorage.multiGet).toHaveBeenCalledWith(keys, deserializers.tokenAmount);
});
it('should clear all portfolio records', () => {
const {
clear,
balances,
primaryBreakdown
} = portfolioBalanceStorageMaker({
balanceStorage,
primaryBreakdownStorage,
primaryTokenId: tokenMocks.primaryETH.info.id
});
balances.save(tokenBalanceMocks.storage.entries1);
primaryBreakdown.save(tokenBalanceMocks.primaryETHBreakdown);
let balanceResult = balances.all();
let primaryBreakdownResult = primaryBreakdown.read();
expect(balanceResult).toEqual(tokenBalanceMocks.storage.entries1);
expect(primaryBreakdownResult).toEqual(tokenBalanceMocks.primaryETHBreakdown);
clear();
balanceResult = balances.all();
primaryBreakdownResult = primaryBreakdown.read();
// keys are gone
expect(balanceResult).toEqual([]);
expect(primaryBreakdownResult).toEqual(null);
expect(balanceStorage.clear).toHaveBeenCalled();
expect(primaryBreakdownStorage.clear).toHaveBeenCalled();
});
it('should return all keys', () => {
const {
balances,
primaryBreakdown
} = portfolioBalanceStorageMaker({
balanceStorage,
primaryBreakdownStorage,
primaryTokenId: tokenMocks.primaryETH.info.id
});
balances.save(tokenBalanceMocks.storage.entries1);
primaryBreakdown.save(tokenBalanceMocks.primaryETHBreakdown);
let balanceResult = balances.keys();
expect(balanceResult).toEqual([...new Map(tokenBalanceMocks.storage.entries1).keys()]);
});
it('should call clear', () => {
const {
balances,
primaryBreakdown
} = portfolioBalanceStorageMaker({
balanceStorage,
primaryBreakdownStorage,
primaryTokenId: tokenMocks.primaryETH.info.id
});
balances.clear();
primaryBreakdown.clear();
expect(balanceStorage.clear).toHaveBeenCalled();
expect(primaryBreakdownStorage.clear).toHaveBeenCalled();
});
});
function createMockStorage() {
let path = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '/';
let deserializer = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : JSON.parse;
let serializer = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : storageSerializer;
let storage = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : new Map();
let subscriptions = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : new Set();
const withPath = key => `${path}${key}`;
return {
join: jest.fn(folderName => createMockStorage(`${path}${folderName}`, deserializer, serializer, storage, subscriptions)),
getItem: jest.fn(function (key) {
let parser = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : deserializer;
const item = storage.get(withPath(key)) ?? null;
return parser(item);
}),
multiGet: jest.fn(function (keys) {
let parser = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : deserializer;
return keys.map(key => [key, parser(storage.get(withPath(key)) ?? null)]);
}),
setItem: jest.fn(function (key, value) {
let stringifier = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : serializer;
storage.set(withPath(key), stringifier(value));
}),
multiSet: jest.fn(function (tuples) {
let stringifier = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : serializer;
tuples.forEach(_ref => {
let [key, value] = _ref;
storage.set(withPath(key), stringifier(value));
});
}),
removeItem: jest.fn(key => {
storage.delete(withPath(key));
}),
removeFolder: jest.fn(folderName => {
const prefix = `${path}${folderName}`;
const keysToRemove = [...storage.keys()].filter(key => key.startsWith(prefix));
keysToRemove.forEach(key => storage.delete(key));
}),
multiRemove: jest.fn(keys => {
keys.forEach(key => storage.delete(withPath(key)));
}),
getAllKeys: jest.fn(() => {
const withoutPath = absolutePath => absolutePath.slice(path.length);
return [...storage.keys()].filter(key => key.startsWith(path)).map(key => withoutPath(key));
}),
clear: jest.fn(() => {
storage.clear();
}),
onChange: jest.fn((_keysToObserve, callback) => {
subscriptions.add(callback);
return {
unsubscribe: jest.fn(() => {
subscriptions.delete(callback);
})
};
})
};
}
//# sourceMappingURL=balance-storage-maker.test.js.map