Skip to content

Commit

Permalink
test: fix base 'setUp' method to account Sablier v2 streams and small…
Browse files Browse the repository at this point in the history
… improvements
  • Loading branch information
gabrielstoica committed Jul 10, 2024
1 parent ec845e7 commit d87ce84
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 31 deletions.
28 changes: 22 additions & 6 deletions test/Base.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { MockERC20NoReturn } from "./mocks/MockERC20NoReturn.sol";
import { MockModule } from "./mocks/MockModule.sol";
import { Container } from "./../src/Container.sol";
import { InvoiceModule } from "./../src/modules/invoice-module/InvoiceModule.sol";
import { SablierV2LockupLinear } from "@sablier/v2-core/src/SablierV2LockupLinear.sol";
import { NFTDescriptorMock } from "@sablier/v2-core/test/mocks/NFTDescriptorMock.sol";

abstract contract Base_Test is Test, Events {
/*//////////////////////////////////////////////////////////////////////////
Expand All @@ -25,22 +27,36 @@ abstract contract Base_Test is Test, Events {
MockERC20NoReturn internal usdt;
MockModule internal mockModule;

// Sablier V2 related test contracts
NFTDescriptorMock internal mockNFTDescriptor;
SablierV2LockupLinear internal sablierV2LockupLinear;

/*//////////////////////////////////////////////////////////////////////////
SET-UP FUNCTION
//////////////////////////////////////////////////////////////////////////*/

function setUp() public virtual {
// Deploy test contracts
// Deploy the mock USDT contract to deal it to the users
usdt = new MockERC20NoReturn("Tether USD", "USDT", 6);
invoiceModule = new InvoiceModule();

// Create test users
users = Users({ admin: createUser("admin"), eve: createUser("eve"), bob: createUser("bob") });

// Deploy test contracts
mockNFTDescriptor = new NFTDescriptorMock();
sablierV2LockupLinear = new SablierV2LockupLinear({
initialAdmin: users.admin,
initialNFTDescriptor: mockNFTDescriptor
});
invoiceModule = new InvoiceModule({
_brokerAdmin: users.admin,
_sablierLockupDeployment: sablierV2LockupLinear
});
mockModule = new MockModule();

// Label the test contracts so we can easily track them
vm.label({ account: address(usdt), newLabel: "USDT" });
vm.label({ account: address(invoiceModule), newLabel: "InvoiceModule" });

// Create test users
users = Users({ eve: createUser("eve"), bob: createUser("bob") });
}

/*//////////////////////////////////////////////////////////////////////////
Expand All @@ -60,7 +76,7 @@ abstract contract Base_Test is Test, Events {
function createUser(string memory name) internal returns (address payable) {
address payable user = payable(makeAddr(name));
vm.deal({ account: user, newBalance: 100 ether });
deal({ token: address(usdt), to: user, give: 1000000e16 });
deal({ token: address(usdt), to: user, give: 1000000e6 });

return user;
}
Expand Down
6 changes: 3 additions & 3 deletions test/unit/concrete/container/Container.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
pragma solidity ^0.8.26;

import { Base_Test } from "../../../Base.t.sol";
import { InvoiceModule } from "./../../../../src/modules/invoice-module/InvoiceModule.sol";

contract Container_Unit_Concrete_Test is Base_Test {
function setUp() public virtual override {
Base_Test.setUp();

address[] memory modules = new address[](1);
modules[0] = address(invoiceModule);
address[] memory modules = new address[](2);
modules[0] = address(mockModule);
modules[1] = address(invoiceModule);

container = deployContainer({ owner: users.eve, initialModules: modules });
}
Expand Down
4 changes: 2 additions & 2 deletions test/unit/concrete/container/enable-module/enableModule.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
pragma solidity ^0.8.26;

import { Container_Unit_Concrete_Test } from "../Container.t.sol";
import { InvoiceModule } from "./../../../../../src/modules/invoice-module/InvoiceModule.sol";
import { MockModule } from "../../../../mocks/MockModule.sol";
import { Events } from "../../../../utils/Events.sol";
import { Errors } from "../../../../utils/Errors.sol";

Expand Down Expand Up @@ -42,7 +42,7 @@ contract EnableModule_Unit_Concrete_Test is Container_Unit_Concrete_Test {

function test_EnableModule() external whenCallerOwner whenNonZeroCodeModule {
// Create a new mock module
InvoiceModule mockModule = new InvoiceModule();
MockModule mockModule = new MockModule();

// Expect the {ModuleEnabled} to be emitted
vm.expectEmit();
Expand Down
23 changes: 8 additions & 15 deletions test/unit/concrete/container/execute/execute.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -42,31 +42,24 @@ contract Execute_Unit_Concrete_Test is Container_Unit_Concrete_Test {
}

function test_Execute() external whenCallerOwner whenModuleEnabled {
// Create the mock invoice and calldata for the module execution
InvoiceModuleTypes.Invoice memory invoice = Helpers.createInvoiceDataType({ recipient: address(container) });
bytes memory data = abi.encodeWithSignature(
"createInvoice((address,uint8,uint8,uint40,uint40,(uint8,uint8,uint24,address,uint256)))",
invoice
);
// Create the calldata for the mock module execution
bytes memory data = abi.encodeWithSignature("createModuleItem()", "");

// Expect the {ModuleExecutionSucceded} event to be emitted
vm.expectEmit();
emit Events.ModuleExecutionSucceded({ module: address(invoiceModule), value: 0, data: data });
emit Events.ModuleExecutionSucceded({ module: address(mockModule), value: 0, data: data });

// Run the test
container.execute({ module: address(invoiceModule), value: 0, data: data });
container.execute({ module: address(mockModule), value: 0, data: data });

// Alter the `createInvoice` method signature by removing the `payment.amount` field
bytes memory wrongData = abi.encodeWithSignature(
"createInvoice((address,uint8,uint8,uint40,uint40,(uint8,uint8,uint24,address)))",
invoice
);
// Alter the `createModuleItem` method signature by adding an invalid `uint256` field
bytes memory wrongData = abi.encodeWithSignature("createModuleItem(uint256)", 1);

// Expect the {ModuleExecutionFailed} event to be emitted
vm.expectEmit();
emit Events.ModuleExecutionFailed({ module: address(invoiceModule), value: 0, data: wrongData });
emit Events.ModuleExecutionFailed({ module: address(mockModule), value: 0, data: wrongData });

// Run the test
container.execute({ module: address(invoiceModule), value: 0, data: wrongData });
container.execute({ module: address(mockModule), value: 0, data: wrongData });
}
}
10 changes: 5 additions & 5 deletions test/utils/Helpers.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ library Helpers {
return
InvoiceModulesTypes.Invoice({
recipient: recipient,
status: InvoiceModulesTypes.Status.Active,
status: InvoiceModulesTypes.Status.Pending,
frequency: InvoiceModulesTypes.Frequency.Regular,
startTime: 0,
endTime: uint40(block.timestamp) + 150,
endTime: uint40(block.timestamp) + 1 weeks,
payment: InvoiceModulesTypes.Payment({
recurrence: InvoiceModulesTypes.Recurrence.OneTime,
method: InvoiceModulesTypes.Method.Transfer,
amount: 1 ether,
recurrence: InvoiceModulesTypes.Recurrence.OneTime,
paymentsLeft: 1,
asset: address(0),
paymentsLeft: 1
amount: uint128(1 ether)
})
});
}
Expand Down
2 changes: 2 additions & 0 deletions test/utils/Types.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
pragma solidity ^0.8.26;

struct Users {
// Account with administrative permissions
address admin;
// Account to interact with the protocol
address eve;
// Account to interact with the protocol
Expand Down

0 comments on commit d87ce84

Please sign in to comment.