import 'package:consumer_app/core/networking/api_client.dart';
import 'package:consumer_app/core/networking/public_read_cache.dart';
import 'package:consumer_app/repositories/http_discovery_repository.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:http/http.dart' as http;
import 'package:http/testing.dart';
void main() {
test('forwards the complete shared discovery query contract', () async {
Uri? requestedUri;
final httpClient = MockClient((request) async {
requestedUri = request.url;
return http.Response(
'{"items":[],"meta":{"page":2,"per_page":12,"total":0}}',
200,
);
});
final api = ApiClient(
baseUrl: Uri.parse('https://example.test/wp-json/meinweimar/v1'),
locale: () => 'de-DE',
client: httpClient,
publicReadCache: PublicReadCache(store: _MemoryStore()),
);
final response = await HttpDiscoveryRepository(api).discover(
types: const ['places', 'events'],
search: ' Café ',
page: 2,
perPage: 12,
category: 'gastro',
region: 'weimar',
status: 'published',
sort: 'title',
latitude: 50.98,
longitude: 11.33,
radiusKm: 25,
filters: const {'offer_type': 'employment', 'work_mode': 'remote'},
minLatitude: 50.8,
maxLatitude: 51.1,
minLongitude: 11.1,
maxLongitude: 11.5,
);
expect(response.meta.page, 2);
expect(requestedUri?.queryParameters, {
'types': 'places,events',
'page': '2',
'per_page': '12',
'radius_km': '25',
'sort': 'title',
'search': 'Café',
'category': 'gastro',
'region': 'weimar',
'status': 'published',
'offer_type': 'employment',
'work_mode': 'remote',
'lat': '50.98',
'lng': '11.33',
'min_lat': '50.8',
'max_lat': '51.1',
'min_lng': '11.1',
'max_lng': '11.5',
});
});
test('keeps ten metre radius precision in the REST query', () async {
Uri? requestedUri;
final httpClient = MockClient((request) async {
requestedUri = request.url;
return http.Response(
'{"items":[],"meta":{"page":1,"per_page":40,"total":0}}',
200,
);
});
final api = ApiClient(
baseUrl: Uri.parse('https://example.test/wp-json/meinweimar/v1'),
locale: () => 'de-DE',
client: httpClient,
publicReadCache: PublicReadCache(store: _MemoryStore()),
);
await HttpDiscoveryRepository(
api,
).discover(types: const ['events'], radiusKm: 0.01);
expect(requestedUri?.queryParameters['radius_km'], '0.01');
});
test(
'omits geo radius when an editorial resource does not use location',
() async {
Uri? requestedUri;
final httpClient = MockClient((request) async {
requestedUri = request.url;
return http.Response(
'{"items":[],"meta":{"page":1,"per_page":40,"total":0}}',
200,
);
});
final api = ApiClient(
baseUrl: Uri.parse('https://example.test/wp-json/meinweimar/v1'),
locale: () => 'de-DE',
client: httpClient,
publicReadCache: PublicReadCache(store: _MemoryStore()),
);
await HttpDiscoveryRepository(api).discover(
types: const ['news'],
latitude: null,
longitude: null,
radiusKm: null,
);
expect(requestedUri?.queryParameters.containsKey('radius_km'), isFalse);
expect(requestedUri?.queryParameters.containsKey('lat'), isFalse);
expect(requestedUri?.queryParameters.containsKey('lng'), isFalse);
},
);
}
class _MemoryStore implements PublicReadCacheStore {
final Map<String, String> values = {};
@override
Future<String?> read(String key) async => values[key];
@override
Future<void> write(String key, String value) async => values[key] = value;
@override
Future<void> remove(String key) async => values.remove(key);
@override
Future<Set<String>> keys() async => values.keys.toSet();
}
