@@ -6,6 +6,30 @@ import 'package:test/test.dart';
66
77import '../../test_utils.dart' ;
88
9+ /// Mock connectivity provider for testing different connectivity states
10+ class MockConnectivityProvider implements ParseConnectivityProvider {
11+ final StreamController <ParseConnectivityResult > _controller =
12+ StreamController <ParseConnectivityResult >.broadcast ();
13+ ParseConnectivityResult _currentState = ParseConnectivityResult .wifi;
14+
15+ @override
16+ Future <ParseConnectivityResult > checkConnectivity () async {
17+ return _currentState;
18+ }
19+
20+ @override
21+ Stream <ParseConnectivityResult > get connectivityStream => _controller.stream;
22+
23+ void setConnectivity (ParseConnectivityResult state) {
24+ _currentState = state;
25+ _controller.add (state);
26+ }
27+
28+ void dispose () {
29+ _controller.close ();
30+ }
31+ }
32+
933void main () {
1034 setUpAll (() async {
1135 // Create a fake server
@@ -62,4 +86,124 @@ void main() {
6286 // 10 millisecond hold for stream
6387 await Future .delayed (Duration (milliseconds: 10 ));
6488 });
89+
90+ group ('Connectivity handling' , () {
91+ late MockConnectivityProvider mockConnectivity;
92+
93+ // Initialize once with mock provider, then test state changes
94+ setUpAll (() async {
95+ mockConnectivity = MockConnectivityProvider ();
96+ // Initialize Parse once with the mock provider
97+ await Parse ().initialize (
98+ 'appId' ,
99+ serverUrl,
100+ debug: false ,
101+ fileDirectory: 'someDirectory' ,
102+ appName: 'appName' ,
103+ appPackageName: 'somePackageName' ,
104+ appVersion: 'someAppVersion' ,
105+ connectivityProvider: mockConnectivity,
106+ );
107+ });
108+
109+ tearDownAll (() {
110+ mockConnectivity.dispose ();
111+ });
112+
113+ // Test data for parameterized connectivity state tests
114+ final connectivityTestCases = < Map <String , dynamic >> [
115+ {
116+ 'state' : ParseConnectivityResult .wifi,
117+ 'isOnline' : true ,
118+ 'description' : 'wifi should be treated as online' ,
119+ },
120+ {
121+ 'state' : ParseConnectivityResult .ethernet,
122+ 'isOnline' : true ,
123+ 'description' : 'ethernet should be treated as online' ,
124+ },
125+ {
126+ 'state' : ParseConnectivityResult .mobile,
127+ 'isOnline' : true ,
128+ 'description' : 'mobile should be treated as online' ,
129+ },
130+ {
131+ 'state' : ParseConnectivityResult .none,
132+ 'isOnline' : false ,
133+ 'description' : 'none should be treated as offline' ,
134+ },
135+ ];
136+
137+ for (final testCase in connectivityTestCases) {
138+ test (testCase['description' ], () async {
139+ // arrange
140+ final state = testCase['state' ] as ParseConnectivityResult ;
141+ final isOnline = testCase['isOnline' ] as bool ;
142+
143+ // act
144+ mockConnectivity.setConnectivity (state);
145+ final result = await mockConnectivity.checkConnectivity ();
146+
147+ // assert - verify the state is correctly identified
148+ expect (result, state);
149+ expect (result != ParseConnectivityResult .none, isOnline);
150+ });
151+ }
152+
153+ test ('should emit connectivity state transitions through stream' , () async {
154+ // arrange
155+ final emittedStates = < ParseConnectivityResult > [];
156+ final subscription = mockConnectivity.connectivityStream.listen ((state) {
157+ emittedStates.add (state);
158+ });
159+
160+ // act - transition through different connectivity states
161+ mockConnectivity.setConnectivity (ParseConnectivityResult .wifi);
162+ await Future .delayed (Duration (milliseconds: 10 ));
163+ mockConnectivity.setConnectivity (ParseConnectivityResult .ethernet);
164+ await Future .delayed (Duration (milliseconds: 10 ));
165+ mockConnectivity.setConnectivity (ParseConnectivityResult .mobile);
166+ await Future .delayed (Duration (milliseconds: 10 ));
167+ mockConnectivity.setConnectivity (ParseConnectivityResult .none);
168+ await Future .delayed (Duration (milliseconds: 10 ));
169+
170+ // assert - all state changes should be emitted
171+ expect (emittedStates.length, 4 );
172+ expect (emittedStates[0 ], ParseConnectivityResult .wifi);
173+ expect (emittedStates[1 ], ParseConnectivityResult .ethernet);
174+ expect (emittedStates[2 ], ParseConnectivityResult .mobile);
175+ expect (emittedStates[3 ], ParseConnectivityResult .none);
176+
177+ // verify online states (wifi, ethernet, mobile) are not "none"
178+ expect (emittedStates[0 ], isNot (ParseConnectivityResult .none));
179+ expect (emittedStates[1 ], isNot (ParseConnectivityResult .none));
180+ expect (emittedStates[2 ], isNot (ParseConnectivityResult .none));
181+
182+ await subscription.cancel ();
183+ });
184+
185+ test ('should transition from offline to online correctly' , () async {
186+ // arrange
187+ final stateChanges = < ParseConnectivityResult > [];
188+ final subscription = mockConnectivity.connectivityStream.listen ((state) {
189+ stateChanges.add (state);
190+ });
191+
192+ // act - start offline, then go online via ethernet
193+ mockConnectivity.setConnectivity (ParseConnectivityResult .none);
194+ await Future .delayed (Duration (milliseconds: 10 ));
195+ mockConnectivity.setConnectivity (ParseConnectivityResult .ethernet);
196+ await Future .delayed (Duration (milliseconds: 10 ));
197+
198+ // assert
199+ expect (stateChanges.length, 2 );
200+ expect (stateChanges[0 ], ParseConnectivityResult .none);
201+ expect (stateChanges[1 ], ParseConnectivityResult .ethernet);
202+ // Verify the transition is from offline to online
203+ expect (stateChanges[0 ] == ParseConnectivityResult .none, true );
204+ expect (stateChanges[1 ] != ParseConnectivityResult .none, true );
205+
206+ await subscription.cancel ();
207+ });
208+ });
65209}
0 commit comments