-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test(cancel-invoice): add basic integration 'cancelInvoice' tests
- Loading branch information
1 parent
bdd8015
commit b2594c5
Showing
4 changed files
with
254 additions
and
0 deletions.
There are no files selected for viewing
170 changes: 170 additions & 0 deletions
170
test/integration/concrete/invoice-module/cancel-invoice/cancelInvoice.t.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.26; | ||
|
||
import { CancelInvoice_Integration_Shared_Test } from "../../../shared/cancelInvoice.t.sol"; | ||
import { Types } from "./../../../../../src/modules/invoice-module/libraries/Types.sol"; | ||
import { Events } from "../../../../utils/Events.sol"; | ||
import { Errors } from "../../../../utils/Errors.sol"; | ||
|
||
contract CancelInvoice_Integration_Concret_Test is CancelInvoice_Integration_Shared_Test { | ||
function setUp() public virtual override { | ||
CancelInvoice_Integration_Shared_Test.setUp(); | ||
} | ||
|
||
function test_RevertWhen_InvoiceIsPaid() external { | ||
// Set the one-off ETH transfer invoice as current one | ||
uint256 invoiceId = 1; | ||
|
||
// Make Bob the payer for the default invoice | ||
vm.startPrank({ msgSender: users.bob }); | ||
|
||
// Pay the invoice first | ||
invoiceModule.payInvoice{ value: invoices[invoiceId].payment.amount }({ id: invoiceId }); | ||
|
||
// Make Eve the caller who is the recipient of the invoice | ||
vm.startPrank({ msgSender: users.eve }); | ||
|
||
// Expect the call to revert with the {CannotCancelPaidInvoice} error | ||
vm.expectRevert(Errors.CannotCancelPaidInvoice.selector); | ||
|
||
// Run the test | ||
invoiceModule.cancelInvoice({ id: invoiceId }); | ||
} | ||
|
||
function test_RevertWhen_InvoiceIsCanceled() external whenInvoiceNotAlreadyPaid { | ||
// Set the one-off ETH transfer invoice as current one | ||
uint256 invoiceId = 1; | ||
|
||
// Make Eve the caller who is the recipient of the invoice | ||
vm.startPrank({ msgSender: users.eve }); | ||
|
||
// Cancel the invoice first | ||
invoiceModule.cancelInvoice({ id: invoiceId }); | ||
|
||
// Expect the call to revert with the {InvoiceAlreadyCanceled} error | ||
vm.expectRevert(Errors.InvoiceAlreadyCanceled.selector); | ||
|
||
// Run the test | ||
invoiceModule.cancelInvoice({ id: invoiceId }); | ||
} | ||
|
||
function test_RevertWhen_PaymentMethodTransfer_SenderNotInvoiceRecipient() | ||
external | ||
whenInvoiceNotAlreadyPaid | ||
whenInvoiceNotCanceled | ||
givenPaymentMethodTransfer | ||
{ | ||
// Set the one-off ETH transfer invoice as current one | ||
uint256 invoiceId = 1; | ||
|
||
// Make Bob the caller who IS NOT the recipient of the invoice | ||
vm.startPrank({ msgSender: users.bob }); | ||
|
||
// Expect the call to revert with the {InvoiceOwnerUnauthorized} error | ||
vm.expectRevert(Errors.InvoiceOwnerUnauthorized.selector); | ||
|
||
// Run the test | ||
invoiceModule.cancelInvoice({ id: invoiceId }); | ||
} | ||
|
||
function test_CancelInvoice_PaymentMethodTransfer() | ||
external | ||
whenInvoiceNotAlreadyPaid | ||
whenInvoiceNotCanceled | ||
givenPaymentMethodTransfer | ||
whenSenderInvoiceRecipient | ||
{ | ||
// Set the one-off ETH transfer invoice as current one | ||
uint256 invoiceId = 1; | ||
|
||
// Make Eve the caller who is the recipient of the invoice | ||
vm.startPrank({ msgSender: users.eve }); | ||
|
||
// Expect the {InvoiceCanceled} event to be emitted | ||
vm.expectEmit(); | ||
emit Events.InvoiceCanceled({ id: invoiceId }); | ||
|
||
// Run the test | ||
invoiceModule.cancelInvoice({ id: invoiceId }); | ||
|
||
// Assert the actual and expected invoice status | ||
Types.Invoice memory invoice = invoiceModule.getInvoice({ id: invoiceId }); | ||
assertEq(uint8(invoice.status), uint8(Types.Status.Canceled)); | ||
} | ||
|
||
function test_RevertWhen_PaymentMethodLinearStream_StatusPending_SenderNotInvoiceRecipient() | ||
external | ||
whenInvoiceNotAlreadyPaid | ||
whenInvoiceNotCanceled | ||
givenPaymentMethodLinearStream | ||
givenInvoiceStatusPending | ||
{ | ||
// Set current invoice as a linear stream-based one | ||
uint256 invoiceId = 3; | ||
|
||
// Make Bob the caller who IS NOT the recipient of the invoice | ||
vm.startPrank({ msgSender: users.bob }); | ||
|
||
// Expect the call to revert with the {InvoiceOwnerUnauthorized} error | ||
vm.expectRevert(Errors.InvoiceOwnerUnauthorized.selector); | ||
|
||
// Run the test | ||
invoiceModule.cancelInvoice({ id: invoiceId }); | ||
} | ||
|
||
function test_CancelInvoice_PaymentMethodLinearStream_StatusPending() | ||
external | ||
whenInvoiceNotAlreadyPaid | ||
whenInvoiceNotCanceled | ||
givenPaymentMethodLinearStream | ||
givenInvoiceStatusPending | ||
whenSenderInvoiceRecipient | ||
{ | ||
// Set current invoice as a linear stream-based one | ||
uint256 invoiceId = 3; | ||
|
||
// Make Eve the caller who is the recipient of the invoice | ||
vm.startPrank({ msgSender: users.eve }); | ||
|
||
// Expect the {InvoiceCanceled} event to be emitted | ||
vm.expectEmit(); | ||
emit Events.InvoiceCanceled({ id: invoiceId }); | ||
|
||
// Run the test | ||
invoiceModule.cancelInvoice({ id: invoiceId }); | ||
|
||
// Assert the actual and expected invoice status | ||
Types.Invoice memory invoice = invoiceModule.getInvoice({ id: invoiceId }); | ||
assertEq(uint8(invoice.status), uint8(Types.Status.Canceled)); | ||
} | ||
|
||
function test_RevertWhen_PaymentMethodLinearStream_StatusOngoing_SenderNotStreamSender() | ||
external | ||
whenInvoiceNotAlreadyPaid | ||
whenInvoiceNotCanceled | ||
givenPaymentMethodLinearStream | ||
givenInvoiceStatusOngoing | ||
{ | ||
// Set current invoice as a linear stream-based one | ||
uint256 invoiceId = 3; | ||
|
||
// The invoice must be paid for its status to be updated to `Ongoing` | ||
// Make Bob the payer of the invoice (also Bob will be the stream sender) | ||
vm.startPrank({ msgSender: users.bob }); | ||
|
||
// Approve the {InvoiceModule} to transfer the USDT tokens on Bob's behalf | ||
usdt.approve({ spender: address(invoiceModule), amount: invoices[invoiceId].payment.amount }); | ||
|
||
// Pay the invoice first (status will be updated to `Ongoing`) | ||
invoiceModule.payInvoice{ value: invoices[invoiceId].payment.amount }({ id: invoiceId }); | ||
|
||
// Make Eve the caller who IS NOT the stream sender | ||
vm.startPrank({ msgSender: users.eve }); | ||
|
||
// Expect the call to revert with the {SablierV2Lockup_Unauthorized} error | ||
vm.expectRevert(abi.encodeWithSelector(Errors.SablierV2Lockup_Unauthorized.selector, 1, users.bob)); | ||
|
||
// Run the test | ||
invoiceModule.cancelInvoice({ id: invoiceId }); | ||
} | ||
} |
40 changes: 40 additions & 0 deletions
40
test/integration/concrete/invoice-module/cancel-invoice/cancelInvoice.tree
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
cancelInvoice.t.sol | ||
├── when the invoice status IS Paid | ||
│ └── it should revert with the {CannotCancelPaidInvoice} error | ||
└── when the invoice status IS NOT Paid | ||
├── when the invoice status IS Canceled | ||
│ └── it should revert with the {InvoiceAlreadyCanceled} error | ||
└── when the invoice status IS NOT Canceled | ||
├── given the payment method is transfer | ||
│ ├── when the sender IS NOT the invoice recipient | ||
│ │ └── it should revert with the {InvoiceOwnerUnauthorized} | ||
│ └── when the sender IS the invoice recipient | ||
│ ├── it should mark the invoice as Canceled | ||
│ └── it should emit an {InvoiceCanceled} event | ||
├── given the payment method is linear stream-based | ||
│ ├── given the invoice status is Pending | ||
│ │ ├── when the sender IS NOT the invoice recipient | ||
│ │ │ └── it should revert with the {InvoiceOwnerUnauthorized} | ||
│ │ └── when the sender IS the invoice recipient | ||
│ │ ├── it should mark the invoice as Canceled | ||
│ │ └── it should emit an {InvoiceCanceled} event | ||
│ └── given the invoice status is Ongoing | ||
│ ├── when the sender IS NOT the stream's sender | ||
│ │ └── it should revert with the {SablierV2Lockup_Unauthorized} error | ||
│ └── when the sender IS the stream's sender | ||
│ ├── it should mark the invoice as Canceled | ||
│ └── it should emit an {InvoiceCanceled} event | ||
└── given the payment method is tranched stream-based | ||
├── given the invoice status is Pending | ||
│ ├── when the sender IS NOT the invoice recipient | ||
│ │ └── it should revert with the {InvoiceOwnerUnauthorized} | ||
│ └── when the sender IS the invoice recipient | ||
│ ├── it should mark the invoice as Canceled | ||
│ └── it should emit an {InvoiceCanceled} event | ||
└── given the invoice status is Ongoing | ||
├── when the sender IS NOT the stream's sender | ||
│ └──it should revert with the {SablierV2Lockup_Unauthorized} error | ||
└── when the sender IS the stream's sender | ||
├── it should mark the invoice as Canceled | ||
└── it should emit an {InvoiceCanceled} event | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.26; | ||
|
||
import { Integration_Test } from "../Integration.t.sol"; | ||
import { PayInvoice_Integration_Shared_Test } from "./payInvoice.t.sol"; | ||
|
||
abstract contract CancelInvoice_Integration_Shared_Test is Integration_Test, PayInvoice_Integration_Shared_Test { | ||
function setUp() public virtual override(Integration_Test, PayInvoice_Integration_Shared_Test) { | ||
PayInvoice_Integration_Shared_Test.setUp(); | ||
} | ||
|
||
modifier whenInvoiceStatusNotPaid() { | ||
_; | ||
} | ||
|
||
modifier whenInvoiceStatusNotCanceled() { | ||
_; | ||
} | ||
|
||
modifier whenSenderInvoiceRecipient() { | ||
_; | ||
} | ||
|
||
modifier givenInvoiceStatusPending() { | ||
_; | ||
} | ||
|
||
modifier givenInvoiceStatusOngoing() { | ||
_; | ||
} | ||
|
||
modifier whenSenderStreamSender() { | ||
_; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters