mirror of
https://github.com/lens-protocol/core.git
synced 2026-04-22 03:02:03 -04:00
747 lines
28 KiB
TypeScript
747 lines
28 KiB
TypeScript
import '@nomiclabs/hardhat-ethers';
|
|
import { expect } from 'chai';
|
|
import { keccak256, toUtf8Bytes } from 'ethers/lib/utils';
|
|
import { UIDataProvider__factory } from '../../typechain-types';
|
|
import { ZERO_ADDRESS } from '../helpers/constants';
|
|
import { ERRORS } from '../helpers/errors';
|
|
import { getJsonMetadataFromBase64TokenUri } from '../helpers/utils';
|
|
import {
|
|
approvalFollowModule,
|
|
deployer,
|
|
emptyCollectModule,
|
|
FIRST_PROFILE_ID,
|
|
followerOnlyReferenceModule,
|
|
governance,
|
|
governanceAddress,
|
|
lensHub,
|
|
makeSuiteCleanRoom,
|
|
mockFollowModule,
|
|
mockModuleData,
|
|
MOCK_FOLLOW_NFT_URI,
|
|
MOCK_PROFILE_HANDLE,
|
|
MOCK_PROFILE_URI,
|
|
MOCK_URI,
|
|
moduleGlobals,
|
|
OTHER_MOCK_URI,
|
|
timedFeeCollectModule,
|
|
treasuryAddress,
|
|
TREASURY_FEE_BPS,
|
|
user,
|
|
userAddress,
|
|
userTwo,
|
|
userTwoAddress,
|
|
} from '../__setup.spec';
|
|
|
|
/**
|
|
* @dev Some of these tests may be redundant, but are still present to ensure an isolated environment,
|
|
* in particular if other test files are changed.
|
|
*/
|
|
makeSuiteCleanRoom('Misc', function () {
|
|
context('NFT Transfer Emitters', function () {
|
|
it('User should not be able to call the follow NFT transfer event emitter function', async function () {
|
|
await expect(
|
|
lensHub.emitFollowNFTTransferEvent(FIRST_PROFILE_ID, 1, userAddress, userTwoAddress)
|
|
).to.be.revertedWith(ERRORS.NOT_FOLLOW_NFT);
|
|
});
|
|
|
|
it('User should not be able to call the collect NFT transfer event emitter function', async function () {
|
|
await expect(
|
|
lensHub.emitCollectNFTTransferEvent(FIRST_PROFILE_ID, 1, 1, userAddress, userTwoAddress)
|
|
).to.be.revertedWith(ERRORS.NOT_COLLECT_NFT);
|
|
});
|
|
});
|
|
|
|
context('Lens Hub Misc', function () {
|
|
beforeEach(async function () {
|
|
await expect(
|
|
lensHub.createProfile({
|
|
to: userAddress,
|
|
handle: MOCK_PROFILE_HANDLE,
|
|
imageURI: MOCK_PROFILE_URI,
|
|
followModule: ZERO_ADDRESS,
|
|
followModuleData: [],
|
|
followNFTURI: MOCK_FOLLOW_NFT_URI,
|
|
})
|
|
).to.not.be.reverted;
|
|
});
|
|
|
|
it('UserTwo should fail to burn profile owned by user without being approved', async function () {
|
|
await expect(lensHub.connect(userTwo).burn(FIRST_PROFILE_ID)).to.be.revertedWith(
|
|
ERRORS.NOT_OWNER_OR_APPROVED
|
|
);
|
|
});
|
|
|
|
it('User should burn profile owned by user', async function () {
|
|
await expect(lensHub.burn(FIRST_PROFILE_ID)).to.not.be.reverted;
|
|
});
|
|
|
|
it('UserTwo should burn profile owned by user if approved', async function () {
|
|
await expect(lensHub.approve(userTwoAddress, FIRST_PROFILE_ID)).to.not.be.reverted;
|
|
await expect(lensHub.connect(userTwo).burn(FIRST_PROFILE_ID)).to.not.be.reverted;
|
|
});
|
|
|
|
it('Governance getter should return proper address', async function () {
|
|
expect(await lensHub.getGovernance()).to.eq(governanceAddress);
|
|
});
|
|
|
|
it('Profile handle getter should return the correct handle', async function () {
|
|
expect(await lensHub.getHandle(FIRST_PROFILE_ID)).to.eq(MOCK_PROFILE_HANDLE);
|
|
});
|
|
|
|
it('Profile dispatcher getter should return the zero address when no dispatcher is set', async function () {
|
|
expect(await lensHub.getDispatcher(FIRST_PROFILE_ID)).to.eq(ZERO_ADDRESS);
|
|
});
|
|
|
|
it('Profile creator whitelist getter should return expected values', async function () {
|
|
expect(await lensHub.isProfileCreatorWhitelisted(userAddress)).to.eq(true);
|
|
await expect(
|
|
lensHub.connect(governance).whitelistProfileCreator(userAddress, false)
|
|
).to.not.be.reverted;
|
|
expect(await lensHub.isProfileCreatorWhitelisted(userAddress)).to.eq(false);
|
|
});
|
|
|
|
it('Profile dispatcher getter should return the correct dispatcher address when it is set, then zero after it is transferred', async function () {
|
|
await expect(lensHub.setDispatcher(FIRST_PROFILE_ID, userTwoAddress)).to.not.be.reverted;
|
|
expect(await lensHub.getDispatcher(FIRST_PROFILE_ID)).to.eq(userTwoAddress);
|
|
|
|
await expect(
|
|
lensHub.transferFrom(userAddress, userTwoAddress, FIRST_PROFILE_ID)
|
|
).to.not.be.reverted;
|
|
expect(await lensHub.getDispatcher(FIRST_PROFILE_ID)).to.eq(ZERO_ADDRESS);
|
|
});
|
|
|
|
it('Profile follow NFT getter should return the zero address before the first follow, then the correct address afterwards', async function () {
|
|
expect(await lensHub.getFollowNFT(FIRST_PROFILE_ID)).to.eq(ZERO_ADDRESS);
|
|
|
|
await expect(lensHub.follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted;
|
|
|
|
expect(await lensHub.getFollowNFT(FIRST_PROFILE_ID)).to.not.eq(ZERO_ADDRESS);
|
|
});
|
|
|
|
it('Profile follow module getter should return the zero address, then the correct follow module after it is set', async function () {
|
|
expect(await lensHub.getFollowModule(FIRST_PROFILE_ID)).to.eq(ZERO_ADDRESS);
|
|
|
|
await expect(
|
|
lensHub.connect(governance).whitelistFollowModule(mockFollowModule.address, true)
|
|
).to.not.be.reverted;
|
|
|
|
await expect(
|
|
lensHub.setFollowModule(FIRST_PROFILE_ID, mockFollowModule.address, mockModuleData)
|
|
).to.not.be.reverted;
|
|
expect(await lensHub.getFollowModule(FIRST_PROFILE_ID)).to.eq(mockFollowModule.address);
|
|
});
|
|
|
|
it('Profile publication count getter should return zero, then the correct amount after some publications', async function () {
|
|
expect(await lensHub.getPubCount(FIRST_PROFILE_ID)).to.eq(0);
|
|
|
|
await expect(
|
|
lensHub.connect(governance).whitelistCollectModule(emptyCollectModule.address, true)
|
|
).to.not.be.reverted;
|
|
|
|
const expectedCount = 5;
|
|
for (let i = 0; i < expectedCount; i++) {
|
|
await expect(
|
|
lensHub.post({
|
|
profileId: FIRST_PROFILE_ID,
|
|
contentURI: MOCK_URI,
|
|
collectModule: emptyCollectModule.address,
|
|
collectModuleData: [],
|
|
referenceModule: ZERO_ADDRESS,
|
|
referenceModuleData: [],
|
|
})
|
|
).to.not.be.reverted;
|
|
}
|
|
expect(await lensHub.getPubCount(FIRST_PROFILE_ID)).to.eq(expectedCount);
|
|
});
|
|
|
|
it('Profile tokenURI should return the accurate URI', async function () {
|
|
const tokenURI = await lensHub.tokenURI(FIRST_PROFILE_ID);
|
|
const jsonMetadata = await getJsonMetadataFromBase64TokenUri(tokenURI);
|
|
expect(jsonMetadata.name).to.eq(`@${MOCK_PROFILE_HANDLE}`);
|
|
expect(jsonMetadata.description).to.eq(`@${MOCK_PROFILE_HANDLE} - Lens profile`);
|
|
const expectedAttributes = [
|
|
{ trait_type: 'id', value: `#${FIRST_PROFILE_ID.toString()}` },
|
|
{ trait_type: 'followers', value: '0' },
|
|
{ trait_type: 'owner', value: userAddress.toLowerCase() },
|
|
{ trait_type: 'handle', value: `@${MOCK_PROFILE_HANDLE}` },
|
|
];
|
|
expect(jsonMetadata.attributes).to.eql(expectedAttributes);
|
|
expect(keccak256(toUtf8Bytes(tokenURI))).to.eq(
|
|
'0xa2e9967e825705ce8f38931f7d1f88fe63bef6f2f2c52715692f14d42d889b76'
|
|
);
|
|
});
|
|
|
|
it('Publication reference module getter should return the correct reference module (or zero in case of no reference module)', async function () {
|
|
await expect(
|
|
lensHub.connect(governance).whitelistCollectModule(emptyCollectModule.address, true)
|
|
).to.not.be.reverted;
|
|
|
|
await expect(
|
|
lensHub
|
|
.connect(governance)
|
|
.whitelistReferenceModule(followerOnlyReferenceModule.address, true)
|
|
).to.not.be.reverted;
|
|
|
|
await expect(
|
|
lensHub.post({
|
|
profileId: FIRST_PROFILE_ID,
|
|
contentURI: MOCK_URI,
|
|
collectModule: emptyCollectModule.address,
|
|
collectModuleData: [],
|
|
referenceModule: ZERO_ADDRESS,
|
|
referenceModuleData: [],
|
|
})
|
|
).to.not.be.reverted;
|
|
expect(await lensHub.getReferenceModule(FIRST_PROFILE_ID, 1)).to.eq(ZERO_ADDRESS);
|
|
|
|
await expect(
|
|
lensHub.post({
|
|
profileId: FIRST_PROFILE_ID,
|
|
contentURI: MOCK_URI,
|
|
collectModule: emptyCollectModule.address,
|
|
collectModuleData: [],
|
|
referenceModule: followerOnlyReferenceModule.address,
|
|
referenceModuleData: [],
|
|
})
|
|
).to.not.be.reverted;
|
|
expect(await lensHub.getReferenceModule(FIRST_PROFILE_ID, 2)).to.eq(
|
|
followerOnlyReferenceModule.address
|
|
);
|
|
});
|
|
|
|
it('Publication pointer getter should return an empty pointer for posts', async function () {
|
|
await expect(
|
|
lensHub.connect(governance).whitelistCollectModule(emptyCollectModule.address, true)
|
|
).to.not.be.reverted;
|
|
|
|
await expect(
|
|
lensHub.post({
|
|
profileId: FIRST_PROFILE_ID,
|
|
contentURI: MOCK_URI,
|
|
collectModule: emptyCollectModule.address,
|
|
collectModuleData: [],
|
|
referenceModule: ZERO_ADDRESS,
|
|
referenceModuleData: [],
|
|
})
|
|
).to.not.be.reverted;
|
|
|
|
const pointer = await lensHub.getPubPointer(FIRST_PROFILE_ID, 1);
|
|
expect(pointer[0]).to.eq(0);
|
|
expect(pointer[1]).to.eq(0);
|
|
});
|
|
|
|
it('Publication pointer getter should return the correct pointer for comments', async function () {
|
|
await expect(
|
|
lensHub.connect(governance).whitelistCollectModule(emptyCollectModule.address, true)
|
|
).to.not.be.reverted;
|
|
|
|
await expect(
|
|
lensHub.post({
|
|
profileId: FIRST_PROFILE_ID,
|
|
contentURI: MOCK_URI,
|
|
collectModule: emptyCollectModule.address,
|
|
collectModuleData: [],
|
|
referenceModule: ZERO_ADDRESS,
|
|
referenceModuleData: [],
|
|
})
|
|
).to.not.be.reverted;
|
|
|
|
await expect(
|
|
lensHub.comment({
|
|
profileId: FIRST_PROFILE_ID,
|
|
contentURI: MOCK_URI,
|
|
profileIdPointed: FIRST_PROFILE_ID,
|
|
pubIdPointed: 1,
|
|
collectModule: emptyCollectModule.address,
|
|
collectModuleData: [],
|
|
referenceModule: ZERO_ADDRESS,
|
|
referenceModuleData: [],
|
|
})
|
|
).to.not.be.reverted;
|
|
|
|
const pointer = await lensHub.getPubPointer(FIRST_PROFILE_ID, 2);
|
|
expect(pointer[0]).to.eq(FIRST_PROFILE_ID);
|
|
expect(pointer[1]).to.eq(1);
|
|
});
|
|
|
|
it('Publication pointer getter should return the correct pointer for mirrors', async function () {
|
|
await expect(
|
|
lensHub.connect(governance).whitelistCollectModule(emptyCollectModule.address, true)
|
|
).to.not.be.reverted;
|
|
|
|
await expect(
|
|
lensHub.post({
|
|
profileId: FIRST_PROFILE_ID,
|
|
contentURI: MOCK_URI,
|
|
collectModule: emptyCollectModule.address,
|
|
collectModuleData: [],
|
|
referenceModule: ZERO_ADDRESS,
|
|
referenceModuleData: [],
|
|
})
|
|
).to.not.be.reverted;
|
|
|
|
await expect(
|
|
lensHub.mirror({
|
|
profileId: FIRST_PROFILE_ID,
|
|
profileIdPointed: FIRST_PROFILE_ID,
|
|
pubIdPointed: 1,
|
|
referenceModule: ZERO_ADDRESS,
|
|
referenceModuleData: [],
|
|
})
|
|
).to.not.be.reverted;
|
|
|
|
const pointer = await lensHub.getPubPointer(FIRST_PROFILE_ID, 2);
|
|
expect(pointer[0]).to.eq(FIRST_PROFILE_ID);
|
|
expect(pointer[1]).to.eq(1);
|
|
});
|
|
|
|
it('Publication content URI getter should return the correct URI for posts', async function () {
|
|
await expect(
|
|
lensHub.connect(governance).whitelistCollectModule(emptyCollectModule.address, true)
|
|
).to.not.be.reverted;
|
|
|
|
await expect(
|
|
lensHub.post({
|
|
profileId: FIRST_PROFILE_ID,
|
|
contentURI: MOCK_URI,
|
|
collectModule: emptyCollectModule.address,
|
|
collectModuleData: [],
|
|
referenceModule: ZERO_ADDRESS,
|
|
referenceModuleData: [],
|
|
})
|
|
).to.not.be.reverted;
|
|
|
|
expect(await lensHub.getContentURI(FIRST_PROFILE_ID, 1)).to.eq(MOCK_URI);
|
|
});
|
|
|
|
it('Publication content URI getter should return the correct URI for comments', async function () {
|
|
await expect(
|
|
lensHub.connect(governance).whitelistCollectModule(emptyCollectModule.address, true)
|
|
).to.not.be.reverted;
|
|
|
|
await expect(
|
|
lensHub.post({
|
|
profileId: FIRST_PROFILE_ID,
|
|
contentURI: MOCK_URI,
|
|
collectModule: emptyCollectModule.address,
|
|
collectModuleData: [],
|
|
referenceModule: ZERO_ADDRESS,
|
|
referenceModuleData: [],
|
|
})
|
|
).to.not.be.reverted;
|
|
|
|
await expect(
|
|
lensHub.comment({
|
|
profileId: FIRST_PROFILE_ID,
|
|
contentURI: OTHER_MOCK_URI,
|
|
profileIdPointed: FIRST_PROFILE_ID,
|
|
pubIdPointed: 1,
|
|
collectModule: emptyCollectModule.address,
|
|
collectModuleData: [],
|
|
referenceModule: ZERO_ADDRESS,
|
|
referenceModuleData: [],
|
|
})
|
|
).to.not.be.reverted;
|
|
|
|
expect(await lensHub.getContentURI(FIRST_PROFILE_ID, 2)).to.eq(OTHER_MOCK_URI);
|
|
});
|
|
|
|
it('Publication content URI getter should return the correct URI for mirrors', async function () {
|
|
await expect(
|
|
lensHub.connect(governance).whitelistCollectModule(emptyCollectModule.address, true)
|
|
).to.not.be.reverted;
|
|
|
|
await expect(
|
|
lensHub.post({
|
|
profileId: FIRST_PROFILE_ID,
|
|
contentURI: MOCK_URI,
|
|
collectModule: emptyCollectModule.address,
|
|
collectModuleData: [],
|
|
referenceModule: ZERO_ADDRESS,
|
|
referenceModuleData: [],
|
|
})
|
|
).to.not.be.reverted;
|
|
|
|
await expect(
|
|
lensHub.mirror({
|
|
profileId: FIRST_PROFILE_ID,
|
|
profileIdPointed: FIRST_PROFILE_ID,
|
|
pubIdPointed: 1,
|
|
referenceModule: ZERO_ADDRESS,
|
|
referenceModuleData: [],
|
|
})
|
|
).to.not.be.reverted;
|
|
expect(await lensHub.getContentURI(FIRST_PROFILE_ID, 2)).to.eq(MOCK_URI);
|
|
});
|
|
|
|
it('Publication collect module getter should return the correct collectModule for posts', async function () {
|
|
await expect(
|
|
lensHub.connect(governance).whitelistCollectModule(emptyCollectModule.address, true)
|
|
).to.not.be.reverted;
|
|
|
|
await expect(
|
|
lensHub.post({
|
|
profileId: FIRST_PROFILE_ID,
|
|
contentURI: MOCK_URI,
|
|
collectModule: emptyCollectModule.address,
|
|
collectModuleData: [],
|
|
referenceModule: ZERO_ADDRESS,
|
|
referenceModuleData: [],
|
|
})
|
|
).to.not.be.reverted;
|
|
|
|
expect(await lensHub.getCollectModule(FIRST_PROFILE_ID, 1)).to.eq(emptyCollectModule.address);
|
|
});
|
|
|
|
it('Publication collect module getter should return the correct collectModule for comments', async function () {
|
|
await expect(
|
|
lensHub.connect(governance).whitelistCollectModule(emptyCollectModule.address, true)
|
|
).to.not.be.reverted;
|
|
|
|
await expect(
|
|
lensHub.post({
|
|
profileId: FIRST_PROFILE_ID,
|
|
contentURI: MOCK_URI,
|
|
collectModule: emptyCollectModule.address,
|
|
collectModuleData: [],
|
|
referenceModule: ZERO_ADDRESS,
|
|
referenceModuleData: [],
|
|
})
|
|
).to.not.be.reverted;
|
|
|
|
await expect(
|
|
lensHub.mirror({
|
|
profileId: FIRST_PROFILE_ID,
|
|
profileIdPointed: FIRST_PROFILE_ID,
|
|
pubIdPointed: 1,
|
|
referenceModule: ZERO_ADDRESS,
|
|
referenceModuleData: [],
|
|
})
|
|
).to.not.be.reverted;
|
|
|
|
await expect(
|
|
lensHub.comment({
|
|
profileId: FIRST_PROFILE_ID,
|
|
contentURI: OTHER_MOCK_URI,
|
|
profileIdPointed: FIRST_PROFILE_ID,
|
|
pubIdPointed: 2,
|
|
collectModule: emptyCollectModule.address,
|
|
collectModuleData: [],
|
|
referenceModule: ZERO_ADDRESS,
|
|
referenceModuleData: [],
|
|
})
|
|
).to.not.be.reverted;
|
|
|
|
expect(await lensHub.getCollectModule(FIRST_PROFILE_ID, 3)).to.eq(emptyCollectModule.address);
|
|
});
|
|
|
|
it('Publication collect module getter should return the zero address for mirrors', async function () {
|
|
await expect(
|
|
lensHub.connect(governance).whitelistCollectModule(emptyCollectModule.address, true)
|
|
).to.not.be.reverted;
|
|
|
|
await expect(
|
|
lensHub.post({
|
|
profileId: FIRST_PROFILE_ID,
|
|
contentURI: MOCK_URI,
|
|
collectModule: emptyCollectModule.address,
|
|
collectModuleData: [],
|
|
referenceModule: ZERO_ADDRESS,
|
|
referenceModuleData: [],
|
|
})
|
|
).to.not.be.reverted;
|
|
|
|
await expect(
|
|
lensHub.mirror({
|
|
profileId: FIRST_PROFILE_ID,
|
|
profileIdPointed: FIRST_PROFILE_ID,
|
|
pubIdPointed: 1,
|
|
referenceModule: ZERO_ADDRESS,
|
|
referenceModuleData: [],
|
|
})
|
|
).to.not.be.reverted;
|
|
|
|
expect(await lensHub.getCollectModule(FIRST_PROFILE_ID, 2)).to.eq(ZERO_ADDRESS);
|
|
});
|
|
|
|
it('Publication type getter should return the correct publication type for all publication types, or nonexistent', async function () {
|
|
await expect(
|
|
lensHub.connect(governance).whitelistCollectModule(emptyCollectModule.address, true)
|
|
).to.not.be.reverted;
|
|
|
|
await expect(
|
|
lensHub.post({
|
|
profileId: FIRST_PROFILE_ID,
|
|
contentURI: MOCK_URI,
|
|
collectModule: emptyCollectModule.address,
|
|
collectModuleData: [],
|
|
referenceModule: ZERO_ADDRESS,
|
|
referenceModuleData: [],
|
|
})
|
|
).to.not.be.reverted;
|
|
|
|
await expect(
|
|
lensHub.comment({
|
|
profileId: FIRST_PROFILE_ID,
|
|
contentURI: OTHER_MOCK_URI,
|
|
profileIdPointed: FIRST_PROFILE_ID,
|
|
pubIdPointed: 1,
|
|
collectModule: emptyCollectModule.address,
|
|
collectModuleData: [],
|
|
referenceModule: ZERO_ADDRESS,
|
|
referenceModuleData: [],
|
|
})
|
|
).to.not.be.reverted;
|
|
|
|
await expect(
|
|
lensHub.mirror({
|
|
profileId: FIRST_PROFILE_ID,
|
|
profileIdPointed: FIRST_PROFILE_ID,
|
|
pubIdPointed: 1,
|
|
referenceModule: ZERO_ADDRESS,
|
|
referenceModuleData: [],
|
|
})
|
|
).to.not.be.reverted;
|
|
|
|
expect(await lensHub.getPubType(FIRST_PROFILE_ID, 1)).to.eq(0);
|
|
expect(await lensHub.getPubType(FIRST_PROFILE_ID, 2)).to.eq(1);
|
|
expect(await lensHub.getPubType(FIRST_PROFILE_ID, 3)).to.eq(2);
|
|
expect(await lensHub.getPubType(FIRST_PROFILE_ID, 4)).to.eq(3);
|
|
});
|
|
|
|
it('Profile getter should return accurate profile parameters', async function () {
|
|
const fetchedProfile = await lensHub.getProfile(FIRST_PROFILE_ID);
|
|
expect(fetchedProfile.pubCount).to.eq(0);
|
|
expect(fetchedProfile.handle).to.eq(MOCK_PROFILE_HANDLE);
|
|
expect(fetchedProfile.followModule).to.eq(ZERO_ADDRESS);
|
|
expect(fetchedProfile.followNFT).to.eq(ZERO_ADDRESS);
|
|
});
|
|
});
|
|
|
|
context('Follow Module Misc', function () {
|
|
beforeEach(async function () {
|
|
await expect(
|
|
lensHub.connect(governance).whitelistFollowModule(approvalFollowModule.address, true)
|
|
).to.not.be.reverted;
|
|
|
|
await expect(
|
|
lensHub.createProfile({
|
|
to: userAddress,
|
|
handle: MOCK_PROFILE_HANDLE,
|
|
imageURI: MOCK_PROFILE_URI,
|
|
followModule: approvalFollowModule.address,
|
|
followModuleData: [],
|
|
followNFTURI: MOCK_FOLLOW_NFT_URI,
|
|
})
|
|
).to.not.be.reverted;
|
|
});
|
|
|
|
it('User should fail to call processFollow directly on a follow module inheriting from the FollowValidatorFollowModuleBase', async function () {
|
|
await expect(approvalFollowModule.processFollow(ZERO_ADDRESS, 0, [])).to.be.revertedWith(
|
|
ERRORS.NOT_HUB
|
|
);
|
|
});
|
|
|
|
it('Follow module follow validation when there are no follows, and thus no deployed Follow NFT should revert', async function () {
|
|
await expect(
|
|
approvalFollowModule.validateFollow(FIRST_PROFILE_ID, userTwoAddress, 0)
|
|
).to.be.revertedWith(ERRORS.FOLLOW_INVALID);
|
|
});
|
|
|
|
it('Follow module follow validation with zero ID input should revert after another address follows, but not the queried address', async function () {
|
|
await expect(
|
|
approvalFollowModule.connect(user).approve(FIRST_PROFILE_ID, [userAddress], [true])
|
|
).to.not.be.reverted;
|
|
await expect(lensHub.follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted;
|
|
|
|
await expect(
|
|
approvalFollowModule.validateFollow(FIRST_PROFILE_ID, userTwoAddress, 0)
|
|
).to.be.revertedWith(ERRORS.FOLLOW_INVALID);
|
|
});
|
|
|
|
it('Follow module follow validation with specific ID input should revert after following, but the specific ID does not exist yet', async function () {
|
|
await expect(
|
|
approvalFollowModule.connect(user).approve(FIRST_PROFILE_ID, [userAddress], [true])
|
|
).to.not.be.reverted;
|
|
await expect(lensHub.follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted;
|
|
|
|
await expect(
|
|
approvalFollowModule.validateFollow(FIRST_PROFILE_ID, userAddress, 2)
|
|
).to.be.revertedWith(ERRORS.ERC721_QUERY_FOR_NONEXISTENT_TOKEN);
|
|
});
|
|
|
|
it('Follow module follow validation with specific ID input should revert if another address owns the specified follow NFT', async function () {
|
|
await expect(
|
|
approvalFollowModule.connect(user).approve(FIRST_PROFILE_ID, [userAddress], [true])
|
|
).to.not.be.reverted;
|
|
await expect(lensHub.follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted;
|
|
|
|
await expect(
|
|
approvalFollowModule.validateFollow(FIRST_PROFILE_ID, userTwoAddress, 1)
|
|
).to.be.revertedWith(ERRORS.FOLLOW_INVALID);
|
|
});
|
|
|
|
it('Follow module follow validation with specific ID input should work if the queried address owns the specified follow NFT', async function () {
|
|
await expect(
|
|
approvalFollowModule.connect(user).approve(FIRST_PROFILE_ID, [userAddress], [true])
|
|
).to.not.be.reverted;
|
|
await expect(lensHub.follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted;
|
|
|
|
await expect(
|
|
approvalFollowModule.validateFollow(FIRST_PROFILE_ID, userAddress, 1)
|
|
).to.not.be.reverted;
|
|
});
|
|
});
|
|
|
|
context('Collect Module Misc', function () {
|
|
it('Should fail to call processCollect directly on a collect module inheriting from the FollowValidationModuleBase contract', async function () {
|
|
await expect(
|
|
timedFeeCollectModule.processCollect(0, ZERO_ADDRESS, 0, 0, [])
|
|
).to.be.revertedWith(ERRORS.NOT_HUB);
|
|
});
|
|
});
|
|
|
|
context('Module Globals', function () {
|
|
context('Negatives', function () {
|
|
it('User should fail to set the governance address on the module globals', async function () {
|
|
await expect(moduleGlobals.connect(user).setGovernance(ZERO_ADDRESS)).to.be.revertedWith(
|
|
ERRORS.NOT_GOVERNANCE
|
|
);
|
|
});
|
|
|
|
it('User should fail to set the treasury on the module globals', async function () {
|
|
await expect(moduleGlobals.connect(user).setTreasury(ZERO_ADDRESS)).to.be.revertedWith(
|
|
ERRORS.NOT_GOVERNANCE
|
|
);
|
|
});
|
|
|
|
it('User should fail to set the treasury fee on the module globals', async function () {
|
|
await expect(moduleGlobals.connect(user).setTreasuryFee(0)).to.be.revertedWith(
|
|
ERRORS.NOT_GOVERNANCE
|
|
);
|
|
});
|
|
});
|
|
|
|
context('Scenarios', function () {
|
|
it('Governance should set the governance address on the module globals', async function () {
|
|
await expect(
|
|
moduleGlobals.connect(governance).setGovernance(userAddress)
|
|
).to.not.be.reverted;
|
|
});
|
|
|
|
it('Governance should set the treasury on the module globals', async function () {
|
|
await expect(moduleGlobals.connect(governance).setTreasury(userAddress)).to.not.be.reverted;
|
|
});
|
|
|
|
it('Governance should set the treasury fee on the module globals', async function () {
|
|
await expect(moduleGlobals.connect(governance).setTreasuryFee(0)).to.not.be.reverted;
|
|
});
|
|
|
|
it('Governance should fail to whitelist the zero address as a currency', async function () {
|
|
await expect(
|
|
moduleGlobals.connect(governance).whitelistCurrency(ZERO_ADDRESS, true)
|
|
).to.be.revertedWith(ERRORS.INIT_PARAMS_INVALID);
|
|
});
|
|
|
|
it('Governance getter should return expected address', async function () {
|
|
expect(await moduleGlobals.getGovernance()).to.eq(governanceAddress);
|
|
});
|
|
|
|
it('Treasury getter should return expected address', async function () {
|
|
expect(await moduleGlobals.getTreasury()).to.eq(treasuryAddress);
|
|
});
|
|
|
|
it('Treasury fee getter should return the expected fee', async function () {
|
|
expect(await moduleGlobals.getTreasuryFee()).to.eq(TREASURY_FEE_BPS);
|
|
});
|
|
});
|
|
});
|
|
|
|
context('UI Data Provider', function () {
|
|
it('UI Data Provider should return expected values', async function () {
|
|
// First, create a profile,
|
|
await expect(
|
|
lensHub.createProfile({
|
|
to: userAddress,
|
|
handle: MOCK_PROFILE_HANDLE,
|
|
imageURI: MOCK_PROFILE_URI,
|
|
followModule: ZERO_ADDRESS,
|
|
followModuleData: [],
|
|
followNFTURI: MOCK_FOLLOW_NFT_URI,
|
|
})
|
|
).to.not.be.reverted;
|
|
|
|
// Then, whitelist a collect module
|
|
await expect(
|
|
lensHub.connect(governance).whitelistCollectModule(emptyCollectModule.address, true)
|
|
).to.not.be.reverted;
|
|
|
|
// Then, publish twice
|
|
const firstURI = 'first publication';
|
|
const secondURI = 'second publication';
|
|
await expect(
|
|
lensHub.post({
|
|
profileId: FIRST_PROFILE_ID,
|
|
contentURI: firstURI,
|
|
collectModule: emptyCollectModule.address,
|
|
collectModuleData: [],
|
|
referenceModule: ZERO_ADDRESS,
|
|
referenceModuleData: [],
|
|
})
|
|
).to.not.be.reverted;
|
|
|
|
await expect(
|
|
lensHub.post({
|
|
profileId: FIRST_PROFILE_ID,
|
|
contentURI: secondURI,
|
|
collectModule: emptyCollectModule.address,
|
|
collectModuleData: [],
|
|
referenceModule: ZERO_ADDRESS,
|
|
referenceModuleData: [],
|
|
})
|
|
).to.not.be.reverted;
|
|
|
|
// Then, deploy the data provider
|
|
const dataProvider = await new UIDataProvider__factory(deployer).deploy(lensHub.address);
|
|
|
|
// `getLatestDataByProfile`, validate the result from the data provider
|
|
const resultByProfileId = await dataProvider.getLatestDataByProfile(FIRST_PROFILE_ID);
|
|
const pubByProfileIdStruct = resultByProfileId.publicationStruct;
|
|
const profileByProfileIdStruct = resultByProfileId.profileStruct;
|
|
|
|
expect(profileByProfileIdStruct.pubCount).to.eq(2);
|
|
expect(profileByProfileIdStruct.followModule).to.eq(ZERO_ADDRESS);
|
|
expect(profileByProfileIdStruct.followNFT).to.eq(ZERO_ADDRESS);
|
|
expect(profileByProfileIdStruct.handle).to.eq(MOCK_PROFILE_HANDLE);
|
|
expect(profileByProfileIdStruct.imageURI).to.eq(MOCK_PROFILE_URI);
|
|
expect(profileByProfileIdStruct.followNFTURI).to.eq(MOCK_FOLLOW_NFT_URI);
|
|
|
|
expect(pubByProfileIdStruct.profileIdPointed).to.eq(0);
|
|
expect(pubByProfileIdStruct.pubIdPointed).to.eq(0);
|
|
expect(pubByProfileIdStruct.contentURI).to.eq(secondURI);
|
|
expect(pubByProfileIdStruct.referenceModule).to.eq(ZERO_ADDRESS);
|
|
expect(pubByProfileIdStruct.collectModule).to.eq(emptyCollectModule.address);
|
|
expect(pubByProfileIdStruct.collectNFT).to.eq(ZERO_ADDRESS);
|
|
|
|
// `getLatestDataByHandle`, validate the result from the data provider
|
|
const resultByHandle = await dataProvider.getLatestDataByHandle(MOCK_PROFILE_HANDLE);
|
|
const pubByHandleStruct = resultByHandle.publicationStruct;
|
|
const profileByHandleStruct = resultByHandle.profileStruct;
|
|
|
|
expect(profileByHandleStruct.pubCount).to.eq(2);
|
|
expect(profileByHandleStruct.followModule).to.eq(ZERO_ADDRESS);
|
|
expect(profileByHandleStruct.followNFT).to.eq(ZERO_ADDRESS);
|
|
expect(profileByHandleStruct.handle).to.eq(MOCK_PROFILE_HANDLE);
|
|
expect(profileByHandleStruct.imageURI).to.eq(MOCK_PROFILE_URI);
|
|
expect(profileByHandleStruct.followNFTURI).to.eq(MOCK_FOLLOW_NFT_URI);
|
|
|
|
expect(pubByHandleStruct.profileIdPointed).to.eq(0);
|
|
expect(pubByHandleStruct.pubIdPointed).to.eq(0);
|
|
expect(pubByHandleStruct.contentURI).to.eq(secondURI);
|
|
expect(pubByHandleStruct.referenceModule).to.eq(ZERO_ADDRESS);
|
|
expect(pubByHandleStruct.collectModule).to.eq(emptyCollectModule.address);
|
|
expect(pubByHandleStruct.collectNFT).to.eq(ZERO_ADDRESS);
|
|
});
|
|
});
|
|
});
|