Skip to content

Commit

Permalink
Merge #266
Browse files Browse the repository at this point in the history
266: Customize dio adapter r=brunoocasali a=ahmednfwela

Fixes #138

this adds a new `MeiliSearchClient.withCustomDio` which can customize adapter and interceptors

- [ ] Added Tests


Co-authored-by: Ahmed Fwela <ahmednfwela@bdaya-dev.com>
  • Loading branch information
bors[bot] and ahmednfwela committed Mar 15, 2023
2 parents 821cc6e + eeac053 commit 1205677
Show file tree
Hide file tree
Showing 7 changed files with 133 additions and 20 deletions.
39 changes: 29 additions & 10 deletions lib/src/client.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:dio/dio.dart';
import 'package:meilisearch/src/key.dart';
import 'package:meilisearch/src/query_parameters/cancel_tasks_query.dart';
import 'package:meilisearch/src/query_parameters/delete_tasks_query.dart';
Expand All @@ -15,8 +16,21 @@ import 'client_impl.dart';
import 'stats.dart' show AllStats;

abstract class MeiliSearchClient {
factory MeiliSearchClient(String serverUrl,
[String? apiKey, Duration? connectTimeout]) = MeiliSearchClientImpl;
factory MeiliSearchClient(
String serverUrl, [
String? apiKey,
Duration? connectTimeout,
]) = MeiliSearchClientImpl;

factory MeiliSearchClient.withCustomDio(
String serverUrl, {
String? apiKey,
Duration? connectTimeout,
HttpClientAdapter? adapter,
List<Interceptor>? interceptors,
}) =>
MeiliSearchClientImpl(
serverUrl, apiKey, connectTimeout, adapter, interceptors);

/// Http client instance.
HttpRequest get http;
Expand All @@ -30,8 +44,12 @@ abstract class MeiliSearchClient {
/// Timeout in milliseconds for opening a url.
Duration? get connectTimeout;

String generateTenantToken(String uid, Object? searchRules,
{String? apiKey, DateTime? expiresAt});
String generateTenantToken(
String uid,
Object? searchRules, {
String? apiKey,
DateTime? expiresAt,
});

/// Create an index object by given [uid].
MeiliSearchIndex index(String uid);
Expand Down Expand Up @@ -77,12 +95,13 @@ abstract class MeiliSearchClient {
Future<Key> getKey(String keyOrUid);

/// Create a new key.
Future<Key> createKey(
{DateTime? expiresAt,
String? description,
String? uid,
required List<String> indexes,
required List<String> actions});
Future<Key> createKey({
DateTime? expiresAt,
String? description,
String? uid,
required List<String> indexes,
required List<String> actions,
});

/// Update a key.
Future<Key> updateKey(String key, {String? description, String? name});
Expand Down
15 changes: 13 additions & 2 deletions lib/src/client_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,19 @@ import 'key.dart';
import 'stats.dart' show AllStats;

class MeiliSearchClientImpl implements MeiliSearchClient {
MeiliSearchClientImpl(this.serverUrl, [this.apiKey, this.connectTimeout])
: http = HttpRequestImpl(serverUrl, apiKey, connectTimeout);
MeiliSearchClientImpl(
this.serverUrl, [
this.apiKey,
this.connectTimeout,
HttpClientAdapter? adapter,
List<Interceptor>? interceptors,
]) : http = HttpRequestImpl(
serverUrl,
apiKey,
connectTimeout,
adapter,
interceptors,
);

@override
final String serverUrl;
Expand Down
9 changes: 7 additions & 2 deletions lib/src/http_request.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@ import 'package:dio/dio.dart';
import 'http_request_impl.dart';

abstract class HttpRequest {
factory HttpRequest(String serverUrl, String apiKey,
[Duration connectTimeout]) = HttpRequestImpl;
factory HttpRequest(
String serverUrl,
String apiKey, [
Duration? connectTimeout,
HttpClientAdapter? adapter,
List<Interceptor>? interceptors,
]) = HttpRequestImpl;

/// Meilisearch server URL.
String get serverUrl;
Expand Down
21 changes: 18 additions & 3 deletions lib/src/http_request_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,13 @@ import 'exception.dart';
const bool _kIsWeb = bool.fromEnvironment('dart.library.js_util');

class HttpRequestImpl implements HttpRequest {
HttpRequestImpl(this.serverUrl, this.apiKey, [this.connectTimeout])
: dio = Dio(
HttpRequestImpl(
this.serverUrl,
this.apiKey, [
this.connectTimeout,
HttpClientAdapter? adapter,
List<Interceptor>? interceptors,
]) : dio = Dio(
BaseOptions(
baseUrl: serverUrl,
headers: <String, Object>{
Expand All @@ -20,7 +25,17 @@ class HttpRequestImpl implements HttpRequest {
responseType: ResponseType.json,
connectTimeout: connectTimeout ?? Duration(seconds: 5),
),
);
) {
if (adapter != null) {
dio.httpClientAdapter = adapter;
}

dio.interceptors.removeImplyContentTypeInterceptor();

if (interceptors != null) {
dio.interceptors.addAll(interceptors);
}
}

@override
final String serverUrl;
Expand Down
58 changes: 58 additions & 0 deletions test/custom_dio_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import 'dart:typed_data';

import 'package:dio/dio.dart';
import 'package:dio/io.dart';
import 'package:meilisearch/meilisearch.dart';
import 'package:test/test.dart';

import 'utils/client.dart';

class TestInterceptor extends Interceptor {
bool onRequestCalled = false;
@override
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
onRequestCalled = true;
super.onRequest(options, handler);
}
}

class TestAdapter extends IOHttpClientAdapter {
bool fetchCalled = false;
@override
Future<ResponseBody> fetch(RequestOptions options,
Stream<Uint8List>? requestStream, Future<void>? cancelFuture) {
fetchCalled = true;
return super.fetch(options, requestStream, cancelFuture);
}
}

void main() {
group('Custom dio', () {
test('Interceptor', () async {
final interceptor = TestInterceptor();
final client = MeiliSearchClient.withCustomDio(
testServer,
apiKey: "masterKey",
interceptors: [interceptor],
);

var health = await client.health();

expect(health, {'status': 'available'});
expect(interceptor.onRequestCalled, equals(true));
});
test("Adapter", () async {
final adapter = TestAdapter();
final client = MeiliSearchClient.withCustomDio(
testServer,
apiKey: "masterKey",
adapter: adapter,
);

var health = await client.health();

expect(health, {'status': 'available'});
expect(adapter.fetchCalled, equals(true));
});
});
}
4 changes: 4 additions & 0 deletions test/health_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,17 @@ void main() {

test('of the server when the url is valid', () async {
var health = await client.health();

expect(health, {'status': 'available'});
});

test('of the server when the url is valid with isHealthy', () async {
var health = await client.isHealthy();

expect(health, true);
});
});

group('Health Fail', () {
setUpClientWithWrongUrl();

Expand All @@ -25,6 +28,7 @@ void main() {

test('when the url is not valid with isHealthy', () async {
var health = await client.isHealthy();

expect(health, false);
});
});
Expand Down
7 changes: 4 additions & 3 deletions test/utils/client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ Future<void> deleteAllKeys() async {
void setUpClient() {
setUp(() {
final String server = testServer;

client = MeiliSearchClient(server, 'masterKey');
const masterKey = 'masterKey';
client = MeiliSearchClient(server, masterKey);
random = Random();
});

Expand All @@ -56,8 +56,9 @@ void setUpClientWithWrongUrl() {
setUp(() {
final String server = 'http://wrongurl:1234';
final connectTimeout = Duration(milliseconds: 1000);
const masterKey = 'masterKey';

client = MeiliSearchClient(server, 'masterKey', connectTimeout);
client = MeiliSearchClient(server, masterKey, connectTimeout);
});
}

Expand Down

0 comments on commit 1205677

Please sign in to comment.