You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
156 lines
6.3 KiB
JavaScript
156 lines
6.3 KiB
JavaScript
2 years ago
|
const { deployContract, getBlockTimestamp, mineBlockTimestamp } = require('../helpers.js');
|
||
|
const { expect } = require('chai');
|
||
|
const { constants } = require('@openzeppelin/test-helpers');
|
||
|
const { ZERO_ADDRESS } = constants;
|
||
|
|
||
|
const createTestSuite = ({ contract, constructorArgs }) =>
|
||
|
function () {
|
||
|
context(`${contract}`, function () {
|
||
|
beforeEach(async function () {
|
||
|
this.erc4097a = await deployContract(contract, constructorArgs);
|
||
|
});
|
||
|
|
||
|
describe('EIP-165 support', async function () {
|
||
|
it('supports ERC165', async function () {
|
||
|
expect(await this.erc4097a.supportsInterface('0x01ffc9a7')).to.eq(true);
|
||
|
});
|
||
|
|
||
|
it('supports IERC721', async function () {
|
||
|
expect(await this.erc4097a.supportsInterface('0x80ac58cd')).to.eq(true);
|
||
|
});
|
||
|
|
||
|
it('supports ERC721Metadata', async function () {
|
||
|
expect(await this.erc4097a.supportsInterface('0x5b5e139f')).to.eq(true);
|
||
|
});
|
||
|
|
||
|
it('supports ERC4907', async function () {
|
||
|
expect(await this.erc4097a.supportsInterface('0xad092b5c')).to.eq(true);
|
||
|
});
|
||
|
|
||
|
it('does not support random interface', async function () {
|
||
|
expect(await this.erc4097a.supportsInterface('0x00000042')).to.eq(false);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
context('with minted tokens', async function () {
|
||
|
beforeEach(async function () {
|
||
|
const [owner, addr1] = await ethers.getSigners();
|
||
|
this.owner = owner;
|
||
|
this.addr1 = addr1;
|
||
|
|
||
|
await this.erc4097a['mint(address,uint256)'](this.owner.address, 1);
|
||
|
await this.erc4097a['mint(address,uint256)'](this.addr1.address, 2);
|
||
|
|
||
|
this.expires = (await getBlockTimestamp()) + 123;
|
||
|
this.tokenId = 2;
|
||
|
this.user = this.owner;
|
||
|
});
|
||
|
|
||
|
it('explicitUserOf returns zero address after minting', async function () {
|
||
|
expect(await this.erc4097a.explicitUserOf(0)).to.equal(ZERO_ADDRESS);
|
||
|
expect(await this.erc4097a.explicitUserOf(1)).to.equal(ZERO_ADDRESS);
|
||
|
expect(await this.erc4097a.explicitUserOf(2)).to.equal(ZERO_ADDRESS);
|
||
|
});
|
||
|
|
||
|
it('userOf returns zero address after minting', async function () {
|
||
|
expect(await this.erc4097a.userOf(0)).to.equal(ZERO_ADDRESS);
|
||
|
expect(await this.erc4097a.userOf(1)).to.equal(ZERO_ADDRESS);
|
||
|
expect(await this.erc4097a.userOf(2)).to.equal(ZERO_ADDRESS);
|
||
|
});
|
||
|
|
||
|
it('userExpires returns zero timestamp after minting', async function () {
|
||
|
expect(await this.erc4097a.userExpires(0)).to.equal(0);
|
||
|
expect(await this.erc4097a.userExpires(1)).to.equal(0);
|
||
|
expect(await this.erc4097a.userExpires(2)).to.equal(0);
|
||
|
});
|
||
|
|
||
|
describe('setUser', async function () {
|
||
|
beforeEach(async function () {
|
||
|
this.setUser = async () => await this.erc4097a.connect(this.addr1)
|
||
|
.setUser(this.tokenId, this.user.address, this.expires);
|
||
|
|
||
|
this.setupAuthTest = async () => {
|
||
|
this.tokenId = 0;
|
||
|
await expect(this.setUser()).to.be.revertedWith('SetUserCallerNotOwnerNorApproved');
|
||
|
};
|
||
|
});
|
||
|
|
||
|
it('correctly changes the return value of explicitUserOf', async function () {
|
||
|
await this.setUser();
|
||
|
expect(await this.erc4097a.explicitUserOf(this.tokenId)).to.equal(this.user.address);
|
||
|
});
|
||
|
|
||
|
it('correctly changes the return value of userOf', async function () {
|
||
|
await this.setUser();
|
||
|
expect(await this.erc4097a.userOf(this.tokenId)).to.equal(this.user.address);
|
||
|
});
|
||
|
|
||
|
it('correctly changes the return value of expires', async function () {
|
||
|
await this.setUser();
|
||
|
expect(await this.erc4097a.userExpires(this.tokenId)).to.equal(this.expires);
|
||
|
});
|
||
|
|
||
|
it('emits the UpdateUser event properly', async function () {
|
||
|
await expect(await this.setUser())
|
||
|
.to.emit(this.erc4097a, 'UpdateUser')
|
||
|
.withArgs(this.tokenId, this.user.address, this.expires);
|
||
|
});
|
||
|
|
||
|
it('reverts for an invalid token', async function () {
|
||
|
this.tokenId = 123;
|
||
|
await expect(this.setUser()).to.be.revertedWith('OwnerQueryForNonexistentToken');
|
||
|
});
|
||
|
|
||
|
it('requires token ownership', async function () {
|
||
|
await this.setupAuthTest();
|
||
|
await this.erc4097a.transferFrom(this.owner.address, this.addr1.address, this.tokenId);
|
||
|
await this.setUser();
|
||
|
});
|
||
|
|
||
|
it('requires token approval', async function () {
|
||
|
await this.setupAuthTest();
|
||
|
await this.erc4097a.approve(this.addr1.address, this.tokenId);
|
||
|
await this.setUser();
|
||
|
});
|
||
|
|
||
|
it('requires operator approval', async function () {
|
||
|
await this.setupAuthTest();
|
||
|
await this.erc4097a.setApprovalForAll(this.addr1.address, 1);
|
||
|
await this.setUser();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('after expiry', async function () {
|
||
|
beforeEach(async function () {
|
||
|
await this.erc4097a.connect(this.addr1)
|
||
|
.setUser(this.tokenId, this.user.address, this.expires);
|
||
|
});
|
||
|
|
||
|
it('userOf returns zero address after expires', async function () {
|
||
|
expect(await this.erc4097a.userOf(this.tokenId)).to.equal(this.user.address);
|
||
|
await mineBlockTimestamp(this.expires);
|
||
|
expect(await this.erc4097a.userOf(this.tokenId)).to.equal(this.user.address);
|
||
|
await mineBlockTimestamp(this.expires + 1);
|
||
|
expect(await this.erc4097a.userOf(this.tokenId)).to.equal(ZERO_ADDRESS);
|
||
|
});
|
||
|
|
||
|
it('explicitUserOf returns correct address after expiry', async function () {
|
||
|
expect(await this.erc4097a.explicitUserOf(this.tokenId)).to.equal(this.user.address);
|
||
|
await mineBlockTimestamp(this.expires);
|
||
|
expect(await this.erc4097a.explicitUserOf(this.tokenId)).to.equal(this.user.address);
|
||
|
await mineBlockTimestamp(this.expires + 1);
|
||
|
expect(await this.erc4097a.explicitUserOf(this.tokenId)).to.equal(this.user.address);
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
};
|
||
|
|
||
|
describe(
|
||
|
'ERC4907A',
|
||
|
createTestSuite({
|
||
|
contract: 'ERC4907AMock',
|
||
|
constructorArgs: ['Azuki', 'AZUKI'],
|
||
|
})
|
||
|
);
|