feat: 实现起卦、设置与积分系统
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:meeyao_qianwen/core/auth/session_store.dart';
|
||||
import 'package:meeyao_qianwen/data/network/api_client.dart';
|
||||
import 'package:meeyao_qianwen/data/storage/local_kv_store.dart';
|
||||
import 'package:meeyao_qianwen/features/auth/data/apis/auth_api.dart';
|
||||
import 'package:meeyao_qianwen/features/auth/data/repositories/auth_repository.dart';
|
||||
|
||||
class _FakeSessionStore extends SessionStore {
|
||||
_FakeSessionStore({this.refreshToken, this.throwOnGetRefreshToken = false})
|
||||
: super(LocalKvStore());
|
||||
|
||||
String? refreshToken;
|
||||
bool throwOnGetRefreshToken;
|
||||
|
||||
bool clearTokenCalled = false;
|
||||
bool clearRefreshTokenCalled = false;
|
||||
bool clearEmailCalled = false;
|
||||
|
||||
@override
|
||||
Future<String?> getRefreshToken() async {
|
||||
if (throwOnGetRefreshToken) {
|
||||
throw Exception('read refresh token failed');
|
||||
}
|
||||
return refreshToken;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> clearToken() async {
|
||||
clearTokenCalled = true;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> clearRefreshToken() async {
|
||||
clearRefreshTokenCalled = true;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> clearEmail() async {
|
||||
clearEmailCalled = true;
|
||||
}
|
||||
}
|
||||
|
||||
class _FakeAuthApi extends AuthApi {
|
||||
_FakeAuthApi()
|
||||
: super(apiClient: ApiClient(baseUrl: 'http://127.0.0.1:5775'));
|
||||
|
||||
bool deleteSessionCalled = false;
|
||||
bool throwOnDeleteSession = false;
|
||||
|
||||
@override
|
||||
Future<void> deleteSession({required String refreshToken}) async {
|
||||
deleteSessionCalled = true;
|
||||
if (throwOnDeleteSession) {
|
||||
throw Exception('delete session failed');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
test(
|
||||
'logout should clear local session when getRefreshToken throws',
|
||||
() async {
|
||||
final authApi = _FakeAuthApi();
|
||||
final sessionStore = _FakeSessionStore(throwOnGetRefreshToken: true);
|
||||
final repository = AuthRepositoryImpl(
|
||||
authApi: authApi,
|
||||
sessionStore: sessionStore,
|
||||
);
|
||||
|
||||
await expectLater(repository.logout(), throwsA(isA<Exception>()));
|
||||
|
||||
expect(authApi.deleteSessionCalled, isFalse);
|
||||
expect(sessionStore.clearTokenCalled, isTrue);
|
||||
expect(sessionStore.clearRefreshTokenCalled, isTrue);
|
||||
expect(sessionStore.clearEmailCalled, isTrue);
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
'logout should skip deleteSession when refresh token is empty',
|
||||
() async {
|
||||
final authApi = _FakeAuthApi();
|
||||
final sessionStore = _FakeSessionStore(refreshToken: '');
|
||||
final repository = AuthRepositoryImpl(
|
||||
authApi: authApi,
|
||||
sessionStore: sessionStore,
|
||||
);
|
||||
|
||||
await repository.logout();
|
||||
|
||||
expect(authApi.deleteSessionCalled, isFalse);
|
||||
expect(sessionStore.clearTokenCalled, isTrue);
|
||||
expect(sessionStore.clearRefreshTokenCalled, isTrue);
|
||||
expect(sessionStore.clearEmailCalled, isTrue);
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
'logout should still clear local session when deleteSession throws',
|
||||
() async {
|
||||
final authApi = _FakeAuthApi()..throwOnDeleteSession = true;
|
||||
final sessionStore = _FakeSessionStore(refreshToken: 'r1');
|
||||
final repository = AuthRepositoryImpl(
|
||||
authApi: authApi,
|
||||
sessionStore: sessionStore,
|
||||
);
|
||||
|
||||
await expectLater(repository.logout(), throwsA(isA<Exception>()));
|
||||
|
||||
expect(authApi.deleteSessionCalled, isTrue);
|
||||
expect(sessionStore.clearTokenCalled, isTrue);
|
||||
expect(sessionStore.clearRefreshTokenCalled, isTrue);
|
||||
expect(sessionStore.clearEmailCalled, isTrue);
|
||||
},
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user