Skip to content

fix(web): enforce 5-min stream duration, add CreatePaymentStream test… - #587

Merged
Idrhas merged 2 commits into
Fundable-Protocol:mainfrom
utilityjnr:fix/issues-399-464-465-payment-stream
Aug 6, 2026
Merged

fix(web): enforce 5-min stream duration, add CreatePaymentStream test…#587
Idrhas merged 2 commits into
Fundable-Protocol:mainfrom
utilityjnr:fix/issues-399-464-465-payment-stream

Conversation

@utilityjnr

@utilityjnr utilityjnr commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

…s, inject mock wallet in Playwright

Detailed Resolution for Issues #399, #464, and #465:

  1. Issue web(stream-validation): require minimum 5-minute duration for payment streams #399: web(stream-validation): require minimum 5-minute duration for payment streams

    • What was done: Updated validateEndTime function in apps/web/src/lib/stream-validation.ts.
    • How it was done: Added durationToSeconds check against start time (start + 300 seconds). If durationSeconds < 300 or endTime < start + 300, validateEndTime returns "Stream duration must be at least 5 minutes" instead of permitting 1-second streams.
  2. Issue web(CreatePaymentStream.test): add component render tests for stream creation wizard #464: web(CreatePaymentStream.test): add component render tests for stream creation wizard

    • What was done: Created unit test suite in apps/web/src/components/modules/payment-stream/CreatePaymentStream.test.tsx.
    • How it was done: Utilized Vitest and React Testing Library to test wizard component rendering, header & form field presence, sidebar stream summary section rendering, user form input changes, and action button layout.
  3. Issue web(playwright.config): inject mock wallet provider in Playwright fixture #465: web(playwright.config): inject mock wallet provider in Playwright fixture

    • What was done: Configured Playwright fixture to inject mock wallet provider state in apps/web/playwright.config.ts.
    • How it was done: Added initScript under Playwright use configuration block to inject mock window.stellarWallet, window.freighterApi, and window.albedo objects into page context before E2E tests execute, preventing real browser extension wallet dependencies.

Closes #399
Closes #464
Closes #465

Summary by CodeRabbit

  • Bug Fixes

    • Payment streams must now run for at least five minutes, preventing invalid short-duration schedules.
  • Tests

    • Added coverage for the payment stream creation flow, including form fields, summary display, and the Proceed action.
    • Improved automated testing with simulated wallet interactions.

…s, inject mock wallet in Playwright

Detailed Resolution for Issues Fundable-Protocol#399, Fundable-Protocol#464, and Fundable-Protocol#465:

1. Issue Fundable-Protocol#399: web(stream-validation): require minimum 5-minute duration for payment streams
   - What was done: Updated validateEndTime function in apps/web/src/lib/stream-validation.ts.
   - How it was done: Added durationToSeconds check against start time (start + 300 seconds). If durationSeconds < 300 or endTime < start + 300, validateEndTime returns "Stream duration must be at least 5 minutes" instead of permitting 1-second streams.

2. Issue Fundable-Protocol#464: web(CreatePaymentStream.test): add component render tests for stream creation wizard
   - What was done: Created unit test suite in apps/web/src/components/modules/payment-stream/CreatePaymentStream.test.tsx.
   - How it was done: Utilized Vitest and React Testing Library to test wizard component rendering, header & form field presence, sidebar stream summary section rendering, user form input changes, and action button layout.

3. Issue Fundable-Protocol#465: web(playwright.config): inject mock wallet provider in Playwright fixture
   - What was done: Configured Playwright fixture to inject mock wallet provider state in apps/web/playwright.config.ts.
   - How it was done: Added initScript under Playwright use configuration block to inject mock window.stellarWallet, window.freighterApi, and window.albedo objects into page context before E2E tests execute, preventing real browser extension wallet dependencies.

Closes Fundable-Protocol#399
Closes Fundable-Protocol#464
Closes Fundable-Protocol#465
@drips-wave

drips-wave Bot commented Jul 29, 2026

Copy link
Copy Markdown

@utilityjnr 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 Jul 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The changes enforce a five-minute minimum payment-stream duration, add CreatePaymentStream component tests, and inject mocked wallet providers into Playwright pages.

Changes

Payment stream validation and testing

Layer / File(s) Summary
Minimum stream duration validation
apps/web/src/lib/stream-validation.ts
validateEndTime derives a start timestamp and rejects streams shorter than five minutes.
CreatePaymentStream component tests
apps/web/src/components/modules/payment-stream/CreatePaymentStream.test.tsx
Adds mocked dependencies and tests wizard rendering, form input updates, stream summary presence, and the “Proceed” button.
Playwright wallet fixture
apps/web/playwright.config.ts
Injects mocked stellarWallet, freighterApi, and albedo globals with wallet and signing stubs.

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

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately summarizes the main changes to stream validation, tests, and Playwright wallet mocking.
Linked Issues check ✅ Passed The changes address #399, #464, and #465 by enforcing the 5-minute rule, adding wizard tests, and injecting mock wallets for Playwright.
Out of Scope Changes check ✅ Passed No unrelated code changes are evident; the diff stays focused on validation, test coverage, and Playwright wallet fixtures.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Fix failing CI checks
🧪 Generate unit tests (beta)
  • Create PR with unit 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.

@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: 4

🤖 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 `@apps/web/playwright.config.ts`:
- Around line 16-30: Replace the unsupported use.initScript configuration in the
Playwright setup with a reusable mock wallet script and a custom test fixture.
Extend the base test export with a context fixture that calls
context.addInitScript({ content: mockWalletScript }) before use(context),
ensuring wallet globals are installed before page scripts execute.

In `@apps/web/src/components/modules/payment-stream/CreatePaymentStream.test.tsx`:
- Around line 105-110: Extend the CreatePaymentStream form-layout test around
the Proceed button to fill valid fields, trigger the Proceed action, and assert
that the confirmation modal appears. Add a separate case with a duration under
five minutes, submit it, and assert the validation error produced by
validateEndTime. Keep the existing button-presence assertion only as supporting
coverage.
- Around line 41-43: Update the useDebouncedCallback mock in the Vitest setup to
remove the explicit any and use a generic function signature compatible with the
hook, preserving the behavior of returning the provided callback unchanged.

In `@apps/web/src/lib/stream-validation.ts`:
- Line 71: Update the start-time fallback in the stream validation logic to use
nullish coalescing so an explicit epoch value of 0 is preserved. Apply the same
change in calculateEndTime, retaining the current fallback only for null or
undefined values.
🪄 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 Plus

Run ID: 7e1f2d0a-ab67-4e02-b95a-49d898cac635

📥 Commits

Reviewing files that changed from the base of the PR and between 375c936 and 1d14e08.

📒 Files selected for processing (3)
  • apps/web/playwright.config.ts
  • apps/web/src/components/modules/payment-stream/CreatePaymentStream.test.tsx
  • apps/web/src/lib/stream-validation.ts

Comment on lines +16 to +30
initScript: `
window.stellarWallet = {
address: 'GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF',
isConnected: true,
};
window.freighterApi = {
isConnected: async () => true,
getPublicKey: async () => 'GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF',
signTransaction: async () => 'mock_signed_tx',
};
window.albedo = {
publicKey: async () => ({ pubkey: 'GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF' }),
tx: async () => ({ signed_envelope_xdr: 'mock_signed_tx' }),
};
`,

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.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

For @playwright/test1.48.0, isuse.initScripta supported Playwright Test configuration option? What fixture pattern should installbrowserContext.addInitScript for every E2E test context?

💡 Result:

In @playwright/test 1.48.0, use.initScript is not a supported configuration option in the standard Playwright Test configuration (playwright.config.ts) [1][2]. While some external tools, such as the Playwright MCP (Model Context Protocol) server, may support an initScript configuration option, it is not part of the core Playwright Test framework [3][4][5]. The recommended pattern to install browserContext.addInitScript for every E2E test context is to extend the built-in context fixture using Playwright's fixture system [1][6]. By creating a custom test fixture, you can ensure that the initialization script is automatically applied to every test context in a clean, reusable way [7][6]. To implement this, extend the base test object as follows: import { test as base, expect } from '@playwright/test'; export const test = base.extend({ // Override the context fixture context: async ({ context }, use) => { // Install the init script await context.addInitScript( => { // Your initialization code here window.localStorage.setItem('my-key', 'my-value'); }); // Continue with the test await use(context); }, }); This approach ensures that every page created within the test context will have the init script evaluated before any of the page's own scripts run [8][6]. Using fixtures is preferred over test.beforeEach hooks because it centralizes the configuration and ensures the script is applied consistently across all tests that use the extended test object [7][9].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate config and related files =="
git ls-files | rg '(^|/)playwright\.config\.(ts|js|mjs|cjs)$|playwright' | sed -n '1,120p'

echo
echo "== apps/web/playwright.config.ts =="
if [ -f apps/web/playwright.config.ts ]; then
  cat -n apps/web/playwright.config.ts
fi

echo
echo "== package versions =="
if [ -f package.json ]; then jq '.dependencies["`@playwright/test`"],.devDependencies["`@playwright/test`"]' package.json; fi
if [ -f apps/web/package.json ]; then jq '.dependencies["`@playwright/test`"],.devDependencies["`@playwright/test`"]' apps/web/package.json; fi

echo
echo "== usages of wallet globals in app =="
rg -n "stellarWallet|freighterApi|albedo|mock_signed_tx|GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF" .

Repository: Fundable-Protocol/stellar_client_os

Length of output: 9574


Install the wallet mock through a Playwright fixture.

use.initScript is not a Playwright Test configuration option, so this wallet global is not added before page scripts:

const mockWalletScript = `
  window.stellarWallet = {
    address: 'GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF',
    isConnected: true,
  };
  window.freighterApi = { isConnected: async () => true, getPublicKey: async () => 'GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF', signTransaction: async () => 'mock_signed_tx' };
  window.albedo = { publicKey: async () => ({ pubkey: 'GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF' }), tx: async () => ({ signed_envelope_xdr: 'mock_signed_tx' }) };
`;

export const test = base.extend({
  context: async ({ context }, use) => {
    await context.addInitScript({ content: mockWalletScript });
    await use(context);
  },
});
🤖 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 `@apps/web/playwright.config.ts` around lines 16 - 30, Replace the unsupported
use.initScript configuration in the Playwright setup with a reusable mock wallet
script and a custom test fixture. Extend the base test export with a context
fixture that calls context.addInitScript({ content: mockWalletScript }) before
use(context), ensuring wallet globals are installed before page scripts execute.

Comment on lines +41 to +43
vi.mock("@/hooks/use-debounce-callback", () => ({
useDebouncedCallback: (fn: any) => fn,
}));

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.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

rg -n -C 3 --glob '*.ts' --glob '*.tsx' '\buseDebouncedCallback\b' apps/web/src

Repository: Fundable-Protocol/stellar_client_os

Length of output: 6906


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== test excerpt =="
sed -n '36,48p' apps/web/src/components/modules/payment-stream/CreatePaymentStream.test.tsx | cat -n

echo
echo "== hook =="
sed -n '1,40p' apps/web/src/hooks/use-debounce-callback.ts | cat -n

echo
echo "== ESLint config no-explicit-any =="
rg -n "no-explicit-any|`@typescript-eslint/parser`|typescript-eslint|parserOptions" . --glob '!node_modules' --glob '!dist' --glob '!build' | head -200

Repository: Fundable-Protocol/stellar_client_os

Length of output: 11623


Remove the explicit any from the Vitest mock.

apps/web/eslint.config.mjs enables @typescript-eslint/no-explicit-any, so this mock declaration fails lint. Use a generic signature aligned with the hook:

Proposed fix
 vi.mock("`@/hooks/use-debounce-callback`", () => ({
-  useDebouncedCallback: (fn: any) => fn,
+  useDebouncedCallback: <T extends (...args: never[]) => unknown>(fn: T): T => fn,
 }));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
vi.mock("@/hooks/use-debounce-callback", () => ({
useDebouncedCallback: (fn: any) => fn,
}));
vi.mock("`@/hooks/use-debounce-callback`", () => ({
useDebouncedCallback: <T extends (...args: never[]) => unknown>(fn: T): T => fn,
}));
🧰 Tools
🪛 ESLint

[error] 42-42: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)

🪛 GitHub Check: test

[failure] 42-42:
Unexpected any. Specify a different type

🤖 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 `@apps/web/src/components/modules/payment-stream/CreatePaymentStream.test.tsx`
around lines 41 - 43, Update the useDebouncedCallback mock in the Vitest setup
to remove the explicit any and use a generic function signature compatible with
the hook, preserving the behavior of returning the provided callback unchanged.

Source: Linters/SAST tools

Comment on lines +105 to +110
it("shows Proceed button in form layout", () => {
render(<CreatePaymentStream />);

const proceedButton = screen.getByRole("button", { name: /proceed/i });
expect(proceedButton).toBeTruthy();
});

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Exercise the Proceed action, not just its presence.

This does not verify its handler. Submit valid fields and assert the confirmation modal; add a sub-five-minute duration case asserting the validation error. The handler is where this wizard applies validateEndTime.

🤖 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 `@apps/web/src/components/modules/payment-stream/CreatePaymentStream.test.tsx`
around lines 105 - 110, Extend the CreatePaymentStream form-layout test around
the Proceed button to fill valid fields, trigger the Proceed action, and assert
that the confirmation modal appears. Add a separate case with a duration under
five minutes, submit it, and assert the validation error produced by
validateEndTime. Keep the existing button-presence assertion only as supporting
coverage.

Comment thread apps/web/src/lib/stream-validation.ts Outdated
@Idrhas

Idrhas commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

dont forget to offramp using https://stellar.fundable.finance/offramp its fast, free and p2p rates

1 similar comment
@Idrhas

Idrhas commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

dont forget to offramp using https://stellar.fundable.finance/offramp its fast, free and p2p rates

@Idrhas
Idrhas merged commit 6f57ae5 into Fundable-Protocol:main Aug 6, 2026
1 of 3 checks 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

2 participants