@@ -3,6 +3,7 @@ import 'dart:convert';
3
3
import 'dart:io' ;
4
4
5
5
import 'package:checks/checks.dart' ;
6
+ import 'package:collection/collection.dart' ;
6
7
import 'package:crypto/crypto.dart' ;
7
8
import 'package:file_picker/file_picker.dart' ;
8
9
import 'package:flutter_checks/flutter_checks.dart' ;
@@ -56,14 +57,23 @@ void main() {
56
57
User ? selfUser,
57
58
List <User > otherUsers = const [],
58
59
List <ZulipStream > streams = const [],
60
+ List <Message >? messages,
59
61
bool ? mandatoryTopics,
60
62
int ? zulipFeatureLevel,
61
63
}) async {
62
64
if (narrow case ChannelNarrow (: var streamId) || TopicNarrow (: var streamId)) {
63
- assert (streams.any ((stream) => stream.streamId == streamId),
65
+ final channel = streams.firstWhereOrNull ((s) => s.streamId == streamId);
66
+ assert (channel != null ,
64
67
'Add a channel with "streamId" the same as of $narrow .streamId to the store.' );
68
+ if (narrow is ChannelNarrow ) {
69
+ // By default, bypass the complexity where the topic input is autofocused
70
+ // on an empty fetch, by making the fetch not empty. (In particular that
71
+ // complexity includes a getStreamTopics fetch for topic autocomplete.)
72
+ messages ?? = [eg.streamMessage (stream: channel)];
73
+ }
65
74
}
66
75
addTearDown (testBinding.reset);
76
+ messages ?? = [];
67
77
selfUser ?? = eg.selfUser;
68
78
zulipFeatureLevel ?? = eg.futureZulipFeatureLevel;
69
79
final selfAccount = eg.account (user: selfUser, zulipFeatureLevel: zulipFeatureLevel);
@@ -81,7 +91,11 @@ void main() {
81
91
connection = store.connection as FakeApiConnection ;
82
92
83
93
connection.prepare (json:
84
- eg.newestGetMessagesResult (foundOldest: true , messages: []).toJson ());
94
+ eg.newestGetMessagesResult (foundOldest: true , messages: messages).toJson ());
95
+ if (narrow is ChannelNarrow && messages.isEmpty) {
96
+ // The topic input will autofocus, triggering a getStreamTopics request.
97
+ connection.prepare (json: GetStreamTopicsResult (topics: []).toJson ());
98
+ }
85
99
await tester.pumpWidget (TestZulipApp (accountId: selfAccount.id,
86
100
child: MessageListPage (initNarrow: narrow)));
87
101
await tester.pumpAndSettle ();
@@ -134,6 +148,64 @@ void main() {
134
148
await tester.pump (Duration .zero);
135
149
}
136
150
151
+ group ('auto focus' , () {
152
+ testWidgets ('ChannelNarrow, non-empty fetch' , (tester) async {
153
+ final channel = eg.stream ();
154
+ await prepareComposeBox (tester,
155
+ narrow: ChannelNarrow (channel.streamId),
156
+ streams: [channel],
157
+ messages: [eg.streamMessage (stream: channel)]);
158
+ check (controller).isA <StreamComposeBoxController >()
159
+ ..topicFocusNode.hasFocus.isFalse ()
160
+ ..contentFocusNode.hasFocus.isFalse ();
161
+ });
162
+
163
+ testWidgets ('ChannelNarrow, empty fetch' , (tester) async {
164
+ final channel = eg.stream ();
165
+ await prepareComposeBox (tester,
166
+ narrow: ChannelNarrow (channel.streamId),
167
+ streams: [channel],
168
+ messages: []);
169
+ check (controller).isA <StreamComposeBoxController >()
170
+ .topicFocusNode.hasFocus.isTrue ();
171
+ });
172
+
173
+ testWidgets ('TopicNarrow, non-empty fetch' , (tester) async {
174
+ final channel = eg.stream ();
175
+ await prepareComposeBox (tester,
176
+ narrow: TopicNarrow (channel.streamId, eg.t ('topic' )),
177
+ streams: [channel],
178
+ messages: [eg.streamMessage (stream: channel, topic: 'topic' )]);
179
+ check (controller).isNotNull ().contentFocusNode.hasFocus.isFalse ();
180
+ });
181
+
182
+ testWidgets ('TopicNarrow, empty fetch' , (tester) async {
183
+ final channel = eg.stream ();
184
+ await prepareComposeBox (tester,
185
+ narrow: TopicNarrow (channel.streamId, eg.t ('topic' )),
186
+ streams: [channel],
187
+ messages: []);
188
+ check (controller).isNotNull ().contentFocusNode.hasFocus.isTrue ();
189
+ });
190
+
191
+ testWidgets ('DmNarrow, non-empty fetch' , (tester) async {
192
+ final user = eg.user ();
193
+ await prepareComposeBox (tester,
194
+ selfUser: eg.selfUser,
195
+ narrow: DmNarrow .withUser (user.userId, selfUserId: eg.selfUser.userId),
196
+ messages: [eg.dmMessage (from: user, to: [eg.selfUser])]);
197
+ check (controller).isNotNull ().contentFocusNode.hasFocus.isFalse ();
198
+ });
199
+
200
+ testWidgets ('DmNarrow, empty fetch' , (tester) async {
201
+ await prepareComposeBox (tester,
202
+ selfUser: eg.selfUser,
203
+ narrow: DmNarrow .withUser (eg.user ().userId, selfUserId: eg.selfUser.userId),
204
+ messages: []);
205
+ check (controller).isNotNull ().contentFocusNode.hasFocus.isTrue ();
206
+ });
207
+ });
208
+
137
209
group ('ComposeBoxTheme' , () {
138
210
test ('lerp light to dark, no crash' , () {
139
211
final a = ComposeBoxTheme .light;
0 commit comments