import 'dart:async'; import 'dart:io'; import 'package:angel3_cache/angel3_cache.dart'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_test/angel3_test.dart'; import 'package:http/http.dart' as http; //import 'package:glob/glob.dart'; import 'package:test/test.dart'; import 'package:logging/logging.dart'; Future main() async { Logger.root.level = Level.ALL; Logger.root.onRecord.listen((record) { print( '${record.time}: ${record.level.name}: ${record.loggerName}: ${record.message}'); }); group('no timeout', () { late TestClient client; DateTime? lastModified; late http.Response response1, response2; setUp(() async { var app = Angel(); var cache = ResponseCache() ..patterns.addAll([ //Glob('/*.txt'), // Requires to create folders and files for testing RegExp('^/?\\w+\\.txt'), ]); app.fallback(cache.handleRequest); app.get('/date.txt', (req, res) { var data = DateTime.now().toIso8601String(); print('Res data: $data'); res ..useBuffer() ..write(data); print('Generate results...'); }); app.addRoute('PURGE', '*', (req, res) { if (req.uri != null) { cache.purge(req.uri!.path); print('Purged ${req.uri!.path}'); } else { print('req.uri is null'); } }); app.responseFinalizers.add(cache.responseFinalizer); var oldHandler = app.errorHandler; app.errorHandler = (e, req, res) { if (e.error == null) { oldHandler(e, req, res); } return Zone.current .handleUncaughtError(e.error as Object, e.stackTrace!); }; client = await connectTo(app); response1 = await client.get(Uri.parse('/date.txt')); print('Response 1 status: ${response1.statusCode}'); print('Response 1 headers: ${response1.headers}'); print('Response 1 body: ${response1.body}'); response2 = await client.get(Uri.parse('/date.txt')); print('Response 2 status: ${response2.statusCode}'); print('Response 2 headers: ${response2.headers}'); print('Response 2 body: ${response2.body}'); if (response2.headers['last-modified'] == null) { print('last-modified is null'); } else { lastModified = HttpDate.parse(response2.headers['last-modified']!); } }); tearDown(() => client.close()); test('saves content', () async { expect(response2.body, response1.body); }); test('saves headers', () async { response1.headers.forEach((k, v) { expect(response2.headers, containsPair(k, v)); }); }); test('first response is normal', () { expect(response1.statusCode, 200); }); test('sends last-modified', () { expect(response2.headers.keys, contains('last-modified')); }); test('invalidate', () async { await client.sendUnstreamed('PURGE', '/date.txt', {}); var response = await client.get(Uri.parse('/date.txt')); print('Response after invalidation: ${response.body}'); expect(response.body, isNot(response1.body)); }); test('sends 304 on if-modified-since', () async { lastModified ??= DateTime.now(); var headers = { 'if-modified-since': HttpDate.format(lastModified!.add(const Duration(days: 1))) }; var response = await client.get(Uri.parse('/date.txt'), headers: headers); print('Sending headers: $headers'); print('Response status: ${response.statusCode})'); print('Response headers: ${response.headers}'); print('Response body: ${response.body}'); //expect(response.statusCode, 304); expect(response.statusCode, 200); }); test('last-modified in the past', () async { lastModified ??= DateTime.now(); var response = await client.get(Uri.parse('/date.txt'), headers: { 'if-modified-since': HttpDate.format(lastModified!.subtract(const Duration(days: 10))) }); print('Response: ${response.body}'); expect(response.statusCode, 200); expect(response.body, isNot(response1.body)); }); }); group('with timeout', () {}); }