diff --git a/lib/widgets/action_sheet.dart b/lib/widgets/action_sheet.dart index 30bbf433f5..c56e41d5c2 100644 --- a/lib/widgets/action_sheet.dart +++ b/lib/widgets/action_sheet.dart @@ -1409,7 +1409,7 @@ class QuoteAndReplyButton extends MessageActionSheetMenuItemButton { composeBoxController!; if ( composeBoxController is StreamComposeBoxController - && composeBoxController.topic.textNormalized == kNoTopicTopic + && composeBoxController.topic.isTopicVacuous && message is StreamMessage ) { composeBoxController.topic.setTopic(message.topic); diff --git a/test/model/autocomplete_checks.dart b/test/model/autocomplete_checks.dart index cb08378e77..65e3aaf755 100644 --- a/test/model/autocomplete_checks.dart +++ b/test/model/autocomplete_checks.dart @@ -10,6 +10,7 @@ extension ComposeContentControllerChecks on Subject { extension ComposeTopicControllerChecks on Subject { Subject?> get autocompleteIntent => has((c) => c.autocompleteIntent(), 'autocompleteIntent'); + Subject get textNormalized => has((c) => c.textNormalized, 'textNormalized'); } extension AutocompleteIntentChecks on Subject> { diff --git a/test/widgets/action_sheet_test.dart b/test/widgets/action_sheet_test.dart index 621f759f28..c43c6daab7 100644 --- a/test/widgets/action_sheet_test.dart +++ b/test/widgets/action_sheet_test.dart @@ -41,6 +41,7 @@ import '../api/fake_api.dart'; import '../api/model/model_checks.dart'; import '../example_data.dart' as eg; import '../flutter_checks.dart'; +import '../model/autocomplete_checks.dart'; import '../model/binding.dart'; import '../model/content_test.dart'; import '../model/test_store.dart'; @@ -1674,8 +1675,33 @@ void main() { check(contentController).not((it) => it.validationErrors.contains(ContentValidationError.quoteAndReplyInProgress)); } - testWidgets('in channel narrow', (tester) async { - final message = eg.streamMessage(); + testWidgets('in channel narrow with different, non-vacuous topic', (tester) async { + final message = eg.streamMessage(topic: 'some topic'); + await setupToMessageActionSheet(tester, message: message, narrow: ChannelNarrow(message.streamId)); + + final composeBoxController = findComposeBoxController(tester) as StreamComposeBoxController; + final contentController = composeBoxController.content; + + // Ensure channel-topics are loaded before testing quote & reply behavior + connection.prepare(body: + jsonEncode(GetStreamTopicsResult(topics: [eg.getStreamTopicsEntry()]).toJson())); + final topicController = composeBoxController.topic; + topicController.value = TextEditingValue(text: 'other topic'); + + final valueBefore = contentController.value; + prepareRawContentResponseSuccess(message: message, rawContent: 'Hello world'); + await tapQuoteAndReplyButton(tester); + checkLoadingState(store, contentController, valueBefore: valueBefore, message: message); + await tester.pump(Duration.zero); // message is fetched; compose box updates + check(composeBoxController.contentFocusNode.hasFocus).isTrue(); + checkSuccessState(store, contentController, + valueBefore: valueBefore, message: message, rawContent: 'Hello world'); + check(topicController).textNormalized.equals('other topic'); + }); + + testWidgets('in channel narrow with empty topic', (tester) async { + // Regression test for https://github.com/zulip/zulip-flutter/issues/1469 + final message = eg.streamMessage(topic: 'some topic'); await setupToMessageActionSheet(tester, message: message, narrow: ChannelNarrow(message.streamId)); final composeBoxController = findComposeBoxController(tester) as StreamComposeBoxController; @@ -1685,7 +1711,7 @@ void main() { connection.prepare(body: jsonEncode(GetStreamTopicsResult(topics: [eg.getStreamTopicsEntry()]).toJson())); final topicController = composeBoxController.topic; - topicController.value = const TextEditingValue(text: kNoTopicTopic); + topicController.value = const TextEditingValue(text: ''); final valueBefore = contentController.value; prepareRawContentResponseSuccess(message: message, rawContent: 'Hello world'); @@ -1695,6 +1721,7 @@ void main() { check(composeBoxController.contentFocusNode.hasFocus).isTrue(); checkSuccessState(store, contentController, valueBefore: valueBefore, message: message, rawContent: 'Hello world'); + check(topicController).textNormalized.equals('some topic'); }); group('in topic narrow', () {