From 5b709d9b5232994dda35fc3c521d53e5087c0cf0 Mon Sep 17 00:00:00 2001 From: iamacook Date: Mon, 13 Nov 2023 16:35:08 +0100 Subject: [PATCH] fix: add test coverage + remove comments --- package.json | 1 + .../EnableRecoveryFlowReview.tsx | 3 +- src/pages/settings/recovery.tsx | 1 - src/services/recovery/__tests__/setup.test.ts | 100 ++++++++++++++++++ yarn.lock | 33 +++++- 5 files changed, 134 insertions(+), 4 deletions(-) create mode 100644 src/services/recovery/__tests__/setup.test.ts diff --git a/package.json b/package.json index 9882a430e1..d58949d6b9 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "@emotion/react": "^11.10.0", "@emotion/server": "^11.10.0", "@emotion/styled": "^11.10.0", + "@gnosis.pm/zodiac": "^3.4.2", "@mui/icons-material": "^5.14.3", "@mui/material": "^5.14.3", "@mui/x-date-pickers": "^5.0.12", diff --git a/src/components/tx-flow/flows/EnableRecovery/EnableRecoveryFlowReview.tsx b/src/components/tx-flow/flows/EnableRecovery/EnableRecoveryFlowReview.tsx index 7772e437c5..97bb575dcb 100644 --- a/src/components/tx-flow/flows/EnableRecovery/EnableRecoveryFlowReview.tsx +++ b/src/components/tx-flow/flows/EnableRecovery/EnableRecoveryFlowReview.tsx @@ -59,7 +59,6 @@ export function EnableRecoveryFlowReview({ params }: { params: EnableRecoveryFlo - {/* TODO: Info */} @@ -83,7 +82,7 @@ export function EnableRecoveryFlowReview({ params }: { params: EnableRecoveryFlo > {delay} - {/* TODO: Info */} + diff --git a/src/pages/settings/recovery.tsx b/src/pages/settings/recovery.tsx index a5aa677b9f..b483293687 100644 --- a/src/pages/settings/recovery.tsx +++ b/src/pages/settings/recovery.tsx @@ -4,7 +4,6 @@ import type { NextPage } from 'next' import SettingsHeader from '@/components/settings/SettingsHeader' import { Recovery } from '@/components/settings/Recovery' -// TODO: Condense to other setting section once confirmed const RecoveryPage: NextPage = () => { return ( <> diff --git a/src/services/recovery/__tests__/setup.test.ts b/src/services/recovery/__tests__/setup.test.ts new file mode 100644 index 0000000000..258d9a1ab9 --- /dev/null +++ b/src/services/recovery/__tests__/setup.test.ts @@ -0,0 +1,100 @@ +import { getModuleInstance, KnownContracts, deployAndSetUpModule } from '@gnosis.pm/zodiac' +import { faker } from '@faker-js/faker' +import { BigNumber } from 'ethers' +import type { Web3Provider } from '@ethersproject/providers' +import type { SafeInfo } from '@safe-global/safe-gateway-typescript-sdk' + +import { getRecoverySetup } from '@/services/recovery/setup' + +jest.mock('@gnosis.pm/zodiac', () => ({ + ...jest.requireActual('@gnosis.pm/zodiac'), + getModuleInstance: jest.fn(), + deployAndSetUpModule: jest.fn(), +})) + +const mockGetModuleInstance = getModuleInstance as jest.MockedFunction +const mockDeployAndSetUpModule = deployAndSetUpModule as jest.MockedFunction + +describe('getRecoverySetup', () => { + beforeEach(() => { + jest.clearAllMocks() + }) + + it('should deploy Delay Modifier, enable it on Safe and add a Guardian', () => { + const txCooldown = faker.string.numeric() + const txExpiration = faker.string.numeric() + const guardians = [faker.finance.ethereumAddress()] + const safeAddress = faker.finance.ethereumAddress() + const chainId = faker.string.numeric() + const safe = { + address: { + value: safeAddress, + }, + chainId, + } as SafeInfo + const provider = {} as Web3Provider + + const expectedModuleAddress = faker.finance.ethereumAddress() + const deployDelayModifierTx = { + to: faker.finance.ethereumAddress(), + data: faker.string.hexadecimal(), + value: BigNumber.from(0), + } + mockGetModuleInstance.mockReturnValue({ + interface: { + encodeFunctionData: jest.fn().mockReturnValue(deployDelayModifierTx.data), + }, + } as any) + mockDeployAndSetUpModule.mockReturnValue({ + expectedModuleAddress, + transaction: deployDelayModifierTx, + }) + + const result = getRecoverySetup({ + txCooldown, + txExpiration, + guardians, + safe, + provider, + }) + + expect(mockDeployAndSetUpModule).toHaveBeenCalledTimes(1) + expect(mockDeployAndSetUpModule).toHaveBeenCalledWith( + KnownContracts.DELAY, + { + types: ['address', 'address', 'address', 'uint256', 'uint256'], + values: [ + safeAddress, // address _owner + safeAddress, // address _avatar + safeAddress, // address _target + txCooldown, // uint256 _cooldown + txExpiration, // uint256 _expiration + ], + }, + provider, + Number(safe.chainId), + expect.any(String), + ) + + expect(result.expectedModuleAddress).toEqual(expectedModuleAddress) + expect(result.transactions).toHaveLength(3) + + // Deploy Delay Modifier + expect(result.transactions[0]).toEqual({ + ...deployDelayModifierTx, + value: '0', + }) + // Enable Delay Modifier on Safe + expect(result.transactions[1]).toEqual({ + to: safeAddress, + data: expect.any(String), + value: '0', + }) + // Add guardian to Delay Modifier + expect(result.transactions[2]).toEqual({ + to: expectedModuleAddress, + data: expect.any(String), + value: '0', + }) + }) +}) diff --git a/yarn.lock b/yarn.lock index 978b89eee0..0f23fdb5d2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2706,6 +2706,27 @@ dependencies: tslib "^2.1.0" +"@gnosis.pm/mock-contract@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@gnosis.pm/mock-contract/-/mock-contract-4.0.0.tgz#eaf500fddcab81b5f6c22280a7b22ff891dd6f87" + integrity sha512-SkRq2KwPx6vo0LAjSc8JhgQstrQFXRyn2yqquIfub7r2WHi5nUbF8beeSSXsd36hvBcQxQfmOIYNYRpj9JOhrQ== + +"@gnosis.pm/safe-contracts@1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@gnosis.pm/safe-contracts/-/safe-contracts-1.3.0.tgz#316741a7690d8751a1f701538cfc9ec80866eedc" + integrity sha512-1p+1HwGvxGUVzVkFjNzglwHrLNA67U/axP0Ct85FzzH8yhGJb4t9jDjPYocVMzLorDoWAfKicGy1akPY9jXRVw== + +"@gnosis.pm/zodiac@^3.4.2": + version "3.4.2" + resolved "https://registry.yarnpkg.com/@gnosis.pm/zodiac/-/zodiac-3.4.2.tgz#ce3e7498e39ccc3324eabc6f163bd173bf4d9aad" + integrity sha512-u7BPXsoo1ZdbmsElMbuejKNTWA3NPvFdzs3vjUSIcFfHTb9B/UE+gDQ3vMYL6bt+YLVw0F/IT5ytbiruKYQpEQ== + dependencies: + "@gnosis.pm/mock-contract" "^4.0.0" + "@gnosis.pm/safe-contracts" "1.3.0" + "@openzeppelin/contracts" "^5.0.0" + "@openzeppelin/contracts-upgradeable" "^5.0.0" + ethers "^5.7.1" + "@grpc/grpc-js@~1.9.0": version "1.9.5" resolved "https://registry.yarnpkg.com/@grpc/grpc-js/-/grpc-js-1.9.5.tgz#22e283754b7b10d1ad26c3fb21849028dcaabc53" @@ -3604,11 +3625,21 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@openzeppelin/contracts-upgradeable@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-5.0.0.tgz#859c00c55f04b6dda85b3c88bce507d65019888f" + integrity sha512-D54RHzkOKHQ8xUssPgQe2d/U92mwaiBDY7qCCVGq6VqwQjsT3KekEQ3bonev+BLP30oZ0R1U6YC8/oLpizgC5Q== + "@openzeppelin/contracts@^4.9.2": version "4.9.3" resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.9.3.tgz#00d7a8cf35a475b160b3f0293a6403c511099364" integrity sha512-He3LieZ1pP2TNt5JbkPA4PNT9WC3gOTOlDcFGJW4Le4QKqwmiNJCRt44APfxMxvq7OugU/cqYuPcSBzOw38DAg== +"@openzeppelin/contracts@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-5.0.0.tgz#ee0e4b4564f101a5c4ee398cd4d73c0bd92b289c" + integrity sha512-bv2sdS6LKqVVMLI5+zqnNrNU/CA+6z6CmwFXm/MzmOPBRSO5reEJN7z0Gbzvs0/bv/MZZXNklubpwy3v2+azsw== + "@polka/url@^1.0.0-next.20": version "1.0.0-next.23" resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.23.tgz#498e41218ab3b6a1419c735e5c6ae2c5ed609b6c" @@ -8798,7 +8829,7 @@ ethers@5.5.4: "@ethersproject/web" "5.5.1" "@ethersproject/wordlists" "5.5.0" -ethers@5.7.2: +ethers@5.7.2, ethers@^5.7.1: version "5.7.2" resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.2.tgz#3a7deeabbb8c030d4126b24f84e525466145872e" integrity sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==