diff --git a/packages/contract/contracts/WavePortal.sol b/packages/contract/contracts/WavePortal.sol index 3d26bca8..dd50e2de 100644 --- a/packages/contract/contracts/WavePortal.sol +++ b/packages/contract/contracts/WavePortal.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.19; -import 'hardhat/console.sol'; +// import 'hardhat/console.sol'; contract WavePortal { uint256 private _totalWaves; @@ -25,7 +25,7 @@ contract WavePortal { mapping(address => uint256) public lastWavedAt; constructor() payable { - console.log('We have been constructed!'); + // console.log('We have been constructed!'); /* * 初期シードの設定 */ @@ -36,7 +36,7 @@ contract WavePortal { /* * 現在ユーザーがwaveを送信している時刻と、前回waveを送信した時刻が15分以上離れていることを確認。 */ - require(lastWavedAt[msg.sender] + 0 minutes < block.timestamp, 'Wait 15m'); + require(lastWavedAt[msg.sender] + 15 minutes < block.timestamp, 'Wait 15m'); /* * ユーザーの現在のタイムスタンプを更新する @@ -44,7 +44,7 @@ contract WavePortal { lastWavedAt[msg.sender] = block.timestamp; _totalWaves += 1; - console.log('%s has waved!', msg.sender); + // console.log('%s has waved!', msg.sender); /* * ユーザーのために乱数を設定 @@ -54,7 +54,7 @@ contract WavePortal { _waves.push(Wave(msg.sender, _message, block.timestamp, _seed)); if (_seed <= 50) { - console.log('%s won!', msg.sender); + // console.log('%s won!', msg.sender); uint256 prizeAmount = 0.0001 ether; require( diff --git a/packages/contract/test/test.js b/packages/contract/test/test.js index ccea9d97..6d5c82c0 100644 --- a/packages/contract/test/test.js +++ b/packages/contract/test/test.js @@ -1,63 +1,109 @@ +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); const hre = require('hardhat'); const { expect } = require('chai'); +const { ethers } = require('hardhat'); -describe('Wave Contract', function () { - it('test if wave and token are sent', async function () { - const waveContractFactory = await hre.ethers.getContractFactory( - 'WavePortal', - ); - /* - * デプロイする際0.1ETHをコントラクトに提供する - */ - const waveContract = await waveContractFactory.deploy({ +describe('WavePortal', function () { + // すべてのテストで同じセットアップを再利用するためにフィクスチャーを定義します。 + async function deployProjectFixture() { + const wavePortalFactory = await ethers.getContractFactory('WavePortal'); + + // コントラクトは、デフォルトで最初の署名者/アカウント(ここではuser1)を使用してデプロイされます。 + const [user1, user2] = await ethers.getSigners(); + + const wavePortal = await wavePortalFactory.deploy({ value: hre.ethers.utils.parseEther('0.1'), }); - await waveContract.deployed(); - /* - * コントラクトの残高を取得(0.1ETH) - */ - const contractBalanceBefore = hre.ethers.utils.formatEther( - await hre.ethers.provider.getBalance(waveContract.address), + + await wavePortal.deployed(); + + // 現在のコントラクトの残高を取得します。 + const wavePortalBalance = hre.ethers.utils.formatEther( + await hre.ethers.provider.getBalance(wavePortal.address), ); - /* - * 2回 waves を送るシミュレーションを行う - */ - const waveTxn = await waveContract.wave('This is wave #1'); - await waveTxn.wait(); + // waveを2回実行する関数を定義します。 + const sendTwoWaves = async () => { + // user1, user2がそれぞれwaveを送ります。 + await wavePortal.connect(user1).wave('This is wave #1'); + await wavePortal.connect(user2).wave('This is wave #2'); + }; - const waveTxn2 = await waveContract.wave('This is wave #2'); - await waveTxn2.wait(); + return { wavePortal, wavePortalBalance, sendTwoWaves, user1, user2 }; + } - /* - * コントラクトの残高を取得し、Waveを取得した後の結果を出力 - */ - const contractBalanceAfter = hre.ethers.utils.formatEther( - await hre.ethers.provider.getBalance(waveContract.address), - ); + // テストケース + describe('getTotalWaves', function () { + it('should return total waves', async function () { + const { wavePortal, sendTwoWaves } = await loadFixture( + deployProjectFixture, + ); + + await sendTwoWaves(); + + const totalWaves = await wavePortal.getTotalWaves(); + + expect(totalWaves).to.equal(2); + }); + }); + + describe('getAllWaves', function () { + it('should return all waves', async function () { + const { wavePortal, sendTwoWaves, user1, user2 } = await loadFixture( + deployProjectFixture, + ); + + await sendTwoWaves(); + + const allWaves = await wavePortal.getAllWaves(); + + expect(allWaves[0].waver).to.equal(user1.address); + expect(allWaves[0].message).to.equal('This is wave #1'); + expect(allWaves[1].waver).to.equal(user2.address); + expect(allWaves[1].message).to.equal('This is wave #2'); + }); + }); + + describe('wave', function () { + context('when user waved', function () { + it('should send tokens at random.', async function () { + const { wavePortal, wavePortalBalance, sendTwoWaves } = + await loadFixture(deployProjectFixture); + + await sendTwoWaves(); + + // wave後のコントラクトの残高を取得します。 + const wavePortalBalanceAfter = hre.ethers.utils.formatEther( + await hre.ethers.provider.getBalance(wavePortal.address), + ); + + // 勝利した回数に応じてコントラクトから出ていくトークンを計算します。 + const allWaves = await wavePortal.getAllWaves(); + let cost = 0; + for (let i = 0; i < allWaves.length; i++) { + if (allWaves[i].seed <= 50) { + cost += 0.0001; + } + } + + // コントラクトのトークン残高がwave時の勝負による減少に連動しているかテストします。 + expect(parseFloat(wavePortalBalanceAfter)).to.equal( + wavePortalBalance - cost, + ); + }); + }); + context( + 'when user1 tried to resubmit without waiting 15 mitutes', + function () { + it('reverts', async function () { + const { wavePortal, user1 } = await loadFixture(deployProjectFixture); - /* - *勝利した回数に応じてコントラクトから出ていくトークンを計算 - */ - const allWaves = await waveContract.getAllWaves(); - let cost = 0; - for (let i = 0; i < allWaves.length; i++) { - if (allWaves[i].seed <= 50) { - cost += 0.0001; - } - } - - /* - *メッセージの送信をテスト - */ - expect(allWaves[0].message).to.equal('This is wave #1'); - expect(allWaves[1].message).to.equal('This is wave #2'); - - /* - *コントラクトのトークン残高がwave時の勝負による減少に連動しているかテスト - */ - expect(parseFloat(contractBalanceAfter)).to.equal( - contractBalanceBefore - cost, + await wavePortal.connect(user1).wave('This is wave #1'); + await expect( + wavePortal.connect(user1).wave('This is wave #2'), + ).to.be.revertedWith('Wait 15m'); + }); + }, ); }); });