125 lines
4.0 KiB
Dart
125 lines
4.0 KiB
Dart
import 'dart:async';
|
|
import 'dart:convert';
|
|
import 'dart:io';
|
|
import 'package:wrnexus_inbox/src/client.dart';
|
|
import 'package:wrnexus_inbox/src/models.dart';
|
|
|
|
Future<void> main() async {
|
|
final server = await HttpServer.bind(InternetAddress.loopbackIPv4, 0);
|
|
var tokens = 0, streams = 0;
|
|
final calls = <String>[];
|
|
final bodies = <Json>[];
|
|
final serving = server.listen((request) async {
|
|
calls.add('${request.method} ${request.uri}');
|
|
if (request.headers.value('authorization') !=
|
|
'Bearer recipient-${calls.length}') {
|
|
throw StateError('Recipient authorization/refresh mismatch');
|
|
}
|
|
if (request.uri.path.endsWith('stream')) {
|
|
streams++;
|
|
if (streams == 3) {
|
|
request.response.statusCode = 401;
|
|
request.response.write(
|
|
'{"error":{"code":"recipient-token-invalid","message":"Expired"}}',
|
|
);
|
|
} else {
|
|
request.response.headers.contentType = ContentType(
|
|
'text',
|
|
'event-stream',
|
|
);
|
|
request.response.write(
|
|
'event: inbox\r\ndata: {"messages":[],"unreadCount":$streams}\r\n\r\n',
|
|
);
|
|
}
|
|
} else if (request.method == 'POST') {
|
|
final body = jsonDecode(await utf8.decoder.bind(request).join()) as Json;
|
|
bodies.add(body);
|
|
request.response.write(
|
|
'{"ok":true,"id":"d","revision":2,"replayed":false}',
|
|
);
|
|
} else if (request.uri.path.endsWith('preferences')) {
|
|
request.response.write(
|
|
'{"branding":{"displayName":"HTTP fixture"},"deliveryRules":{"timezone":"UTC","quietHours":null,"marketingDailyLimit":null},"preferences":[],"channelPreferences":[]}',
|
|
);
|
|
} else if (request.uri.path.endsWith('devices')) {
|
|
request.response.write(
|
|
'{"devices":[],"mobileDevices":[],"connections":[],"mobileConnections":[]}',
|
|
);
|
|
} else {
|
|
request.response.write('{"messages":[],"unreadCount":4}');
|
|
}
|
|
await request.response.close();
|
|
});
|
|
final client = InboxClient(
|
|
endpoint: Uri.parse('http://127.0.0.1:${server.port}'),
|
|
token: () => 'recipient-${++tokens}',
|
|
);
|
|
void require(bool value, String message) {
|
|
if (!value) throw StateError(message);
|
|
}
|
|
|
|
try {
|
|
require((await client.messages(limit: 20)).unreadCount == 4, 'Snapshot');
|
|
await client.markRead('m');
|
|
await client.archive('m');
|
|
await client.preferences();
|
|
await client.devices();
|
|
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.ios,
|
|
token: 'rotated',
|
|
marketingConsent: false,
|
|
),
|
|
);
|
|
await client.unregisterMobilePush('d');
|
|
await client.unregisterWebPush('w');
|
|
final received = <int>[];
|
|
try {
|
|
await for (final snapshot in client.updates()) {
|
|
received.add(snapshot.unreadCount);
|
|
}
|
|
} on InboxException catch (error) {
|
|
require(error.status == 401, 'Expected terminal auth error');
|
|
}
|
|
require(received.join(',') == '1,2', 'CRLF frames/reconnect');
|
|
require(streams == 3, 'Terminal authentication must stop retries');
|
|
require(calls.first == 'GET /api/v1/inbox/messages?limit=20', 'Query');
|
|
require(
|
|
bodies[0]['action'] == 'read' && bodies[1]['action'] == 'archive',
|
|
'Writes',
|
|
);
|
|
require(
|
|
(bodies[2]['deliveryRules'] as Json).containsKey('quietHours'),
|
|
'Explicit nullable setting',
|
|
);
|
|
require(
|
|
bodies[3]['installationId'] == 'i' && bodies[3]['token'] == 'rotated',
|
|
'Rotation',
|
|
);
|
|
stdout.writeln(
|
|
jsonEncode({
|
|
'localHttpChecks': 'passed',
|
|
'requests': calls.length,
|
|
'streamSnapshots': received,
|
|
'authorizationRefresh': true,
|
|
'providerSendsSubmitted': false,
|
|
}),
|
|
);
|
|
} finally {
|
|
client.close();
|
|
await serving.cancel();
|
|
await server.close(force: true);
|
|
}
|
|
}
|