feat(poc): Flutter POC simulation tests, session-dead guard & web OAuth docs#35
feat(poc): Flutter POC simulation tests, session-dead guard & web OAuth docs#35cemal-yilmaz-bt wants to merge 15 commits into
Conversation
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>
Reviewer's GuideHardens 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
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
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.
| 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')); |
There was a problem hiding this comment.
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.
| 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')); |
| final client = clientOverride ?? http.Client(); | ||
| final ownsClient = clientOverride == null; |
There was a problem hiding this comment.
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
|
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. |
Summary
PocSimStepsealed classes + typedrunPocSimStepexecutor driven bypoc-simulation.json; steps are now data, not codeisErrorsemantics, JSON parsing,isPocSessionDeadStop, mocked HTTP fetch client, and asset loading (poc_simulation_test.dart, 296 lines)isPocSessionDeadStopdetects stale Keycloak sessions in the auto-simulation loop; kept pure for testabilitywebOriginsfix, profile-mode runner (run_web.sh),memoryStorageMorphPluginon web to avoid ContextStore identity deadlock on redirectpoc-guide.mdFlutter section,dart-parity.mdupdated with web OAuth notes and Keycloak configWhat diverged from
f/pluginThis 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 testpasses inpoc/flutter-poc/(15 unit tests)flutter analyze— no issues🤖 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:
Enhancements:
Documentation:
Tests: