Skip to content

feat: Enhance smoke tests with management API functionality#45

Open
dylankilkenny wants to merge 1 commit intomainfrom
update-smoke-script
Open

feat: Enhance smoke tests with management API functionality#45
dylankilkenny wants to merge 1 commit intomainfrom
update-smoke-script

Conversation

@dylankilkenny
Copy link
Member

@dylankilkenny dylankilkenny commented Dec 18, 2025

  • Added management API tests for fee limits CRUD operations.
  • Updated command-line options to include management API tests.
  • Improved default RPC URL and contract ID handling based on network type.

Summary by CodeRabbit

  • New Features

    • Added management API smoke test for fee operations (get, set, delete limits).
    • Introduced network-aware defaults for RPC URL and contract ID.
    • Added --admin-secret and --log-fees-spent CLI flags for management operations.
  • Improvements

    • Enhanced result output formatting in debug and standard modes.

✏️ Tip: You can customize this high-level summary in your review settings.

Signed-off-by: Dylan Kilkenny <dylankilkenny95@gmail.com>
Copilot AI review requested due to automatic review settings December 18, 2025 15:03
@coderabbitai
Copy link

coderabbitai bot commented Dec 18, 2025

Walkthrough

The scripts/smoke.ts file was enhanced with a new management API test, environment-aware defaults for rpc-url and contract-id based on network type, extended runtime context to include apiKey and adminSecret, improved result printing for debug and normal modes, and additional CLI flags (mgmt-api, admin-secret, log-fees-spent).

Changes

Cohort / File(s) Summary
Management API Test Implementation
scripts/smoke.ts
Added new mgmt-api test that exercises management API endpoints (getFeeUsage, getFeeLimit, setFeeLimit, deleteFeeLimit) with verification steps. Requires admin secret for execution.
Environment-Aware Configuration Defaults
scripts/smoke.ts
Introduced network-specific defaults for rpc-url (mainnet/testnet-aware) and contract-id (different IDs per network when not provided).
Runtime Context Extensions
scripts/smoke.ts
Extended Ctx (runtime context) to propagate apiKey and optional adminSecret fields throughout test execution.
Result Printing & Output Improvements
scripts/smoke.ts
Enhanced debug mode to pretty-print full envelope; improved non-debug result summaries using ok flag for clearer success/failure indication.
CLI Flags & Help Documentation
scripts/smoke.ts
Added mgmt-api to test-id options; introduced admin-secret and log-fees-spent flags to support new management API operations and fee logging.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Areas requiring attention:

  • Management API test implementation logic and verification steps
  • Network-specific default values and conditional configuration
  • Runtime context propagation to ensure apiKey and adminSecret are correctly passed through execution flow
  • CLI flag parsing and their integration with test execution logic

Poem

🐰 A smoke test takes flight, with management in sight,
Networks now aware of their rightful plight,
API keys dance through contexts anew,
Fee limits set and verified too,
Another fine patch, tested and true! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Enhance smoke tests with management API functionality' accurately reflects the main changes: adding management API tests for fee operations, expanding test capabilities, and improving configuration handling.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch update-smoke-script

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR enhances the smoke test script by adding comprehensive management API testing for fee limits CRUD operations, while also improving network-specific configuration handling.

Key Changes:

  • Adds a new mgmt-api test that validates fee limits CRUD operations (get usage, get/set/delete limits)
  • Implements network-aware default values for RPC URLs and contract IDs (testnet vs mainnet)
  • Updates the context type to include apiKey and adminSecret for management API operations

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

console.log(` ✓ ${label}: ${hash || status || 'confirmed'}`);
// For tx results, show hash; for mgmt results, show ok or just confirmed
const detail = hash || status || (ok !== undefined ? `ok=${ok}` : 'ok');
console.log(` ${label}: ${detail}`);
Copy link

Copilot AI Dec 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The checkmark symbol (✓) has been removed from the success output. This changes the visual feedback users receive when tests pass successfully. The checkmark provided a clear, at-a-glance indication of success. Consider retaining the checkmark prefix for consistency with the original UX.

Suggested change
console.log(` ${label}: ${detail}`);
console.log(` ${label}: ${detail}`);

Copilot uses AI. Check for mistakes.
} else {
const error = envelope?.error || 'unknown error';
console.log(` ${label}: ${error}`);
console.log(` ${label}: FAILED - ${error}`);
Copy link

Copilot AI Dec 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error output format has been changed from "✗" to no symbol and from just the error to "FAILED - " prefix. While this might be intentional, the removal of the "✗" symbol makes it less visually distinct from success messages. Consider retaining the "✗" symbol for better visual distinction between success and failure cases.

Suggested change
console.log(` ${label}: FAILED - ${error}`);
console.log(` ${label}: FAILED - ${error}`);

Copilot uses AI. Check for mistakes.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 375b755 and 423c0c4.

📒 Files selected for processing (1)
  • scripts/smoke.ts (6 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Agent
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: Analyze (rust)
🔇 Additional comments (5)
scripts/smoke.ts (5)

9-9: LGTM! Clear documentation of new features.

The documentation updates accurately describe the new management API test and related CLI flags.

Also applies to: 55-55, 59-60


158-162: LGTM! Sensible network-aware defaults.

The conditional RPC URL defaults based on network type improve usability and align with common Stellar endpoints.


211-214: LGTM! Context extension is appropriate for the new test.

Adding apiKey and adminSecret to the execution context allows the management API test to access the necessary credentials while keeping the implementation clean.


418-440: LGTM! Improved result printing handles management API responses.

The modified printResult function now correctly handles both transaction results (with hash/status) and management API results (with ok flag), providing clearer output in non-debug mode.


167-172: These contract ID defaults are appropriate for this smoke test script. Both the no_auth_bump() and write_with_address_auth() methods are confirmed to exist in the smoke contract implementation at contracts/smoke-contract/src/lib.rs, and the contract is maintained within this repository. The code already supports overriding these defaults via CLI arguments or environment variables.

Comment on lines +259 to +311
{
id: 'mgmt-api',
label: 'Management API: fee limits CRUD',
run: async ({ client, apiKey, adminSecret, debug }) => {
if (!adminSecret) {
console.log(' ⏭ Skipped (requires --admin-secret)');
return;
}

const formatStroops = (s: number) => `${s.toLocaleString()} stroops (${(s / 10_000_000).toFixed(7)} XLM)`;

// 1. Get current fee usage
const usage = await client.getFeeUsage(apiKey);
printResult('getFeeUsage', { success: true, data: usage }, debug);
if (!debug) console.log(` consumed: ${formatStroops(usage.consumed)}`);

// 2. Get current fee limit
const limitBefore = await client.getFeeLimit(apiKey);
printResult('getFeeLimit', { success: true, data: limitBefore }, debug);
if (!debug) console.log(` limit: ${limitBefore.limit ? formatStroops(limitBefore.limit) : 'unlimited'}`);

// 3. Set a custom fee limit (5 XLM)
const testLimit = 50_000_000;
const setResult = await client.setFeeLimit(apiKey, testLimit);
if (!setResult.ok || setResult.limit !== testLimit) {
throw new Error(`setFeeLimit failed: expected ${testLimit}, got ${setResult.limit}`);
}
printResult('setFeeLimit', { success: true, data: setResult }, debug);
if (!debug) console.log(` limit: ${formatStroops(setResult.limit)}`);

// 4. Verify limit was set
const limitAfterSet = await client.getFeeLimit(apiKey);
if (limitAfterSet.limit !== testLimit) {
throw new Error(`getFeeLimit after set: expected ${testLimit}, got ${limitAfterSet.limit}`);
}
printResult('getFeeLimit (verify set)', { success: true, data: limitAfterSet }, debug);

// 5. Delete the custom limit
const deleteResult = await client.deleteFeeLimit(apiKey);
if (!deleteResult.ok) {
throw new Error('deleteFeeLimit failed');
}
printResult('deleteFeeLimit', { success: true, data: deleteResult }, debug);

// 6. Verify limit was deleted
const limitAfterDelete = await client.getFeeLimit(apiKey);
if (limitAfterDelete.limit === testLimit) {
throw new Error('getFeeLimit after delete: custom limit still present');
}
printResult('getFeeLimit (verify deleted)', { success: true, data: limitAfterDelete }, debug);
if (!debug) console.log(` limit: ${limitAfterDelete.limit ? formatStroops(limitAfterDelete.limit) : 'unlimited'}`);
},
},
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Save and restore initial state to avoid side effects.

The management API test modifies state (sets and deletes fee limits) without restoring the original state. If a custom limit exists before the test runs, it will be lost after the test completes. This can affect subsequent tests or ongoing operations.

Additionally, the verification at lines 305-307 only checks that the test limit was removed, not that the original state was restored.

🔎 Apply this diff to save and restore the initial state:
     run: async ({ client, apiKey, adminSecret, debug }) => {
       if (!adminSecret) {
         console.log('   ⏭ Skipped (requires --admin-secret)');
         return;
       }

       const formatStroops = (s: number) => `${s.toLocaleString()} stroops (${(s / 10_000_000).toFixed(7)} XLM)`;

       // 1. Get current fee usage
       const usage = await client.getFeeUsage(apiKey);
       printResult('getFeeUsage', { success: true, data: usage }, debug);
       if (!debug) console.log(`      consumed: ${formatStroops(usage.consumed)}`);

       // 2. Get current fee limit (save for restoration)
       const limitBefore = await client.getFeeLimit(apiKey);
       printResult('getFeeLimit', { success: true, data: limitBefore }, debug);
       if (!debug) console.log(`      limit: ${limitBefore.limit ? formatStroops(limitBefore.limit) : 'unlimited'}`);
+      const originalLimit = limitBefore.limit;

       // 3. Set a custom fee limit (5 XLM)
       const testLimit = 50_000_000;
       const setResult = await client.setFeeLimit(apiKey, testLimit);
       if (!setResult.ok || setResult.limit !== testLimit) {
         throw new Error(`setFeeLimit failed: expected ${testLimit}, got ${setResult.limit}`);
       }
       printResult('setFeeLimit', { success: true, data: setResult }, debug);
       if (!debug) console.log(`      limit: ${formatStroops(setResult.limit)}`);

       // 4. Verify limit was set
       const limitAfterSet = await client.getFeeLimit(apiKey);
       if (limitAfterSet.limit !== testLimit) {
         throw new Error(`getFeeLimit after set: expected ${testLimit}, got ${limitAfterSet.limit}`);
       }
       printResult('getFeeLimit (verify set)', { success: true, data: limitAfterSet }, debug);

       // 5. Delete the custom limit
       const deleteResult = await client.deleteFeeLimit(apiKey);
       if (!deleteResult.ok) {
         throw new Error('deleteFeeLimit failed');
       }
       printResult('deleteFeeLimit', { success: true, data: deleteResult }, debug);

       // 6. Verify limit was deleted
       const limitAfterDelete = await client.getFeeLimit(apiKey);
       if (limitAfterDelete.limit === testLimit) {
         throw new Error('getFeeLimit after delete: custom limit still present');
       }
       printResult('getFeeLimit (verify deleted)', { success: true, data: limitAfterDelete }, debug);
       if (!debug) console.log(`      limit: ${limitAfterDelete.limit ? formatStroops(limitAfterDelete.limit) : 'unlimited'}`);
+
+      // 7. Restore original state
+      if (originalLimit !== undefined && originalLimit !== null) {
+        const restoreResult = await client.setFeeLimit(apiKey, originalLimit);
+        if (!restoreResult.ok || restoreResult.limit !== originalLimit) {
+          console.warn(`      ⚠ Failed to restore original limit: expected ${originalLimit}, got ${restoreResult.limit}`);
+        } else {
+          if (!debug) console.log(`      restored original limit: ${formatStroops(originalLimit)}`);
+        }
+      }
     },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{
id: 'mgmt-api',
label: 'Management API: fee limits CRUD',
run: async ({ client, apiKey, adminSecret, debug }) => {
if (!adminSecret) {
console.log(' ⏭ Skipped (requires --admin-secret)');
return;
}
const formatStroops = (s: number) => `${s.toLocaleString()} stroops (${(s / 10_000_000).toFixed(7)} XLM)`;
// 1. Get current fee usage
const usage = await client.getFeeUsage(apiKey);
printResult('getFeeUsage', { success: true, data: usage }, debug);
if (!debug) console.log(` consumed: ${formatStroops(usage.consumed)}`);
// 2. Get current fee limit
const limitBefore = await client.getFeeLimit(apiKey);
printResult('getFeeLimit', { success: true, data: limitBefore }, debug);
if (!debug) console.log(` limit: ${limitBefore.limit ? formatStroops(limitBefore.limit) : 'unlimited'}`);
// 3. Set a custom fee limit (5 XLM)
const testLimit = 50_000_000;
const setResult = await client.setFeeLimit(apiKey, testLimit);
if (!setResult.ok || setResult.limit !== testLimit) {
throw new Error(`setFeeLimit failed: expected ${testLimit}, got ${setResult.limit}`);
}
printResult('setFeeLimit', { success: true, data: setResult }, debug);
if (!debug) console.log(` limit: ${formatStroops(setResult.limit)}`);
// 4. Verify limit was set
const limitAfterSet = await client.getFeeLimit(apiKey);
if (limitAfterSet.limit !== testLimit) {
throw new Error(`getFeeLimit after set: expected ${testLimit}, got ${limitAfterSet.limit}`);
}
printResult('getFeeLimit (verify set)', { success: true, data: limitAfterSet }, debug);
// 5. Delete the custom limit
const deleteResult = await client.deleteFeeLimit(apiKey);
if (!deleteResult.ok) {
throw new Error('deleteFeeLimit failed');
}
printResult('deleteFeeLimit', { success: true, data: deleteResult }, debug);
// 6. Verify limit was deleted
const limitAfterDelete = await client.getFeeLimit(apiKey);
if (limitAfterDelete.limit === testLimit) {
throw new Error('getFeeLimit after delete: custom limit still present');
}
printResult('getFeeLimit (verify deleted)', { success: true, data: limitAfterDelete }, debug);
if (!debug) console.log(` limit: ${limitAfterDelete.limit ? formatStroops(limitAfterDelete.limit) : 'unlimited'}`);
},
},
{
id: 'mgmt-api',
label: 'Management API: fee limits CRUD',
run: async ({ client, apiKey, adminSecret, debug }) => {
if (!adminSecret) {
console.log(' ⏭ Skipped (requires --admin-secret)');
return;
}
const formatStroops = (s: number) => `${s.toLocaleString()} stroops (${(s / 10_000_000).toFixed(7)} XLM)`;
// 1. Get current fee usage
const usage = await client.getFeeUsage(apiKey);
printResult('getFeeUsage', { success: true, data: usage }, debug);
if (!debug) console.log(` consumed: ${formatStroops(usage.consumed)}`);
// 2. Get current fee limit (save for restoration)
const limitBefore = await client.getFeeLimit(apiKey);
printResult('getFeeLimit', { success: true, data: limitBefore }, debug);
if (!debug) console.log(` limit: ${limitBefore.limit ? formatStroops(limitBefore.limit) : 'unlimited'}`);
const originalLimit = limitBefore.limit;
// 3. Set a custom fee limit (5 XLM)
const testLimit = 50_000_000;
const setResult = await client.setFeeLimit(apiKey, testLimit);
if (!setResult.ok || setResult.limit !== testLimit) {
throw new Error(`setFeeLimit failed: expected ${testLimit}, got ${setResult.limit}`);
}
printResult('setFeeLimit', { success: true, data: setResult }, debug);
if (!debug) console.log(` limit: ${formatStroops(setResult.limit)}`);
// 4. Verify limit was set
const limitAfterSet = await client.getFeeLimit(apiKey);
if (limitAfterSet.limit !== testLimit) {
throw new Error(`getFeeLimit after set: expected ${testLimit}, got ${limitAfterSet.limit}`);
}
printResult('getFeeLimit (verify set)', { success: true, data: limitAfterSet }, debug);
// 5. Delete the custom limit
const deleteResult = await client.deleteFeeLimit(apiKey);
if (!deleteResult.ok) {
throw new Error('deleteFeeLimit failed');
}
printResult('deleteFeeLimit', { success: true, data: deleteResult }, debug);
// 6. Verify limit was deleted
const limitAfterDelete = await client.getFeeLimit(apiKey);
if (limitAfterDelete.limit === testLimit) {
throw new Error('getFeeLimit after delete: custom limit still present');
}
printResult('getFeeLimit (verify deleted)', { success: true, data: limitAfterDelete }, debug);
if (!debug) console.log(` limit: ${limitAfterDelete.limit ? formatStroops(limitAfterDelete.limit) : 'unlimited'}`);
// 7. Restore original state
if (originalLimit !== undefined && originalLimit !== null) {
const restoreResult = await client.setFeeLimit(apiKey, originalLimit);
if (!restoreResult.ok || restoreResult.limit !== originalLimit) {
console.warn(` ⚠ Failed to restore original limit: expected ${originalLimit}, got ${restoreResult.limit}`);
} else {
if (!debug) console.log(` restored original limit: ${formatStroops(originalLimit)}`);
}
}
},
},
🤖 Prompt for AI Agents
In scripts/smoke.ts around lines 259 to 311, the test mutates the fee limit
without restoring the original value; capture the initial limit (and whether it
was "unlimited") before changing anything, run the set/delete/verify steps
inside a try block, and in a finally block restore the original state: if there
was an original numeric limit re-apply it, otherwise ensure the custom limit is
deleted; update the final verification to assert that the post-test state
matches the captured original value rather than only checking that the test
value was removed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants