Skip to content

Commit

Permalink
Enable request tests on all platforms
Browse files Browse the repository at this point in the history
  • Loading branch information
kuhnroyal committed Aug 9, 2023
1 parent 0854519 commit 076b141
Show file tree
Hide file tree
Showing 4 changed files with 345 additions and 197 deletions.
6 changes: 6 additions & 0 deletions dio/dart_test.yaml
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
file_reporters:
json: build/reports/test-results.json

override_platforms:
chrome:
settings:
# disable web security to allow CORS requests
arguments: --disable-web-security
7 changes: 5 additions & 2 deletions dio/lib/src/adapters/browser_adapter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ class BrowserHttpClientAdapter implements HttpClientAdapter {
xhr.status!,
headers: xhr.responseHeaders.map((k, v) => MapEntry(k, v.split(','))),
statusMessage: xhr.statusText,
isRedirect: xhr.status == 302 || xhr.status == 301,
isRedirect: xhr.status == 302 ||
xhr.status == 301 ||
options.uri.toString() != xhr.responseUrl,
),
);
});
Expand Down Expand Up @@ -198,7 +200,8 @@ class BrowserHttpClientAdapter implements HttpClientAdapter {
});

cancelFuture?.then((_) {
if (xhr.readyState < 4 && xhr.readyState > 0) {
if (xhr.readyState < HttpRequest.DONE &&
xhr.readyState > HttpRequest.UNSENT) {
connectTimeoutTimer?.cancel();
try {
xhr.abort();
Expand Down
334 changes: 334 additions & 0 deletions dio/test/request_integration_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,334 @@
import 'package:dio/dio.dart';
import 'package:test/test.dart';

import 'utils.dart';

void main() {
group('requests', () {
late Dio dio;

setUp(() {
dio = Dio();
dio.options.baseUrl = 'https://httpbun.com/';
});

group('restful APIs', () {
const data = {'content': 'I am payload'};

test('HEAD', () async {
final response = await dio.head(
'/anything',
);
expect(response.statusCode, 200);
expect(response.isRedirect, isFalse);
});

test('GET', () async {
final response = await dio.get(
'/get',
queryParameters: {'id': '12', 'name': 'wendu'},
);
expect(response.statusCode, 200);
expect(response.isRedirect, isFalse);
expect(response.data['method'], 'GET');
expect(response.data['args'], {'id': '12', 'name': 'wendu'});
});

// TODO This is not supported on web, should we warn?
test('GET with content', () async {
final response = await dio.get(
'/anything',
queryParameters: {'id': '12', 'name': 'wendu'},
data: data,
);
expect(response.statusCode, 200);
expect(response.isRedirect, isFalse);
expect(response.data['method'], 'GET');
expect(response.data['args'], {'id': '12', 'name': 'wendu'});
expect(response.data['json'], data);
expect(
response.data['headers']['Content-Type'],
Headers.jsonContentType,
);
}, testOn: '!browser');

test('POST', () async {
final response = await dio.post(
'/post',
data: data,
options: Options(contentType: Headers.jsonContentType),
);
expect(response.statusCode, 200);
expect(response.isRedirect, isFalse);
expect(response.data['method'], 'POST');
expect(response.data['json'], data);
expect(
response.data['headers']['Content-Type'],
Headers.jsonContentType,
);
});

test('PUT', () async {
final response = await dio.put(
'/put',
data: data,
);
expect(response.statusCode, 200);
expect(response.isRedirect, isFalse);
expect(response.data['method'], 'PUT');
expect(response.data['json'], data);
expect(
response.data['headers']['Content-Type'],
Headers.jsonContentType,
);
});

test('PATCH', () async {
final response = await dio.patch(
'/patch',
data: data,
);
expect(response.statusCode, 200);
expect(response.isRedirect, isFalse);
expect(response.data['method'], 'PATCH');
expect(response.data['json'], data);
expect(
response.data['headers']['Content-Type'],
Headers.jsonContentType,
);
});

test('DELETE', () async {
final response = await dio.delete(
'/delete',
);
expect(response.statusCode, 200);
expect(response.isRedirect, isFalse);
expect(response.data['method'], 'DELETE');
});

test('DELETE with content', () async {
final response = await dio.delete(
'/delete',
data: data,
);
expect(response.statusCode, 200);
expect(response.isRedirect, isFalse);
expect(response.data['method'], 'DELETE');
expect(response.data['json'], data);
expect(
response.data['headers']['Content-Type'],
Headers.jsonContentType,
);
});
});

group('request with URI', () {
const data = {'content': 'I am payload'};

test('HEAD', () async {
final response = await dio.headUri(
Uri.parse('/anything'),
);
expect(response.statusCode, 200);
expect(response.isRedirect, isFalse);
});

test('GET', () async {
final response = await dio.getUri(
Uri(path: '/get', queryParameters: {'id': '12', 'name': 'wendu'}),
);
expect(response.statusCode, 200);
expect(response.isRedirect, isFalse);
expect(response.data['args'], {'id': '12', 'name': 'wendu'});
});

// Not supported on web
test('GET with content', () async {
final response = await dio.getUri(
Uri(
path: '/anything',
queryParameters: {'id': '12', 'name': 'wendu'},
),
data: data,
);
expect(response.statusCode, 200);
expect(response.isRedirect, isFalse);
expect(response.data['args'], {'id': '12', 'name': 'wendu'});
expect(response.data['json'], data);
expect(
response.data['headers']['Content-Type'],
Headers.jsonContentType,
);
}, testOn: '!browser');

test('POST', () async {
final response = await dio.postUri(
Uri.parse('/post'),
data: data,
);
expect(response.statusCode, 200);
expect(response.isRedirect, isFalse);
expect(response.data['method'], 'POST');
expect(response.data['json'], data);
expect(
response.data['headers']['Content-Type'],
Headers.jsonContentType,
);
});

test('PUT', () async {
final response = await dio.putUri(
Uri.parse('/put'),
data: data,
);
expect(response.statusCode, 200);
expect(response.isRedirect, isFalse);
expect(response.data['method'], 'PUT');
expect(response.data['json'], data);
expect(
response.data['headers']['Content-Type'],
Headers.jsonContentType,
);
});

test('PATCH', () async {
final response = await dio.patchUri(
Uri.parse('/patch'),
data: data,
);
expect(response.statusCode, 200);
expect(response.isRedirect, isFalse);
expect(response.data['method'], 'PATCH');
expect(response.data['json'], data);
expect(
response.data['headers']['Content-Type'],
Headers.jsonContentType,
);
});

test('DELETE', () async {
final response = await dio.deleteUri(
Uri.parse('/delete'),
);
expect(response.statusCode, 200);
expect(response.isRedirect, isFalse);
expect(response.data['method'], 'DELETE');
});

test('DELETE with content', () async {
final response = await dio.deleteUri(
Uri.parse('/delete'),
data: data,
);
expect(response.statusCode, 200);
expect(response.isRedirect, isFalse);
expect(response.data['method'], 'DELETE');
expect(response.data['json'], data);
expect(
response.data['headers']['Content-Type'],
Headers.jsonContentType,
);
});
});

group('redirects', () {
test('single', () async {
final response = await dio.get(
'/redirect',
queryParameters: {'url': 'https://httpbun.com/get'},
onReceiveProgress: (received, total) {
// ignore progress
},
);
expect(response.isRedirect, isTrue);

if (!isWeb) {
// Redirects are not supported in web.
// Rhe browser will follow the redirects automatically.
expect(response.redirects.length, 1);
final ri = response.redirects.first;
expect(ri.statusCode, 302);
expect(ri.location.path, '/get');
expect(ri.method, 'GET');
}
});

test('multiple', () async {
final response = await dio.get(
'/redirect/3',
);
expect(response.isRedirect, isTrue);

if (!isWeb) {
// Redirects are not supported in web.
// Rhe browser will follow the redirects automatically.
expect(response.redirects.length, 3);
final ri = response.redirects.first;
expect(ri.statusCode, 302);
expect(ri.method, 'GET');
}
});
});

group('status codes', () {
for (final code in [400, 401, 404, 500, 503]) {
test('$code', () async {
expect(
dio.get('/status/$code').catchError(
(e) => throw (e as DioException).response!.statusCode!),
throwsA(equals(code)),
);
});
}
});

test('multi value headers', () async {
final Response response = await dio.get(
'/get',
options: Options(
headers: {
'x-multi-value-request-header': ['value1', 'value2'],
},
),
);
expect(response.statusCode, 200);
expect(response.isRedirect, isFalse);
expect(
response.data['headers']['X-Multi-Value-Request-Header'],
// TODO we have a diff here between browser and non-browser
equals('value1, value2'),
);
});

group('generic parameters', () {
test('default (Map)', () async {
final response = await dio.get('/get');
expect(response.data, isA<Map>());
expect(response.data, isNotEmpty);
});

test('Map', () async {
final response = await dio.get<Map>('/get');
expect(response.data, isA<Map>());
expect(response.data, isNotEmpty);
});

test('String', () async {
final response = await dio.get<String>('/get');
expect(response.data, isA<String>());
expect(response.data, isNotEmpty);
});

test('List', () async {
final response = await dio.post<List>(
'/payload',
data: '[1,2,3]',
);
expect(response.data, isA<List>());
expect(response.data, isNotEmpty);
expect(response.data![0], 1);
});
});
});
}
Loading

0 comments on commit 076b141

Please sign in to comment.