Skip to content

Commit cc17906

Browse files
committed
test: add APIConsumer unit tests with mock FunctionsRouter
1 parent 6648e74 commit cc17906

1 file changed

Lines changed: 102 additions & 0 deletions

File tree

test/FunctionConsumer.t.sol

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.19;
3+
4+
import "forge-std/Test.sol";
5+
import "../src/APIConsumer.sol";
6+
import {FunctionsRouter} from "@chainlink/functions/v1_0_0/FunctionsRouter.sol";
7+
8+
contract MockFunctionsRouter is FunctionsRouter {
9+
bytes32 public lastRequestId;
10+
bytes public lastRequestCBOR;
11+
uint64 public lastSubscriptionId;
12+
uint32 public lastGasLimit;
13+
bytes32 public lastDonId;
14+
15+
constructor() FunctionsRouter(address(0)) {}
16+
17+
function sendRequest(
18+
uint64 subscriptionId,
19+
bytes calldata requestCBOR,
20+
uint32 gasLimit,
21+
bytes32 donId
22+
) external returns (bytes32) {
23+
lastRequestId = keccak256(abi.encodePacked(subscriptionId, requestCBOR, block.timestamp));
24+
lastRequestCBOR = requestCBOR;
25+
lastSubscriptionId = subscriptionId;
26+
lastGasLimit = gasLimit;
27+
lastDonId = donId;
28+
return lastRequestId;
29+
}
30+
31+
function simulateFulfillment(
32+
bytes32 requestId,
33+
address consumer,
34+
bytes memory response,
35+
bytes memory err
36+
) external {
37+
APIConsumer(consumer).handleOracleFulfillment(requestId, response, err);
38+
}
39+
}
40+
41+
contract APIConsumerTest is Test {
42+
MockFunctionsRouter public mockRouter;
43+
APIConsumer public apiConsumer;
44+
45+
bytes32 public constant DON_ID = keccak256("test-don-id");
46+
uint64 public constant SUBSCRIPTION_ID = 12345;
47+
48+
event RequestSent(bytes32 indexed requestId);
49+
event ResponseReceived(bytes32 indexed requestId, bytes response, bytes err);
50+
51+
function setUp() public {
52+
mockRouter = new MockFunctionsRouter();
53+
apiConsumer = new APIConsumer(
54+
address(mockRouter),
55+
DON_ID,
56+
SUBSCRIPTION_ID
57+
);
58+
}
59+
60+
function testInitialization() public {
61+
assertEq(apiConsumer.donId(), DON_ID);
62+
assertEq(apiConsumer.subscriptionId(), SUBSCRIPTION_ID);
63+
assertEq(apiConsumer.gasLimit(), 300000);
64+
assertEq(apiConsumer.owner(), address(this));
65+
}
66+
67+
function testRequestAPIData() public {
68+
string memory endpoint = "posts";
69+
string memory id = "1";
70+
71+
vm.expectEmit(true, false, false, false);
72+
emit RequestSent(bytes32(0))
73+
74+
bytes32 requestId = apiConsumer.requestAPIData(endpoint, id);
75+
76+
assertEq(mockRouter.lastSubscriptionId(), SUBSCRIPTION_ID);
77+
assertEq(mockRouter.lastGasLimit(), 300000);
78+
assertEq(mockRouter.lastDonId(), DON_ID);
79+
assertTrue(mockRouter.lastRequestCBOR().length > 0);
80+
}
81+
82+
function testFulfillRequest() public {
83+
84+
string memory endpoint = "posts";
85+
string memory id = "1";
86+
bytes32 requestId = apiConsumer.requestAPIData(endpoint, id);
87+
88+
bytes memory mockResponse = bytes('{"id":1,"title":"Test Post Title"}');
89+
bytes memory emptyError = "";
90+
91+
vm.expectEmit(true, true, true, true);
92+
emit ResponseReceived(requestId, mockResponse, emptyError);
93+
94+
mockRouter.simulateFulfillment(requestId, address(apiConsumer), mockResponse, emptyError);
95+
96+
assertEq(apiConsumer.lastResponse(), mockResponse);
97+
98+
string memory decodedResponse = apiConsumer.decodeResponse();
99+
assertEq(decodedResponse, '{"id":1,"title":"Test Post Title"}');
100+
}
101+
102+
}

0 commit comments

Comments
 (0)