Skip to content

test: add coverage for pagination cursor, leaderboard sort, wallet validator, and creator profile stats - #688

Merged
Chucks1093 merged 1 commit into
accesslayerorg:mainfrom
Akpolo:test/issues-678-679-680-682
Jul 28, 2026
Merged

test: add coverage for pagination cursor, leaderboard sort, wallet validator, and creator profile stats#688
Chucks1093 merged 1 commit into
accesslayerorg:mainfrom
Akpolo:test/issues-678-679-680-682

Conversation

@Akpolo

@Akpolo Akpolo commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds test coverage for four assigned Stellar Wave issues in one branch/PR, per each issue's acceptance criteria. Two issues (#680, #678) required a small, targeted production fix because the endpoint they describe didn't fully exist yet; one issue (#682) exposed a real validation bug. Each is called out below.

#679 — Pagination cursor encode/decode round-trip (src/utils/test/cursor.utils.test.ts)

  • Integer ID + timestamp sort value round-trips losslessly, with typeof/toBe checks proving the type survives (not just toEqual).
  • String ID + numeric sort value round-trips losslessly, same strict-equality treatment.
  • A base64-tampered cursor (character flipped in the middle of the payload segment, not just at an edge) throws CursorChecksumError — this codebase's InvalidCursor-equivalent for encodeCursor/decodeCursor.
  • An empty string cursor throws CursorChecksumError.
  • No production code changed — the encoder/decoder already worked correctly; the existing test file only covered a narrower set of type combinations before this PR.

#680 — Leaderboard endpoint sorted by holder count (src/modules/creators/creator-leaderboard-sort-order.integration.test.ts)

  • Seeds three creators with holder counts 50 / 20 / 50 (mocked Prisma, following the same convention as the sibling trending endpoint's test).
  • Asserts both 50-holder creators rank above the 20-holder creator.
  • Asserts the 50/50 tie is broken alphabetically ascending by creator address.
  • Asserts every entry has rank, creator, holder_count, and current_price.
  • Production change: GET /api/v1/creators/leaderboard did not exist at all. Added httpGetCreatorLeaderboard (creators.controllers.ts) and wired the route in creators.routes.ts, computing holder count per creator, resolving creator to the owning user's Stellar wallet address, and sorting by holder count desc / address asc.

#682 — Stellar wallet address validator (src/modules/wallet/__tests__/wallet.utils.test.ts)

  • Valid mainnet G-address → true; wrong prefix (M... muxed-style) → false; random string → false; empty string → false (already covered by existing tests, extended with a real muxed-account fixture for the M-prefix case).
  • Invalid checksum → falsethis exposed a real bug: isValidStellarAddress only checked the surface shape (/^G[A-Z2-7]{55}$/) and never verified the StrKey checksum, so a well-formed-but-corrupted address passed validation. Fixed by delegating to StrKey.isValidEd25519PublicKey from the already-installed @stellar/stellar-base dependency.
  • Because several existing test fixtures across the wallet-holdings module used a non-checksum-valid placeholder address (GAAAA...) that only passed the old naive regex, this fix required swapping those fixtures for a real, checksum-valid address in: wallet-holdings-price-snapshot.integration.test.ts, wallet-holdings-zero-balance.integration.test.ts, wallet-holdings.service.integration.test.ts, and wallet-holdings-multiple-snapshots.integration.test.ts. No behavior in those files changed — only the fixture address.

#678 — Creator profile key stats after a buy (src/modules/creators/creator-stats-buy-transaction.integration.test.ts)

  • Seeds a creator with 3 holders totaling 10 keys and an initial price snapshot; asserts baseline totalSupply: 10, holderCount: 3.
  • Simulates a buy of 5 keys by a new investor via updateOwnership plus a new price snapshot value; asserts totalSupply: 15, holderCount: 4, updated currentPrice, and HTTP 200 — all three stats returned together.
  • Also covers that an existing holder buying more keys does not change the holder count.
  • Production fix: GET /api/v1/creators/:id/stats hardcoded totalSupply: 0 instead of deriving it from the ownership read model, so it never reflected buys. Fixed to aggregate keyOwnership.balance for the creator. Also added currentPrice (previously absent from this endpoint) sourced from creatorPriceSnapshot, since the acceptance criteria requires price to be returned alongside supply and holder count from the same response.

Test plan

Test Suites: 10 passed, 10 total
Tests:       60 passed, 60 total
```//covers all new/changed files above (creator-leaderboard-sort-order, creator-stats-buy-transaction, creator-detail-holder-count-sequential, trending-creators, cursor.utils, wallet.utils, and the four wallet-holdings fixture files)

Full existing suite re-run before/after: identical set of 55 pre-existing failing suites (unrelated to this change, e.g. a stray double-space typo in an error message, a `.js` import extension bug, and shared-DB cache-control flakiness) — no new regressions introduced. `pnpm exec tsc --noEmit`, `eslint`, and `prettier --check` all pass on every changed file.

Closes #678
Closes #679
Closes #680
Closes #682

@drips-wave

drips-wave Bot commented Jul 28, 2026

Copy link
Copy Markdown

@Akpolo 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! 🚀

Learn more about application limits

@Chucks1093
Chucks1093 merged commit d25eebb into accesslayerorg:main Jul 28, 2026
1 check passed
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