Skip to content

fix(ui): enrich link previews for uppercase URL schemes#2843

Merged
xsahil03x merged 1 commit into
masterfrom
sahil/flu-625-url-enrichment-fails-for-uppercase-https-in-flutter
Jul 23, 2026
Merged

fix(ui): enrich link previews for uppercase URL schemes#2843
xsahil03x merged 1 commit into
masterfrom
sahil/flu-625-url-enrichment-fails-for-uppercase-https-in-flutter

Conversation

@xsahil03x

@xsahil03x xsahil03x commented Jul 23, 2026

Copy link
Copy Markdown
Member

Summary

Fixes FLU-625. URLs with an uppercase scheme (e.g. HTTPS://example.com) were not enriched into link previews, while lowercase https:// worked.

The composer's URL regex already matched uppercase schemes, but the raw matched text was forwarded to client.enrichUrl(...) verbatim — so the /og endpoint received HTTPS://… and failed to enrich. The fix normalizes the scheme (via Uri.parse, which lowercases it) before enriching, so HTTPS:// behaves the same as https://.

Flutter counterpart to the React (#3226) and Angular (#734) fixes.

Scope

This fixes the composer link-preview enrichment path. Display-side linkification of uppercase schemes in rendered message text lives in stream_core_flutter and is out of scope here.

Testing

Added message_composer_url_enrichment_test.dart — asserts enrichUrl is called with the normalized https://example.com for both uppercase and lowercase input. Fails before the fix, passes after.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Fixed link-preview (OG) enrichment when URL schemes are uppercase (e.g., HTTPS://) by normalizing the scheme before enrichment.
    • Improves preview selection by choosing the first eligible URL found in the message.
    • Clears any existing link-preview attachment when no qualifying preview candidate is available or link sending isn’t allowed.
  • Tests

    • Expanded widget tests with table-driven cases covering multiple scheme/host casing combinations and URLs embedded in surrounding text, ensuring the normalized URL is used for enrichment.

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The message composer normalizes URL schemes before link-preview enrichment, selects the first eligible URL, clears invalid OG attachments, and adds widget tests for URL casing and embedded links.

Changes

URL enrichment normalization

Layer / File(s) Summary
Normalize preview candidates
packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart, packages/stream_chat_flutter/CHANGELOG.md
The composer normalizes URL schemes before filtering and enrichment, selects the first eligible match, clears invalid OG attachments, and documents the fix.
Validate enrichment inputs
packages/stream_chat_flutter/test/src/message_input/message_composer_url_enrichment_test.dart
Widget tests cover uppercase and mixed-case schemes and hosts, preserve path/query casing, validate embedded URLs, and confirm lowercase schemes remain unchanged.

Estimated code review effort: 2 (Simple) | ~15 minutes

Suggested reviewers: renefloor

🚥 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 clearly matches the main fix: normalizing uppercase URL schemes so link previews can be enriched.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sahil/flu-625-url-enrichment-fails-for-uppercase-https-in-flutter

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.

@xsahil03x
xsahil03x force-pushed the sahil/flu-625-url-enrichment-fails-for-uppercase-https-in-flutter branch from daef717 to 27915b8 Compare July 23, 2026 10:08
@xsahil03x xsahil03x changed the title fix(message_input): recognize uppercase URL schemes for link enrichment fix(ui): enrich link previews for uppercase URL schemes Jul 23, 2026

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

🧹 Nitpick comments (2)
packages/stream_chat_flutter/test/src/message_input/message_composer_url_enrichment_test.dart (2)

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

Avoid the relative fakes.dart import.

The documented exception covers ../mocks.dart, not ../fakes.dart. Use a package import or add an explicit test-helper exception if this file must remain test-only. As per coding guidelines, packages/**/{lib,test}/**/*.dart: Use package imports instead of relative imports.

🤖 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
`@packages/stream_chat_flutter/test/src/message_input/message_composer_url_enrichment_test.dart`
at line 9, Replace the relative ../fakes.dart import in the message composer URL
enrichment test with the appropriate package import, following the package’s
existing import conventions; only add an explicit test-helper exception if a
package import is not viable.

Sources: Coding guidelines, Learnings


51-72: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use fake test time for the debounce.

runAsync is intended for real asynchronous work; this test only needs timer advancement. Pumping 500 ms avoids wall-clock delay and reduces timing sensitivity. (api.flutter.dev)

Proposed change
-      // Enrichment runs behind a real-clock debounce, so drive the flow with
-      // real timers via runAsync.
-      await tester.runAsync(() async {
-        await tester.pumpWidget(
-          MaterialApp(
-            home: StreamChat(
-              client: client,
-              connectivityStream: Stream.value([ConnectivityResult.mobile]),
-              child: StreamChannel(
-                channel: channel,
-                child: Scaffold(body: StreamMessageComposer()),
-              ),
-            ),
-          ),
-        );
-        await tester.pumpAndSettle();
-
-        await tester.enterText(find.byType(TextField), text);
-        await Future<void>.delayed(const Duration(milliseconds: 500));
-        await tester.pumpAndSettle();
-      });
+      await tester.pumpWidget(
+        MaterialApp(
+          home: StreamChat(
+            client: client,
+            connectivityStream: Stream.value([ConnectivityResult.mobile]),
+            child: StreamChannel(
+              channel: channel,
+              child: Scaffold(body: StreamMessageComposer()),
+            ),
+          ),
+        ),
+      );
+      await tester.pumpAndSettle();
+      await tester.enterText(find.byType(TextField), text);
+      await tester.pump(const Duration(milliseconds: 500));
+      await tester.pumpAndSettle();
🤖 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
`@packages/stream_chat_flutter/test/src/message_input/message_composer_url_enrichment_test.dart`
around lines 51 - 72, Update enrichUrlFrom to use Flutter’s fake test clock for
the debounce instead of tester.runAsync and a real Future.delayed. After
entering the text, advance the test duration by 500 milliseconds with the
tester’s pump mechanism, preserving the existing widget setup and settling
behavior.

Source: MCP tools

🤖 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.

Nitpick comments:
In
`@packages/stream_chat_flutter/test/src/message_input/message_composer_url_enrichment_test.dart`:
- Line 9: Replace the relative ../fakes.dart import in the message composer URL
enrichment test with the appropriate package import, following the package’s
existing import conventions; only add an explicit test-helper exception if a
package import is not viable.
- Around line 51-72: Update enrichUrlFrom to use Flutter’s fake test clock for
the debounce instead of tester.runAsync and a real Future.delayed. After
entering the text, advance the test duration by 500 milliseconds with the
tester’s pump mechanism, preserving the existing widget setup and settling
behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: bf9d5fa9-45d0-4568-952a-76d4fb451bf0

📥 Commits

Reviewing files that changed from the base of the PR and between 141dec2 and daef717.

📒 Files selected for processing (3)
  • packages/stream_chat_flutter/CHANGELOG.md
  • packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart
  • packages/stream_chat_flutter/test/src/message_input/message_composer_url_enrichment_test.dart

@codecov

codecov Bot commented Jul 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 71.71%. Comparing base (141dec2) to head (c9d2e5d).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2843      +/-   ##
==========================================
+ Coverage   71.48%   71.71%   +0.22%     
==========================================
  Files         426      426              
  Lines       26892    26891       -1     
==========================================
+ Hits        19224    19285      +61     
+ Misses       7668     7606      -62     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Uppercase schemes like `HTTPS://` were detected but forwarded verbatim
to the enrichment endpoint, which failed to return link-preview data.
Normalize the scheme before enriching so `HTTPS://` behaves like
`https://`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@xsahil03x
xsahil03x force-pushed the sahil/flu-625-url-enrichment-fails-for-uppercase-https-in-flutter branch from 27915b8 to c9d2e5d Compare July 23, 2026 10:42

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

🧹 Nitpick comments (1)
packages/stream_chat_flutter/test/src/message_input/message_composer_url_enrichment_test.dart (1)

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

Use a package import for fakes.dart.

The relative-import exception applies to ../mocks.dart, not ../fakes.dart. As per coding guidelines, “Use package imports instead of relative imports.” Based on learnings, only the shared mocks.dart helper is exempt.

🤖 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
`@packages/stream_chat_flutter/test/src/message_input/message_composer_url_enrichment_test.dart`
at line 9, Update the import in message composer URL enrichment tests to use the
package-qualified path for fakes.dart instead of a relative import, while
preserving the existing ../mocks.dart exception if present.

Sources: Coding guidelines, Learnings

🤖 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.

Nitpick comments:
In
`@packages/stream_chat_flutter/test/src/message_input/message_composer_url_enrichment_test.dart`:
- Line 9: Update the import in message composer URL enrichment tests to use the
package-qualified path for fakes.dart instead of a relative import, while
preserving the existing ../mocks.dart exception if present.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 15b5728b-5f74-4818-b7ed-cc3a0311f2d2

📥 Commits

Reviewing files that changed from the base of the PR and between 27915b8 and c9d2e5d.

📒 Files selected for processing (3)
  • packages/stream_chat_flutter/CHANGELOG.md
  • packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart
  • packages/stream_chat_flutter/test/src/message_input/message_composer_url_enrichment_test.dart
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/stream_chat_flutter/CHANGELOG.md

}).toList();
// Find the first url to preview, normalizing the scheme so links like
// `HTTPS://` enrich the same as `https://`.
String? firstMatchedUrl;

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.

Question: Wouldn't it be possible to end up without an enriched URL, it the /og endpoint doesn't return in time before sending the message, or if we send the message before this method fires (350ms debounce).
I am curious if maybe the bug report was for that reason 🤔 Because I can see some messages getting enriched even with HTTPS:// prefix

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes, it's a possibility. But when i tried reproducing it in the sample app i wasn't able to get any og for a link with uppercase HTTPS://. One way to solve it is to use url_enrichment flag on channel but it will still fail as the backend extracts the url from text and the text will still be with Uppercase letters. So this also needs to be fixed in the backend code in order to work correctly.

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.

I see, I was afraid that we would still see reports of this issue after the fix. But nevertheless, I see no reason to block this PR. But we should probably bring this up with the BE as well.

@xsahil03x
xsahil03x merged commit 6cb8195 into master Jul 23, 2026
27 of 28 checks passed
@xsahil03x
xsahil03x deleted the sahil/flu-625-url-enrichment-fails-for-uppercase-https-in-flutter branch July 23, 2026 12:37
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.

4 participants