@@ -226,6 +226,142 @@ void main() {
226
226
await localStorage.persistSession ('session3' );
227
227
expect (await localStorage.accessToken (), 'session3' );
228
228
});
229
+
230
+ test ('handles concurrent access properly' , () async {
231
+ final localStorage = SharedPreferencesLocalStorage (
232
+ persistSessionKey: 'test_concurrent' ,
233
+ );
234
+ await localStorage.initialize ();
235
+
236
+ // Simulate concurrent operations
237
+ final futures = < Future > [];
238
+ for (int i = 0 ; i < 10 ; i++ ) {
239
+ futures.add (localStorage.persistSession ('session$i ' ));
240
+ }
241
+ await Future .wait (futures);
242
+
243
+ // One of the sessions should be persisted
244
+ expect (await localStorage.hasAccessToken (), true );
245
+ final token = await localStorage.accessToken ();
246
+ expect (token, isNotNull);
247
+ expect (token, startsWith ('session' ));
248
+ });
249
+
250
+ test ('handles reinitialization attempt gracefully' , () async {
251
+ final localStorage = SharedPreferencesLocalStorage (
252
+ persistSessionKey: 'test_multi_init' ,
253
+ );
254
+
255
+ // First initialization
256
+ await localStorage.initialize ();
257
+
258
+ // Storage should work normally after first init
259
+ await localStorage.persistSession ('test-session' );
260
+ expect (await localStorage.hasAccessToken (), true );
261
+ expect (await localStorage.accessToken (), 'test-session' );
262
+ });
263
+
264
+ test ('handles very long session strings' , () async {
265
+ final localStorage = SharedPreferencesLocalStorage (
266
+ persistSessionKey: 'test_long_session' ,
267
+ );
268
+ await localStorage.initialize ();
269
+
270
+ // Create a very long session string (simulating large JWT)
271
+ final longSession = 'session${'x' * 10000 }' ;
272
+ await localStorage.persistSession (longSession);
273
+ expect (await localStorage.hasAccessToken (), true );
274
+ expect (await localStorage.accessToken (), longSession);
275
+ });
276
+
277
+ test ('custom persistSessionKey works correctly' , () async {
278
+ const customKey = 'my.custom.session.key' ;
279
+ final localStorage = SharedPreferencesLocalStorage (
280
+ persistSessionKey: customKey,
281
+ );
282
+ await localStorage.initialize ();
283
+
284
+ await localStorage.persistSession ('custom-session' );
285
+ expect (await localStorage.hasAccessToken (), true );
286
+ expect (await localStorage.accessToken (), 'custom-session' );
287
+
288
+ // Verify it's stored under the custom key
289
+ final prefs = await SharedPreferences .getInstance ();
290
+ expect (prefs.getString (customKey), 'custom-session' );
291
+ });
292
+ });
293
+
294
+ // Test SharedPreferencesGotrueAsyncStorage additional scenarios
295
+ group ('SharedPreferencesGotrueAsyncStorage additional tests' , () {
296
+ late SharedPreferencesGotrueAsyncStorage asyncStorage;
297
+
298
+ setUp (() async {
299
+ SharedPreferences .setMockInitialValues ({});
300
+ asyncStorage = SharedPreferencesGotrueAsyncStorage ();
301
+ await Future .delayed (const Duration (milliseconds: 100 ));
302
+ });
303
+
304
+ test ('handles concurrent access to same key' , () async {
305
+ const testKey = 'concurrent_key' ;
306
+
307
+ // Simulate concurrent operations
308
+ final futures = < Future > [];
309
+ for (int i = 0 ; i < 10 ; i++ ) {
310
+ futures.add (asyncStorage.setItem (key: testKey, value: 'value$i ' ));
311
+ }
312
+ await Future .wait (futures);
313
+
314
+ // One value should be persisted
315
+ final result = await asyncStorage.getItem (key: testKey);
316
+ expect (result, isNotNull);
317
+ expect (result, startsWith ('value' ));
318
+ });
319
+
320
+ test ('handles keys with special characters' , () async {
321
+ const specialKey = 'test.key:with/special@characters' ;
322
+ const testValue = 'special-value' ;
323
+
324
+ await asyncStorage.setItem (key: specialKey, value: testValue);
325
+ final result = await asyncStorage.getItem (key: specialKey);
326
+ expect (result, testValue);
327
+
328
+ await asyncStorage.removeItem (key: specialKey);
329
+ final removedResult = await asyncStorage.getItem (key: specialKey);
330
+ expect (removedResult, null );
331
+ });
332
+
333
+ test ('handles empty string values' , () async {
334
+ const testKey = 'empty_value_key' ;
335
+
336
+ await asyncStorage.setItem (key: testKey, value: '' );
337
+ final result = await asyncStorage.getItem (key: testKey);
338
+ expect (result, '' );
339
+ });
340
+
341
+ test ('handles multiple different keys' , () async {
342
+ final keyValuePairs = < String , String > {
343
+ 'key1' : 'value1' ,
344
+ 'key2' : 'value2' ,
345
+ 'key3' : 'value3' ,
346
+ };
347
+
348
+ // Set multiple values
349
+ for (final entry in keyValuePairs.entries) {
350
+ await asyncStorage.setItem (key: entry.key, value: entry.value);
351
+ }
352
+
353
+ // Verify all values
354
+ for (final entry in keyValuePairs.entries) {
355
+ final result = await asyncStorage.getItem (key: entry.key);
356
+ expect (result, entry.value);
357
+ }
358
+
359
+ // Remove one key and verify others remain
360
+ await asyncStorage.removeItem (key: 'key2' );
361
+ expect (await asyncStorage.getItem (key: 'key1' ), 'value1' );
362
+ expect (await asyncStorage.getItem (key: 'key2' ), null );
363
+ expect (await asyncStorage.getItem (key: 'key3' ), 'value3' );
364
+ });
229
365
});
230
366
});
231
367
}
0 commit comments