Skip to content

Commit

Permalink
Convert bools to ints (#44)
Browse files Browse the repository at this point in the history
  • Loading branch information
rrousselGit authored Jul 15, 2024
1 parent dd8ef56 commit 8ae9e2a
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 24 deletions.
2 changes: 2 additions & 0 deletions packages/dart_firebase_admin/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
## Unreleased minor

- Fixes some errors incorrectly coming back as "unknown".
- `Apns` parameters are no-longer required
- Fixes argument error in FMC when sending booleans
- Renamed various error codes to remove duplicates and removed
unused codes.
- Fixes crash when updating users (thanks to @HeySreelal)
Expand Down
41 changes: 28 additions & 13 deletions packages/dart_firebase_admin/lib/src/messaging/messaging_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,22 @@ class WebpushNotificationAction {
'action': action,
'icon': icon,
'title': title,
};
}._cleanProto();
}
}

extension on Map<String, Object?> {
Map<String, Object?> _cleanProto() {
for (final entry in entries) {
switch (entry.value) {
case true:
this[entry.key] = 1;
case false:
this[entry.key] = 0;
}
}

return this;
}
}

Expand Down Expand Up @@ -368,7 +383,7 @@ class WebpushNotification {
'timestamp': timestamp,
'vibrate': vibrate,
if (customData case final customData?) ...customData,
};
}._cleanProto();
}
}

Expand Down Expand Up @@ -422,21 +437,21 @@ class ApnsPayload {
return {
'aps': aps._toProto(),
if (customData case final customData?) ...customData,
};
}._cleanProto();
}
}

/// Represents the [aps dictionary](https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/PayloadKeyReference.html)
/// that is part of APNs messages.
class Aps {
Aps({
required this.alert,
required this.badge,
required this.sound,
required this.contentAvailable,
required this.mutableContent,
required this.category,
required this.threadId,
this.alert,
this.badge,
this.sound,
this.contentAvailable,
this.mutableContent,
this.category,
this.threadId,
});

/// Alert to be included in the message. This may be a string or an object of
Expand Down Expand Up @@ -472,7 +487,7 @@ class Aps {
'mutable-content': mutableContent,
'category': category,
'thread-id': threadId,
};
}._cleanProto();
}
}

Expand Down Expand Up @@ -516,7 +531,7 @@ class ApsAlert {
'subtitle-loc-args': subtitleLocArgs,
'action-loc-key': actionLocKey,
'launch-image': launchImage,
};
}._cleanProto();
}
}

Expand All @@ -542,7 +557,7 @@ class CriticalSound {
'critical': critical,
'name': name,
'volume': volume,
};
}._cleanProto();
}
}

Expand Down
76 changes: 65 additions & 11 deletions packages/dart_firebase_admin/test/messaging/messaging_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import 'dart:convert';

import 'package:dart_firebase_admin/src/messaging.dart';
import 'package:firebaseapis/fcm/v1.dart' as fmc1;
import 'package:firebaseapis/fcm/v1.dart';
import 'package:http/http.dart';
import 'package:mocktail/mocktail.dart';
import 'package:test/test.dart';
Expand All @@ -11,15 +10,19 @@ import '../google_cloud_firestore/util/helpers.dart';
import '../mock.dart';

class ProjectsMessagesResourceMock extends Mock
implements ProjectsMessagesResource {}
implements fmc1.ProjectsMessagesResource {}

class FirebaseMessagingRequestHandlerMock extends Mock
implements FirebaseMessagingRequestHandler {}

class FirebaseCloudMessagingApiMock extends Mock
implements FirebaseCloudMessagingApi {}
implements fmc1.FirebaseCloudMessagingApi {}

class ProjectsResourceMock extends Mock implements ProjectsResource {}
class ProjectsResourceMock extends Mock implements fmc1.ProjectsResource {}

extension on Object? {
T cast<T>() => this as T;
}

void main() {
late Messaging messaging;
Expand Down Expand Up @@ -141,7 +144,7 @@ void main() {
..called(1);
verifyNoMoreInteractions(messages);

final request = capture.captured.first as SendMessageRequest;
final request = capture.captured.first as fmc1.SendMessageRequest;
final parent = capture.captured.last as String;

expect(request.message?.topic, 'test');
Expand Down Expand Up @@ -180,10 +183,60 @@ void main() {
final capture = verify(() => messages.send(captureAny(), captureAny()))
..called(1);

final request = capture.captured.first as SendMessageRequest;
final request = capture.captured.first as fmc1.SendMessageRequest;

expect(request.validateOnly, true);
});

test('supports booleans', () async {
when(() => messages.send(any(), any())).thenAnswer(
(_) => Future.value(fmc1.Message(name: 'test')),
);

await messaging.send(
TopicMessage(
topic: 'test',
apns: ApnsConfig(
payload: ApnsPayload(
aps: Aps(
contentAvailable: true,
mutableContent: true,
sound: CriticalSound(critical: true, name: 'default'),
),
),
),
webpush: WebpushConfig(
notification: WebpushNotification(renotify: true),
),
),
);

final capture = verify(() => messages.send(captureAny(), captureAny()))
..called(1);
final request = capture.captured.first as fmc1.SendMessageRequest;

expect(
request.message!.apns!.payload!['aps']!
.cast<Map<Object?, Object?>>()['content-available'],
1,
);
expect(
request.message!.apns!.payload!['aps']!
.cast<Map<Object?, Object?>>()['mutable-content'],
1,
);
expect(
request.message!.apns!.payload!['aps']!
.cast<Map<Object?, Object?>>()['sound']
.cast<Map<Object?, Object?>>()['critical'],
1,
);

expect(
request.message!.webpush!.notification!['renotify'],
1,
);
});
});

group('sendEach', () {
Expand Down Expand Up @@ -218,7 +271,8 @@ void main() {
test('works', () async {
when(() => messages.send(any(), any())).thenAnswer(
(i) {
final request = i.positionalArguments.first as SendMessageRequest;
final request =
i.positionalArguments.first as fmc1.SendMessageRequest;
switch (request.message?.topic) {
case 'test':
// Voluntary cause "test" to resolve after "test2"
Expand Down Expand Up @@ -257,11 +311,11 @@ void main() {
..called(2);
verifyNoMoreInteractions(messages);

var request = capture.captured.first as SendMessageRequest;
var request = capture.captured.first as fmc1.SendMessageRequest;

expect(request.validateOnly, null);

request = capture.captured[1] as SendMessageRequest;
request = capture.captured[1] as fmc1.SendMessageRequest;

expect(request.validateOnly, null);
});
Expand All @@ -280,11 +334,11 @@ void main() {
..called(2);
verifyNoMoreInteractions(messages);

var request = capture.captured.first as SendMessageRequest;
var request = capture.captured.first as fmc1.SendMessageRequest;

expect(request.validateOnly, true);

request = capture.captured[1] as SendMessageRequest;
request = capture.captured[1] as fmc1.SendMessageRequest;

expect(request.validateOnly, true);
});
Expand Down

0 comments on commit 8ae9e2a

Please sign in to comment.