blob: 3bed931e95640767b398eb977439b41d5f795d95 [file] [log] [blame]
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
import 'dart:io';
import 'package:cupertino_http/cupertino_http.dart';
import 'package:integration_test/integration_test.dart';
import 'package:test/test.dart';
void testDataTaskWithCompletionHandler(URLSession session) {
group('dataTaskWithCompletionHandler', () {
late HttpServer successServer;
late HttpServer failureServer;
late HttpServer redirectServer;
setUp(() async {
successServer = (await HttpServer.bind('localhost', 0))
..listen((request) async {
await request.drain<void>();
request.response.headers.set('Content-Type', 'text/plain');
request.response.write('Hello World');
await request.response.close();
});
failureServer = (await HttpServer.bind('localhost', 0))
..listen((request) async {
await request.drain<void>();
request.response.statusCode = 500;
request.response.headers.set('Content-Type', 'text/plain');
request.response.write('Hello World');
await request.response.close();
});
// URI | Redirects TO
// ===========|==============
// ".../10" | ".../9"
// ".../9" | ".../8"
// ... | ...
// ".../1" | "/"
// "/" | <no redirect>
redirectServer = await HttpServer.bind('localhost', 0)
..listen((request) async {
if (request.requestedUri.pathSegments.isEmpty) {
unawaited(request.response.close());
} else {
final n = int.parse(request.requestedUri.pathSegments.last);
final nextPath = n - 1 == 0 ? '' : '${n - 1}';
unawaited(request.response.redirect(Uri.parse(
'http://localhost:${redirectServer.port}/$nextPath')));
}
});
});
tearDown(() {
successServer.close();
failureServer.close();
redirectServer.close();
});
test('success', () async {
final c = Completer<void>();
Data? data;
HTTPURLResponse? response;
Error? error;
session.dataTaskWithCompletionHandler(
URLRequest.fromUrl(
Uri.parse('http://localhost:${successServer.port}')), (d, r, e) {
data = d;
response = r;
error = e;
c.complete();
}).resume();
await c.future;
expect(data!.bytes, 'Hello World'.codeUnits);
expect(response!.statusCode, 200);
expect(error, null);
});
test('success no data', () async {
final c = Completer<void>();
Data? data;
HTTPURLResponse? response;
Error? error;
final request = MutableURLRequest.fromUrl(
Uri.parse('http://localhost:${successServer.port}'))
..httpMethod = 'HEAD';
session.dataTaskWithCompletionHandler(request, (d, r, e) {
data = d;
response = r;
error = e;
c.complete();
}).resume();
await c.future;
expect(data, null);
expect(response!.statusCode, 200);
expect(error, null);
});
test('500 response', () async {
final c = Completer<void>();
Data? data;
HTTPURLResponse? response;
Error? error;
session.dataTaskWithCompletionHandler(
URLRequest.fromUrl(
Uri.parse('http://localhost:${failureServer.port}')), (d, r, e) {
data = d;
response = r;
error = e;
c.complete();
}).resume();
await c.future;
expect(data!.bytes, 'Hello World'.codeUnits);
expect(response!.statusCode, 500);
expect(error, null);
});
test('too many redirects', () async {
// Ensures that the delegate used to implement the completion handler
// does not interfere with the default redirect behavior.
final c = Completer<void>();
Data? data;
HTTPURLResponse? response;
Error? error;
session.dataTaskWithCompletionHandler(
URLRequest.fromUrl(
Uri.parse('http://localhost:${redirectServer.port}/100')),
(d, r, e) {
data = d;
response = r;
error = e;
c.complete();
}).resume();
await c.future;
expect(response, null);
expect(data, null);
expect(error!.code, -1007); // kCFURLErrorHTTPTooManyRedirects
});
test('unable to connect', () async {
final c = Completer<void>();
Data? data;
HTTPURLResponse? response;
Error? error;
session.dataTaskWithCompletionHandler(
URLRequest.fromUrl(Uri.parse('http://this is not a valid URL')),
(d, r, e) {
data = d;
response = r;
error = e;
c.complete();
}).resume();
await c.future;
expect(data, null);
expect(response, null);
expect(error!.code, -1003); // kCFURLErrorCannotFindHost
expect(error!.localizedRecoverySuggestion, null);
});
});
}
void testURLSession(URLSession session) {
group('URLSession', () {
late HttpServer server;
setUp(() async {
server = (await HttpServer.bind('localhost', 0))
..listen((request) async {
await request.drain<void>();
request.response.headers.set('Content-Type', 'text/plain');
request.response.write('Hello World');
await request.response.close();
});
});
tearDown(() {
server.close();
});
test('sessionDescription', () async {
session.sessionDescription = null;
expect(session.sessionDescription, null);
session.sessionDescription = 'Happy Days!';
expect(session.sessionDescription, 'Happy Days!');
});
test('dataTask', () async {
final task = session.dataTaskWithRequest(
URLRequest.fromUrl(Uri.parse('http://localhost:${server.port}')))
..resume();
while (task.state != URLSessionTaskState.urlSessionTaskStateCompleted) {
// Let the event loop run.
await Future<void>.delayed(const Duration());
}
final response = task.response as HTTPURLResponse;
expect(response.statusCode, 200);
});
test('downloadTask', () async {
final task = session.downloadTaskWithRequest(
URLRequest.fromUrl(Uri.parse('http://localhost:${server.port}')))
..resume();
while (task.state != URLSessionTaskState.urlSessionTaskStateCompleted) {
// Let the event loop run.
await Future<void>.delayed(const Duration());
}
final response = task.response as HTTPURLResponse;
expect(response.statusCode, 200);
});
testDataTaskWithCompletionHandler(session);
});
}
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
group('sharedSession', () {
final session = URLSession.sharedSession();
test('configuration', () {
expect(session.configuration, isA<URLSessionConfiguration>());
});
testURLSession(session);
});
group('defaultSessionConfiguration', () {
final config = URLSessionConfiguration.defaultSessionConfiguration()
..allowsCellularAccess = false;
final session = URLSession.sessionWithConfiguration(config);
test('configuration', () {
expect(session.configuration.allowsCellularAccess, false);
});
testURLSession(session);
});
group('backgroundSession', () {
final config =
URLSessionConfiguration.backgroundSession('backgroundSession')
..allowsCellularAccess = false;
final session = URLSession.sessionWithConfiguration(config);
test('configuration', () {
expect(session.configuration.allowsCellularAccess, false);
});
testURLSession(session);
});
}