import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:ikar/backend/api.dart'; import 'package:ikar/backend/modules/account/sessions_module.dart'; import 'package:ikar/core/protocol/opcode_map.dart'; import 'package:ikar/core/protocol/packet.dart'; import 'package:shared_preferences/shared_preferences.dart'; class _FakeApi extends Api { _FakeApi(this.response); final Packet response; int? requestedOpcode; Map? requestedPayload; @override SessionState get state => SessionState.online; @override Future sendRequest( int opcode, Map payload, { void Function()? beforeSend, bool silent = false, }) async { beforeSend?.call(); requestedOpcode = opcode; requestedPayload = payload; return response; } } void main() { TestWidgetsFlutterBinding.ensureInitialized(); const secureStorageChannel = MethodChannel( 'plugins.it_nomads.com/flutter_secure_storage', ); final secureWrites = []; setUp(() { SharedPreferences.setMockInitialValues({'active_account_id': '42'}); secureWrites.clear(); TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMethodCallHandler(secureStorageChannel, (call) async { if (call.method == 'write') secureWrites.add(call); return null; }); }); tearDown(() { TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMethodCallHandler(secureStorageChannel, null); }); test('terminateOtherSessions persists the rotated session token', () async { final api = _FakeApi( Packet( cmd: CmdType.ok, opcode: Opcode.sessionsClose, payload: {'token': 'rotated-token'}, ), ); await SessionsModule(api).terminateOtherSessions(); expect(api.requestedOpcode, Opcode.sessionsClose); expect(api.requestedPayload, isEmpty); expect(secureWrites, hasLength(1)); expect(secureWrites.single.method, 'write'); final arguments = secureWrites.single.arguments as Map; expect(arguments['key'], 'auth_token_42'); expect(arguments['value'], 'rotated-token'); }); test( 'terminateOtherSessions accepts a response without token rotation', () async { final api = _FakeApi( Packet( cmd: CmdType.ok, opcode: Opcode.sessionsClose, payload: {}, ), ); await SessionsModule(api).terminateOtherSessions(); expect(secureWrites, isEmpty); }, ); test( 'terminateOtherSessions rejects rotation without active account', () async { SharedPreferences.setMockInitialValues({}); final api = _FakeApi( Packet( cmd: CmdType.ok, opcode: Opcode.sessionsClose, payload: {'token': 'rotated-token'}, ), ); await expectLater( SessionsModule(api).terminateOtherSessions(), throwsA(isA()), ); expect(secureWrites, isEmpty); }, ); }