mirror of
https://github.com/block/buzz.git
synced 2026-10-30 22:11:36 +00:00
fix(mobile): accept UUIDv5 push channel targets
Signed-off-by: Tom Brow <tomb@block.xyz>
This commit is contained in:
@@ -56,7 +56,6 @@ public struct BuzzPushNavigationTarget: Codable, Equatable, Sendable {
|
||||
let bytes = Array(value.utf8)
|
||||
guard bytes.count == 36,
|
||||
bytes[8] == 45, bytes[13] == 45, bytes[18] == 45, bytes[23] == 45,
|
||||
bytes[14] == 52,
|
||||
[56, 57, 97, 98].contains(bytes[19])
|
||||
else { return false }
|
||||
return bytes.enumerated().allSatisfy { index, byte in
|
||||
|
||||
@@ -3,7 +3,7 @@ import Testing
|
||||
|
||||
@testable import BuzzPushKit
|
||||
|
||||
@Test func `Round-trip navigation target through notification user info`() {
|
||||
@Test func `Round-trip UUIDv4 navigation target through notification user info`() {
|
||||
let target = BuzzPushNavigationTarget(
|
||||
eventID: String(repeating: "A", count: 64),
|
||||
communityID: "community-id",
|
||||
@@ -19,7 +19,22 @@ import Testing
|
||||
#expect(target.channelID == "123e4567-e89b-42d3-a456-426614174000")
|
||||
}
|
||||
|
||||
@Test func `Reject incomplete navigation target`() {
|
||||
@Test func `Decode UUIDv5 navigation target`() {
|
||||
let target = BuzzPushNavigationTarget(
|
||||
eventID: String(repeating: "B", count: 64),
|
||||
communityID: "community-id",
|
||||
channelID: "9A1657AC-F7AA-5DB0-B632-D8BBEB6DFB50"
|
||||
)
|
||||
|
||||
#expect(
|
||||
BuzzPushNavigationTarget.decodeIfPresent(
|
||||
from: [BuzzPushNavigationTarget.userInfoKey: target.userInfoValue]
|
||||
) == target
|
||||
)
|
||||
#expect(target.channelID == "9a1657ac-f7aa-5db0-b632-d8bbeb6dfb50")
|
||||
}
|
||||
|
||||
@Test func `Reject incomplete or malformed navigation target`() {
|
||||
#expect(
|
||||
BuzzPushNavigationTarget.decodeIfPresent(
|
||||
from: [
|
||||
@@ -42,6 +57,18 @@ import Testing
|
||||
]
|
||||
) == nil
|
||||
)
|
||||
|
||||
#expect(
|
||||
BuzzPushNavigationTarget.decodeIfPresent(
|
||||
from: [
|
||||
BuzzPushNavigationTarget.userInfoKey: [
|
||||
"event_id": String(repeating: "a", count: 64),
|
||||
"community_id": "community-id",
|
||||
"channel_id": "9a1657ac-f7aa-5db0-7632-d8bbeb6dfb50",
|
||||
]
|
||||
]
|
||||
) == nil
|
||||
)
|
||||
}
|
||||
|
||||
@Test func `Buffer preserves cold-start target until consumed`() {
|
||||
|
||||
@@ -26,7 +26,7 @@ final pendingPushNotificationLink = ValueNotifier<MessageDeepLink?>(null);
|
||||
|
||||
final _pushEventIdPattern = RegExp(r'^[0-9a-f]{64}$');
|
||||
final _pushChannelIdPattern = RegExp(
|
||||
r'^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$',
|
||||
r'^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$',
|
||||
);
|
||||
|
||||
MessageDeepLink? _pushNotificationLink(Object? arguments) {
|
||||
|
||||
@@ -150,7 +150,7 @@ void main() {
|
||||
expect(apnsRegistrationError.value, 'denied');
|
||||
});
|
||||
|
||||
test('turns a warm notification response into a message link', () async {
|
||||
test('routes a warm notification response with a UUIDv4 channel', () async {
|
||||
final response = Completer<ByteData?>();
|
||||
await TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
||||
.handlePlatformMessage(
|
||||
@@ -178,6 +178,58 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
test('routes a warm notification response with a UUIDv5 channel', () async {
|
||||
final response = Completer<ByteData?>();
|
||||
await TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
||||
.handlePlatformMessage(
|
||||
_channel.name,
|
||||
_channel.codec.encodeMethodCall(
|
||||
MethodCall('notificationOpened', {
|
||||
'eventId': 'b' * 64,
|
||||
'communityId': 'community-id',
|
||||
'channelId': '9A1657AC-F7AA-5DB0-B632-D8BBEB6DFB50',
|
||||
}),
|
||||
),
|
||||
response.complete,
|
||||
);
|
||||
|
||||
final envelope = await response.future;
|
||||
expect(envelope, isNotNull);
|
||||
expect(_channel.codec.decodeEnvelope(envelope!), 'handled');
|
||||
expect(
|
||||
pendingPushNotificationLink.value,
|
||||
MessageDeepLink(
|
||||
communityId: 'community-id',
|
||||
channelId: '9a1657ac-f7aa-5db0-b632-d8bbeb6dfb50',
|
||||
messageId: 'b' * 64,
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
test(
|
||||
'rejects a notification response with a malformed channel UUID',
|
||||
() async {
|
||||
final response = Completer<ByteData?>();
|
||||
await TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
||||
.handlePlatformMessage(
|
||||
_channel.name,
|
||||
_channel.codec.encodeMethodCall(
|
||||
MethodCall('notificationOpened', {
|
||||
'eventId': 'c' * 64,
|
||||
'communityId': 'community-id',
|
||||
'channelId': '9a1657ac-f7aa-5db0-7632-d8bbeb6dfb50',
|
||||
}),
|
||||
),
|
||||
response.complete,
|
||||
);
|
||||
|
||||
final envelope = await response.future;
|
||||
expect(envelope, isNotNull);
|
||||
expect(_channel.codec.decodeEnvelope(envelope!), 'ignored');
|
||||
expect(pendingPushNotificationLink.value, isNull);
|
||||
},
|
||||
);
|
||||
|
||||
test('pulls a cold-start notification response from native iOS', () async {
|
||||
debugDefaultTargetPlatformOverride = TargetPlatform.iOS;
|
||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
||||
|
||||
Reference in New Issue
Block a user