> ## Documentation Index
> Fetch the complete documentation index at: https://core.anylayer.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Hardhat Testing

> Test ZKScore contracts using Hardhat testing framework

## Overview

Complete guide for testing ZKScore smart contracts using Hardhat testing framework.

## Prerequisites

* **Hardhat**: v2.17.0 or higher
* **Node.js**: v16.0.0 or higher
* **Test Tokens**: ETH for testing transactions

## Setup

### Installation

```bash theme={null}
npm install --save-dev hardhat @nomicfoundation/hardhat-toolbox
npx hardhat init
```

### Configuration

```javascript theme={null}
// hardhat.config.js
require("@nomicfoundation/hardhat-toolbox");

module.exports = {
  solidity: "0.8.19",
  networks: {
    hardhat: {
      chainId: 31337
    },
    localhost: {
      url: "http://127.0.0.1:8545"
    }
  }
};
```

## Test Structure

### Basic Test Setup

<CodeGroup>
  ```javascript JavaScript theme={null}
  // test/IdentitySBT.test.js
  const { expect } = require("chai");
  const { ethers } = require("hardhat");

  describe("IdentitySBT", function () {
    let identitySBT;
    let owner;
    let user1;
    let user2;
    
    beforeEach(async function () {
      [owner, user1, user2] = await ethers.getSigners();
      
      const IdentitySBT = await ethers.getContractFactory("IdentitySBT");
      identitySBT = await IdentitySBT.deploy(
        "ZKScore Identity",
        "ZKSID",
        "https://api.onzks.com/metadata/identity/"
      );
      await identitySBT.deployed();
    });
    
    describe("Minting", function () {
      it("Should mint identity successfully", async function () {
        const zksId = "alice.zks";
        const displayName = "Alice Smith";
        const avatarUrl = "https://example.com/avatar.jpg";
        
        const mintingFee = await identitySBT.mintingFee();
        
        await expect(
          identitySBT.connect(user1).mintIdentity(
            zksId,
            displayName,
            avatarUrl,
            { value: mintingFee }
          )
        ).to.emit(identitySBT, "IdentityMinted")
          .withArgs(user1.address, 1, zksId);
        
        const identity = await identitySBT.getIdentity(user1.address);
        expect(identity.exists).to.be.true;
        expect(identity.zksId).to.equal(zksId);
      });
    });
  });
  ```
</CodeGroup>

## Identity SBT Tests

### Minting Tests

<CodeGroup>
  ```javascript JavaScript theme={null}
  describe("Identity Minting", function () {
    it("Should prevent duplicate ZKS IDs", async function () {
      const zksId = "alice.zks";
      const mintingFee = await identitySBT.mintingFee();
      
      // First mint should succeed
      await identitySBT.connect(user1).mintIdentity(
        zksId,
        "Alice Smith",
        "https://example.com/avatar.jpg",
        { value: mintingFee }
      );
      
      // Second mint with same ZKS ID should fail
      await expect(
        identitySBT.connect(user2).mintIdentity(
          zksId,
          "Alice Johnson",
          "https://example.com/avatar2.jpg",
          { value: mintingFee }
        )
      ).to.be.revertedWith("ZKS_ID_ALREADY_TAKEN");
    });
    
    it("Should prevent second identity minting", async function () {
      const mintingFee = await identitySBT.mintingFee();
      
      // First identity
      await identitySBT.connect(user1).mintIdentity(
        "alice.zks",
        "Alice Smith",
        "https://example.com/avatar.jpg",
        { value: mintingFee }
      );
      
      // Second identity should fail
      await expect(
        identitySBT.connect(user1).mintIdentity(
          "alice2.zks",
          "Alice Smith 2",
          "https://example.com/avatar2.jpg",
          { value: mintingFee }
        )
      ).to.be.revertedWith("IDENTITY_ALREADY_EXISTS");
    });
  });
  ```
</CodeGroup>

### Activation Tests

<CodeGroup>
  ```javascript JavaScript theme={null}
  describe("Identity Activation", function () {
    it("Should activate identity successfully", async function () {
      const mintingFee = await identitySBT.mintingFee();
      
      // Mint identity
      await identitySBT.connect(user1).mintIdentity(
        "alice.zks",
        "Alice Smith",
        "https://example.com/avatar.jpg",
        { value: mintingFee }
      );
      
      // Activate identity
      await expect(
        identitySBT.connect(user1).activateIdentity()
      ).to.emit(identitySBT, "IdentityActivated")
        .withArgs(user1.address, 1, "alice.zks");
      
      const isActivated = await identitySBT.isActivated(user1.address);
      expect(isActivated).to.be.true;
    });
  });
  ```
</CodeGroup>

## Score Calculator Tests

### Score Calculation Tests

<CodeGroup>
  ```javascript JavaScript theme={null}
  describe("Score Calculator", function () {
    let scoreCalculator;
    
    beforeEach(async function () {
      const ScoreCalculator = await ethers.getContractFactory("ScoreCalculator");
      scoreCalculator = await ScoreCalculator.deploy(
        identitySBT.address,
        owner.address
      );
      await scoreCalculator.deployed();
    });
    
    it("Should calculate score correctly", async function () {
      // Setup user with identity
      const mintingFee = await identitySBT.mintingFee();
      await identitySBT.connect(user1).mintIdentity(
        "alice.zks",
        "Alice Smith",
        "https://example.com/avatar.jpg",
        { value: mintingFee }
      );
      await identitySBT.connect(user1).activateIdentity();
      
      // Update score
      const newScore = 750;
      const breakdown = {
        defi: 200,
        nft: 150,
        social: 100,
        trading: 200,
        governance: 50,
        gaming: 25,
        identity: 25,
        trust: 0
      };
      
      await scoreCalculator.updateScore(
        user1.address,
        newScore,
        breakdown
      );
      
      const score = await scoreCalculator.getScore(user1.address);
      expect(score.total).to.equal(newScore);
      
      const scoreBreakdown = await scoreCalculator.getScoreBreakdown(user1.address);
      expect(scoreBreakdown.defi).to.equal(breakdown.defi);
    });
  });
  ```
</CodeGroup>

## Achievement Registry Tests

### Achievement Creation Tests

<CodeGroup>
  ```javascript JavaScript theme={null}
  describe("Achievement Registry", function () {
    let achievementRegistry;
    
    beforeEach(async function () {
      const AchievementRegistry = await ethers.getContractFactory("AchievementRegistry");
      achievementRegistry = await AchievementRegistry.deploy();
      await achievementRegistry.deployed();
    });
    
    it("Should create achievement successfully", async function () {
      const achievementData = {
        name: "DeFi Pioneer",
        description: "Complete your first DeFi transaction",
        category: "defi",
        rarity: "common",
        points: 50,
        requirements: {
          type: "transaction_count",
          protocol: "uniswap",
          minimum: 1
        },
        imageUrl: "https://api.onzks.com/achievements/defi-pioneer.png"
      };
      
      await achievementRegistry.createAchievement(
        achievementData.name,
        achievementData.description,
        achievementData.category,
        achievementData.rarity,
        achievementData.points,
        achievementData.requirements,
        achievementData.imageUrl
      );
      
      const achievement = await achievementRegistry.getAchievement(1);
      expect(achievement.name).to.equal(achievementData.name);
      expect(achievement.category).to.equal(achievementData.category);
    });
  });
  ```
</CodeGroup>

## Integration Tests

### End-to-End Tests

<CodeGroup>
  ```javascript JavaScript theme={null}
  describe("ZKScore Integration", function () {
    it("Should complete full user journey", async function () {
      // 1. Mint identity
      const mintingFee = await identitySBT.mintingFee();
      await identitySBT.connect(user1).mintIdentity(
        "alice.zks",
        "Alice Smith",
        "https://example.com/avatar.jpg",
        { value: mintingFee }
      );
      
      // 2. Activate identity
      await identitySBT.connect(user1).activateIdentity();
      
      // 3. Update score
      await scoreCalculator.updateScore(
        user1.address,
        800,
        {
          defi: 300,
          nft: 200,
          social: 100,
          trading: 150,
          governance: 25,
          gaming: 25,
          identity: 0,
          trust: 0
        }
      );
      
      // 4. Create achievement
      await achievementRegistry.createAchievement(
        "DeFi Pioneer",
        "Complete your first DeFi transaction",
        "defi",
        "common",
        50,
        { type: "transaction_count", protocol: "uniswap", minimum: 1 },
        "https://api.onzks.com/achievements/defi-pioneer.png"
      );
      
      // 5. Claim achievement
      await achievementRegistry.connect(user1).claimAchievement(1);
      
      // Verify final state
      const identity = await identitySBT.getIdentity(user1.address);
      const score = await scoreCalculator.getScore(user1.address);
      const achievements = await achievementRegistry.getUserAchievements(user1.address);
      
      expect(identity.exists).to.be.true;
      expect(score.total).to.equal(800);
      expect(achievements.length).to.equal(1);
    });
  });
  ```
</CodeGroup>

## Running Tests

### Test Commands

```bash theme={null}
# Run all tests
npx hardhat test

# Run specific test file
npx hardhat test test/IdentitySBT.test.js

# Run tests with gas reporting
REPORT_GAS=true npx hardhat test

# Run tests with coverage
npx hardhat coverage
```

### Test Coverage

```bash theme={null}
# Install coverage tool
npm install --save-dev solidity-coverage

# Run coverage
npx hardhat coverage
```

## Best Practices

1. **Comprehensive Testing**: Test all functions and edge cases
2. **Event Testing**: Verify events are emitted correctly
3. **Gas Testing**: Monitor gas usage for optimization
4. **Integration Testing**: Test complete user journeys
5. **Error Testing**: Test all error conditions

## Related Documentation

* [Contract Deployment](/contracts/deployment)
* [Direct Contract Calls](/contracts/examples/direct-contract-calls)
* [Ethers Integration](/contracts/examples/ethers-integration)
