mirror of
https://github.com/lens-protocol/core.git
synced 2026-01-10 06:38:05 -05:00
396 lines
14 KiB
TypeScript
396 lines
14 KiB
TypeScript
import '@nomiclabs/hardhat-ethers';
|
|
import { expect } from 'chai';
|
|
import { FollowNFT__factory } from '../../../typechain-types';
|
|
import { ZERO_ADDRESS } from '../../helpers/constants';
|
|
import { ERRORS } from '../../helpers/errors';
|
|
import { getTimestamp, matchEvent, waitForTx } from '../../helpers/utils';
|
|
import {
|
|
freeCollectModule,
|
|
FIRST_PROFILE_ID,
|
|
followerOnlyReferenceModule,
|
|
governance,
|
|
lensHub,
|
|
makeSuiteCleanRoom,
|
|
MOCK_FOLLOW_NFT_URI,
|
|
MOCK_PROFILE_HANDLE,
|
|
MOCK_PROFILE_URI,
|
|
MOCK_URI,
|
|
user,
|
|
userAddress,
|
|
userThreeAddress,
|
|
userTwo,
|
|
userTwoAddress,
|
|
abiCoder,
|
|
} from '../../__setup.spec';
|
|
|
|
makeSuiteCleanRoom('Follower Only Reference Module', function () {
|
|
const SECOND_PROFILE_ID = FIRST_PROFILE_ID + 1;
|
|
|
|
beforeEach(async function () {
|
|
await expect(
|
|
lensHub.createProfile({
|
|
to: userAddress,
|
|
handle: MOCK_PROFILE_HANDLE,
|
|
imageURI: MOCK_PROFILE_URI,
|
|
followModule: ZERO_ADDRESS,
|
|
followModuleInitData: [],
|
|
followNFTURI: MOCK_FOLLOW_NFT_URI,
|
|
})
|
|
).to.not.be.reverted;
|
|
await expect(
|
|
lensHub.createProfile({
|
|
to: userTwoAddress,
|
|
handle: 'user2',
|
|
imageURI: MOCK_PROFILE_URI,
|
|
followModule: ZERO_ADDRESS,
|
|
followModuleInitData: [],
|
|
followNFTURI: MOCK_FOLLOW_NFT_URI,
|
|
})
|
|
).to.not.be.reverted;
|
|
await expect(
|
|
lensHub
|
|
.connect(governance)
|
|
.whitelistReferenceModule(followerOnlyReferenceModule.address, true)
|
|
).to.not.be.reverted;
|
|
await expect(
|
|
lensHub.connect(governance).whitelistCollectModule(freeCollectModule.address, true)
|
|
).to.not.be.reverted;
|
|
await expect(
|
|
lensHub.post({
|
|
profileId: FIRST_PROFILE_ID,
|
|
contentURI: MOCK_URI,
|
|
collectModule: freeCollectModule.address,
|
|
collectModuleInitData: abiCoder.encode(['bool'], [true]),
|
|
referenceModule: followerOnlyReferenceModule.address,
|
|
referenceModuleInitData: [],
|
|
})
|
|
).to.not.be.reverted;
|
|
});
|
|
|
|
context('Negatives', function () {
|
|
// We don't need a `publishing` or `initialization` context because initialization never reverts in the FollowerOnlyReferenceModule.
|
|
context('Commenting', function () {
|
|
it('Commenting should fail if commenter is not a follower and follow NFT not yet deployed', async function () {
|
|
await expect(
|
|
lensHub.connect(userTwo).comment({
|
|
profileId: SECOND_PROFILE_ID,
|
|
contentURI: MOCK_URI,
|
|
profileIdPointed: FIRST_PROFILE_ID,
|
|
pubIdPointed: 1,
|
|
collectModule: freeCollectModule.address,
|
|
collectModuleInitData: abiCoder.encode(['bool'], [true]),
|
|
referenceModuleData: [],
|
|
referenceModule: ZERO_ADDRESS,
|
|
referenceModuleInitData: [],
|
|
})
|
|
).to.be.revertedWith(ERRORS.FOLLOW_INVALID);
|
|
});
|
|
|
|
it('Commenting should fail if commenter follows, then transfers the follow NFT before attempting to comment', async function () {
|
|
await expect(lensHub.connect(userTwo).follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted;
|
|
const followNFT = FollowNFT__factory.connect(
|
|
await lensHub.getFollowNFT(FIRST_PROFILE_ID),
|
|
user
|
|
);
|
|
|
|
await expect(
|
|
followNFT.connect(userTwo).transferFrom(userTwoAddress, userThreeAddress, 1)
|
|
).to.not.be.reverted;
|
|
|
|
await expect(
|
|
lensHub.connect(userTwo).comment({
|
|
profileId: SECOND_PROFILE_ID,
|
|
contentURI: MOCK_URI,
|
|
profileIdPointed: FIRST_PROFILE_ID,
|
|
pubIdPointed: 1,
|
|
collectModule: freeCollectModule.address,
|
|
collectModuleInitData: abiCoder.encode(['bool'], [true]),
|
|
referenceModuleData: [],
|
|
referenceModule: ZERO_ADDRESS,
|
|
referenceModuleInitData: [],
|
|
})
|
|
).to.be.revertedWith(ERRORS.FOLLOW_INVALID);
|
|
});
|
|
});
|
|
|
|
context('Mirroring', function () {
|
|
it('Mirroring should fail if mirrorer is not a follower and follow NFT not yet deployed', async function () {
|
|
await expect(
|
|
lensHub.connect(userTwo).mirror({
|
|
profileId: SECOND_PROFILE_ID,
|
|
profileIdPointed: FIRST_PROFILE_ID,
|
|
pubIdPointed: 1,
|
|
referenceModuleData: [],
|
|
referenceModule: ZERO_ADDRESS,
|
|
referenceModuleInitData: [],
|
|
})
|
|
).to.be.revertedWith(ERRORS.FOLLOW_INVALID);
|
|
});
|
|
|
|
it('Mirroring should fail if mirrorer follows, then transfers the follow NFT before attempting to mirror', async function () {
|
|
await expect(lensHub.connect(userTwo).follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted;
|
|
const followNFT = FollowNFT__factory.connect(
|
|
await lensHub.getFollowNFT(FIRST_PROFILE_ID),
|
|
user
|
|
);
|
|
|
|
await expect(
|
|
followNFT.connect(userTwo).transferFrom(userTwoAddress, userAddress, 1)
|
|
).to.not.be.reverted;
|
|
|
|
await expect(
|
|
lensHub.connect(userTwo).mirror({
|
|
profileId: SECOND_PROFILE_ID,
|
|
profileIdPointed: FIRST_PROFILE_ID,
|
|
pubIdPointed: 1,
|
|
referenceModuleData: [],
|
|
referenceModule: ZERO_ADDRESS,
|
|
referenceModuleInitData: [],
|
|
})
|
|
).to.be.revertedWith(ERRORS.FOLLOW_INVALID);
|
|
});
|
|
});
|
|
});
|
|
|
|
context('Scenarios', function () {
|
|
context('Publishing', function () {
|
|
it('Posting with follower only reference module as reference module should emit expected events', async function () {
|
|
const tx = lensHub.post({
|
|
profileId: FIRST_PROFILE_ID,
|
|
contentURI: MOCK_URI,
|
|
collectModule: freeCollectModule.address,
|
|
collectModuleInitData: abiCoder.encode(['bool'], [true]),
|
|
referenceModule: followerOnlyReferenceModule.address,
|
|
referenceModuleInitData: [],
|
|
});
|
|
const receipt = await waitForTx(tx);
|
|
|
|
expect(receipt.logs.length).to.eq(1);
|
|
matchEvent(receipt, 'PostCreated', [
|
|
FIRST_PROFILE_ID,
|
|
2,
|
|
MOCK_URI,
|
|
freeCollectModule.address,
|
|
abiCoder.encode(['bool'], [true]),
|
|
followerOnlyReferenceModule.address,
|
|
[],
|
|
await getTimestamp(),
|
|
]);
|
|
});
|
|
});
|
|
|
|
context('Commenting', function () {
|
|
it('Commenting should work if the commenter is a follower', async function () {
|
|
await expect(lensHub.connect(userTwo).follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted;
|
|
const followNFT = FollowNFT__factory.connect(
|
|
await lensHub.getFollowNFT(FIRST_PROFILE_ID),
|
|
user
|
|
);
|
|
|
|
await expect(
|
|
lensHub.connect(userTwo).comment({
|
|
profileId: SECOND_PROFILE_ID,
|
|
contentURI: MOCK_URI,
|
|
profileIdPointed: FIRST_PROFILE_ID,
|
|
pubIdPointed: 1,
|
|
collectModule: freeCollectModule.address,
|
|
collectModuleInitData: abiCoder.encode(['bool'], [true]),
|
|
referenceModuleData: [],
|
|
referenceModule: ZERO_ADDRESS,
|
|
referenceModuleInitData: [],
|
|
})
|
|
).to.not.be.reverted;
|
|
});
|
|
|
|
it('Commenting should work if the commenter is the publication owner and he is following himself', async function () {
|
|
await expect(lensHub.follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted;
|
|
const followNFT = FollowNFT__factory.connect(
|
|
await lensHub.getFollowNFT(FIRST_PROFILE_ID),
|
|
user
|
|
);
|
|
|
|
await expect(
|
|
lensHub.comment({
|
|
profileId: FIRST_PROFILE_ID,
|
|
contentURI: MOCK_URI,
|
|
profileIdPointed: FIRST_PROFILE_ID,
|
|
pubIdPointed: 1,
|
|
referenceModuleData: [],
|
|
collectModule: freeCollectModule.address,
|
|
collectModuleInitData: abiCoder.encode(['bool'], [true]),
|
|
referenceModule: ZERO_ADDRESS,
|
|
referenceModuleInitData: [],
|
|
})
|
|
).to.not.be.reverted;
|
|
});
|
|
|
|
it('Commenting should work if the commenter is the publication owner even when he is not following himself and follow NFT was not deployed', async function () {
|
|
await expect(
|
|
lensHub.comment({
|
|
profileId: FIRST_PROFILE_ID,
|
|
contentURI: MOCK_URI,
|
|
profileIdPointed: FIRST_PROFILE_ID,
|
|
pubIdPointed: 1,
|
|
referenceModuleData: [],
|
|
collectModule: freeCollectModule.address,
|
|
collectModuleInitData: abiCoder.encode(['bool'], [true]),
|
|
referenceModule: ZERO_ADDRESS,
|
|
referenceModuleInitData: [],
|
|
})
|
|
).to.not.be.reverted;
|
|
});
|
|
|
|
it('Commenting should work if the commenter is the publication owner even when he is not following himself and follow NFT was deployed', async function () {
|
|
await expect(lensHub.follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted;
|
|
const followNFT = FollowNFT__factory.connect(
|
|
await lensHub.getFollowNFT(FIRST_PROFILE_ID),
|
|
user
|
|
);
|
|
|
|
await expect(followNFT.transferFrom(userAddress, userTwoAddress, 1)).to.not.be.reverted;
|
|
|
|
await expect(
|
|
lensHub.comment({
|
|
profileId: FIRST_PROFILE_ID,
|
|
contentURI: MOCK_URI,
|
|
profileIdPointed: FIRST_PROFILE_ID,
|
|
pubIdPointed: 1,
|
|
referenceModuleData: [],
|
|
collectModule: freeCollectModule.address,
|
|
collectModuleInitData: abiCoder.encode(['bool'], [true]),
|
|
referenceModule: ZERO_ADDRESS,
|
|
referenceModuleInitData: [],
|
|
})
|
|
).to.not.be.reverted;
|
|
});
|
|
|
|
it('Commenting should work if the commenter follows, transfers the follow NFT then receives it back before attempting to comment', async function () {
|
|
await expect(lensHub.connect(userTwo).follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted;
|
|
const followNFT = FollowNFT__factory.connect(
|
|
await lensHub.getFollowNFT(FIRST_PROFILE_ID),
|
|
user
|
|
);
|
|
|
|
await expect(
|
|
followNFT.connect(userTwo).transferFrom(userTwoAddress, userAddress, 1)
|
|
).to.not.be.reverted;
|
|
|
|
await expect(followNFT.transferFrom(userAddress, userTwoAddress, 1)).to.not.be.reverted;
|
|
|
|
await expect(
|
|
lensHub.connect(userTwo).comment({
|
|
profileId: SECOND_PROFILE_ID,
|
|
contentURI: MOCK_URI,
|
|
profileIdPointed: FIRST_PROFILE_ID,
|
|
pubIdPointed: 1,
|
|
collectModule: freeCollectModule.address,
|
|
collectModuleInitData: abiCoder.encode(['bool'], [true]),
|
|
referenceModuleData: [],
|
|
referenceModule: ZERO_ADDRESS,
|
|
referenceModuleInitData: [],
|
|
})
|
|
).to.not.be.reverted;
|
|
});
|
|
});
|
|
|
|
context('Mirroring', function () {
|
|
it('Mirroring should work if mirrorer is a follower', async function () {
|
|
await expect(lensHub.connect(userTwo).follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted;
|
|
const followNFT = FollowNFT__factory.connect(
|
|
await lensHub.getFollowNFT(FIRST_PROFILE_ID),
|
|
user
|
|
);
|
|
|
|
await expect(
|
|
lensHub.connect(userTwo).mirror({
|
|
profileId: SECOND_PROFILE_ID,
|
|
profileIdPointed: FIRST_PROFILE_ID,
|
|
pubIdPointed: 1,
|
|
referenceModuleData: [],
|
|
referenceModule: ZERO_ADDRESS,
|
|
referenceModuleInitData: [],
|
|
})
|
|
).to.not.be.reverted;
|
|
});
|
|
|
|
it('Mirroring should work if mirrorer follows, transfers the follow NFT then receives it back before attempting to mirror', async function () {
|
|
await expect(lensHub.connect(userTwo).follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted;
|
|
const followNFT = FollowNFT__factory.connect(
|
|
await lensHub.getFollowNFT(FIRST_PROFILE_ID),
|
|
user
|
|
);
|
|
|
|
await expect(
|
|
followNFT.connect(userTwo).transferFrom(userTwoAddress, userAddress, 1)
|
|
).to.not.be.reverted;
|
|
|
|
await expect(followNFT.transferFrom(userAddress, userTwoAddress, 1)).to.not.be.reverted;
|
|
|
|
await expect(
|
|
lensHub.connect(userTwo).mirror({
|
|
profileId: SECOND_PROFILE_ID,
|
|
profileIdPointed: FIRST_PROFILE_ID,
|
|
pubIdPointed: 1,
|
|
referenceModuleData: [],
|
|
referenceModule: ZERO_ADDRESS,
|
|
referenceModuleInitData: [],
|
|
})
|
|
).to.not.be.reverted;
|
|
});
|
|
|
|
it('Mirroring should work if the mirrorer is the publication owner and he is following himself', async function () {
|
|
await expect(lensHub.follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted;
|
|
const followNFT = FollowNFT__factory.connect(
|
|
await lensHub.getFollowNFT(FIRST_PROFILE_ID),
|
|
user
|
|
);
|
|
|
|
await expect(
|
|
lensHub.mirror({
|
|
profileId: FIRST_PROFILE_ID,
|
|
profileIdPointed: FIRST_PROFILE_ID,
|
|
pubIdPointed: 1,
|
|
referenceModuleData: [],
|
|
referenceModule: ZERO_ADDRESS,
|
|
referenceModuleInitData: [],
|
|
})
|
|
).to.not.be.reverted;
|
|
});
|
|
|
|
it('Mirroring should work if the mirrorer is the publication owner even when he is not following himself and follow NFT was not deployed', async function () {
|
|
await expect(
|
|
lensHub.mirror({
|
|
profileId: FIRST_PROFILE_ID,
|
|
profileIdPointed: FIRST_PROFILE_ID,
|
|
pubIdPointed: 1,
|
|
referenceModuleData: [],
|
|
referenceModule: ZERO_ADDRESS,
|
|
referenceModuleInitData: [],
|
|
})
|
|
).to.not.be.reverted;
|
|
});
|
|
|
|
it('Mirroring should work if the mirrorer is the publication owner even when he is not following himself and follow NFT was deployed', async function () {
|
|
await expect(lensHub.follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted;
|
|
const followNFT = FollowNFT__factory.connect(
|
|
await lensHub.getFollowNFT(FIRST_PROFILE_ID),
|
|
user
|
|
);
|
|
|
|
await expect(followNFT.transferFrom(userAddress, userTwoAddress, 1)).to.not.be.reverted;
|
|
|
|
await expect(
|
|
lensHub.mirror({
|
|
profileId: FIRST_PROFILE_ID,
|
|
profileIdPointed: FIRST_PROFILE_ID,
|
|
pubIdPointed: 1,
|
|
referenceModuleData: [],
|
|
referenceModule: ZERO_ADDRESS,
|
|
referenceModuleInitData: [],
|
|
})
|
|
).to.not.be.reverted;
|
|
});
|
|
});
|
|
});
|
|
});
|