Skip to content

[Tests] Unit & Integration Tests for OpenZeppelin-Based Non-Fungible Promotion NFT Contract #116

@aguilar1x

Description

@aguilar1x

🎯 Objective

Implement a complete test suite for the Promotion NFT Contract built with OpenZeppelin’s Stellar contracts, ensuring that minting, redemption, transfer, access control, and event emission work as expected for non-fungible promotional NFTs (e.g., discount codes, access passes).


🧪 Scope

Test the following modules and behaviors:

promotion-nft-contract/src/

  mint.rs           // One-off NFT minting with metadata
  redeem.rs         // Redemption flow (mark as used)
  transfer.rs       // Ownership transfers
  roles.rs          // Role-based access control
  metadata.rs       // Token-specific metadata access
  storage.rs        // NFT ownership, state, redemption tracking
  lib.rs            // Contract entry and initialization

✅ Test Categories & Cases

1. Initialization

  • ✅ Only one call to initialize() allowed
  • DEFAULT_ADMIN_ROLE correctly set
  • ✅ Revert on second initialization
  • ✅ Emit ContractInitialized only once

2. Role Management

  • ✅ Only ADMIN_ROLE can grant MINTER_ROLE
  • ✅ Only REDEEMER_ROLE (if used) can redeem on behalf of users
  • ✅ Revert on unauthorized role access
  • ✅ Events: RoleGranted, RoleRevoked

3. Minting Logic

  • ✅ Only minters can mint (mint_promo(recipient, metadata_uri))
  • ✅ Revert on unauthorized mint
  • ✅ Revert if recipient is invalid
  • ✅ Token ID must be unique
  • ✅ Metadata URI stored and retrievable
  • ✅ Emit PromoMinted(token_id, recipient)

4. Redemption Logic

  • ✅ User can redeem if they own the token
  • ✅ Optional: allow redemption by REDEEMER_ROLE
  • ✅ Cannot redeem the same token twice
  • ✅ Mark token as redeemed in storage
  • ✅ Emit Redeemed(token_id, user, timestamp)
  • ✅ Prevent transfers after redemption (if enforced)

5. Transfer Logic

  • ✅ Owner can transfer to another valid address
  • ✅ Ownership updates after transfer
  • ✅ Revert if non-owner tries to transfer
  • ✅ Emit Transfer(from, to, token_id)
  • ✅ Optional: disallow transfer after redemption

6. Metadata Access

  • ✅ Metadata URI must match what was minted
  • ✅ Immutable after mint
  • ✅ Test uniqueness of metadata per token
  • ✅ Query metadata by token_id

7. Storage Integrity

  • ✅ Ensure token IDs are never duplicated
  • ✅ Validate redemption status is persisted
  • ✅ No overwrites of metadata or ownership
  • ✅ All keys follow expected isolation pattern

8. Event Emission

  • ✅ Verify all relevant events:

    • ContractInitialized
    • PromoMinted
    • Redeemed
    • Transfer
    • RoleGranted, RoleRevoked
  • ✅ Event values should be correct and consistent


🧰 Tooling & Environment

  • Use soroban-sdk test helpers and mocks

  • Organize tests into modules by feature: mint_tests, redeem_tests, transfer_tests, roles_tests

  • Use representative mock accounts:

    • admin, seller, buyer1, redeemer

📌 Additional Recommendations

  • Cover edge cases (mint same token twice, redeem twice, transfer after redemption)
  • Use mock timestamps to test redemption timing (optional)
  • Prepare for future extension to burn-on-redeem logic
  • Structure test assertions for easy CI logging

🔗 References


Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions