From be5d54a715b87002ee9d6f3ad0b92e0a9e2c208d Mon Sep 17 00:00:00 2001 From: EDOHWARES Date: Tue, 26 May 2026 14:30:36 +0100 Subject: [PATCH] feat: implement docs, tests, and CI coverage for assigned issues (#2, #98, #99, #100) --- .github/workflows/ci.yml | 13 +++++++ contracts/token/src/test.rs | 78 +++++++++++++++++++++++++++++++++++++ sdk/README.md | 32 +++++++++++++++ 3 files changed, 123 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ae59e77..320d8d1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -51,6 +51,19 @@ jobs: - name: Run tests run: cargo test --all + - name: Install Tarpaulin + run: cargo install cargo-tarpaulin + + - name: Run coverage (Tarpaulin) + run: cargo tarpaulin --workspace --out Html --out Xml --out Stdout + continue-on-error: true + + - name: Upload coverage artifact + uses: actions/upload-artifact@v4 + with: + name: coverage-report + path: ./tarpaulin-report.html + - name: Build WASM run: cargo build --target wasm32-unknown-unknown --release diff --git a/contracts/token/src/test.rs b/contracts/token/src/test.rs index d05c169..f127c8a 100644 --- a/contracts/token/src/test.rs +++ b/contracts/token/src/test.rs @@ -729,6 +729,84 @@ fn test_transfer_while_paused_returns_error() { client.transfer(&sender, &receiver, &100); } +// ─── Pause/Unpause Edge Case Tests ───────────────────────────────────────── + +#[test] +fn test_transfer_ownership_while_paused() { + let env = Env::default(); + env.mock_all_auths(); + let (client, _) = setup_contract(&env); + let admin = init_default(&env, &client); + let new_admin = Address::generate(&env); + let _ = client.pause(); + // Ownership transfer should still work while paused + client.transfer_ownership(&new_admin); + // New admin can mint + client.mint(&new_admin, &admin, &1); +} + +#[test] +fn test_balance_query_while_paused() { + let env = Env::default(); + env.mock_all_auths(); + let (client, _) = setup_contract(&env); + let admin = init_default(&env, &client); + let user = Address::generate(&env); + client.mint(&admin, &user, &123); + client.pause(); + // Balance query should still work while paused + let bal = client.balance(&user); + assert_eq!(bal, 123); +} + +// ─── Negative Admin Function Tests ───────────────────────────────────────── + +#[test] +#[should_panic(expected = "unauthorized: missing role")] +fn test_pause_unauthorized_panics() { + let env = Env::default(); + env.mock_all_auths(); + let (client, _) = setup_contract(&env); + let _admin = init_default(&env, &client); + let not_admin = Address::generate(&env); + client.pause_with_auth(¬_admin); +} + +#[test] +#[should_panic(expected = "unauthorized: missing role")] +fn test_unpause_unauthorized_panics() { + let env = Env::default(); + env.mock_all_auths(); + let (client, _) = setup_contract(&env); + let _admin = init_default(&env, &client); + let not_admin = Address::generate(&env); + client.unpause_with_auth(¬_admin); +} + +#[test] +#[should_panic(expected = "unauthorized: missing role")] +fn test_transfer_ownership_unauthorized_panics() { + let env = Env::default(); + env.mock_all_auths(); + let (client, _) = setup_contract(&env); + let _admin = init_default(&env, &client); + let not_admin = Address::generate(&env); + let new_admin = Address::generate(&env); + client.transfer_ownership_with_auth(&new_admin, ¬_admin); +} + +#[test] +#[should_panic(expected = "unauthorized: missing role")] +fn test_mint_unauthorized_panics() { + let env = Env::default(); + env.mock_all_auths(); + let (client, _) = setup_contract(&env); + let _admin = init_default(&env, &client); + let not_admin = Address::generate(&env); + let user = Address::generate(&env); + client.mint(¬_admin, &user, &100); +} + // ─── Version ───────────────────────────────────────────────────────────────── #[test] diff --git a/sdk/README.md b/sdk/README.md index ff75060..213cfa8 100644 --- a/sdk/README.md +++ b/sdk/README.md @@ -60,6 +60,20 @@ await client.transfer( ); ``` +## Burning Tokens + +```typescript +const ownerKeypair = Keypair.fromSecret('SXXX...SECRET'); + +// Burn 50 tokens from owner's balance +const burnResult = await client.burn( + ownerKeypair.publicKey(), + BigInt(50_0000000), + ownerKeypair +); +console.log('Burn TX:', burnResult.hash, 'Success:', burnResult.success); +``` + ## Approving & Delegated Transfers ```typescript @@ -76,6 +90,24 @@ const allowance = await client.getAllowance( ownerKeypair.publicKey(), 'GSPENDER...ADDR' ); +console.log('Allowance:', allowance); +``` + +## Querying Allowance + +```typescript +const allowance = await client.getAllowance( + 'GOWNER...ADDR', + 'GSPENDER...ADDR' +); +console.log('Allowance:', allowance); +``` + +## Querying Contract Version + +```typescript +const version = await client.getVersion(); +console.log('Contract version:', version); ``` ## Admin Operations