Skip to content

Commit

Permalink
Add multicast/send-all support
Browse files Browse the repository at this point in the history
  • Loading branch information
kentcb committed Mar 22, 2019
1 parent 9719659 commit 81a4a5e
Show file tree
Hide file tree
Showing 13 changed files with 533 additions and 30 deletions.
Expand Up @@ -49,5 +49,76 @@ public async Task Send()
Assert.True(!string.IsNullOrEmpty(id));
Assert.Matches(new Regex("^projects/.*/messages/.*$"), id);
}

[Fact]
public async Task SendAll()
{
var message1 = new Message()
{
Topic = "foo-bar",
Notification = new Notification()
{
Title = "Title",
Body = "Body",
},
Android = new AndroidConfig()
{
Priority = Priority.Normal,
TimeToLive = TimeSpan.FromHours(1),
RestrictedPackageName = "com.google.firebase.testing",
},
};
var message2 = new Message()
{
Topic = "fiz-buz",
Notification = new Notification()
{
Title = "Title",
Body = "Body",
},
Android = new AndroidConfig()
{
Priority = Priority.Normal,
TimeToLive = TimeSpan.FromHours(1),
RestrictedPackageName = "com.google.firebase.testing",
},
};
var response = await FirebaseMessaging.DefaultInstance.SendAllAsync(new[] { message1, message2 }, dryRun: true);
Assert.NotNull(response);
Assert.Equal(2, response.SuccessCount);
Assert.True(!string.IsNullOrEmpty(response.Responses[0].MessageId));
Assert.Matches(new Regex("^projects/.*/messages/.*$"), response.Responses[0].MessageId);
Assert.True(!string.IsNullOrEmpty(response.Responses[1].MessageId));
Assert.Matches(new Regex("^projects/.*/messages/.*$"), response.Responses[1].MessageId);
}

[Fact]
public async Task SendMulticast()
{
var multicastMessage = new MulticastMessage
{
Notification = new Notification()
{
Title = "Title",
Body = "Body",
},
Android = new AndroidConfig()
{
Priority = Priority.Normal,
TimeToLive = TimeSpan.FromHours(1),
RestrictedPackageName = "com.google.firebase.testing",
},
Tokens = new[]
{
"token1",
"token2",
},
};
var response = await FirebaseMessaging.DefaultInstance.SendMulticastAsync(multicastMessage, dryRun: true);
Assert.NotNull(response);
Assert.Equal(2, response.FailureCount);
Assert.NotNull(response.Responses[0].Exception);
Assert.NotNull(response.Responses[1].Exception);
}
}
}
Expand Up @@ -4,12 +4,12 @@

namespace FirebaseAdmin.Tests.Messaging
{
public class SendResponseTest
public class BatchItemResponseTest
{
[Fact]
public void SuccessfulResponse()
{
var response = SendResponse.FromMessageId("message-id");
var response = BatchItemResponse.FromMessageId("message-id");

Assert.Equal("message-id", response.MessageId);
Assert.True(response.IsSuccessful);
Expand All @@ -20,10 +20,10 @@ public void SuccessfulResponse()
public void FailureResponse()
{
FirebaseMessagingException exception = new FirebaseMessagingException(
"error-code",
400,
"error-message",
null);
SendResponse response = SendResponse.FromException(exception);
var response = BatchItemResponse.FromException(exception);

Assert.Null(response.MessageId);
Assert.False(response.IsSuccessful);
Expand All @@ -33,19 +33,19 @@ public void FailureResponse()
[Fact]
public void MessageIdCannotBeNull()
{
Assert.Throws<ArgumentNullException>(() => SendResponse.FromMessageId(null));
Assert.Throws<ArgumentNullException>(() => BatchItemResponse.FromMessageId(null));
}

[Fact]
public void MessageIdCannotBeEmpty()
{
Assert.Throws<ArgumentException>(() => SendResponse.FromMessageId(string.Empty));
Assert.Throws<ArgumentException>(() => BatchItemResponse.FromMessageId(string.Empty));
}

[Fact]
public void ExceptionCannotBeNull()
{
Assert.Throws<ArgumentNullException>(() => SendResponse.FromException(null));
Assert.Throws<ArgumentNullException>(() => BatchItemResponse.FromException(null));
}
}
}
12 changes: 6 additions & 6 deletions FirebaseAdmin/FirebaseAdmin.Tests/Messaging/BatchResponseTest.cs
Expand Up @@ -11,7 +11,7 @@ public class BatchResponseTest
[Fact]
public void EmptyResponses()
{
var responses = new List<SendResponse>();
var responses = new List<BatchItemResponse>();

var batchResponse = new BatchResponse(responses);

Expand All @@ -23,13 +23,13 @@ public void EmptyResponses()
[Fact]
public void SomeResponse()
{
var responses = new SendResponse[]
var responses = new BatchItemResponse[]
{
SendResponse.FromMessageId("message1"),
SendResponse.FromMessageId("message2"),
SendResponse.FromException(
BatchItemResponse.FromMessageId("message1"),
BatchItemResponse.FromMessageId("message2"),
BatchItemResponse.FromException(
new FirebaseMessagingException(
"error-code",
400,
"error-message",
null)),
};
Expand Down
Expand Up @@ -14,7 +14,6 @@

using System;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using FirebaseAdmin.Tests;
using Google.Apis.Auth.OAuth2;
Expand Down Expand Up @@ -89,6 +88,65 @@ public async Task SendAsync()
Assert.Equal(2, handler.Calls);
}

[Fact]
public async Task SendAllAsync()
{
var rawResponse = @"
--batch_test-boundary
Content-Type: application/http
Content-ID: response-
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Vary: Origin
Vary: X-Origin
Vary: Referer
{
""name"": ""projects/fir-adminintegrationtests/messages/8580920590356323124""
}
--batch_test-boundary
Content-Type: application/http
Content-ID: response-
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Vary: Origin
Vary: X-Origin
Vary: Referer
{
""name"": ""projects/fir-adminintegrationtests/messages/5903525881088369386""
}
--batch_test-boundary
";
var handler = new MockMessageHandler()
{
Response = rawResponse,
ApplyContentHeaders = (headers) =>
{
headers.Remove("Content-Type");
headers.TryAddWithoutValidation("Content-Type", "multipart/mixed; boundary=batch_test-boundary");
},
};
var factory = new MockHttpClientFactory(handler);
var client = new FirebaseMessagingClient(factory, MockCredential, "test-project");
var message1 = new Message()
{
Token = "test-token1",
};
var message2 = new Message()
{
Token = "test-token2",
};
var response = await client.SendAllAsync(new[] { message1, message2 });
Assert.Equal(2, response.SuccessCount);
Assert.Equal("projects/fir-adminintegrationtests/messages/8580920590356323124", response.Responses[0].MessageId);
Assert.Equal("projects/fir-adminintegrationtests/messages/5903525881088369386", response.Responses[1].MessageId);
}

[Fact]
public async Task HttpErrorAsync()
{
Expand Down
@@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FirebaseAdmin.Messaging;
using Google.Apis.Json;
using Newtonsoft.Json.Linq;
Expand All @@ -23,6 +21,21 @@ public void EmptyMulticastMessage()
this.AssertJsonEquals(new JObject() { { "tokens", new JArray("test-token") } }, message);
}

[Fact]
public void GetMessageList()
{
var message = new MulticastMessage
{
Tokens = new[] { "test-token1", "test-token2" },
};

var messages = message.GetMessageList();

Assert.Equal(2, messages.Count);
Assert.Equal("test-token1", messages[0].Token);
Assert.Equal("test-token2", messages[1].Token);
}

[Fact]
public void Data()
{
Expand Down Expand Up @@ -143,6 +156,12 @@ public void MessageWithNoTokens()
Assert.Throws<ArgumentException>(() => new MulticastMessage { Tokens = new string[] { } }.CopyAndValidate());
}

[Fact]
public void MessageWithTooManyTokens()
{
Assert.Throws<ArgumentException>(() => new MulticastMessage { Tokens = Enumerable.Range(0, 101).Select(x => x.ToString()).ToList() }.CopyAndValidate());
}

[Fact]
public void AndroidConfig()
{
Expand Down
14 changes: 13 additions & 1 deletion FirebaseAdmin/FirebaseAdmin.Tests/MockMessageHandler.cs
Expand Up @@ -39,6 +39,8 @@ public MockMessageHandler()

public delegate void SetHeaders(HttpResponseHeaders header);

public delegate void SetContentHeaders(HttpContentHeaders header);

public string Request { get; private set; }

public HttpStatusCode StatusCode { get; set; }
Expand All @@ -47,6 +49,8 @@ public MockMessageHandler()

public SetHeaders ApplyHeaders { get; set; }

public SetContentHeaders ApplyContentHeaders { get; set; }

protected override async Task<HttpResponseMessage> SendAsyncCore(
HttpRequestMessage request, CancellationToken cancellationToken)
{
Expand Down Expand Up @@ -80,7 +84,15 @@ public MockMessageHandler()
this.ApplyHeaders(resp.Headers);
}

resp.Content = new StringContent(json, Encoding.UTF8, "application/json");
var responseContent = new StringContent(json, Encoding.UTF8, "application/json");

if (this.ApplyContentHeaders != null)
{
this.ApplyContentHeaders(responseContent.Headers);
}

resp.Content = responseContent;

var tcs = new TaskCompletionSource<HttpResponseMessage>();
tcs.SetResult(resp);
return await tcs.Task;
Expand Down
2 changes: 1 addition & 1 deletion FirebaseAdmin/FirebaseAdmin/FirebaseException.cs
Expand Up @@ -19,7 +19,7 @@ namespace FirebaseAdmin
/// <summary>
/// Common error type for all exceptions raised by Firebase APIs.
/// </summary>
public sealed class FirebaseException : Exception
public class FirebaseException : Exception
{
internal FirebaseException(string message)
: base(message) { }
Expand Down
Expand Up @@ -20,14 +20,14 @@ namespace FirebaseAdmin.Messaging
/// The result of an individual send operation that was executed as part of a batch. See
/// <see cref="BatchResponse"/> for more details.
/// </summary>
public sealed class SendResponse
public sealed class BatchItemResponse
{
private SendResponse(string messageId)
private BatchItemResponse(string messageId)
{
this.MessageId = messageId;
}

private SendResponse(FirebaseMessagingException exception)
private BatchItemResponse(FirebaseException exception)
{
this.Exception = exception;
}
Expand All @@ -40,7 +40,7 @@ private SendResponse(FirebaseMessagingException exception)
/// <summary>
/// Gets an exception if the send operation failed. Otherwise returns null.
/// </summary>
public FirebaseMessagingException Exception { get; }
public FirebaseException Exception { get; }

/// <summary>
/// Gets a value indicating whether the send operation was successful or not. When this property
Expand All @@ -50,7 +50,7 @@ private SendResponse(FirebaseMessagingException exception)
/// </summary>
public bool IsSuccessful => !string.IsNullOrEmpty(this.MessageId);

internal static SendResponse FromMessageId(string messageId)
internal static BatchItemResponse FromMessageId(string messageId)
{
if (messageId == null)
{
Expand All @@ -62,17 +62,17 @@ internal static SendResponse FromMessageId(string messageId)
throw new ArgumentException("Cannot be empty.", nameof(messageId));
}

return new SendResponse(messageId);
return new BatchItemResponse(messageId);
}

internal static SendResponse FromException(FirebaseMessagingException exception)
internal static BatchItemResponse FromException(FirebaseException exception)
{
if (exception == null)
{
throw new ArgumentNullException(nameof(exception));
}

return new SendResponse(exception);
return new BatchItemResponse(exception);
}
}
}
4 changes: 2 additions & 2 deletions FirebaseAdmin/FirebaseAdmin/Messaging/BatchResponse.cs
Expand Up @@ -27,7 +27,7 @@ public sealed class BatchResponse
/// Initializes a new instance of the <see cref="BatchResponse"/> class.
/// </summary>
/// <param name="responses">The responses.</param>
public BatchResponse(IEnumerable<SendResponse> responses)
public BatchResponse(IEnumerable<BatchItemResponse> responses)
{
if (responses == null)
{
Expand All @@ -52,7 +52,7 @@ public BatchResponse(IEnumerable<SendResponse> responses)
/// <summary>
/// Gets information about all responses for the batch.
/// </summary>
public IReadOnlyList<SendResponse> Responses { get; }
public IReadOnlyList<BatchItemResponse> Responses { get; }

/// <summary>
/// Gets a count of how many of the responses in <see cref="Responses"/> were
Expand Down

0 comments on commit 81a4a5e

Please sign in to comment.