@@ -207,12 +207,11 @@ public async Task SendAllAsyncWithError()
207
207
""error"": {
208
208
""code"": 400,
209
209
""message"": ""The registration token is not a valid FCM registration token"",
210
- ""errors"": [
211
- {
212
- ""message"": ""The registration token is not a valid FCM registration token"",
213
- ""domain"": ""global"",
214
- ""reason"": ""badRequest""
215
- }
210
+ ""details"": [
211
+ {
212
+ ""@type"": ""type.googleapis.com/google.firebase.fcm.v1.FcmError"",
213
+ ""errorCode"": ""UNREGISTERED""
214
+ }
216
215
],
217
216
""status"": ""INVALID_ARGUMENT""
218
217
}
@@ -245,7 +244,87 @@ public async Task SendAllAsyncWithError()
245
244
Assert . Equal ( 1 , response . SuccessCount ) ;
246
245
Assert . Equal ( 1 , response . FailureCount ) ;
247
246
Assert . Equal ( "projects/fir-adminintegrationtests/messages/8580920590356323124" , response . Responses [ 0 ] . MessageId ) ;
248
- Assert . NotNull ( response . Responses [ 1 ] . Exception ) ;
247
+
248
+ var exception = response . Responses [ 1 ] . Exception ;
249
+ Assert . NotNull ( exception ) ;
250
+ Assert . Equal ( ErrorCode . InvalidArgument , exception . ErrorCode ) ;
251
+ Assert . Equal ( "The registration token is not a valid FCM registration token" , exception . Message ) ;
252
+ Assert . Equal ( MessagingErrorCode . Unregistered , exception . MessagingErrorCode ) ;
253
+ Assert . NotNull ( exception . HttpResponse ) ;
254
+
255
+ Assert . Equal ( 1 , handler . Calls ) ;
256
+ var versionHeader = $ "X-Firebase-Client: { FirebaseMessagingClient . ClientVersion } ";
257
+ Assert . Equal ( 2 , this . CountLinesWithPrefix ( handler . LastRequestBody , versionHeader ) ) ;
258
+ }
259
+
260
+ [ Fact ]
261
+ public async Task SendAllAsyncWithErrorNoDetail ( )
262
+ {
263
+ var rawResponse = @"
264
+ --batch_test-boundary
265
+ Content-Type: application/http
266
+ Content-ID: response-
267
+
268
+ HTTP/1.1 200 OK
269
+ Content-Type: application/json; charset=UTF-8
270
+ Vary: Origin
271
+ Vary: X-Origin
272
+ Vary: Referer
273
+
274
+ {
275
+ ""name"": ""projects/fir-adminintegrationtests/messages/8580920590356323124""
276
+ }
277
+
278
+ --batch_test-boundary
279
+ Content-Type: application/http
280
+ Content-ID: response-
281
+
282
+ HTTP/1.1 400 Bad Request
283
+ Content-Type: application/json; charset=UTF-8
284
+
285
+ {
286
+ ""error"": {
287
+ ""code"": 400,
288
+ ""message"": ""The registration token is not a valid FCM registration token"",
289
+ ""status"": ""INVALID_ARGUMENT""
290
+ }
291
+ }
292
+
293
+ --batch_test-boundary
294
+ " ;
295
+ var handler = new MockMessageHandler ( )
296
+ {
297
+ Response = rawResponse ,
298
+ ApplyHeaders = ( _ , headers ) =>
299
+ {
300
+ headers . Remove ( "Content-Type" ) ;
301
+ headers . TryAddWithoutValidation ( "Content-Type" , "multipart/mixed; boundary=batch_test-boundary" ) ;
302
+ } ,
303
+ } ;
304
+ var factory = new MockHttpClientFactory ( handler ) ;
305
+ var client = new FirebaseMessagingClient ( factory , MockCredential , "test-project" ) ;
306
+ var message1 = new Message ( )
307
+ {
308
+ Token = "test-token1" ,
309
+ } ;
310
+ var message2 = new Message ( )
311
+ {
312
+ Token = "test-token2" ,
313
+ } ;
314
+
315
+ var response = await client . SendAllAsync ( new [ ] { message1 , message2 } ) ;
316
+
317
+ Assert . Equal ( 1 , response . SuccessCount ) ;
318
+ Assert . Equal ( 1 , response . FailureCount ) ;
319
+ Assert . Equal ( "projects/fir-adminintegrationtests/messages/8580920590356323124" , response . Responses [ 0 ] . MessageId ) ;
320
+
321
+ var exception = response . Responses [ 1 ] . Exception ;
322
+ Assert . NotNull ( exception ) ;
323
+ Assert . Equal ( ErrorCode . InvalidArgument , exception . ErrorCode ) ;
324
+ Assert . Equal ( "The registration token is not a valid FCM registration token" , exception . Message ) ;
325
+ Assert . Null ( exception . MessagingErrorCode ) ;
326
+ Assert . NotNull ( exception . HttpResponse ) ;
327
+
249
328
Assert . Equal ( 1 , handler . Calls ) ;
250
329
var versionHeader = $ "X-Firebase-Client: { FirebaseMessagingClient . ClientVersion } ";
251
330
Assert . Equal ( 2 , this . CountLinesWithPrefix ( handler . LastRequestBody , versionHeader ) ) ;
@@ -279,6 +358,82 @@ public async Task SendAllAsyncWithTooManyMessages()
279
358
280
359
[ Fact ]
281
360
public async Task HttpErrorAsync ( )
361
+ {
362
+ var handler = new MockMessageHandler ( )
363
+ {
364
+ StatusCode = HttpStatusCode . InternalServerError ,
365
+ Response = @"{
366
+ ""error"": {
367
+ ""status"": ""PERMISSION_DENIED"",
368
+ ""message"": ""test error"",
369
+ ""details"": [
370
+ {
371
+ ""@type"": ""type.googleapis.com/google.firebase.fcm.v1.FcmError"",
372
+ ""errorCode"": ""UNREGISTERED""
373
+ }
374
+ ]
375
+ }
376
+ }" ,
377
+ } ;
378
+ var factory = new MockHttpClientFactory ( handler ) ;
379
+ var client = new FirebaseMessagingClient ( factory , MockCredential , "test-project" ) ;
380
+ var message = new Message ( )
381
+ {
382
+ Topic = "test-topic" ,
383
+ } ;
384
+
385
+ var ex = await Assert . ThrowsAsync < FirebaseMessagingException > (
386
+ async ( ) => await client . SendAsync ( message ) ) ;
387
+
388
+ Assert . Equal ( ErrorCode . PermissionDenied , ex . ErrorCode ) ;
389
+ Assert . Equal ( "test error" , ex . Message ) ;
390
+ Assert . Equal ( MessagingErrorCode . Unregistered , ex . MessagingErrorCode ) ;
391
+ Assert . NotNull ( ex . HttpResponse ) ;
392
+
393
+ var req = JsonConvert . DeserializeObject < FirebaseMessagingClient . SendRequest > (
394
+ handler . LastRequestBody ) ;
395
+ Assert . Equal ( "test-topic" , req . Message . Topic ) ;
396
+ Assert . False ( req . ValidateOnly ) ;
397
+ Assert . Equal ( 1 , handler . Calls ) ;
398
+ }
399
+
400
+ [ Fact ]
401
+ public async Task HttpErrorNoDetailAsync ( )
402
+ {
403
+ var handler = new MockMessageHandler ( )
404
+ {
405
+ StatusCode = HttpStatusCode . InternalServerError ,
406
+ Response = @"{
407
+ ""error"": {
408
+ ""status"": ""PERMISSION_DENIED"",
409
+ ""message"": ""test error""
410
+ }
411
+ }" ,
412
+ } ;
413
+ var factory = new MockHttpClientFactory ( handler ) ;
414
+ var client = new FirebaseMessagingClient ( factory , MockCredential , "test-project" ) ;
415
+ var message = new Message ( )
416
+ {
417
+ Topic = "test-topic" ,
418
+ } ;
419
+
420
+ var ex = await Assert . ThrowsAsync < FirebaseMessagingException > (
421
+ async ( ) => await client . SendAsync ( message ) ) ;
422
+
423
+ Assert . Equal ( ErrorCode . PermissionDenied , ex . ErrorCode ) ;
424
+ Assert . Equal ( "test error" , ex . Message ) ;
425
+ Assert . Null ( ex . MessagingErrorCode ) ;
426
+ Assert . NotNull ( ex . HttpResponse ) ;
427
+
428
+ var req = JsonConvert . DeserializeObject < FirebaseMessagingClient . SendRequest > (
429
+ handler . LastRequestBody ) ;
430
+ Assert . Equal ( "test-topic" , req . Message . Topic ) ;
431
+ Assert . False ( req . ValidateOnly ) ;
432
+ Assert . Equal ( 1 , handler . Calls ) ;
433
+ }
434
+
435
+ [ Fact ]
436
+ public async Task HttpErrorNonJsonAsync ( )
282
437
{
283
438
var handler = new MockMessageHandler ( )
284
439
{
@@ -297,7 +452,7 @@ public async Task HttpErrorAsync()
297
452
298
453
Assert . Equal ( ErrorCode . Internal , ex . ErrorCode ) ;
299
454
Assert . Equal (
300
- $ "Unexpected HTTP response with status: { 500 } (InternalServerError)\n not json",
455
+ "Unexpected HTTP response with status: 500 (InternalServerError)\n not json" ,
301
456
ex . Message ) ;
302
457
Assert . Null ( ex . MessagingErrorCode ) ;
303
458
Assert . NotNull ( ex . HttpResponse ) ;
0 commit comments