mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-10-19 14:07:26 +02:00
fix(search): reject pending completions after clearing results
This commit is contained in:
1 parent
bf40ef8ebe
commit
cfeeaa3084
2 files changed
+70
-1
No files matched your search
@@ -161,7 +161,8 @@ class TrackNotifier extends Notifier<TrackState> {
|
||||
return const TrackState();
|
||||
}
|
||||
|
||||
bool _isRequestValid(int requestId) => requestId == _currentRequestId;
|
||||
bool _isRequestValid(int requestId) =>
|
||||
ref.mounted && requestId == _currentRequestId;
|
||||
|
||||
Future<void> fetchFromUrl(String url) async {
|
||||
final requestId = ++_currentRequestId;
|
||||
@@ -170,6 +171,7 @@ class TrackNotifier extends Notifier<TrackState> {
|
||||
|
||||
try {
|
||||
var extensionHandler = await PlatformBridge.findURLHandler(url);
|
||||
if (!_isRequestValid(requestId)) return;
|
||||
if (extensionHandler == null) {
|
||||
final extensionState = ref.read(extensionProvider);
|
||||
if (!extensionState.isInitialized && extensionState.isLoading) {
|
||||
@@ -181,6 +183,7 @@ class TrackNotifier extends Notifier<TrackState> {
|
||||
.waitForInitialization(timeout: _extensionInitRetryTimeout);
|
||||
if (!_isRequestValid(requestId)) return;
|
||||
extensionHandler = await PlatformBridge.findURLHandler(url);
|
||||
if (!_isRequestValid(requestId)) return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,6 +220,7 @@ class TrackNotifier extends Notifier<TrackState> {
|
||||
|
||||
if (attempt < 3) {
|
||||
await Future<void>.delayed(const Duration(milliseconds: 500));
|
||||
if (!_isRequestValid(requestId)) return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -547,6 +551,7 @@ class TrackNotifier extends Notifier<TrackState> {
|
||||
}
|
||||
|
||||
void clear() {
|
||||
_currentRequestId++;
|
||||
state = const TrackState();
|
||||
}
|
||||
|
||||
|
||||
@@ -62,4 +62,68 @@ void main() {
|
||||
expect(container.read(trackProvider).isLoading, isFalse);
|
||||
},
|
||||
);
|
||||
|
||||
for (final fails in [false, true]) {
|
||||
test(
|
||||
'clear rejects a pending search ${fails ? 'error' : 'result'}',
|
||||
() async {
|
||||
const channel = MethodChannel('com.zarz.spotiflac/backend');
|
||||
final messenger =
|
||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger;
|
||||
final response = Completer<String>();
|
||||
final started = Completer<void>();
|
||||
messenger.setMockMethodCallHandler(channel, (call) async {
|
||||
if (call.method != 'customSearchWithExtension') return null;
|
||||
started.complete();
|
||||
return response.future;
|
||||
});
|
||||
addTearDown(() => messenger.setMockMethodCallHandler(channel, null));
|
||||
final container = ProviderContainer();
|
||||
addTearDown(container.dispose);
|
||||
final notifier = container.read(trackProvider.notifier);
|
||||
final search = notifier.customSearch('clear-search-$fails', 'query');
|
||||
await started.future;
|
||||
notifier.clear();
|
||||
if (fails) {
|
||||
response.completeError(PlatformException(code: 'late-search-error'));
|
||||
} else {
|
||||
response.complete('[{"id":"late","name":"Late result"}]');
|
||||
}
|
||||
await search;
|
||||
final state = container.read(trackProvider);
|
||||
expect(state.hasContent, isFalse);
|
||||
expect(state.isLoading, isFalse);
|
||||
expect(state.error, isNull);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
for (final handler in [null, 'clear-url-provider']) {
|
||||
test('clear rejects URL preflight completion ($handler)', () async {
|
||||
const channel = MethodChannel('com.zarz.spotiflac/backend');
|
||||
final messenger =
|
||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger;
|
||||
final response = Completer<String?>();
|
||||
final started = Completer<void>();
|
||||
messenger.setMockMethodCallHandler(channel, (call) async {
|
||||
expect(call.method, 'findURLHandler');
|
||||
started.complete();
|
||||
return response.future;
|
||||
});
|
||||
addTearDown(() => messenger.setMockMethodCallHandler(channel, null));
|
||||
final container = ProviderContainer();
|
||||
addTearDown(container.dispose);
|
||||
final notifier = container.read(trackProvider.notifier);
|
||||
final fetch = notifier.fetchFromUrl(
|
||||
'https://example.test/clear-$handler',
|
||||
);
|
||||
await started.future;
|
||||
notifier.clear();
|
||||
response.complete(handler);
|
||||
await fetch;
|
||||
expect(container.read(trackProvider).hasContent, isFalse);
|
||||
expect(container.read(trackProvider).isLoading, isFalse);
|
||||
expect(container.read(trackProvider).error, isNull);
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user