fix(backup): restore download and metadata provider order

Backups now carry both provider priority lists in the extensions section. Restore applies them after reinstalled extensions are enabled, so the saved order replaces the defaults instead of being reset.
This commit is contained in:
zarzet committed 2026-10-01 23:16:21 +07:00
1 parent 50f21d9c82
commit b487154065
3 files changed
+178 -3

No files matched your search

+142
View File
@@ -0,0 +1,142 @@
import 'dart:convert';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:spotiflac_android/providers/extension_provider.dart';
Extension _extension(String id) => Extension.fromJson({
'id': id,
'name': id,
'display_name': id,
'version': '1.0.0',
'enabled': true,
'has_download_provider': true,
'has_metadata_provider': true,
});
class _InstalledExtensions extends ExtensionNotifier {
@override
ExtensionState build() => ExtensionState(
extensions: [
_extension('example-a'),
_extension('example-b'),
_extension('example-c'),
],
providerPriority: const ['example-a', 'example-b', 'example-c'],
metadataProviderPriority: const ['example-a', 'example-b', 'example-c'],
);
}
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
const backend = MethodChannel('com.zarz.spotiflac/backend');
final messenger =
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger;
late Map<String, List<String>> pushed;
setUp(() {
SharedPreferences.setMockInitialValues({});
pushed = {};
messenger.setMockMethodCallHandler(backend, (call) async {
final args = call.arguments;
if (args is Map && args['priority'] is String) {
pushed[call.method] = (jsonDecode(args['priority'] as String) as List)
.cast<String>();
}
return null;
});
});
tearDown(() => messenger.setMockMethodCallHandler(backend, null));
ExtensionNotifier notifierFor(ProviderContainer container) =>
container.read(extensionProvider.notifier);
ProviderContainer container() {
final container = ProviderContainer(
overrides: [extensionProvider.overrideWith(_InstalledExtensions.new)],
);
addTearDown(container.dispose);
return container;
}
test('backup carries both provider priority lists', () {
final notifier = notifierFor(container());
expect(notifier.providerPriorityBackup(), {
'provider_priority': ['example-a', 'example-b', 'example-c'],
'metadata_provider_priority': ['example-a', 'example-b', 'example-c'],
});
});
test('restore applies the saved order to state, prefs and backend', () async {
final notifier = notifierFor(container());
await notifier.restoreProviderPriorityBackup({
'provider_priority': ['example-c', 'example-a', 'example-b'],
'metadata_provider_priority': ['example-b', 'example-c', 'example-a'],
});
expect(notifier.state.providerPriority, [
'example-c',
'example-a',
'example-b',
]);
expect(notifier.state.metadataProviderPriority, [
'example-b',
'example-c',
'example-a',
]);
expect(pushed['setProviderPriority'], notifier.state.providerPriority);
expect(
pushed['setMetadataProviderPriority'],
notifier.state.metadataProviderPriority,
);
final prefs = await SharedPreferences.getInstance();
expect(
jsonDecode(prefs.getString('provider_priority')!),
notifier.state.providerPriority,
);
expect(
jsonDecode(prefs.getString('metadata_provider_priority')!),
notifier.state.metadataProviderPriority,
);
});
test('restore keeps missing and new providers usable', () async {
final notifier = notifierFor(container());
await notifier.restoreProviderPriorityBackup({
'provider_priority': ['example-missing', 'example-c'],
});
// Unavailable IDs are dropped; providers absent from the backup follow.
expect(notifier.state.providerPriority, [
'example-c',
'example-a',
'example-b',
]);
expect(notifier.state.metadataProviderPriority, [
'example-a',
'example-b',
'example-c',
]);
expect(pushed.keys, ['setProviderPriority']);
});
test('backups without priority lists leave the current order', () async {
final notifier = notifierFor(container());
await notifier.restoreProviderPriorityBackup({
'items': const <Object>[],
'provider_priority': 'invalid',
});
expect(notifier.state.providerPriority, [
'example-a',
'example-b',
'example-c',
]);
expect(pushed, isEmpty);
});
}