ERC721URIStorage.test.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. const { ethers } = require('hardhat');
  2. const { expect } = require('chai');
  3. const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers');
  4. const { shouldSupportInterfaces } = require('../../../utils/introspection/SupportsInterface.behavior');
  5. const name = 'Non Fungible Token';
  6. const symbol = 'NFT';
  7. const baseURI = 'https://api.example.com/v1/';
  8. const otherBaseURI = 'https://api.example.com/v2/';
  9. const sampleUri = 'mock://mytoken';
  10. const tokenId = 1n;
  11. const nonExistentTokenId = 2n;
  12. async function fixture() {
  13. const [owner] = await ethers.getSigners();
  14. const token = await ethers.deployContract('$ERC721URIStorageMock', [name, symbol]);
  15. return { owner, token };
  16. }
  17. contract('ERC721URIStorage', function () {
  18. beforeEach(async function () {
  19. Object.assign(this, await loadFixture(fixture));
  20. });
  21. shouldSupportInterfaces(['0x49064906']);
  22. describe('token URI', function () {
  23. beforeEach(async function () {
  24. await this.token.$_mint(this.owner, tokenId);
  25. });
  26. it('it is empty by default', async function () {
  27. expect(await this.token.tokenURI(tokenId)).to.equal('');
  28. });
  29. it('reverts when queried for non existent token id', async function () {
  30. await expect(this.token.tokenURI(nonExistentTokenId))
  31. .to.be.revertedWithCustomError(this.token, 'ERC721NonexistentToken')
  32. .withArgs(nonExistentTokenId);
  33. });
  34. it('can be set for a token id', async function () {
  35. await this.token.$_setTokenURI(tokenId, sampleUri);
  36. expect(await this.token.tokenURI(tokenId)).to.equal(sampleUri);
  37. });
  38. it('setting the uri emits an event', async function () {
  39. await expect(this.token.$_setTokenURI(tokenId, sampleUri))
  40. .to.emit(this.token, 'MetadataUpdate')
  41. .withArgs(tokenId);
  42. });
  43. it('setting the uri for non existent token id is allowed', async function () {
  44. await expect(await this.token.$_setTokenURI(nonExistentTokenId, sampleUri))
  45. .to.emit(this.token, 'MetadataUpdate')
  46. .withArgs(nonExistentTokenId);
  47. // value will be accessible after mint
  48. await this.token.$_mint(this.owner, nonExistentTokenId);
  49. expect(await this.token.tokenURI(nonExistentTokenId)).to.equal(sampleUri);
  50. });
  51. it('base URI can be set', async function () {
  52. await this.token.setBaseURI(baseURI);
  53. expect(await this.token.$_baseURI()).to.equal(baseURI);
  54. });
  55. it('base URI is added as a prefix to the token URI', async function () {
  56. await this.token.setBaseURI(baseURI);
  57. await this.token.$_setTokenURI(tokenId, sampleUri);
  58. expect(await this.token.tokenURI(tokenId)).to.equal(baseURI + sampleUri);
  59. });
  60. it('token URI can be changed by changing the base URI', async function () {
  61. await this.token.setBaseURI(baseURI);
  62. await this.token.$_setTokenURI(tokenId, sampleUri);
  63. await this.token.setBaseURI(otherBaseURI);
  64. expect(await this.token.tokenURI(tokenId)).to.equal(otherBaseURI + sampleUri);
  65. });
  66. it('tokenId is appended to base URI for tokens with no URI', async function () {
  67. await this.token.setBaseURI(baseURI);
  68. expect(await this.token.tokenURI(tokenId)).to.equal(baseURI + tokenId);
  69. });
  70. it('tokens without URI can be burnt ', async function () {
  71. await this.token.$_burn(tokenId);
  72. await expect(this.token.tokenURI(tokenId))
  73. .to.be.revertedWithCustomError(this.token, 'ERC721NonexistentToken')
  74. .withArgs(tokenId);
  75. });
  76. it('tokens with URI can be burnt ', async function () {
  77. await this.token.$_setTokenURI(tokenId, sampleUri);
  78. await this.token.$_burn(tokenId);
  79. await expect(this.token.tokenURI(tokenId))
  80. .to.be.revertedWithCustomError(this.token, 'ERC721NonexistentToken')
  81. .withArgs(tokenId);
  82. });
  83. it('tokens URI is kept if token is burnt and reminted ', async function () {
  84. await this.token.$_setTokenURI(tokenId, sampleUri);
  85. await this.token.$_burn(tokenId);
  86. await expect(this.token.tokenURI(tokenId))
  87. .to.be.revertedWithCustomError(this.token, 'ERC721NonexistentToken')
  88. .withArgs(tokenId);
  89. await this.token.$_mint(this.owner, tokenId);
  90. expect(await this.token.tokenURI(tokenId)).to.equal(sampleUri);
  91. });
  92. });
  93. });