99 lines
4.0 KiB
Dart
99 lines
4.0 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:http/http.dart' as http;
|
|
import 'package:http/testing.dart';
|
|
import 'package:package_info_plus/package_info_plus.dart';
|
|
import 'package:plezy/utils/media_server_http_client.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:plezy/services/base_shared_preferences_service.dart';
|
|
import 'package:plezy/services/update_service.dart';
|
|
|
|
import '../test_helpers/prefs.dart';
|
|
|
|
void main() {
|
|
const lastCheckKey = 'update_last_check_time';
|
|
|
|
setUp(resetSharedPreferencesForTest);
|
|
PackageInfo.setMockInitialValues(
|
|
appName: 'Plezy',
|
|
packageName: 'com.plezy.test',
|
|
version: '1.0.0',
|
|
buildNumber: '1',
|
|
buildSignature: '',
|
|
);
|
|
|
|
test('malformed cooldown state fails open and removes the invalid value', () async {
|
|
final prefs = await BaseSharedPreferencesService.sharedCache();
|
|
await prefs.setString(lastCheckKey, 'not-an-instant');
|
|
|
|
expect(await UpdateService.shouldCheckForUpdates(), isTrue);
|
|
expect(prefs.getString(lastCheckKey), isNull);
|
|
});
|
|
|
|
test('future cooldown state fails open and removes the invalid value', () async {
|
|
final prefs = await BaseSharedPreferencesService.sharedCache();
|
|
await prefs.setString(lastCheckKey, DateTime.now().add(const Duration(days: 30)).toIso8601String());
|
|
|
|
expect(await UpdateService.shouldCheckForUpdates(), isTrue);
|
|
expect(prefs.getString(lastCheckKey), isNull);
|
|
});
|
|
|
|
test('recent valid cooldown state suppresses a duplicate check and remains stored', () async {
|
|
final prefs = await BaseSharedPreferencesService.sharedCache();
|
|
final recent = DateTime.now().subtract(const Duration(minutes: 5)).toIso8601String();
|
|
await prefs.setString(lastCheckKey, recent);
|
|
|
|
expect(await UpdateService.shouldCheckForUpdates(), isFalse);
|
|
expect(prefs.getString(lastCheckKey), recent);
|
|
});
|
|
|
|
test('old valid cooldown state permits a new check', () async {
|
|
final prefs = await BaseSharedPreferencesService.sharedCache();
|
|
final old = DateTime.now().subtract(const Duration(days: 2)).toIso8601String();
|
|
await prefs.setString(lastCheckKey, old);
|
|
|
|
expect(await UpdateService.shouldCheckForUpdates(), isTrue);
|
|
expect(prefs.getString(lastCheckKey), old);
|
|
});
|
|
|
|
final failedResponses = <String, Future<http.Response> Function()>{
|
|
'timeout': () async => throw TimeoutException('request timed out'),
|
|
'non-200 response': () async => http.Response('unavailable', 503),
|
|
'parse failure': () async => http.Response('not-json', 200, headers: {'content-type': 'application/json'}),
|
|
};
|
|
|
|
for (final failure in failedResponses.entries) {
|
|
test('startup ${failure.key} records cooldown before request and manual check bypasses it', () async {
|
|
final prefs = await BaseSharedPreferencesService.sharedCache();
|
|
final cooldownAtRequest = <String?>[];
|
|
var requestCount = 0;
|
|
final client = MediaServerHttpClient(
|
|
client: MockClient((_) async {
|
|
requestCount++;
|
|
cooldownAtRequest.add(prefs.getString(lastCheckKey));
|
|
return failure.value();
|
|
}),
|
|
);
|
|
addTearDown(client.close);
|
|
|
|
expect(await UpdateService.debugPerformUpdateCheck(respectCooldown: true, client: client), isNull);
|
|
expect(requestCount, 1);
|
|
expect(cooldownAtRequest.single, isNotNull);
|
|
final recordedCooldown = prefs.getString(lastCheckKey);
|
|
expect(recordedCooldown, cooldownAtRequest.single);
|
|
expect(DateTime.now().difference(DateTime.parse(recordedCooldown!)), lessThan(const Duration(minutes: 1)));
|
|
|
|
expect(await UpdateService.debugPerformUpdateCheck(respectCooldown: true, client: client), isNull);
|
|
expect(requestCount, 1, reason: 'a simulated next launch must honor the failed attempt cooldown');
|
|
|
|
expect(await UpdateService.debugPerformUpdateCheck(respectCooldown: false, client: client), isNull);
|
|
expect(requestCount, 2, reason: 'an explicit manual check must bypass a recent startup cooldown');
|
|
expect(
|
|
prefs.getString(lastCheckKey),
|
|
recordedCooldown,
|
|
reason: 'manual checks must not rewrite startup cooldown',
|
|
);
|
|
});
|
|
}
|
|
}
|