130 lines
3.7 KiB
Dart
130 lines
3.7 KiB
Dart
|
|
import 'dart:async';
|
||
|
|
import 'dart:convert';
|
||
|
|
import 'dart:io';
|
||
|
|
|
||
|
|
import 'package:flutter_test/flutter_test.dart';
|
||
|
|
|
||
|
|
import 'fake_protocol_server.dart';
|
||
|
|
|
||
|
|
import 'package:mews/protocols/spartan.dart';
|
||
|
|
|
||
|
|
Uri open(String path, FakeSpartanServer server) =>
|
||
|
|
Uri.parse('spartan://localhost:${server.port}$path');
|
||
|
|
|
||
|
|
void main() {
|
||
|
|
late FakeSpartanServer server;
|
||
|
|
late StreamSubscription<Socket> answers;
|
||
|
|
final client = SpartanClient(timeout: const Duration(seconds: 5));
|
||
|
|
|
||
|
|
tearDown(() async {
|
||
|
|
await answers.cancel();
|
||
|
|
await server.close();
|
||
|
|
});
|
||
|
|
|
||
|
|
test('a success answers with status, meta and body', () async {
|
||
|
|
server = FakeSpartanServer();
|
||
|
|
await server.start();
|
||
|
|
var requested = '';
|
||
|
|
answers = server.answer((line, upload, socket) {
|
||
|
|
requested = line;
|
||
|
|
socket.add(utf8.encode('2 text/gemini\r\nhello'));
|
||
|
|
});
|
||
|
|
|
||
|
|
final response = await client.fetch(open('/page', server));
|
||
|
|
|
||
|
|
expect(response.status, 2);
|
||
|
|
expect(response.meta, 'text/gemini');
|
||
|
|
expect(utf8.decode(response.body!), 'hello');
|
||
|
|
expect(requested, 'localhost /page 0');
|
||
|
|
});
|
||
|
|
|
||
|
|
test('an upload rides behind the request line', () async {
|
||
|
|
server = FakeSpartanServer();
|
||
|
|
await server.start();
|
||
|
|
var requested = '';
|
||
|
|
var uploaded = '';
|
||
|
|
answers = server.answer((line, upload, socket) {
|
||
|
|
requested = line;
|
||
|
|
uploaded = utf8.decode(upload);
|
||
|
|
socket.add(utf8.encode('2 text/gemini\r\nok'));
|
||
|
|
});
|
||
|
|
|
||
|
|
final response =
|
||
|
|
await client.fetch(open('/echo', server), upload: utf8.encode('payload'));
|
||
|
|
|
||
|
|
expect(response.status, 2);
|
||
|
|
expect(requested, 'localhost /echo 7');
|
||
|
|
expect(uploaded, 'payload');
|
||
|
|
});
|
||
|
|
|
||
|
|
test('a query is part of the path', () async {
|
||
|
|
server = FakeSpartanServer();
|
||
|
|
await server.start();
|
||
|
|
var requested = '';
|
||
|
|
answers = server.answer((line, upload, socket) {
|
||
|
|
requested = line;
|
||
|
|
socket.add(utf8.encode('2 text/gemini\r\nok'));
|
||
|
|
});
|
||
|
|
|
||
|
|
await client.fetch(open('/search?q=phones', server));
|
||
|
|
|
||
|
|
expect(requested, 'localhost /search?q=phones 0');
|
||
|
|
});
|
||
|
|
|
||
|
|
test('a redirect is followed to the final address', () async {
|
||
|
|
server = FakeSpartanServer();
|
||
|
|
await server.start();
|
||
|
|
final requests = <String>[];
|
||
|
|
answers = server.answer((line, upload, socket) async {
|
||
|
|
requests.add(line);
|
||
|
|
if (line.contains('/here')) {
|
||
|
|
socket.add(utf8.encode('3 ${open('/there', server)}\r\n'));
|
||
|
|
} else {
|
||
|
|
socket.add(utf8.encode('2 text/gemini\r\narrived'));
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
final response = await client.fetch(open('/here', server));
|
||
|
|
|
||
|
|
expect(response.status, 2);
|
||
|
|
expect(utf8.decode(response.body!), 'arrived');
|
||
|
|
expect(response.url.path, '/there');
|
||
|
|
expect(requests, hasLength(2));
|
||
|
|
});
|
||
|
|
|
||
|
|
test('a redirect loop gives up after five hops', () async {
|
||
|
|
server = FakeSpartanServer();
|
||
|
|
await server.start();
|
||
|
|
final requests = <String>[];
|
||
|
|
answers = server.answer((line, upload, socket) async {
|
||
|
|
requests.add(line);
|
||
|
|
socket.add(utf8.encode('3 ${open('/loop', server)}\r\n'));
|
||
|
|
});
|
||
|
|
|
||
|
|
await expectLater(
|
||
|
|
client.fetch(open('/loop', server)),
|
||
|
|
throwsA(isA<SpartanTooManyRedirects>()),
|
||
|
|
);
|
||
|
|
expect(requests, hasLength(6));
|
||
|
|
});
|
||
|
|
|
||
|
|
test('an error status carries its message', () async {
|
||
|
|
server = FakeSpartanServer();
|
||
|
|
await server.start();
|
||
|
|
answers = server.answer((line, upload, socket) =>
|
||
|
|
socket.add(utf8.encode('4 Nothing lives here\r\n')));
|
||
|
|
|
||
|
|
final response = await client.fetch(open('/gone', server));
|
||
|
|
|
||
|
|
expect(response.status, 4);
|
||
|
|
expect(response.meta, 'Nothing lives here');
|
||
|
|
expect(response.body, isNull);
|
||
|
|
});
|
||
|
|
|
||
|
|
test('an unreachable host is one failure', () async {
|
||
|
|
final nowhere = Uri.parse('spartan://localhost:1/');
|
||
|
|
|
||
|
|
await expectLater(client.fetch(nowhere), throwsA(isA<SpartanException>()));
|
||
|
|
});
|
||
|
|
}
|