Jumping into Solidity — The ERC721 Standard (Part 8)

“person pouring purple liquid on clear glass container” by Louis Reed on Unsplash

The Set-up

Today I’ll be using NodeJS, with the Mocha test framework. We’ll also be making use of Web3 and ganache-cli.

Token_Metadata.test.js

const compiledToken = require('../ethereum/build/TokenERC721.json');
const compiledToken = require('../ethereum/build/TokenERC721Metadata.json');
constructor(uint _initialSupply, string _name, string _symbol, string _uriBase)
const _name = "SomeTokenName";
const _symbol = "STN";
const _uriBase = "someTokenName.uri/";
arguments: [initialTokens]
arguments: [initialTokens,_name,_symbol,_uriBase]

A few extra Metadata tests

it('Correct token name is reported', async () => {
const name_reported = await token.methods.name().call();

assert(_name == name_reported);
});
it('Correct token symbol is reported', async () => {
const symbol_reported = await token.methods.symbol().call();

assert(_symbol == symbol_reported);
});
it('Correct tokenURI is reported',async() => {
var tokenId = '1';
const tokenURI_reported = await token.methods.tokenURI(tokenId).call();
const tokenURI_expected = _uriBase + tokenId;
assert(tokenURI_expected == tokenURI_reported);
});

Token_Enumerable.test.js

const compiledToken = require('../ethereum/build/TokenERC721.json');
const compiledToken = require('../ethereum/build/TokenERC721Enumerable.json');

A few extra Enumerable tests

it("Reported total supply is accurate for initial supply", async() => {
const totalSupply_reported = await token.methods.totalSupply().call();
assert(totalSupply_reported == initialTokens);
});
it("Reported total supply is accurate after minting extra tokens", async() => {
const toIssue = 2;
const owner = accounts[0];
await token.methods.issueTokens(toIssue).send({
from: owner,
gas:'8000000'
});
const totalSupply_expected = initialTokens + toIssue;

const totalSupply_reported = await token.methods.totalSupply().call();
assert(totalSupply_reported == totalSupply_expected);
});
it("Reported total supply is accurate after burning a token", async() => {
//Remember, this burns an individual token, not a group of tokens.
const tokenToBurn = '2'; //2 is the tokenId
const owner = accounts[0];
await token.methods.burnToken(tokenToBurn).send({
from: owner,
gas:'8000000'
});

const totalSupply_expected = initialTokens - 1;

const totalSupply_reported = await token.methods.totalSupply().call();
assert(totalSupply_reported == totalSupply_expected);
});
it("Initially reports correct tokenByIndex", async() => {
let tokenId_expected, tokenId_reported;
for(var i = 0; i < initialTokens; i++){
tokenId_expected = String(i + 1);
tokenId_reported = await token.methods.tokenByIndex(i).call();
assert(tokenId_expected == tokenId_reported);
}
});
it("Reports correct tokenByIndex after minting extra tokens", async() => {
const toIssue = 2;
const owner = accounts[0];
await token.methods.issueTokens(toIssue).send({
from: owner,
gas:'8000000'
});

let tokenId_expected, tokenId_reported;
for(var i = 0; i < initialTokens + toIssue; i++){
tokenId_expected = String(i + 1);
tokenId_reported = await token.methods.tokenByIndex(i).call();
assert(tokenId_expected == tokenId_reported);
}
});
[1,10,3,4,5,6,7,8,9]
it("Reports correct tokenByIndex after burning a token", async() => {
const tokenToBurn = '2'; //2 is the tokenId
const owner = accounts[0];
await token.methods.burnToken(tokenToBurn).send({
from: owner,
gas:'8000000'
});

const tokenIds_expected = ['1','10','3','4','5','6','7','8','9'];

let tokenId_expected, tokenId_reported;
for(var i = 0; i < tokenIds_expected.length; i++){
tokenId_expected = tokenIds_expected[i];
tokenId_reported = await token.methods.tokenByIndex(i).call();
assert(tokenId_expected == tokenId_reported);
}
});
it("Initially reports correct tokenOfOwnerByIndex", async() => {
const owner = accounts[0];
let tokenId_expected, tokenId_reported;
for(var i = 0; i < initialTokens; i++){
tokenId_expected = String(i + 1);
tokenId_reported = await token.methods.tokenOfOwnerByIndex(owner,i).call();
assert(tokenId_expected == tokenId_reported);
}
});
it("Reports correct tokenOfOwnerByIndex after minting extra tokens", async() => {
const toIssue = 2;
const owner = accounts[0];
await token.methods.issueTokens(toIssue).send({
from: owner,
gas:'8000000'
});

let tokenId_expected, tokenId_reported;
for(var i = 0; i < initialTokens + toIssue; i++){
tokenId_expected = String(i + 1);
tokenId_reported = await token.methods.tokenOfOwnerByIndex(owner,i).call();
assert(tokenId_expected == tokenId_reported);
}
});
it("Reports correct tokenOfOwnerByIndex after burning a token", async() => {
const tokenToBurn = '2'; //2 is the tokenId
const owner = accounts[0];
await token.methods.burnToken(tokenToBurn).send({
from: owner,
gas:'8000000'
});

const tokenIds_expected = ['1','10','3','4','5','6','7','8','9'];

let tokenId_expected, tokenId_reported;
for(var i = 0; i < tokenIds_expected.length; i++){
tokenId_expected = tokenIds_expected[i];
tokenId_reported = await token.methods.tokenOfOwnerByIndex(owner,i).call();
assert(tokenId_expected == tokenId_reported);
}
});
it("Reports correct tokenOfOwnerByIndex after transferring tokens", async() => {
const person_A = accounts[0];
const person_B = accounts[1];

//Person A sends token 2 to Person B
await token.methods.transferFrom(person_A,person_B,'2').send({
from: person_A,
gas:'8000000'
});
//Person A sends token 4 to Person B
await token.methods.transferFrom(person_A,person_B,'4').send({
from: person_A,
gas:'8000000'
});
//Person B sends token 2 back to Person A
await token.methods.transferFrom(person_B,person_A,'2').send({
from: person_B,
gas:'8000000'
});

const tokenIds_expected_A = ['1','10','3','9','5','6','7','8','2'];
const tokenIds_expected_B = ['4'];

let tokenId_reported, tokenId_expected;
for(let i = 0; i < tokenIds_expected_A.length; i++){
tokenId_expected = tokenIds_expected_A[i];
tokenId_reported = await token.methods.tokenOfOwnerByIndex(person_A,i).call();
assert(tokenId_expected == tokenId_reported);
}
for(let i = 0; i < tokenIds_expected_B.length; i++){
tokenId_expected = tokenIds_expected_B[i];
tokenId_reported = await token.methods.tokenOfOwnerByIndex(person_B,i).call();
assert(tokenId_expected == tokenId_reported);
}
});

Wrapping up

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store