@@ -226,6 +226,142 @@ void main() {
226226 await localStorage.persistSession ('session3' );
227227 expect (await localStorage.accessToken (), 'session3' );
228228 });
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+ });
229365 });
230366 });
231367}
0 commit comments