it("shouldn't delete a person unless is owner", async function() {
let instance = await People.deployed();
await truffleAssert.fails(instance.deletePerson(accounts[0], { from: accounts[1]}), truffleAssert.ErrorType.REVERT);
});
it("should allow owner to delete a person", async function() {
let instance = await People.deployed();
await instance.createPerson("Doe", 70, 185, { value: web3.utils.toWei("1", "ether"), from: accounts[1] });
await truffleAssert.passes(instance.deletePerson(accounts[1], { from: accounts[0]}), truffleAssert.ErrorType.REVERT);
});
My People unit test
const People = artifacts.require('../contracts/People.sol');
const truffleAssert = require('truffle-assertions');
contract('People', (accounts) => {
let instance;
const owner = accounts[0];
const notOwner = accounts[1];
it('Should deploy smart contract', async () => {
instance = await People.deployed();
console.log(instance.address);
assert(instance.address !== '', "contract failed to deploy");
});
it('should NOT create a person with age over 150 years', async () => {
await truffleAssert.fails(instance.createPerson("Tom", 151, "5ft 11 inch", {value: web3.utils.toWei("1", "ether")}), truffleAssert.ErrorType.REVERT);
})
it('should NOT create a person without paying', async () => {
await truffleAssert.fails(instance.createPerson("Tom", 39, "5ft 11 inch"), truffleAssert.ErrorType.REVERT);
})
it('should create a person', async () => {
await truffleAssert.passes(instance.createPerson("Tom", 65, "5ft 11 inch", {value: web3.utils.toWei("1", "ether")}));
let result = await instance.getPerson();
assert(result.isSenior === true, 'the person should be senior');
assert(result.age.toNumber() === 65, 'the age should be 65');
assert(result.name === 'Tom', 'the name should be Tom');
assert(result.height === '5ft 11 inch', 'The height should be 5ft 11 inch');
})
it("should only allow 'owner' to delete a person", async () => {
await truffleAssert.fails(instance.deletePerson(owner, {from: notOwner}), truffleAssert.ErrorType.REVERT);
await truffleAssert.passes(instance.deletePerson(owner, {from: owner}))
})
});
updated to use different person object as described in the following video
it("should only allow 'owner' to delete a person", async () => {
await instance.createPerson("Somebody", 18, "5ft 10 inch", {from:notOwner, value: web3.utils.toWei("1", "ether")})
await truffleAssert.fails(instance.deletePerson(owner, {from: notOwner}), truffleAssert.ErrorType.REVERT);
await truffleAssert.passes(instance.deletePerson(owner, {from: owner}))
})
Added test around withdraw function
const People = artifacts.require('../contracts/People.sol');
const truffleAssert = require('truffle-assertions');
contract('People', (accounts) => {
let instance;
let cleanInstance;
let fee = web3.utils.toWei("1", "ether");
before(async () => {
instance = await People.deployed();
})
beforeEach(async () => {
cleanInstance = await People.new();
})
const owner = accounts[0];
const notOwner = accounts[1];
it('Should deploy smart contract', async () => {
assert(instance.address !== '', "contract failed to deploy");e
});
it('should NOT create a person with age over 150 years', async () => {
await truffleAssert.fails(instance.createPerson("Tom", 151, "5ft 11 inch", {value: fee}), truffleAssert.ErrorType.REVERT);
})
it('should NOT create a person without paying', async () => {
await truffleAssert.fails(instance.createPerson("Tom", 39, "5ft 11 inch"), truffleAssert.ErrorType.REVERT);
})
it('should create a person', async () => {
await truffleAssert.passes(instance.createPerson("Tom", 65, "5ft 11 inch", {value: fee}));
let result = await instance.getPerson();
assert(result.isSenior === true, 'the person should be senior');
assert(result.age.toNumber() === 65, 'the age should be 65');
assert(result.name === 'Tom', 'the name should be Tom');
assert(result.height === '5ft 11 inch', 'The height should be 5ft 11 inch');
})
it("should only allow 'owner' to delete a person", async () => {
await instance.createPerson("Somebody", 18, "5ft 10 inch", {
from: notOwner,
value: fee
})
await truffleAssert.fails(instance.deletePerson(owner, {from: notOwner}), truffleAssert.ErrorType.REVERT);
await truffleAssert.passes(instance.deletePerson(owner, {from: owner}))
})
it("should have correct balance", async () => {
await cleanInstance.createPerson("Tom", 65, "5ft 11 inch", {value: fee});
const balance = await cleanInstance.getContractBalance();
assert.equal(balance.valueOf(), fee, 'the balance should be 1 ether');
});
it("should not allow non-owner to withdraw", async () => {
await cleanInstance.createPerson("Tom", 65, "5ft 11 inch", {
value: fee,
from: accounts[2]
});
await truffleAssert.fails(cleanInstance.withdrawAll({from: notOwner}));
});
it("should only allow owner to withdraw", async () => {
await cleanInstance.createPerson("Tom", 65, "5ft 11 inch", {
value: fee,
from: accounts[2]
});
let beforeWithdraw = await web3.eth.getBalance(accounts[0]);
await truffleAssert.passes(cleanInstance.withdrawAll({from: owner}), 'The owner should be able to withdraw');
const actualBalance = await web3.eth.getBalance(accounts[0]);
console.log("balance before withdraw: " + beforeWithdraw + "\nbalance afetr: " + actualBalance)
assert(beforeWithdraw < actualBalance, 'the balance should include the withdrawn fees')
});
});
it("should update contract balance", async function() {
let instance = await People.new();
let initialBalance = await instance.balance();
assert(initialBalance.toString() === web3.utils.toWei("0", "ether"));
assert(await web3.eth.getBalance(instance.address) === "0");
await instance.createPerson("Doe", 70, 185, { value: web3.utils.toWei("1", "ether"), from: accounts[1] });
assert(await web3.eth.getBalance(instance.address) === web3.utils.toWei("1", "ether"), "Contract balance not set correctly");
});
it("should allow owner to withraw all", async function() {
let instance = await People.new();
await instance.createPerson("Doe", 70, 185, { value: web3.utils.toWei("1", "ether"), from: accounts[1] });
let initialBalance = await web3.eth.getBalance(accounts[0]);
await instance.withdrawAll({ from: accounts[0] });
let instanceBalance = await instance.balance();
assert(instanceBalance.toString() === web3.utils.toWei("0", "ether"));
assert(await web3.eth.getBalance(instance.address) === web3.utils.toWei("0", "ether"), "Contract balance not empty after withdraw");
assert(await web3.eth.getBalance(accounts[0]) > initialBalance, "Owner contract balance not updated after withdraw");
});
Took me a while, but I got it to work! Here is my solution for testing the deletePerson function:
it("Owner should be able to delete person", async function () {
let instance = await People.deployed();
await instance.createPerson("Albert", 35, 180, {from: accounts[1], value: web3.utils.toWei("1", "ether")})
await truffleAssert.passes(instance.deletePerson(accounts[1], {from: accounts[0]}), truffleAssert.ErrorType.REVERT);
});
it("Non-owner should not be able to delete person", async function () {
let instance = await People.deployed();
await instance.createPerson("Mya", 50, 160, { from: accounts[1], value: web3.utils.toWei("1", "ether") });
await truffleAssert.fails(instance.deletePerson(accounts[1], {from: accounts[1]}), truffleAssert.ErrorType.REVERT);
});
This is for the Value Assignment
Unit Testing. Not sure about the last 2 unit tests (Check Balance after withdrawal?) .
});
it("should reduce account by 1 Eth after person created", async function(){
let instance = await People.new();
await instance.createPerson("Genni", 35, 54,
{from: accounts[1], value: web3.utils.toWei("1", "ether")});
let balance = await instance.balance();
let oldBalance = parseFloat(balance);
let newBalance = await web3.eth.getBalance(instance.address);
assert(oldBalance == web3.utils.toWei("1", "ether") && oldBalance == newBalance)
});
it("should only allow the owner to withdraw balance", async function(){
let instance = await People.new();
await instance.createPerson("Dave", 52, 510,
{from: accounts[2], value: web3.utils.toWei("1", "ether")});
await truffleAssert.passes(instance.withdrawAll(
{from: accounts[0]}));
});
it("should not allow a non-owner to withdraw balance", async function(){
let instance = await People.new();
await instance.createPerson("Genni", 35, 54,
{from: accounts[1], value: web3.utils.toWei("1", "ether")});
await truffleAssert.fails(instance.withdrawAll(
{from: accounts[2]}), truffleAssert.ErrorType.REVERT);
});
});
Owner Test Assignment
contract(âPeopleâ, async function(accounts) {
it("shouldn't be possible to delete a person without beeing the owner", async function() {
let instance = await People.deployed();
await instance.createPerson("frodo", 135, 50, {value: web3.utils.toWei("1", "ether"), from : accounts[2]});
await truffleAssert.fails(instance.deletePerson(accounts[2],{from: accounts[1]}), truffleAssert.ErrorType.REVERT);
});
it("should be possible to delete a person from the owner", async function() {
let instance = await People.deployed();
await instance.deletePerson(accounts[2],{from: accounts[0]});
let result = await instance.getPerson({from: accounts[2]});
assert(result.name === "" && result.age == 0, "Person was NOT deleted");
});
} );
it("should delete person", async function(accounts){
let instance = await People.deployed();
await instance.deletePerson(accounts[2], {from: accounts[0]});
let result = await instance.getPerson(accounts[0]);
assert(result.name === "Bob", "person not deleted")
});
Hi,
I want to understand the search terms to google while solving assignments.
For eg while finding the solution for the deletePerson
assignment what would be some of the search terms inorder to find passes
assertion property.
it("should find contract address", async function(){
let instance = await People.new();
let initialBalance = await instance.balance();
var contractAbi = web3.eth.contract(People.abi);
let contractAddress = contractAbi.at("address");
assert(initialBalance.toString() === web3.utils.toWei("0", "ether"));
assert(await web3.eth.getBalance(contractAddress) === "0");
await instance.createPerson("Ramesh", 25, 195, { value: web3.utils.toWei("1", "ether"), from: accounts[1] });
assert(await web3.eth.getBalance(contractAddress) === web3.utils.toWei("1", "ether"), "Contract balance is wrong");
initialBalance += await web3.eth.getBalance(initialBalance);
await initialBalance.withdrawAll(contractAddress, { from: accounts[0] });
});
Here is my solution for the value assignment:
//When a person gets added, the balance of the contract gets increased and the balance variable matches the balance that is registered on the blockchain
it("The balance should increase when a new person gets created", async function () {
let priorBalance = await web3.eth.getBalance(People.address);
await instance.createPerson("Alexander", 100, 195, { value: web3.utils.toWei("1", "ether") });
let newBalance = await web3.eth.getBalance(People.address);
assert(parseInt(newBalance) === parseInt(priorBalance) + parseInt(web3.utils.toWei("1", "ether")), "The balance did not increase");
});
it("The balance on the blockchain should match the contract's internal balance variable", async function () {
await instance.createPerson("Peter", 45, 127, { value: web3.utils.toWei("1", "ether") });
let contractBalance = await instance.balance(); //Why paretheses after balance? Not a function.
let blockchainBalance = await web3.eth.getBalance(People.address);
assert(parseInt(contractBalance) === parseInt(blockchainBalance), "The contract balance does not match the internal balance variable");
});
//The contract owner can withdraw the balance, the balance is reduced to 0, the balance variable matches the balance on the blockchain, and the owner's balance increases
it("The contract owner can withdraw the balance", async function () {
await instance.createPerson("Napoleon", 149, 300, { value: web3.utils.toWei("1", "ether") });
await truffleAssert.passes(instance.withdrawAll({ from: accounts[0] }), truffleAssert.ErrorType.REVERT);
});
it("When the contract owner withdraws the balance, the balance is reduced to 0 and the balance matches the internal balance variable", async function () {
await instance.createPerson("Allison", 33, 120, { value: web3.utils.toWei("1", "ether") });
await instance.withdrawAll();
let contractBalance = await instance.balance()
let blockchainBalance = await web3.eth.getBalance(People.address);
assert(parseInt(blockchainBalance) === 0 && parseInt(contractBalance) === parseInt(blockchainBalance), "The balance was not reduced to 0, the internal balance variable does not match the on-chain balance");
});
it("When the contract owner withdraws the balance, their balance increases", async function () {
await instance.createPerson("Allison", 33, 120, { value: web3.utils.toWei("1", "ether") });
let priorOwnerBalance = await web3.eth.getBalance(accounts[0]);
await instance.withdrawAll();
let newOwnerBalance = await web3.eth.getBalance(accounts[0]);
assert(parseInt(newOwnerBalance) > parseInt(priorOwnerBalance), "The owner's balance did not increasee");
});
@filip, I have a syntax question. One thing I still donât understand is why we need to use parentheses when we reference the contract balance variable that we declared in the contract:
let contractBalance = await instance.balance()
Isnât that syntax reserved for functions? Why is using instance.balance not legitimate?
If you set the visibility of a variable to âpublicâ, Solidity will automatically create for you a getter function, which is indeed what you call by doing await instance.balance()
.
Docs: https://docs.soliditylang.org/en/develop/contracts.html#visibility-and-getters
Ah, thatâs what I was forgetting! Thank you!
Thanks, I did this and cleared the first error. Now this:
Compiling your contractsâŚ
Compiling .\contracts\Migrations.sol
Success
Contract: Helloworld
1) should initialize correctly
> No events were emitted
0 passing (416ms)
1 failing
- Contract: Helloworld
should initialize correctly:
AssertionError: Unspecified AssertionError
at Context. (test\helloworldtest.js:10:5)
at process._tickCallback (internal/process/next_tick.js:68:7)
This works, but it shouldnât:
assert(message != âHello Again!â);
Here is my Helloworld_deploy.js â looks identical to Filipâs
const Helloworld = artifacts.require(âHelloworldâ);
module.exports = function(deployer, network, accounts){
deployer.deploy(Helloworld).then(function(instance){
// Value is in wei, not Ether
instance.setMessage(âHello again!â, {value: 1000000, from: accounts[0]}).then(function(){
console.log(âSuccessâ);
//instance.getMessage().then(function(message){
// console.log("Current message: " + message);
}).catch(function(err){
console.log("error: " + err);
});
}).catch(function(err){
console.log("Deploy failed " + err);
});
};
Ha, I must have looked at this 20 times: âHello again!â != âHello Again!â
Value Assignment
const People = artifacts.require(âPeopleâ);
const truffleAssert= require(âtruffle-assertionsâ);
contract(âPeopleâ, async function(accounts){
it("Contractâs balance & user balance should update correctly ", async function(){
let instance= await People.deployed();
let contractAddress= await People.address;
let userBal= await web3.eth.getBalance(accounts[1]);
let contractBal= await web3.eth.getBalance(contractAddress);
await instance.createPerson(âBettyâ, 32, 165,{value: web3.utils.toWei(â1â,âetherâ), from: accounts[1]});
let userBalUpdate= await web3.eth.getBalance(accounts[1]);
let contractBalUpdate= await web3.eth.getBalance(contractAddress);
assert((userBalUpdate<userBal)&&(contractBalUpdate>contractBal),âBalance not updating correctlyâ);
});
it(âBalance should be zero after owner withdrawallâ, async function(){
let instance= await People.new();
let contractAddress= await instance.address;
await instance.createPerson(âMiamiâ, 28, 165, {value: web3.utils.toWei(â1â,âetherâ), from: accounts[1]});
let contractBal= await web3.eth.getBalance(contractAddress);
await truffleAssert.passes(instance.withdrawAll(),âWithdraw failâ);
await truffleAssert.passes(contractBal.toString()===â0â,âcontract balance is not zeroâ);
});
});
Re the example video, it seems that because the return value of the Github People file is a tuple/array of values, I found it useful to put in a small edit so the returned senior bool value was checked via âresult[3]â rather than âresult[senior]â
//Owner Test Assignment, my try:
const People = artifacts.require(âPeopleâ);
const truffleAssert = require(âtruffle-assertionsâ);
contract(âPeopleâ, async function(accounts){
it (âshouldnât create a person with age over 150 yearsâ, async function(){
let instance = await People.deployed();
await truffleAssert.fails(instance.createPerson(âBobâ,200,190, {value:web3.utils.toWei(â1â, âetherâ)}),
truffleAssert.ErrorType.REVERT);
//if the above doesnât fail we have an error;
});
it (âshouldnât create a person without paymentâ, async function(){
let instance = await People.deployed();
await truffleAssert.fails(instance.createPerson(âBobâ,50,190, {value:1000}),
truffleAssert.ErrorType.REVERT);
//if the above doesnât fail we have an error;
});
it (âshould set senior status correctlyâ, async function(){
let instance = await People.deployed();
await instance.createPerson(âBobâ,65,190, {value:web3.utils.toWei(â1â,âEtherâ)});
let result = await instance.getPerson();
assert(result[3] === true, âSenior level not setâ);
//if the above doesnât fail we have an error;
});
it (âshould not allow non-owners to withdraw all fundsâ, async function(){
let instance = await People.deployed();
await truffleAssert.fails(instance.withdrawAll({from:accounts[1]}));
});
it (âshould allow owner to withdraw all fundsâ, async function(){
let instance = await People.deployed();
await truffleAssert.passes(instance.withdrawAll({from:accounts[0]}));
});
});
//value assignmentâŚ
const People = artifacts.require(âPeopleâ);
const truffleAssert = require(âtruffle-assertionsâ);
contract(âPeopleâ, async function(accounts){
it (âshouldnât create a person with age over 150 yearsâ, async function(){
let instance = await People.deployed();
await truffleAssert.fails(instance.createPerson(âBobâ,200,190, {value:web3.utils.toWei(â1â, âetherâ)}),
truffleAssert.ErrorType.REVERT);
//if the above doesnât fail we have an error;
});
it (âshouldnât create a person without paymentâ, async function(){
let instance = await People.deployed();
await truffleAssert.fails(instance.createPerson(âBobâ,50,190, {value:1000}),
truffleAssert.ErrorType.REVERT);
//if the above doesnât fail we have an error;
});
it (âshould set senior status correctlyâ, async function(){
let instance = await People.deployed();
await instance.createPerson(âBobâ,65,190, {value:web3.utils.toWei(â1â,âEtherâ)});
let result = await instance.getPerson();
assert(result[3] === true, âSenior level not setâ);
//if the above doesnât fail we have an error;
});
it (âshould not allow non-owner to delete peopleâ, async function(){
let instance = await People.deployed();
await instance.createPerson(âLisaâ, 35, 160, {from: accounts[1], value: web3.utils.toWei(â1â,âetherâ)});
await truffleAssert.fails(instance.deletePerson(accounts[1], {from: accounts[1]}), truffleAssert.ErrorType.REVERT);
});
it (âshould allow owner to delete peopleâ, async function(){
let instance = await People.new();
await instance.createPerson(âLisaâ, 35, 160, {from: accounts[1], value: web3.utils.toWei(â1â,âetherâ)});
await truffleAssert.paases(instance.deletePerson(accounts[1], {from: accounts[0]}), truffleAssert.ErrorType.REVERT);
});
/*
using this.address for the assignment
else use let instace = await People.deployed();
let contractAddress = await instance.address;
*/
it ("should increment the reconciled contract balance upon adding a person", async function(){
let instance = await People.deployed();
let contractAddress = await instance.address;
let initialBalance = await web3.eth.getBalance(contractAddress);
await assert (web3.eth.getBalance(contractAddress) === instance.balance, "-initial balances reconcile...");
await instance.createPerson("Lisa", 35, 160, {from: accounts[1], value: web3.utils.toWei("1","ether")});
let currentBalance = await instance.balance;
assert (currentBalance === initialBalance + web3.utils.toWei("1","ether"), "-balance not up by 1 ether...");
assert (currentBalance === web3.eth.getBalance(contractAddress), "-contract balance data not reconciled to blockchain.");
})
it ("should not allow non-owners to withdraw all funds", async function(){
let instance = await People.deployed();
await truffleAssert.fails(instance.withdrawAll({from:accounts[1]}),"funds withdrawn by non-owner");
});
it ("should allow owner to withdraw all funds", async function(){
let instance = await People.deployed();
let contractAddress = await instance.address;
let initialBalance = await web3.eth.getBalance(contractAddress);
let initialOwnerBalance = await web3.eth.getBalance(accounts[0]);
await assert (web3.eth.getBalance(contractAddress) === instance.balance, "-initial balances reconcile..");
await truffleAssert.passes(instance.withdrawAll({from:accounts[0]}), "funds not withdrawable by owner");
let currentBalance = await instance.balance;
assert (currentBalance === 0, "-contract balance not settled...");
await assert (currentBalance === web3.eth.getBalance(contractAddress), "-contract balance data not reconciled to blockchain.");
await assert ( web3.eth.getBalance(accounts[0]) === initialBalance + initialOwnerBalance, "-owner not credited all the funds");
});
});