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 NewAccessPoint(string apName, uint256 indexed tokenId, address indexed owner);
|
||||||
event RemoveAccessPoint(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 ChangeAccessPointScore(string apName, uint256 indexed tokenId, uint256 score, address indexed triggeredBy);
|
||||||
|
|
||||||
event ChangeAccessPointNameVerify(
|
event ChangeAccessPointNameVerify(
|
||||||
|
|
@ -41,6 +48,13 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl, Fl
|
||||||
bool indexed verified,
|
bool indexed verified,
|
||||||
address indexed triggeredBy
|
address indexed triggeredBy
|
||||||
);
|
);
|
||||||
|
event ChangeAccessPointStatus(
|
||||||
|
string apName,
|
||||||
|
uint256 tokenId,
|
||||||
|
AccessPointCreationStatus status,
|
||||||
|
address indexed triggeredBy
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The properties are stored as string to keep consistency with
|
* The properties are stored as string to keep consistency with
|
||||||
* other token contracts, we might consider changing for bytes32
|
* 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
|
mapping(uint256 => Build) builds; // Mapping to build details for each build number
|
||||||
string logo;
|
string logo;
|
||||||
uint24 color; // Color of the nft
|
uint24 color; // Color of the nft
|
||||||
|
bool accessPointAutoApproval; // AP Auto Approval
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -65,6 +80,16 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl, Fl
|
||||||
string gitRepository;
|
string gitRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creation status enums for access points
|
||||||
|
*/
|
||||||
|
enum AccessPointCreationStatus {
|
||||||
|
DRAFT,
|
||||||
|
APPROVED,
|
||||||
|
REJECTED,
|
||||||
|
REMOVED
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The stored data for each AccessPoint.
|
* The stored data for each AccessPoint.
|
||||||
*/
|
*/
|
||||||
|
|
@ -74,6 +99,7 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl, Fl
|
||||||
bool contentVerified;
|
bool contentVerified;
|
||||||
bool nameVerified;
|
bool nameVerified;
|
||||||
address owner;
|
address owner;
|
||||||
|
AccessPointCreationStatus status;
|
||||||
}
|
}
|
||||||
|
|
||||||
Counters.Counter private _appIds;
|
Counters.Counter private _appIds;
|
||||||
|
|
@ -117,7 +143,8 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl, Fl
|
||||||
string memory commitHash,
|
string memory commitHash,
|
||||||
string memory gitRepository,
|
string memory gitRepository,
|
||||||
string memory logo,
|
string memory logo,
|
||||||
uint24 color
|
uint24 color,
|
||||||
|
bool accessPointAutoApproval
|
||||||
) public payable requireCollectionRole(CollectionRoles.Owner) returns (uint256) {
|
) public payable requireCollectionRole(CollectionRoles.Owner) returns (uint256) {
|
||||||
uint256 tokenId = _appIds.current();
|
uint256 tokenId = _appIds.current();
|
||||||
_mint(to, tokenId);
|
_mint(to, tokenId);
|
||||||
|
|
@ -130,6 +157,7 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl, Fl
|
||||||
app.ENS = ENS;
|
app.ENS = ENS;
|
||||||
app.logo = logo;
|
app.logo = logo;
|
||||||
app.color = color;
|
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.
|
// 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;
|
app.currentBuild = 0;
|
||||||
|
|
@ -225,6 +253,26 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl, Fl
|
||||||
return "data:application/json;base64,";
|
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`.
|
* @dev Updates the `externalURL` metadata field of a minted `tokenId`.
|
||||||
*
|
*
|
||||||
|
|
@ -380,9 +428,56 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl, Fl
|
||||||
_requireMinted(tokenId);
|
_requireMinted(tokenId);
|
||||||
require(_accessPoints[apName].owner == address(0), "FleekERC721: AP already exists");
|
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);
|
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) {
|
function removeAccessPoint(string memory apName) public whenNotPaused requireAP(apName) {
|
||||||
require(msg.sender == _accessPoints[apName].owner, "FleekERC721: must be AP owner");
|
require(msg.sender == _accessPoints[apName].owner, "FleekERC721: must be AP owner");
|
||||||
|
_accessPoints[apName].status = AccessPointCreationStatus.REMOVED;
|
||||||
uint256 tokenId = _accessPoints[apName].tokenId;
|
uint256 tokenId = _accessPoints[apName].tokenId;
|
||||||
|
emit ChangeAccessPointStatus(apName, tokenId, AccessPointCreationStatus.REMOVED, msg.sender);
|
||||||
delete _accessPoints[apName];
|
|
||||||
emit RemoveAccessPoint(apName, tokenId, msg.sender);
|
emit RemoveAccessPoint(apName, tokenId, msg.sender);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ library FleekStrings {
|
||||||
'"owner":"', uint160(owner).toHexString(20), '",',
|
'"owner":"', uint160(owner).toHexString(20), '",',
|
||||||
'"external_url":"', app.externalURL, '",',
|
'"external_url":"', app.externalURL, '",',
|
||||||
'"image":"', FleekSVG.generateBase64(app.name, app.ENS, app.logo, app.color.toColorString()), '",',
|
'"image":"', FleekSVG.generateBase64(app.name, app.ENS, app.logo, app.color.toColorString()), '",',
|
||||||
|
'"access_point_auto_approval":',app.accessPointAutoApproval.toString(),',',
|
||||||
'"attributes": [',
|
'"attributes": [',
|
||||||
'{"trait_type": "ENS", "value":"', app.ENS,'"},',
|
'{"trait_type": "ENS", "value":"', app.ENS,'"},',
|
||||||
'{"trait_type": "Commit Hash", "value":"', app.builds[app.currentBuild].commitHash,'"},',
|
'{"trait_type": "Commit Hash", "value":"', app.builds[app.currentBuild].commitHash,'"},',
|
||||||
|
|
@ -63,7 +64,8 @@ library FleekStrings {
|
||||||
'"score":', ap.score.toString(), ",",
|
'"score":', ap.score.toString(), ",",
|
||||||
'"nameVerified":', ap.nameVerified.toString(), ",",
|
'"nameVerified":', ap.nameVerified.toString(), ",",
|
||||||
'"contentVerified":', ap.contentVerified.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;
|
pragma solidity ^0.8.17;
|
||||||
|
|
||||||
import "./TestBase.sol";
|
import "../TestBase.sol";
|
||||||
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
|
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
|
||||||
import {FleekAccessControl} from "contracts/FleekAccessControl.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;
|
using Strings for address;
|
||||||
uint256 internal tokenId;
|
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 {
|
function setUp() public {
|
||||||
baseSetUp();
|
baseSetUp();
|
||||||
tokenId = mintDefault(deployer);
|
tokenId = mintDefault(deployer);
|
||||||
|
|
@ -33,7 +21,7 @@ contract Test_FleekERC721_AccessPoint is Test_FleekERC721_Base {
|
||||||
string memory accessPointName = "accesspoint.com";
|
string memory accessPointName = "accesspoint.com";
|
||||||
CuT.addAccessPoint(tokenId, accessPointName);
|
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 {
|
function test_removeAccessPoint() public {
|
||||||
|
|
@ -41,24 +29,14 @@ contract Test_FleekERC721_AccessPoint is Test_FleekERC721_Base {
|
||||||
CuT.addAccessPoint(tokenId, accessPointName);
|
CuT.addAccessPoint(tokenId, accessPointName);
|
||||||
CuT.removeAccessPoint(accessPointName);
|
CuT.removeAccessPoint(accessPointName);
|
||||||
|
|
||||||
expectRevertWithInvalidAP();
|
APConstants.assertAccessPointJSON(accessPointName, "0", "0", "false", "false", deployer, "3", CuT.getAccessPointJSON(accessPointName));
|
||||||
CuT.getAccessPointJSON(accessPointName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function test_cannotRemoveNonexistentAccessPoint() public {
|
function test_cannotRemoveNonExistentAccessPoint() public {
|
||||||
expectRevertWithInvalidAP();
|
expectRevertWithInvalidAP();
|
||||||
CuT.removeAccessPoint("accesspoint.com");
|
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 {
|
function test_isAccessPointNameVerified() public {
|
||||||
string memory accessPointName = "accesspoint.com";
|
string memory accessPointName = "accesspoint.com";
|
||||||
CuT.addAccessPoint(tokenId, accessPointName);
|
CuT.addAccessPoint(tokenId, accessPointName);
|
||||||
|
|
@ -69,20 +47,20 @@ contract Test_FleekERC721_AccessPoint is Test_FleekERC721_Base {
|
||||||
function test_increaseAccessPointScore() public {
|
function test_increaseAccessPointScore() public {
|
||||||
string memory accessPointName = "accesspoint.com";
|
string memory accessPointName = "accesspoint.com";
|
||||||
CuT.addAccessPoint(tokenId, accessPointName);
|
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);
|
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);
|
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 {
|
function test_cannotDecreaseAccessPointScoreToMinusOne() public {
|
||||||
string memory accessPointName = "accesspoint.com";
|
string memory accessPointName = "accesspoint.com";
|
||||||
CuT.addAccessPoint(tokenId, accessPointName);
|
CuT.addAccessPoint(tokenId, accessPointName);
|
||||||
|
|
||||||
assertAccessPointJSON(accessPointName, "0", "0", "false", "false", deployer);
|
APConstants.assertAccessPointJSON(accessPointName, "0", "0", "false", "false", deployer, "0", CuT.getAccessPointJSON(accessPointName));
|
||||||
expectRevertWithMinimalScore();
|
expectRevertWithMinimalScore();
|
||||||
CuT.decreaseAccessPointScore(accessPointName);
|
CuT.decreaseAccessPointScore(accessPointName);
|
||||||
}
|
}
|
||||||
|
|
@ -91,11 +69,11 @@ contract Test_FleekERC721_AccessPoint is Test_FleekERC721_Base {
|
||||||
string memory accessPointName = "accesspoint.com";
|
string memory accessPointName = "accesspoint.com";
|
||||||
CuT.addAccessPoint(tokenId, accessPointName);
|
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);
|
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);
|
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 {
|
function test_cannotAddAccessPointToNonexistentToken() public {
|
||||||
|
|
@ -122,6 +100,6 @@ contract Test_FleekERC721_AccessPoint is Test_FleekERC721_Base {
|
||||||
CuT.setAccessPointContentVerify(accessPointName, true);
|
CuT.setAccessPointContentVerify(accessPointName, true);
|
||||||
vm.stopPrank();
|
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",
|
"94e8ba38568aea4fb277a37a4c472d94a6ce880a",
|
||||||
"https://github.com/a-different/repository",
|
"https://github.com/a-different/repository",
|
||||||
TestConstants.LOGO_1,
|
TestConstants.LOGO_1,
|
||||||
0x654321
|
0x654321,
|
||||||
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
assertEq(firstMint, 0);
|
assertEq(firstMint, 0);
|
||||||
assertEq(secondMint, 1);
|
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 {
|
function test_balanceOfDeployerAfterAndBeforeMinting() public {
|
||||||
assertEq(CuT.balanceOf(deployer), 0);
|
assertEq(CuT.balanceOf(deployer), 0);
|
||||||
|
|
||||||
|
|
@ -59,10 +77,22 @@ contract Test_FleekERC721_Mint is Test_FleekERC721_Base {
|
||||||
string memory commitHash,
|
string memory commitHash,
|
||||||
string memory gitRepository,
|
string memory gitRepository,
|
||||||
string memory logo,
|
string memory logo,
|
||||||
uint24 color
|
uint24 color,
|
||||||
|
bool autoApprovalAp
|
||||||
) public {
|
) public {
|
||||||
vm.assume(to != address(0));
|
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(tokenId, 0);
|
||||||
assertEq(CuT.ownerOf(tokenId), to);
|
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_COMMIT_HASH,
|
||||||
TestConstants.APP_GIT_REPOSITORY,
|
TestConstants.APP_GIT_REPOSITORY,
|
||||||
TestConstants.LOGO_0,
|
TestConstants.LOGO_0,
|
||||||
TestConstants.APP_COLOR
|
TestConstants.APP_COLOR,
|
||||||
|
false // Auto Approval Is OFF
|
||||||
);
|
);
|
||||||
|
|
||||||
return mint;
|
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 { loadFixture } from '@nomicfoundation/hardhat-network-helpers';
|
||||||
import { expect } from 'chai';
|
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>>;
|
let fixture: Awaited<ReturnType<typeof Fixtures.withMint>>;
|
||||||
const DefaultAP = 'accesspoint.com';
|
const DefaultAP = 'accesspoint.com';
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
fixture = await loadFixture(Fixtures.withMint);
|
fixture = await loadFixture(Fixtures.withMint);
|
||||||
|
fixture.contract.setAccessPointAutoApproval(fixture.tokenId, true);
|
||||||
fixture.contract.addAccessPoint(fixture.tokenId, DefaultAP);
|
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;
|
const { contract, owner, tokenId } = fixture;
|
||||||
|
|
||||||
await expect(contract.addAccessPoint(tokenId, 'random.com'))
|
await expect(contract.addAccessPoint(tokenId, 'random.com'))
|
||||||
.to.emit(contract, 'NewAccessPoint')
|
.to.emit(contract, 'ChangeAccessPointStatus')
|
||||||
.withArgs('random.com', tokenId, owner.address);
|
.withArgs(
|
||||||
|
'random.com',
|
||||||
|
tokenId,
|
||||||
|
AccessPointStatus.APPROVED,
|
||||||
|
owner.address
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return a AP json object', async () => {
|
it('should return a AP json object', async () => {
|
||||||
const { contract, owner, tokenId } = fixture;
|
const { contract, owner, tokenId } = fixture;
|
||||||
|
|
||||||
const ap = await contract.getAccessPointJSON(DefaultAP);
|
const ap = await contract.getAccessPointJSON(DefaultAP);
|
||||||
const parsedAp = JSON.parse(ap);
|
const parsedAp = JSON.parse(ap);
|
||||||
|
|
||||||
|
|
@ -31,6 +38,7 @@ describe('AccessPoints', () => {
|
||||||
owner: owner.address.toLowerCase(),
|
owner: owner.address.toLowerCase(),
|
||||||
contentVerified: false,
|
contentVerified: false,
|
||||||
nameVerified: false,
|
nameVerified: false,
|
||||||
|
status: AccessPointStatus.APPROVED,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -56,6 +64,7 @@ describe('AccessPoints', () => {
|
||||||
owner: owner.address.toLowerCase(),
|
owner: owner.address.toLowerCase(),
|
||||||
contentVerified: false,
|
contentVerified: false,
|
||||||
nameVerified: false,
|
nameVerified: false,
|
||||||
|
status: AccessPointStatus.APPROVED,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -75,6 +84,7 @@ describe('AccessPoints', () => {
|
||||||
owner: owner.address.toLowerCase(),
|
owner: owner.address.toLowerCase(),
|
||||||
contentVerified: false,
|
contentVerified: false,
|
||||||
nameVerified: false,
|
nameVerified: false,
|
||||||
|
status: AccessPointStatus.APPROVED,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -91,6 +101,18 @@ describe('AccessPoints', () => {
|
||||||
await expect(contract.removeAccessPoint(DefaultAP))
|
await expect(contract.removeAccessPoint(DefaultAP))
|
||||||
.to.emit(contract, 'RemoveAccessPoint')
|
.to.emit(contract, 'RemoveAccessPoint')
|
||||||
.withArgs(DefaultAP, tokenId, owner.address);
|
.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 () => {
|
it('should allow only AP owner to remove it', async () => {
|
||||||
|
|
@ -162,4 +184,17 @@ describe('AccessPoints', () => {
|
||||||
|
|
||||||
expect(parsedAp.nameVerified).to.be.false;
|
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.commitHash,
|
||||||
TestConstants.MintParams.gitRepository,
|
TestConstants.MintParams.gitRepository,
|
||||||
TestConstants.MintParams.logo,
|
TestConstants.MintParams.logo,
|
||||||
TestConstants.MintParams.color
|
TestConstants.MintParams.color,
|
||||||
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,12 @@ export const TestConstants = Object.freeze({
|
||||||
TokenRoles: {
|
TokenRoles: {
|
||||||
Controller: 0,
|
Controller: 0,
|
||||||
},
|
},
|
||||||
|
AccessPointStatus: {
|
||||||
|
DRAFT: 0,
|
||||||
|
APPROVED: 1,
|
||||||
|
REJECTED: 2,
|
||||||
|
REMOVED: 3,
|
||||||
|
},
|
||||||
MintParams: {
|
MintParams: {
|
||||||
name: 'Fleek Test App',
|
name: 'Fleek Test App',
|
||||||
description: 'Fleek Test App Description',
|
description: 'Fleek Test App Description',
|
||||||
|
|
@ -14,6 +20,7 @@ export const TestConstants = Object.freeze({
|
||||||
gitRepository: 'https://github.com/fleekxyz/non-fungible-apps',
|
gitRepository: 'https://github.com/fleekxyz/non-fungible-apps',
|
||||||
logo: 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjI1MDAiIHdpZHRoPSIyMTgzIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMjQgMTQxLjUzMTk5OTk5OTk5OTk4Ij48cGF0aCBkPSJNMTAuMzgzIDEyNi44OTRMMCAwbDEyNCAuMjU1LTEwLjk3OSAxMjYuNjM5LTUwLjU1MyAxNC42Mzh6IiBmaWxsPSIjZTM0ZjI2Ii8+PHBhdGggZD0iTTYyLjQ2OCAxMjkuMjc3VjEyLjA4NWw1MS4wNjQuMTctOS4xMDYgMTA0Ljg1MXoiIGZpbGw9IiNlZjY1MmEiLz48cGF0aCBkPSJNOTkuNDkgNDEuMzYybDEuNDQ2LTE1LjQ5SDIyLjM4M2w0LjM0IDQ3LjQ5aDU0LjIxM0w3OC44MSA5My42MTdsLTE3LjM2MiA0LjY4LTE3LjYxNy01LjEwNi0uOTM2LTEyLjA4NUgyNy4zMTlsMi4xMjggMjQuNjgxIDMyIDguOTM2IDMyLjI1NS04LjkzNiA0LjM0LTQ4LjE3SDQxLjEwN0wzOS40OSA0MS4zNjJ6IiBmaWxsPSIjZmZmIi8+PC9zdmc+',
|
logo: 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjI1MDAiIHdpZHRoPSIyMTgzIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMjQgMTQxLjUzMTk5OTk5OTk5OTk4Ij48cGF0aCBkPSJNMTAuMzgzIDEyNi44OTRMMCAwbDEyNCAuMjU1LTEwLjk3OSAxMjYuNjM5LTUwLjU1MyAxNC42Mzh6IiBmaWxsPSIjZTM0ZjI2Ii8+PHBhdGggZD0iTTYyLjQ2OCAxMjkuMjc3VjEyLjA4NWw1MS4wNjQuMTctOS4xMDYgMTA0Ljg1MXoiIGZpbGw9IiNlZjY1MmEiLz48cGF0aCBkPSJNOTkuNDkgNDEuMzYybDEuNDQ2LTE1LjQ5SDIyLjM4M2w0LjM0IDQ3LjQ5aDU0LjIxM0w3OC44MSA5My42MTdsLTE3LjM2MiA0LjY4LTE3LjYxNy01LjEwNi0uOTM2LTEyLjA4NUgyNy4zMTlsMi4xMjggMjQuNjgxIDMyIDguOTM2IDMyLjI1NS04LjkzNiA0LjM0LTQ4LjE3SDQxLjEwN0wzOS40OSA0MS4zNjJ6IiBmaWxsPSIjZmZmIi8+PC9zdmc+',
|
||||||
color: 0xe34f26,
|
color: 0xe34f26,
|
||||||
|
accessPointAutoApprovalSettings: false,
|
||||||
},
|
},
|
||||||
CollectionParams: {
|
CollectionParams: {
|
||||||
name: 'FleekERC721',
|
name: 'FleekERC721',
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,8 @@ export abstract class Fixtures {
|
||||||
TestConstants.MintParams.commitHash,
|
TestConstants.MintParams.commitHash,
|
||||||
TestConstants.MintParams.gitRepository,
|
TestConstants.MintParams.gitRepository,
|
||||||
TestConstants.MintParams.logo,
|
TestConstants.MintParams.logo,
|
||||||
TestConstants.MintParams.color
|
TestConstants.MintParams.color,
|
||||||
|
TestConstants.MintParams.accessPointAutoApprovalSettings
|
||||||
);
|
);
|
||||||
|
|
||||||
const tokenId = response.value.toNumber();
|
const tokenId = response.value.toNumber();
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,8 @@ describe('FleekERC721.Minting', () => {
|
||||||
MintParams.commitHash,
|
MintParams.commitHash,
|
||||||
MintParams.gitRepository,
|
MintParams.gitRepository,
|
||||||
MintParams.logo,
|
MintParams.logo,
|
||||||
MintParams.color
|
MintParams.color,
|
||||||
|
MintParams.accessPointAutoApprovalSettings
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(response.value).to.be.instanceOf(ethers.BigNumber);
|
expect(response.value).to.be.instanceOf(ethers.BigNumber);
|
||||||
|
|
@ -40,7 +41,8 @@ describe('FleekERC721.Minting', () => {
|
||||||
MintParams.commitHash,
|
MintParams.commitHash,
|
||||||
MintParams.gitRepository,
|
MintParams.gitRepository,
|
||||||
MintParams.logo,
|
MintParams.logo,
|
||||||
MintParams.color
|
MintParams.color,
|
||||||
|
MintParams.accessPointAutoApprovalSettings
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.to.be.revertedWithCustomError(contract, Errors.MustHaveCollectionRole)
|
.to.be.revertedWithCustomError(contract, Errors.MustHaveCollectionRole)
|
||||||
|
|
@ -61,7 +63,8 @@ describe('FleekERC721.Minting', () => {
|
||||||
MintParams.commitHash,
|
MintParams.commitHash,
|
||||||
MintParams.gitRepository,
|
MintParams.gitRepository,
|
||||||
MintParams.logo,
|
MintParams.logo,
|
||||||
MintParams.color
|
MintParams.color,
|
||||||
|
MintParams.accessPointAutoApprovalSettings
|
||||||
);
|
);
|
||||||
|
|
||||||
const tokenId = response.value.toNumber();
|
const tokenId = response.value.toNumber();
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,8 @@ describe('FleekERC721.Pausable', () => {
|
||||||
MintParams.commitHash,
|
MintParams.commitHash,
|
||||||
MintParams.gitRepository,
|
MintParams.gitRepository,
|
||||||
MintParams.logo,
|
MintParams.logo,
|
||||||
MintParams.color
|
MintParams.color,
|
||||||
|
false
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ describe('FleekERC721.TokenURI', () => {
|
||||||
description: TestConstants.MintParams.description,
|
description: TestConstants.MintParams.description,
|
||||||
image: TestConstants.ResultantImage.Default,
|
image: TestConstants.ResultantImage.Default,
|
||||||
external_url: TestConstants.MintParams.externalUrl,
|
external_url: TestConstants.MintParams.externalUrl,
|
||||||
|
access_point_auto_approval: false,
|
||||||
attributes: [
|
attributes: [
|
||||||
{
|
{
|
||||||
trait_type: 'ENS',
|
trait_type: 'ENS',
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue