From 1899d006e4b56bb8ec3b8c5402e6beaffbdc4928 Mon Sep 17 00:00:00 2001 From: Abu-Miracle Date: Mon, 2 Sep 2024 21:07:07 -0700 Subject: [PATCH 1/7] test(StudentRegistryV2): register students validations --- contracts/StudentRegistryV2.sol | 28 ++++++++++++++++--------- test/StudentRegistryV2.js | 36 +++++++++++++++++++++++++++++++-- 2 files changed, 52 insertions(+), 12 deletions(-) diff --git a/contracts/StudentRegistryV2.sol b/contracts/StudentRegistryV2.sol index bae95ecb..a596ff64 100644 --- a/contracts/StudentRegistryV2.sol +++ b/contracts/StudentRegistryV2.sol @@ -26,6 +26,7 @@ contract StudentRegistryV2 is Ownable { event authorizeStudentReg(address _studentAddress); event addStud(address _studentAddr); event PaidFee(address indexed payer, uint256 amount); + event registerStudent(address _addr, string name, uint8 age, uint256 time); // Function For Paying function payFee() public payable { @@ -46,30 +47,37 @@ contract StudentRegistryV2 is Ownable { string memory _name, uint8 _age ) public payable { + Student storage student = studentsMapping[msg.sender]; + require(student.hasPaid == true, "You need to pay fees"); require(bytes(_name).length > 0, "No name has been inputed"); - require(_age >= 18, "name should be 18 or more"); - Student storage student = studentsMapping[msg.sender]; + require(_age >= 18, "age should be 18 or more"); student.name = _name; student.age = _age; - emit registerStudent(msg.sender, _name, _age); + emit registerStudent(msg.sender, _name, _age, block.timestamp); } // Function for authorizing registered Student function authorizeStudentRegistration( address _studentAddr ) public onlyOwner { - require( - studentsMapping[_studentAddr].studentAddr == address(0), - "You're already registered" - ); + // require( + // studentsMapping[_studentAddr].studentAddr == address(0), + // "You're already registered" + // ); + Student storage student = studentsMapping[_studentAddr]; + require(student.hasPaid == true, "You need to pay fees"); + require(student.isAuthorized == false, "You have already been authorized"); + student.isAuthorized = true; addStudent(_studentAddr); + students.push(student); emit authorizeStudentReg(_studentAddr); } // Function for Adding student, this function is called in the authorizeStudentRegistration() function - function addStudent(address _studentAddr) private { + function addStudent(address _studentAddr) private onlyOwner() { uint256 _studentId = students.length + 1; - + Student storage student = studentsMapping[_studentAddr]; + student.studentId = _studentId; } // Function to get student by call the ID @@ -127,7 +135,7 @@ contract StudentRegistryV2 is Ownable { } - function getAllStudents() public view returns (Student[] memory students) { + function getAllStudents() public view returns (Student[] memory) { return students; } diff --git a/test/StudentRegistryV2.js b/test/StudentRegistryV2.js index 9c34fb2b..d2c6684b 100644 --- a/test/StudentRegistryV2.js +++ b/test/StudentRegistryV2.js @@ -24,7 +24,7 @@ const toDecimal = (amount) => { return parseFloat(fromEther(amount)); }; -describe("StudentRegistryV2 Test Suite", () => { +describe.only("StudentRegistryV2 Test Suite", () => { // deploy util function const deployUtil = async () => { const StudentRegistryV2 = await ethers.getContractFactory("StudentRegistryV2"); // instance of StudentRegistryV2 contract in Contracts folder @@ -79,7 +79,7 @@ describe("StudentRegistryV2 Test Suite", () => { ); }); - it.only("should revert attempt to payFee multiple times", async () => { + it("should revert attempt to payFee multiple times", async () => { const { deployedStudentRegistryV2, addr1, deployedStudentRegistryV2Address } = await loadFixture(deployUtil); // BEFORE PAYFEE TXN const initialContractBalance = await getBalance(deployedStudentRegistryV2Address); @@ -158,6 +158,38 @@ describe("StudentRegistryV2 Test Suite", () => { .withArgs(addr1.address, ethers.parseEther("1")); }); }); + + describe("Register Students", () => { + describe("Validations", () => { + it("should revert when trying to register without making payment", async () => { + const { deployedStudentRegistryV2, addr1 } = await loadFixture(deployUtil); + + await expect( + deployedStudentRegistryV2.register("John", 20) + ).to.be.revertedWith("You need to pay fees"); + }) + + it("should revert when trying to register with no name", async () => { + const { deployedStudentRegistryV2, addr1 } = await loadFixture(deployUtil); + + await deployedStudentRegistryV2.connect(addr1).payFee({ value: toEther("1")}); + + await expect( + deployedStudentRegistryV2.connect(addr1).register("", 20) + ).to.be.revertedWith("No name has been inputed"); + }) + + it("should revert when trying to register a student who is below the age of 18", async () => { + const { deployedStudentRegistryV2, addr1 } = await loadFixture(deployUtil); + + await deployedStudentRegistryV2.connect(addr1).payFee({ value: toEther("1")}); + + await expect( + deployedStudentRegistryV2.connect(addr1).register("West", 12) + ).to.be.revertedWith("age should be 18 or more"); + }) + }) + }) }); }); }); From 9249800cc2d7f31972338025aaa6e2f389c1b009 Mon Sep 17 00:00:00 2001 From: Abu-Miracle Date: Mon, 2 Sep 2024 21:09:10 -0700 Subject: [PATCH 2/7] test(StudentRegistryV2): successful student register --- test/StudentRegistryV2.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/test/StudentRegistryV2.js b/test/StudentRegistryV2.js index d2c6684b..c6879fbb 100644 --- a/test/StudentRegistryV2.js +++ b/test/StudentRegistryV2.js @@ -189,6 +189,30 @@ describe.only("StudentRegistryV2 Test Suite", () => { ).to.be.revertedWith("age should be 18 or more"); }) }) + + describe("Successful Student Register", () => { + it("should successfully regsiter a student", async () => { + const {deployedStudentRegistryV2, addr1} = await loadFixture(deployUtil); + + // Make Payment + await deployedStudentRegistryV2.connect(addr1).payFee({ value: toEther("1")}); + + // Register Student + await deployedStudentRegistryV2.connect(addr1).register("Daniel", 19); + + const registeredStudent = [ + addr1.address, + "Daniel", + 0, + 19, + true, + false + ] + + const studentMap = await deployedStudentRegistryV2.studentsMapping(addr1); + await expect(...studentMap).to.eq(...registeredStudent); + }) + }) }) }); }); From 5e47d105e6dfccd13231888ab4e09cc0aaf2ddf6 Mon Sep 17 00:00:00 2001 From: Abu-Miracle Date: Mon, 2 Sep 2024 21:30:40 -0700 Subject: [PATCH 3/7] test(StudentRegistryV2): register students events --- contracts/StudentRegistryV2.sol | 4 ++-- test/StudentRegistryV2.js | 15 ++++++++++++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/contracts/StudentRegistryV2.sol b/contracts/StudentRegistryV2.sol index a596ff64..ffc2be01 100644 --- a/contracts/StudentRegistryV2.sol +++ b/contracts/StudentRegistryV2.sol @@ -26,7 +26,7 @@ contract StudentRegistryV2 is Ownable { event authorizeStudentReg(address _studentAddress); event addStud(address _studentAddr); event PaidFee(address indexed payer, uint256 amount); - event registerStudent(address _addr, string name, uint8 age, uint256 time); + event RegisterStudent(address _addr, string name, uint8 age, uint256 time); // Function For Paying function payFee() public payable { @@ -53,7 +53,7 @@ contract StudentRegistryV2 is Ownable { require(_age >= 18, "age should be 18 or more"); student.name = _name; student.age = _age; - emit registerStudent(msg.sender, _name, _age, block.timestamp); + emit RegisterStudent(msg.sender, _name, _age, block.timestamp); } // Function for authorizing registered Student diff --git a/test/StudentRegistryV2.js b/test/StudentRegistryV2.js index c6879fbb..c8af637c 100644 --- a/test/StudentRegistryV2.js +++ b/test/StudentRegistryV2.js @@ -189,7 +189,7 @@ describe.only("StudentRegistryV2 Test Suite", () => { ).to.be.revertedWith("age should be 18 or more"); }) }) - + describe("Successful Student Register", () => { it("should successfully regsiter a student", async () => { const {deployedStudentRegistryV2, addr1} = await loadFixture(deployUtil); @@ -213,6 +213,19 @@ describe.only("StudentRegistryV2 Test Suite", () => { await expect(...studentMap).to.eq(...registeredStudent); }) }) + + describe("Events", () => { + it("should emit an event when a student is registered", async () => { + const {deployedStudentRegistryV2, addr1} = await loadFixture(deployUtil); + + await deployedStudentRegistryV2.connect(addr1).payFee({value: toEther("1")}); + + await expect( + deployedStudentRegistryV2.connect(addr1).register("Sandy", 20) + ).to.emit(deployedStudentRegistryV2, "RegisterStudent") + .withArgs(addr1.address, "Sandy", 20, anyValue) + }) + }) }) }); }); From fd839a3d925a383fa6066214bda2ec438890ddd6 Mon Sep 17 00:00:00 2001 From: Abu-Miracle Date: Mon, 2 Sep 2024 21:53:51 -0700 Subject: [PATCH 4/7] test(StudentRegistryV2): validations for authorization --- test/StudentRegistryV2.js | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/test/StudentRegistryV2.js b/test/StudentRegistryV2.js index c8af637c..ac69155d 100644 --- a/test/StudentRegistryV2.js +++ b/test/StudentRegistryV2.js @@ -227,6 +227,44 @@ describe.only("StudentRegistryV2 Test Suite", () => { }) }) }) + + describe("Authorization", () => { + describe("Validations", () => { + it("should revert when non-owner tries to authorize", async () => { + const {deployedStudentRegistryV2, addr1} = await loadFixture(deployUtil); + + await deployedStudentRegistryV2.connect(addr1).payFee({value: toEther("1")}); + + await deployedStudentRegistryV2.connect(addr1).register("Aaron", 20); + + await expect( + deployedStudentRegistryV2.connect(addr1).authorizeStudentRegistration(addr1) + ).to.be.revertedWith("Caller not owner"); + }) + + it("should revert when trying to authorize student who has not paid", async () => { + const { deployedStudentRegistryV2,owner, addr1 } = await loadFixture(deployUtil); + + await expect( + deployedStudentRegistryV2.connect(owner).authorizeStudentRegistration(addr1) + ).to.be.revertedWith("You need to pay fees"); + }) + + it("should revert when trying to authorize student who has already been authorized", async () => { + const {deployedStudentRegistryV2, owner, addr1} = await loadFixture(deployUtil); + + await deployedStudentRegistryV2.connect(addr1).payFee({value: toEther("1")}); + + await deployedStudentRegistryV2.connect(addr1).register("Aaron", 20); + + await deployedStudentRegistryV2.connect(owner).authorizeStudentRegistration(addr1); + + await expect( + deployedStudentRegistryV2.connect(owner).authorizeStudentRegistration(addr1) + ).to.revertedWith("You have already been authorized"); + }) + }) + }) }); }); }); From 5e308c6842dce15ed22238f2e8ad3fbb2331a4d6 Mon Sep 17 00:00:00 2001 From: Abu-Miracle Date: Mon, 2 Sep 2024 22:11:41 -0700 Subject: [PATCH 5/7] test(StudentRegistryV2): successful authorization --- contracts/StudentRegistryV2.sol | 7 ++++--- test/StudentRegistryV2.js | 29 +++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/contracts/StudentRegistryV2.sol b/contracts/StudentRegistryV2.sol index ffc2be01..bb7fe9cb 100644 --- a/contracts/StudentRegistryV2.sol +++ b/contracts/StudentRegistryV2.sol @@ -23,8 +23,8 @@ contract StudentRegistryV2 is Ownable { string _StName, uint8 _stAge ); - event authorizeStudentReg(address _studentAddress); - event addStud(address _studentAddr); + event AuthorizeStudentReg(address _studentAddress, uint256 time); + event AddStud(address _studentAddr); event PaidFee(address indexed payer, uint256 amount); event RegisterStudent(address _addr, string name, uint8 age, uint256 time); @@ -70,7 +70,7 @@ contract StudentRegistryV2 is Ownable { student.isAuthorized = true; addStudent(_studentAddr); students.push(student); - emit authorizeStudentReg(_studentAddr); + emit AuthorizeStudentReg(_studentAddr, block.timestamp); } // Function for Adding student, this function is called in the authorizeStudentRegistration() function @@ -78,6 +78,7 @@ contract StudentRegistryV2 is Ownable { uint256 _studentId = students.length + 1; Student storage student = studentsMapping[_studentAddr]; student.studentId = _studentId; + emit AddStud(_studentAddr); } // Function to get student by call the ID diff --git a/test/StudentRegistryV2.js b/test/StudentRegistryV2.js index ac69155d..592e76d4 100644 --- a/test/StudentRegistryV2.js +++ b/test/StudentRegistryV2.js @@ -264,6 +264,35 @@ describe.only("StudentRegistryV2 Test Suite", () => { ).to.revertedWith("You have already been authorized"); }) }) + + describe("Successful Authorization", () => { + it("should successfully initialize studentID and isAuthorized in student struct", async () => { + const {deployedStudentRegistryV2, owner, addr1} = await loadFixture(deployUtil); + + await deployedStudentRegistryV2.connect(addr1).payFee({value: toEther("1")}); + await deployedStudentRegistryV2.connect(addr1).register("Aaron", 20); + await deployedStudentRegistryV2.connect(owner).authorizeStudentRegistration(addr1); + + const authorizedStudent = [addr1, "Aaron", 1, 20, true, true]; + + const studentMapping = await deployedStudentRegistryV2.studentsMapping(addr1); + + expect(...authorizedStudent).to.eq(...studentMapping); + }) + + it("should successfully push to student array", async () => { + const {deployedStudentRegistryV2, owner, addr1} = await loadFixture(deployUtil); + + await deployedStudentRegistryV2.connect(addr1).payFee({value: toEther("1")}); + await deployedStudentRegistryV2.connect(addr1).register("Maria", 20); + await deployedStudentRegistryV2.connect(owner).authorizeStudentRegistration(addr1); + + const studentMapping = await deployedStudentRegistryV2.studentsMapping(addr1); + const student1= await deployedStudentRegistryV2.students(0); + + expect(...student1).to.eq(...studentMapping); + }) + }) }) }); }); From 8e0c38c89b3f6f14f5aa6b73387e8c899c9a40a2 Mon Sep 17 00:00:00 2001 From: Abu-Miracle Date: Mon, 2 Sep 2024 22:19:09 -0700 Subject: [PATCH 6/7] test(StudentRegistryV2): authorization events --- test/StudentRegistryV2.js | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/test/StudentRegistryV2.js b/test/StudentRegistryV2.js index 592e76d4..acf5ef81 100644 --- a/test/StudentRegistryV2.js +++ b/test/StudentRegistryV2.js @@ -254,9 +254,7 @@ describe.only("StudentRegistryV2 Test Suite", () => { const {deployedStudentRegistryV2, owner, addr1} = await loadFixture(deployUtil); await deployedStudentRegistryV2.connect(addr1).payFee({value: toEther("1")}); - await deployedStudentRegistryV2.connect(addr1).register("Aaron", 20); - await deployedStudentRegistryV2.connect(owner).authorizeStudentRegistration(addr1); await expect( @@ -293,6 +291,32 @@ describe.only("StudentRegistryV2 Test Suite", () => { expect(...student1).to.eq(...studentMapping); }) }) + + describe("Events", () => { + it("should emit an event when student is added", async () => { + const {deployedStudentRegistryV2, owner, addr1} = await loadFixture(deployUtil); + + await deployedStudentRegistryV2.connect(addr1).payFee({value: toEther("1")}); + await deployedStudentRegistryV2.connect(addr1).register("Aaron", 20); + + await expect( + deployedStudentRegistryV2.connect(owner).authorizeStudentRegistration(addr1) + ).to.emit(deployedStudentRegistryV2, "AddStud") + .withArgs(addr1.address); + }) + + it("should emit an event when student is authorized", async () => { + const {deployedStudentRegistryV2, owner, addr1} = await loadFixture(deployUtil); + + await deployedStudentRegistryV2.connect(addr1).payFee({value: toEther("1")}); + await deployedStudentRegistryV2.connect(addr1).register("Aaron", 20); + + await expect( + deployedStudentRegistryV2.connect(owner).authorizeStudentRegistration(addr1) + ).to.emit(deployedStudentRegistryV2, "AuthorizeStudentReg") + .withArgs(addr1.address, anyValue); + }) + }) }) }); }); From ee5712633d4a96554b5309b53b8d2fc5bc7a4f58 Mon Sep 17 00:00:00 2001 From: Abu-Miracle Date: Thu, 5 Sep 2024 00:23:30 -0700 Subject: [PATCH 7/7] test(StudentRegistryV2): added balance checks --- contracts/StudentRegistryV2.sol | 6 ----- test/StudentRegistryV2.js | 45 ++++++++++++++++++--------------- 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/contracts/StudentRegistryV2.sol b/contracts/StudentRegistryV2.sol index bb7fe9cb..8e40031e 100644 --- a/contracts/StudentRegistryV2.sol +++ b/contracts/StudentRegistryV2.sol @@ -24,7 +24,6 @@ contract StudentRegistryV2 is Ownable { uint8 _stAge ); event AuthorizeStudentReg(address _studentAddress, uint256 time); - event AddStud(address _studentAddr); event PaidFee(address indexed payer, uint256 amount); event RegisterStudent(address _addr, string name, uint8 age, uint256 time); @@ -60,10 +59,6 @@ contract StudentRegistryV2 is Ownable { function authorizeStudentRegistration( address _studentAddr ) public onlyOwner { - // require( - // studentsMapping[_studentAddr].studentAddr == address(0), - // "You're already registered" - // ); Student storage student = studentsMapping[_studentAddr]; require(student.hasPaid == true, "You need to pay fees"); require(student.isAuthorized == false, "You have already been authorized"); @@ -78,7 +73,6 @@ contract StudentRegistryV2 is Ownable { uint256 _studentId = students.length + 1; Student storage student = studentsMapping[_studentAddr]; student.studentId = _studentId; - emit AddStud(_studentAddr); } // Function to get student by call the ID diff --git a/test/StudentRegistryV2.js b/test/StudentRegistryV2.js index acf5ef81..b3430809 100644 --- a/test/StudentRegistryV2.js +++ b/test/StudentRegistryV2.js @@ -104,7 +104,6 @@ describe.only("StudentRegistryV2 Test Suite", () => { expect(finalContractBalanceNum).to.be.closeTo(initialContractBalanceNum + 1, 0.01); // Use a tolerance for floating point comparison const studentsMapping = await deployedStudentRegistryV2.studentsMapping(addr1.address); - console.log("student mapping___", studentsMapping); const expectStudentStruct = [addr1.address, "", "0", "0", true, false]; expect(...studentsMapping).to.eq(...expectStudentStruct); @@ -161,7 +160,7 @@ describe.only("StudentRegistryV2 Test Suite", () => { describe("Register Students", () => { describe("Validations", () => { - it("should revert when trying to register without making payment", async () => { + it("should revert attempt to register without making payment", async () => { const { deployedStudentRegistryV2, addr1 } = await loadFixture(deployUtil); await expect( @@ -169,7 +168,7 @@ describe.only("StudentRegistryV2 Test Suite", () => { ).to.be.revertedWith("You need to pay fees"); }) - it("should revert when trying to register with no name", async () => { + it("should revert attempt to register with no name", async () => { const { deployedStudentRegistryV2, addr1 } = await loadFixture(deployUtil); await deployedStudentRegistryV2.connect(addr1).payFee({ value: toEther("1")}); @@ -179,7 +178,7 @@ describe.only("StudentRegistryV2 Test Suite", () => { ).to.be.revertedWith("No name has been inputed"); }) - it("should revert when trying to register a student who is below the age of 18", async () => { + it("should revert attempt to register a student who is below the age of 18", async () => { const { deployedStudentRegistryV2, addr1 } = await loadFixture(deployUtil); await deployedStudentRegistryV2.connect(addr1).payFee({ value: toEther("1")}); @@ -192,11 +191,29 @@ describe.only("StudentRegistryV2 Test Suite", () => { describe("Successful Student Register", () => { it("should successfully regsiter a student", async () => { - const {deployedStudentRegistryV2, addr1} = await loadFixture(deployUtil); + const {deployedStudentRegistryV2, addr1, deployedStudentRegistryV2Address} = await loadFixture(deployUtil); + + // Check Balance Before txn + const initialContractBalance = await getBalance(deployedStudentRegistryV2Address); + const initialPayerBalance = await getBalance(addr1.address); // Make Payment await deployedStudentRegistryV2.connect(addr1).payFee({ value: toEther("1")}); + const finalPayerBalance = await getBalance(addr1.address); + const finalContractBalance = await getBalance(deployedStudentRegistryV2Address); + + // Assert the balance changes + const initialPayerBalanceNum = parseFloat(ethers.formatEther(initialPayerBalance)); + const finalPayerBalanceNum = parseFloat(ethers.formatEther(finalPayerBalance)); + const initialContractBalanceNum = parseFloat(ethers.formatEther(initialContractBalance)); + const finalContractBalanceNum = parseFloat(ethers.formatEther(finalContractBalance)); + + // Check that the payer's balance decreased by 1 ETH + expect(finalPayerBalanceNum).to.be.closeTo(initialPayerBalanceNum - 1, 0.01); + // Check that the contract's balance increased by 1 ETH + expect(finalContractBalanceNum).to.be.closeTo(initialContractBalanceNum + 1, 0.01); + // Register Student await deployedStudentRegistryV2.connect(addr1).register("Daniel", 19); @@ -230,7 +247,7 @@ describe.only("StudentRegistryV2 Test Suite", () => { describe("Authorization", () => { describe("Validations", () => { - it("should revert when non-owner tries to authorize", async () => { + it("should revert non-owner attwmpt to authorize student", async () => { const {deployedStudentRegistryV2, addr1} = await loadFixture(deployUtil); await deployedStudentRegistryV2.connect(addr1).payFee({value: toEther("1")}); @@ -242,7 +259,7 @@ describe.only("StudentRegistryV2 Test Suite", () => { ).to.be.revertedWith("Caller not owner"); }) - it("should revert when trying to authorize student who has not paid", async () => { + it("should revert attempt to authorize student who has not paid", async () => { const { deployedStudentRegistryV2,owner, addr1 } = await loadFixture(deployUtil); await expect( @@ -250,7 +267,7 @@ describe.only("StudentRegistryV2 Test Suite", () => { ).to.be.revertedWith("You need to pay fees"); }) - it("should revert when trying to authorize student who has already been authorized", async () => { + it("should revert attempt to authorize student who has already been authorized", async () => { const {deployedStudentRegistryV2, owner, addr1} = await loadFixture(deployUtil); await deployedStudentRegistryV2.connect(addr1).payFee({value: toEther("1")}); @@ -293,18 +310,6 @@ describe.only("StudentRegistryV2 Test Suite", () => { }) describe("Events", () => { - it("should emit an event when student is added", async () => { - const {deployedStudentRegistryV2, owner, addr1} = await loadFixture(deployUtil); - - await deployedStudentRegistryV2.connect(addr1).payFee({value: toEther("1")}); - await deployedStudentRegistryV2.connect(addr1).register("Aaron", 20); - - await expect( - deployedStudentRegistryV2.connect(owner).authorizeStudentRegistration(addr1) - ).to.emit(deployedStudentRegistryV2, "AddStud") - .withArgs(addr1.address); - }) - it("should emit an event when student is authorized", async () => { const {deployedStudentRegistryV2, owner, addr1} = await loadFixture(deployUtil);