const { expect } = require('chai'); const { ethers } = require('hardhat'); const { time } = require('@openzeppelin/test-helpers'); describe('GovernanceContract Integration Tests', () => { let governanceContract; let votingContract; let owner; let proposer; let voter1; let voter2; let voter3; beforeEach(async () => { const [deployer, _proposer, _voter1, _voter2, _voter3] = await ethers.getSigners(); owner = deployer; proposer = _proposer; voter1 = _voter1; voter2 = _voter2; voter3 = _voter3; const VotingContract = await ethers.getContractFactory('VotingContract'); const GovernanceContract = await ethers.getContractFactory('GovernanceContract'); votingContract = await VotingContract.deploy(); await votingContract.deployed(); governanceContract = await GovernanceContract.deploy(votingContract.address); await governanceContract.deployed(); }); describe('Proposal Creation and Voting', () => { it('should allow creating a proposal', async () => { const proposalParams = { title: 'Community Fund Allocation', description: 'Proposal to allocate funds for community development', targetAddress: proposer.address, votingPeriod: 604800, // 1 week in seconds requiredQuorum: ethers.utils.parseEther('1000'), // 1000 tokens proposalType: 0 // Assuming 0 is a standard governance proposal }; await governanceContract.connect(proposer).createProposal( proposalParams.title, proposalParams.description, proposalParams.targetAddress, proposalParams.votingPeriod, proposalParams.requiredQuorum, proposalParams.proposalType ); const proposalCount = await governanceContract.getProposalCount(); expect(proposalCount).to.equal(1); const proposal = await governanceContract.getProposal(0); expect(proposal.title).to.equal(proposalParams.title); expect(proposal.proposer).to.equal(proposer.address); }); it('should handle voting on a proposal', async () => { // Create proposal await governanceContract.connect(proposer).createProposal( 'Test Proposal', 'Description', proposer.address, 604800, ethers.utils.parseEther('1000'), 0 ); // Simulate voting power allocation await governanceContract.connect(voter1).delegateVotingPower(voter1.address, ethers.utils.parseEther('500')); await governanceContract.connect(voter2).delegateVotingPower(voter2.address, ethers.utils.parseEther('300')); await governanceContract.connect(voter3).delegateVotingPower(voter3.address, ethers.utils.parseEther('200')); // Cast votes await governanceContract.connect(voter1).castVote(0, true); await governanceContract.connect(voter2).castVote(0, true); await governanceContract.connect(voter3).castVote(0, false); // Advance time to end voting period await time.increase(604800); // Finalize proposal await governanceContract.connect(proposer).finalizeProposal(0); const proposal = await governanceContract.getProposal(0); expect(proposal.status).to.equal(1); // Assuming 1 is PASSED status expect(proposal.votesFor).to.equal(ethers.utils.parseEther('800')); expect(proposal.votesAgainst).to.equal(ethers.utils.parseEther('200')); }); it('should prevent double voting', async () => { await governanceContract.connect(proposer).createProposal( 'Duplicate Vote Test', 'Preventing multiple votes', proposer.address, 604800, ethers.utils.parseEther('1000'), 0 ); await governanceContract.connect(voter1).delegateVotingPower(voter1.address, ethers.utils.parseEther('500')); await governanceContract.connect(voter1).castVote(0, true); await expect( governanceContract.connect(voter1).castVote(0, false) ).to.be.revertedWith('Already voted on this proposal'); }); }); describe('Error Handling', () => { it('should reject proposal creation from unauthorized address', async () => { await expect( governanceContract.connect(voter1).createProposal( 'Unauthorized Proposal', 'Should fail', voter1.address, 604800, ethers.utils.parseEther('1000'), 0 ) ).to.be.revertedWith('Not authorized to create proposal'); }); }); });