Skip to content

Commit

Permalink
adjust gotrue tests
Browse files Browse the repository at this point in the history
  • Loading branch information
dshukertjr committed Apr 2, 2024
1 parent 4d7cf9c commit 0d3c00e
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 40 deletions.
47 changes: 28 additions & 19 deletions packages/gotrue/lib/src/gotrue_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -924,28 +924,37 @@ class GoTrueClient {

/// Recover session from stringified [Session].
Future<AuthResponse> recoverSession(String jsonStr) async {
final session = Session.fromJson(json.decode(jsonStr));
if (session == null) {
await signOut();
throw notifyException(AuthException('Current session is missing data.'));
}

if (session.isExpired) {
final refreshToken = session.refreshToken;
if (_autoRefreshToken && refreshToken != null) {
return await _callRefreshToken(refreshToken);
} else {
try {
final session = Session.fromJson(json.decode(jsonStr));
if (session == null) {
await signOut();
throw notifyException(AuthException('Session expired.'));
throw notifyException(
AuthException('Current session is missing data.'),
);
}
} else {
final shouldEmitEvent = _currentSession == null ||
_currentSession?.user.id != session.user.id;
_saveSession(session);

if (shouldEmitEvent) notifyAllSubscribers(AuthChangeEvent.tokenRefreshed);
if (session.isExpired) {
final refreshToken = session.refreshToken;
if (_autoRefreshToken && refreshToken != null) {
return await _callRefreshToken(refreshToken);
} else {
await signOut();
throw notifyException(AuthException('Session expired.'));
}
} else {
final shouldEmitEvent = _currentSession == null ||
_currentSession?.user.id != session.user.id;
_saveSession(session);

return AuthResponse(session: session);
if (shouldEmitEvent) {
notifyAllSubscribers(AuthChangeEvent.tokenRefreshed);
}

return AuthResponse(session: session);
}
} catch (error) {
notifyException(error);
rethrow;
}
}

Expand Down Expand Up @@ -1164,7 +1173,7 @@ class GoTrueClient {

/// For internal use only.
@internal
Exception notifyException(Exception exception, [StackTrace? stackTrace]) {
Object notifyException(Object exception, [StackTrace? stackTrace]) {
_onAuthStateChangeController.addError(
exception,
stackTrace ?? StackTrace.current,
Expand Down
27 changes: 10 additions & 17 deletions packages/gotrue/test/client_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -373,26 +373,19 @@ void main() {
final session =
'{"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2ODAzNDE3MDUsInN1YiI6IjRkMjU4M2RhLThkZTQtNDlkMy05Y2QxLTM3YTlhNzRmNTViZCIsImVtYWlsIjoiZmFrZTE2ODAzMzgxMDVAZW1haWwuY29tIiwicGhvbmUiOiIiLCJhcHBfbWV0YWRhdGEiOnsicHJvdmlkZXIiOiJlbWFpbCIsInByb3ZpZGVycyI6WyJlbWFpbCJdfSwidXNlcl9tZXRhZGF0YSI6eyJIZWxsbyI6IldvcmxkIn0sInJvbGUiOiIiLCJhYWwiOiJhYWwxIiwiYW1yIjpbeyJtZXRob2QiOiJwYXNzd29yZCIsInRpbWVzdGFtcCI6MTY4MDMzODEwNX1dLCJzZXNzaW9uX2lkIjoiYzhiOTg2Y2UtZWJkZC00ZGUxLWI4MjAtZjIyOWYyNjg1OGIwIn0.0x1rFlPKbIU1rZPY1SH_FNSZaXerfkFA1Y-EOlhuzUs","expires_in":3600,"refresh_token":"-yeS4omysFs9tpUYBws9Rg","token_type":"bearer","provider_token":null,"provider_refresh_token":null,"user":{"id":"4d2583da-8de4-49d3-9cd1-37a9a74f55bd","app_metadata":{"provider":"email","providers":["email"]},"user_metadata":{"Hello":"World"},"aud":"","email":"[email protected]","phone":"","created_at":"2023-04-01T08:35:05.208586Z","confirmed_at":null,"email_confirmed_at":"2023-04-01T08:35:05.220096086Z","phone_confirmed_at":null,"last_sign_in_at":"2023-04-01T08:35:05.222755878Z","role":"","updated_at":"2023-04-01T08:35:05.226938Z"},"expiresAt":1680341705}';

///These 3 are bundled and in sum 4 refresh token requests are made, because the first 3 fail in [RetryTestHttpClient]
final future1 = Future.wait([
client.recoverSession(session),
///These 3 are bundled and in sum 1 refresh token requests is made, because the first 3 fail in [RetryTestHttpClient]
final responses = await Future.wait([
client.recoverSession(session),
client.recoverSession(session),
]);

await expectLater(future1, throwsA(isA<ClientException>()));
expect(httpClient.retryCount, 1);

/// Again these 3 are bundled and only one refresh token request is made
final future2 = Future.wait([
client.recoverSession(session),
client.recoverSession(session),
client.recoverSession(session),
]);
expect(responses[0].session?.accessToken, isNotNull);
expect(
responses[0].session?.accessToken,
responses[1].session?.accessToken,
);

await expectLater(future2, throwsA(isA<ClientException>()));
expect(client.onAuthStateChange, emits(isA<AuthState>()));
expect(httpClient.retryCount, 2);
expect(httpClient.retryCount, 4);
});

test('Sign out on wrong refresh token', () async {
Expand All @@ -410,10 +403,10 @@ void main() {
]),
);

final session =
final expiredSession =
getSessionData(DateTime.now().subtract(Duration(hours: 1)));

await expectLater(client.recoverSession(session.sessionString),
await expectLater(client.recoverSession(expiredSession.sessionString),
throwsA(isA<AuthException>()));
expect(stream, emitsError(isA<AuthException>()));

Expand Down
6 changes: 5 additions & 1 deletion packages/gotrue/test/custom_http_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,11 @@ class RetryTestHttpClient extends BaseClient {
throw ClientException('Retry #$retryCount');
}
final jwt = JWT(
{'exp': (DateTime.now().millisecondsSinceEpoch / 1000).round() + 60},
{
'exp': (DateTime.now().millisecondsSinceEpoch / 1000).round() + 60,
'retry_count':
retryCount, // Add retryCount so that tokens issued on different retries are different.
},
subject: userId1,
);

Expand Down
7 changes: 4 additions & 3 deletions packages/gotrue/test/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,14 @@ String getServiceRoleToken(DotEnv env) {
}

/// Construct session data for a given expiration date
({String accessToken, String sessionString}) getSessionData(DateTime dateTime) {
final expiresAt = dateTime.millisecondsSinceEpoch ~/ 1000;
({String accessToken, String sessionString}) getSessionData(
DateTime expireDateTime) {
final expiresAt = expireDateTime.millisecondsSinceEpoch ~/ 1000;
final accessTokenMid = base64.encode(utf8.encode(json.encode(
{'exp': expiresAt, 'sub': '1234567890', 'role': 'authenticated'})));
final accessToken = 'any.$accessTokenMid.any';
final sessionString =
'{"access_token":"$accessToken","expires_in":${dateTime.difference(DateTime.now()).inSeconds},"refresh_token":"-yeS4omysFs9tpUYBws9Rg","token_type":"bearer","provider_token":null,"provider_refresh_token":null,"user":{"id":"4d2583da-8de4-49d3-9cd1-37a9a74f55bd","app_metadata":{"provider":"email","providers":["email"]},"user_metadata":{"Hello":"World"},"aud":"","email":"[email protected]","phone":"","created_at":"2023-04-01T08:35:05.208586Z","confirmed_at":null,"email_confirmed_at":"2023-04-01T08:35:05.220096086Z","phone_confirmed_at":null,"last_sign_in_at":"2023-04-01T08:35:05.222755878Z","role":"","updated_at":"2023-04-01T08:35:05.226938Z"}}';
'{"access_token":"$accessToken","expires_in":${expireDateTime.difference(DateTime.now()).inSeconds},"refresh_token":"-yeS4omysFs9tpUYBws9Rg","token_type":"bearer","provider_token":null,"provider_refresh_token":null,"user":{"id":"4d2583da-8de4-49d3-9cd1-37a9a74f55bd","app_metadata":{"provider":"email","providers":["email"]},"user_metadata":{"Hello":"World"},"aud":"","email":"[email protected]","phone":"","created_at":"2023-04-01T08:35:05.208586Z","confirmed_at":null,"email_confirmed_at":"2023-04-01T08:35:05.220096086Z","phone_confirmed_at":null,"last_sign_in_at":"2023-04-01T08:35:05.222755878Z","role":"","updated_at":"2023-04-01T08:35:05.226938Z"}}';
return (accessToken: accessToken, sessionString: sessionString);
}

Expand Down

0 comments on commit 0d3c00e

Please sign in to comment.