Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow setting mock user to null #112

Merged
merged 6 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 25 additions & 18 deletions lib/src/firebase_auth_mocks_base.dart
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@ class MockFirebaseAuth implements FirebaseAuth {
}
} else {
// Notify of null on startup.
signOut();
_notifyCredential(null);
}
}

set mockUser(MockUser user) {
set mockUser(MockUser? user) {
_mockUser = user;
// Update _currentUser if already sign in
if (_currentUser != null) {
Expand Down Expand Up @@ -168,9 +168,7 @@ class MockFirebaseAuth implements FirebaseAuth {
maybeThrowException(this, Invocation.method(#signOut, [null]));

_currentUser = null;
stateChangedStreamController.add(null);
userChangedStreamController.add(null);
authForFakeFirestoreStreamController.add(null);
_notifyCredential(null);
}

@override
Expand All @@ -184,22 +182,31 @@ class MockFirebaseAuth implements FirebaseAuth {
Future<UserCredential> _fakeSignIn({bool isAnonymous = false}) async {
final userCredential = MockUserCredential(isAnonymous, mockUser: _mockUser);
_currentUser = userCredential.user;
stateChangedStreamController.add(_currentUser);
userChangedStreamController.add(_currentUser);
final u = userCredential.mockUser;
authForFakeFirestoreStreamController.add({
'uid': u.uid,
'token': {
'name': u.displayName,
'email': u.email,
'email_verified': u.emailVerified,
'firebase.sign_in_provider': u.getIdTokenResultSync().signInProvider,
...u.getIdTokenResultSync().claims ?? {}
}
});
_notifyCredential(userCredential);
return Future.value(userCredential);
}

void _notifyCredential(MockUserCredential? credential) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

final user = credential?.user;
stateChangedStreamController.add(user);
userChangedStreamController.add(user);

final mockUser = credential?.mockUser;
authForFakeFirestoreStreamController.add(mockUser == null
? null
: {
'uid': mockUser.uid,
'token': {
'name': mockUser.displayName,
'email': mockUser.email,
'email_verified': mockUser.emailVerified,
'firebase.sign_in_provider':
mockUser.getIdTokenResultSync().signInProvider,
...mockUser.getIdTokenResultSync().claims ?? {}
}
});
}

Future<UserCredential> _fakeSignUp({bool isAnonymous = false}) {
return _fakeSignIn(isAnonymous: isAnonymous);
}
Expand Down
47 changes: 39 additions & 8 deletions test/firebase_auth_mocks_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -239,15 +239,46 @@ void main() {
expect(idTokenResult.claims, {'weight': 70});
});

test('Returns null after sign out', () async {
final auth = MockFirebaseAuth(signedIn: true, mockUser: tUser);
final user = auth.currentUser;
group('Sign out', () {
test('Returns null after sign out', () async {
final auth = MockFirebaseAuth(signedIn: true, mockUser: tUser);
final user = auth.currentUser;

await auth.signOut();
await auth.signOut();

expect(auth.currentUser, isNull);
expect(auth.authStateChanges(), emitsInOrder([user, null]));
expect(auth.userChanges(), emitsInOrder([user, null]));
});

test('Can sign in again after sign out', () async {
final auth = MockFirebaseAuth(signedIn: true, mockUser: tUser);
final user = auth.currentUser;

await auth.signOut();

expect(auth.currentUser, isNull);
expect(auth.authStateChanges(), emitsInOrder([user, null]));
expect(auth.userChanges(), emitsInOrder([user, null]));
auth.mockUser = tUser;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since signing out does not set mockUser to null anymore, do you still need to set mockUser again if signing in with the same user? Maybe you can remove this line.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes, you're right - this should have been removed too. I'll clean that up

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, looks like you fixed it - I missed your other comment. Thanks!

await auth.signInWithProvider(AppleAuthProvider());

expect(auth.authStateChanges(),
emitsInOrder([user, null, auth.currentUser]));
expect(auth.userChanges(), emitsInOrder([user, null, auth.currentUser]));
});

test('Can sign in anonymously after sign out', () async {
final auth = MockFirebaseAuth(signedIn: true, mockUser: tUser);
final user = auth.currentUser;

await auth.signOut();

auth.mockUser = null;
await auth.signInAnonymously();

expect(auth.currentUser!.isAnonymous, isTrue);
expect(auth.authStateChanges(),
emitsInOrder([user, null, auth.currentUser]));
expect(auth.userChanges(), emitsInOrder([user, null, auth.currentUser]));
});
});

test('sendPasswordResetEmail works', () async {
Expand Down Expand Up @@ -774,7 +805,7 @@ void main() {
expect(decodedToken['bodyHeight'], 169);
});

test('The customClain should exist after sign-out and sign-in', () async {
test('The customClaim should exist after sign-out and sign-in', () async {
final auth = MockFirebaseAuth(
mockUser: MockUser(customClaim: {'role': 'admin', 'bodyHeight': 169}),
signedIn: true,
Expand Down
Loading