Skip to content

tests: add tests to ensapi using ens-test-env#1873

Open
sevenzing wants to merge 5 commits intoll/chore-fixesfrom
ll/rest-api-tests
Open

tests: add tests to ensapi using ens-test-env#1873
sevenzing wants to merge 5 commits intoll/chore-fixesfrom
ll/rest-api-tests

Conversation

@sevenzing
Copy link
Copy Markdown
Contributor

Summary

  • Add integration tests for the ENSApi resolution endpoints (resolve-primary-name, resolve-primary-names, resolve-records)
  • Minor updates docker-compose.yml: add build section to build images locally, also added RPC_URL_15658733 because without it running indexer with ens-test-env results in fail with error like failed to make request to localhost:8545

Why

  • Improve confidence in the REST API by covering real requests 👍


Pre-Review Checklist (Blocking)

  • This PR does not introduce significant changes and is low-risk to review quickly.
  • Relevant changesets are included (or are not required)

@sevenzing sevenzing requested a review from a team as a code owner April 5, 2026 20:04
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Apr 5, 2026

🦋 Changeset detected

Latest commit: ac0822d

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 23 packages
Name Type
ensapi Patch
ensindexer Patch
ensadmin Patch
ensrainbow Patch
fallback-ensapi Patch
enssdk Patch
enscli Patch
enskit Patch
ensskills Patch
@ensnode/datasources Patch
@ensnode/ensrainbow-sdk Patch
@ensnode/ensdb-sdk Patch
@ensnode/ensnode-react Patch
@ensnode/ensnode-sdk Patch
@ensnode/ponder-sdk Patch
@ensnode/ponder-subgraph Patch
@ensnode/shared-configs Patch
@docs/ensnode Patch
@docs/ensrainbow Patch
@docs/mintlify Patch
@namehash/ens-referrals Patch
@namehash/namehash-ui Patch
@ensnode/integration-test-env Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link
Copy Markdown
Contributor

vercel bot commented Apr 5, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

3 Skipped Deployments
Project Deployment Actions Updated (UTC)
admin.ensnode.io Skipped Skipped Apr 6, 2026 8:46am
ensnode.io Skipped Skipped Apr 6, 2026 8:46am
ensrainbow.io Skipped Skipped Apr 6, 2026 8:46am

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 5, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: acf96c4b-eac3-4108-835c-61948b791ea9

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ll/rest-api-tests

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.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Apr 5, 2026

Greptile Summary

This PR adds integration test coverage for the three REST API resolution endpoints in ensapi (resolve-primary-name, resolve-primary-names, resolve-records) and makes minor docker-compose.yml updates.

  • New integration tests cover success paths (resolving ETH addresses, text records, aliased names, multi-chain primary names) and validation error paths (invalid addresses, non-normalized names, duplicate/invalid query parameters)
  • Tests are data-driven using it.each and use toMatchObject for flexible partial matching against the devnet state
  • docker-compose.yml now supports ENSNODE_VERSION and DEVNET_VERSION env vars for pinning image versions, adds build: sections for local development, and adds RPC_URL_15658733 to the ensindexer service to fix connection errors when running with ens-test-env
  • Minor: resolution-api-client.ts is exported but never imported by any test file; and there is a small URL construction inconsistency in resolve-records.integration.test.ts compared to the other two test files

Confidence Score: 5/5

This PR is safe to merge — all changes are test infrastructure and docker configuration with no production code changes.

Both findings are P2 (dead code export and a stylistic URL inconsistency). No logic bugs, security issues, or breaking changes are introduced. The tests are well-structured with comprehensive coverage of success and error paths.

apps/ensapi/src/test/integration/resolution-api-client.ts — unused file that should either be imported or removed.

Important Files Changed

Filename Overview
.changeset/sparkly-mangos-tease.md Adds patch changeset entry for ensapi integration tests
apps/ensapi/src/handlers/api/resolution/resolve-primary-name.integration.test.ts Integration tests for primary-name endpoint; covers success, acceleration flag, and validation error cases
apps/ensapi/src/handlers/api/resolution/resolve-primary-names.integration.test.ts Integration tests for primary-names (multi-chain) endpoint; covers success, omitted chainIds, and validation errors
apps/ensapi/src/handlers/api/resolution/resolve-records.integration.test.ts Integration tests for records endpoint; covers addresses, texts, aliased names, and validation errors; minor URL construction inconsistency on line 222
apps/ensapi/src/test/integration/resolution-api-client.ts Exports EnsApiClient instance that is never imported by any test file — dead code
docker-compose.yml Parameterizes image versions via env vars, adds build sections for local development, and adds RPC_URL_15658733 to ensindexer

Sequence Diagram

sequenceDiagram
    participant Test as Integration Tests
    participant API as ENSApi (:4334)
    participant DB as PostgreSQL
    participant DN as Devnet (chain 15658733)

    Test->>API: GET /api/resolve/primary-name/:address/:chainId
    API->>DB: query primary name record
    DB-->>API: null (no primary set in devnet)
    API-->>Test: 200 { name: null, accelerationRequested: false }

    Test->>API: GET /api/resolve/primary-names/:address?chainIds=1,15658733
    API->>DB: query primary names for each chainId
    DB-->>API: { 1: null, 15658733: null }
    API-->>Test: 200 { names: { "1": null, "15658733": null }, ... }

    Test->>API: GET /api/resolve/records/test.eth?addresses=60
    API->>DB: query resolver records
    DB-->>API: { addresses: { 60: "0x70997970..." } }
    API-->>Test: 200 { records: { addresses: { 60: "0x70997970..." } }, ... }

    Test->>API: GET /api/resolve/records/TEST.ETH?addresses=60
    API-->>Test: 400 { message: "Invalid Input", details: { name: ["Must be normalized..."] } }
Loading

Reviews (1): Last reviewed commit: "docs(changeset): add integration tests f..." | Re-trigger Greptile

@vercel vercel bot temporarily deployed to Preview – ensrainbow.io April 6, 2026 08:46 Inactive
@vercel vercel bot temporarily deployed to Preview – admin.ensnode.io April 6, 2026 08:46 Inactive
@vercel vercel bot temporarily deployed to Preview – ensnode.io April 6, 2026 08:46 Inactive
@sevenzing sevenzing changed the title Ll/rest api tests tests: add tests to ensapi using ens-test-env Apr 6, 2026
Copy link
Copy Markdown
Member

@lightwalker-eth lightwalker-eth left a comment

Choose a reason for hiding this comment

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

@sevenzing Hey cool to see this. Reviewed and shared some suggestions appreciate your advice.

ensrainbow:
container_name: ensrainbow
image: ghcr.io/namehash/ensnode/ensrainbow:latest
image: ghcr.io/namehash/ensnode/ensrainbow:${ENSNODE_VERSION:-latest}
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.

Could you please suggest all the relevant places for us to add docs about ENSNODE_VERSION when running this docker compose file? I assume this is a new environment variable that's being added.

We want to always have all environment variables formally documented.

devnet:
container_name: devnet
image: ghcr.io/ensdomains/contracts-v2:main-e8696c6
image: ghcr.io/ensdomains/contracts-v2:${DEVNET_VERSION:-main-e8696c6}
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.

Similar feedback about DEVNET_VERSION.

ENSDB_URL: postgresql://postgres:password@postgres:5432/postgres
ENSINDEXER_SCHEMA_NAME: docker_compose_ensindexer_schema
ENSRAINBOW_URL: http://ensrainbow:3223
RPC_URL_15658733: http://devnet:8545
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.

Can you please share your advice here?

I'm worried that we're combining too many goals together into this root docker-compose.yml file.

What if someone wants to docker compose just running ENSNode without also running the devnet? In many cases this will be true. I don't believe we should assume that anyone wanting to run docker compose will also want to run the full devnet (and integration tests).

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.

yes! agree on that, I also dont know why we included devnet as default option.

I would simply create docker directory and store several composes in it splitting by enviroments

  • docker-compose.yaml -- basic case when user wants to run ensnode against mainnet
  • docker-compose.devnet.yaml -- case when user wants to run ensnode against devnet .for example try use extend` feature in docker-compose
  • docker-compose.sepolia.yaml

but i think we can discuss it with team in slack thread

@@ -105,7 +118,7 @@ services:

devnet:
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.

Please see my other feedback above about making the assumption that anyone running docker-compose also wants to run the devnet.

Advice appreciated.

"ensapi": patch
---

add integration tests for ensapi
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.

Suggested change
add integration tests for ensapi
add integration tests for resolution APIs in ensapi

expectedBody: { name: null, accelerationRequested: false, accelerationAttempted: false },
},
{
description: "owner address with accelerate=true returns accelerationRequested: true",
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.

What is an "owner address"? Owner of what?

it.each([
{
description:
"resolves primary names for owner address on chain 1 (no primary name set in devnet)",
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.

What is an "owner" address?

},
},
{
description: "resolves primary names across all supported chains when chainIds is omitted",
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.

Suggested change
description: "resolves primary names across all supported chains when chainIds is omitted",
description: "resolves primary names across all indexed chains when chainIds is omitted",

Can you please double check the correct terminology here with @shrugs? It will be valuable for us to precisely describe this idea.

I'm not sure just from my memory what determines the chainids that will be returned here by default. Let's precisely document it.


const BASE_URL = process.env.ENSNODE_URL || "http://localhost:4334";

const OWNER = "0x70997970c51812dc3a010c7d01b50e0d17dc79c8";
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.

Can you help me understand why we call this OWNER? I'm concerned about the overloaded use of terminology.

Is there a more specific / distinct name we could give this?

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 already use this notation in project:

const DEVNET_OWNER = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8";
// biome-ignore lint/correctness/noUnusedVariables: keeping it around for the future
const DEVNET_USER = "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC";

[ENSNamespaceIds.EnsTestEnv]: [
{ address: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", name: "deployer" },
{ address: "0x70997970C51812dc3A010C7d01b50e0d17dc79C8", name: "owner" },
{ address: "0x90F79bf6EB2c4f870365E785982E1f101E93b906", name: "user" },
],

I thought this is well known names for devnet testing 😄

I had an idea to reuse defined const for deployer and user, but importing them from omnigraph/examples-queries.ts looked weird and I didn't want to overload the PR by moving it in a separate module, but I can do it without any problems!

@@ -0,0 +1,230 @@
import { describe, expect, it } from "vitest";

const BASE_URL = process.env.ENSNODE_URL || "http://localhost:4334";
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.

Instead of directly reading from environment variables in these integration test files, what if you read from the config object as exported from apps/ensapi/src/config/index.ts?

Goal: Prefer to constrain where the responsibility lives for reading from / parsing environment variables.

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.

agree, I didt like my solution here, and wanted to use config. I just decided to be concise with current approach here

export const ENSNODE_OMNIGRAPH_API_URL = new URL(
"/api/omnigraph",
process.env.ENSNODE_URL || "http://localhost:4334",
).href;

and didnt want to rewrite existing tests.

Should I simply try to use this approach in resolution ensapi only or try to apply in omnigraph also?

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