From 847c566ef0107cdafe4971800f0c7a39c326af8b Mon Sep 17 00:00:00 2001 From: neila <40727091+neila@users.noreply.github.com> Date: Mon, 22 Jan 2024 14:27:57 +0900 Subject: [PATCH] add deploy and test scripts --- scripts/deploy.ts | 15 +++++ test/Government.ts | 115 +++++++++++++++++++++++++++++++++ test/Medical.ts | 125 ++++++++++++++++++++++++++++++++++++ test/SocialNetwork.ts | 145 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 400 insertions(+) create mode 100644 scripts/deploy.ts create mode 100644 test/Government.ts create mode 100644 test/Medical.ts create mode 100644 test/SocialNetwork.ts diff --git a/scripts/deploy.ts b/scripts/deploy.ts new file mode 100644 index 0000000..0046e5b --- /dev/null +++ b/scripts/deploy.ts @@ -0,0 +1,15 @@ +import { ethers } from "hardhat" + +async function main() { + const submission = await ethers.getContractFactory("SocialNetworkExample") + const contract = await submission.deploy() + + await contract.deployed() + + console.log(`Contract deployed to ${contract.address}`) +} + +main().catch((error) => { + console.error(error) + process.exitCode = 1 +}) diff --git a/test/Government.ts b/test/Government.ts new file mode 100644 index 0000000..972cbee --- /dev/null +++ b/test/Government.ts @@ -0,0 +1,115 @@ +import { loadFixture, time } from "@nomicfoundation/hardhat-network-helpers" +import { expect } from "chai" +import { ethers } from "hardhat" + +import { IGovernment } from "../typechain-types/interfaces" + +describe("Government", function () { + async function deployContract() { + const accounts = await ethers.getSigners() + + const governmentFactory = await ethers.getContractFactory("Government") + const government = (await governmentFactory.deploy()) as IGovernment + + return { + government, + deployAccount: accounts[0], + userAccounts: accounts.slice(1, accounts.length), + } + } + + describe("Run for", function () { + it("run for & check the address is registered as candidate.", async function () { + const { government, userAccounts } = await loadFixture(deployContract) + const candidate1 = userAccounts[0] + await government.connect(candidate1).runForCandidate() + + expect(await government.isCandidate(candidate1.address)).to.equal(true) + }) + + it("check a address is not registered as a candidate before running for.", async function () { + const { government, userAccounts } = await loadFixture(deployContract) + const someone = userAccounts[0] + + expect(await government.isCandidate(someone.address)).to.equal(false) + }) + }) + + describe("Vote", function () { + it("someone run for & check the number of vote is initially zero.", async function () { + const { government, userAccounts } = await loadFixture(deployContract) + const candidate1 = userAccounts[0] + await government.connect(candidate1).runForCandidate() + + expect(await government.numberOfVotes(candidate1.address)).to.equal(0) + }) + + it("Revert transaction if there is a double vote.", async function () { + const { government, userAccounts } = await loadFixture(deployContract) + + const candidate1 = userAccounts[0] + const voter1 = userAccounts[1] + + await government.connect(candidate1).runForCandidate() + + // first time + await government.connect(voter1).vote(candidate1.address) + // second time -> revert + await expect(government.connect(voter1).vote(candidate1.address)).to.be + .reverted + }) + + it("Revert transaction if there is a vote after abstain.", async function () { + const { government, userAccounts } = await loadFixture(deployContract) + + const candidate1 = userAccounts[0] + const voter1 = userAccounts[1] + + await government.connect(candidate1).runForCandidate() + + // abstain. + await government.connect(voter1).abstain() + // vote -> revert + await expect(government.connect(voter1).vote(candidate1.address)).to.be + .reverted + }) + }) + + describe("Determine winner", function () { + it("Candidates run for & voters vote & determine president & check president.", async function () { + const { government, userAccounts } = await loadFixture(deployContract) + + const threeWeeksInSeconds = 60 * 60 * 24 * 7 * 3 + const numOfCandidates = 3 + const indexOfPresident = 1 + const candidates = userAccounts.slice(0, numOfCandidates) + const voters = userAccounts.slice(numOfCandidates, userAccounts.length) + + // Run for. + for (let index = 0; index < candidates.length; index++) { + await government.connect(candidates[index]).runForCandidate() + } + + // Vote. + for (let voterIndex = 0; voterIndex < voters.length; voterIndex++) { + let candidateIndexToVote: number = voterIndex % numOfCandidates + if (candidateIndexToVote === 0 || candidateIndexToVote === 1) { + candidateIndexToVote = indexOfPresident + } + await government + .connect(voters[voterIndex]) + .vote(candidates[candidateIndexToVote].address) + } + + // Adjust the end time. + await time.increase(threeWeeksInSeconds) + + // Determine president. + await government.determinePresident() + + expect(await government.getPresident()).to.equal( + candidates[indexOfPresident].address, + ) + }) + }) +}) diff --git a/test/Medical.ts b/test/Medical.ts new file mode 100644 index 0000000..04ba044 --- /dev/null +++ b/test/Medical.ts @@ -0,0 +1,125 @@ +import { loadFixture } from "@nomicfoundation/hardhat-network-helpers" +import { expect } from "chai" +import { ethers } from "hardhat" + +import { IMedical } from "../typechain-types/interfaces" + +describe("Medical", function () { + async function deploy() { + const accounts = await ethers.getSigners() + const deployAccount = accounts[0] + const userAccounts = accounts.slice(1, accounts.length) + + // Deploy. + const medicalFactory = await ethers.getContractFactory("Medical") + const medical = (await medicalFactory.deploy()) as IMedical + + return { + medical, + deployAccount, + userAccounts, + } + } + + async function deployAndRegister() { + const { medical, deployAccount, userAccounts } = await loadFixture(deploy) + + const patient = userAccounts[0] + const otherAccounts = userAccounts.slice(1, userAccounts.length) + + const defaultName = "Default patient" + const defaultBloodType = "A" + await medical.connect(patient).register(defaultName, defaultBloodType) + return { + medical, + deployAccount, + patient, + otherAccounts, + defaultName, + defaultBloodType, + } + } + + describe("Register and get data.", function () { + it("Verify that the correct name is registered.", async function () { + const { medical, patient, defaultName } = await deployAndRegister() + + const { name } = await medical + .connect(patient) + .getMedicalData(patient.address) + + expect(name).to.equal(defaultName) + }) + + it("Verify that the correct blood type is registered.", async function () { + const { medical, patient, defaultBloodType } = await deployAndRegister() + + const { bloodType } = await medical + .connect(patient) + .getMedicalData(patient.address) + + expect(bloodType).to.equal(defaultBloodType) + }) + + // Skip the test of time of last update because it's implementation-dependent. + }) + + describe("Edit medical data", function () { + it("Patients can update their name.", async function () { + const { medical, patient } = await deployAndRegister() + + const newName = "new name" + await medical.connect(patient).updateName(newName) + + const { name } = await medical + .connect(patient) + .getMedicalData(patient.address) + + expect(name).to.equal(newName) + }) + + it("Patients can update their blood type.", async function () { + const { medical, patient } = await deployAndRegister() + + const newBloodType = "B" + await medical.connect(patient).updateBloodType(newBloodType) + + const { bloodType } = await medical + .connect(patient) + .getMedicalData(patient.address) + + expect(bloodType).to.equal(newBloodType) + }) + }) + + describe("Viewing access", function () { + it("No viewing access by default.", async function () { + const { medical, patient, otherAccounts } = await deployAndRegister() + + const medicalProvider = otherAccounts[0] + + expect( + await medical.isViewingAccessGranted( + patient.address, + medicalProvider.address, + ), + ).to.equal(false) + }) + + it("Check viewing access after provided.", async function () { + const { medical, patient, otherAccounts } = await deployAndRegister() + + const medicalProvider = otherAccounts[0] + await medical + .connect(patient) + .provideViewingAccess(medicalProvider.address) + + expect( + await medical.isViewingAccessGranted( + patient.address, + medicalProvider.address, + ), + ).to.equal(true) + }) + }) +}) diff --git a/test/SocialNetwork.ts b/test/SocialNetwork.ts new file mode 100644 index 0000000..7d83dba --- /dev/null +++ b/test/SocialNetwork.ts @@ -0,0 +1,145 @@ +import { loadFixture } from "@nomicfoundation/hardhat-network-helpers" +import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers" +import { expect } from "chai" +import { BigNumber } from "ethers" +import { ethers } from "hardhat" + +import { ISocialNetwork } from "../typechain-types/interfaces" + +describe("SocialNetwork", function () { + async function deployContract() { + const accounts = await ethers.getSigners() + + const snsFactory = await ethers.getContractFactory("SocialNetwork") + const socialNetwork = (await snsFactory.deploy()) as ISocialNetwork + + return { + socialNetwork, + deployAccount: accounts[0], + userAccounts: accounts.slice(1, accounts.length), + } + } + + async function postAndGetId( + socialNetwork: ISocialNetwork, + signer: SignerWithAddress, + msg: string, + ) { + await socialNetwork.connect(signer).post(msg) + return await socialNetwork.getLastPostId() + } + + describe("Post and get post", function () { + async function deployAndPost() { + const { socialNetwork, deployAccount } = await loadFixture(deployContract) + const msg = "first post" + const id = await postAndGetId(socialNetwork, deployAccount, msg) + return { socialNetwork, id, msg } + } + + it("Post and verify that the correct message is posted.", async function () { + const { socialNetwork, id, msg } = await deployAndPost() + + const { message } = await socialNetwork.getPost(id) + expect(message).to.equal(msg) + }) + + it("Post and verify that the correct number of likes is posted.", async function () { + const { socialNetwork, id } = await deployAndPost() + + const { totalLikes } = await socialNetwork.getPost(id) + expect(totalLikes).to.equal(0) + }) + + // Skip the test of time of post because it's implementation-dependent. + + it("Post multiple and verify that the correct messages is posted.", async function () { + const { socialNetwork, userAccounts } = await loadFixture(deployContract) + + type PostType = { + id: BigNumber + msg: string + } + + const allPosts: PostType[] = [] + + // Multiple post and store the data in allPosts. + for (let i = 0; i < userAccounts.length; i++) { + const newMsg = userAccounts[i].address + const newId = await postAndGetId(socialNetwork, userAccounts[i], newMsg) + const newPost: PostType = { + id: newId, + msg: newMsg, + } + allPosts.push(newPost) + } + + for (const post of allPosts) { + const { message } = await socialNetwork.getPost(post.id) + expect(message).to.equal(post.msg) + } + }) + }) + + describe("Like", function () { + it("The total number of likes is increase if one account like.", async function () { + const { socialNetwork, userAccounts } = await loadFixture(deployContract) + + const accountToPost = userAccounts[0] + const accountToLike = userAccounts[1] + + const id = await postAndGetId(socialNetwork, accountToPost, "message") + const { totalLikes: totalLikesBefore } = await socialNetwork.getPost(id) + + await socialNetwork.connect(accountToLike).like(id) + + const { totalLikes: totalLikesAfter } = await socialNetwork.getPost(id) + expect(totalLikesAfter.sub(totalLikesBefore)).to.equal(1) + }) + + it("The total number of likes is increase if multiple accounts like.", async function () { + const { socialNetwork, userAccounts } = await loadFixture(deployContract) + + const accountToPost = userAccounts[0] + const otherAccounts = userAccounts.slice(1, userAccounts.length) + + const id = await postAndGetId(socialNetwork, accountToPost, "message") + const { totalLikes: totalLikesBefore } = await socialNetwork.getPost(id) + + for (let i = 0; i < otherAccounts.length; i++) { + await socialNetwork.connect(otherAccounts[i]).like(id) + } + + const { totalLikes: totalLikesAfter } = await socialNetwork.getPost(id) + expect(totalLikesAfter.sub(totalLikesBefore)).to.equal( + otherAccounts.length, + ) + }) + }) + + describe("unlike", function () { + it("The total number of likes is decrease if one account unlike.", async function () { + const { socialNetwork, userAccounts } = await loadFixture(deployContract) + + const accountToPost = userAccounts[0] + const accountToUnlike = userAccounts[1] + + const id = await postAndGetId(socialNetwork, accountToPost, "message") + const { totalLikes: totalLikesBefore } = await socialNetwork.getPost(id) + + await socialNetwork.connect(accountToUnlike).like(id) + + const { totalLikes: totalLikesAfterLike } = await socialNetwork.getPost( + id, + ) + expect(totalLikesAfterLike.sub(totalLikesBefore)).to.equal(1) + + await socialNetwork.connect(accountToUnlike).unlike(id) + + const { totalLikes: totalLikesAfterUnlike } = await socialNetwork.getPost( + id, + ) + expect(totalLikesAfterUnlike.sub(totalLikesBefore)).to.equal(0) + }) + }) +})