99 lines
3.5 KiB
Dart
99 lines
3.5 KiB
Dart
|
|
import 'package:flutter_test/flutter_test.dart';
|
||
|
|
|
||
|
|
import 'package:mews/application/pages/mews_urls.dart';
|
||
|
|
|
||
|
|
void main() {
|
||
|
|
group('isInternal', () {
|
||
|
|
test('recognizes the mews scheme only', () {
|
||
|
|
expect(MewsUrls.isInternal('mews:hub'), isTrue);
|
||
|
|
expect(MewsUrls.isInternal('mews:'), isTrue);
|
||
|
|
expect(MewsUrls.isInternal('https://example.test/'), isFalse);
|
||
|
|
expect(MewsUrls.isInternal('not a url at all'), isFalse);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
group('isAction', () {
|
||
|
|
test('accepts exactly one verb under do/', () {
|
||
|
|
expect(MewsUrls.isAction('mews:do/set-theme?value=dark'), isTrue);
|
||
|
|
expect(MewsUrls.isAction('mews:do/clear-history'), isTrue);
|
||
|
|
});
|
||
|
|
|
||
|
|
test('rejects pages, bare do and deeper paths', () {
|
||
|
|
expect(MewsUrls.isAction('mews:settings'), isFalse);
|
||
|
|
expect(MewsUrls.isAction('mews:do'), isFalse);
|
||
|
|
expect(MewsUrls.isAction('mews:do/a/b'), isFalse);
|
||
|
|
// A fetched page must not reach the dispatcher by mimicking the path.
|
||
|
|
expect(MewsUrls.isAction('https://example.test/do/clear-history'), isFalse);
|
||
|
|
});
|
||
|
|
|
||
|
|
test('verbOf reads the verb back', () {
|
||
|
|
expect(MewsUrls.verbOf('mews:do/set-size?step=up'), 'set-size');
|
||
|
|
expect(MewsUrls.verbOf('mews:settings'), isNull);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
group('canonical', () {
|
||
|
|
test('bare mews: is the hub', () {
|
||
|
|
expect(MewsUrls.canonical('mews:'), MewsUrls.hub);
|
||
|
|
});
|
||
|
|
|
||
|
|
test('keeps a query string and drops a fragment', () {
|
||
|
|
expect(MewsUrls.canonical('mews:bookmarks?tag=phones'),
|
||
|
|
'mews:bookmarks?tag=phones');
|
||
|
|
expect(MewsUrls.canonical('mews:settings#colors'), 'mews:settings');
|
||
|
|
});
|
||
|
|
|
||
|
|
test('leaves external addresses alone', () {
|
||
|
|
expect(MewsUrls.canonical('https://example.test/a?b=c'),
|
||
|
|
'https://example.test/a?b=c');
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
group('action', () {
|
||
|
|
test('builds an address the dispatcher accepts', () {
|
||
|
|
final url = MewsUrls.action('set-theme', {'value': 'dark'});
|
||
|
|
expect(url, 'mews:do/set-theme?value=dark');
|
||
|
|
expect(MewsUrls.isAction(url), isTrue);
|
||
|
|
});
|
||
|
|
|
||
|
|
test('round-trips a url carried inside the query string', () {
|
||
|
|
// Every per-item action names its target this way, so the inner address
|
||
|
|
// must survive encoding untouched.
|
||
|
|
const target = 'https://example.test/p?q=1&r=2';
|
||
|
|
final url = MewsUrls.action('remove-bookmark', {'url': target});
|
||
|
|
expect(Uri.parse(url).queryParameters['url'], target);
|
||
|
|
expect(MewsUrls.isAction(url), isTrue);
|
||
|
|
});
|
||
|
|
|
||
|
|
test('takes no query string when there are no arguments', () {
|
||
|
|
expect(MewsUrls.action('clear-history'), 'mews:do/clear-history');
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
group('page', () {
|
||
|
|
test('merges over the existing parameters', () {
|
||
|
|
final url = MewsUrls.page(Uri.parse('mews:bookmarks?tag=phones'),
|
||
|
|
{'q': 'retro'});
|
||
|
|
final params = Uri.parse(url).queryParameters;
|
||
|
|
expect(params, {'tag': 'phones', 'q': 'retro'});
|
||
|
|
});
|
||
|
|
|
||
|
|
test('an empty value drops the parameter', () {
|
||
|
|
final url =
|
||
|
|
MewsUrls.page(Uri.parse('mews:bookmarks?tag=phones&q=retro'), {'q': ''});
|
||
|
|
expect(Uri.parse(url).queryParameters, {'tag': 'phones'});
|
||
|
|
});
|
||
|
|
|
||
|
|
test('drops the query string once nothing is left', () {
|
||
|
|
final url = MewsUrls.page(Uri.parse('mews:bookmarks?q=retro'), {'q': ''});
|
||
|
|
expect(url, 'mews:bookmarks');
|
||
|
|
});
|
||
|
|
|
||
|
|
test('survives a value needing escapes', () {
|
||
|
|
final url = MewsUrls.page(Uri.parse(MewsUrls.bookmarks), {'q': 'a b&c=d'});
|
||
|
|
expect(Uri.parse(url).queryParameters['q'], 'a b&c=d');
|
||
|
|
expect(MewsUrls.canonical(url), url);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
}
|