@@ -133,6 +133,212 @@ public async Task SendDryRunAsync()
133
133
this . CheckHeaders ( handler . LastRequestHeaders ) ;
134
134
}
135
135
136
+ [ Fact ]
137
+ public async Task SendEachAsync ( )
138
+ {
139
+ var handler = new MockMessageHandler ( )
140
+ {
141
+ GenerateResponse = ( incomingRequest ) =>
142
+ {
143
+ string name ;
144
+ if ( incomingRequest . Body . Contains ( "test-token1" ) )
145
+ {
146
+ name = "projects/fir-adminintegrationtests/messages/8580920590356323124" ;
147
+ }
148
+ else
149
+ {
150
+ name = "projects/fir-adminintegrationtests/messages/5903525881088369386" ;
151
+ }
152
+
153
+ return new FirebaseMessagingClient . SingleMessageResponse ( )
154
+ {
155
+ Name = name ,
156
+ } ;
157
+ } ,
158
+ } ;
159
+ var factory = new MockHttpClientFactory ( handler ) ;
160
+ var client = this . CreateMessagingClient ( factory ) ;
161
+ var message1 = new Message ( )
162
+ {
163
+ Token = "test-token1" ,
164
+ } ;
165
+ var message2 = new Message ( )
166
+ {
167
+ Token = "test-token2" ,
168
+ } ;
169
+
170
+ var response = await client . SendEachAsync ( new [ ] { message1 , message2 } ) ;
171
+
172
+ Assert . Equal ( 2 , response . SuccessCount ) ;
173
+ Assert . Equal ( "projects/fir-adminintegrationtests/messages/8580920590356323124" , response . Responses [ 0 ] . MessageId ) ;
174
+ Assert . Equal ( "projects/fir-adminintegrationtests/messages/5903525881088369386" , response . Responses [ 1 ] . MessageId ) ;
175
+ Assert . Equal ( 2 , handler . Calls ) ;
176
+ }
177
+
178
+ [ Fact ]
179
+ public async Task SendEachAsyncWithError ( )
180
+ {
181
+ // Return a success for `message1` and an error for `message2`
182
+ var handler = new MockMessageHandler ( )
183
+ {
184
+ GenerateResponse = ( incomingRequest ) =>
185
+ {
186
+ string name ;
187
+ if ( incomingRequest . Body . Contains ( "test-token1" ) )
188
+ {
189
+ name = "projects/fir-adminintegrationtests/messages/8580920590356323124" ;
190
+ return new FirebaseMessagingClient . SingleMessageResponse ( )
191
+ {
192
+ Name = name ,
193
+ } ;
194
+ }
195
+ else
196
+ {
197
+ return @"{
198
+ ""error"": {
199
+ ""status"": ""INVALID_ARGUMENT"",
200
+ ""message"": ""The registration token is not a valid FCM registration token"",
201
+ ""details"": [
202
+ {
203
+ ""@type"": ""type.googleapis.com/google.firebase.fcm.v1.FcmError"",
204
+ ""errorCode"": ""UNREGISTERED""
205
+ }
206
+ ]
207
+ }
208
+ }" ;
209
+ }
210
+ } ,
211
+ GenerateStatusCode = ( incomingRequest ) =>
212
+ {
213
+ if ( incomingRequest . Body . Contains ( "test-token1" ) )
214
+ {
215
+ return HttpStatusCode . OK ;
216
+ }
217
+ else
218
+ {
219
+ return HttpStatusCode . InternalServerError ;
220
+ }
221
+ } ,
222
+ } ;
223
+ var factory = new MockHttpClientFactory ( handler ) ;
224
+ var client = this . CreateMessagingClient ( factory ) ;
225
+ var message1 = new Message ( )
226
+ {
227
+ Token = "test-token1" ,
228
+ } ;
229
+ var message2 = new Message ( )
230
+ {
231
+ Token = "test-token2" ,
232
+ } ;
233
+
234
+ var response = await client . SendEachAsync ( new [ ] { message1 , message2 } ) ;
235
+
236
+ Assert . Equal ( 1 , response . SuccessCount ) ;
237
+ Assert . Equal ( 1 , response . FailureCount ) ;
238
+ Assert . Equal ( "projects/fir-adminintegrationtests/messages/8580920590356323124" , response . Responses [ 0 ] . MessageId ) ;
239
+
240
+ var exception = response . Responses [ 1 ] . Exception ;
241
+ Assert . NotNull ( exception ) ;
242
+ Assert . Equal ( ErrorCode . InvalidArgument , exception . ErrorCode ) ;
243
+ Assert . Equal ( "The registration token is not a valid FCM registration token" , exception . Message ) ;
244
+ Assert . Equal ( MessagingErrorCode . Unregistered , exception . MessagingErrorCode ) ;
245
+ Assert . NotNull ( exception . HttpResponse ) ;
246
+
247
+ Assert . Equal ( 2 , handler . Calls ) ;
248
+ }
249
+
250
+ [ Fact ]
251
+ public async Task SendEachAsyncWithErrorNoDetail ( )
252
+ {
253
+ // Return a success for `message1` and an error for `message2`
254
+ var handler = new MockMessageHandler ( )
255
+ {
256
+ GenerateResponse = ( incomingRequest ) =>
257
+ {
258
+ string name ;
259
+ if ( incomingRequest . Body . Contains ( "test-token1" ) )
260
+ {
261
+ name = "projects/fir-adminintegrationtests/messages/8580920590356323124" ;
262
+ return new FirebaseMessagingClient . SingleMessageResponse ( )
263
+ {
264
+ Name = name ,
265
+ } ;
266
+ }
267
+ else
268
+ {
269
+ return @"{
270
+ ""error"": {
271
+ ""status"": ""INVALID_ARGUMENT"",
272
+ ""message"": ""The registration token is not a valid FCM registration token"",
273
+ }
274
+ }" ;
275
+ }
276
+ } ,
277
+ GenerateStatusCode = ( incomingRequest ) =>
278
+ {
279
+ if ( incomingRequest . Body . Contains ( "test-token1" ) )
280
+ {
281
+ return HttpStatusCode . OK ;
282
+ }
283
+ else
284
+ {
285
+ return HttpStatusCode . InternalServerError ;
286
+ }
287
+ } ,
288
+ } ;
289
+ var factory = new MockHttpClientFactory ( handler ) ;
290
+ var client = this . CreateMessagingClient ( factory ) ;
291
+ var message1 = new Message ( )
292
+ {
293
+ Token = "test-token1" ,
294
+ } ;
295
+ var message2 = new Message ( )
296
+ {
297
+ Token = "test-token2" ,
298
+ } ;
299
+
300
+ var response = await client . SendEachAsync ( new [ ] { message1 , message2 } ) ;
301
+
302
+ Assert . Equal ( 1 , response . SuccessCount ) ;
303
+ Assert . Equal ( 1 , response . FailureCount ) ;
304
+ Assert . Equal ( "projects/fir-adminintegrationtests/messages/8580920590356323124" , response . Responses [ 0 ] . MessageId ) ;
305
+
306
+ var exception = response . Responses [ 1 ] . Exception ;
307
+ Assert . NotNull ( exception ) ;
308
+ Assert . Equal ( ErrorCode . InvalidArgument , exception . ErrorCode ) ;
309
+ Assert . Equal ( "The registration token is not a valid FCM registration token" , exception . Message ) ;
310
+ Assert . Null ( exception . MessagingErrorCode ) ;
311
+ Assert . NotNull ( exception . HttpResponse ) ;
312
+
313
+ Assert . Equal ( 2 , handler . Calls ) ;
314
+ }
315
+
316
+ [ Fact ]
317
+ public async Task SendEachAsyncNullList ( )
318
+ {
319
+ var factory = new MockHttpClientFactory ( new MockMessageHandler ( ) ) ;
320
+ var client = this . CreateMessagingClient ( factory ) ;
321
+
322
+ await Assert . ThrowsAsync < ArgumentNullException > ( ( ) => client . SendEachAsync ( null ) ) ;
323
+ }
324
+
325
+ [ Fact ]
326
+ public async Task SendEachAsyncWithNoMessages ( )
327
+ {
328
+ var factory = new MockHttpClientFactory ( new MockMessageHandler ( ) ) ;
329
+ var client = this . CreateMessagingClient ( factory ) ;
330
+ await Assert . ThrowsAsync < ArgumentException > ( ( ) => client . SendEachAsync ( Enumerable . Empty < Message > ( ) ) ) ;
331
+ }
332
+
333
+ [ Fact ]
334
+ public async Task SendEachAsyncWithTooManyMessages ( )
335
+ {
336
+ var factory = new MockHttpClientFactory ( new MockMessageHandler ( ) ) ;
337
+ var client = this . CreateMessagingClient ( factory ) ;
338
+ var messages = Enumerable . Range ( 0 , 501 ) . Select ( _ => new Message { Topic = "test-topic" } ) ;
339
+ await Assert . ThrowsAsync < ArgumentException > ( ( ) => client . SendEachAsync ( messages ) ) ;
340
+ }
341
+
136
342
[ Fact ]
137
343
public async Task SendAllAsync ( )
138
344
{
0 commit comments