Lesson 9: getting error while testing the last it case #1866
-
rafffle.test const { assert, expect } = require("chai")
const { getNamedAccounts, deployments, ethers, network } = require("hardhat")
const { developmentChains, networkConfig } = require("../../helper-hardhat-config")
!developmentChains.includes(network.name)
? describe.skip
: describe("Raffle Unit tests", function () {
let raffle, vrfCoordinatorV2Mock, raffleEntranceFee, deployer, interval
const chainId = network.config.chainId
beforeEach(async function () {
deployer = (await getNamedAccounts()).deployer
await deployments.fixture(["all"])
raffle = await ethers.getContract("Raffle", deployer)
vrfCoordinatorV2Mock = await ethers.getContract("VRFCoordinatorV2Mock", deployer)
raffleEntranceFee = await raffle.getEntranceFee()
interval = await raffle.getInterval()
})
describe("constructor", function () {
it("initializes the raffle correctly", async function () {
// ideally we make our tests have just 1 assert per "it"
const raffleState = await raffle.getRaffleState()
assert.equal(raffleState.toString(), "0")
assert.equal(interval.toString(), networkConfig[chainId]["interval"])
})
})
describe("enterRaffle", function () {
it("reverts when you dont pay enough", async function () {
await expect(raffle.enterRaffle()).to.be.revertedWith(
"Raffle__NotEnoughETHEntered()"
)
})
it("records players when they enter", async function () {
await raffle.enterRaffle({ value: raffleEntranceFee })
const playerFromContract = await raffle.getPlayer(0)
assert.equal(playerFromContract, deployer)
})
it("emits event on enter", async function () {
await expect(raffle.enterRaffle({ value: raffleEntranceFee })).to.emit(
raffle,
"RaffleEnter"
)
})
it("dosent alllow entrance when raffle is calculating", async function () {
await raffle.enterRaffle({ value: raffleEntranceFee })
await network.provider.send("evm_increaseTime", [interval.toNumber() + 1])
await network.provider.send("evm_mine", [])
// We pretend to be a Chainlink Keeper
await raffle.performUpkeep([])
await expect(raffle.enterRaffle({ value: raffleEntranceFee })).to.be.revertedWith(
"Raffle__NotOpen"
)
})
})
describe("checkUpkeep", function () {
it("returns false if people havent sent any ETH", async function () {
await network.provider.send("evm_increaseTime", [interval.toNumber() + 1])
await network.provider.send("evm_mine", [])
const { upkeepNeeded } = await raffle.callStatic.checkUpkeep([])
assert(!upkeepNeeded)
})
it("returns false if raffle isn't open", async function () {
await raffle.enterRaffle({ value: raffleEntranceFee })
await network.provider.send("evm_increaseTime", [interval.toNumber() + 1])
await network.provider.send("evm_mine", [])
await raffle.performUpkeep([])
const raffleState = await raffle.getRaffleState() //Add this
const { upkeepNeeded } = await raffle.callStatic.checkUpkeep([]) // A
assert.equal(raffleState.toString(), "1")
assert.equal(upkeepNeeded, false)
})
it("returns false if enough time hasent passed ", async function () {
await raffle.enterRaffle({ value: raffleEntranceFee })
await network.provider.send("evm_increaseTime", [interval.toNumber() - 1])
await network.provider.request({ method: "evm_mine", params: [] })
const { upkeepNeeded } = await raffle.callStatic.checkUpkeep("0x")
assert(!upkeepNeeded)
})
it("returns true if enough time has passed, has players ,eth,and is open", async function () {
await raffle.enterRaffle({ value: raffleEntranceFee })
await network.provider.send("evm_increaseTime", [interval.toNumber() + 1])
await network.provider.request({ method: "evm_mine", params: [] })
const { upkeepNeeded } = await raffle.callStatic.checkUpkeep("0x")
assert(upkeepNeeded)
})
})
describe("performupKeep", function () {
it("it can only run if checkupkeep is true", async function () {
await raffle.enterRaffle({ value: raffleEntranceFee })
await network.provider.send("evm_increaseTime", [interval.toNumber() + 1])
await network.provider.send("evm_mine", [])
const tx = await raffle.performUpkeep([])
assert(tx)
})
it("reverts when checkupKeep is false", async function () {
await expect(raffle.performUpkeep([])).to.be.revertedWith(
"Raffle__UpkeepNotNeeded"
)
})
it("updates the raffle state, emits and event, and calls the vrf coordinotort", async function () {
raffle.enterRaffle({ value: raffleEntranceFee })
network.provider.send("evm_increaseTime", [interval.toNumber() + 1])
network.provider.send("evm_mine", [])
const txResponse = await raffle.performUpkeep([])
const txReceipt = await txResponse.wait(1)
const requestId = txReceipt.events[1].args.requestId
const raffleState = await raffle.getRaffleState()
assert(requestId.toNumber() > 0)
assert(raffleState.toString() == "1")
})
})
describe("fulfillRandomWords", function () {
beforeEach(async function () {
await raffle.enterRaffle({ value: raffleEntranceFee })
await network.provider.send("evm_increaseTime", [interval.toNumber() + 1])
await network.provider.send("evm_mine", [])
})
it("can only be called after performUpkeep", async function () {
await expect(
vrfCoordinatorV2Mock.fulfillRandomWords(0, raffle.address)
).to.be.revertedWith("nonexistent request")
await expect(
vrfCoordinatorV2Mock.fulfillRandomWords(1, raffle.address)
).to.be.revertedWith("nonexistent request")
})
it("picks a winner, resets the lottery,a nd sends money", async function () {
const additionalEntrants = 3
const startingAccountIndex = 1
const accounts = await ethers.getSigners()
for (
let i = startingAccountIndex;
i < startingAccountIndex + additionalEntrants;
i++
) {
const accountConnectedRaffle = raffle.connect(accounts[i])
await accountConnectedRaffle.enterRaffle({ value: raffleEntranceFee })
}
const startingTimeStamp = await raffle.getLatestTimeStamp()
//performUpkeep (mock being Chainlink Keepers)
//fullfillRandomWords (mock being the ChainLink VRF)
//we will have to wait for the fullfillRandomWords to be called
await new Promise(async (resolve, reject) => {
raffle.once("winnerPicked", async () => {
try {
console.log(accounts[2])
console.log(accounts[0])
console.log(accounts[1])
console.log(accounts[3])
const recentWinner = await raffle.getRecentWinner()
console.log(recentWinner)
const raffleState = await raffle.getRaffleState()
const endingTimeStamp = await raffle.getLatestTimeStamp()
const numPlayers = await raffle.getNumberOfPlayers()
assert.equal(numPlayers.toString(), "0")
assert.equal(raffleState, "0")
assert(endingTimeStamp > startingTimeStamp)
} catch (e) {
reject(e)
}
resolve()
})
//setting up the listner
// below ,we will fire the event ,and the listner will pick it up, and resolve
const tx = await raffle.performUpkeep([])
const txReceipt = await tx.wait(1)
await vrfCoordinatorV2Mock.fulfillRandomWords(
txReceipt.events[1].args.requestId,
raffle.address
)
})
})
})
}) raffle.sol //SPDX-License-Identifier:MIT
pragma solidity ^0.8.7;
import "@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol";
import "@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol";
import "@chainlink/contracts/src/v0.8/interfaces/KeeperCompatibleInterface.sol";
error Raffle__NotEnoughETHEntered();
error Raffle__TransferFailed();
error Raffle__NotOpen();
error Raffle__UpkeepNotNeeded(uint256 currentBalance, uint256 numPlayers, uint256 raffleSatate);
/** @title A Sample Raffle Contract
* @author Patrick Collins
* @notice This contract is for creating an untamperablee decentralized smart contract
* @dev This implements ChainnlinkVRF V2 and Chainlink Keepers */
contract Raffle is VRFConsumerBaseV2, KeeperCompatibleInterface {
/* Type declarations */
enum RaffleState {
OPEN,
CALCULATING
}
/* stateVariables*/
uint256 private immutable i_entranceFee;
address payable[] private s_players;
VRFCoordinatorV2Interface private immutable i_vrfCoordinator;
bytes32 private immutable i_gasLane;
uint64 private immutable i_subscriptionId;
uint16 private constant REQUEST_CONFIRMATIONS = 3;
uint32 private immutable i_callbackGasLimit;
uint32 private constant NUM_WORDS = 1;
//Lottery Varibales
address private s_recentWinner;
RaffleState private s_raffleState;
uint256 private s_lastTimeStamp;
uint256 private immutable i_interval;
/*Events */
event RaffleEnter(address indexed player);
event RequestedRaffleWinner(uint256 indexed requestId);
event WinnerPicked(address indexed winner);
constructor(
address vrfCoordinatorV2, //contract
uint256 entranceFee,
bytes32 gasLane,
uint64 subscriptionId,
uint32 callbackGasLimit,
uint256 interval
) VRFConsumerBaseV2(vrfCoordinatorV2) {
i_entranceFee = entranceFee;
i_vrfCoordinator = VRFCoordinatorV2Interface(vrfCoordinatorV2);
i_gasLane = gasLane;
i_subscriptionId = subscriptionId;
i_callbackGasLimit = callbackGasLimit;
s_raffleState = RaffleState.OPEN;
s_lastTimeStamp = block.timestamp;
i_interval = interval;
}
function enterRaffle() public payable {
if (msg.value < i_entranceFee) {
revert Raffle__NotEnoughETHEntered();
}
if (s_raffleState != RaffleState.OPEN) {
revert Raffle__NotOpen();
}
s_players.push(payable(msg.sender));
emit RaffleEnter(msg.sender);
}
/**
* @dev This is the function that ChainLink Keeper nodess call
* they look for the `upkeepNeeded` to return true
*The following should be true in order to return true:
* 1. Our time interval should have passes
* 2. The Lottery should have at least 1 player , and have some ETH
* 3. Our subscriptiion is funded with LINK
* 4. The Lottery should be in an "open" state.
*/
function checkUpkeep(
bytes memory /*checkData*/
)
public
override
returns (
bool upkeepNeeded,
bytes memory /* performData */
)
{
bool isOpen = (RaffleState.OPEN == s_raffleState);
bool timePassed = ((block.timestamp - s_lastTimeStamp) > i_interval);
bool hasPlayers = (s_players.length > 0);
bool hasBalance = address(this).balance > 0;
upkeepNeeded = (isOpen && timePassed && hasPlayers && hasBalance);
//block
}
function performUpkeep(
bytes calldata /*performData*/
) external override {
(bool upKeepNeeded, ) = checkUpkeep("");
if (!upKeepNeeded) {
revert Raffle__UpkeepNotNeeded(
address(this).balance,
s_players.length,
uint256(s_raffleState)
);
}
s_raffleState = RaffleState.CALCULATING;
uint256 requestId = i_vrfCoordinator.requestRandomWords(
i_gasLane,
i_subscriptionId,
REQUEST_CONFIRMATIONS,
i_callbackGasLimit,
NUM_WORDS
);
emit RequestedRaffleWinner(requestId);
}
function fulfillRandomWords(
uint256,
/*requestId,*/
uint256[] memory randomWords
) internal override {
uint256 indexOfWinner = randomWords[0] % s_players.length;
address payable recentWinner = s_players[indexOfWinner];
s_recentWinner = recentWinner;
s_raffleState = RaffleState.OPEN;
s_players = new address payable[](0);
s_lastTimeStamp = block.timestamp;
(bool success, ) = recentWinner.call{value: address(this).balance}("");
if (!success) {
revert Raffle__TransferFailed();
}
emit WinnerPicked(recentWinner);
}
/*View / Pure functions*/
function getEntranceFee() public view returns (uint256) {
return i_entranceFee;
}
function getPlayer(uint256 index) public view returns (address) {
return s_players[index];
}
function getRecentWinner() public view returns (address) {
return s_recentWinner;
}
function getRaffleState() public view returns (RaffleState) {
return s_raffleState;
}
function getNumWords() public pure returns (uint256) {
return NUM_WORDS;
}
function getNumberOfPlayers() public view returns (uint256) {
return s_players.length;
}
function getLatestTimeStamp() public view returns (uint256) {
return s_lastTimeStamp;
}
function getRequestConfirmations() public pure returns (uint256) {
return REQUEST_CONFIRMATIONS;
}
function getInterval() public view returns (uint256) {
return i_interval;
}
} hardhat config.js require("@nomiclabs/hardhat-waffle")
require("@nomiclabs/hardhat-etherscan")
require("hardhat-deploy")
require("solidity-coverage")
require("hardhat-gas-reporter")
require("hardhat-contract-sizer")
require("dotenv").config()
const RINKEBY_RPC_URL = process.env.RINKEBY_RPC_URL || "https://eth-rinkeby"
const PRIVATE_KEY = process.env.PRIVATE_KEY || "0xkey"
const ETHERSCAN_API_KEY = process.env.ETHERSCAN_API_KEY || "key"
const COINMARKETCAP_API_KEY = process.env.COINMARKETCAP_API_KEY || "key"
/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
defaultNetwork: "hardhat",
networks: {
hardhat: {
chainId: 31337,
blockconfirmations: 1,
},
rinkeby: {
chainId: 4,
blockconfirmations: 6,
url: RINKEBY_RPC_URL,
accounts: [PRIVATE_KEY],
},
},
gasReporter: {
enabled: false,
outputFile: "gas-report.txt",
noColors: true,
currency: "USD",
// coinmarketcap: COINMARKETCAP_API_KEY,
token: "MATIC",
},
solidity: "0.8.7",
namedAccounts: {
deployer: {
default: 0,
},
player: {
default: 1,
},
},
mocha: {
timeout: 200000,
},
} |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
Try and add increase the mocha timeout value to 400000 |
Beta Was this translation helpful? Give feedback.
-
Here is your error raffle.once("winnerPicked", async () => {
try {
console.log(accounts[2])
console.log(accounts[0])
console.log(accounts[1])
console.log(accounts[3])
const recentWinner = await raffle.getRecentWinner()
console.log(recentWinner)
const raffleState = await raffle.getRaffleState()
const endingTimeStamp = await raffle.getLatestTimeStamp()
const numPlayers = await raffle.getNumberOfPlayers()
assert.equal(numPlayers.toString(), "0")
assert.equal(raffleState, "0")
assert(endingTimeStamp > startingTimeStamp)
} catch (e) {
reject(e)
}
resolve()
}) In raffle.sol raffle.once("WinnerPicked", async () => {
try {
console.log(accounts[2])
console.log(accounts[0])
console.log(accounts[1])
console.log(accounts[3])
const recentWinner = await raffle.getRecentWinner()
console.log(recentWinner)
const raffleState = await raffle.getRaffleState()
const endingTimeStamp = await raffle.getLatestTimeStamp()
const numPlayers = await raffle.getNumberOfPlayers()
assert.equal(numPlayers.toString(), "0")
assert.equal(raffleState, "0")
assert(endingTimeStamp > startingTimeStamp)
} catch (e) {
reject(e)
}
resolve()
}) |
Beta Was this translation helpful? Give feedback.
Here is your error