Add proxy routing and sing-box support
This commit is contained in:
+1
-1
@@ -24,7 +24,7 @@ import 'dart:typed_data';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:riverpod/experimental/persist.dart';
|
||||
import 'package:riverpod/riverpod.dart';
|
||||
import 'package:search_backend/search_backend.dart';
|
||||
import 'package:search_protocol/search_protocol.dart';
|
||||
import 'package:weblibre/features/search_credits/domain/controllers/search_token_issuance_controller.dart';
|
||||
import 'package:weblibre/features/user/data/providers.dart';
|
||||
import 'package:weblibre/features/web_search/domain/controllers/search_controller.dart';
|
||||
|
||||
@@ -125,23 +125,25 @@ void main() {
|
||||
expect(decoded['url'], contains('t='));
|
||||
});
|
||||
|
||||
test('err=1 starts the loader in the error pane with a retry button',
|
||||
() async {
|
||||
final url = await server.loaderUrl(
|
||||
tabId: 'tab-9',
|
||||
captureId: 'failed9',
|
||||
error: true,
|
||||
);
|
||||
final res = await _get(url);
|
||||
expect(res.statusCode, 200);
|
||||
// Retry is now a JS-driven button, not an HTML form — assert the
|
||||
// shell starts in error mode (error pane visible, pending hidden)
|
||||
// and that the button + JS retry endpoint string are present.
|
||||
expect(res.body, contains('id="retry"'));
|
||||
expect(res.body, contains('id="error" class="error"'));
|
||||
expect(res.body, contains('id="pending" class="hidden"'));
|
||||
expect(res.body, contains('/loader/retry?tab='));
|
||||
});
|
||||
test(
|
||||
'err=1 starts the loader in the error pane with a retry button',
|
||||
() async {
|
||||
final url = await server.loaderUrl(
|
||||
tabId: 'tab-9',
|
||||
captureId: 'failed9',
|
||||
error: true,
|
||||
);
|
||||
final res = await _get(url);
|
||||
expect(res.statusCode, 200);
|
||||
// Retry is now a JS-driven button, not an HTML form — assert the
|
||||
// shell starts in error mode (error pane visible, pending hidden)
|
||||
// and that the button + JS retry endpoint string are present.
|
||||
expect(res.body, contains('id="retry"'));
|
||||
expect(res.body, contains('id="error" class="error"'));
|
||||
expect(res.body, contains('id="pending" class="hidden"'));
|
||||
expect(res.body, contains('/loader/retry?tab='));
|
||||
},
|
||||
);
|
||||
|
||||
test('loader with invalid capture id returns 404', () async {
|
||||
final port = await server.ensureStarted();
|
||||
@@ -174,9 +176,7 @@ void main() {
|
||||
// Start the long-poll while nothing has been published yet — it
|
||||
// should block on the per-id completer, not busy-poll the filesystem.
|
||||
final pollFuture = _get(
|
||||
Uri.parse(
|
||||
'http://127.0.0.1:$port/loader/wait?tab=t&capture=signaled',
|
||||
),
|
||||
Uri.parse('http://127.0.0.1:$port/loader/wait?tab=t&capture=signaled'),
|
||||
);
|
||||
// Race-free: publish only after the request hit the handler. A short
|
||||
// microtask flush gives the handler time to register its waiter.
|
||||
@@ -192,23 +192,25 @@ void main() {
|
||||
});
|
||||
|
||||
group('retry route', () {
|
||||
test('emits a RetryRequest on retryRequests stream and returns 204',
|
||||
() async {
|
||||
final port = await server.ensureStarted();
|
||||
final retryFuture = server.retryRequests.first;
|
||||
test(
|
||||
'emits a RetryRequest on retryRequests stream and returns 204',
|
||||
() async {
|
||||
final port = await server.ensureStarted();
|
||||
final retryFuture = server.retryRequests.first;
|
||||
|
||||
final res = await _post(
|
||||
Uri.parse(
|
||||
'http://127.0.0.1:$port/loader/retry?tab=tab-42&capture=cap42',
|
||||
),
|
||||
);
|
||||
// 204 No Content — the JS loader re-polls; a body would be wasted.
|
||||
expect(res.statusCode, 204);
|
||||
final res = await _post(
|
||||
Uri.parse(
|
||||
'http://127.0.0.1:$port/loader/retry?tab=tab-42&capture=cap42',
|
||||
),
|
||||
);
|
||||
// 204 No Content — the JS loader re-polls; a body would be wasted.
|
||||
expect(res.statusCode, 204);
|
||||
|
||||
final req = await retryFuture.timeout(const Duration(seconds: 2));
|
||||
expect(req.tabId, 'tab-42');
|
||||
expect(req.captureId, 'cap42');
|
||||
});
|
||||
final req = await retryFuture.timeout(const Duration(seconds: 2));
|
||||
expect(req.tabId, 'tab-42');
|
||||
expect(req.captureId, 'cap42');
|
||||
},
|
||||
);
|
||||
|
||||
test('retry rejects GET with 405', () async {
|
||||
final port = await server.ensureStarted();
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:search_backend/search_backend.dart';
|
||||
import 'package:search_protocol/search_protocol.dart';
|
||||
import 'package:weblibre/features/geckoview/domain/entities/tab_container_selection.dart';
|
||||
import 'package:weblibre/features/geckoview/features/tabs/data/entities/tab_mode.dart';
|
||||
import 'package:weblibre/features/user/domain/providers.dart';
|
||||
@@ -79,14 +79,14 @@ void main() {
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
await tester.pump(const Duration(milliseconds: 100));
|
||||
|
||||
expect(find.text('Heading'), findsOneWidget);
|
||||
expect(find.text('Body copy'), findsOneWidget);
|
||||
expect(find.text('Fabian'), findsOneWidget);
|
||||
|
||||
await tester.tap(find.byTooltip('Open in browser'));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.pump();
|
||||
|
||||
expect(opener.openedUris, [Uri.parse(url)]);
|
||||
});
|
||||
|
||||
+17
-9
@@ -23,7 +23,9 @@ import 'dart:typed_data';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:search_backend/search_backend.dart';
|
||||
import 'package:search_protocol/search_protocol.dart';
|
||||
import 'package:weblibre/features/search_credits/data/models/web_search_settings.dart';
|
||||
import 'package:weblibre/features/search_credits/domain/repositories/web_search_settings.dart';
|
||||
import 'package:weblibre/features/user/domain/providers.dart';
|
||||
import 'package:weblibre/features/web_search/domain/controllers/search_controller.dart';
|
||||
import 'package:weblibre/features/web_search/presentation/widgets/search_result_card.dart';
|
||||
@@ -39,12 +41,15 @@ void main() {
|
||||
ProviderScope(
|
||||
overrides: [
|
||||
...webSearchTestOverrides(),
|
||||
metaSearchControllerProvider.overrideWithValue(
|
||||
MetaSearchState(status: WebSearchStatus.ready),
|
||||
),
|
||||
watchCachedIconBytesProvider.overrideWith((ref, origin) {
|
||||
return Stream.value(null);
|
||||
}),
|
||||
metaSearchControllerProvider.overrideWithValue(
|
||||
const MetaSearchState(status: WebSearchStatus.ready),
|
||||
),
|
||||
webSearchSettingsControllerProvider.overrideWithValue(
|
||||
WebSearchSettings.withDefaults(),
|
||||
),
|
||||
],
|
||||
child: MaterialApp(
|
||||
home: Scaffold(
|
||||
@@ -67,7 +72,7 @@ void main() {
|
||||
);
|
||||
|
||||
await tester.tap(find.text('LensAI result'));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.pump();
|
||||
|
||||
expect(openedUris, [Uri.parse(url)]);
|
||||
});
|
||||
@@ -84,15 +89,18 @@ void main() {
|
||||
ProviderScope(
|
||||
overrides: [
|
||||
...webSearchTestOverrides(),
|
||||
watchCachedIconBytesProvider.overrideWith((ref, origin) {
|
||||
return Stream.value(null);
|
||||
}),
|
||||
metaSearchControllerProvider.overrideWithValue(
|
||||
MetaSearchState(
|
||||
status: WebSearchStatus.ready,
|
||||
imagesByUrl: {thumbnailUrl: Uint8List.fromList(pngBytes)},
|
||||
),
|
||||
),
|
||||
watchCachedIconBytesProvider.overrideWith((ref, origin) {
|
||||
return Stream.value(null);
|
||||
}),
|
||||
webSearchSettingsControllerProvider.overrideWithValue(
|
||||
WebSearchSettings.withDefaults(),
|
||||
),
|
||||
],
|
||||
child: MaterialApp(
|
||||
home: Scaffold(
|
||||
@@ -114,7 +122,7 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
await tester.pump(const Duration(milliseconds: 100));
|
||||
|
||||
expect(find.byType(Image), findsOneWidget);
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user