Skip to content

Commit ce5d99a

Browse files
wip: mock server
1 parent a427124 commit ce5d99a

File tree

2 files changed

+120
-0
lines changed

2 files changed

+120
-0
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import 'dart:async';
2+
import 'dart:convert';
3+
4+
import 'package:http/http.dart' as http;
5+
import 'package:test/test.dart';
6+
7+
import 'server/sync_server/mock_sync_server.dart';
8+
9+
void main() {
10+
late TestHttpServerHelper testServer;
11+
12+
setUp(() async {
13+
testServer = TestHttpServerHelper();
14+
await testServer.start();
15+
});
16+
17+
tearDown(() async {
18+
await testServer.stop();
19+
});
20+
21+
test('should receive events from the sync stream without waiting for close',
22+
() async {
23+
final client = http.Client();
24+
final request =
25+
http.Request('POST', testServer.uri.replace(path: '/sync/stream'));
26+
request.headers['Content-Type'] = 'application/json';
27+
28+
// Send the request and get the response stream
29+
final responseStream = await client.send(request);
30+
31+
final expectedEvents = ['event1', 'event2', 'event3'];
32+
final receivedEvents = <String>[];
33+
final completer = Completer<void>();
34+
35+
// Listen to the response stream for real-time processing of incoming events
36+
final subscription = responseStream.stream
37+
.transform(utf8.decoder)
38+
.transform(LineSplitter())
39+
.listen(
40+
(event) {
41+
receivedEvents.add(event);
42+
if (receivedEvents.length == expectedEvents.length) {
43+
completer.complete(); // Complete once all events are received
44+
}
45+
},
46+
onError: (e) => completer.completeError(e),
47+
);
48+
49+
// Programmatically trigger events on the server
50+
for (final event in expectedEvents) {
51+
testServer.addEvent('$event\n');
52+
await Future.delayed(
53+
Duration(milliseconds: 100)); // Small delay for each event
54+
}
55+
56+
// Wait for the events to be received
57+
await completer.future.timeout(Duration(seconds: 5));
58+
await subscription.cancel();
59+
client.close();
60+
61+
expect(receivedEvents.toSet().containsAll(expectedEvents.toSet()), isTrue);
62+
});
63+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import 'dart:async';
2+
import 'dart:convert';
3+
import 'dart:io';
4+
5+
import 'package:shelf/shelf.dart';
6+
import 'package:shelf/shelf_io.dart' as io;
7+
import 'package:shelf_router/shelf_router.dart';
8+
9+
class TestHttpServerHelper {
10+
final StreamController<String> _controller = StreamController<String>();
11+
late HttpServer _server;
12+
// late Timer _timer;
13+
14+
Uri get uri => Uri.parse('http://localhost:${_server.port}');
15+
16+
// Start the HTTP server
17+
Future<void> start() async {
18+
final router = Router()
19+
..post('/sync/stream', (Request request) async {
20+
// Respond immediately with a stream
21+
return Response.ok(_controller.stream.transform(utf8.encoder),
22+
headers: {
23+
'Content-Type': 'text/event-stream',
24+
'Cache-Control': 'no-cache',
25+
'Connection': 'keep-alive',
26+
'Transfer-Encoding': 'identity', // Use chunked transfer encoding
27+
},
28+
context: {
29+
"shelf.io.buffer_output": false
30+
});
31+
});
32+
33+
// Sending a newline gets the stream going and resolving on the client side
34+
_controller.add("\n");
35+
36+
// // Add data. The mock stream does not seem to resolve without data
37+
// _timer = Timer.periodic(Duration(seconds: 1), (Timer timer) {
38+
// // This code will execute every second
39+
// _controller.add('{ "token_expires_in": 3600}\n');
40+
// });
41+
42+
_server = await io.serve(router, 'localhost', 0);
43+
print('Test server running at ${_server.address}:${_server.port}');
44+
}
45+
46+
// Programmatically add data to the stream
47+
void addEvent(String data) {
48+
_controller.add(data);
49+
}
50+
51+
// Stop the HTTP server
52+
Future<void> stop() async {
53+
// _timer.cancel();
54+
await _controller.close();
55+
await _server.close();
56+
}
57+
}

0 commit comments

Comments
 (0)