Files

114 lines
3.6 KiB
Dart

import 'dart:convert';
import 'package:flutter_test/flutter_test.dart';
import 'package:http/http.dart' as http;
import 'package:http/testing.dart';
import 'package:wrnexus_inbox/wrnexus_inbox.dart';
void main() {
test(
'recipient transport, token refresh, writes and nullable delivery rules',
() async {
final calls = <http.Request>[];
var tokens = 0;
final client = InboxClient(
token: () => 'recipient-${++tokens}',
transport: MockClient((r) async {
calls.add(r);
if (r.method == 'GET') {
return http.Response('{"messages":[],"unreadCount":3}', 200);
}
return http.Response('{"id":"d","revision":2,"replayed":false}', 200);
}),
);
expect((await client.messages(limit: 20)).unreadCount, 3);
await client.markRead('m');
await client.archive('m');
await client.savePreferences(
const PreferenceInput(
category: '*',
inAppEnabled: true,
marketingEnabled: false,
deliveryRules: DeliveryRules(timezone: 'UTC'),
),
);
await client.registerMobilePush(
const MobileRegistration(
connectionId: 'c',
installationId: 'i',
name: 'Phone',
platform: MobilePlatform.android,
token: 'fcm',
marketingConsent: false,
),
);
await client.unregisterMobilePush('d');
await client.unregisterWebPush('w');
expect(
calls.map((r) => r.headers['authorization']),
List.generate(7, (i) => 'Bearer recipient-${i + 1}'),
);
expect(calls.first.url.path, '/api/v1/inbox/messages');
expect(calls.first.url.query, 'limit=20');
expect(jsonDecode(calls[1].body), {'id': 'm', 'action': 'read'});
expect((jsonDecode(calls[3].body) as Map)['deliveryRules'], {
'timezone': 'UTC',
'quietHours': null,
'marketingDailyLimit': null,
});
expect((jsonDecode(calls[4].body) as Map)['action'], 'register-mobile');
client.close();
await expectLater(
client.messages(),
throwsA(isA<InboxException>().having((e) => e.code, 'code', 'closed')),
);
},
);
test('API errors stop without retry', () async {
var calls = 0;
final client = InboxClient(
token: () => 'expired',
transport: MockClient((_) async {
calls++;
return http.Response(
'{"error":{"code":"expired-token","message":"Expired"}}',
401,
);
}),
);
await expectLater(
client.markRead('m'),
throwsA(
isA<InboxException>()
.having((e) => e.status, 'status', 401)
.having((e) => e.code, 'code', 'expired-token'),
),
);
expect(calls, 1);
client.close();
});
test('origin, actions and frame parsing', () {
for (final text in [
'http://example.com',
'https://u:p@example.com',
'https://example.com/a',
'https://example.com?q=x',
]) {
expect(
() => InboxClient(endpoint: Uri.parse(text), token: () => 'r'),
throwsA(isA<InboxException>()),
);
}
expect(InboxClient.safeActionUri('javascript:alert(1)'), isNull);
expect(InboxClient.safeActionUri('https://u:p@example.com'), isNull);
final parser = InboxEventParser();
expect(parser.line(': heartbeat'), isNull);
expect(parser.line(''), isNull);
parser.line('event: inbox');
parser.line('data: {"messages":[],"unreadCount":2}');
expect(parser.line('')!.unreadCount, 2);
parser.line('event: inbox');
parser.line('data: broken');
expect(() => parser.line(''), throwsFormatException);
});
}