feat: access point auto approval settings for tokens (#121)
* feat: add accessPointAutoApprovalSettings field to mint, app struct, and expose a function for changing the field later + an event. * feat: add checks for the autoapproval settings on function addAccessPoint. * feat: add setApprovalForAccessPoint function and ChangeAccessPointApprovalStatus event. * test: add new constant variables to the hardhat tests and update mint tests. * feat: update removeAccessPoint function to check the status and also update getAccessPointJSON to include status. * test: add two access point test files and fix errors and mismatches in them with the auto approval set up * feat: remove the access point mapping in the App struct and wherever it was used. * chore: update foundry tests to match the new interface of the contract. * test: add new tests for the approval settings * chore: update foundry tests to match new interface. * test: update foundry tests and the settings for auto approvals * feat: keep history of removed APs. Update tests. * fix: make changes to the contract and tests to fix the tests. * chore: apply changes Zoruka requested. * fix: change name of setAutoApprovalSettings function in foundry tests. * perf: revert back to enums, update hardhat and foundry tests. * fix: apply requested changes by janison. * fix: error in hardhat test. * fix: mint params of a foundry test. * fix: merge errors. * fix: revert back to tokenOwner for setAutoApproval functions. * chore: remove comment for accessPointAutoApproval
This commit is contained in:
parent
770ab78668
commit
cfea9a90ea
|
|
@ -27,6 +27,13 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl, Fl
|
|||
|
||||
event NewAccessPoint(string apName, uint256 indexed tokenId, address indexed owner);
|
||||
event RemoveAccessPoint(string apName, uint256 indexed tokenId, address indexed owner);
|
||||
|
||||
event ChangeAccessPointAutoApproval(
|
||||
uint256 indexed token,
|
||||
bool indexed settings,
|
||||
address indexed triggeredBy
|
||||
);
|
||||
|
||||
event ChangeAccessPointScore(string apName, uint256 indexed tokenId, uint256 score, address indexed triggeredBy);
|
||||
|
||||
event ChangeAccessPointNameVerify(
|
||||
|
|
@ -41,6 +48,13 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl, Fl
|
|||
bool indexed verified,
|
||||
address indexed triggeredBy
|
||||
);
|
||||
event ChangeAccessPointStatus(
|
||||
string apName,
|
||||
uint256 tokenId,
|
||||
AccessPointCreationStatus status,
|
||||
address indexed triggeredBy
|
||||
);
|
||||
|
||||
/**
|
||||
* The properties are stored as string to keep consistency with
|
||||
* other token contracts, we might consider changing for bytes32
|
||||
|
|
@ -55,6 +69,7 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl, Fl
|
|||
mapping(uint256 => Build) builds; // Mapping to build details for each build number
|
||||
string logo;
|
||||
uint24 color; // Color of the nft
|
||||
bool accessPointAutoApproval; // AP Auto Approval
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -65,6 +80,16 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl, Fl
|
|||
string gitRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creation status enums for access points
|
||||
*/
|
||||
enum AccessPointCreationStatus {
|
||||
DRAFT,
|
||||
APPROVED,
|
||||
REJECTED,
|
||||
REMOVED
|
||||
}
|
||||
|
||||
/**
|
||||
* The stored data for each AccessPoint.
|
||||
*/
|
||||
|
|
@ -74,6 +99,7 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl, Fl
|
|||
bool contentVerified;
|
||||
bool nameVerified;
|
||||
address owner;
|
||||
AccessPointCreationStatus status;
|
||||
}
|
||||
|
||||
Counters.Counter private _appIds;
|
||||
|
|
@ -117,7 +143,8 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl, Fl
|
|||
string memory commitHash,
|
||||
string memory gitRepository,
|
||||
string memory logo,
|
||||
uint24 color
|
||||
uint24 color,
|
||||
bool accessPointAutoApproval
|
||||
) public payable requireCollectionRole(CollectionRoles.Owner) returns (uint256) {
|
||||
uint256 tokenId = _appIds.current();
|
||||
_mint(to, tokenId);
|
||||
|
|
@ -130,6 +157,7 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl, Fl
|
|||
app.ENS = ENS;
|
||||
app.logo = logo;
|
||||
app.color = color;
|
||||
app.accessPointAutoApproval = accessPointAutoApproval;
|
||||
|
||||
// The mint interaction is considered to be the first build of the site. Updates from now on all increment the currentBuild by one and update the mapping.
|
||||
app.currentBuild = 0;
|
||||
|
|
@ -225,6 +253,26 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl, Fl
|
|||
return "data:application/json;base64,";
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Updates the `accessPointAutoApproval` settings on minted `tokenId`.
|
||||
*
|
||||
* May emit a {ChangeAccessPointAutoApproval} event.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - the tokenId must be minted and valid.
|
||||
* - the sender must have the `tokenController` role.
|
||||
*
|
||||
*/
|
||||
function setAccessPointAutoApproval(
|
||||
uint256 tokenId,
|
||||
bool _apAutoApproval
|
||||
) public virtual requireTokenOwner(tokenId) {
|
||||
_requireMinted(tokenId);
|
||||
_apps[tokenId].accessPointAutoApproval = _apAutoApproval;
|
||||
emit ChangeAccessPointAutoApproval(tokenId, _apAutoApproval, msg.sender);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Updates the `externalURL` metadata field of a minted `tokenId`.
|
||||
*
|
||||
|
|
@ -380,9 +428,56 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl, Fl
|
|||
_requireMinted(tokenId);
|
||||
require(_accessPoints[apName].owner == address(0), "FleekERC721: AP already exists");
|
||||
|
||||
_accessPoints[apName] = AccessPoint(tokenId, 0, false, false, msg.sender);
|
||||
|
||||
emit NewAccessPoint(apName, tokenId, msg.sender);
|
||||
|
||||
if (_apps[tokenId].accessPointAutoApproval) {
|
||||
// Auto Approval is on.
|
||||
_accessPoints[apName] = AccessPoint(tokenId, 0, false, false, msg.sender, AccessPointCreationStatus.APPROVED);
|
||||
|
||||
emit ChangeAccessPointStatus(apName, tokenId, AccessPointCreationStatus.APPROVED, msg.sender);
|
||||
} else {
|
||||
// Auto Approval is off. Should wait for approval.
|
||||
_accessPoints[apName] = AccessPoint(tokenId, 0, false, false, msg.sender, AccessPointCreationStatus.DRAFT);
|
||||
emit ChangeAccessPointStatus(apName, tokenId, AccessPointCreationStatus.DRAFT, msg.sender);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Set approval settings for an access point.
|
||||
* It will add the access point to the token's AP list, if `approved` is true.
|
||||
*
|
||||
* May emit a {ChangeAccessPointApprovalStatus} event.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - the tokenId must exist and be the same as the tokenId that is set for the AP.
|
||||
* - the AP must exist.
|
||||
* - must be called by a token controller.
|
||||
*/
|
||||
function setApprovalForAccessPoint(
|
||||
uint256 tokenId,
|
||||
string memory apName,
|
||||
bool approved
|
||||
) public requireTokenOwner(tokenId) {
|
||||
AccessPoint storage accessPoint = _accessPoints[apName];
|
||||
require(
|
||||
accessPoint.tokenId == tokenId,
|
||||
"FleekERC721: the passed tokenId is not the same as the access point's tokenId."
|
||||
);
|
||||
require(
|
||||
accessPoint.status == AccessPointCreationStatus.DRAFT,
|
||||
"FleekERC721: the access point creation status has been set before."
|
||||
);
|
||||
|
||||
if (approved) {
|
||||
// Approval
|
||||
accessPoint.status = AccessPointCreationStatus.APPROVED;
|
||||
emit ChangeAccessPointStatus(apName, tokenId, AccessPointCreationStatus.APPROVED, msg.sender);
|
||||
} else {
|
||||
// Not Approved
|
||||
accessPoint.status = AccessPointCreationStatus.REJECTED;
|
||||
emit ChangeAccessPointStatus(apName, tokenId, AccessPointCreationStatus.REJECTED, msg.sender);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -400,9 +495,9 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl, Fl
|
|||
*/
|
||||
function removeAccessPoint(string memory apName) public whenNotPaused requireAP(apName) {
|
||||
require(msg.sender == _accessPoints[apName].owner, "FleekERC721: must be AP owner");
|
||||
_accessPoints[apName].status = AccessPointCreationStatus.REMOVED;
|
||||
uint256 tokenId = _accessPoints[apName].tokenId;
|
||||
|
||||
delete _accessPoints[apName];
|
||||
emit ChangeAccessPointStatus(apName, tokenId, AccessPointCreationStatus.REMOVED, msg.sender);
|
||||
emit RemoveAccessPoint(apName, tokenId, msg.sender);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ library FleekStrings {
|
|||
'"owner":"', uint160(owner).toHexString(20), '",',
|
||||
'"external_url":"', app.externalURL, '",',
|
||||
'"image":"', FleekSVG.generateBase64(app.name, app.ENS, app.logo, app.color.toColorString()), '",',
|
||||
'"access_point_auto_approval":',app.accessPointAutoApproval.toString(),',',
|
||||
'"attributes": [',
|
||||
'{"trait_type": "ENS", "value":"', app.ENS,'"},',
|
||||
'{"trait_type": "Commit Hash", "value":"', app.builds[app.currentBuild].commitHash,'"},',
|
||||
|
|
@ -63,7 +64,8 @@ library FleekStrings {
|
|||
'"score":', ap.score.toString(), ",",
|
||||
'"nameVerified":', ap.nameVerified.toString(), ",",
|
||||
'"contentVerified":', ap.contentVerified.toString(), ",",
|
||||
'"owner":"', uint160(ap.owner).toHexString(20), '"',
|
||||
'"owner":"', uint160(ap.owner).toHexString(20), '",',
|
||||
'"status":',uint(ap.status).toString(),
|
||||
"}"
|
||||
));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,28 +2,16 @@
|
|||
|
||||
pragma solidity ^0.8.17;
|
||||
|
||||
import "./TestBase.sol";
|
||||
import "../TestBase.sol";
|
||||
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
|
||||
import {FleekAccessControl} from "contracts/FleekAccessControl.sol";
|
||||
import "../../../../contracts/FleekERC721.sol";
|
||||
import './ApBase.sol';
|
||||
|
||||
contract Test_FleekERC721_AccessPoint is Test_FleekERC721_Base {
|
||||
contract Test_FleekERC721_AccessPoint is Test_FleekERC721_Base, APConstants {
|
||||
using Strings for address;
|
||||
uint256 internal tokenId;
|
||||
|
||||
function assertAccessPointJSON(
|
||||
string memory accessPointName,
|
||||
string memory _tokenId,
|
||||
string memory score,
|
||||
string memory nameVerified,
|
||||
string memory contentVerified,
|
||||
address owner
|
||||
) internal {
|
||||
string memory current = CuT.getAccessPointJSON(accessPointName);
|
||||
// prettier-ignore
|
||||
string memory expectedJSON = string(abi.encodePacked('{"tokenId":', _tokenId, ',"score":', score, ',"nameVerified":', nameVerified, ',"contentVerified":', contentVerified, ',"owner":"', owner.toHexString(), '"}'));
|
||||
assertEq(current, expectedJSON);
|
||||
}
|
||||
|
||||
function setUp() public {
|
||||
baseSetUp();
|
||||
tokenId = mintDefault(deployer);
|
||||
|
|
@ -33,7 +21,7 @@ contract Test_FleekERC721_AccessPoint is Test_FleekERC721_Base {
|
|||
string memory accessPointName = "accesspoint.com";
|
||||
CuT.addAccessPoint(tokenId, accessPointName);
|
||||
|
||||
assertAccessPointJSON(accessPointName, "0", "0", "false", "false", deployer);
|
||||
APConstants.assertAccessPointJSON(accessPointName, "0", "0", "false", "false", deployer, "0", CuT.getAccessPointJSON(accessPointName));
|
||||
}
|
||||
|
||||
function test_removeAccessPoint() public {
|
||||
|
|
@ -41,24 +29,14 @@ contract Test_FleekERC721_AccessPoint is Test_FleekERC721_Base {
|
|||
CuT.addAccessPoint(tokenId, accessPointName);
|
||||
CuT.removeAccessPoint(accessPointName);
|
||||
|
||||
expectRevertWithInvalidAP();
|
||||
CuT.getAccessPointJSON(accessPointName);
|
||||
APConstants.assertAccessPointJSON(accessPointName, "0", "0", "false", "false", deployer, "3", CuT.getAccessPointJSON(accessPointName));
|
||||
}
|
||||
|
||||
function test_cannotRemoveNonexistentAccessPoint() public {
|
||||
function test_cannotRemoveNonExistentAccessPoint() public {
|
||||
expectRevertWithInvalidAP();
|
||||
CuT.removeAccessPoint("accesspoint.com");
|
||||
}
|
||||
|
||||
function test_cannotTwiceRemoveAccessPoint() public {
|
||||
string memory accessPointName = "accesspoint.com";
|
||||
CuT.addAccessPoint(tokenId, accessPointName);
|
||||
CuT.removeAccessPoint(accessPointName);
|
||||
|
||||
expectRevertWithInvalidAP();
|
||||
CuT.removeAccessPoint(accessPointName);
|
||||
}
|
||||
|
||||
function test_isAccessPointNameVerified() public {
|
||||
string memory accessPointName = "accesspoint.com";
|
||||
CuT.addAccessPoint(tokenId, accessPointName);
|
||||
|
|
@ -69,20 +47,20 @@ contract Test_FleekERC721_AccessPoint is Test_FleekERC721_Base {
|
|||
function test_increaseAccessPointScore() public {
|
||||
string memory accessPointName = "accesspoint.com";
|
||||
CuT.addAccessPoint(tokenId, accessPointName);
|
||||
assertAccessPointJSON(accessPointName, "0", "0", "false", "false", deployer);
|
||||
APConstants.assertAccessPointJSON(accessPointName, "0", "0", "false", "false", deployer, "0", CuT.getAccessPointJSON(accessPointName));
|
||||
|
||||
CuT.increaseAccessPointScore(accessPointName);
|
||||
assertAccessPointJSON(accessPointName, "0", "1", "false", "false", deployer);
|
||||
APConstants.assertAccessPointJSON(accessPointName, "0", "1", "false", "false", deployer, "0", CuT.getAccessPointJSON(accessPointName));
|
||||
|
||||
CuT.increaseAccessPointScore(accessPointName);
|
||||
assertAccessPointJSON(accessPointName, "0", "2", "false", "false", deployer);
|
||||
APConstants.assertAccessPointJSON(accessPointName, "0", "2", "false", "false", deployer, "0", CuT.getAccessPointJSON(accessPointName));
|
||||
}
|
||||
|
||||
function test_cannotDecreaseAccessPointScoreToMinusOne() public {
|
||||
string memory accessPointName = "accesspoint.com";
|
||||
CuT.addAccessPoint(tokenId, accessPointName);
|
||||
|
||||
assertAccessPointJSON(accessPointName, "0", "0", "false", "false", deployer);
|
||||
APConstants.assertAccessPointJSON(accessPointName, "0", "0", "false", "false", deployer, "0", CuT.getAccessPointJSON(accessPointName));
|
||||
expectRevertWithMinimalScore();
|
||||
CuT.decreaseAccessPointScore(accessPointName);
|
||||
}
|
||||
|
|
@ -91,11 +69,11 @@ contract Test_FleekERC721_AccessPoint is Test_FleekERC721_Base {
|
|||
string memory accessPointName = "accesspoint.com";
|
||||
CuT.addAccessPoint(tokenId, accessPointName);
|
||||
|
||||
assertAccessPointJSON(accessPointName, "0", "0", "false", "false", deployer);
|
||||
APConstants.assertAccessPointJSON(accessPointName, "0", "0", "false", "false", deployer, "0", CuT.getAccessPointJSON(accessPointName));
|
||||
CuT.increaseAccessPointScore(accessPointName);
|
||||
assertAccessPointJSON(accessPointName, "0", "1", "false", "false", deployer);
|
||||
APConstants.assertAccessPointJSON(accessPointName, "0", "1", "false", "false", deployer, "0", CuT.getAccessPointJSON(accessPointName));
|
||||
CuT.decreaseAccessPointScore(accessPointName);
|
||||
assertAccessPointJSON(accessPointName, "0", "0", "false", "false", deployer);
|
||||
APConstants.assertAccessPointJSON(accessPointName, "0", "0", "false", "false", deployer, "0", CuT.getAccessPointJSON(accessPointName));
|
||||
}
|
||||
|
||||
function test_cannotAddAccessPointToNonexistentToken() public {
|
||||
|
|
@ -122,6 +100,6 @@ contract Test_FleekERC721_AccessPoint is Test_FleekERC721_Base {
|
|||
CuT.setAccessPointContentVerify(accessPointName, true);
|
||||
vm.stopPrank();
|
||||
|
||||
assertAccessPointJSON(accessPointName, "0", "0", "true", "true", deployer);
|
||||
APConstants.assertAccessPointJSON(accessPointName, "0", "0", "true", "true", deployer, "0", CuT.getAccessPointJSON(accessPointName));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8.17;
|
||||
|
||||
import "../TestBase.sol";
|
||||
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
|
||||
import {FleekAccessControl} from "contracts/FleekAccessControl.sol";
|
||||
import "../../../../contracts/FleekERC721.sol";
|
||||
import "./ApBase.sol";
|
||||
|
||||
contract Test_FleekERC721_AccessPoint is Test_FleekERC721_Base, APConstants {
|
||||
using Strings for address;
|
||||
uint256 internal tokenId;
|
||||
|
||||
function setUp() public {
|
||||
baseSetUp();
|
||||
tokenId = mintDefault(deployer);
|
||||
CuT.setAccessPointAutoApproval(0, true);
|
||||
}
|
||||
|
||||
function test_getAccessPointJSON() public {
|
||||
string memory accessPointName = "accesspoint.com";
|
||||
CuT.addAccessPoint(tokenId, accessPointName);
|
||||
|
||||
APConstants.assertAccessPointJSON(accessPointName, "0", "0", "false", "false", deployer, "1", CuT.getAccessPointJSON(accessPointName));
|
||||
}
|
||||
|
||||
function test_removeAccessPoint() public {
|
||||
string memory accessPointName = "accesspoint.com";
|
||||
CuT.addAccessPoint(tokenId, accessPointName);
|
||||
CuT.removeAccessPoint(accessPointName);
|
||||
|
||||
APConstants.assertAccessPointJSON(accessPointName, "0", "0", "false", "false", deployer, "3", CuT.getAccessPointJSON(accessPointName));
|
||||
}
|
||||
|
||||
function test_cannotRemoveNonExistentAccessPoint() public {
|
||||
expectRevertWithInvalidAP();
|
||||
CuT.removeAccessPoint("accesspoint.com");
|
||||
}
|
||||
|
||||
function test_isAccessPointNameVerified() public {
|
||||
string memory accessPointName = "accesspoint.com";
|
||||
CuT.addAccessPoint(tokenId, accessPointName);
|
||||
assertFalse(CuT.isAccessPointNameVerified(accessPointName));
|
||||
CuT.setAccessPointNameVerify(accessPointName, true);
|
||||
assertEq(CuT.isAccessPointNameVerified(accessPointName), true);
|
||||
}
|
||||
|
||||
function test_increaseAccessPointScore() public {
|
||||
string memory accessPointName = "accesspoint.com";
|
||||
CuT.addAccessPoint(tokenId, accessPointName);
|
||||
APConstants.assertAccessPointJSON(accessPointName, "0", "0", "false", "false", deployer, "1", CuT.getAccessPointJSON(accessPointName));
|
||||
|
||||
CuT.increaseAccessPointScore(accessPointName);
|
||||
APConstants.assertAccessPointJSON(accessPointName, "0", "1", "false", "false", deployer, "1", CuT.getAccessPointJSON(accessPointName));
|
||||
|
||||
CuT.increaseAccessPointScore(accessPointName);
|
||||
APConstants.assertAccessPointJSON(accessPointName, "0", "2", "false", "false", deployer, "1", CuT.getAccessPointJSON(accessPointName));
|
||||
}
|
||||
|
||||
function test_cannotDecreaseAccessPointScoreToMinusOne() public {
|
||||
string memory accessPointName = "accesspoint.com";
|
||||
CuT.addAccessPoint(tokenId, accessPointName);
|
||||
|
||||
APConstants.assertAccessPointJSON(accessPointName, "0", "0", "false", "false", deployer, "1", CuT.getAccessPointJSON(accessPointName));
|
||||
expectRevertWithMinimalScore();
|
||||
CuT.decreaseAccessPointScore(accessPointName);
|
||||
}
|
||||
|
||||
function test_decreaseAccessPointScore() public {
|
||||
string memory accessPointName = "accesspoint.com";
|
||||
CuT.addAccessPoint(tokenId, accessPointName);
|
||||
|
||||
APConstants.assertAccessPointJSON(accessPointName, "0", "0", "false", "false", deployer, "1", CuT.getAccessPointJSON(accessPointName));
|
||||
CuT.increaseAccessPointScore(accessPointName);
|
||||
APConstants.assertAccessPointJSON(accessPointName, "0", "1", "false", "false", deployer, "1", CuT.getAccessPointJSON(accessPointName));
|
||||
CuT.decreaseAccessPointScore(accessPointName);
|
||||
APConstants.assertAccessPointJSON(accessPointName, "0", "0", "false", "false", deployer, "1", CuT.getAccessPointJSON(accessPointName));
|
||||
}
|
||||
|
||||
function test_cannotAddAccessPointToNonExistentToken() public {
|
||||
expectRevertWithInvalidTokenId();
|
||||
CuT.addAccessPoint(1, "accesspoint.com");
|
||||
}
|
||||
|
||||
function test_setAccessPointVerifiesWithCorrectRole() public {
|
||||
string memory accessPointName = "accesspoint.com";
|
||||
address randomAddress = address(12);
|
||||
CuT.addAccessPoint(tokenId, accessPointName);
|
||||
|
||||
vm.startPrank(randomAddress);
|
||||
expectRevertWithTokenRole(tokenId, FleekAccessControl.TokenRoles.Controller);
|
||||
CuT.setAccessPointNameVerify(accessPointName, true);
|
||||
expectRevertWithTokenRole(tokenId, FleekAccessControl.TokenRoles.Controller);
|
||||
CuT.setAccessPointContentVerify(accessPointName, true);
|
||||
vm.stopPrank();
|
||||
|
||||
CuT.grantTokenRole(tokenId, FleekAccessControl.TokenRoles.Controller, randomAddress);
|
||||
|
||||
vm.startPrank(randomAddress);
|
||||
CuT.setAccessPointNameVerify(accessPointName, true);
|
||||
CuT.setAccessPointContentVerify(accessPointName, true);
|
||||
vm.stopPrank();
|
||||
|
||||
APConstants.assertAccessPointJSON(accessPointName, "0", "0", "true", "true", deployer, "1", CuT.getAccessPointJSON(accessPointName));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8.17;
|
||||
import "../TestBase.sol";
|
||||
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
|
||||
|
||||
contract APConstants is Test {
|
||||
using Strings for address;
|
||||
|
||||
function assertAccessPointJSON(
|
||||
string memory accessPointName,
|
||||
string memory _tokenId,
|
||||
string memory score,
|
||||
string memory nameVerified,
|
||||
string memory contentVerified,
|
||||
address owner,
|
||||
string memory status,
|
||||
string memory current // the json result from getAccessPointJSON
|
||||
) public {
|
||||
// prettier-ignore
|
||||
string memory expectedJSON = string(abi.encodePacked('{"tokenId":', _tokenId, ',"score":', score, ',"nameVerified":', nameVerified, ',"contentVerified":', contentVerified, ',"owner":"', owner.toHexString(), '","status":', status,'}'));
|
||||
assertEq(current, expectedJSON);
|
||||
}
|
||||
}
|
||||
|
|
@ -35,13 +35,31 @@ contract Test_FleekERC721_Mint is Test_FleekERC721_Base {
|
|||
"94e8ba38568aea4fb277a37a4c472d94a6ce880a",
|
||||
"https://github.com/a-different/repository",
|
||||
TestConstants.LOGO_1,
|
||||
0x654321
|
||||
0x654321,
|
||||
false
|
||||
);
|
||||
|
||||
assertEq(firstMint, 0);
|
||||
assertEq(secondMint, 1);
|
||||
}
|
||||
|
||||
function test_mintWithAutoApprovalAPsOn() public {
|
||||
uint256 mint = CuT.mint(
|
||||
address(12),
|
||||
"Different App Name",
|
||||
"This is a different description for another app.",
|
||||
"https://fleek.xyz",
|
||||
"fleek.eth",
|
||||
"94e8ba38568aea4fb277a37a4c472d94a6ce880a",
|
||||
"https://github.com/a-different/repository",
|
||||
TestConstants.LOGO_1,
|
||||
0x654321,
|
||||
true
|
||||
);
|
||||
|
||||
assertEq(mint, 0);
|
||||
}
|
||||
|
||||
function test_balanceOfDeployerAfterAndBeforeMinting() public {
|
||||
assertEq(CuT.balanceOf(deployer), 0);
|
||||
|
||||
|
|
@ -59,10 +77,22 @@ contract Test_FleekERC721_Mint is Test_FleekERC721_Base {
|
|||
string memory commitHash,
|
||||
string memory gitRepository,
|
||||
string memory logo,
|
||||
uint24 color
|
||||
uint24 color,
|
||||
bool autoApprovalAp
|
||||
) public {
|
||||
vm.assume(to != address(0));
|
||||
uint256 tokenId = CuT.mint(to, appName, description, externalURL, ens, commitHash, gitRepository, logo, color);
|
||||
uint256 tokenId = CuT.mint(
|
||||
to,
|
||||
appName,
|
||||
description,
|
||||
externalURL,
|
||||
ens,
|
||||
commitHash,
|
||||
gitRepository,
|
||||
logo,
|
||||
color,
|
||||
autoApprovalAp
|
||||
);
|
||||
|
||||
assertEq(tokenId, 0);
|
||||
assertEq(CuT.ownerOf(tokenId), to);
|
||||
|
|
|
|||
|
|
@ -60,7 +60,8 @@ abstract contract Test_FleekERC721_Base is Test, Test_FleekERC721_Assertions {
|
|||
TestConstants.APP_COMMIT_HASH,
|
||||
TestConstants.APP_GIT_REPOSITORY,
|
||||
TestConstants.LOGO_0,
|
||||
TestConstants.APP_COLOR
|
||||
TestConstants.APP_COLOR,
|
||||
false // Auto Approval Is OFF
|
||||
);
|
||||
|
||||
return mint;
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,255 @@
|
|||
import { loadFixture } from '@nomicfoundation/hardhat-network-helpers';
|
||||
import { expect } from 'chai';
|
||||
import { before } from 'mocha';
|
||||
import { TestConstants, Fixtures } from '../helpers';
|
||||
const { AccessPointStatus } = TestConstants;
|
||||
|
||||
describe('FleekERC721.AccessPoints.AutoApprovalOff', () => {
|
||||
let fixture: Awaited<ReturnType<typeof Fixtures.withMint>>;
|
||||
|
||||
beforeEach(async () => {
|
||||
fixture = await loadFixture(Fixtures.withMint);
|
||||
});
|
||||
|
||||
it('should add an AP with draft status', async () => {
|
||||
const { contract, owner, tokenId } = fixture;
|
||||
|
||||
await expect(contract.addAccessPoint(tokenId, 'accesspoint.com'))
|
||||
.to.emit(contract, 'NewAccessPoint')
|
||||
.withArgs('accesspoint.com', tokenId, owner.address);
|
||||
|
||||
let ap = await contract.getAccessPointJSON('accesspoint.com');
|
||||
const parsedAp = JSON.parse(ap);
|
||||
|
||||
expect(parsedAp).to.eql({
|
||||
tokenId,
|
||||
score: 0,
|
||||
owner: owner.address.toLowerCase(),
|
||||
contentVerified: false,
|
||||
nameVerified: false,
|
||||
status: AccessPointStatus.DRAFT,
|
||||
});
|
||||
});
|
||||
|
||||
it('should return a AP json object', async () => {
|
||||
const { contract, owner, tokenId } = fixture;
|
||||
|
||||
await contract.addAccessPoint(tokenId, 'accesspoint.com');
|
||||
|
||||
const ap = await contract.getAccessPointJSON('accesspoint.com');
|
||||
const parsedAp = JSON.parse(ap);
|
||||
|
||||
expect(parsedAp).to.eql({
|
||||
tokenId,
|
||||
score: 0,
|
||||
owner: owner.address.toLowerCase(),
|
||||
contentVerified: false,
|
||||
nameVerified: false,
|
||||
status: AccessPointStatus.DRAFT,
|
||||
});
|
||||
});
|
||||
|
||||
it('should revert if AP does not exist', async () => {
|
||||
const { contract } = fixture;
|
||||
|
||||
await expect(
|
||||
contract.getAccessPointJSON('accesspoint.com')
|
||||
).to.be.revertedWith('FleekERC721: invalid AP');
|
||||
});
|
||||
|
||||
it('should increase the AP score', async () => {
|
||||
const { contract, owner, tokenId } = fixture;
|
||||
|
||||
await contract.addAccessPoint(tokenId, 'accesspoint.com');
|
||||
|
||||
await contract.increaseAccessPointScore('accesspoint.com');
|
||||
|
||||
const ap = await contract.getAccessPointJSON('accesspoint.com');
|
||||
const parsedAp = JSON.parse(ap);
|
||||
|
||||
expect(parsedAp).to.eql({
|
||||
tokenId,
|
||||
score: 1,
|
||||
owner: owner.address.toLowerCase(),
|
||||
contentVerified: false,
|
||||
nameVerified: false,
|
||||
status: AccessPointStatus.DRAFT,
|
||||
});
|
||||
});
|
||||
|
||||
it('should decrease the AP score', async () => {
|
||||
const { contract, owner, tokenId } = fixture;
|
||||
|
||||
await contract.addAccessPoint(tokenId, 'accesspoint.com');
|
||||
|
||||
await contract.increaseAccessPointScore('accesspoint.com');
|
||||
await contract.increaseAccessPointScore('accesspoint.com');
|
||||
await contract.decreaseAccessPointScore('accesspoint.com');
|
||||
|
||||
const ap = await contract.getAccessPointJSON('accesspoint.com');
|
||||
const parsedAp = JSON.parse(ap);
|
||||
|
||||
expect(parsedAp).to.eql({
|
||||
tokenId,
|
||||
score: 1,
|
||||
owner: owner.address.toLowerCase(),
|
||||
contentVerified: false,
|
||||
nameVerified: false,
|
||||
status: AccessPointStatus.DRAFT,
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow anyone to change AP score', async () => {
|
||||
const { contract, otherAccount, tokenId } = fixture;
|
||||
|
||||
await contract.addAccessPoint(tokenId, 'accesspoint.com');
|
||||
await contract.increaseAccessPointScore('accesspoint.com');
|
||||
await contract
|
||||
.connect(otherAccount)
|
||||
.increaseAccessPointScore('accesspoint.com');
|
||||
});
|
||||
|
||||
it('should remove an AP', async () => {
|
||||
const { contract, owner, tokenId } = fixture;
|
||||
|
||||
await contract.addAccessPoint(tokenId, 'accesspoint.com');
|
||||
|
||||
await expect(contract.removeAccessPoint('accesspoint.com'))
|
||||
.to.emit(contract, 'RemoveAccessPoint')
|
||||
.withArgs('accesspoint.com', tokenId, owner.address);
|
||||
});
|
||||
|
||||
it('should allow only AP owner to remove it', async () => {
|
||||
const { contract, otherAccount, tokenId } = fixture;
|
||||
|
||||
await contract.addAccessPoint(tokenId, 'accesspoint.com');
|
||||
|
||||
await expect(
|
||||
contract.connect(otherAccount).removeAccessPoint('accesspoint.com')
|
||||
).to.be.revertedWith('FleekERC721: must be AP owner');
|
||||
});
|
||||
|
||||
it('should not be allowed to add the same AP more than once', async () => {
|
||||
const { contract, tokenId } = fixture;
|
||||
|
||||
await contract.addAccessPoint(tokenId, 'accesspoint.com');
|
||||
|
||||
await expect(
|
||||
contract.addAccessPoint(tokenId, 'accesspoint.com')
|
||||
).to.be.revertedWith('FleekERC721: AP already exists');
|
||||
});
|
||||
|
||||
it('should change "contentVerified" to true', async () => {
|
||||
const { contract, tokenId } = fixture;
|
||||
|
||||
await contract.addAccessPoint(tokenId, 'accesspoint.com');
|
||||
|
||||
await contract.setAccessPointContentVerify('accesspoint.com', true);
|
||||
|
||||
const ap = await contract.getAccessPointJSON('accesspoint.com');
|
||||
const parsedAp = JSON.parse(ap);
|
||||
|
||||
expect(parsedAp.contentVerified).to.be.true;
|
||||
});
|
||||
|
||||
it('should change "contentVerified" to false', async () => {
|
||||
const { contract, tokenId } = fixture;
|
||||
|
||||
await contract.addAccessPoint(tokenId, 'accesspoint.com');
|
||||
|
||||
const beforeAp = await contract.getAccessPointJSON('accesspoint.com');
|
||||
const beforeParsedAp = JSON.parse(beforeAp);
|
||||
expect(beforeParsedAp.contentVerified).to.be.false;
|
||||
|
||||
await contract.setAccessPointContentVerify('accesspoint.com', true);
|
||||
await contract.setAccessPointContentVerify('accesspoint.com', false);
|
||||
|
||||
const ap = await contract.getAccessPointJSON('accesspoint.com');
|
||||
const parsedAp = JSON.parse(ap);
|
||||
|
||||
expect(parsedAp.contentVerified).to.be.false;
|
||||
});
|
||||
|
||||
it('should change "nameVerified" to true', async () => {
|
||||
const { contract, tokenId } = fixture;
|
||||
|
||||
await contract.addAccessPoint(tokenId, 'accesspoint.com');
|
||||
|
||||
await contract.setAccessPointNameVerify('accesspoint.com', true);
|
||||
|
||||
const ap = await contract.getAccessPointJSON('accesspoint.com');
|
||||
const parsedAp = JSON.parse(ap);
|
||||
|
||||
expect(parsedAp.nameVerified).to.be.true;
|
||||
});
|
||||
|
||||
it('should change "nameVerified" to false', async () => {
|
||||
const { contract, tokenId } = fixture;
|
||||
|
||||
await contract.addAccessPoint(tokenId, 'accesspoint.com');
|
||||
|
||||
const beforeAp = await contract.getAccessPointJSON('accesspoint.com');
|
||||
const beforeParsedAp = JSON.parse(beforeAp);
|
||||
expect(beforeParsedAp.nameVerified).to.be.false;
|
||||
|
||||
await contract.setAccessPointNameVerify('accesspoint.com', true);
|
||||
await contract.setAccessPointNameVerify('accesspoint.com', false);
|
||||
|
||||
const ap = await contract.getAccessPointJSON('accesspoint.com');
|
||||
const parsedAp = JSON.parse(ap);
|
||||
|
||||
expect(parsedAp.nameVerified).to.be.false;
|
||||
});
|
||||
|
||||
it('should token owner be able to change the auto approval settings to on', async () => {
|
||||
const { contract, tokenId, owner } = fixture;
|
||||
|
||||
await contract
|
||||
.connect(owner)
|
||||
.setAccessPointAutoApproval(tokenId, true);
|
||||
|
||||
await contract.addAccessPoint(tokenId, 'accesspoint.com');
|
||||
|
||||
const beforeAp = await contract.getAccessPointJSON('accesspoint.com');
|
||||
const beforeParsedAp = JSON.parse(beforeAp);
|
||||
|
||||
expect(beforeParsedAp.status).to.be.eql(AccessPointStatus.APPROVED); //APPROVED STATUS
|
||||
});
|
||||
|
||||
it('should token owner be able to approve a draft ap', async () => {
|
||||
const { contract, tokenId, owner } = fixture;
|
||||
|
||||
await contract.addAccessPoint(tokenId, 'accesspoint.com');
|
||||
|
||||
const beforeAp = await contract.getAccessPointJSON('accesspoint.com');
|
||||
const beforeParsedAp = JSON.parse(beforeAp);
|
||||
expect(beforeParsedAp.status).to.be.eql(AccessPointStatus.DRAFT); //DRAFT STATUS
|
||||
|
||||
await contract
|
||||
.connect(owner)
|
||||
.setApprovalForAccessPoint(tokenId, 'accesspoint.com', true);
|
||||
|
||||
const afterAp = await contract.getAccessPointJSON('accesspoint.com');
|
||||
const afterParsedAp = JSON.parse(afterAp);
|
||||
expect(afterParsedAp.status).to.be.eql(AccessPointStatus.APPROVED); //APPROVED STATUS
|
||||
});
|
||||
|
||||
it('should token owner be able to reject a draft ap', async () => {
|
||||
const { contract, tokenId, owner } = fixture;
|
||||
|
||||
await contract.addAccessPoint(tokenId, 'accesspoint.com');
|
||||
|
||||
const beforeAp = await contract.getAccessPointJSON('accesspoint.com');
|
||||
const beforeParsedAp = JSON.parse(beforeAp);
|
||||
expect(beforeParsedAp.status).to.be.eql(AccessPointStatus.DRAFT); //DRAFT STATUS
|
||||
|
||||
await contract
|
||||
.connect(owner)
|
||||
.setApprovalForAccessPoint(tokenId, 'accesspoint.com', false);
|
||||
|
||||
const afterAp = await contract.getAccessPointJSON('accesspoint.com');
|
||||
const afterParsedAp = JSON.parse(afterAp);
|
||||
|
||||
expect(afterParsedAp.status).to.be.eql(AccessPointStatus.REJECTED); //REJECTED STATUS
|
||||
});
|
||||
});
|
||||
|
|
@ -1,27 +1,34 @@
|
|||
import { loadFixture } from '@nomicfoundation/hardhat-network-helpers';
|
||||
import { expect } from 'chai';
|
||||
import { Fixtures } from './helpers';
|
||||
import { before } from 'mocha';
|
||||
import { TestConstants, Fixtures } from '../helpers';
|
||||
const { AccessPointStatus } = TestConstants;
|
||||
|
||||
describe('AccessPoints', () => {
|
||||
describe('FleekERC721.AccessPoints.AutoApprovalOn', () => {
|
||||
let fixture: Awaited<ReturnType<typeof Fixtures.withMint>>;
|
||||
const DefaultAP = 'accesspoint.com';
|
||||
|
||||
beforeEach(async () => {
|
||||
fixture = await loadFixture(Fixtures.withMint);
|
||||
fixture.contract.setAccessPointAutoApproval(fixture.tokenId, true);
|
||||
fixture.contract.addAccessPoint(fixture.tokenId, DefaultAP);
|
||||
});
|
||||
|
||||
it('should add an AP', async () => {
|
||||
it('should add an AP with approved status', async () => {
|
||||
const { contract, owner, tokenId } = fixture;
|
||||
|
||||
await expect(contract.addAccessPoint(tokenId, 'random.com'))
|
||||
.to.emit(contract, 'NewAccessPoint')
|
||||
.withArgs('random.com', tokenId, owner.address);
|
||||
.to.emit(contract, 'ChangeAccessPointStatus')
|
||||
.withArgs(
|
||||
'random.com',
|
||||
tokenId,
|
||||
AccessPointStatus.APPROVED,
|
||||
owner.address
|
||||
);
|
||||
});
|
||||
|
||||
it('should return a AP json object', async () => {
|
||||
const { contract, owner, tokenId } = fixture;
|
||||
|
||||
const ap = await contract.getAccessPointJSON(DefaultAP);
|
||||
const parsedAp = JSON.parse(ap);
|
||||
|
||||
|
|
@ -31,6 +38,7 @@ describe('AccessPoints', () => {
|
|||
owner: owner.address.toLowerCase(),
|
||||
contentVerified: false,
|
||||
nameVerified: false,
|
||||
status: AccessPointStatus.APPROVED,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -56,6 +64,7 @@ describe('AccessPoints', () => {
|
|||
owner: owner.address.toLowerCase(),
|
||||
contentVerified: false,
|
||||
nameVerified: false,
|
||||
status: AccessPointStatus.APPROVED,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -75,6 +84,7 @@ describe('AccessPoints', () => {
|
|||
owner: owner.address.toLowerCase(),
|
||||
contentVerified: false,
|
||||
nameVerified: false,
|
||||
status: AccessPointStatus.APPROVED,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -91,6 +101,18 @@ describe('AccessPoints', () => {
|
|||
await expect(contract.removeAccessPoint(DefaultAP))
|
||||
.to.emit(contract, 'RemoveAccessPoint')
|
||||
.withArgs(DefaultAP, tokenId, owner.address);
|
||||
|
||||
const ap = await contract.getAccessPointJSON(DefaultAP);
|
||||
const parsedAp = JSON.parse(ap);
|
||||
|
||||
expect(parsedAp).to.eql({
|
||||
tokenId,
|
||||
score: 0,
|
||||
owner: owner.address.toLowerCase(),
|
||||
contentVerified: false,
|
||||
nameVerified: false,
|
||||
status: AccessPointStatus.REMOVED,
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow only AP owner to remove it', async () => {
|
||||
|
|
@ -162,4 +184,17 @@ describe('AccessPoints', () => {
|
|||
|
||||
expect(parsedAp.nameVerified).to.be.false;
|
||||
});
|
||||
|
||||
it('should token owner be able to change the auto approval settings to off', async () => {
|
||||
const { contract, tokenId } = fixture;
|
||||
|
||||
await contract.setAccessPointAutoApproval(tokenId, false);
|
||||
|
||||
await contract.addAccessPoint(tokenId, 'random.com');
|
||||
|
||||
const beforeAp = await contract.getAccessPointJSON('random.com');
|
||||
const beforeParsedAp = JSON.parse(beforeAp);
|
||||
|
||||
expect(beforeParsedAp.status).to.be.eql(AccessPointStatus.DRAFT); //DRAFT STATUS
|
||||
});
|
||||
});
|
||||
|
|
@ -18,7 +18,8 @@ describe('FleekERC721.GetLastTokenId', () => {
|
|||
TestConstants.MintParams.commitHash,
|
||||
TestConstants.MintParams.gitRepository,
|
||||
TestConstants.MintParams.logo,
|
||||
TestConstants.MintParams.color
|
||||
TestConstants.MintParams.color,
|
||||
false
|
||||
);
|
||||
|
||||
return response;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,12 @@ export const TestConstants = Object.freeze({
|
|||
TokenRoles: {
|
||||
Controller: 0,
|
||||
},
|
||||
AccessPointStatus: {
|
||||
DRAFT: 0,
|
||||
APPROVED: 1,
|
||||
REJECTED: 2,
|
||||
REMOVED: 3,
|
||||
},
|
||||
MintParams: {
|
||||
name: 'Fleek Test App',
|
||||
description: 'Fleek Test App Description',
|
||||
|
|
@ -14,6 +20,7 @@ export const TestConstants = Object.freeze({
|
|||
gitRepository: 'https://github.com/fleekxyz/non-fungible-apps',
|
||||
logo: 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjI1MDAiIHdpZHRoPSIyMTgzIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMjQgMTQxLjUzMTk5OTk5OTk5OTk4Ij48cGF0aCBkPSJNMTAuMzgzIDEyNi44OTRMMCAwbDEyNCAuMjU1LTEwLjk3OSAxMjYuNjM5LTUwLjU1MyAxNC42Mzh6IiBmaWxsPSIjZTM0ZjI2Ii8+PHBhdGggZD0iTTYyLjQ2OCAxMjkuMjc3VjEyLjA4NWw1MS4wNjQuMTctOS4xMDYgMTA0Ljg1MXoiIGZpbGw9IiNlZjY1MmEiLz48cGF0aCBkPSJNOTkuNDkgNDEuMzYybDEuNDQ2LTE1LjQ5SDIyLjM4M2w0LjM0IDQ3LjQ5aDU0LjIxM0w3OC44MSA5My42MTdsLTE3LjM2MiA0LjY4LTE3LjYxNy01LjEwNi0uOTM2LTEyLjA4NUgyNy4zMTlsMi4xMjggMjQuNjgxIDMyIDguOTM2IDMyLjI1NS04LjkzNiA0LjM0LTQ4LjE3SDQxLjEwN0wzOS40OSA0MS4zNjJ6IiBmaWxsPSIjZmZmIi8+PC9zdmc+',
|
||||
color: 0xe34f26,
|
||||
accessPointAutoApprovalSettings: false,
|
||||
},
|
||||
CollectionParams: {
|
||||
name: 'FleekERC721',
|
||||
|
|
|
|||
|
|
@ -42,7 +42,8 @@ export abstract class Fixtures {
|
|||
TestConstants.MintParams.commitHash,
|
||||
TestConstants.MintParams.gitRepository,
|
||||
TestConstants.MintParams.logo,
|
||||
TestConstants.MintParams.color
|
||||
TestConstants.MintParams.color,
|
||||
TestConstants.MintParams.accessPointAutoApprovalSettings
|
||||
);
|
||||
|
||||
const tokenId = response.value.toNumber();
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@ describe('FleekERC721.Minting', () => {
|
|||
MintParams.commitHash,
|
||||
MintParams.gitRepository,
|
||||
MintParams.logo,
|
||||
MintParams.color
|
||||
MintParams.color,
|
||||
MintParams.accessPointAutoApprovalSettings
|
||||
);
|
||||
|
||||
expect(response.value).to.be.instanceOf(ethers.BigNumber);
|
||||
|
|
@ -40,7 +41,8 @@ describe('FleekERC721.Minting', () => {
|
|||
MintParams.commitHash,
|
||||
MintParams.gitRepository,
|
||||
MintParams.logo,
|
||||
MintParams.color
|
||||
MintParams.color,
|
||||
MintParams.accessPointAutoApprovalSettings
|
||||
)
|
||||
)
|
||||
.to.be.revertedWithCustomError(contract, Errors.MustHaveCollectionRole)
|
||||
|
|
@ -61,7 +63,8 @@ describe('FleekERC721.Minting', () => {
|
|||
MintParams.commitHash,
|
||||
MintParams.gitRepository,
|
||||
MintParams.logo,
|
||||
MintParams.color
|
||||
MintParams.color,
|
||||
MintParams.accessPointAutoApprovalSettings
|
||||
);
|
||||
|
||||
const tokenId = response.value.toNumber();
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@ describe('FleekERC721.Pausable', () => {
|
|||
MintParams.commitHash,
|
||||
MintParams.gitRepository,
|
||||
MintParams.logo,
|
||||
MintParams.color
|
||||
MintParams.color,
|
||||
false
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ describe('FleekERC721.TokenURI', () => {
|
|||
description: TestConstants.MintParams.description,
|
||||
image: TestConstants.ResultantImage.Default,
|
||||
external_url: TestConstants.MintParams.externalUrl,
|
||||
access_point_auto_approval: false,
|
||||
attributes: [
|
||||
{
|
||||
trait_type: 'ENS',
|
||||
|
|
|
|||
Loading…
Reference in New Issue