You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
221 lines
7.7 KiB
221 lines
7.7 KiB
2 years ago
|
import 'dart:async';
|
||
|
|
||
|
import 'package:nextcloud/nextcloud.dart';
|
||
|
import 'package:nextcloud_push_proxy/nextcloud_push_proxy.dart';
|
||
|
import 'package:test/test.dart';
|
||
|
|
||
|
import 'helper.dart';
|
||
|
|
||
|
Future main() async {
|
||
|
final dockerImageName = await TestHelper.prepareDockerImage();
|
||
|
|
||
|
group('notifications', () {
|
||
|
late TestNextcloudClient client;
|
||
|
setUp(() async {
|
||
|
client = await TestHelper.getPreparedClient(
|
||
|
dockerImageName,
|
||
|
username: 'admin',
|
||
|
);
|
||
|
});
|
||
|
tearDown(() => client.destroy());
|
||
|
|
||
|
Future sendTestNotification() async {
|
||
|
await validateResponse<EmptyResponse, void>(
|
||
|
client.notifications,
|
||
|
client.notifications.sendAdminNotificationWithHttpInfo(
|
||
|
'admin',
|
||
|
AdminNotification(
|
||
|
shortMessage: '123',
|
||
|
longMessage: '456',
|
||
|
),
|
||
|
),
|
||
|
);
|
||
|
}
|
||
|
|
||
|
test('Send admin notification', () async {
|
||
|
await sendTestNotification();
|
||
|
});
|
||
|
|
||
|
test('List notifications', () async {
|
||
|
await sendTestNotification();
|
||
|
|
||
|
final startTime = DateTime.now().toUtc();
|
||
|
final response = (await validateResponse<ListNotificationsResponse, void>(
|
||
|
client.notifications,
|
||
|
client.notifications.listNotificationsWithHttpInfo(),
|
||
|
))!;
|
||
|
expect(response.ocs!.data, hasLength(1));
|
||
|
expect(response.ocs!.data[0].notificationId, 1);
|
||
|
expect(response.ocs!.data[0].app, 'admin_notifications');
|
||
|
expect(response.ocs!.data[0].user, 'admin');
|
||
|
expectDateInReasonableTimeRange(DateTime.parse(response.ocs!.data[0].datetime!), startTime);
|
||
|
expect(response.ocs!.data[0].objectType, 'admin_notifications');
|
||
|
expect(response.ocs!.data[0].objectId, isNotNull);
|
||
|
expect(response.ocs!.data[0].subject, '123');
|
||
|
expect(response.ocs!.data[0].message, '456');
|
||
|
expect(response.ocs!.data[0].link, '');
|
||
|
expect(response.ocs!.data[0].subjectRich, '');
|
||
|
expect(response.ocs!.data[0].subjectRichParameters, hasLength(0));
|
||
|
expect(response.ocs!.data[0].messageRich, '');
|
||
|
expect(response.ocs!.data[0].messageRichParameters, hasLength(0));
|
||
|
expect(response.ocs!.data[0].icon, isNotEmpty);
|
||
|
expect(response.ocs!.data[0].actions, hasLength(0));
|
||
|
});
|
||
|
|
||
|
test('Get notification', () async {
|
||
|
await sendTestNotification();
|
||
|
|
||
|
final startTime = DateTime.now().toUtc();
|
||
|
final response = (await validateResponse<GetNotificationResponse, void>(
|
||
|
client.notifications,
|
||
|
client.notifications.getNotificationWithHttpInfo(1),
|
||
|
))!;
|
||
|
expect(response.ocs!.data!.notificationId, 1);
|
||
|
expect(response.ocs!.data!.app, 'admin_notifications');
|
||
|
expect(response.ocs!.data!.user, 'admin');
|
||
|
expectDateInReasonableTimeRange(DateTime.parse(response.ocs!.data!.datetime!), startTime);
|
||
|
expect(response.ocs!.data!.objectType, 'admin_notifications');
|
||
|
expect(response.ocs!.data!.objectId, isNotNull);
|
||
|
expect(response.ocs!.data!.subject, '123');
|
||
|
expect(response.ocs!.data!.message, '456');
|
||
|
expect(response.ocs!.data!.link, '');
|
||
|
expect(response.ocs!.data!.subjectRich, '');
|
||
|
expect(response.ocs!.data!.subjectRichParameters, hasLength(0));
|
||
|
expect(response.ocs!.data!.messageRich, '');
|
||
|
expect(response.ocs!.data!.messageRichParameters, hasLength(0));
|
||
|
expect(response.ocs!.data!.icon, isNotEmpty);
|
||
|
expect(response.ocs!.data!.actions, hasLength(0));
|
||
|
});
|
||
|
|
||
|
test('Delete notification', () async {
|
||
|
await sendTestNotification();
|
||
|
await validateResponse<EmptyResponse, void>(
|
||
|
client.notifications,
|
||
|
client.notifications.deleteNotificationWithHttpInfo(1),
|
||
|
);
|
||
|
|
||
|
final response = (await validateResponse<ListNotificationsResponse, void>(
|
||
|
client.notifications,
|
||
|
client.notifications.listNotificationsWithHttpInfo(),
|
||
|
))!;
|
||
|
expect(response.ocs!.data, hasLength(0));
|
||
|
});
|
||
|
|
||
|
test('Delete all notifications', () async {
|
||
|
await sendTestNotification();
|
||
|
await sendTestNotification();
|
||
|
await validateResponse<EmptyResponse, void>(
|
||
|
client.notifications,
|
||
|
client.notifications.deleteAllNotificationsWithHttpInfo(),
|
||
|
);
|
||
|
|
||
|
final response = (await validateResponse<ListNotificationsResponse, void>(
|
||
|
client.notifications,
|
||
|
client.notifications.listNotificationsWithHttpInfo(),
|
||
|
))!;
|
||
|
expect(response.ocs!.data, hasLength(0));
|
||
|
});
|
||
|
});
|
||
|
|
||
|
group('push notifications', () {
|
||
|
late TestNextcloudClient client;
|
||
|
setUp(() async {
|
||
|
client = await TestHelper.getPreparedClient(
|
||
|
dockerImageName,
|
||
|
username: 'admin',
|
||
|
// We need to use app passwords in order to register push devices
|
||
|
useAppPassword: true,
|
||
|
);
|
||
|
});
|
||
|
tearDown(() => client.destroy());
|
||
|
|
||
|
// The key size has to be 2048, other sizes are not accepted by Nextcloud (at the moment at least)
|
||
|
// ignore: avoid_redundant_argument_values
|
||
|
RSAKeypair generateKeypair() => RSAKeypair.fromRandom(keySize: 2048);
|
||
|
|
||
|
test('Register device and receive notification', () async {
|
||
|
const pushToken = '789';
|
||
|
final port = randomPort();
|
||
|
final keypair = generateKeypair();
|
||
|
|
||
|
final pushProxy = NextcloudPushProxy();
|
||
|
|
||
|
final subscription = (await client.notifications.registerDeviceAtServer(
|
||
|
pushToken,
|
||
|
keypair.publicKey,
|
||
|
'http://host.docker.internal:$port/',
|
||
|
))!
|
||
|
.ocs!
|
||
|
.data!;
|
||
|
expect(subscription.publicKey, hasLength(451));
|
||
|
RSAPublicKey.fromPEM(subscription.publicKey!);
|
||
|
expect(subscription.deviceIdentifier, isNotEmpty);
|
||
|
expect(subscription.signature, isNotEmpty);
|
||
|
|
||
|
final deviceCompleter = Completer();
|
||
|
final notificationCompleter = Completer();
|
||
|
|
||
|
await pushProxy.create(
|
||
|
logging: false,
|
||
|
port: port,
|
||
|
);
|
||
|
pushProxy.onNewDevice.listen((final device) async {
|
||
|
expect(device.pushToken, pushToken);
|
||
|
expect(device.deviceIdentifier, isNotEmpty);
|
||
|
expect(device.deviceIdentifierSignature, isNotEmpty);
|
||
|
expect(device.userPublicKey, isNotEmpty);
|
||
|
|
||
|
deviceCompleter.complete();
|
||
|
});
|
||
|
pushProxy.onNewNotification.listen((final notification) async {
|
||
|
expect(notification.deviceIdentifier, subscription.deviceIdentifier);
|
||
|
expect(notification.pushTokenHash, client.notifications.generatePushTokenHash(pushToken));
|
||
|
expect(notification.subject, isNotEmpty);
|
||
|
expect(notification.signature, isNotEmpty);
|
||
|
expect(notification.priority, 'normal');
|
||
|
expect(notification.type, 'alert');
|
||
|
|
||
|
final decryptedSubject =
|
||
|
client.notifications.decryptPushNotificationSubject(keypair.privateKey, notification.subject);
|
||
|
expect(decryptedSubject.nid, isNotNull);
|
||
|
expect(decryptedSubject.app, 'admin_notifications');
|
||
|
expect(decryptedSubject.subject, '123');
|
||
|
expect(decryptedSubject.type, 'admin_notifications');
|
||
|
expect(decryptedSubject.id, isNotEmpty);
|
||
|
|
||
|
notificationCompleter.complete();
|
||
|
});
|
||
|
|
||
|
await client.notifications.registerDeviceAtPushProxy(
|
||
|
pushToken,
|
||
|
subscription,
|
||
|
'http://localhost:$port/',
|
||
|
);
|
||
|
await client.notifications.sendAdminNotification(
|
||
|
'admin',
|
||
|
AdminNotification(
|
||
|
shortMessage: '123',
|
||
|
longMessage: '456',
|
||
|
),
|
||
|
);
|
||
|
|
||
|
await deviceCompleter.future;
|
||
|
await notificationCompleter.future;
|
||
|
await pushProxy.close();
|
||
|
});
|
||
|
|
||
|
test('Remove push device', () async {
|
||
|
await client.notifications.registerDeviceAtServer(
|
||
|
'789',
|
||
|
generateKeypair().publicKey,
|
||
|
'https://example.com/',
|
||
|
);
|
||
|
|
||
|
await validateResponse<EmptyResponse, void>(
|
||
|
client.notifications,
|
||
|
client.notifications.removeDeviceWithHttpInfo(),
|
||
|
);
|
||
|
});
|
||
|
});
|
||
|
}
|