Skip to content

feat(poc): Flutter POC simulation tests, session-dead guard & web OAuth docs#35

Closed
cemal-yilmaz-bt wants to merge 15 commits into
f/pluginfrom
feat/issue-27-flutter-poc-parity
Closed

feat(poc): Flutter POC simulation tests, session-dead guard & web OAuth docs#35
cemal-yilmaz-bt wants to merge 15 commits into
f/pluginfrom
feat/issue-27-flutter-poc-parity

Conversation

@cemal-yilmaz-bt

@cemal-yilmaz-bt cemal-yilmaz-bt commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Simulation engine hardeningPocSimStep sealed classes + typed runPocSimStep executor driven by poc-simulation.json; steps are now data, not code
  • Unit test suite — 15 tests covering isError semantics, JSON parsing, isPocSessionDeadStop, mocked HTTP fetch client, and asset loading (poc_simulation_test.dart, 296 lines)
  • Session-dead guardisPocSessionDeadStop detects stale Keycloak sessions in the auto-simulation loop; kept pure for testability
  • Web OAuth polish — CORS webOrigins fix, profile-mode runner (run_web.sh), memoryStorageMorphPlugin on web to avoid ContextStore identity deadlock on redirect
  • Docspoc-guide.md Flutter section, dart-parity.md updated with web OAuth notes and Keycloak config

What diverged from f/plugin

This branch was cut before the TS SDK restructure (PR #32, #33). No conflicting changes — just 3 infra commits behind on f/plugin.

Test plan

  • flutter test passes in poc/flutter-poc/ (15 unit tests)
  • flutter analyze — no issues
  • Web OAuth flow works end-to-end with Keycloak (manual, see poc-guide.md)

🤖 Generated with Claude Code

Summary by Sourcery

Harden the Flutter PoC simulation engine, add unit tests around simulation and session-dead detection, refine the session-expiry guard used by the simulation UI, and extend docs with Flutter PoC and web OAuth details.

New Features:

  • Introduce a pure isPocSessionDeadStop helper to decide when the auto-simulation loop should stop on stale Keycloak sessions.
  • Expose parsePocSimulationJson to build PocSimulationConfig from JSON with a configurable mock API base URL fallback.
  • Add a test-only HTTP fetch entry point to support mocking HTTP in simulation tests.

Enhancements:

  • Refactor the simulation panel to reuse the shared session-dead helper instead of inlined logic.
  • Allow the fetch simulation step to use an injected HTTP client and ensure HTTP clients are properly disposed.
  • Clarify and restructure Dart parity notes for the Flutter PoC, storage behavior, and CI coverage limitations.
  • Document how the Flutter PoC executes simulation steps and its session-dead semantics in the simulation guide.
  • Update the docs index to describe Dart parity coverage and Flutter PoC parity more accurately.

Documentation:

  • Add a Flutter PoC section to the PoC guide covering web run script, OAuth, CORS, storage, simulation, and tests.
  • Expand dart-parity.md with details on Flutter PoC parity, storage behavior on web vs non-web, web OAuth constraints, and current CI scope.
  • Describe the Flutter PoC simulation executor and session-dead logic in docs/poc/simulation.md, including references to tests and JSON config.

Tests:

  • Add poc_simulation_test.dart with unit tests for PocSimStepResult.isError, JSON parsing, session-dead detection, mocked HTTP fetch steps, and asset loading.
  • Replace the empty widget_test.dart with a minimal smoke test to ensure the Flutter test harness runs.

u0b002 and others added 14 commits May 4, 2026 14:33
Closes #27

- Add assets/poc-simulation.json (copy of docs/poc/poc-simulation.json)
- Add lib/poc_simulation.dart: PocSimStep sealed classes + runPocSimStep
  executor for fetch / host / logout_provider steps
- Add lib/widgets/mock_api_sheet.dart: bottom sheet with all 9 simulation
  steps as buttons + integrated HTTP trace log
- Add lib/widgets/provider_config_sheet.dart: shows getProviderMeta() as
  formatted JSON
- Add lib/widgets/simulation_panel.dart: sequential auto-loop runner with
  per-step result rows, 404-probe toggle, and session-dead guard
- Refactor home_screen.dart: status grouped by provider, per-row dynamic
  actions driven by grantHint, Config button, token exchange dropdown
- Add getMockApiBase() to morph_init.dart (Android 10.0.2.2 aware)
- Add http as direct dependency; fix morph_realm.json localhost:4200 URIs
- flutter analyze: no issues

Co-authored-by: Cursor <cursoragent@cursor.com>
…bility

Co-authored-by: Cursor <cursoragent@cursor.com>
… new tab

Co-authored-by: Cursor <cursoragent@cursor.com>
Debug mode loads 596 separate JS files (30-60s) causing the Keycloak
authorization code (60s default) to expire before completeOAuthCallback
can exchange it, resulting in a blank screen / no-token state.

- run_web.sh: default to --profile (single bundled JS, ~2s load);
  --debug flag available when hot-reload is needed
- morph-realm.json: accessCodeLifespan 60s→300s so even slower loads
  won't race the code expiry window

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
… log panel

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…rashes

Co-authored-by: Cursor <cursoragent@cursor.com>
…tity deadlock

ContextStore.setData with Boundary.user silently drops writes when
_activeUser is not set. On web the OAuth redirect reloads the page so
the user identity is never established before the token write, causing
all session-scoped tokens to be silently discarded.

Use memoryStorageMorphPlugin on web: completeOAuthCallback() runs in
main() before runApp(), so the token is in the same JS heap the UI
then reads from — no persistence needed for the current page load.

Co-authored-by: Cursor <cursoragent@cursor.com>
…lank screen

The blank screen was caused by completeOAuthCallback hanging or crashing
silently before runApp() was called.  Render the UI first, then process
the OAuth callback in initState via addPostFrameCallback.  HomeScreen
exposes a public refreshStatus() that the parent app calls after the
callback completes.

Co-authored-by: Cursor <cursoragent@cursor.com>
- simulation_panel: fix &&/|| precedence in session-dead guard
- simulation_panel: drop duplicate Simulation title; use Spacer in toolbar
- mock_api_sheet: message color from result.isError; remove redundant ternary
- poc_simulation: 10s timeout on http.get; document PoC string-matching tradeoff

Co-authored-by: Cursor <cursoragent@cursor.com>
- Extract parsePocSimulationJson for JSON parsing without rootBundle
- Add isPocSessionDeadStop (used by SimulationPanel) with regression tests
- Refactor _runFetch to optional http.Client override + runPocSimFetchForTesting
- Add 15 tests: models, parser, session guard, mocked fetch, asset load
- Replace empty widget_test placeholder with minimal smoke test

Co-authored-by: Cursor <cursoragent@cursor.com>
- dart-parity: Flutter PoC parity (#27/#28), web vs native storage, Keycloak
  webOrigins, run_web.sh profile default, unit tests, CI scope for flutter-poc
- README: dart-parity description reflects current status
- poc-guide: new Flutter PoC section (run paths, OAuth, CORS, simulation, tests)
- poc/simulation: Flutter executor + isPocSessionDeadStop + test pointer

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@sourcery-ai

sourcery-ai Bot commented Jun 1, 2026

Copy link
Copy Markdown

Reviewer's Guide

Hardens the Flutter PoC simulation engine with a pure session-dead guard and testable fetch executor, adds a focused unit test suite around JSON parsing and HTTP behavior, and updates docs to describe Flutter PoC behavior and web OAuth configuration nuances.

File-Level Changes

Change Details Files
Add pure session-dead detection helper and JSON parser entrypoint for the Flutter PoC simulation engine.
  • Introduce isPocSessionDeadStop helper that encapsulates AUTH/session-dead detection logic based on step auth context and error detail.
  • Refactor loadPocSimulation to delegate to new parsePocSimulationJson for deterministic JSON parsing with a mockApiFallback base URL.
  • Document JSON parsing behavior and session-dead semantics in docs/poc/simulation.md.
poc/flutter-poc/lib/poc_simulation.dart
docs/poc/simulation.md
Make fetch simulation steps testable via injectable HTTP client and expose a testing-specific wrapper.
  • Extend _runFetch to accept an optional http.Client and manage its lifecycle when not injected.
  • Add @VisibleForTesting runPocSimFetchForTesting that forwards to _runFetch with an injected client for unit tests.
  • Ensure network errors and unexpected status handling remain consistent while using the injected client.
poc/flutter-poc/lib/poc_simulation.dart
Wire the new session-dead helper into the simulation UI panel instead of duplicating logic.
  • Replace inline session-dead detection in SimulationPanel with a call to isPocSessionDeadStop.
  • Preserve existing behavior of setting _sessionDeadMessage and breaking the simulation loop when a dead session is detected.
poc/flutter-poc/lib/widgets/simulation_panel.dart
Add a comprehensive unit test suite for the Flutter PoC simulation behavior and a minimal widget test harness.
  • Create poc_simulation_test.dart covering PocSimStepResult.isError semantics, parsePocSimulationJson parsing paths, isPocSessionDeadStop edge cases, mocked HTTP fetch behavior, and loading the real poc-simulation.json asset.
  • Update the placeholder widget_test.dart to include a trivial smoke test ensuring the Flutter test harness runs.
poc/flutter-poc/test/poc_simulation_test.dart
poc/flutter-poc/test/widget_test.dart
Expand Flutter PoC and Dart parity documentation with web OAuth, storage, simulation, and CI notes.
  • Add a Flutter PoC section to poc-guide.md describing run_web.sh, OAuth configuration, CORS/webOrigins, storage behavior, simulation UI, and tests.
  • Update dart-parity.md to clarify persistent storage vs web in-memory usage, Flutter PoC parity with the TS Vue PoC, web OAuth and Keycloak webOrigins requirements, unit tests, and CI coverage/limitations.
  • Adjust docs/README.md Dart parity entry to reflect broader Dart/Flutter SDK status and backlog.
  • Document the Flutter PoC simulation executor mapping and session-dead behavior in docs/poc/simulation.md.
docs/poc-guide.md
docs/dart-parity.md
docs/README.md
docs/poc/simulation.md

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented Jun 1, 2026

Copy link
Copy Markdown

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: defaults

Review profile: CHILL

Plan: Pro

Run ID: aaf600e4-af6e-4397-bcf0-53c5bf7bd5ba

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 feat/issue-27-flutter-poc-parity

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.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request introduces documentation and implementation updates for the Flutter Proof of Concept (PoC) to achieve feature parity with the TypeScript/Vue PoC. Key changes include adding detailed documentation for the Flutter PoC, implementing a session-dead check helper (isPocSessionDeadStop), refactoring the simulation JSON parsing, and adding comprehensive unit tests for the simulation logic. Feedback on the changes suggests simplifying the isPocSessionDeadStop logic to avoid closure overhead and optimizing HTTP client usage in fetch steps to enable connection reuse.

Comment on lines +84 to +91
if (result.status != 'AUTH') return false;
final isSessionDead = sessionDeadAuthIds.any(
(id) => step is PocSimHostStep && step.auth == id,
);
final detail = result.detail ?? '';
return isSessionDead &&
(detail.contains('invalid_grant') ||
detail.contains('Token is not active'));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The isPocSessionDeadStop function can be simplified and made more efficient. Currently, it performs a closure allocation and iterates over sessionDeadAuthIds using any for every check, even if the step is not a PocSimHostStep. By checking if the step is a PocSimHostStep first, we can perform a direct contains check on sessionDeadAuthIds, which is cleaner, more idiomatic, and avoids closure overhead.

Suggested change
if (result.status != 'AUTH') return false;
final isSessionDead = sessionDeadAuthIds.any(
(id) => step is PocSimHostStep && step.auth == id,
);
final detail = result.detail ?? '';
return isSessionDead &&
(detail.contains('invalid_grant') ||
detail.contains('Token is not active'));
if (result.status != 'AUTH') return false;
if (step is! PocSimHostStep) return false;
final isSessionDead = sessionDeadAuthIds.contains(step.auth);
final detail = result.detail ?? '';
return isSessionDead &&
(detail.contains('invalid_grant') ||
detail.contains('Token is not active'));

Comment on lines +217 to +218
final client = clientOverride ?? http.Client();
final ownsClient = clientOverride == null;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Creating a new http.Client instance on every single fetch step execution when clientOverride is null is inefficient. It prevents TCP connection reuse (keep-alive) and adds unnecessary overhead for each request. Consider managing a single, shared http.Client instance for the duration of the simulation loop (e.g., in the simulation panel state or the runner) and passing it down to _runFetch.

…+ reuse http.Client

- isPocSessionDeadStop: replace any() closure with type check + contains()
  for cleaner, closure-free logic (Gemini medium #1)
- SimulationPanel: own a single http.Client (_httpClient) for the widget
  lifetime, pass it through runPocSimStep → _runFetch to enable TCP
  keep-alive across simulation steps; close in dispose() (Gemini medium #2)
- runPocSimStep: add optional http.Client? param to thread client down
@cemal-yilmaz-bt

Copy link
Copy Markdown
Contributor Author

Closing in favour of a clean PR from fix/flutter-poc-tests-and-docs — the original branch had rebase conflicts due to diverged history. The Gemini fixes are preserved in the new PR.

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.

1 participant