Files
api/packages/rpc-core/src/formatting.spec.ts
T
Jaco Greeff c7c76f6edb Rework uniqTypes without duplication (#1316)
* Rework uniqTypes without  duplication

* Extra info for vX -> v7 conversion

* Add vX to naming

* Rework unwrap return

* Ignore gathering unique for v0

* Fix getUniq for V0 (well, def. throw-away, but anyway...)

* compareMap cleanup

* Cleanup author extraction

* Add modules via Struct.with (Metadata)

* Revert "Add modules via Struct.with (Metadata)"

This reverts commit 0666c3014cf840fb4ab26a5231cdf67dbe977bd7.

* Consistency in injected vs defined classes (Metadata)

* Add isTrue/isFalse to Bool

* Meta PlainType/MapType in registry

* Fix wrong v6 imports

* Extract storage modifier

* Split additional Metadata classes into interfaces

* Minor cleanups in type naming

* Static json renames

* Convert most V0 classes to interfaces

* Additional meta classes to interfaces

* No classes for Metadata V0 & V1 anymore

* Rename json imports

* Base cleanups

* Add polkadot static
2019-08-18 15:01:21 +02:00

215 lines
7.1 KiB
TypeScript

// Copyright 2017-2019 @polkadot/rpc-core authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import '@polkadot/types/injector';
import { Balance } from '@polkadot/types/interfaces';
import { Codec } from '@polkadot/types/types';
import fromMetadata from '@polkadot/api-metadata/storage/fromMetadata';
import { Storage } from '@polkadot/api-metadata/storage/types';
import Metadata from '@polkadot/types/Metadata';
import rpcMetadataV3 from '@polkadot/types/Metadata/v3/static';
import rpcMetadataV4 from '@polkadot/types/Metadata/v4/static';
import rpcMetadataV5 from '@polkadot/types/Metadata/v5/static';
import rpcMetadataV6 from '@polkadot/types/Metadata/v6/static';
import rpcMetadataV7 from '@polkadot/types/Metadata/v7/static';
import Api from '.';
const ADDR_ONE = '5DkQbYAExs3M2sZgT1Ec3mKfZnAQCL4Dt9beTCknkCUn5jzo';
const ADDR_TWO = '5C62W7ELLAAfix9LYrcx5smtcffbhvThkM5x7xfMeYXCtGwF';
const BALANCE_KEYS = [
/* v3-, using xxHash */ '0x4af2c53fce3ec33c6ccccf22e926f1a7',
/* v4+, using blake2_256 */ '0xec8f96437274a883afcac82d01a9defeb68209cd4f2c084632813692aa5e65ad'
];
const OPTION_BYTES_HEX = '0x210100000000000000000000000000000000000000000000000000000000000000000000000000000000011b4d03dd8c01f1049143cf9c4c817e4b167f1d1b83e5c6f0f10d89ba1e7bce';
function formattingTests (version: string, storage: Storage, encodedValues: [string, string, string]): void {
const [ENC_ONE, ENC_TWO, CONTRACT_KEY] = encodedValues;
describe(`formatting with Metadata ${version}`, (): void => {
let api: Api;
let provider: any;
beforeEach((): void => {
provider = {
send: jest.fn((method, [key]): Promise<any> =>
Promise.resolve(
BALANCE_KEYS.includes(key)
? '0x01020000000000000000000000000000'
: null
)
),
subscribe: jest.fn((type, method, params, cb): Promise<void> => {
if (params[0][0] === CONTRACT_KEY) {
// this emulates https://github.com/polkadot-js/api/issues/1051
cb(null, {
block: '0x2345',
changes: [
[CONTRACT_KEY, OPTION_BYTES_HEX]
]
});
} else if (params[0][0] === ENC_ONE || params[0][0] === ENC_TWO) {
// known values for the balanaces
cb(null, {
block: '0x1234',
changes: [
[ENC_ONE, '0x01020000000000000000000000000000'],
[ENC_TWO, '0x02010000000000000000000000000000']
]
});
} else {
// return empty values for all else
cb(null, {
block: '0x3456',
changes: [
[params[0][0], null]
]
});
}
return Promise.resolve();
})
};
api = new Api(provider);
});
it('encodes key (with params), decoding response', (done): void => {
api.state
.getStorage<Balance>([storage.balances.freeBalance, ADDR_ONE])
.subscribe((value): void => {
expect(
provider.send
).toHaveBeenCalledWith(
'state_getStorage',
[ENC_ONE]
);
expect(value.toNumber()).toEqual(513);
done();
});
});
it('returns the fallback result on not-found values', (done): void => {
api.state
.getStorage([storage.system.accountNonce, ADDR_ONE])
.subscribe((value): void => {
expect(value.toHex()).toEqual('0x00000000');
done();
});
});
it('encodes multiple keys, decoding multiple results', (done): void => {
api.state.subscribeStorage<[Balance, Balance]>(
[
[storage.balances.freeBalance, ADDR_ONE],
[storage.balances.freeBalance, ADDR_TWO]
]
).subscribe((value): void => {
// console.error(value);
expect(
provider.subscribe
).toHaveBeenCalledWith(
'state_storage',
'state_subscribeStorage',
[[ENC_ONE, ENC_TWO]],
expect.anything()
);
expect(
value.map((balance): number =>
balance.toNumber()
)
).toEqual([0x0201, 0x0102]);
done();
});
});
it('handles the case where Option<Bytes> are retrieved', (done): void => {
const call = Number(version.slice(1)) <= 5
? storage.contract.pristineCode
: storage.contracts.pristineCode;
api.state
.subscribeStorage([[call, '0x00']])
// eslint-disable-next-line @typescript-eslint/no-unused-vars
.subscribe((value: Codec[]): void => {
expect(value).toHaveLength(1);
// console.error(value);
// expect(value.toHex()).toBe(OPTION_BYTES_HEX);
done();
});
});
it('handles fallbacks for linked heads (new metadata only)', (done): void => {
const headKey = storage.staking.validators && storage.staking.validators.headKey;
// skip for old
if (!headKey) {
return done();
}
api.state
.subscribeStorage([headKey])
.subscribe((value: Codec[]): void => {
expect(value).toHaveLength(1);
// console.error('head fallback', value);
done();
});
});
it('handles fallbacks for linked maps (new metadata only)', (done): void => {
const headKey = storage.staking.validators && storage.staking.validators.headKey;
// skip for old
if (!headKey) {
return done();
}
api.state
.subscribeStorage([[storage.staking.validators, '0x00']])
.subscribe(([value]: Codec[]): void => {
expect(value).toBeDefined();
// console.error('linked falklback', value);
done();
});
});
});
}
formattingTests('v3', fromMetadata(new Metadata(rpcMetadataV3)), [
'0x4af2c53fce3ec33c6ccccf22e926f1a7',
'0x3e62f7ed6e788e1337bce2a97b68a12a',
'0x777519cd81f845abdb40d253923d6098'
]);
formattingTests('v4', fromMetadata(new Metadata(rpcMetadataV4)), [
'0xec8f96437274a883afcac82d01a9defeb68209cd4f2c084632813692aa5e65ad',
'0x1dbb0224910f42a14e7f1406b24c6fe8157296691b02a78756e01946038fffab',
'0xc7879f4faa637a90d782070a3cb6be99a9fb0316e19a0454ce93c4f0a34712f1'
]);
formattingTests('v5', fromMetadata(new Metadata(rpcMetadataV5)), [
'0xec8f96437274a883afcac82d01a9defeb68209cd4f2c084632813692aa5e65ad',
'0x1dbb0224910f42a14e7f1406b24c6fe8157296691b02a78756e01946038fffab',
'0xc7879f4faa637a90d782070a3cb6be99a9fb0316e19a0454ce93c4f0a34712f1'
]);
formattingTests('v6', fromMetadata(new Metadata(rpcMetadataV6)), [
'0xec8f96437274a883afcac82d01a9defeb68209cd4f2c084632813692aa5e65ad',
'0x1dbb0224910f42a14e7f1406b24c6fe8157296691b02a78756e01946038fffab',
'0xc7879f4faa637a90d782070a3cb6be99a9fb0316e19a0454ce93c4f0a34712f1'
]);
formattingTests('v7', fromMetadata(new Metadata(rpcMetadataV7)), [
'0xec8f96437274a883afcac82d01a9defeb68209cd4f2c084632813692aa5e65ad',
'0x1dbb0224910f42a14e7f1406b24c6fe8157296691b02a78756e01946038fffab',
'0xc7879f4faa637a90d782070a3cb6be99a9fb0316e19a0454ce93c4f0a34712f1'
]);