> For the complete documentation index, see [llms.txt](https://1hive.gitbook.io/celeste/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://1hive.gitbook.io/celeste/developers/documentation/testing-disputable-contracts.md).

# Testing disputable contracts

Guide and API description of different mock contracts.

The `celeste-helpers` package provides a number of mocks which simulate the DisputeManger, AragonCourt and Arbitrator Manifest API's and their functionality on a basic level. This should help when creating tests for Disputable contracts as you can avoid all the overhead necessary to fork xDai or even deploy a full Celeste instance in your test environment.&#x20;

## TestERC20

As the name implies is an ERC20 token that is easy to instantiate for tests. `TestERC20` supports all standard ERC20 methods and events along with additional methods defined in`@openzeppelin/contracts/token/ERC20/ERC20.sol`.

This contract takes no constructor arguments. The deployer address will automatically be assigned as the token owner. Ownership can queried, transferred and revoked based on [Openzeppelin's Ownable API](https://docs.openzeppelin.com/contracts/4.x/api/access#Ownable).

### `TestERC20.mint(address, uint256) -> ()`

#### Parameters:

* **`address _recipient`**:\
  Recipient of newly minted test tokens
* **`uint256 _amount`**:\
  Amount of test tokens to be minted

#### Emitted events:

In accordance to the recommendation in the ERC20 spec a `ERC20.Transfer` event is transferred with the `from` address being the zero address and the `to` address being the `_recipient`

#### General function

Method issues new tokens to recipient. Reverts if caller is not the owner. This is to avoid accidental mints within your tests.

## DisputeManager and AragonCourt mocks

The mock for these contracts is a single contract taking up the functionality and the API of both. The mock only simulates the necessary methods so that evidence can be submitted, disputes can be settled and rulings can be set.

The Dispute Lifecycle is mostly absent for disputes created within the mocks. Once created they'll be open, existing indefinitely until the owner sets a ruling.&#x20;

### `celest-helpers/contracts/mocks/MockArbitrator.sol` API

{% tabs %}
{% tab title="instantiating" %}

#### `constructor(address)`

#### Parameters:

* **`address _feeToken`**:\
  Address of token to be used as fee for dispute creation.

#### Emitted Events:

The constructor does not emit any events

#### General function

Stores the `_feeToken` address in an immutable property and sets the instantiating address as the owner of this instance. Uses [OpenZeppelin's Ownable API](https://docs.openzeppelin.com/contracts/4.x/api/access#Ownable) for ownership.
{% endtab %}

{% tab title="dispute creation" %}

#### `createDispute(uint256, bytes) -> (uint256)`

Similar to a real `arbitrator.createDispute` call but it only stores the subject for the dispute, pulls the fee and emits a `NewDispute` event. Reverts if `_possibleRulings` is not 2.
{% endtab %}

{% tab title="submitting evidence" %}

#### `submitEvidence(uint256, address, bytes) -> ()`

Virtually identical to a `arbitrator.submitEvidence` call. Exactly the same revert messages are issued if the caller is not the subject or if the dispute does not exist. Also emits the `EvidenceSubmitted` event.
{% endtab %}

{% tab title="closing the evidence period" %}

#### `closeEvidencePeriod(uint256) -> ()`

Virtually identical to a `arbitrator.closeEvidencePeriod` call. Exactly the same revert messages are issued if the caller is not the subject or if the dispute does not exist. Also emits the `EvidencePeriodClosed` event. Only difference is it has no effect in terms of shortening the evidence phase.
{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="retrieving a ruling" %}

#### `rule(uint256) -> (address, uint256)`

Virtually identical to a `arbitrator.rule` call. Returns the subject and ruling if a ruling has been set. Emits a `RulingComputed` the first time a ruling is retrieved.&#x20;
{% endtab %}

{% tab title="setting a ruling" %}

#### `setRuling(uint256, uint256) -> ()`

#### Parameters:

* **`uint256 _disputeId`**:\
  The dispute ID for which the ruling is to be set
* **`uint256 _ruling`**:\
  Ruling ID (2 / 3 /  4)

#### Emitted events:

Does not emit any events.

**General function**

Reverts if:

* The dispute does not exist yet
* **OR** The caller is not the owner
* **OR** `_ruling` it not 2 / 3 / 4

Directly sets the ruling for a dispute. This is extremely in testing as you can directly simulate a ruling for your disputable contract without having to simulate a full jury selection, vote, appeal etc.&#x20;
{% endtab %}

{% tab title="getters" %}

#### `getSubjectOf(uint256 _disputeId) -> (address subject)`

#### `getDisputeFees() -> (address recipient, IERC20 feeToken, uint256 feeAmount)`

For the arbitrator mock the fee recipient will always be itself.

#### `getDisputeManager() -> (address disputeManager)`

Since the arbitrator mock is a 2-in-1 AragonCourt and DisputeManger it will return its own address.
{% endtab %}
{% endtabs %}

## Arbitrator Manifest Mock

Identical to the normal Arbitrator Manifest except it's only compatible with the AragonCourt / DisputeManager mock. The outward facing API is also identical.&#x20;

## Example

For a concrete example on how a test for a Disputable contract using the mocks looks like check out the test for the `WorkAgreement` contract described in the [Getting Started](/celeste/developers/documentation/getting-started.md) section. The test can be found [here](https://github.com/1Hive/celeste-helpers/blob/master/test/WorkAgreement.test.js).
