Skip to content

Implement unit tests for credential-nft contract (tests/unit/credential_tests.rs) #2

Description

@DeFiVC

Description

The file tests/unit/credential_tests.rs contains 8 test function skeletons for the credential-nft contract. All assertions are commented out. The goal is to uncomment and complete these tests.

How to set up each test

  1. Create Env::default()
  2. Generate admin: let admin = Address::generate(&env);
  3. Register: let contract_id = env.register(CredentialNft, ());
  4. Create client: let client = CredentialNftClient::new(&env, &contract_id);
  5. Initialize: client.initialize(&admin);
  6. Call env.mock_all_auths();

Reference: inline tests at contracts/credential-nft/src/lib.rs:92-201.

Tests to uncomment and complete

test_mint_requires_passing_score

What it verifies: #[should_panic(expected = "score 40 below minimum threshold 50")] — score < 50 (MIN_CREDENTIAL_SCORE) panics.

let learner = Address::generate(&env);
env.mock_all_auths();
let course_id = Symbol::new(&env, "rust_101");
let uri = Symbol::new(&env, "ipfs://Qm123");
client.mint_credential(&learner, &course_id, &40, &uri);  // panics

test_mint_with_valid_score

What it verifies: Minting with score 85 succeeds. verify_credential returns correct info.

let cred_id = client.mint_credential(&learner, &course_id, &85, &metadata_uri);
assert_eq!(cred_id, 1);
let info = client.verify_credential(&cred_id);
assert_eq!(info.learner, learner);
assert_eq!(info.course_id, course_id);
assert_eq!(info.score, 85);
assert!(!info.revoked);

test_prevent_duplicate_credentials

What it verifies: #[should_panic(expected = "credential already exists for this learner and course")] — minting twice for same learner+course panics.

client.mint_credential(&learner, &course_id, &90, &uri);
client.mint_credential(&learner, &course_id, &95, &uri);  // panics

test_get_credentials_for_learner

What it verifies: After minting 2 credentials for different courses, get_credentials_for(&learner) returns 2 IDs.

let course1 = Symbol::new(&env, "rust_101");
let course2 = Symbol::new(&env, "sol_201");
let uri = Symbol::new(&env, "ipfs://meta");
client.mint_credential(&learner, &course1, &90, &uri);
client.mint_credential(&learner, &course2, &75, &uri);
let creds = client.get_credentials_for(&learner);
assert_eq!(creds.len(), 2);

test_revoke_credential

What it verifies: After minting, is_credential_valid returns true. After revoking, it returns false and verify_credential shows revoked: true.

let cred_id = client.mint_credential(&learner, &course_id, &80, &uri);
assert!(client.is_credential_valid(&cred_id));
client.revoke_credential(&cred_id);
assert!(!client.is_credential_valid(&cred_id));
let info = client.verify_credential(&cred_id);
assert!(info.revoked);

test_double_revoke

What it verifies: #[should_panic(expected = "credential already revoked")] — revoking twice panics.

let cred_id = client.mint_credential(&learner, &course_id, &80, &uri);
client.revoke_credential(&cred_id);
client.revoke_credential(&cred_id);  // panics

test_nonexistent_credential_invalid

What it verifies: is_credential_valid(&999) returns false for a credential that was never minted.

assert!(!client.is_credential_valid(&999));

test_credential_id_increment

What it verifies: Two mints for different learners return IDs 1 and 2 respectively.

let id1 = client.mint_credential(&learner1, &course, &80, &uri);
let id2 = client.mint_credential(&learner2, &course, &90, &uri);
assert_eq!(id1, 1);
assert_eq!(id2, 2);

Imports needed

use credential_nft::{CredentialNft, CredentialNftClient};
use soroban_sdk::{testutils::Address as _, Address, Env, Symbol};

How to run

cd chainlearn-contracts
cargo test --package credential-nft --test credential_tests

References

  • Contract source: contracts/credential-nft/src/lib.rs (201 lines)
  • Minting logic: contracts/credential-nft/src/mint.rs — score gate at line 32: if score < MIN_CREDENTIAL_SCORE
  • Verification: contracts/credential-nft/src/verify.rs
  • Data types: contracts/credential-nft/src/metadata.rsCredentialInfo struct with fields: learner, course_id, score, issued_at, revoked, metadata_uri
  • Constants: packages/shared/src/constants.rsMIN_CREDENTIAL_SCORE = 50

Metadata

Metadata

Assignees

No one assigned

    Labels

    good first issueGood for newcomersrustRust languagetestsTest additions or improvements

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions