Commit 69531661 authored by Hanwen Cheng's avatar Hanwen Cheng Committed by Thibaut Sardan
Browse files

fix: display soft derivation custom path (#523)



* fix: display soft derivation custom path

* group the unknown path with first path

* add comments and fix according review

* grammar
Co-authored-by: default avatarThibaut Sardan <33178835+Tbaut@users.noreply.github.com>
parent 1368bca1
Pipeline #74841 passed with stages
in 18 minutes and 9 seconds
......@@ -30,120 +30,110 @@ import {
UnknownNetworkKeys
} from '../../src/constants';
const addressFunding1 = 'address1',
addressFunding2 = 'address2',
addressSoft = 'address3',
addressPolkadot = 'address5',
addressStaking = 'address4',
addressEthereum = 'address6',
addressDefault = 'addressDefault',
addressKusamaRoot = 'addressKusamaRoot',
addressRoot = 'addressRoot',
addressCustom = 'addressCustom',
paths = [
'//kusama//default',
'//kusama//funding/1',
'//kusama/softKey1',
'//kusama//funding/2',
'//kusama//staking/1',
'//polkadot//default',
'1',
'//kusama',
'',
'//custom'
],
kusamaPaths = [
'//kusama//default',
'//kusama//funding/1',
'//kusama/softKey1',
'//kusama//funding/2',
'//kusama//staking/1',
'//kusama'
],
metaCustom = {
address: addressCustom,
createdAt: 1571068850409,
name: 'custom Path',
updatedAt: 1571068850409
},
metaDefault = {
address: addressDefault,
createdAt: 1571068850409,
const raw = [
{
address: 'addressDefault',
expectName: 'default',
isKusamaPath: true,
name: '',
updatedAt: 1571078850509
path: '//kusama//default'
},
metaFunding1 = {
address: addressFunding1,
createdAt: 1571068850409,
{
address: 'address1',
expectName: 'funding account1',
isKusamaPath: true,
name: 'funding account1',
updatedAt: 1571078850509
path: '//kusama//funding/1'
},
metaFunding2 = {
address: addressFunding2,
createdAt: 1571068850409,
{
address: 'address3',
expectName: 'softKey1',
isKusamaPath: true,
name: '',
updatedAt: 1571078850509
path: '//kusama/softKey1'
},
metaStaking = {
address: addressStaking,
createdAt: 1571068850409,
{
address: 'address2',
expectName: 'funding2',
isKusamaPath: true,
name: '',
updatedAt: 1571078850509
path: '//kusama//funding/2'
},
metaPolkadot = {
address: addressPolkadot,
createdAt: 1573142786972,
name: 'PolkadotFirst',
updatedAt: 1573142786972
{
address: 'address4',
expectName: 'staking1',
isKusamaPath: true,
name: '',
path: '//kusama//staking/1'
},
metaEthereum = {
address: addressEthereum,
createdAt: 1573142786972,
name: 'Eth account',
updatedAt: 1573142786972
{
address: 'address5',
expectName: 'default',
name: '',
path: '//polkadot//default'
},
metaKusamaRoot = {
address: addressKusamaRoot,
createdAt: 1573142786972,
{
address: 'address6',
expectName: 'No name',
name: '',
updatedAt: 1573142786972
path: '1'
},
metaRoot = {
address: addressRoot,
createdAt: 1573142786972,
{
address: 'addressKusamaRoot',
expectName: 'kusama',
isKusamaPath: true,
name: '',
updatedAt: 1573142786972
path: '//kusama'
},
metaSoftKey = {
address: addressSoft,
createdAt: 1573142786972,
{
address: 'addressRoot',
expectName: '',
name: '',
path: ''
},
{
address: 'addressCustom',
expectName: 'CustomName',
name: 'CustomName',
path: '//custom'
},
{
address: 'addressKusamaSoft',
expectName: 'kusama',
name: '',
path: '/kusama'
},
{
address: 'softAddress',
expectName: '1',
name: '',
path: '/kusama/1'
},
{
address: 'softAddress2',
expectName: '1',
name: '',
path: '/polkadot/1'
}
];
const expectNames = raw.map(v => v.expectName);
const paths = raw.map(v => v.path);
const kusamaPaths = raw.filter(v => v.isKusamaPath).map(v => v.path);
const metaMap = raw.reduce((acc, v) => {
const meta = {
address: v.address,
createdAt: 1573142786972,
name: v.name,
updatedAt: 1573142786972
};
const addressesMap = new Map([
[addressDefault, paths[0]],
[addressFunding1, paths[1]],
[addressSoft, paths[2]],
[addressFunding2, paths[3]],
[addressStaking, paths[4]],
[addressPolkadot, paths[5]],
[addressEthereum, paths[6]],
[addressKusamaRoot, paths[7]],
[addressRoot, paths[8]],
[addressCustom, paths[9]]
]);
const metaMap = new Map([
[paths[0], metaDefault],
[paths[1], metaFunding1],
[paths[2], metaSoftKey],
[paths[3], metaStaking],
[paths[4], metaFunding2],
[paths[5], metaPolkadot],
[paths[6], metaEthereum],
[paths[7], metaKusamaRoot],
[paths[8], metaRoot],
[paths[9], metaCustom]
]);
acc.set(v.path, meta);
return acc;
}, new Map());
const addressesMap = raw.reduce((acc, v) => {
acc.set(v.address, v.path);
return acc;
}, new Map());
const testIdentities = [
{
addresses: addressesMap,
......@@ -191,33 +181,36 @@ describe('IdentitiesUtils', () => {
});
it('regroup the unknown paths', () => {
const unKnownPaths = ['//polkadot//default', '', '//custom'];
const unKnownPaths = [
'//polkadot//default',
'',
'//custom',
'/kusama',
'/kusama/1',
'/polkadot/1'
];
const groupResult = groupPaths(unKnownPaths);
expect(groupResult).toEqual([
{
paths: ['//polkadot//default'],
title: '//default'
title: '//polkadot'
},
{
paths: ['//custom'],
title: 'custom'
title: '//custom'
},
{
paths: ['/polkadot/1'],
title: '/polkadot'
},
{
paths: ['/kusama', '/kusama/1'],
title: '/kusama'
}
]);
});
it('get the path name', () => {
const expectNames = [
'default',
'funding account1',
'softKey1',
'funding2',
'staking1',
'PolkadotFirst',
'Eth account',
'',
'',
'custom Path'
];
paths.forEach((path, index) => {
const name = getPathName(path, testIdentities[0]);
expect(name).toEqual(expectNames[index]);
......
......@@ -95,7 +95,7 @@ function PathsList({ accounts, navigation }) {
rootPath,
seedPhrase,
networkKey,
`${networkParams.title} Root`
''
);
if (derivationSucceed) {
navigateToPathDetails(navigation, networkKey, rootPath);
......
......@@ -37,12 +37,13 @@ const extractPathId = path => {
export const extractSubPathName = path => {
const pathFragments = path.match(pathsRegex.allPath);
if (!pathFragments || pathFragments.length <= 1) return '';
if (!pathFragments || pathFragments.length === 0) return '';
if (pathFragments.length === 1) return removeSlash(pathFragments[0]);
return removeSlash(pathFragments.slice(1).join(''));
};
export const isSubstratePath = path =>
path.split('//')[1] !== undefined || path === '';
path.match(pathsRegex.allPath) !== null || path === '';
export const isEthereumAccountId = v => v.indexOf('ethereum:') === 0;
......@@ -204,35 +205,46 @@ export const getPathName = (path, lookUpIdentity) => {
return extractSubPathName(path);
};
/**
* This function decides how to group the list of derivation paths in the display based on the following rules.
* If the network is unknown: group by the first subpath, e.g. '/random' of '/random//derivation/1'
* If the network is known: group by the second subpath, e.g. '//staking' of '//kusama//staking/0'
* Please refer to identitiesUtils.spec.js for more examples.
**/
export const groupPaths = paths => {
const unSortedPaths = paths.reduce((groupedPath, path) => {
const insertPathIntoGroup = (matchingPath, fullPath, pathGroup) => {
const groupName = matchingPath.match(pathsRegex.firstPath)[0];
const existedItem = pathGroup.find(p => p.title === groupName);
if (existedItem) {
existedItem.paths.push(fullPath);
existedItem.paths.sort();
} else {
pathGroup.push({ paths: [fullPath], title: groupName });
}
};
const groupedPaths = paths.reduce((groupedPath, path) => {
if (path === '') {
return groupedPath;
}
const pathId = extractPathId(path) || '';
const isRootPath = removeSlash(path) === pathId;
if (isRootPath) {
const isUnknownRootPath = Object.values(NETWORK_LIST).every(
v => v.pathId !== pathId
);
if (isUnknownRootPath) {
groupedPath.push({ paths: [path], title: pathId });
}
const rootPath = path.match(pathsRegex.firstPath)[0];
const isUnknownRootPath = Object.values(NETWORK_LIST).every(
v => `//${v.pathId}` !== rootPath
);
if (isUnknownRootPath) {
insertPathIntoGroup(path, path, groupedPath);
return groupedPath;
}
const subPath = path.slice(pathId.length + 2);
const isRootPath = path === rootPath;
if (isRootPath) return groupedPath;
const groupName = subPath.match(pathsRegex.firstPath)[0];
const subPath = path.slice(rootPath.length);
insertPathIntoGroup(subPath, path, groupedPath);
const existedItem = groupedPath.find(p => p.title === groupName);
if (existedItem) {
existedItem.paths.push(path);
existedItem.paths.sort();
} else {
groupedPath.push({ paths: [path], title: groupName });
}
return groupedPath;
}, []);
return unSortedPaths.sort((a, b) => a.paths.length - b.paths.length);
return groupedPaths.sort((a, b) => a.paths.length - b.paths.length);
};
......@@ -19,7 +19,7 @@
export const pathsRegex = {
allPath: /(\/|\/\/)[\w-.]+(?=(\/?))/g,
firstPath: /(\/|\/\/)[\w-.]+(?=(\/)?)/,
networkPath: /(\/|\/\/)[\w-.]+(?=(\/)?)/,
networkPath: /(\/\/)[\w-.]+(?=(\/)?)/,
validateDerivedPath: /^(\/\/?[\w-.]+)*$/
};
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment