171 lines
7.1 KiB
TypeScript
171 lines
7.1 KiB
TypeScript
|
|
import { expect } from "chai";
|
||
|
|
import { ethers } from "hardhat";
|
||
|
|
import { DocumentRegistry } from "../typechain-types";
|
||
|
|
import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers";
|
||
|
|
|
||
|
|
/**
|
||
|
|
* DocumentRegistry Smart Contract Tests
|
||
|
|
*
|
||
|
|
* These tests verify all core functionality:
|
||
|
|
* 1. Document registration with timestamp
|
||
|
|
* 2. Document verification
|
||
|
|
* 3. Duplicate prevention
|
||
|
|
* 4. Non-existent document handling
|
||
|
|
* 5. Depositor document tracking
|
||
|
|
* 6. Ownership controls
|
||
|
|
*/
|
||
|
|
describe("DocumentRegistry", function () {
|
||
|
|
let registry: DocumentRegistry;
|
||
|
|
let owner: SignerWithAddress;
|
||
|
|
let user1: SignerWithAddress;
|
||
|
|
let user2: SignerWithAddress;
|
||
|
|
|
||
|
|
// Sample document hashes (simulating SHA-256 hashes)
|
||
|
|
const docHash1 = ethers.keccak256(ethers.toUtf8Bytes("contract-insurance-auto-2024.pdf"));
|
||
|
|
const docHash2 = ethers.keccak256(ethers.toUtf8Bytes("contract-home-loan-2024.pdf"));
|
||
|
|
const docHash3 = ethers.keccak256(ethers.toUtf8Bytes("contract-health-insurance.pdf"));
|
||
|
|
|
||
|
|
beforeEach(async function () {
|
||
|
|
// Get test accounts (Hardhat provides 20 free accounts)
|
||
|
|
[owner, user1, user2] = await ethers.getSigners();
|
||
|
|
|
||
|
|
// Deploy new contract instance before each test
|
||
|
|
const DocumentRegistryFactory = await ethers.getContractFactory("DocumentRegistry");
|
||
|
|
registry = await DocumentRegistryFactory.deploy();
|
||
|
|
await registry.waitForDeployment();
|
||
|
|
});
|
||
|
|
|
||
|
|
// ═══════════════════════════════════════════════════
|
||
|
|
// DEPLOYMENT TESTS
|
||
|
|
// ═══════════════════════════════════════════════════
|
||
|
|
|
||
|
|
describe("Deployment", function () {
|
||
|
|
it("should set the deployer as owner", async function () {
|
||
|
|
expect(await registry.owner()).to.equal(owner.address);
|
||
|
|
});
|
||
|
|
|
||
|
|
it("should start with zero documents", async function () {
|
||
|
|
expect(await registry.totalDocuments()).to.equal(0);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
// ═══════════════════════════════════════════════════
|
||
|
|
// REGISTRATION TESTS
|
||
|
|
// ═══════════════════════════════════════════════════
|
||
|
|
|
||
|
|
describe("Document Registration", function () {
|
||
|
|
it("should register a document and emit event", async function () {
|
||
|
|
const tx = await registry.registerDocument(docHash1);
|
||
|
|
const receipt = await tx.wait();
|
||
|
|
|
||
|
|
// Verify event was emitted
|
||
|
|
await expect(tx)
|
||
|
|
.to.emit(registry, "DocumentRegistered")
|
||
|
|
.withArgs(docHash1, (await ethers.provider.getBlock(receipt!.blockNumber))!.timestamp, owner.address);
|
||
|
|
});
|
||
|
|
|
||
|
|
it("should store correct timestamp", async function () {
|
||
|
|
const tx = await registry.registerDocument(docHash1);
|
||
|
|
const receipt = await tx.wait();
|
||
|
|
const block = await ethers.provider.getBlock(receipt!.blockNumber);
|
||
|
|
|
||
|
|
const timestamp = await registry.getTimestamp(docHash1);
|
||
|
|
expect(timestamp).to.equal(block!.timestamp);
|
||
|
|
});
|
||
|
|
|
||
|
|
it("should increment totalDocuments counter", async function () {
|
||
|
|
await registry.registerDocument(docHash1);
|
||
|
|
expect(await registry.totalDocuments()).to.equal(1);
|
||
|
|
|
||
|
|
await registry.registerDocument(docHash2);
|
||
|
|
expect(await registry.totalDocuments()).to.equal(2);
|
||
|
|
});
|
||
|
|
|
||
|
|
it("should prevent duplicate registration (same hash)", async function () {
|
||
|
|
await registry.registerDocument(docHash1);
|
||
|
|
|
||
|
|
await expect(
|
||
|
|
registry.registerDocument(docHash1)
|
||
|
|
).to.be.revertedWith("Document already registered on-chain");
|
||
|
|
});
|
||
|
|
|
||
|
|
it("should prevent non-owners from registering documents", async function () {
|
||
|
|
await expect(
|
||
|
|
registry.connect(user1).registerDocument(docHash1)
|
||
|
|
).to.be.revertedWith("Only owner can call this function");
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
// ═══════════════════════════════════════════════════
|
||
|
|
// VERIFICATION TESTS
|
||
|
|
// ═══════════════════════════════════════════════════
|
||
|
|
|
||
|
|
describe("Document Verification", function () {
|
||
|
|
it("should verify a registered document", async function () {
|
||
|
|
await registry.registerDocument(docHash1);
|
||
|
|
|
||
|
|
const [exists, timestamp, depositor] = await registry.verifyDocument(docHash1);
|
||
|
|
expect(exists).to.be.true;
|
||
|
|
expect(timestamp).to.be.greaterThan(0);
|
||
|
|
expect(depositor).to.equal(owner.address);
|
||
|
|
});
|
||
|
|
|
||
|
|
it("should return false for unregistered document", async function () {
|
||
|
|
const fakeHash = ethers.keccak256(ethers.toUtf8Bytes("non-existent.pdf"));
|
||
|
|
|
||
|
|
const [exists, timestamp, depositor] = await registry.verifyDocument(fakeHash);
|
||
|
|
expect(exists).to.be.false;
|
||
|
|
expect(timestamp).to.equal(0);
|
||
|
|
expect(depositor).to.equal(ethers.ZeroAddress);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
// ═══════════════════════════════════════════════════
|
||
|
|
// DEPOSITOR TRACKING TESTS
|
||
|
|
// ═══════════════════════════════════════════════════
|
||
|
|
|
||
|
|
describe("Depositor Tracking", function () {
|
||
|
|
it("should track all documents by a depositor", async function () {
|
||
|
|
await registry.registerDocument(docHash1);
|
||
|
|
await registry.registerDocument(docHash2);
|
||
|
|
|
||
|
|
const docs = await registry.getDocumentsByDepositor(owner.address);
|
||
|
|
expect(docs.length).to.equal(2);
|
||
|
|
expect(docs[0]).to.equal(docHash1);
|
||
|
|
expect(docs[1]).to.equal(docHash2);
|
||
|
|
});
|
||
|
|
|
||
|
|
it("should return correct document count", async function () {
|
||
|
|
await registry.registerDocument(docHash1);
|
||
|
|
await registry.registerDocument(docHash2);
|
||
|
|
await registry.registerDocument(docHash3);
|
||
|
|
|
||
|
|
expect(await registry.getDocumentCount(owner.address)).to.equal(3);
|
||
|
|
expect(await registry.getDocumentCount(user2.address)).to.equal(0);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
// ═══════════════════════════════════════════════════
|
||
|
|
// OWNERSHIP TESTS
|
||
|
|
// ═══════════════════════════════════════════════════
|
||
|
|
|
||
|
|
describe("Ownership", function () {
|
||
|
|
it("should transfer ownership", async function () {
|
||
|
|
await registry.transferOwnership(user1.address);
|
||
|
|
expect(await registry.owner()).to.equal(user1.address);
|
||
|
|
});
|
||
|
|
|
||
|
|
it("should prevent non-owner from transferring ownership", async function () {
|
||
|
|
await expect(
|
||
|
|
registry.connect(user1).transferOwnership(user2.address)
|
||
|
|
).to.be.revertedWith("Only owner can call this function");
|
||
|
|
});
|
||
|
|
|
||
|
|
it("should prevent transfer to zero address", async function () {
|
||
|
|
await expect(
|
||
|
|
registry.transferOwnership(ethers.ZeroAddress)
|
||
|
|
).to.be.revertedWith("New owner cannot be zero address");
|
||
|
|
});
|
||
|
|
});
|
||
|
|
});
|