TimedCrowdsale Test not working

:computer: Environment
Truffle v5.2.6 (core: 5.2.6)
Solidity - 0.5.5 (solc-js)
Node v14.16.0
Web3.js v1.2.9

:memo:Details
I developing a TimedCrowdsale contract, but I’m open the Crowdsale for the test

:1234: Code to reproduce

//Crowdsale Test
import ether from './helpers/ether';
import EVMRevert from './helpers/EVMRevert';
import { latest, advanceBlock, increase, duration } from '@openzeppelin/test-helpers/src/time';

const BN = web3.utils.BN;

const PFBTokenCrowdsale = artifacts.require('PFBTokenCrowdsale');
const PFBToken = artifacts.require('PFBToken');

require('chai')
  .use(require('chai-as-promised'))
  .use(require('chai-bn')(BN))
  .should();

contract('PFBTokenCrowdsale', function([_ , wallet, investor1, investor2]) {
  before(async function () {
    // Advance to the next block to correctly read time in the solidity "now" function interpreted by ganache
    await advanceBlock();
    // Advance time to crowdsale start
    await increase(duration.weeks(2));
  });
  beforeEach(async function () {
    // Token config
    this.name = "PFB Test Token";
    this.symbol = 'PFBT';
    this.decimals = new BN(18);

    // Deploy Token
    this.token = await PFBToken.new(
      this.name, 
      this.symbol, 
      this.decimals
    );

    // Crowdsale config
    this.rate =  new BN(1500000);
    this.wallet = wallet;
    this.cap = ether(14001);
    this.openingTime = new BN(latest() + duration.weeks(1));
    this.closingTime = this.openingTime + duration.years(1);
    this.goal = ether(14000);

    // Investor caps
    this.investorMinCap = ether(0.01);
    this.inestorHardCap = ether(350);

    this.crowdsale = await PFBTokenCrowdsale.new(
      this.rate,
      this.wallet,
      this.token.address,
      this.cap,
      this.openingTime,
      this.closingTime,
      this.goal
    );

    // Add Mintor Role to crowdsale
    await this.token.addMinter(this.crowdsale.address);

    // Add investors to whitelist
    await this.crowdsale.addWhitelisted(investor1);
    await this.crowdsale.addWhitelisted(investor2);
  });

  describe('crowdsale', function() {

    it('tracks the rate', async function() {
      const rate = await this.crowdsale.rate();
      rate.should.be.bignumber.equal(this.rate);
    });

    it('tracks the wallet', async function() {
      const wallet = await this.crowdsale.wallet();
      wallet.should.equal(this.wallet);
    });

    it('tracks the token', async function() {
      const token = await this.crowdsale.token();
      token.should.equal(this.token.address);
    });
  });

  describe('minted crowdsale', function() {
    it('mints tokens after purchase', async function() {
      const originalTotalSupply = await this.token.totalSupply();
      await this.crowdsale.sendTransaction({ value: ether(1), from: investor1 });
      const newTotalSupply = await this.token.totalSupply();
      assert.isTrue(newTotalSupply > originalTotalSupply);
    });
  });

  describe('capped crowdsale', async function() {
    it('has the correct hard cap', async function() {
      const cap = await this.crowdsale.cap();
      cap.should.be.bignumber.equal(this.cap);
    });
  });

  describe('timed crowdsale', function() {
    it('is open', async function() {
      const isOpen = await this.crowdsale.isOpen();
      isOpen.should.be.true;
    });

    it('is not closed yest', async function() {
      const isClosed = await this.crowdsale.hasClosed();
      isClosed.should.be.false;
    });
  });

  describe('whitelisted crowdsale', function() {
    it('rejects contributions from non-whitelisted investors', async function() {
      const notWhitelisted = _;
      await this.crowdsale.buyTokens(notWhitelisted, { value: ether(1), from: notWhitelisted }).should.be.rejectedWith(EVMRevert);
    });
  });

  describe('accepting payments', function() {
    it('should accept payments', async function() {
      const value = ether(1);
      const purchaser = investor2;
      await this.crowdsale.sendTransaction({ value: value, from: investor1 }).should.be.fulfilled;
      await this.crowdsale.buyTokens(investor1, { value: value, from: purchaser }).should.be.fulfilled;
    });
  });

  describe('buyTokens()', function() {
    describe('when the contribution is less than the minimum cap', function() {
      it('rejects the transaction', async function() {
        const value = ether(0.0001);
        await this.crowdsale.buyTokens(investor2, { value: value, from: investor2 }).should.be.rejectedWith(EVMRevert);
      });
    });

    describe('when the investor has already met the minimum cap', function() {
      it('allows the investor to contribute below the minimum cap', async function() {
        // First contribution is valid
        const value1 = ether(1);
        await this.crowdsale.buyTokens(investor1, { value: value1, from: investor1 });
        // Second contribution is less than investor cap
        const value2 = ether(0.001);
        await this.crowdsale.buyTokens(investor1, { value: value2, from: investor1 }).should.be.fulfilled;
      });
    });
  });

  describe('when the contribution is within the valid range', function () {
    const value = ether(2);
    it('succeeds & updates the contribution amount', async function () {
      await this.crowdsale.buyTokens(investor2, { value: value, from: investor2 }).should.be.fulfilled;
      const contribution = await this.crowdsale.getUserContribution(investor2);
      contribution.should.be.bignumber.equal(value);
    });
  });

});
//end of code

the results

Compiling your contracts...
===========================
> Compiling .\contracts\PFBTokenCrowdsale.sol
> Artifacts written to C:\Users\Ahmed\AppData\Local\Temp\test--10724-ZPTnk01x4uXs
> Compiled successfully using:
   - solc: 0.5.5+commit.47a71e8f.Linux.g++

web3-shh package will be deprecated in version 1.3.5 and will no longer be supported.
web3-bzz package will be deprecated in version 1.3.5 and will no longer be supported.


  Contract: PFBTokenCrowdsale
    crowdsale
      √ tracks the rate (218ms)
      √ tracks the wallet (104ms)
      √ tracks the token (151ms)
    minted crowdsale
      1) mints tokens after purchase

    Events emitted during test:
    ---------------------------

    PFBToken.MinterAdded(
      account: <indexed> 0xB4D759068d9057822baE22b77b38139b96ae2BE8 (type: address)
    )

    PFBToken.PauserAdded(
      account: <indexed> 0xB4D759068d9057822baE22b77b38139b96ae2BE8 (type: address)
    )

    PFBTokenCrowdsale.WhitelistAdminAdded(
      account: <indexed> 0xB4D759068d9057822baE22b77b38139b96ae2BE8 (type: address)
    )

    Warning: Could not decode event!

    PFBToken.MinterAdded(
      account: <indexed> 0x00344a1debD5F462a88325e923f1e75966b74206 (type: address)
    )

    PFBTokenCrowdsale.WhitelistedAdded(
      account: <indexed> 0x743c38F8d164706dF82Ab25EC8a45cCBaCfF486e (type: address)
    )

    PFBTokenCrowdsale.WhitelistedAdded(
      account: <indexed> 0xA02495B4577421D23F98565e2636c84253Cf022d (type: address)
    )


    ---------------------------
    capped crowdsale
      √ has the correct hard cap (135ms)
    timed crowdsale
      2) is open

    Events emitted during test:
    ---------------------------

    PFBToken.MinterAdded(
      account: <indexed> 0xB4D759068d9057822baE22b77b38139b96ae2BE8 (type: address)
    )

    PFBToken.PauserAdded(
      account: <indexed> 0xB4D759068d9057822baE22b77b38139b96ae2BE8 (type: address)
    )

    PFBTokenCrowdsale.WhitelistAdminAdded(
      account: <indexed> 0xB4D759068d9057822baE22b77b38139b96ae2BE8 (type: address)
    )

    Warning: Could not decode event!

    PFBToken.MinterAdded(
      account: <indexed> 0x52e3D517B63aB5A97CF8363A4E619A725ae38612 (type: address)
    )

    PFBTokenCrowdsale.WhitelistedAdded(
      account: <indexed> 0x743c38F8d164706dF82Ab25EC8a45cCBaCfF486e (type: address)
    )

    PFBTokenCrowdsale.WhitelistedAdded(
      account: <indexed> 0xA02495B4577421D23F98565e2636c84253Cf022d (type: address)
    )


    ---------------------------
      √ is not closed yest (157ms)
    whitelisted crowdsale
      √ rejects contributions from non-whitelisted investors (507ms)
    accepting payments
      3) should accept payments

    Events emitted during test:
    ---------------------------

    PFBToken.MinterAdded(
      account: <indexed> 0xB4D759068d9057822baE22b77b38139b96ae2BE8 (type: address)
    )

    PFBToken.PauserAdded(
      account: <indexed> 0xB4D759068d9057822baE22b77b38139b96ae2BE8 (type: address)
    )

    PFBTokenCrowdsale.WhitelistAdminAdded(
      account: <indexed> 0xB4D759068d9057822baE22b77b38139b96ae2BE8 (type: address)
    )

    Warning: Could not decode event!

    PFBToken.MinterAdded(
      account: <indexed> 0x1319Fa7A68870E11dE058A6cB8b64B1f581eE428 (type: address)
    )

    PFBTokenCrowdsale.WhitelistedAdded(
      account: <indexed> 0x743c38F8d164706dF82Ab25EC8a45cCBaCfF486e (type: address)
    )

    PFBTokenCrowdsale.WhitelistedAdded(
      account: <indexed> 0xA02495B4577421D23F98565e2636c84253Cf022d (type: address)
    )


    ---------------------------
    buyTokens()
      when the contribution is less than the minimum cap
        √ rejects the transaction (325ms)
      when the investor has already met the minimum cap
        4) allows the investor to contribute below the minimum cap

    Events emitted during test:
    ---------------------------

    PFBToken.MinterAdded(
      account: <indexed> 0xB4D759068d9057822baE22b77b38139b96ae2BE8 (type: address)
    )

    PFBToken.PauserAdded(
      account: <indexed> 0xB4D759068d9057822baE22b77b38139b96ae2BE8 (type: address)
    )

    PFBTokenCrowdsale.WhitelistAdminAdded(
      account: <indexed> 0xB4D759068d9057822baE22b77b38139b96ae2BE8 (type: address)
    )

    Warning: Could not decode event!

    PFBToken.MinterAdded(
      account: <indexed> 0x4f6b8385ef4c1F1C9E2bdbaea833532bD3A2e311 (type: address)
    )

    PFBTokenCrowdsale.WhitelistedAdded(
      account: <indexed> 0x743c38F8d164706dF82Ab25EC8a45cCBaCfF486e (type: address)
    )

    PFBTokenCrowdsale.WhitelistedAdded(
      account: <indexed> 0xA02495B4577421D23F98565e2636c84253Cf022d (type: address)
    )


    ---------------------------
    when the contribution is within the valid range
      5) succeeds & updates the contribution amount

    Events emitted during test:
    ---------------------------

    PFBToken.MinterAdded(
      account: <indexed> 0xB4D759068d9057822baE22b77b38139b96ae2BE8 (type: address)
    )

    PFBToken.PauserAdded(
      account: <indexed> 0xB4D759068d9057822baE22b77b38139b96ae2BE8 (type: address)
    )

    PFBTokenCrowdsale.WhitelistAdminAdded(
      account: <indexed> 0xB4D759068d9057822baE22b77b38139b96ae2BE8 (type: address)
    )

    Warning: Could not decode event!

    PFBToken.MinterAdded(
      account: <indexed> 0x8eD879B552ebDC112239B82C79387eCF06B670F8 (type: address)
    )

    PFBTokenCrowdsale.WhitelistedAdded(
      account: <indexed> 0x743c38F8d164706dF82Ab25EC8a45cCBaCfF486e (type: address)
    )

    PFBTokenCrowdsale.WhitelistedAdded(
      account: <indexed> 0xA02495B4577421D23F98565e2636c84253Cf022d (type: address)
    )


    ---------------------------


  7 passing (29s)
  5 failing

  1) Contract: PFBTokenCrowdsale
       minted crowdsale
         mints tokens after purchase:
     Error: Returned error: VM Exception while processing transaction: revert TimedCrowdsale: not open -- Reason given: TimedCrowdsale: not open.
      at Context._callee6$ (test\PFBTokenCrowdsale.test.js:188:37)
      at tryCatch (node_modules\babel-polyfill\node_modules\regenerator-runtime\runtime.js:65:40)
      at Generator.invoke [as _invoke] (node_modules\babel-polyfill\node_modules\regenerator-runtime\runtime.js:303:22)
      at Generator.prototype.<computed> [as next] (node_modules\babel-polyfill\node_modules\regenerator-runtime\runtime.js:117:21)
      at step (test\PFBTokenCrowdsale.test.js:17:191)
      at D:\Google Drive\PFB\Test\PFB_Token_Sale\test\PFBTokenCrowdsale.test.js:17:361
      at runMicrotasks (<anonymous>)
      at processTicksAndRejections (internal/process/task_queues.js:93:5)

  2) Contract: PFBTokenCrowdsale
       timed crowdsale
         is open:

      AssertionError: expected false to be true
      + expected - actual

      -false
      +true

      at Context._callee9$ (test\PFBTokenCrowdsale.test.js:256:32)
      at tryCatch (node_modules\babel-polyfill\node_modules\regenerator-runtime\runtime.js:65:40)
      at Generator.invoke [as _invoke] (node_modules\babel-polyfill\node_modules\regenerator-runtime\runtime.js:303:22)
      at Generator.prototype.<computed> [as next] (node_modules\babel-polyfill\node_modules\regenerator-runtime\runtime.js:117:21)
      at step (test\PFBTokenCrowdsale.test.js:17:191)
      at D:\Google Drive\PFB\Test\PFB_Token_Sale\test\PFBTokenCrowdsale.test.js:17:361
      at runMicrotasks (<anonymous>)
      at processTicksAndRejections (internal/process/task_queues.js:93:5)

  3) Contract: PFBTokenCrowdsale
       accepting payments
         should accept payments:
     AssertionError: expected promise to be fulfilled but it was rejected with 'Error: Returned error: VM Exception while processing transaction: revert TimedCrowdsale: not open -- Reason given: TimedCrowdsale: not open.'


  4) Contract: PFBTokenCrowdsale
       buyTokens()
         when the investor has already met the minimum cap
           allows the investor to contribute below the minimum cap:
     Error: Returned error: VM Exception while processing transaction: revert TimedCrowdsale: not open -- Reason given: TimedCrowdsale: not open.
      at Context._callee14$ (test\PFBTokenCrowdsale.test.js:365:39)
      at tryCatch (node_modules\babel-polyfill\node_modules\regenerator-runtime\runtime.js:65:40)
      at Generator.invoke [as _invoke] (node_modules\babel-polyfill\node_modules\regenerator-runtime\runtime.js:303:22)
      at Generator.prototype.<computed> [as next] (node_modules\babel-polyfill\node_modules\regenerator-runtime\runtime.js:117:21)
      at step (test\PFBTokenCrowdsale.test.js:17:191)
      at D:\Google Drive\PFB\Test\PFB_Token_Sale\test\PFBTokenCrowdsale.test.js:17:437
      at new Promise (<anonymous>)
      at Context.<anonymous> (test\PFBTokenCrowdsale.test.js:17:99)
      at processImmediate (internal/timers.js:461:21)

  5) Contract: PFBTokenCrowdsale
       when the contribution is within the valid range
         succeeds & updates the contribution amount:
     AssertionError: expected promise to be fulfilled but it was rejected with 'Error: Returned error: VM Exception while processing transaction: revert TimedCrowdsale: not open -- Reason given: TimedCrowdsale: not open.'

The block time, noting that I’m running the code on Apr 02, 2021

Transaction: 0xcbfc10f19e0b7a6f996f6c8f9d3bc1314de67092bafc426860be11c4d3032c86
  Gas usage: 27245
  Block Number: 151
  Block Time: Fri Apr 30 2021 18:51:20 GMT+0300 (Eastern European Summer Time)
1 Like

It seems like this contract does not open, so may be you can have a check for the current time and when will this contract open

2 Likes

Yes, I understand that, but what I don’t understand is why the crowd sale is not open, note that I have increased the block time for 2 weeks more and the opening date is one week from the current date.

// Advance time to crowdsale start
    await increase(duration.weeks(2));

this.openingTime = new BN(latest() + duration.weeks(1));

1 Like

I think you can print it out to check whether the time increases as you expect.

1 Like

How I can print it???

1 Like

Not sure, I think you will use Truffle + Ganache to test, so I think you can have a try as following:

blockNum = await web3.eth.getBlockNumber()
block = await web3.eth.getBlock(blockNum)
block[‘timestamp’]
1 Like

Hi @Ahmed_Awadallah,

You may want to look at the OpenZeppelin Contracts tests