Skip to content

Commit

Permalink
Merge pull request #38 from BigWhaleLabs/contract-test-setup
Browse files Browse the repository at this point in the history
Add basic tests for KetlCred
  • Loading branch information
wilsonplau authored Jul 12, 2023
2 parents 97a2d00 + 65138e7 commit 587b0e8
Show file tree
Hide file tree
Showing 8 changed files with 5,975 additions and 290 deletions.
1 change: 1 addition & 0 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import '@nomiclabs/hardhat-etherscan'
import '@nomiclabs/hardhat-waffle'
import '@openzeppelin/hardhat-upgrades'
import '@typechain/hardhat'
import 'hardhat-gas-reporter'
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"@ethersproject/providers": "^5.7.2",
"@nomiclabs/hardhat-ethers": "^2.2.3",
"@nomiclabs/hardhat-etherscan": "^3.1.7",
"@nomiclabs/hardhat-waffle": "^2.0.3",
"@opengsn/contracts": "^3.0.0-beta.6",
"@openzeppelin/contracts": "^4.8.3",
"@typechain/ethers-v5": "^10.2.1",
Expand All @@ -60,6 +61,7 @@
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-sort-imports-es6-autofix": "^0.6.0",
"ethereum-waffle": "^3.4.4",
"ethers": "^5.7.2",
"hardhat": "^2.14.0",
"hardhat-gas-reporter": "^1.0.9",
Expand Down
156 changes: 156 additions & 0 deletions test/OBSSStorage.ketlkred.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import { Feeds, KetlCred, OBSSStorage, Profiles } from '../typechain'
import { MOCK_CID, zeroAddress } from './utils'
import { ethers, upgrades } from 'hardhat'
import { expect } from 'chai'
import { getFakeKetlAttestationContract } from './utils/fakes'
import { version } from '../package.json'

describe('OBSSStorage: KetlCred', () => {
before(async function () {
this.accounts = await ethers.getSigners()
this.owner = this.accounts[0]
this.user = this.accounts[1]

this.fakeKetlAttestationContract = await getFakeKetlAttestationContract(
this.owner
)
await this.fakeKetlAttestationContract.mock.balanceOf.returns(1)
await this.fakeKetlAttestationContract.mock.currentTokenId.returns(1)

this.profilesFactory = await ethers.getContractFactory('Profiles')
this.ketlCredFactory = await ethers.getContractFactory('KetlCred')
this.feedsFactory = await ethers.getContractFactory('Feeds')
this.obssStorageFactory = await ethers.getContractFactory('OBSSStorage')
})

describe('grantKetlCred: feedPosts', () => {
beforeEach(async function () {
this.profiles = (await upgrades.deployProxy(this.profilesFactory, [
this.fakeKetlAttestationContract.address,
0,
this.owner.address,
])) as Profiles
this.ketlCred = (await upgrades.deployProxy(
this.ketlCredFactory,
['Ketl', 'KETL', 0, this.owner.address],
{
initializer: 'initializeKetlCred',
}
)) as KetlCred
this.feeds = (await upgrades.deployProxy(this.feedsFactory, [
this.fakeKetlAttestationContract.address,
0,
this.owner.address,
])) as Feeds
this.obssStorage = (await upgrades.deployProxy(
this.obssStorageFactory,
[
zeroAddress,
version,
this.ketlCred.address,
this.profiles.address,
this.feeds.address,
],
{
initializer: 'initialize',
}
)) as OBSSStorage

await this.ketlCred.setAllowedCaller(this.obssStorage.address)
await this.profiles.setAllowedCaller(this.obssStorage.address)
await this.feeds.setAllowedCaller(this.obssStorage.address)

await this.feeds.addFeed(MOCK_CID)
await this.obssStorage.addFeedPost({
feedId: 0,
postMetadata: MOCK_CID,
})
})

it('should grant KetlCred when feedPost is upvoted by different user', async function () {
await this.obssStorage.connect(this.user).addFeedReaction({
feedId: 0,
postId: 0,
commentId: 0,
reactionType: 1,
})
expect(await this.ketlCred.balanceOf(this.owner.address)).to.equal(1)
})
it('should not grant KetlCred when feedPost is downvoted by user', async function () {
await this.obssStorage.connect(this.user).addFeedReaction({
feedId: 0,
postId: 0,
commentId: 0,
reactionType: 2,
})
expect(await this.ketlCred.balanceOf(this.owner.address)).to.equal(0)
})
it('should not grant KetlCred when feedPost is upvoted by author', async function () {
await this.obssStorage.connect(this.owner).addFeedReaction({
feedId: 0,
postId: 0,
commentId: 0,
reactionType: 1,
})
expect(await this.ketlCred.balanceOf(this.owner.address)).to.equal(0)
})
it('should not burn KetlCred when upvote is replaced with downvote', async function () {
await this.obssStorage.connect(this.user).addFeedReaction({
feedId: 0,
postId: 0,
commentId: 0,
reactionType: 1,
})
const reactionBefore = await this.feeds.usersToReactions(
0,
0,
0,
this.user.address
)
expect(reactionBefore.reactionType).to.equal(1)
await this.obssStorage.connect(this.user).addFeedReaction({
feedId: 0,
postId: 0,
commentId: 0,
reactionType: 2,
})
const reactionAfter = await this.feeds.usersToReactions(
0,
0,
0,
this.user.address
)
expect(reactionAfter.reactionType).to.equal(2)
expect(await this.ketlCred.balanceOf(this.owner.address)).to.equal(1)
})
it('should not burn KetlCred when upvote is removed', async function () {
await this.obssStorage.connect(this.user).addFeedReaction({
feedId: 0,
postId: 0,
commentId: 0,
reactionType: 1,
})
const reactionBefore = await this.feeds.usersToReactions(
0,
0,
0,
this.user.address
)
expect(reactionBefore.reactionType).to.equal(1)
await this.obssStorage.connect(this.user).removeFeedReaction({
feedId: 0,
postId: 0,
commentId: 0,
reactionId: reactionBefore.reactionId,
})
const reactionAfter = await this.feeds.usersToReactions(
0,
0,
0,
this.user.address
)
expect(reactionAfter.sender).to.equal(zeroAddress)
expect(await this.ketlCred.balanceOf(this.owner.address)).to.equal(1)
})
})
})
4 changes: 2 additions & 2 deletions test/OBSSStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import { zeroAddress } from './utils'

describe('OBSSStorage contract tests', () => {
before(async function () {
this.factory = await ethers.getContractFactory('OBSSStorage')
this.obssStorageFactory = await ethers.getContractFactory('OBSSStorage')
})

describe('Constructor', function () {
it('should deploy the contract with the correct fields', async function () {
const version = 'v0.0.1'
const contract = await upgrades.deployProxy(
this.factory,
this.obssStorageFactory,
[zeroAddress, version, zeroAddress, zeroAddress, zeroAddress],
{
initializer: 'initialize',
Expand Down
30 changes: 28 additions & 2 deletions test/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,33 @@
import type { OBSSStorage__factory } from '../typechain'
import { MockContract } from 'ethereum-waffle'
import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'
import type {
Feeds,
Feeds__factory,
KetlCred,
KetlCred__factory,
OBSSStorage,
OBSSStorage__factory,
Profiles,
Profiles__factory,
} from '../typechain'

declare module 'mocha' {
export interface Context {
factory: OBSSStorage__factory
// Factories for contracts
profilesFactory: Profiles__factory
feedsFactory: Feeds__factory
ketlCredFactory: KetlCred__factory
obssStorageFactory: OBSSStorage__factory
// Contract instances
profiles: Profiles
feeds: Feeds
ketlCred: KetlCred
obssStorage: OBSSStorage
// Mock contracts
fakeKetlAttestationContract: MockContract
// Signers
accounts: SignerWithAddress[]
owner: SignerWithAddress
user: SignerWithAddress
}
}
39 changes: 39 additions & 0 deletions test/utils/fakes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'
import { allowMapInput } from '.'
import { deployMockContract } from 'ethereum-waffle'

export async function getFakeCommitmentProof() {
return {
a: [1, 2],
b: [
[1, 2],
[3, 4],
],
c: [1, 2],
input: await allowMapInput(),
}
}

export async function getFakeKetlAttestationContract(
signer: SignerWithAddress
) {
return await deployMockContract(signer, [
{
inputs: [
{ internalType: 'address', name: 'account', type: 'address' },
{ internalType: 'uint256', name: 'id', type: 'uint256' },
],
name: 'balanceOf',
outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],
stateMutability: 'view',
type: 'function',
},
{
inputs: [],
name: 'currentTokenId',
outputs: [{ internalType: 'uint32', name: '', type: 'uint32' }],
stateMutability: 'view',
type: 'function',
},
])
}
14 changes: 1 addition & 13 deletions test/utils.ts → test/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,7 @@ function generateRandomBytes32(): string {
return `0x${crypto.randomBytes(32).toString('hex')}`
}

export async function getFakeCommitmentProof() {
return {
a: [1, 2],
b: [
[1, 2],
[3, 4],
],
c: [1, 2],
input: await allowMapInput(),
}
}

async function allowMapInput() {
export async function allowMapInput() {
const randomUint256 = () => BigNumber.from(randomBytes(32)).toBigInt()
const thousandRandomUint256 = Array.from({ length: 1000 }, randomUint256)
const leaf = thousandRandomUint256[0]
Expand Down
Loading

0 comments on commit 587b0e8

Please sign in to comment.