2018-07-09 17:20:14 +00:00
|
|
|
import 'package:angel_framework/angel_framework.dart';
|
|
|
|
import 'package:angel_seo/angel_seo.dart';
|
|
|
|
import 'package:angel_static/angel_static.dart';
|
|
|
|
import 'package:angel_test/angel_test.dart';
|
|
|
|
import 'package:file/file.dart';
|
|
|
|
import 'package:file/memory.dart';
|
|
|
|
import 'package:html/dom.dart' as html;
|
|
|
|
import 'package:html/parser.dart' as html;
|
2018-11-08 16:17:44 +00:00
|
|
|
import 'package:http_parser/http_parser.dart';
|
|
|
|
import 'package:logging/logging.dart';
|
2018-07-09 17:20:14 +00:00
|
|
|
import 'package:test/test.dart';
|
|
|
|
|
|
|
|
void main() {
|
|
|
|
group('inlineAssets', () {
|
|
|
|
group('buffer', inlineAssetsTests((app, dir) {
|
2018-11-08 16:17:44 +00:00
|
|
|
app.get('/', (req, res) async {
|
2018-07-09 17:20:14 +00:00
|
|
|
var indexHtml = dir.childFile('index.html');
|
2018-11-08 16:17:44 +00:00
|
|
|
var contents = await indexHtml.readAsBytes();
|
2018-07-09 17:20:14 +00:00
|
|
|
res
|
2018-11-08 16:17:44 +00:00
|
|
|
..useBuffer()
|
2021-02-21 02:47:23 +00:00
|
|
|
..contentType = MediaType.parse('text/html; charset=utf-8')
|
2021-06-20 12:37:20 +00:00
|
|
|
..buffer!.add(contents);
|
2018-07-09 17:20:14 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
app.responseFinalizers.add(inlineAssets(dir));
|
|
|
|
}));
|
|
|
|
|
|
|
|
group('virtual_directory', inlineAssetsTests((app, dir) {
|
|
|
|
var vDir = inlineAssetsFromVirtualDirectory(
|
2021-02-21 02:47:23 +00:00
|
|
|
VirtualDirectory(app, dir.fileSystem, source: dir));
|
2018-11-08 16:17:44 +00:00
|
|
|
app.fallback(vDir.handleRequest);
|
2018-07-09 17:20:14 +00:00
|
|
|
}));
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-07-09 17:23:12 +00:00
|
|
|
/// Typedef for backwards-compatibility with Dart 1.
|
2021-06-20 12:37:20 +00:00
|
|
|
typedef InlineAssetTest = void Function(Angel app, Directory dir);
|
2018-07-09 17:23:12 +00:00
|
|
|
|
|
|
|
void Function() inlineAssetsTests(InlineAssetTest f) {
|
2018-07-09 17:20:14 +00:00
|
|
|
return () {
|
2021-06-20 12:37:20 +00:00
|
|
|
late TestClient client;
|
2018-07-09 17:20:14 +00:00
|
|
|
|
|
|
|
setUp(() async {
|
2021-02-21 02:47:23 +00:00
|
|
|
var app = Angel();
|
|
|
|
var fs = MemoryFileSystem();
|
2018-07-09 17:20:14 +00:00
|
|
|
var dir = fs.currentDirectory;
|
|
|
|
f(app, dir);
|
|
|
|
client = await connectTo(app);
|
|
|
|
|
|
|
|
for (var path in contents.keys) {
|
|
|
|
var file = fs.file(path);
|
2021-06-20 12:37:20 +00:00
|
|
|
await file.writeAsString(contents[path]!.trim());
|
2018-07-09 17:20:14 +00:00
|
|
|
}
|
2018-11-08 16:17:44 +00:00
|
|
|
|
2021-02-21 02:47:23 +00:00
|
|
|
app.logger = Logger('angel_seo')
|
2018-11-08 16:17:44 +00:00
|
|
|
..onRecord.listen((rec) {
|
|
|
|
print(rec);
|
|
|
|
if (rec.error != null) print(rec.error);
|
|
|
|
if (rec.stackTrace != null) print(rec.stackTrace);
|
|
|
|
});
|
2018-07-09 17:20:14 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
tearDown(() => client.close());
|
|
|
|
|
|
|
|
group('sends html', () {
|
2021-06-20 12:37:20 +00:00
|
|
|
late html.Document doc;
|
2018-07-09 17:20:14 +00:00
|
|
|
|
|
|
|
setUp(() async {
|
2021-06-20 12:37:20 +00:00
|
|
|
var res =
|
|
|
|
await client.get(Uri.parse('/'), headers: {'accept': 'text/html'});
|
2018-11-08 16:17:44 +00:00
|
|
|
print(res.body);
|
2018-07-09 17:20:14 +00:00
|
|
|
doc = html.parse(res.body);
|
|
|
|
});
|
|
|
|
|
|
|
|
group('stylesheets', () {
|
|
|
|
test('replaces <link> with <style>', () {
|
|
|
|
expect(doc.querySelectorAll('link'), hasLength(1));
|
|
|
|
});
|
|
|
|
|
|
|
|
test('populates a <style>', () {
|
|
|
|
var style = doc.querySelector('style');
|
2021-06-20 12:37:20 +00:00
|
|
|
expect(style?.innerHtml.trim(), contents['site.css']);
|
2018-07-09 17:20:14 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
test('heeds data-no-inline', () {
|
2021-06-20 12:37:20 +00:00
|
|
|
var link = doc.querySelector('link')!;
|
2018-07-09 17:20:14 +00:00
|
|
|
expect(link.attributes, containsPair('rel', 'stylesheet'));
|
|
|
|
expect(link.attributes, containsPair('href', 'not-inlined.css'));
|
|
|
|
expect(link.attributes.keys, isNot(contains('data-no-inline')));
|
|
|
|
});
|
|
|
|
|
|
|
|
test('preserves other attributes', () {
|
2021-06-20 12:37:20 +00:00
|
|
|
var link = doc.querySelector('link')!;
|
2018-07-09 17:20:14 +00:00
|
|
|
expect(link.attributes, containsPair('data-foo', 'bar'));
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
group('scripts', () {
|
|
|
|
test('does not replace <script> with anything', () {
|
|
|
|
expect(doc.querySelectorAll('script'), hasLength(2));
|
|
|
|
});
|
|
|
|
|
|
|
|
test('populates innerHtml', () {
|
|
|
|
var script0 = doc.querySelectorAll('script')[0];
|
|
|
|
expect(script0.innerHtml.trim(), contents['site.js']);
|
|
|
|
});
|
|
|
|
|
|
|
|
test('heeds data-no-inline', () {
|
|
|
|
var script1 = doc.querySelectorAll('script')[1];
|
|
|
|
expect(script1.attributes, containsPair('src', 'not-inlined.js'));
|
|
|
|
expect(script1.attributes.keys, isNot(contains('data-no-inline')));
|
|
|
|
});
|
|
|
|
|
|
|
|
test('preserves other attributes', () {
|
|
|
|
var script0 = doc.querySelectorAll('script')[0];
|
|
|
|
var script1 = doc.querySelectorAll('script')[1];
|
|
|
|
expect(script0.attributes, containsPair('data-foo', 'bar'));
|
|
|
|
expect(script1.attributes, containsPair('type', 'text/javascript'));
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
var contents = <String, String>{
|
|
|
|
'index.html': '''<!doctype html>
|
|
|
|
<html lang="en">
|
|
|
|
<head>
|
|
|
|
<meta charset="UTF-8">
|
|
|
|
<meta name="viewport"
|
|
|
|
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
|
|
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
|
|
|
<link rel="stylesheet" href="site.css">
|
|
|
|
<link data-foo="bar" rel="stylesheet" href="not-inlined.css" data-no-inline>
|
|
|
|
<script data-foo="bar" src="site.js"></script>
|
|
|
|
<script type="text/javascript" src="not-inlined.js" data-no-inline></script>
|
|
|
|
<title>Angel SEO</title>
|
|
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<h1>Angel SEO</h1>
|
|
|
|
<p>Embrace the power of inlined styles, etc.</p>
|
|
|
|
</body>
|
|
|
|
</html>''',
|
|
|
|
'not-inlined.css': '''p {
|
|
|
|
font-style: italic;
|
|
|
|
}''',
|
|
|
|
'not-inlined.js': '''window.addEventListener('load', function() {
|
|
|
|
console.log('THIS message was not from an inlined file.');
|
|
|
|
});''',
|
|
|
|
'site.css': '''h1 {
|
|
|
|
color: pink;
|
|
|
|
}''',
|
|
|
|
'site.js': '''window.addEventListener('load', function() {
|
|
|
|
console.log('Hello, inline world!');
|
|
|
|
});'''
|
|
|
|
};
|