Skip to content

Test: Shared tests for start#1032

Merged
tuliomir merged 26 commits intomasterfrom
test/shared-start
Mar 25, 2026
Merged

Test: Shared tests for start#1032
tuliomir merged 26 commits intomasterfrom
test/shared-start

Conversation

@tuliomir
Copy link
Copy Markdown
Contributor

@tuliomir tuliomir commented Mar 9, 2026

Summary

This PR introduces a shared integration test architecture for the start() method across both wallet facades (HathorWallet and HathorWalletServiceWallet), serving as both an implementation and a Proof of Concept for the testing strategy going forward.

Motivation

Today, the two wallet facades have independent, largely duplicated test suites with no shared validation point. This makes it easy for behavioral drift to go unnoticed and makes it harder to reason about what the facades guarantee as a contract. We need shared tests — but the facades (and their supposed shared interface, IHathorWallet) are not yet aligned. This is being addressed by HathorNetwork/rfcs#100.

While the changes proposed by RFC 100 are implemented, this PR takes a pragmatic approach: develop test adapters that bridge the current API mismatches, letting us write shared tests today. These adapters are explicitly designed as a temporary layer — they can be trimmed down or removed entirely once RFC 100 unifies the facade interfaces.

What this PR does

1. Adapter layer (__tests__/integration/adapters/)

  • IWalletTestAdapter — a unified interface for test setup, wallet lifecycle, fund injection, and capability queries.
  • FullnodeTestAdapter and ServiceTestAdapter — concrete implementations that wrap each facade's existing test helpers, normalizing differences (e.g. fullnode's non-blocking start() vs service's blocking start()).
  • WalletCapabilities — feature flags (supportsMultisig, requiresExplicitWaitReady, etc.) so shared tests can conditionally skip unsupported scenarios instead of failing.

2. Shared tests via describe.each (__tests__/integration/shared/)

  • start.test.ts — a self-contained test file that uses Jest's describe.each to run start() behavior tests against both adapters: parameter validation, successful startup with empty/existing history, and state event ordering.
  • Jest discovers the file directly — no exports, no manual registration in facade-specific files.

3. Per-feature file splitting (fullnode-specific/, service-specific/)

  • The monolithic hathorwallet_facade.test.ts and walletservice_facade.test.ts are being broken apart into smaller, feature-scoped files.
  • This is a complement for the work on feat: Dev Miner for Integration Tests rfcs#102 and feat: Integration test helper rfcs#103, which aim to parallelize the integration test suite. Smaller files = independent Jest workers.
  • This PR starts with start.test.ts for both facades; further features will follow.

4. Deduplication

  • Removes ~620 lines of duplicated test code from the original monolith files.
  • Facade-specific tests (multisig, xpub-readonly, external signing for fullnode; WebSocket config, service-specific mocks) remain in their dedicated files.

Design decisions

  • Implementation-first approach: Instead of writing an abstract design document, this PR ships working code so we can discuss concrete trade-offs with the full implementation in front of us.
  • Adapters as a bridge, not a destination: The adapter layer exists because the facades aren't aligned yet. It should shrink as RFC 100 progresses. The FuzzyWalletType union and the casts it requires are a deliberate signal of this misalignment.
  • Capability-driven conditional testing: Rather than maintaining separate "skip lists," each adapter declares its capabilities and shared tests use those flags. This keeps the shared tests readable and the skip reasons explicit.
  • describe.each over factory exports: Shared tests use describe.each([adapters]) so they are proper .test.ts files auto-discovered by Jest and following the structures offered by this test framework.

Related RFCs

RFC Relevance
RFC 100 Facade interface unification — will allow removing/simplifying the adapter layer
RFC 102 Dev Miner — predictable tx mining periods for faster test execution
RFC 103 Test Helper Service — manages parallel test race conditions

File summary

Path Change
adapters/types.ts New — adapter interface + type definitions
adapters/fullnode.adapter.ts New — fullnode adapter implementation
adapters/service.adapter.ts New — service adapter implementation
shared/start.test.ts New — shared start() tests via describe.each
fullnode-specific/start.test.ts New — fullnode-only start tests
service-specific/start.test.ts New — service-only start tests
hathorwallet_facade.test.ts Removed start tests (moved out)
walletservice_facade.test.ts Removed (start tests moved out)

Test plan

  • Fullnode integration tests pass (fullnode-specific/start.test.ts)
  • Service integration tests pass (service-specific/start.test.ts)
  • Shared tests produce identical assertions against both facades (shared/start.test.ts)
  • No regressions in remaining monolith test files

Summary by CodeRabbit

  • Tests
    • Reorganized integration test infrastructure with a formal adapter abstraction and shared start-test suite for consistent wallet testing.
    • Added Fullnode and Service test adapters and new fullnode- and service-specific start suites covering startup, funding, state events, multisig, token-scope, xpub, and external-signing scenarios.
    • Consolidated and removed legacy startup tests, migrating coverage into the new adapter/shared structure.

tuliomir and others added 3 commits March 6, 2026 20:29
The shared start test called getAddressAtIndex in a loop to verify
precalculated addresses. This fails on the service facade because
it resolves via HTTP API (walletApi.getAddresses), which is not
available in this test context. Moved the verification to a dedicated
fullnode-specific test.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 9, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a test-adapter abstraction and two concrete adapters (Fullnode and Service), plus shared and adapter-specific integration tests. Provides standardized types/interfaces for wallet lifecycle, creation, funding, and transaction utilities used across integration suites.

Changes

Cohort / File(s) Summary
Adapter Types
__tests__/integration/adapters/types.ts
New type/interface layer: ConcreteWalletType, FuzzyWalletType, CreateWalletOptions, CreateWalletResult, WalletCapabilities, and IWalletTestAdapter.
Fullnode Adapter
__tests__/integration/adapters/fullnode.adapter.ts
Adds FullnodeWalletTestAdapter implementing IWalletTestAdapter: lifecycle hooks, wallet creation/start/stop, pre-start funding, tx waiting, and precalculation usage.
Service Adapter
__tests__/integration/adapters/service.adapter.ts
Adds ServiceWalletTestAdapter implementing IWalletTestAdapter: service-specific lifecycle, creation/start/stop, funding helpers, and tx polling.
Shared Start Tests
__tests__/integration/shared/start.test.ts
New cross-adapter start tests exercising required params, startup with/without history, and state event emission; uses adapter capabilities to drive assertions.
Fullnode-specific Tests
__tests__/integration/fullnode-specific/start.test.ts
New Fullnode-only start suite covering constructor validation, precalculated/runtime addresses, multisig, token-scope, xpub-readonly, external-signing, and pinless flows.
Service-specific Tests
__tests__/integration/service-specific/start.test.ts
New Service-only start suite covering websocket defaults, access-data error handling, and xpriv-derived auth flows.
Facade Test Cleanup
__tests__/integration/hathorwallet_facade.test.ts, __tests__/integration/walletservice_facade.test.ts
Removed large monolithic start test blocks and associated imports; retained other facade tests with updated imports.

Sequence Diagram(s)

sequenceDiagram
    participant Test as Test Suite
    participant Adapter as IWalletTestAdapter
    participant Facade as Wallet Facade
    participant Storage as Storage/Network
    participant Genesis as Genesis Helper

    Test->>Adapter: suiteSetup()
    Adapter->>Genesis: init/start
    Adapter->>Storage: configure/prepare

    Test->>Adapter: createWallet(opts)
    Adapter->>Adapter: buildWalletInstance(opts)
    Adapter->>Facade: instantiate (seed/xpub/..., config)
    Adapter->>Facade: startWallet(pin/password)
    Facade->>Storage: load/sync history
    Adapter->>Adapter: waitForReady(wallet)
    Adapter-->>Test: CreateWalletResult

    Test->>Adapter: injectFunds(dest, addr, amount)
    Adapter->>Genesis: send funds
    Genesis->>Facade: submit tx
    Facade->>Storage: update UTXO/state
    Adapter-->>Test: txId

    Test->>Adapter: stopAllWallets()
    Adapter->>Facade: wallet.stop() for each
    Facade->>Storage: cleanup
    Adapter->>Genesis: suiteTeardown()/cleanup
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested reviewers

  • raul-oliveira
  • pedroferreira1

Poem

🐰 I hopped through tests with tiny paws,

adapters stitched to match their laws,
Fullnode, Service, side by side,
seeds and xpubs in joyful stride,
a carrot-coded test parade — hooray! 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Test: Shared tests for start' clearly and concisely summarizes the main change—introducing shared integration tests for the start() method across both wallet facades.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch test/shared-start

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown

@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: 2

🧹 Nitpick comments (4)
__tests__/integration/fullnode-specific/start.test.ts (3)

196-200: Minor: Consider for...of with entries for array iteration.

Line 174 uses the cleaner for...of with entries(), while lines 196-200 use for...in. For consistency and to avoid string-to-number coercion:

-    for (const addressIndex in walletData.addresses) {
-      const precalcAddress = walletData.addresses[+addressIndex];
-      const addressAtIndex = await hWallet.getAddressAtIndex(+addressIndex);
+    for (const [index, precalcAddress] of walletData.addresses.entries()) {
+      const addressAtIndex = await hWallet.getAddressAtIndex(index);
       expect(precalcAddress).toEqual(addressAtIndex);
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@__tests__/integration/fullnode-specific/start.test.ts` around lines 196 -
200, The loop uses for...in over walletData.addresses causing string index
coercion; change it to a for...of with entries() to iterate indexes and values
consistently (e.g., iterate over walletData.addresses.entries()), and use the
numeric index to call hWallet.getAddressAtIndex(index) and compare the value to
avoid +addressIndex coercion; update the block around walletData.addresses and
hWallet.getAddressAtIndex accordingly.

246-247: Consider replacing delay(1000) with deterministic wait.

The delay(1000) before stopping the wallet may lead to flaky tests if the token creation transaction hasn't fully propagated. Consider using a transaction wait helper instead:

-    await delay(1000);
+    // Wait for the token creation tx to be fully processed
+    await waitForTxReceived(hWallet, tokenUid);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@__tests__/integration/fullnode-specific/start.test.ts` around lines 246 -
247, Replace the fixed sleep with a deterministic wait for the token creation
transaction to be confirmed: instead of await delay(1000), await the transaction
confirmation using the transaction hash returned by your token creation step
(e.g., tokenTxHash) via your existing helper (e.g., await
waitForTransaction(tokenTxHash) or await
provider.waitForTransaction(tokenTxHash)) before calling await hWallet.stop({
cleanStorage: true, cleanAddresses: true }); this ensures the token creation is
fully propagated prior to stopping the wallet.

346-364: Use consistent network configuration in externally signed wallet tests.

Lines 349 and 369 use new Network('privatenet') for HD key derivation, but generateWalletHelper connects to NETWORK_NAME ('testnet'). Align these tests with the xpub readonly wallet test (line 283), which correctly uses 'testnet':

Suggested change
-    const rootXpriv = code.toHDPrivateKey('', new Network('privatenet'));
+    const rootXpriv = code.toHDPrivateKey('', new Network(NETWORK_NAME));
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@__tests__/integration/fullnode-specific/start.test.ts` around lines 346 -
364, The test constructs HD keys with new Network('privatenet') but
generateWalletHelper connects to NETWORK_NAME ('testnet'), causing inconsistent
network configuration; update the Network instantiation used to derive rootXpriv
(the call to new Network(...) used with Mnemonic and toHDPrivateKey in this
test) to use 'testnet' (matching the xpub readonly wallet test) so xpriv/xpub
and generateWalletHelper operate on the same network; ensure any other
Network(...) calls in this test also use 'testnet' for consistency.
__tests__/integration/adapters/fullnode.adapter.ts (1)

103-116: Non-started wallet added to tracking array.

buildWalletInstance adds the wallet to startedWallets (line 108) even though the wallet hasn't been started. If stopAllWallets() is called and the wallet was never started, calling stop() on it might throw or behave unexpectedly.

This appears intentional based on the pattern (validation tests use buildWalletInstance then startWallet), but the naming startedWallets is misleading. Consider either:

  1. Renaming to trackedWallets or managedWallets
  2. Only adding to the list when startWallet is called
  3. Adding a comment explaining the rationale
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@__tests__/integration/adapters/fullnode.adapter.ts` around lines 103 - 116,
The buildWalletInstance function is pushing non-started wallets into
startedWallets which is misleading; either rename startedWallets to
trackedWallets (or managedWallets) across the module (update all references like
stopAllWallets and any places assuming "started" semantics) or move the push out
of buildWalletInstance and into startWallet so only actually-started
HathorWallet instances are added (also ensure stopAllWallets guards against
non-started wallets by checking a started state before calling stop). Choose one
approach and apply the consistent rename or relocation of the push and update
all references to the collection and any stop logic accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@__tests__/integration/adapters/service.adapter.ts`:
- Around line 155-158: injectFundsBeforeStart currently uses a non-null
assertion on fundTx.hash (from GenesisWalletServiceHelper.injectFunds) without
verifying it exists; update injectFundsBeforeStart to check that fundTx and
fundTx.hash are defined (e.g., if (!fundTx?.hash) throw or return a clear error)
before returning the hash to match the guard behavior in
FullnodeTestAdapter.injectFundsBeforeStart and avoid the unsafe `!` assertion.

In `@__tests__/integration/service-specific/start.test.ts`:
- Around line 90-113: Add a guard assertion and clarify the credential mismatch:
assert accessData.acctPathKey is defined (e.g.,
expect(accessData.acctPathKey).toBeDefined()) before calling
decryptData(accessData.acctPathKey!, '1234') to avoid the non-null assertion
risk, and either align the test credentials or add an inline comment near
generateAccessDataFromSeed / HathorWalletServiceWallet construction explaining
that the '1234' pin/password are only used for key derivation/decryption while
wallet.start(pinCode, password) uses the separate outer-scope credentials
(pinCode/password) to avoid confusion when reading the test.

---

Nitpick comments:
In `@__tests__/integration/adapters/fullnode.adapter.ts`:
- Around line 103-116: The buildWalletInstance function is pushing non-started
wallets into startedWallets which is misleading; either rename startedWallets to
trackedWallets (or managedWallets) across the module (update all references like
stopAllWallets and any places assuming "started" semantics) or move the push out
of buildWalletInstance and into startWallet so only actually-started
HathorWallet instances are added (also ensure stopAllWallets guards against
non-started wallets by checking a started state before calling stop). Choose one
approach and apply the consistent rename or relocation of the push and update
all references to the collection and any stop logic accordingly.

In `@__tests__/integration/fullnode-specific/start.test.ts`:
- Around line 196-200: The loop uses for...in over walletData.addresses causing
string index coercion; change it to a for...of with entries() to iterate indexes
and values consistently (e.g., iterate over walletData.addresses.entries()), and
use the numeric index to call hWallet.getAddressAtIndex(index) and compare the
value to avoid +addressIndex coercion; update the block around
walletData.addresses and hWallet.getAddressAtIndex accordingly.
- Around line 246-247: Replace the fixed sleep with a deterministic wait for the
token creation transaction to be confirmed: instead of await delay(1000), await
the transaction confirmation using the transaction hash returned by your token
creation step (e.g., tokenTxHash) via your existing helper (e.g., await
waitForTransaction(tokenTxHash) or await
provider.waitForTransaction(tokenTxHash)) before calling await hWallet.stop({
cleanStorage: true, cleanAddresses: true }); this ensures the token creation is
fully propagated prior to stopping the wallet.
- Around line 346-364: The test constructs HD keys with new
Network('privatenet') but generateWalletHelper connects to NETWORK_NAME
('testnet'), causing inconsistent network configuration; update the Network
instantiation used to derive rootXpriv (the call to new Network(...) used with
Mnemonic and toHDPrivateKey in this test) to use 'testnet' (matching the xpub
readonly wallet test) so xpriv/xpub and generateWalletHelper operate on the same
network; ensure any other Network(...) calls in this test also use 'testnet' for
consistency.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f5a59f60-24c5-4ead-b156-073907d20946

📥 Commits

Reviewing files that changed from the base of the PR and between 397f816 and aaf71b3.

📒 Files selected for processing (8)
  • __tests__/integration/adapters/fullnode.adapter.ts
  • __tests__/integration/adapters/service.adapter.ts
  • __tests__/integration/adapters/types.ts
  • __tests__/integration/fullnode-specific/start.test.ts
  • __tests__/integration/hathorwallet_facade.test.ts
  • __tests__/integration/service-specific/start.test.ts
  • __tests__/integration/shared/start.shared.ts
  • __tests__/integration/walletservice_facade.test.ts
💤 Files with no reviewable changes (1)
  • tests/integration/walletservice_facade.test.ts

@tuliomir tuliomir moved this from Todo to In Progress (WIP) in Hathor Network Mar 9, 2026
Orphaned imports left behind after extracting
start() tests into the shared test architecture.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@tuliomir tuliomir changed the title Test/shared start Test: Shared tests for start Mar 9, 2026
@tuliomir tuliomir mentioned this pull request Mar 9, 2026
@codecov
Copy link
Copy Markdown

codecov bot commented Mar 9, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 87.86%. Comparing base (c663620) to head (903760f).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1032      +/-   ##
==========================================
+ Coverage   87.77%   87.86%   +0.09%     
==========================================
  Files         114      114              
  Lines        8828     8828              
  Branches     2006     2006              
==========================================
+ Hits         7749     7757       +8     
+ Misses       1051     1043       -8     
  Partials       28       28              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown

@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.

🧹 Nitpick comments (2)
__tests__/integration/adapters/fullnode.adapter.ts (1)

173-175: Non-null assertion on precalculationHelpers.test assumes prior initialization.

The precalculationHelpers.test! assertion assumes the test helper was initialized during test setup. This is a reasonable assumption for test infrastructure, but if getPrecalculatedWallet() is ever called before suite setup completes, it will throw a cryptic runtime error.

Consider adding a guard for clearer error messaging:

🛡️ Optional defensive check
  getPrecalculatedWallet(): PrecalculatedWalletData {
+   if (!precalculationHelpers.test) {
+     throw new Error('Precalculation helper not initialized — was suiteSetup() called?');
+   }
-   return precalculationHelpers.test!.getPrecalculatedWallet();
+   return precalculationHelpers.test.getPrecalculatedWallet();
  }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@__tests__/integration/adapters/fullnode.adapter.ts` around lines 173 - 175,
The method getPrecalculatedWallet() currently uses a non-null assertion on
precalculationHelpers.test which will throw a cryptic error if not initialized;
update getPrecalculatedWallet (and any similar accessors) to first check if
precalculationHelpers.test is defined and, if not, throw a clear, descriptive
error (e.g., "precalculationHelpers.test is not initialized - ensure test setup
ran") or return a safe fallback; reference the getPrecalculatedWallet function
and the precalculationHelpers.test symbol when adding this guard so callers get
a deterministic, debuggable failure instead of a runtime assertion error.
__tests__/integration/adapters/service.adapter.ts (1)

167-169: Same non-null assertion pattern as fullnode adapter.

Same optional defensive check could be applied here as suggested for FullnodeTestAdapter.getPrecalculatedWallet().

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@__tests__/integration/adapters/service.adapter.ts` around lines 167 - 169,
The getPrecalculatedWallet method currently uses a non-null assertion on
precalculationHelpers.test; change it to defensively check for
precalculationHelpers.test (same approach as
FullnodeTestAdapter.getPrecalculatedWallet) and either throw a clear error or
return a safe fallback when it's undefined, then call .getPrecalculatedWallet()
only when the test helper exists; reference symbols: getPrecalculatedWallet,
PrecalculatedWalletData, precalculationHelpers.test, and
FullnodeTestAdapter.getPrecalculatedWallet.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@__tests__/integration/adapters/fullnode.adapter.ts`:
- Around line 173-175: The method getPrecalculatedWallet() currently uses a
non-null assertion on precalculationHelpers.test which will throw a cryptic
error if not initialized; update getPrecalculatedWallet (and any similar
accessors) to first check if precalculationHelpers.test is defined and, if not,
throw a clear, descriptive error (e.g., "precalculationHelpers.test is not
initialized - ensure test setup ran") or return a safe fallback; reference the
getPrecalculatedWallet function and the precalculationHelpers.test symbol when
adding this guard so callers get a deterministic, debuggable failure instead of
a runtime assertion error.

In `@__tests__/integration/adapters/service.adapter.ts`:
- Around line 167-169: The getPrecalculatedWallet method currently uses a
non-null assertion on precalculationHelpers.test; change it to defensively check
for precalculationHelpers.test (same approach as
FullnodeTestAdapter.getPrecalculatedWallet) and either throw a clear error or
return a safe fallback when it's undefined, then call .getPrecalculatedWallet()
only when the test helper exists; reference symbols: getPrecalculatedWallet,
PrecalculatedWalletData, precalculationHelpers.test, and
FullnodeTestAdapter.getPrecalculatedWallet.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c9e861b1-69ec-49f9-a505-df92aa5c5e9d

📥 Commits

Reviewing files that changed from the base of the PR and between 4d208c5 and 3e7a793.

📒 Files selected for processing (6)
  • __tests__/integration/adapters/fullnode.adapter.ts
  • __tests__/integration/adapters/service.adapter.ts
  • __tests__/integration/fullnode-specific/start.test.ts
  • __tests__/integration/service-specific/start.test.ts
  • __tests__/integration/shared/start.shared.ts
  • __tests__/integration/walletservice_facade.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/integration/walletservice_facade.test.ts

@tuliomir tuliomir moved this from In Progress (WIP) to In Progress (Done) in Hathor Network Mar 9, 2026
@tuliomir tuliomir requested a review from r4mmer March 9, 2026 19:20
@tuliomir tuliomir moved this from In Progress (Done) to In Progress (WIP) in Hathor Network Mar 12, 2026
Replace the exported registerSharedStartTests()
factory with a self-contained describe.each test
file that Jest discovers directly.

This eliminates the need for manual imports or
registration in facade files and removes the
jest/no-export lint suppression.
Copy link
Copy Markdown

@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.

🧹 Nitpick comments (1)
__tests__/integration/shared/start.test.ts (1)

113-148: Clarify non-standard parameter order in getRandomInt usage.

The call getRandomInt(10, 1) uses a non-standard argument order (max, min), whereas most random utilities follow the convention of (min, max). While the code is correct, adding a brief comment would help future readers understand the intentional parameter order.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@__tests__/integration/shared/start.test.ts` around lines 113 - 148, The test
uses getRandomInt(10, 1) with a non-standard (max, min) argument order; update
the test "should start with a transaction history" to add a short inline comment
next to the injectValue assignment referencing getRandomInt to clarify the
intentional parameter order (e.g., note that getRandomInt accepts (max, min)
here) so future readers aren't confused; keep the change local to this test and
do not alter getRandomInt implementation or other calls.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@__tests__/integration/shared/start.test.ts`:
- Around line 113-148: The test uses getRandomInt(10, 1) with a non-standard
(max, min) argument order; update the test "should start with a transaction
history" to add a short inline comment next to the injectValue assignment
referencing getRandomInt to clarify the intentional parameter order (e.g., note
that getRandomInt accepts (max, min) here) so future readers aren't confused;
keep the change local to this test and do not alter getRandomInt implementation
or other calls.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 43807ec4-e5fa-4833-a5e9-c21aedbf80c5

📥 Commits

Reviewing files that changed from the base of the PR and between 3e7a793 and 42f2525.

📒 Files selected for processing (3)
  • __tests__/integration/fullnode-specific/start.test.ts
  • __tests__/integration/service-specific/start.test.ts
  • __tests__/integration/shared/start.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/integration/service-specific/start.test.ts

@tuliomir tuliomir moved this from In Progress (WIP) to In Progress (Done) in Hathor Network Mar 13, 2026
Copy link
Copy Markdown

@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: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@__tests__/integration/adapters/fullnode.adapter.ts`:
- Around line 207-212: The current fillDefaults branch always overwrites
provided credentials with DEFAULT_PASSWORD and DEFAULT_PIN_CODE; change the
logic so defaults are applied only when the caller left fields undefined: when
fillDefaults is true, merge in password: options?.password === undefined ?
DEFAULT_PASSWORD : options.password and pinCode: options?.pinCode === undefined
? DEFAULT_PIN_CODE : options.pinCode (preserving existing behavior when options
is undefined), referencing the fillDefaults flag, DEFAULT_PASSWORD,
DEFAULT_PIN_CODE, options, password and pinCode in the create path so explicit
credentials are never silently replaced.
- Around line 91-95: The test constructs a HathorWallet but only adds it to
this.trackedWallets after hWallet.start() and waitForWalletReady(), so if
startup throws the wallet isn't tracked and stopAllWallets can't clean it; fix
by pushing the new HathorWallet instance into this.trackedWallets immediately
after creating hWallet (before calling hWallet.start() and
waitForWalletReady()), and wrap the start/wait calls in a try/catch if you want
to log and rethrow while still keeping the wallet tracked so stopAllWallets can
handle cleanup (refer to HathorWallet, start(), waitForWalletReady(),
this.trackedWallets, and stopAllWallets).

In `@__tests__/integration/fullnode-specific/start.test.ts`:
- Around line 57-59: Tests leak wallets because some HathorWallet instances are
created and started outside the adapter lifecycle; ensure each manual wallet
lifecycle either registers the wallet with adapter (so adapter.stopAllWallets()
will clean it up) or wrap the start/usage/stop sequence in try/finally to call
wallet.stop() on all execution paths. Locate the manual new HathorWallet(...)
usages referenced (the blocks at lines ~242-269, ~279-356, ~370-379) and for
each: either call adapter.registerWallet(wallet) immediately after creation, or
surround the code that starts/uses the wallet with try { ... } finally { await
wallet.stop(); } so failures don’t leave live connections/listeners; keep
afterEach(async () => await adapter.stopAllWallets()) as the global safety net.

In `@__tests__/integration/shared/start.test.ts`:
- Line 17: The file's formatting is failing CI for the adapters declaration; run
Prettier (or the project's formatter) on the test file and reformat the
declaration using the project's style rules so the line declaring "const
adapters: IWalletTestAdapter[] = [new FullnodeWalletTestAdapter(), new
ServiceWalletTestAdapter()];" matches the repository formatting settings (ensure
spacing, trailing commas, and line breaks conform to configured Prettier rules).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d02af521-d797-4797-b94d-75e67f144cf1

📥 Commits

Reviewing files that changed from the base of the PR and between 42f2525 and 5682e8a.

📒 Files selected for processing (5)
  • __tests__/integration/adapters/fullnode.adapter.ts
  • __tests__/integration/adapters/service.adapter.ts
  • __tests__/integration/fullnode-specific/start.test.ts
  • __tests__/integration/service-specific/start.test.ts
  • __tests__/integration/shared/start.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/integration/service-specific/start.test.ts
  • tests/integration/adapters/service.adapter.ts

@tuliomir tuliomir requested a review from r4mmer March 16, 2026 16:17
capabilities: WalletCapabilities = {
supportsMultisig: false,
supportsTokenScope: false,
supportsXpubReadonly: false,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The wallet service has readonly wallet. Is it different?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We didn't have tests for it yet. I thought about postponing this to another PR but decided to implement it right now, as it's a good opportunity to increase coverage. Done on b362c67

tuliomir and others added 5 commits March 23, 2026 12:58
Addresses PR review comment: stop options were duplicated between the
WalletTracker constructor and the stopWallet method in both adapters.
Now both reference a single STOP_OPTIONS constant.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Addresses PR review comment: explains that injectFunds polls the
destination wallet for tx confirmation, which would fail when the
wallet hasn't started yet.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Addresses PR review comment: documents that words is intentionally
undefined when only xpub or xpriv is provided, since buildConfig
handles those fields independently of the seed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Addresses PR review comments #2 and #3: createWallet no longer
duplicates wallet construction logic. It delegates to
buildWalletInstance for construction and startWallet for startup,
passing default credentials at start() time. This also removes the
fillDefaults flag from buildConfig since credentials are now always
provided at start time rather than construction time.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@tuliomir tuliomir moved this from In Progress (Done) to In Review (WIP) in Hathor Network Mar 23, 2026
tuliomir and others added 4 commits March 23, 2026 20:45
Enables readonly wallet testing for the wallet-service facade and
reorganizes readonly tests into shared vs. facade-specific:

- Service adapter: adds xpub support in buildWalletInstance/startWallet,
  routing to startReadOnly() for xpub wallets. Pre-registers the wallet
  on the backend (via seed start+stop) before attaching as readonly.
- Shared tests: isReadonly verification, zero balance, fund injection —
  run against both facades via describe.each.
- Fullnode-specific: address generation (local derivation) and 15
  WalletFromXPubGuard assertions.
- Service-specific: 5 WalletFromXPubGuard assertions for guarded methods.
- Helper: buildWalletInstance() now accepts optional xpub parameter.

Addresses PR review comment #1 about wallet-service readonly support.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Deduplicates the 3-line Mnemonic→xpub derivation that was copy-pasted
across shared, fullnode-specific, and service-specific test files into
a single helper in core.util.ts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Addresses CodeRabbit review findings:
- Replace unsafe (e as Error).message casts with instanceof checks
- Add expect(addr).toBeDefined() before non-null assertion in
  readonly fund injection test

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@tuliomir tuliomir requested a review from pedroferreira1 March 24, 2026 14:17
@tuliomir tuliomir moved this from In Review (WIP) to In Progress (Done) in Hathor Network Mar 24, 2026
@github-project-automation github-project-automation bot moved this from In Progress (Done) to In Review (WIP) in Hathor Network Mar 25, 2026
@tuliomir tuliomir merged commit 1991f55 into master Mar 25, 2026
6 of 7 checks passed
@github-project-automation github-project-automation bot moved this from In Review (WIP) to Waiting to be deployed in Hathor Network Mar 25, 2026
@tuliomir tuliomir deleted the test/shared-start branch March 25, 2026 19:06
r4mmer added a commit that referenced this pull request Mar 26, 2026
…-policy-2

* origin/master:
  Test: Shared tests for `start` (#1032)
  feat: export all types and utils from public API (#1034)
raul-oliveira added a commit that referenced this pull request Apr 10, 2026
* feat: export all types and utils from public API (#1034)

* Test: Shared tests for `start` (#1032)

* Merge pull request #1046 from HathorNetwork/refact/fee-test-suite

refact: move fee test suite to the right folder

* test: add new fee template integration tests (#1048)

* refact: move fee test suite to the right folder

* review changes

* refact: keep only moved tests, remove new template tests

* test: add new fee template integration tests

* fix: native token version defaulting to deposit (#1054)

* test: Shared tests for internal wallet methods (#1047)

BREAKING CHANGE: HathorWallet.changeServer now returns
Promise<void> instead of void, matching the service
facade signature. Added changeServer to IHathorWallet.

* fix: precalculated wallet address derivation bug (#1056)

* feat: single address policy (#1038)

* feat: single address policy

* chore: improve CI integration test logs (#1049)

---------

Co-authored-by: André Abadesso <andre.abadesso@gmail.com>
Co-authored-by: Tulio Miranda <tulio.mir@gmail.com>
Co-authored-by: André Carneiro <andreluizmrcarneiro@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: Waiting to be deployed

Development

Successfully merging this pull request may close these issues.

3 participants