import 'package:dio/dio.dart'; import 'package:eatvio_app/core/app_config.dart'; import 'package:eatvio_app/core/app_initializer.dart'; import 'package:eatvio_app/core/cached_base_url.dart'; import 'package:eatvio_app/core/env_config.dart'; import 'package:eatvio_app/core/locator_service.dart'; import 'package:eatvio_app/core/prefs.dart'; import 'package:eatvio_app/core/prefs_keys.dart'; import 'package:eatvio_app/features/video_calls/presentation/bloc/video_call_session/video_call_session_cubit.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; import 'package:shared_preferences/shared_preferences.dart'; class _MockVideoCallSessionCubit extends Mock implements VideoCallSessionCubit {} void main() { setUpAll(() async { // Initialize dotenv for tests dotenv.loadFromString( envString: 'DEV_BASE_URL=http://localhost\nBASE_URL=http://localhost', ); }); setUp(() async { await sl.reset(); sl.registerLazySingleton( _MockVideoCallSessionCubit.new, ); }); tearDown(() async { await sl.reset(); }); group('AppConfig', () { test('creates config with prod build type', () { final config = AppConfig(buildType: AppBuildType.prod); expect(config.buildType, AppBuildType.prod); expect(config.baseUrl, EnvConfig.baseUrl); }); test('creates config with dev build type', () { final config = AppConfig(buildType: AppBuildType.dev); expect(config.buildType, AppBuildType.dev); expect(config.baseUrl, EnvConfig.devBaseUrl); }); test('creates config with tests build type', () { final config = AppConfig(buildType: AppBuildType.tests); expect(config.buildType, AppBuildType.tests); expect(config.baseUrl, EnvConfig.devBaseUrl); }); test('setBaseUrl updates baseUrl', () { final config = AppConfig(buildType: AppBuildType.prod); const newUrl = 'https://new-url.com'; config.setBaseUrl(newUrl); expect(config.baseUrl, newUrl); }); test('globalBlocProviders returns list of BlocProvider', () { final config = AppConfig(buildType: AppBuildType.prod); expect(config.globalBlocProviders, isA()); expect(config.globalBlocProviders.isNotEmpty, true); }); test('localizationDelegates returns list of LocalizationsDelegate', () { final config = AppConfig(buildType: AppBuildType.prod); expect(config.localizationDelegates, isA()); expect(config.localizationDelegates.isNotEmpty, true); }); test('supportedLocales returns list of Locale', () { final config = AppConfig(buildType: AppBuildType.prod); expect(config.supportedLocales, isA()); expect(config.supportedLocales.isNotEmpty, true); }); test('baseUrl is initialized correctly for each build type', () { final prodConfig = AppConfig(buildType: AppBuildType.prod); final devConfig = AppConfig(buildType: AppBuildType.dev); final testConfig = AppConfig(buildType: AppBuildType.tests); expect(prodConfig.baseUrl, isA()); expect(devConfig.baseUrl, isA()); expect(testConfig.baseUrl, isA()); expect(devConfig.baseUrl, testConfig.baseUrl); }); test('setBaseUrl saves override to prefs', () async { SharedPreferences.setMockInitialValues({}); final prefs = Prefs(await SharedPreferences.getInstance()); sl.registerSingleton(prefs); final config = AppConfig(buildType: AppBuildType.prod); config.setBaseUrl('https://custom.example'); await Future.delayed(Duration.zero); expect( prefs.getString(PrefsKeys.customBaseUrl), 'https://custom.example', ); expect(prefs.getString(PrefsKeys.apiBaseUrl), 'https://custom.example'); }); test('setBaseUrl removes cached override when url is blank', () async { SharedPreferences.setMockInitialValues({ 'customBaseUrl': 'https://custom.example', }); final prefs = Prefs(await SharedPreferences.getInstance()); sl.registerSingleton(prefs); final config = AppConfig(buildType: AppBuildType.prod); config.setBaseUrl(' '); await Future.delayed(Duration.zero); expect(prefs.getString(PrefsKeys.customBaseUrl), isNull); expect(config.baseUrl, ' '); }); test( 'applyCachedBaseUrl replaces env base url before dio is created', () async { SharedPreferences.setMockInitialValues({ 'customBaseUrl': 'https://cached.example', }); sl.registerLazySingleton( () => AppConfig(buildType: AppBuildType.prod), ); sl.registerSingleton( Prefs(await SharedPreferences.getInstance()), ); sl.registerLazySingleton( () => Dio(BaseOptions(baseUrl: sl().baseUrl)), ); applyCachedBaseUrl(); await Future.delayed(Duration.zero); expect(sl().baseUrl, 'https://cached.example'); expect(sl().options.baseUrl, 'https://cached.example'); expect( sl().getString(PrefsKeys.apiBaseUrl), 'https://cached.example', ); }, ); test('applyCachedBaseUrl keeps env base url when cache is empty', () async { SharedPreferences.setMockInitialValues({}); sl.registerLazySingleton( () => AppConfig(buildType: AppBuildType.prod), ); sl.registerSingleton(Prefs(await SharedPreferences.getInstance())); sl.registerLazySingleton( () => Dio(BaseOptions(baseUrl: sl().baseUrl)), ); applyCachedBaseUrl(); await Future.delayed(Duration.zero); expect(sl().baseUrl, EnvConfig.baseUrl); expect(sl().options.baseUrl, EnvConfig.baseUrl); expect(sl().getString(PrefsKeys.apiBaseUrl), EnvConfig.baseUrl); }); test('setBaseUrl can be called multiple times', () { final config = AppConfig(buildType: AppBuildType.prod); const url1 = 'https://url1.com'; const url2 = 'https://url2.com'; config.setBaseUrl(url1); expect(config.baseUrl, url1); config.setBaseUrl(url2); expect(config.baseUrl, url2); }); test('globalBlocProviders contains expected providers', () { final config = AppConfig(buildType: AppBuildType.prod); final providers = config.globalBlocProviders; expect(providers.length, greaterThan(0)); // Проверяем, что список содержит элементы expect(providers.first, isA()); }); }); }