UNPKG

@substrate/api-sidecar

Version:

REST service that makes it easy to interact with blockchain nodes built using Substrate's FRAME framework.

201 lines 8.14 kB
"use strict"; // Copyright 2017-2025 Parity Technologies (UK) Ltd. // This file is part of Substrate API Sidecar. // // Substrate API Sidecar is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const bn_js_1 = __importDefault(require("bn.js")); const registries_1 = require("../../test-helpers/registries"); const getRelayParentNumber_1 = require("./getRelayParentNumber"); const mockBlockHash = registries_1.polkadotRegistry.createType('BlockHash', '0x7b713de604a99857f6c25eacc115a4f28d2611a23d9ddff99ab0e4f1c17a8578'); const mockRelayParentNumber = 28500000; /** * Create a mock extrinsic that simulates setValidationData */ const createMockSetValidationDataExtrinsic = () => ({ method: { method: { toString: () => 'setValidationData', }, }, }); /** * Create a mock extrinsic that is NOT setValidationData */ const createMockOtherExtrinsic = (methodName) => ({ method: { method: { toString: () => methodName, }, }, }); /** * Create a mock registry.createType that returns the expected structure */ const createMockCreateType = (relayParentNumber) => { return (_typeName, _data) => ({ toJSON: () => ({ args: { data: { validationData: { relayParentNumber, }, }, }, }), }); }; describe('getRelayParentNumber', () => { describe('getRelayParentNumber', () => { it('should extract relay parent number from a parachain block', async () => { const mockApiAt = { registry: { createType: createMockCreateType(mockRelayParentNumber), }, }; const mockAt = jest.fn().mockResolvedValue(mockApiAt); const mockGetBlock = jest.fn().mockResolvedValue({ block: { extrinsics: [ createMockOtherExtrinsic('timestamp'), createMockSetValidationDataExtrinsic(), createMockOtherExtrinsic('transfer'), ], }, }); const mockApi = { at: mockAt, rpc: { chain: { getBlock: mockGetBlock, }, }, }; const result = await (0, getRelayParentNumber_1.getRelayParentNumber)(mockApi, mockBlockHash); expect(result).toBeInstanceOf(bn_js_1.default); expect(result.toNumber()).toBe(mockRelayParentNumber); expect(mockAt).toHaveBeenCalledWith(mockBlockHash); expect(mockGetBlock).toHaveBeenCalledWith(mockBlockHash); }); it('should throw error when setValidationData extrinsic is not found', async () => { const mockApi = { at: jest.fn().mockResolvedValue({}), rpc: { chain: { getBlock: jest.fn().mockResolvedValue({ block: { extrinsics: [createMockOtherExtrinsic('timestamp'), createMockOtherExtrinsic('transfer')], }, }), }, }, }; await expect((0, getRelayParentNumber_1.getRelayParentNumber)(mockApi, mockBlockHash)).rejects.toThrow('Block does not contain setValidationData extrinsic. Cannot determine relay parent number.'); }); it('should handle block with only setValidationData extrinsic', async () => { const mockApiAt = { registry: { createType: createMockCreateType(12345678), }, }; const mockApi = { at: jest.fn().mockResolvedValue(mockApiAt), rpc: { chain: { getBlock: jest.fn().mockResolvedValue({ block: { extrinsics: [createMockSetValidationDataExtrinsic()], }, }), }, }, }; const result = await (0, getRelayParentNumber_1.getRelayParentNumber)(mockApi, mockBlockHash); expect(result.toNumber()).toBe(12345678); }); it('should handle large relay parent numbers', async () => { const largeBlockNumber = 999999999; const mockApiAt = { registry: { createType: createMockCreateType(largeBlockNumber), }, }; const mockApi = { at: jest.fn().mockResolvedValue(mockApiAt), rpc: { chain: { getBlock: jest.fn().mockResolvedValue({ block: { extrinsics: [createMockSetValidationDataExtrinsic()], }, }), }, }, }; const result = await (0, getRelayParentNumber_1.getRelayParentNumber)(mockApi, mockBlockHash); expect(result.toNumber()).toBe(largeBlockNumber); }); }); describe('hasRelayParentData', () => { it('should return true when block contains setValidationData', async () => { const mockApi = { rpc: { chain: { getBlock: jest.fn().mockResolvedValue({ block: { extrinsics: [createMockOtherExtrinsic('timestamp'), createMockSetValidationDataExtrinsic()], }, }), }, }, }; const result = await (0, getRelayParentNumber_1.hasRelayParentData)(mockApi, mockBlockHash); expect(result).toBe(true); }); it('should return false when block does not contain setValidationData', async () => { const mockApi = { rpc: { chain: { getBlock: jest.fn().mockResolvedValue({ block: { extrinsics: [createMockOtherExtrinsic('timestamp'), createMockOtherExtrinsic('transfer')], }, }), }, }, }; const result = await (0, getRelayParentNumber_1.hasRelayParentData)(mockApi, mockBlockHash); expect(result).toBe(false); }); it('should return false for empty extrinsics array', async () => { const mockApi = { rpc: { chain: { getBlock: jest.fn().mockResolvedValue({ block: { extrinsics: [], }, }), }, }, }; const result = await (0, getRelayParentNumber_1.hasRelayParentData)(mockApi, mockBlockHash); expect(result).toBe(false); }); }); }); //# sourceMappingURL=getRelayParentNumber.spec.js.map