Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: passing a string "Caller" instead of "caller" inside of expectRevert() triggers error #190

Open
tesla809 opened this issue Jun 9, 2022 · 0 comments

Comments

@tesla809
Copy link

tesla809 commented Jun 9, 2022

Summary:

When using `expectRevert()`, the passing the string: "Ownable: Caller is not the owner", instead of "Ownable: caller is not the owner" will trigger an error.

The distinction is in the capitalized C in caller.

Context:

While doing Learn section in OpenZeppelin tutorial, stumbled upon error in performing-complex-assertions section of writing-automated-tests.

I find it strange that passing a capitalized letter in a string parameter would trigger an error.

Error:

Caller is capitalized causing unexpected error.

  it("non owner cannot store a value", async function () {
    // Test a transaction reverts
    await expectRevert(
      this.box.setter(value, { from: other }),
      // note using Caller instead of caller will trigger error
      "Ownable: Caller is not the owner"
    );
  });

Solution:

Caller is not capitalized. No error.

  it("non owner cannot store a value", async function () {
    // Test a transaction reverts
    await expectRevert(
      this.box.setter(value, { from: other }),
      // note using Caller insted of caller will trigger error
      "Ownable: caller is not the owner"
    );
  });

Error message:

Using network 'development'.


Compiling your contracts...
===========================
> Everything is up to date, there is nothing to compile.



  Contract: Box
    ✓ getter returns a value previously stored
    ✓ setter emits an event
    1) non owner cannot store a value

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

    Box.OwnershipTransferred(
      previousOwner: <indexed> 0x0000000000000000000000000000000000000000 (type: address),
      newOwner: <indexed> 0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1 (type: address)
    )


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


  2 passing (267ms)
  1 failing

  1) Contract: Box
       non owner cannot store a value:

      Wrong kind of exception received
      + expected - actual

      -Transaction: 0x07151ccfcbc657daafc2c553c0b7c068a40d3cc31f699c793e65d1f4db18feef exited with an error (status 0). Reason given: Ownable: caller is not the owner.
      -     Please check that the transaction:
      -     - satisfies all conditions set by Solidity `require` statements.
      -     - does not trigger a Solidity `revert` statement.
      +Ownable: Caller is not the owner
      
      at expectException (/Users/devrel/Desktop/Code/OZTutorial/node_modules/@openzeppelin/test-helpers/src/expectRevert.js:20:30)
      at processTicksAndRejections (node:internal/process/task_queues:96:5)
      at expectRevert (/Users/devrel/Desktop/Code/OZTutorial/node_modules/@openzeppelin/test-helpers/src/expectRevert.js:75:3)
      at Context.<anonymous> (Box.test.js:50:5)

Steps to reproduce error:

  1. Have smart contract and testing code from Learn section. Small note:retrieve() is named getter, store() is named setter(), reciept variable is named setterReciept.

  2. run truffle test
    npx truffle test

  3. Become a bug enjoyer.

Entire code code context

Box.test.js

// test/Box.test.js
// Load dependencies
const { expect } = require("chai");

// Import utilities from openzepplin/test-helpers
const { BN, expectEvent, expectRevert } = require("@openzeppelin/test-helpers");

// Load compiled artifacts
const Box = artifacts.require("Box");

// Start test block
// passing addresses: owner, other
contract("Box", function ([owner, other]) {
  // Make available in large integers ('big numbers) in all tests
  // since at top of scope
  const value = new BN("42");

  beforeEach(async function () {
    // Deploy a new Box contract for each test
    // from owner address
    this.box = await Box.new({ from: owner });
  });

  // Test cases
  it("getter returns a value previously stored", async function () {
    // Store a value sent by owner
    await this.box.setter(value, { from: owner });

    // check bignumber equality of number stored vs set
    // not not needing to use strings to compare 256bit integers like below
    expect(await this.box.getter()).to.be.bignumber.equal(value);

    // old assertion
    // expect((await this.box.getter()).toString()).to.equal("42");
  });

  it("setter emits an event", async function () {
    // set value from owner address and save reciept
    const setterReciept = await this.box.setter(value, { from: owner });

    // test ValueChanged event was emitted on setter() call
    // note key-value pair: key = value, value = value
    // just a coicidence they are named the same
    // key will always be value.
    expectEvent(setterReciept, "ValueChanged", { value: value });
  });

  it("non owner cannot store a value", async function () {
    // Test a transaction reverts
    await expectRevert(
      this.box.setter(value, { from: other }),
      // note using Caller instead of caller will trigger error
      "Ownable: Caller is not the owner"
    );
  });
});

Box.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

// Import Auth from access control sub-directory
// import "./access-control/Auth.sol";

// Import Ownable from the OpenZeppelin Contracts
import "@openzeppelin/contracts/access/Ownable.sol";

// Make Box inherit from the Ownable contract
contract Box is Ownable {
  uint256 private _value; // private value, statically typed
  
  // Emit event when stored value changes
  event ValueChanged(uint256 value);

  // old Auth.sol contract
  // constructor() {
  //   _auth = new Auth(msg.sender);
  // }

// uses onlyOwner function modifier from Ownable
  function setter(uint256 value) public onlyOwner {
    // old Auth.sol contract
    // // Require caller be registered as administrator in Auth  
    // require(_auth.isAdministrator(msg.sender), "Unauthorized");

    _value = value;
    emit ValueChanged(value);
  }

  function getter() public view returns(uint256) {
    return _value;
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant