Skip to content

Commit

Permalink
Add TaskRegistry and Tests
Browse files Browse the repository at this point in the history
  • Loading branch information
chalex-eth committed Oct 9, 2024
1 parent bc515c0 commit f0ba738
Show file tree
Hide file tree
Showing 6 changed files with 333 additions and 2 deletions.
3 changes: 1 addition & 2 deletions contracts/.github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ name: CI

on:
push:
pull_request:
workflow_dispatch:


env:
FOUNDRY_PROFILE: ci
Expand Down
88 changes: 88 additions & 0 deletions contracts/lcov.info
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
TN:
SF:src/Ownable.sol
FN:35,Ownable.
FNDA:17,Ownable.
DA:36,17
DA:38,17
FN:48,Ownable.transferOwnership
FNDA:3,Ownable.transferOwnership
DA:49,3
DA:50,3
FN:54,Ownable.acceptOwnership
FNDA:2,Ownable.acceptOwnership
DA:55,2
BRDA:55,0,0,1
DA:56,1
DA:57,1
DA:58,1
DA:59,1
FN:63,Ownable.cancelTransferOwnership
FNDA:1,Ownable.cancelTransferOwnership
DA:64,1
DA:65,1
FN:68,Ownable.onlyOwner
FNDA:5,Ownable.onlyOwner
DA:69,5
BRDA:69,1,0,2
FNF:5
FNH:5
LF:12
LH:12
BRF:2
BRH:2
end_of_record
TN:
SF:src/TaskRegistry.sol
FN:45,TaskRegistry.
FNDA:13,TaskRegistry.
DA:46,13
DA:47,13
FN:54,TaskRegistry.setAggregatorNode
FNDA:2,TaskRegistry.setAggregatorNode
DA:55,1
FN:58,TaskRegistry.setClientAppRegistry
FNDA:2,TaskRegistry.setClientAppRegistry
DA:59,1
FN:66,TaskRegistry.createTask
FNDA:8,TaskRegistry.createTask
DA:68,8
DA:71,8
BRDA:71,0,0,1
DA:72,7
DA:73,7
DA:74,7
FN:77,TaskRegistry.respondToTask
FNDA:8,TaskRegistry.respondToTask
DA:79,7
BRDA:79,1,0,1
DA:80,6
BRDA:80,2,0,1
DA:83,5
BRDA:83,3,0,1
DA:84,4
BRDA:84,4,0,1
DA:86,3
DA:87,3
FN:94,TaskRegistry.onlyAggregatorNode
FNDA:8,TaskRegistry.onlyAggregatorNode
DA:95,8
BRDA:95,5,0,1
FNF:6
FNH:6
LF:16
LH:16
BRF:6
BRH:6
end_of_record
TN:
SF:test/TestOwnable.t.sol
FN:10,MockOwnable.updateFlag
FNDA:3,MockOwnable.updateFlag
DA:11,2
FNF:1
FNH:1
LF:1
LH:1
BRF:0
BRH:0
end_of_record
1 change: 1 addition & 0 deletions contracts/src/TaskRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ contract TaskRegistry is Ownable {
if (tasks[taskId] == TaskStatus.COMPLETED) revert InvalidTaskOperation();
if (tasks[taskId] == TaskStatus.FAILED) revert InvalidTaskOperation();

tasks[taskId] = status;
emit TaskResponded(taskId, status);
}

Expand Down
143 changes: 143 additions & 0 deletions contracts/test/TaskRegistry.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.26;

import {Test, console2} from "forge-std/Test.sol";
import {TaskRegistry} from "../src/TaskRegistry.sol";
import {Ownable} from "src/Ownable.sol";
import {TestState} from "./TestState.sol";

contract TaskRegistryTest is TestState {
function setUp() public override {
super.setUp();
}

function testSetAggregatorNode() public {
address newAggregatorNode = address(5);

vm.prank(owner);
taskRegistry.setAggregatorNode(newAggregatorNode);

assertEq(taskRegistry.aggregatorNode(), newAggregatorNode);
}

function testSetAggregatorNode_RevertWhen_NotOwner() public {
address newAggregatorNode = address(5);

vm.prank(user);
vm.expectRevert(Ownable.Unauthorized.selector);
taskRegistry.setAggregatorNode(newAggregatorNode);
}

function testSetClientAppRegistry() public {
address newClientAppRegistry = address(6);

vm.prank(owner);
taskRegistry.setClientAppRegistry(newClientAppRegistry);

assertEq(taskRegistry.clientAppRegistry(), newClientAppRegistry);
}

function testSetClientAppRegistry_RevertWhen_NotOwner() public {
address newClientAppRegistry = address(6);

vm.prank(user);
vm.expectRevert(Ownable.Unauthorized.selector);
taskRegistry.setClientAppRegistry(newClientAppRegistry);
}

function testCreateTask() public {
bytes32 agentId = bytes32(uint256(1));
bytes32 taskId = keccak256(abi.encode(user, agentId, block.timestamp));
assertEq(uint256(taskRegistry.tasks(taskId)), uint256(TaskRegistry.TaskStatus.EMPTY));

vm.prank(user);
taskRegistry.createTask(agentId);
assertEq(uint256(taskRegistry.tasks(taskId)), uint256(TaskRegistry.TaskStatus.PENDING));
}

function testCreateTask_RevertWhen_TaskAlreadyExists() public {
bytes32 agentId = bytes32(uint256(1));

vm.startPrank(user);
taskRegistry.createTask(agentId);

vm.expectRevert(TaskRegistry.TaskAlreadyExists.selector);
taskRegistry.createTask(agentId);
vm.stopPrank();
}

function testRespondToTask() public {
bytes32 agentId = bytes32(uint256(1));

vm.prank(user);
taskRegistry.createTask(agentId);

bytes32 taskId = keccak256(abi.encode(user, agentId, block.timestamp));

vm.prank(aggregatorNode);

taskRegistry.respondToTask(taskId, TaskRegistry.TaskStatus.COMPLETED);
}

function testRespondToTask_RevertWhen_NotAggregatorNode() public {
bytes32 agentId = bytes32(uint256(1));

vm.prank(user);
taskRegistry.createTask(agentId);

bytes32 taskId = keccak256(abi.encode(user, agentId, block.timestamp));

vm.prank(user);
vm.expectRevert(Ownable.Unauthorized.selector);
taskRegistry.respondToTask(taskId, TaskRegistry.TaskStatus.COMPLETED);
}

function testRespondToTask_RevertWhen_InvalidStatus() public {
bytes32 agentId = bytes32(uint256(1));

vm.prank(user);
taskRegistry.createTask(agentId);

bytes32 taskId = keccak256(abi.encode(user, agentId, block.timestamp));

vm.prank(aggregatorNode);
vm.expectRevert(TaskRegistry.InvalidTaskOperation.selector);
taskRegistry.respondToTask(taskId, TaskRegistry.TaskStatus.EMPTY);

vm.prank(aggregatorNode);
vm.expectRevert(TaskRegistry.InvalidTaskOperation.selector);
taskRegistry.respondToTask(taskId, TaskRegistry.TaskStatus.PENDING);
}

function testRespondToTask_RevertWhen_AlreadyRespondedCompleted() public {
bytes32 agentId = bytes32(uint256(1));

vm.prank(user);
taskRegistry.createTask(agentId);

bytes32 taskId = keccak256(abi.encode(user, agentId, block.timestamp));

vm.prank(aggregatorNode);
taskRegistry.respondToTask(taskId, TaskRegistry.TaskStatus.COMPLETED);

vm.prank(aggregatorNode);
vm.expectRevert(TaskRegistry.InvalidTaskOperation.selector);
taskRegistry.respondToTask(taskId, TaskRegistry.TaskStatus.FAILED);
}

function testRespondToTask_RevertWhen_AlreadyRespondedFailed() public {
bytes32 agentId = bytes32(uint256(1));

vm.prank(user);
taskRegistry.createTask(agentId);

bytes32 taskId = keccak256(abi.encode(user, agentId, block.timestamp));

vm.prank(aggregatorNode);
taskRegistry.respondToTask(taskId, TaskRegistry.TaskStatus.FAILED);

vm.prank(aggregatorNode);
vm.expectRevert(TaskRegistry.InvalidTaskOperation.selector);
taskRegistry.respondToTask(taskId, TaskRegistry.TaskStatus.COMPLETED);
}
}
70 changes: 70 additions & 0 deletions contracts/test/TestOwnable.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.26;

import "forge-std/Test.sol";
import {Ownable} from "src/Ownable.sol";

contract MockOwnable is Ownable(msg.sender) {
bool public flag;

function updateFlag() public virtual onlyOwner {
flag = true;
}
}

contract TestOwnable is Test {
MockOwnable mockOwnable;
address alice;
address bob;

function setUp() public {
alice = vm.addr(1);
vm.label(alice, "Alice");
bob = vm.addr(2);
vm.label(bob, "Bob");

vm.prank(alice);
mockOwnable = new MockOwnable();
}

function test_TransherOwnership() public {
vm.prank(alice);
mockOwnable.transferOwnership(bob);
assertEq(mockOwnable.pendingOwner(), bob);

vm.prank(bob);
mockOwnable.acceptOwnership();
assertEq(mockOwnable.owner(), bob);
assertEq(mockOwnable.pendingOwner(), address(0x0));

vm.prank(bob);
mockOwnable.updateFlag();
}

function test_cancelTransferOwnership() public {
vm.startPrank(alice);
mockOwnable.transferOwnership(bob);
assertEq(mockOwnable.pendingOwner(), bob);

mockOwnable.cancelTransferOwnership();
assertEq(mockOwnable.pendingOwner(), address(0x0));

mockOwnable.updateFlag();
}

function test_RevertWhen_Ownable() public {
vm.startPrank(bob);
vm.expectRevert(Ownable.Unauthorized.selector);
mockOwnable.updateFlag();
}

function test_RevertWhen_OnlyPendingOwner() public {
vm.prank(alice);
mockOwnable.transferOwnership(bob);
assertEq(mockOwnable.pendingOwner(), bob);

vm.prank(alice);
vm.expectRevert(Ownable.Unauthorized.selector);
mockOwnable.acceptOwnership();
}
}
30 changes: 30 additions & 0 deletions contracts/test/TestState.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.26;

import {Test} from "forge-std/Test.sol";
import {TaskRegistry} from "src/TaskRegistry.sol";

contract TestState is Test {
address public owner = makeAddr("owner");
address public user = makeAddr("user");
address public aggregatorNode = makeAddr("aggregatorNode");
address public clientAppRegistry = makeAddr("clientAppRegistry");

TaskRegistry public taskRegistry;

function setUp() public virtual {
vm.startPrank(owner);
taskRegistry = new TaskRegistry(owner, aggregatorNode, clientAppRegistry);
vm.stopPrank();
vm.label(owner, "owner");
vm.label(user, "user");
vm.label(aggregatorNode, "aggregatorNode");
vm.label(clientAppRegistry, "clientAppRegistry");
}

function test_initialState() public view {
assertEq(taskRegistry.owner(), owner);
assertEq(taskRegistry.aggregatorNode(), aggregatorNode);
assertEq(taskRegistry.clientAppRegistry(), clientAppRegistry);
}
}

0 comments on commit f0ba738

Please sign in to comment.