diff --git a/.taprc b/.taprc index b2bfffb6b9..ce001c4753 100644 --- a/.taprc +++ b/.taprc @@ -128,7 +128,6 @@ files: - ./packages/cactus-test-plugin-htlc-eth-besu/src/test/typescript/integration/plugin-htlc-eth-besu/get-single-status-endpoint.test.ts - ./packages/cactus-test-plugin-htlc-eth-besu/src/test/typescript/integration/plugin-htlc-eth-besu/withdraw-endpoint-invalid.test.ts - ./packages/cactus-test-plugin-htlc-eth-besu/src/test/typescript/integration/plugin-htlc-eth-besu/openapi/openapi-validation.test.ts - - ./packages/cactus-test-plugin-htlc-eth-besu/src/test/typescript/integration/plugin-htlc-eth-besu/refund-endpoint.test.ts - ./packages/cactus-cmd-api-server/src/test/typescript/benchmark/artillery-api-benchmark.test.ts - ./packages/cactus-cmd-api-server/src/test/typescript/integration/jwt-socketio-endpoint-authorization.test.ts - ./packages/cactus-cmd-api-server/src/test/typescript/integration/jwt-endpoint-authz-scope-enforcement.test.ts diff --git a/jest.config.js b/jest.config.js index bcc279af6e..522805c141 100644 --- a/jest.config.js +++ b/jest.config.js @@ -134,7 +134,6 @@ module.exports = { `./packages/cactus-test-plugin-htlc-eth-besu/src/test/typescript/integration/plugin-htlc-eth-besu/get--status-endpoint-invalid.test.ts`, `./packages/cactus-test-plugin-htlc-eth-besu/src/test/typescript/integration/plugin-htlc-eth-besu/withdraw-endpoint-invalid.test.ts`, `./packages/cactus-test-plugin-htlc-eth-besu/src/test/typescript/integration/plugin-htlc-eth-besu/openapi/openapi-validation.test.ts`, - `./packages/cactus-test-plugin-htlc-eth-besu/src/test/typescript/integration/plugin-htlc-eth-besu/refund-endpoint.test.ts`, `./packages/cactus-cmd-api-server/src/test/typescript/benchmark/artillery-api-benchmark.test.ts`, `./packages/cactus-cmd-api-server/src/test/typescript/integration/jwt-socketio-endpoint-authorization.test.ts`, `./packages/cactus-cmd-api-server/src/test/typescript/integration/jwt-endpoint-authz-scope-enforcement.test.ts`, diff --git a/packages/cactus-test-plugin-htlc-eth-besu/src/test/typescript/integration/plugin-htlc-eth-besu/refund-endpoint.test.ts b/packages/cactus-test-plugin-htlc-eth-besu/src/test/typescript/integration/plugin-htlc-eth-besu/refund-endpoint.test.ts index 0b46aca277..0ac7f38dc1 100644 --- a/packages/cactus-test-plugin-htlc-eth-besu/src/test/typescript/integration/plugin-htlc-eth-besu/refund-endpoint.test.ts +++ b/packages/cactus-test-plugin-htlc-eth-besu/src/test/typescript/integration/plugin-htlc-eth-besu/refund-endpoint.test.ts @@ -1,8 +1,8 @@ import http from "http"; import type { AddressInfo } from "net"; -import test, { Test } from "tape-promise/tape"; import { v4 as uuidv4 } from "uuid"; import express from "express"; +import "jest-extended"; import bodyParser from "body-parser"; import Web3 from "web3"; import { @@ -41,81 +41,8 @@ const connectorId = uuidv4(); const logLevel: LogLevelDesc = "INFO"; const testCase = "Test refund"; -test("BEFORE " + testCase, async (t: Test) => { - const pruning = pruneDockerAllIfGithubAction({ logLevel }); - await t.doesNotReject(pruning, "Pruning did not throw OK"); - t.end(); -}); - -test(testCase, async (t: Test) => { - const timeout = (ms: number) => { - return new Promise((resolve) => setTimeout(resolve, ms)); - }; - t.comment("Starting Besu Test Ledger"); +describe(testCase, () => { const besuTestLedger = new BesuTestLedger({ logLevel }); - - test.onFinish(async () => { - await besuTestLedger.stop(); - await besuTestLedger.destroy(); - await pruneDockerAllIfGithubAction({ logLevel }); - }); - - await besuTestLedger.start(); - - const rpcApiHttpHost = await besuTestLedger.getRpcApiHttpHost(); - const rpcApiWsHost = await besuTestLedger.getRpcApiWsHost(); - const firstHighNetWorthAccount = besuTestLedger.getGenesisAccountPubKey(); - const privateKey = besuTestLedger.getGenesisAccountPrivKey(); - const web3SigningCredential: Web3SigningCredential = { - ethAccount: firstHighNetWorthAccount, - secret: privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - } as Web3SigningCredential; - - const keychainId = uuidv4(); - const keychainPlugin = new PluginKeychainMemory({ - instanceId: uuidv4(), - keychainId, - // pre-provision keychain with mock backend holding the private key of the - // test account that we'll reference while sending requests with the - // signing credential pointing to this keychain entry. - backend: new Map([ - [DemoHelperJSON.contractName, JSON.stringify(DemoHelperJSON)], - ]), - logLevel, - }); - keychainPlugin.set( - HashTimeLockJSON.contractName, - JSON.stringify(HashTimeLockJSON), - ); - - const factory = new PluginFactoryLedgerConnector({ - pluginImportType: PluginImportType.Local, - }); - - const pluginRegistry = new PluginRegistry({}); - const connector: PluginLedgerConnectorBesu = await factory.create({ - rpcApiHttpHost, - rpcApiWsHost, - logLevel, - instanceId: connectorId, - pluginRegistry: new PluginRegistry({ plugins: [keychainPlugin] }), - }); - - pluginRegistry.add(connector); - const pluginOptions: IPluginHtlcEthBesuOptions = { - logLevel, - instanceId: uuidv4(), - pluginRegistry, - }; - - const factoryHTLC = new PluginFactoryHtlcEthBesu({ - pluginImportType: PluginImportType.Local, - }); - - const pluginHtlc = await factoryHTLC.create(pluginOptions); - pluginRegistry.add(pluginHtlc); - const expressApp = express(); expressApp.use(bodyParser.json({ limit: "250mb" })); const server = http.createServer(expressApp); @@ -124,140 +51,197 @@ test(testCase, async (t: Test) => { port: 0, server, }; - const addressInfo = (await Servers.listen(listenOptions)) as AddressInfo; - test.onFinish(async () => await Servers.shutdown(server)); - const { address, port } = addressInfo; - const apiHost = `http://${address}:${port}`; - const configuration = new Configuration({ basePath: apiHost }); - const api = new BesuApi(configuration); - - await pluginHtlc.getOrCreateWebServices(); - await pluginHtlc.registerWebServices(expressApp); - - const web3 = new Web3(rpcApiHttpHost); - - t.comment("Deploys HashTimeLock via .json file on initialize function"); - const initRequest: InitializeRequest = { - connectorId, - keychainId, - constructorArgs: [], - web3SigningCredential, - gas: DataTest.estimated_gas, - }; - const deployOut = await pluginHtlc.initialize(initRequest); - t.ok( - deployOut.transactionReceipt, - "pluginHtlc.initialize() output.transactionReceipt is truthy OK", - ); - t.ok( - deployOut.transactionReceipt.contractAddress, - "pluginHtlc.initialize() output.transactionReceipt.contractAddress is truthy OK", - ); - const hashTimeLockAddress = deployOut.transactionReceipt - .contractAddress as string; - - //Deploy DemoHelpers - t.comment("Deploys DemoHelpers via .json file on deployContract function"); - const deployOutDemo = await connector.deployContract({ - contractName: DemoHelperJSON.contractName, - contractAbi: DemoHelperJSON.abi, - bytecode: DemoHelperJSON.bytecode, - web3SigningCredential, - keychainId, - constructorArgs: [], - gas: DataTest.estimated_gas, + beforeAll(async () => { + const pruning = pruneDockerAllIfGithubAction({ logLevel }); + await expect(pruning).resolves.toBeTruthy(); }); - t.ok(deployOutDemo, "deployContract() output is truthy OK"); - t.ok( - deployOutDemo.transactionReceipt, - "deployContract() output.transactionReceipt is truthy OK", - ); - t.ok( - deployOutDemo.transactionReceipt.contractAddress, - "deployContract() output.transactionReceipt.contractAddress is truthy OK", - ); - t.comment("Get account balance"); - const balance1 = await web3.eth.getBalance(firstHighNetWorthAccount); + afterAll(async () => { + const pruning = pruneDockerAllIfGithubAction({ logLevel }); + await expect(pruning).resolves.toBeTruthy(); + }); - t.comment("Get current timestamp"); - const { callOutput } = await connector.invokeContract({ - contractName: DemoHelperJSON.contractName, - keychainId, - signingCredential: web3SigningCredential, - invocationType: EthContractInvocationType.Call, - methodName: "getTimestamp", - params: [], + afterAll(async () => { + await besuTestLedger.stop(); + await besuTestLedger.destroy(); + await pruneDockerAllIfGithubAction({ logLevel }); }); - t.ok(callOutput, "callOutput() output.callOutput is truthy OK"); - let timestamp = 0; - timestamp = callOutput as number; - timestamp = +timestamp + +10; - t.comment("Create new contract for HTLC"); - const bodyObj: NewContractObj = { - contractAddress: hashTimeLockAddress, - inputAmount: 10, - outputAmount: 0x04, - expiration: timestamp, - hashLock: DataTest.hashLock, - receiver: DataTest.receiver, - outputNetwork: "BTC", - outputAddress: "1AcVYm7M3kkJQH28FXAvyBFQzFRL6xPKu8", - connectorId: connectorId, - web3SigningCredential, - keychainId, - gas: DataTest.estimated_gas, - }; - const resp = await api.newContractV1(bodyObj); - t.ok(resp, "response newContract is OK"); - t.equal(resp.status, 200, "response status newContract is OK"); + afterAll(async () => await Servers.shutdown(server)); - const responseTxId = await connector.invokeContract({ - contractName: DemoHelperJSON.contractName, - keychainId, - signingCredential: web3SigningCredential, - invocationType: EthContractInvocationType.Call, - methodName: "getTxId", - params: [ - firstHighNetWorthAccount, - DataTest.receiver, - 10, - DataTest.hashLock, - timestamp, - ], + beforeAll(async () => { + await besuTestLedger.start(); }); - t.ok(responseTxId.callOutput, "result is truthy OK"); - const id = responseTxId.callOutput as string; - t.comment("Refund HTLC"); - - await timeout(6000); - const refundRequest: RefundReq = { - id, - web3SigningCredential, - connectorId, - keychainId, - }; - const refundResponse = await api.refundV1(refundRequest); - t.equal(refundResponse.status, 200); - t.comment("Get single status of HTLC"); - const balance = await web3.eth.getBalance(firstHighNetWorthAccount); - t.equal( - parseInt(balance), - parseInt(balance1) - 10, - "Balance of account is OK", - ); - const balance2 = await web3.eth.getBalance(firstHighNetWorthAccount); - t.equal(balance1, balance2, "Retrieved balance of test account OK"); - const res = await api.getSingleStatusV1({ - id, - web3SigningCredential, - connectorId, - keychainId, + test(testCase, async () => { + const timeout = (ms: number) => { + return new Promise((resolve) => setTimeout(resolve, ms)); + }; + const rpcApiHttpHost = await besuTestLedger.getRpcApiHttpHost(); + const rpcApiWsHost = await besuTestLedger.getRpcApiWsHost(); + const firstHighNetWorthAccount = besuTestLedger.getGenesisAccountPubKey(); + const privateKey = besuTestLedger.getGenesisAccountPrivKey(); + const web3SigningCredential: Web3SigningCredential = { + ethAccount: firstHighNetWorthAccount, + secret: privateKey, + type: Web3SigningCredentialType.PrivateKeyHex, + } as Web3SigningCredential; + + const keychainId = uuidv4(); + const keychainPlugin = new PluginKeychainMemory({ + instanceId: uuidv4(), + keychainId, + // pre-provision keychain with mock backend holding the private key of the + // test account that we'll reference while sending requests with the + // signing credential pointing to this keychain entry. + backend: new Map([ + [DemoHelperJSON.contractName, JSON.stringify(DemoHelperJSON)], + ]), + logLevel, + }); + keychainPlugin.set( + HashTimeLockJSON.contractName, + JSON.stringify(HashTimeLockJSON), + ); + + const factory = new PluginFactoryLedgerConnector({ + pluginImportType: PluginImportType.Local, + }); + + const pluginRegistry = new PluginRegistry({}); + const connector: PluginLedgerConnectorBesu = await factory.create({ + rpcApiHttpHost, + rpcApiWsHost, + logLevel, + instanceId: connectorId, + pluginRegistry: new PluginRegistry({ plugins: [keychainPlugin] }), + }); + + pluginRegistry.add(connector); + const pluginOptions: IPluginHtlcEthBesuOptions = { + logLevel, + instanceId: uuidv4(), + pluginRegistry, + }; + + const factoryHTLC = new PluginFactoryHtlcEthBesu({ + pluginImportType: PluginImportType.Local, + }); + + const pluginHtlc = await factoryHTLC.create(pluginOptions); + pluginRegistry.add(pluginHtlc); + + const addressInfo = (await Servers.listen(listenOptions)) as AddressInfo; + const { address, port } = addressInfo; + const apiHost = `http://${address}:${port}`; + + const configuration = new Configuration({ basePath: apiHost }); + const api = new BesuApi(configuration); + + await pluginHtlc.getOrCreateWebServices(); + await pluginHtlc.registerWebServices(expressApp); + + const web3 = new Web3(rpcApiHttpHost); + + const initRequest: InitializeRequest = { + connectorId, + keychainId, + constructorArgs: [], + web3SigningCredential, + gas: DataTest.estimated_gas, + }; + const deployOut = await pluginHtlc.initialize(initRequest); + expect(deployOut.transactionReceipt).toBeTruthy(); + expect(deployOut.transactionReceipt.contractAddress).toBeTruthy(); + const hashTimeLockAddress = deployOut.transactionReceipt + .contractAddress as string; + + //Deploy DemoHelpers + const deployOutDemo = await connector.deployContract({ + contractName: DemoHelperJSON.contractName, + contractAbi: DemoHelperJSON.abi, + bytecode: DemoHelperJSON.bytecode, + web3SigningCredential, + keychainId, + constructorArgs: [], + gas: DataTest.estimated_gas, + }); + expect(deployOutDemo).toBeTruthy(); + expect(deployOutDemo.transactionReceipt).toBeTruthy(); + expect(deployOutDemo.transactionReceipt.contractAddress).toBeTruthy(); + + const balance1 = await web3.eth.getBalance(firstHighNetWorthAccount); + + const { callOutput } = await connector.invokeContract({ + contractName: DemoHelperJSON.contractName, + keychainId, + signingCredential: web3SigningCredential, + invocationType: EthContractInvocationType.Call, + methodName: "getTimestamp", + params: [], + }); + expect(callOutput).toBeTruthy(); + let timestamp = 0; + timestamp = callOutput as number; + timestamp = +timestamp + +10; + + const bodyObj: NewContractObj = { + contractAddress: hashTimeLockAddress, + inputAmount: 10, + outputAmount: 0x04, + expiration: timestamp, + hashLock: DataTest.hashLock, + receiver: DataTest.receiver, + outputNetwork: "BTC", + outputAddress: "1AcVYm7M3kkJQH28FXAvyBFQzFRL6xPKu8", + connectorId: connectorId, + web3SigningCredential, + keychainId, + gas: DataTest.estimated_gas, + }; + const resp = await api.newContractV1(bodyObj); + expect(resp).toBeTruthy(); + expect(resp.status).toEqual(200); + + const responseTxId = await connector.invokeContract({ + contractName: DemoHelperJSON.contractName, + keychainId, + signingCredential: web3SigningCredential, + invocationType: EthContractInvocationType.Call, + methodName: "getTxId", + params: [ + firstHighNetWorthAccount, + DataTest.receiver, + 10, + DataTest.hashLock, + timestamp, + ], + }); + expect(responseTxId.callOutput).toBeTruthy(); + const id = responseTxId.callOutput as string; + + await timeout(6000); + const refundRequest: RefundReq = { + id, + web3SigningCredential, + connectorId, + keychainId, + }; + const refundResponse = await api.refundV1(refundRequest); + expect(refundResponse.status).toEqual(200); + + const balance = await web3.eth.getBalance(firstHighNetWorthAccount); + expect(parseInt(balance)).toEqual(parseInt(balance1) - 10); + const balance2 = await web3.eth.getBalance(firstHighNetWorthAccount); + expect(balance1).toEqual(balance2); + const res = await api.getSingleStatusV1({ + id, + web3SigningCredential, + connectorId, + keychainId, + }); + expect(res.status).toEqual(200); + expect(res.data).toEqual(2); }); - t.equal(res.status, 200); - t.equal(res.data, 2, "the contract status is Refunded"); - t.end(); });