Skip to content

refactor: Introduce new setupTest function and helper file for unifying tests#209

Merged
robert-zaremba merged 8 commits intomasterfrom
refactor/helper-functions-for-unifying-tests
Dec 23, 2025
Merged

refactor: Introduce new setupTest function and helper file for unifying tests#209
robert-zaremba merged 8 commits intomasterfrom
refactor/helper-functions-for-unifying-tests

Conversation

@Rcc999
Copy link
Contributor

@Rcc999 Rcc999 commented Dec 1, 2025

Description

Closes: #199


Author Checklist

All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.

I have...

  • included the correct type prefix in the PR title
  • added ! to the type prefix if API or client breaking change
  • added appropriate labels to the PR
  • provided a link to the relevant issue or specification
  • added a changelog entry to CHANGELOG.md
  • included doc comments for public functions
  • updated the relevant documentation or specification
  • reviewed "Files changed" and left comments if necessary

Summary by Sourcery

Refactor BTC indexer tests to use a shared setup helper for constructing test indexers and interacting with test data and storage.

Enhancements:

  • Introduce a reusable btcindexer.test.helpers module that encapsulates Miniflare/DB initialization, package and address seeding, mock wiring, and common assertions for BTC indexer tests.
  • Update existing btcindexer tests to rely on the new setupTestIndexer helper for block setup, transaction insertion, Electrs/Sui mocking, and DB expectations, reducing duplication and improving consistency.

…ng test suite of btcindexer

Signed-off-by: Rayane Charif <rayane.charif@gonative.cc>
@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Dec 1, 2025

Reviewer's Guide

Refactors btcindexer tests to use a centralized setupTestIndexer helper and TestIndexerHelper utilities, consolidating environment, DB, mocks, and common operations such as inserting transactions, seeding blocks, and asserting DB state into a new btcindexer.test.helpers module.

Sequence diagram for btcindexer tests using setupTestIndexer helper

sequenceDiagram
    actor Tester
    participant Jest as JestTest
    participant Miniflare
    participant HelperFn as setupTestIndexer
    participant Helper as TestIndexerHelper
    participant Indexer
    participant D1 as D1Database
    participant KVBlocks as BtcBlocks_KV
    participant KVTxs as NbtcTxs_KV
    participant SuiMock as MockSuiClient
    participant ElectrsMock as ElectrsMock

    Tester->>Jest: run beforeEach
    Jest->>Miniflare: getD1Database DB
    Miniflare-->>Jest: D1Database
    Jest->>HelperFn: setupTestIndexer(mf, options)
    HelperFn->>D1: initDb
    HelperFn->>Miniflare: getBindings
    Miniflare-->>HelperFn: env(DB, BtcBlocks, nbtc_txs)
    HelperFn->>HelperFn: create CFStorage with DB, BtcBlocks, nbtc_txs
    HelperFn->>D1: insert nbtc_packages
    HelperFn->>D1: insert nbtc_deposit_addresses
    HelperFn->>SuiMock: construct MockSuiClient
    HelperFn->>ElectrsMock: mkElectrsServiceMock
    HelperFn->>Indexer: new Indexer(storage, configs, suiClients, nbtcAddressesMap, confirmationDepth, maxRetries, electrsClients)
    HelperFn-->>Jest: TestIndexerHelper
    Jest->>Tester: expose helper and indexer

    Tester->>Helper: setupBlock(329)
    Helper->>KVBlocks: put(blockHash, rawBlockHex)
    Tester->>Helper: mockElectrsSender(fakeSender)
    Helper->>ElectrsMock: getTx mockResolvedValue(Response vout sender)
    Tester->>Indexer: processBlock(blockQueueRecord)
    Indexer->>KVBlocks: get(blockHash)
    Indexer->>D1: insert nbtc_minting and sender data
    Tester->>Helper: expectMintingCount(1)
    Helper->>D1: SELECT * FROM nbtc_minting
    Helper-->>Tester: assertion result
Loading

Class diagram for new btcindexer test helper types

classDiagram
    class TxInfo {
        +string id
        +string suiAddr
        +number amountSats
    }

    class TestBlock {
        +string depositAddr
        +number height
        +string hash
        +string rawBlockHex
        +Record~string, TxInfo~ txs
    }

    class TestBlocks {
        <<type>>
        +Record~number, TestBlock~
    }

    class SetupOptions {
        +string[] depositAddresses
        +NbtcPkgCfg packageConfig
        +number confirmationDepth
        +number maxRetries
        +MockSuiClient customSuiClient
        +TestBlocks testData
    }

    class TestIndexerHelper {
        +Indexer indexer
        +D1Database db
        +KVNamespace blocksKV
        +KVNamespace txsKV
        +CFStorage storage
        +MockSuiClient mockSuiClient
        +Electrs mockElectrs
        +setupBlock(height number) Promise~void~
        +getBlock(height number) Block
        +getTx(height number, txIndex number) GetTxResult
        +createBlockQueueRecord(height number, options BlockQueueRecordPartial) BlockQueueRecord
        +mockElectrsSender(address string) void
        +mockElectrsError(error Error) void
        +mockSuiMintBatch(result MintBatchResult) void
        +insertTx(options InsertTxOptions) Promise~void~
        +expectMintingCount(count number) Promise~void~
        +expectSenderCount(count number, expectedAddress string) Promise~void~
        +expectTxStatus(txId string, expectedStatus string) Promise~void~
    }

    class GetTxResult {
        +TestBlock blockData
        +Block block
        +Transaction targetTx
        +TxInfo txInfo
    }

    class BlockQueueRecord {
        +string hash
        +number height
        +BtcNet network
        +number timestamp_ms
    }

    class BlockQueueRecordPartial {
        <<type>>
        +string hash
        +number height
        +BtcNet network
        +number timestamp_ms
    }

    class InsertTxOptions {
        +string txId
        +string status
        +number retryCount
        +number blockHeight
        +string blockHash
        +string suiRecipient
        +number amountSats
        +string depositAddress
        +string sender
        +number vout
    }

    class MintBatchResult {
        <<type>>
        +tuple[boolean, string] or null
    }

    class Indexer
    class CFStorage
    class MockSuiClient {
        +tryMintNbtcBatch(request any) Promise~MintBatchResult~
        +verifyBlocks(hashes string[]) Promise~boolean[]~
    }

    class Electrs {
        +getTx(txId string) Promise~Response~
    }

    class NbtcPkgCfg {
        +number id
        +BtcNet btc_network
        +string sui_network
        +string nbtc_pkg
        +string nbtc_contract
        +string lc_contract
        +string lc_pkg
        +string sui_fallback_address
        +boolean is_active
    }

    class BtcNet
    class Block
    class Transaction
    class D1Database
    class KVNamespace

    TestBlocks --> TestBlock : values
    TestBlock --> TxInfo : txs values

    TestIndexerHelper --> Indexer : owns
    TestIndexerHelper --> CFStorage : uses
    TestIndexerHelper --> MockSuiClient : exposes mockSuiClient
    TestIndexerHelper --> Electrs : exposes mockElectrs
    TestIndexerHelper --> D1Database : uses db
    TestIndexerHelper --> KVNamespace : uses blocksKV
    TestIndexerHelper --> KVNamespace : uses txsKV

    TestIndexerHelper --> TestBlocks : uses testData
    TestIndexerHelper --> InsertTxOptions : insertTx options
    TestIndexerHelper --> BlockQueueRecord : returns
    TestIndexerHelper --> BlockQueueRecordPartial : optional override
    TestIndexerHelper --> GetTxResult : returns

    SetupOptions --> NbtcPkgCfg : packageConfig
    SetupOptions --> MockSuiClient : customSuiClient
    SetupOptions --> TestBlocks : testData

    NbtcPkgCfg --> BtcNet

    GetTxResult --> TestBlock
    GetTxResult --> Block
    GetTxResult --> Transaction
    GetTxResult --> TxInfo

    MockSuiClient --> MintBatchResult
    Indexer --> CFStorage
    Indexer --> MockSuiClient
    Indexer --> Electrs
    CFStorage --> D1Database
    CFStorage --> KVNamespace
    CFStorage --> KVNamespace
Loading

File-Level Changes

Change Details Files
Replace inline btcindexer test setup and utilities with a reusable TestIndexerHelper and setupTestIndexer helper.
  • Introduce setupTestIndexer to initialize Miniflare bindings, CFStorage, DB schema, package config, deposit addresses, Sui and Electrs mocks, and construct an Indexer instance with configurable confirmation depth and retry limits.
  • Create TestIndexerHelper interface exposing indexer, db, KV namespaces, mocks, and higher-level helper methods for setting up blocks, retrieving transactions, creating BlockQueueRecord messages, and common assertions on minting and sender data.
  • Refactor btcindexer.test.ts to use TestIndexerHelper instead of manual DB/KV setup, replacing custom insert/put utilities and inline SQL with helper methods like setupBlock, insertTx, expectMintingCount, expectSenderCount, and expectTxStatus across Indexer and Storage test suites.
packages/btcindexer/src/btcindexer.test.ts
packages/btcindexer/src/btcindexer.test.helpers.ts

Assessment against linked issues

Issue Objective Addressed Explanation
#199 Introduce a shared helper-based setup to unify btcindexer tests (common Indexer/DB/KV/mocks wiring instead of per-test duplication).
#199 Provide a helper function to insert multiple finalized transactions in a single batch operation (e.g., an insertFinalizedTxBatch-style helper) to replace sequential inserts in tests. The new helper module btcindexer.test.helpers.ts exposes an insertTx helper that inserts a single transaction at a time, and the tests call it repeatedly for multiple transactions. There is no insertFinalizedTxBatch (or equivalent batch insert) function that inserts multiple transactions in a single batch operation as suggested in the issue.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Signed-off-by: Rayane Charif <rayane.charif@gonative.cc>
Signed-off-by: Rayane Charif <rayane.charif@gonative.cc>
Signed-off-by: Rayane Charif <rayane.charif@gonative.cc>
Copy link
Contributor

@sczembor sczembor left a comment

Choose a reason for hiding this comment

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

few of the names are to be improved. How does it relate to the other PR, where we are trying to move the functions to a common module and reuse it across different packages

@sczembor sczembor marked this pull request as ready for review December 23, 2025 10:39
@sczembor sczembor requested a review from a team as a code owner December 23, 2025 10:39
Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • The new helper module imports expect from bun:test but the surrounding test suite appears to be Jest-based; consider relying on the Jest global expect (and removing the Bun import) to avoid mixing test runners and potential type/runtime conflicts.
  • In insertTx and the related tests you pass arbitrary strings like "confirming" and "reorg" as status; it would be safer to narrow this type (e.g., a union including MintTxStatus plus the extra literal states) to catch typos and keep status values consistent.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new helper module imports `expect` from `bun:test` but the surrounding test suite appears to be Jest-based; consider relying on the Jest global `expect` (and removing the Bun import) to avoid mixing test runners and potential type/runtime conflicts.
- In `insertTx` and the related tests you pass arbitrary strings like "confirming" and "reorg" as `status`; it would be safer to narrow this type (e.g., a union including `MintTxStatus` plus the extra literal states) to catch typos and keep status values consistent.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Contributor

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 refactors the btcindexer test file by extracting test setup logic into a new helper file (btcindexer.test.helpers.ts). The refactoring introduces a setupTestIndexer function that centralizes the creation of test fixtures including Miniflare instances, database initialization, mock clients, and helper methods for common test operations.

Key changes:

  • Introduced setupTestIndexer function to unify test setup and provide reusable helper methods
  • Replaced inline test setup with declarative helper calls for improved readability
  • Added helper methods for common assertions (expectMintingCount, expectSenderCount, expectTxStatus)

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
packages/btcindexer/src/btcindexer.test.ts Refactored to use the new test helper, removing ~150 lines of repetitive setup code and replacing with helper method calls
packages/btcindexer/src/btcindexer.test.helpers.ts New file containing setupTestIndexer function and related helper methods for test setup, mocking, and assertions
Comments suppressed due to low confidence (2)

packages/btcindexer/src/btcindexer.test.ts:25

  • These type definitions (TxInfo, TestBlock, TestBlocks) are duplicated in both the test file and the helper file. Since these types are now exported from the helper file and used there, they should be imported from the helper file instead of redeclared here to maintain a single source of truth and avoid potential inconsistencies.
interface TxInfo {
	id: string;
	suiAddr: string;
	amountSats: number;
}
interface TestBlock {
	depositAddr: string;
	height: number;
	hash: string;
	rawBlockHex: string;
	txs: Record<string, TxInfo>;
}

type TestBlocks = Record<number, TestBlock>;

packages/btcindexer/src/btcindexer.test.ts:602

  • This describe block is duplicated - there's another "Indexer.processBlock" describe block at line 161. Both blocks have a test with the same name "should process a block and insert nBTC transactions and sender deposits". The second block (starting here) also has an additional test for reorgs. These should be merged into a single describe block to avoid test name conflicts and confusion. When test frameworks encounter duplicate describe/test names, behavior can be unpredictable (some may skip duplicates, others may run both).
describe("Indexer.processBlock", () => {
	const timestamp_ms = Date.now();
	it("should process a block and insert nBTC transactions and sender deposits", async () => {
		const blockInfo = helper.createBlockQueueRecord(329, { timestamp_ms });
		const fakeSenderAddress = "bc1qtestsenderaddress";

		await helper.setupBlock(329);
		helper.mockElectrsSender(fakeSenderAddress);

		await indexer.processBlock(blockInfo);

		await helper.expectMintingCount(1);
		await helper.expectSenderCount(1, fakeSenderAddress);
	});

	it("should call detectMintedReorgs when processing a block that causes a reorg", async () => {
		const blockData329 = REGTEST_DATA[329]!;
		const txData = blockData329.txs[1]!;

		await helper.insertTx({ txId: txData.id, status: MintTxStatus.Minted });
		await helper.setupBlock(329);

		await helper.db
			.prepare(
				"INSERT INTO btc_blocks (hash, height, network, inserted_at, is_scanned) VALUES (?, ?, ?, ?, ?)",
			)
			.bind(blockData329.hash, blockData329.height, BtcNet.REGTEST, timestamp_ms, 1)
			.run();

		const reorgBlockInfo = helper.createBlockQueueRecord(327, {
			height: blockData329.height,
			timestamp_ms: timestamp_ms + 1000,
		});
		await helper.setupBlock(327);
		await indexer.processBlock(reorgBlockInfo);

		const status = await indexer.storage.getTxStatus(txData.id);
		expect(status).toEqual(MintTxStatus.MintedReorg);
	});
});

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

Copy link
Contributor

Copilot AI commented Dec 23, 2025

@robert-zaremba I've opened a new pull request, #239, to work on those changes. Once the pull request is ready, I'll request review from you.

robert-zaremba and others added 2 commits December 23, 2025 11:59
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Robert Zaremba <robert@zaremba.ch>
Signed-off-by: Robert Zaremba <robert@zaremba.ch>
@robert-zaremba robert-zaremba merged commit d76df0e into master Dec 23, 2025
12 checks passed
@robert-zaremba robert-zaremba deleted the refactor/helper-functions-for-unifying-tests branch December 23, 2025 11:09
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.

Create a better helper function to unify btcindexer tests.

5 participants