Skip to content

Commit

Permalink
Updated README.md file as well as Voting test file.
Browse files Browse the repository at this point in the history
  • Loading branch information
manthis committed Dec 21, 2023
1 parent 6db99d2 commit 31afba2
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 121 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,17 @@ Vous devez alors fournir les tests unitaires de votre smart contract Nous n’at

## :point_right: Stratégie de test

Le plan de test est simple: passer en revue l'ensemble des méthodes du contract _Voting.sol_. Pour cela nous avons effectué les tâches suivantes:

- Définit un objet _WorkflowStatus_ pour répliquer l'enum des différents états du workflow qui se trouve dans le contrat _Voting.sol_.
- Définit nos fixtures pour préparer notre environnement pour nos tests. J'ai pris l'initiative de n'utiliser que des fixtures et aucun appel aux fonctions natives de mocha: _before_ et _beforeEach_. Afin d'améliorer mon code j'ai pris le parti de composer mes fixtures avec des fonctions que je peux réutiliser dans différentes fixtures.
- Définit nos tests unitaires en passant sur chaque méthode. Chaque méthode correspond à un _describe_ qui contient plusieurs tests propre à cette dernière. Pour chaque méthode et afin de déterminer les tests à réaliser nous avons suivi les étapes suivantes:
- Tester le/les modifiers
- Tester les différents require
- Tester les événements émis
- Tester un cas de succès
- Eventuels autres tests

## :point_right: Coverage

### Hardhat tests run
Expand Down
Binary file modified resources/coverage.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
250 changes: 129 additions & 121 deletions test/Voting.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,178 +120,186 @@ describe('Voting', function () {
});
});

describe('Registration', function () {
it('should revert if not called by the owner', async function () {
const { voting, addr1 } = await loadFixture(contractInitializationFixture);
describe('General contract methods', function () {
describe('addVoter', function () {
it('should revert if not called by the owner', async function () {
const { voting, addr1 } = await loadFixture(contractInitializationFixture);

expect(voting.connect(addr1).addVoter(addr1.address)).to.be.revertedWith(
'Ownable: caller is not the owner',
);
});
expect(voting.connect(addr1).addVoter(addr1.address)).to.be.revertedWith(
'Ownable: caller is not the owner',
);
});

it('should revert if voters registration is not open', async function () {
const { voting, owner, addr1 } = await loadFixture(contractStartPropositionsRegisteringFixture);
it('should revert if voters registration is not open', async function () {
const { voting, owner, addr1 } = await loadFixture(contractStartPropositionsRegisteringFixture);

expect(voting.connect(owner).addVoter(addr1.address)).to.be.revertedWith(
'Voters registration is not open yet',
);
});
expect(voting.connect(owner).addVoter(addr1.address)).to.be.revertedWith(
'Voters registration is not open yet',
);
});

it('should revert if the voter is already registered', async function () {
const { voting, owner, addr1 } = await loadFixture(contractInitializationFixture);
await voting.connect(owner).addVoter(addr1.address);
it('should revert if the voter is already registered', async function () {
const { voting, owner, addr1 } = await loadFixture(contractInitializationFixture);
await voting.connect(owner).addVoter(addr1.address);

expect(voting.connect(owner).addVoter(addr1.address)).to.be.revertedWith('Already registered');
});
expect(voting.connect(owner).addVoter(addr1.address)).to.be.revertedWith('Already registered');
});

it('should add a voter when called by the owner', async function () {
const { voting, owner, addr1 } = await loadFixture(contractInitializationFixture);
await voting.connect(owner).addVoter(addr1.address);
const voter = [true, false, BigInt(0)];
it('should add a voter when called by the owner', async function () {
const { voting, owner, addr1 } = await loadFixture(contractInitializationFixture);
await voting.connect(owner).addVoter(addr1.address);
const voter = [true, false, BigInt(0)];

expect(await voting.connect(addr1).getVoter(addr1.address)).to.eql(voter);
});
expect(await voting.connect(addr1).getVoter(addr1.address)).to.eql(voter);
});

it('should emit a VoterRegistered event on success', async function () {
const { voting, owner, addr1 } = await loadFixture(contractInitializationFixture);
it('should emit a VoterRegistered event on success', async function () {
const { voting, owner, addr1 } = await loadFixture(contractInitializationFixture);

expect(voting.connect(owner).addVoter(addr1.address))
.to.emit(voting, 'VoterRegistered')
.withArgs(addr1.address);
expect(voting.connect(owner).addVoter(addr1.address))
.to.emit(voting, 'VoterRegistered')
.withArgs(addr1.address);
});
});
});

describe('Proposals', function () {
it('should revert if not called by a voter', async function () {
const { voting, owner } = await loadFixture(contractInitializationFixture);
describe('addProposal', function () {
it('should revert if not called by a voter', async function () {
const { voting, owner } = await loadFixture(contractInitializationFixture);

expect(voting.connect(owner).addProposal('Alyra')).to.be.revertedWith(`You're not a voter!`);
});
expect(voting.connect(owner).addProposal('Alyra')).to.be.revertedWith(`You're not a voter!`);
});

it('should revert if proposals registration is not open', async function () {
const { voting, owner, addr1 } = await loadFixture(contractInitializationFixture);
await voting.connect(owner).addVoter(addr1.address);
it('should revert if proposals registration is not open', async function () {
const { voting, owner, addr1 } = await loadFixture(contractInitializationFixture);
await voting.connect(owner).addVoter(addr1.address);

expect(voting.connect(addr1).addProposal('Alyra')).to.be.revertedWith('Proposals are not allowed yet');
});
expect(voting.connect(addr1).addProposal('Alyra')).to.be.revertedWith(
'Proposals are not allowed yet',
);
});

it('should revert if proposition is empty', async function () {
const { voting, owner, addr1 } = await loadFixture(contractStartPropositionsRegisteringFixture);
it('should revert if proposition is empty', async function () {
const { voting, owner, addr1 } = await loadFixture(contractStartPropositionsRegisteringFixture);

expect(voting.connect(addr1).addProposal('')).to.be.revertedWith('Vous ne pouvez pas ne rien proposer');
});
expect(voting.connect(addr1).addProposal('')).to.be.revertedWith(
'Vous ne pouvez pas ne rien proposer',
);
});

it('should add a proposal when called by a voter', async function () {
const { voting, owner, addr1 } = await loadFixture(contractStartPropositionsRegisteringFixture);
await voting.connect(addr1).addProposal('Alyra');
const proposal = ['Alyra', BigInt(0)];
it('should add a proposal when called by a voter', async function () {
const { voting, owner, addr1 } = await loadFixture(contractStartPropositionsRegisteringFixture);
await voting.connect(addr1).addProposal('Alyra');
const proposal = ['Alyra', BigInt(0)];

expect(await voting.connect(addr1).getOneProposal(1)).to.eql(proposal);
});
expect(await voting.connect(addr1).getOneProposal(1)).to.eql(proposal);
});

it('should emit a ProposalRegistered event on success', async function () {
const { voting, owner, addr1 } = await loadFixture(contractStartPropositionsRegisteringFixture);
it('should emit a ProposalRegistered event on success', async function () {
const { voting, owner, addr1 } = await loadFixture(contractStartPropositionsRegisteringFixture);

expect(voting.connect(addr1).addProposal('GENESIS')).to.emit(voting, 'ProposalRegistered').withArgs(1);
expect(voting.connect(addr1).addProposal('GENESIS'))
.to.emit(voting, 'ProposalRegistered')
.withArgs(1);
});
});
});

describe('Voting', function () {
it('should revert if not called by a voter', async function () {
const { voting, owner, addr1 } = await loadFixture(contractInitializationFixture);
describe('setVote', function () {
it('should revert if not called by a voter', async function () {
const { voting, owner, addr1 } = await loadFixture(contractInitializationFixture);

expect(voting.connect(owner).setVote(0)).to.be.revertedWith(`You're not a voter!`);
});
expect(voting.connect(owner).setVote(0)).to.be.revertedWith(`You're not a voter!`);
});

it('should revert if id is out of bounds', async function () {
const { voting, owner, addr1 } = await loadFixture(contractStartVotingFixture);
it('should revert if id is out of bounds', async function () {
const { voting, owner, addr1 } = await loadFixture(contractStartVotingFixture);

expect(voting.connect(addr1).setVote(3)).to.be.revertedWith('Proposal not found');
});
expect(voting.connect(addr1).setVote(3)).to.be.revertedWith('Proposal not found');
});

it('should revert if voter already voted', async function () {
const { voting, owner, addr1 } = await loadFixture(contractStartVotingAndVoteFixture);
it('should revert if voter already voted', async function () {
const { voting, owner, addr1 } = await loadFixture(contractStartVotingAndVoteFixture);

expect(voting.connect(addr1).setVote(1)).to.be.revertedWith('You have already voted');
});
expect(voting.connect(addr1).setVote(1)).to.be.revertedWith('You have already voted');
});

it('should revert if voting session is not started', async function () {
const { voting, owner, addr1 } = await loadFixture(contractInitializationFixture);
await voting.connect(owner).addVoter(addr1.address);
it('should revert if voting session is not started', async function () {
const { voting, owner, addr1 } = await loadFixture(contractInitializationFixture);
await voting.connect(owner).addVoter(addr1.address);

expect(voting.connect(addr1).setVote(0)).to.be.revertedWith('Voting session havent started yet');
});
expect(voting.connect(addr1).setVote(0)).to.be.revertedWith('Voting session havent started yet');
});

it('should emit a Voted event on success', async function () {
const { voting, owner, addr1 } = await loadFixture(contractStartVotingFixture);
it('should emit a Voted event on success', async function () {
const { voting, owner, addr1 } = await loadFixture(contractStartVotingFixture);

expect(voting.connect(addr1).setVote(1)).to.emit(voting, 'Voted').withArgs(addr1.address, 1);
});
expect(voting.connect(addr1).setVote(1)).to.emit(voting, 'Voted').withArgs(addr1.address, 1);
});

it('should increment the vote count of a proposition', async function () {
const { voting, owner, addr1 } = await loadFixture(contractStartVotingAndVoteFixture);
const proposal = ['Alyra', BigInt(1)];
it('should increment the vote count of a proposition', async function () {
const { voting, owner, addr1 } = await loadFixture(contractStartVotingAndVoteFixture);
const proposal = ['Alyra', BigInt(1)];

expect(await voting.connect(addr1).getOneProposal(1)).to.eql(proposal);
});
expect(await voting.connect(addr1).getOneProposal(1)).to.eql(proposal);
});

it('should set the hadVoted property of the user struc to true', async function () {
const { voting, owner, addr1 } = await loadFixture(contractStartVotingAndVoteFixture);
const voter = await voting.connect(addr1).getVoter(addr1.address);
it('should set the hadVoted property of the user struc to true', async function () {
const { voting, owner, addr1 } = await loadFixture(contractStartVotingAndVoteFixture);
const voter = await voting.connect(addr1).getVoter(addr1.address);

expect(voter.hasVoted).to.be.true;
});
expect(voter.hasVoted).to.be.true;
});

it('should set the votedProposalId property of the user struct to the id of the voted proposal', async function () {
const { voting, owner, addr1 } = await loadFixture(contractStartVotingAndVoteFixture);
const voter = await voting.connect(addr1).getVoter(addr1.address);
it('should set the votedProposalId property of the user struct to the id of the voted proposal', async function () {
const { voting, owner, addr1 } = await loadFixture(contractStartVotingAndVoteFixture);
const voter = await voting.connect(addr1).getVoter(addr1.address);

expect(voter.votedProposalId).to.be.equal(1);
expect(voter.votedProposalId).to.be.equal(1);
});
});
});

describe('Tallying', function () {
it('should revert if not called by the owner', async function () {
const { voting, owner, addr1 } = await loadFixture(contractStartVotingAndVoteFixture);
describe('tallyVotes', function () {
it('should revert if not called by the owner', async function () {
const { voting, owner, addr1 } = await loadFixture(contractStartVotingAndVoteFixture);

expect(voting.connect(addr1).tallyVotes()).to.be.revertedWith(`Ownable: caller is not the owner`);
});
expect(voting.connect(addr1).tallyVotes()).to.be.revertedWith(`Ownable: caller is not the owner`);
});

it('should revert if voting session has not ended', async function () {
const { voting, owner } = await loadFixture(contractStartVotingFixture);
it('should revert if voting session has not ended', async function () {
const { voting, owner } = await loadFixture(contractStartVotingFixture);

expect(voting.connect(owner).tallyVotes()).to.be.revertedWith(
'Current status is not voting session ended',
);
});
expect(voting.connect(owner).tallyVotes()).to.be.revertedWith(
'Current status is not voting session ended',
);
});

it('should emit a WorkflowStatusChange event on success', async function () {
const { voting, owner } = await loadFixture(contractStartVotingAndVoteFixture);
await voting.connect(owner).endVotingSession();
it('should emit a WorkflowStatusChange event on success', async function () {
const { voting, owner } = await loadFixture(contractStartVotingAndVoteFixture);
await voting.connect(owner).endVotingSession();

expect(await voting.connect(owner).tallyVotes())
.to.emit(voting, 'WorkflowStatusChange')
.withArgs(WorkflowStatus.VotingSessionEnded, WorkflowStatus.VotesTallied);
});
expect(await voting.connect(owner).tallyVotes())
.to.emit(voting, 'WorkflowStatusChange')
.withArgs(WorkflowStatus.VotingSessionEnded, WorkflowStatus.VotesTallied);
});

it('should have definied workflowStatus to VotesTallied', async function () {
const { voting, owner } = await loadFixture(contractStartVotingAndVoteFixture);
await voting.connect(owner).endVotingSession();
await voting.connect(owner).tallyVotes();
it('should have definied workflowStatus to VotesTallied', async function () {
const { voting, owner } = await loadFixture(contractStartVotingAndVoteFixture);
await voting.connect(owner).endVotingSession();
await voting.connect(owner).tallyVotes();

expect(await voting.workflowStatus()).to.be.equal(WorkflowStatus.VotesTallied);
});
expect(await voting.workflowStatus()).to.be.equal(WorkflowStatus.VotesTallied);
});

it('should set winningProposalID with the winning proposal id', async function () {
const { voting, owner } = await loadFixture(contractStartVotingAndVoteFixture);
await voting.connect(owner).endVotingSession();
await voting.connect(owner).tallyVotes();
it('should set winningProposalID with the winning proposal id', async function () {
const { voting, owner } = await loadFixture(contractStartVotingAndVoteFixture);
await voting.connect(owner).endVotingSession();
await voting.connect(owner).tallyVotes();

expect(await voting.winningProposalID()).to.be.equal(1);
expect(await voting.winningProposalID()).to.be.equal(1);
});
});
});

describe('Workflow', function () {
describe('Workflow states handling methods', function () {
describe('startProposalRegistering', function () {
it('should revert if not called by the owner', async function () {
const { voting, owner, addr1 } = await loadFixture(contractInitializationFixture);
Expand Down

0 comments on commit 31afba2

Please sign in to comment.