test(wallets): add integration test for empty trade history - #657
Merged
Chucks1093 merged 1 commit intoJul 26, 2026
Merged
Conversation
Covers GET /api/v1/wallets/:address/activity for a wallet that has never traded: 200 with an empty items array, hasMore false and nextCursor present and null — not a 404 and not an error envelope. Requests go through the real Express app via supertest so routing, address validation, the controller, the service and JSON serialization all participate; only Prisma is mocked, matching the other integration tests in this module. Beyond the four acceptance criteria the suite asserts the query is scoped to the requested wallet (otherwise an empty page would be incidental rather than an answer about that address), pins the wire format for nextCursor directly, and checks the contract holds across type, creator_id, pagination and cursor variants. wallet-activity-invalid-address.integration.test.ts already held a partial version of this case which asserted neither nextCursor nor the cursor branch, in a file scoped to malformed addresses. It moved here rather than being duplicated.
|
@Fury03 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #642
Adds
src/modules/wallets/wallet-activity-empty-history.integration.test.ts, covering the trade history endpoint (GET /api/v1/wallets/:address/activity) for a wallet that has never traded.Requests go through the real Express app via supertest, so routing, address validation, the controller, the service and JSON serialization all participate. Only Prisma is mocked — no database required, consistent with the other integration tests in this module.
Acceptance criteria
expect(response.status).toBe(200)itemsis an empty arrayexpect(body.data.items).toEqual([])has_moreis falseexpect(body.data.meta.hasMore).toBe(false)next_cursoris nullexpect(body.data.meta).toHaveProperty('nextCursor', null)One note on field names
The issue describes the fields as
has_moreandnext_cursor. The endpoint actually serializes them in camelCase (hasMore,nextCursor), nested underdata.meta:{ "success": true, "data": { "items": [], "meta": { "limit": 20, "offset": 0, "total": 0, "hasMore": false, "nextCursor": null } } }There is no snake_case transform anywhere in the response path, so I've pinned the shape the endpoint really returns rather than the shape the issue names. Flagging it in case the intent was that the API should be snake_case — that would be an API change rather than a test, so it isn't in this PR.
Beyond the four assertions
nextCursoris checked withtoHaveProperty(..., null), not equality againstnull. A key that is absent reads back asundefined, and a client doingmeta.nextCursor === nullto decide whether to stop paging behaves differently from one checking for a falsy value. The criterion is that the key is present and null, so that is what's asserted — plus a check on the raw response text for"nextCursor":null, which pins the wire format directly.type=buy,type=sell,creator_id, explicit pagination, offset past the end, combined filters). A filter that happens to match nothing is the same situation as a wallet that never traded, and is the case this endpoint is most likely to hit in production.fetchWalletActivitythan offset paging and computeshasMorefrom the returned row count rather than the total, so it needs its own coverage.11 tests.
Mutation-tested
I confirmed the tests are load-bearing rather than green by accident, by breaking the controller three ways and checking each is caught:
nextCursoromitted from the response404returned whenitemsis emptyhasMorehard-coded totrueThe controller was restored afterwards — this PR contains no source changes.
One relocation
wallet-activity-invalid-address.integration.test.tsalready contained a partial version of this case ('should return 200 with empty data array for a valid Stellar address with no trade history'). It asserted status,itemsandhasMorebut notnextCursor, and it sat in a file whosedescribeblock is Malformed Stellar Address.Rather than leave a weaker duplicate behind, I removed it there and covered it fully in the new file, which matches how this module already splits by concern (
-date-filter,-creator-filter,-invalid-address). Net coverage strictly increases. The now-unusedmockPrisma/VALID_ADDRESSbindings in that file were dropped with it, and a comment points to the new location.Happy to restore it if you'd rather the duplication stayed.
Testing
pnpm lint— cleanpnpm build— cleanpnpm exec prisma generatewhen schema or generated types changed — n/a, no schema changepnpm exec prettier --checkon both touched files — cleanjest wallet-activity-empty-history.integration.test.ts— 11/11 passjest wallet-activity-invalid-address.integration.test.ts— 4/4 passCI runs lint and build only, not the test suite, so the new tests were verified locally.
On the rest of the module suite
Running the whole
src/modules/walletsdirectory locally shows failures I want to be transparent about, none of them from this PR:src/modules/wallets/__tests__/need a real Postgres (they callprisma.*.deleteMany), and I have no database running locally.wallet-activity-invalid-address.integration.test.tsexactly as it is onmain, with none of my changes, and reproducing the same timeout onshould return 400 for address with wrong prefix.Both touched files pass consistently when run with
--runInBand(43s and 41s respectively).Checklist