250 lines
7.0 KiB
Dart
250 lines
7.0 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
import 'package:shared_preferences_platform_interface/in_memory_shared_preferences_async.dart';
|
|
import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart';
|
|
|
|
import 'package:fruitshorts/core/config/app_config.dart';
|
|
import 'package:fruitshorts/core/config/server_endpoint.dart';
|
|
|
|
void main() {
|
|
setUp(() {
|
|
SharedPreferencesAsyncPlatform.instance =
|
|
InMemorySharedPreferencesAsync.empty();
|
|
AppConfig.clearRuntimeBaseUrl();
|
|
AppConfig.ready = Future<void>.value();
|
|
});
|
|
|
|
tearDown(() {
|
|
AppConfig.clearRuntimeBaseUrl();
|
|
AppConfig.ready = Future<void>.value();
|
|
});
|
|
|
|
test('should_normalize_http_urls_and_reject_invalid_values', () {
|
|
expect(
|
|
ServerEndpoint.normalize(' https://192.168.1.9:8081/// '),
|
|
'https://192.168.1.9:8081',
|
|
);
|
|
expect(
|
|
ServerEndpoint.normalize('http://example.test:8081/path/'),
|
|
'http://example.test:8081/path',
|
|
);
|
|
expect(ServerEndpoint.normalize('ftp://example.test'), isNull);
|
|
expect(ServerEndpoint.normalize('example.test:8081'), isNull);
|
|
expect(ServerEndpoint.normalize('http://'), isNull);
|
|
});
|
|
|
|
test('should_prioritize_runtime_over_dart_define_over_default', () {
|
|
expect(
|
|
ServerEndpoint.resolve(
|
|
stored: ' http://runtime.test:8081/ ',
|
|
compiled: 'http://define.test:8081',
|
|
fallback: 'http://default.test:8081',
|
|
),
|
|
'http://runtime.test:8081',
|
|
);
|
|
expect(
|
|
ServerEndpoint.resolve(
|
|
stored: 'ftp://invalid',
|
|
compiled: 'http://define.test:8081/',
|
|
fallback: 'http://default.test:8081',
|
|
),
|
|
'http://define.test:8081',
|
|
);
|
|
expect(
|
|
ServerEndpoint.resolve(
|
|
stored: null,
|
|
compiled: '',
|
|
fallback: 'http://default.test:8081/',
|
|
),
|
|
'http://default.test:8081',
|
|
);
|
|
});
|
|
|
|
test('should_use_the_configured_local_address_for_device_default', () {
|
|
expect(AppConfig.devHostBaseUrl, 'http://10.39.237.1:8081');
|
|
});
|
|
|
|
test('should_skip_probe_when_compiled_override_is_set', () async {
|
|
const compiled = 'http://compiled.test:8081';
|
|
var probeCalls = 0;
|
|
|
|
await AppConfig.probeAndApplyBaseUrl(
|
|
compiledOverride: compiled,
|
|
probe: (_) async {
|
|
probeCalls++;
|
|
return true;
|
|
},
|
|
);
|
|
|
|
expect(probeCalls, 0);
|
|
expect(AppConfig.apiBaseUrl, compiled);
|
|
});
|
|
|
|
test('should_keep_runtime_endpoint_when_compiled_override_is_set', () async {
|
|
const runtime = 'http://runtime.test:8081';
|
|
const compiled = 'http://compiled.test:8081';
|
|
var probeCalls = 0;
|
|
AppConfig.applyRuntimeBaseUrl(runtime);
|
|
|
|
await AppConfig.probeAndApplyBaseUrl(
|
|
compiledOverride: compiled,
|
|
probe: (_) async {
|
|
probeCalls++;
|
|
return true;
|
|
},
|
|
);
|
|
|
|
expect(probeCalls, 0);
|
|
expect(AppConfig.apiBaseUrl, runtime);
|
|
});
|
|
|
|
test('should_keep_probing_when_compiled_override_is_empty', () async {
|
|
final attempts = <String>[];
|
|
|
|
await AppConfig.probeAndApplyBaseUrl(
|
|
compiledOverride: '',
|
|
probe: (baseUrl) async {
|
|
attempts.add(baseUrl);
|
|
return baseUrl == AppConfig.publicBaseUrl;
|
|
},
|
|
);
|
|
|
|
expect(attempts, [
|
|
AppConfig.lanBaseUrl,
|
|
AppConfig.devHostBaseUrl,
|
|
AppConfig.publicBaseUrl,
|
|
]);
|
|
expect(AppConfig.apiBaseUrl, AppConfig.publicBaseUrl);
|
|
});
|
|
|
|
test(
|
|
'should_probe_all_candidates_in_parallel_before_applying_priority',
|
|
() async {
|
|
final attempts = <String>[];
|
|
var active = 0;
|
|
var maxActive = 0;
|
|
final allStarted = Completer<void>();
|
|
|
|
final probing = AppConfig.probeAndApplyBaseUrl(
|
|
fallbackBaseUrl: AppConfig.devHostBaseUrl,
|
|
probe: (baseUrl) async {
|
|
attempts.add(baseUrl);
|
|
active++;
|
|
if (active > maxActive) maxActive = active;
|
|
if (active == 3) allStarted.complete();
|
|
await allStarted.future;
|
|
active--;
|
|
return baseUrl == AppConfig.lanBaseUrl ||
|
|
baseUrl == AppConfig.devHostBaseUrl;
|
|
},
|
|
);
|
|
|
|
await probing.timeout(const Duration(seconds: 1));
|
|
|
|
expect(attempts, [
|
|
AppConfig.lanBaseUrl,
|
|
AppConfig.devHostBaseUrl,
|
|
AppConfig.publicBaseUrl,
|
|
]);
|
|
expect(maxActive, 3);
|
|
expect(AppConfig.apiBaseUrl, AppConfig.lanBaseUrl);
|
|
},
|
|
);
|
|
|
|
test('should_probe_loopback_then_public_in_order', () async {
|
|
final attempts = <String>[];
|
|
|
|
await AppConfig.probeAndApplyBaseUrl(
|
|
fallbackBaseUrl: AppConfig.devHostBaseUrl,
|
|
probe: (baseUrl) async {
|
|
attempts.add(baseUrl);
|
|
return baseUrl == AppConfig.publicBaseUrl;
|
|
},
|
|
);
|
|
|
|
expect(attempts, [
|
|
AppConfig.lanBaseUrl,
|
|
AppConfig.devHostBaseUrl,
|
|
AppConfig.publicBaseUrl,
|
|
]);
|
|
expect(AppConfig.apiBaseUrl, AppConfig.publicBaseUrl);
|
|
});
|
|
|
|
test('should_use_platform_default_when_all_probes_fail', () async {
|
|
final attempts = <String>[];
|
|
|
|
await AppConfig.probeAndApplyBaseUrl(
|
|
fallbackBaseUrl: AppConfig.devHostBaseUrl,
|
|
probe: (baseUrl) async {
|
|
attempts.add(baseUrl);
|
|
return false;
|
|
},
|
|
);
|
|
|
|
expect(attempts, [
|
|
AppConfig.lanBaseUrl,
|
|
AppConfig.devHostBaseUrl,
|
|
AppConfig.publicBaseUrl,
|
|
]);
|
|
expect(AppConfig.apiBaseUrl, AppConfig.devHostBaseUrl);
|
|
});
|
|
|
|
test('should_probe_explicit_runtime_endpoint_first', () async {
|
|
const custom = 'http://custom.test:8081';
|
|
final attempts = <String>[];
|
|
AppConfig.applyRuntimeBaseUrl(custom);
|
|
|
|
await AppConfig.probeAndApplyBaseUrl(
|
|
probe: (baseUrl) async {
|
|
attempts.add(baseUrl);
|
|
return baseUrl == custom;
|
|
},
|
|
);
|
|
|
|
expect(attempts, [
|
|
custom,
|
|
AppConfig.lanBaseUrl,
|
|
AppConfig.devHostBaseUrl,
|
|
AppConfig.publicBaseUrl,
|
|
]);
|
|
expect(AppConfig.apiBaseUrl, custom);
|
|
});
|
|
|
|
test('should_apply_stored_url_only_when_debug_is_enabled', () async {
|
|
SharedPreferencesAsyncPlatform.instance =
|
|
InMemorySharedPreferencesAsync.withData({
|
|
ServerEndpoint.preferenceKey: ' http://192.168.31.187:8081/ ',
|
|
});
|
|
final original = AppConfig.apiBaseUrl;
|
|
|
|
await ServerEndpoint.load(debug: false);
|
|
expect(AppConfig.apiBaseUrl, original);
|
|
|
|
await ServerEndpoint.load(debug: true);
|
|
expect(AppConfig.apiBaseUrl, 'http://192.168.31.187:8081');
|
|
});
|
|
|
|
test('should_save_normalized_url_and_clear_override', () async {
|
|
expect(await ServerEndpoint.save('ftp://invalid'), isFalse);
|
|
expect(
|
|
await SharedPreferencesAsync().getString(ServerEndpoint.preferenceKey),
|
|
isNull,
|
|
);
|
|
|
|
expect(await ServerEndpoint.save(' http://192.168.31.187:8081/ '), isTrue);
|
|
expect(
|
|
await SharedPreferencesAsync().getString(ServerEndpoint.preferenceKey),
|
|
'http://192.168.31.187:8081',
|
|
);
|
|
expect(AppConfig.apiBaseUrl, 'http://192.168.31.187:8081');
|
|
|
|
await ServerEndpoint.clear();
|
|
expect(
|
|
await SharedPreferencesAsync().getString(ServerEndpoint.preferenceKey),
|
|
isNull,
|
|
);
|
|
});
|
|
}
|