Skip to content

fix(donation-api): add controller contract tests and stabilize donati…#69

Open
Joyyyb wants to merge 1 commit into
Fundable-Protocol:devfrom
Joyyyb:fix/donation-controller-api-contract
Open

fix(donation-api): add controller contract tests and stabilize donati…#69
Joyyyb wants to merge 1 commit into
Fundable-Protocol:devfrom
Joyyyb:fix/donation-controller-api-contract

Conversation

@Joyyyb

@Joyyyb Joyyyb commented Jun 29, 2026

Copy link
Copy Markdown

…on error responses

This change adds route/controller coverage for donation creation, listing, detail retrieval, campaign/user/my donation endpoints, admin auth checks, policy validation failures, and not-found behavior. It also ensures donation controllers return shared API payloads consistently and map database-not-ready failures to the stable DB_NOT_READY error code instead of collapsing them into a generic internal error.

The implementation updates the donation controller to recognize database initialization failures explicitly, sends validation issues from policyMiddleware through the shared sendError helper, and introduces API-level tests that exercise success and expected failure responses without changing donation schema fields or endpoint surface area.

Closes #7ea6c6de-c6ed-4cea-9e3b-fe610b2ec172

Summary

Describe what changed and why.

Area

  • Backend API (src/)
  • Indexer common infrastructure (indexer/common/)
  • Streams indexer (indexer/streams/)
  • Distributions indexer (indexer/distributions/)
  • Tooling, docs, CI, or Docker

Scope

  • This PR addresses one scoped issue or task
  • Unrelated formatting, generated files, and follow-up work were left out
  • Backend and indexer package boundaries were respected

Verification

  • bun run type-check
  • bun run test
  • bun run lint
  • bun run indexer:type-check if indexer files changed
  • bun run indexer:test if indexer files changed
  • bun run indexer:lint if indexer files changed

Indexer Safety

  • Event processing changes are idempotent or do not affect event processing
  • Cursor changes advance only after successful processing
  • Event names and payload shapes were confirmed from contracts, if relevant
  • Backfill and replay behavior was considered, if relevant

Notes

Closes #62

Summary by CodeRabbit

  • Bug Fixes
    • Validation failures now return a consistent VALIDATION_ERROR response, including structured issue details.
    • Donation endpoints now detect when the database isn’t initialized and return a clear DB_NOT_READY (500) response.
  • Tests
    • Added controller test coverage for donation creation, listing, lookup, campaign/user filtering, admin-only stats, and error handling (validation + database-not-ready cases).

@drips-wave

drips-wave Bot commented Jun 29, 2026

Copy link
Copy Markdown

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

@coderabbitai

coderabbitai Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds direct VALIDATION_ERROR responses for Zod validation failures, maps uninitialized database errors to DB_NOT_READY, and adds integration tests covering donation route success, authorization, filtering, stats, and error responses.

Changes

Donation Error Mapping and Integration Tests

Layer / File(s) Summary
Policy middleware and controller error mapping
src/appMiddlewares/policy.middleware.ts, src/components/v1/Donation/donation.controller.ts
policy.middleware.ts now returns sendError directly for ZodError with VALIDATION_ERROR; donation.controller.ts adds isDatabaseNotInitializedError and returns DB_NOT_READY for that case.
Test harness setup
src/__tests__/donation.controller.test.ts
Adds a mocked donation repository, Express app factory, HTTP request helpers, and JWT bearer token helper for exercising the donation routes.
Donation route tests
src/__tests__/donation.controller.test.ts
Covers donation creation, admin and auth checks, donation lookup, campaign/user filters, stats aggregation, and the DB_NOT_READY and VALIDATION_ERROR error paths.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The summary is useful, but the required template sections are not filled out, including Area, Scope, and Verification. Fill in the checklist sections with the relevant area, scope, verification commands, and notes before merging.
Linked Issues check ⚠️ Warning The PR covers #62, but it does not implement the required campaign creation endpoint from #7. Add the POST /api/v1/campaigns endpoint with validation, contract integration, persistence, and error handling required by #7.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title is specific and matches the donation API tests and error-handling changes, even though it is truncated.
Out of Scope Changes check ✅ Passed The code changes stay focused on donation API tests and error mapping and do not introduce unrelated functionality.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.


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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/appMiddlewares/policy.middleware.ts (1)

9-9: 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Use the actual response object in this branch.

Line 9 still names the parameter _res, but Lines 24-29 call sendError(res, ...). That leaves res undefined here, so this middleware will not type-check/compile.

Suggested fix
-    (req: IRequest, _res: Response, next: NextFunction) => {
+    (req: IRequest, res: Response, next: NextFunction) => {

Also applies to: 24-29

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/appMiddlewares/policy.middleware.ts` at line 9, The middleware in
policy.middleware.ts is still naming the response parameter `_res`, but the body
uses `res` when calling sendError, so the branch won’t type-check. Update the
middleware signature to use the actual response object name consistently, and
make sure the same identifier is passed through the error handling path in this
function so sendError can reference it correctly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/__tests__/donation.controller.test.ts`:
- Around line 42-88: The repository mock in donation.controller.test.ts is
ignoring the collected query filters, so the tests can’t detect incorrect
campaign/user/auth wiring. Update the createQueryBuilder mock’s getMany(),
getCount(), and getRawOne() behavior to apply the stored _wheres clauses before
returning results, using the qb state built by where() and andWhere(). This
should make the mocked repository honor route-specific filters in the
controller/service tests.
- Around line 96-103: The test helper makeApp is mutating the shared
AppDataSource singleton and leaving mocked isInitialized/getRepository state
behind, which can leak into other tests. Update the donation.controller.test
setup to save the original AppDataSource state before mocking, and restore it
after each test in the relevant describe block(s), including the helper used
around makeApp and the other affected setup at the referenced later location.
Ensure any overrides to AppDataSource as any are reset in afterEach so tests
remain isolated and order-independent.

---

Outside diff comments:
In `@src/appMiddlewares/policy.middleware.ts`:
- Line 9: The middleware in policy.middleware.ts is still naming the response
parameter `_res`, but the body uses `res` when calling sendError, so the branch
won’t type-check. Update the middleware signature to use the actual response
object name consistently, and make sure the same identifier is passed through
the error handling path in this function so sendError can reference it
correctly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3519ffb2-9de1-427f-9b45-16654767b44e

📥 Commits

Reviewing files that changed from the base of the PR and between 43f39f6 and a628f8b.

📒 Files selected for processing (3)
  • src/__tests__/donation.controller.test.ts
  • src/appMiddlewares/policy.middleware.ts
  • src/components/v1/Donation/donation.controller.ts

Comment thread src/__tests__/donation.controller.test.ts
Comment thread src/__tests__/donation.controller.test.ts
@pragmaticAweds

Copy link
Copy Markdown
Contributor

Hi @Joyyyb

Thank you for your awesome contribution, however after analyzing your implementation, there are some minor fixes to be done. Kindly fix them to merge your PR asap.

Also do not forget to use fundable.finance to offramp.

…on error responses

This change adds route/controller coverage for donation creation, listing, detail retrieval, campaign/user/my donation endpoints, admin auth checks, policy validation failures, and not-found behavior. It also ensures donation controllers return shared API payloads consistently and map database-not-ready failures to the stable DB_NOT_READY error code instead of collapsing them into a generic internal error.

The implementation updates the donation controller to recognize database initialization failures explicitly, sends validation issues from policyMiddleware through the shared sendError helper, and introduces API-level tests that exercise success and expected failure responses without changing donation schema fields or endpoint surface area.

Closes #7ea6c6de-c6ed-4cea-9e3b-fe610b2ec172
@Joyyyb Joyyyb force-pushed the fix/donation-controller-api-contract branch from a628f8b to ea61d4e Compare July 1, 2026 14:20

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/__tests__/donation.controller.test.ts (1)

351-380: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Duplicated app-bootstrap logic for the DB_NOT_READY test.

This test re-implements makeApp's body (express init, route mounting, AppDataSource stubbing) instead of parameterizing the existing helper with an isInitialized flag.

♻️ Suggested refactor
-const makeApp = (repo: any) => {
+const makeApp = (repo: any, isInitialized = true) => {
     const app = express();
     app.use(express.json());
-    (AppDataSource as any).isInitialized = true;
+    (AppDataSource as any).isInitialized = isInitialized;
     (AppDataSource as any).getRepository = () => repo;
     app.use('/donations', donationRoutes);
     return app;
 };
 test('POST /donations returns DB_NOT_READY when the data source is unavailable', async () => {
     const repo = makeRepo();
-    const app = express();
-    app.use(express.json());
-    (AppDataSource as any).isInitialized = false;
-    (AppDataSource as any).getRepository = () => repo;
-    app.use('/donations', donationRoutes);
+    const app = makeApp(repo, false);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/__tests__/donation.controller.test.ts` around lines 351 - 380, The
DB_NOT_READY test is duplicating the app setup logic instead of reusing the
shared helper. Update the test to use the existing makeApp helper in
donation.controller.test.ts and add a way to pass the AppDataSource
initialization state (for example, an isInitialized flag) so the test can set
the source as unavailable without rebuilding the express app and route wiring
inline.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/__tests__/donation.controller.test.ts`:
- Around line 128-129: The test helper that creates auth tokens is signing with
a hardcoded secret, which can diverge from the app’s JWT verification config.
Update the bearerToken helper in donation.controller.test.ts to read the same
JWT secret used by the middleware via appConfigs.authConfig.jwtSecret so the
generated tokens match the app configuration. Use the existing helper name
bearerToken and the auth config symbol appConfigs.authConfig.jwtSecret to locate
the change.

---

Nitpick comments:
In `@src/__tests__/donation.controller.test.ts`:
- Around line 351-380: The DB_NOT_READY test is duplicating the app setup logic
instead of reusing the shared helper. Update the test to use the existing
makeApp helper in donation.controller.test.ts and add a way to pass the
AppDataSource initialization state (for example, an isInitialized flag) so the
test can set the source as unavailable without rebuilding the express app and
route wiring inline.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3a866cbf-9633-41d8-b585-314469c724f9

📥 Commits

Reviewing files that changed from the base of the PR and between a628f8b and ea61d4e.

📒 Files selected for processing (3)
  • src/__tests__/donation.controller.test.ts
  • src/appMiddlewares/policy.middleware.ts
  • src/components/v1/Donation/donation.controller.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/appMiddlewares/policy.middleware.ts
  • src/components/v1/Donation/donation.controller.ts

Comment thread src/__tests__/donation.controller.test.ts
@Joyyyb

Joyyyb commented Jul 1, 2026

Copy link
Copy Markdown
Author

Hi @Joyyyb

Thank you for your awesome contribution, however after analyzing your implementation, there are some minor fixes to be done. Kindly fix them to merge your PR asap.

Also do not forget to use fundable.finance to offramp.

Conflict has been resolved. Thanks for calling my attention to it, and I will surely check out Fundable.finance.

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.

Add donation API integration tests and stable error mapping

2 participants