Skip to content

Commit c69b430

Browse files
author
Leo
committed
Refactored and tests pass
1 parent 186b96d commit c69b430

File tree

5 files changed

+97
-134
lines changed

5 files changed

+97
-134
lines changed

FirebaseAdmin/FirebaseAdmin.Tests/Messaging/TopicManagementResponseTest.cs

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using FirebaseAdmin.Messaging;
34
using Newtonsoft.Json;
45
using Xunit;
@@ -10,9 +11,8 @@ public class TopicManagementResponseTest
1011
[Fact]
1112
public void SuccessfulReponse()
1213
{
13-
var json = @"{""results"": [{}, {}]}";
14-
var instanceIdServiceResponse = JsonConvert.DeserializeObject<InstanceIdServiceResponse>(json);
15-
var response = new TopicManagementResponse(instanceIdServiceResponse);
14+
var topicManagementResults = new List<string> { null };
15+
var response = new TopicManagementResponse(topicManagementResults);
1616

1717
Assert.Empty(response.Errors);
1818
Assert.Equal(2, response.SuccessCount);
@@ -21,9 +21,8 @@ public void SuccessfulReponse()
2121
[Fact]
2222
public void UnsuccessfulResponse()
2323
{
24-
var json = @"{""results"": [{}, {""error"":""NOT_FOUND""}]}";
25-
var instanceIdServiceResponse = JsonConvert.DeserializeObject<InstanceIdServiceResponse>(json);
26-
var response = new TopicManagementResponse(instanceIdServiceResponse);
24+
var topicManagementResults = new List<string> { null, "NOT_FOUND" };
25+
var response = new TopicManagementResponse(topicManagementResults);
2726

2827
Assert.Single(response.Errors);
2928
Assert.Equal(1, response.SuccessCount);
@@ -44,19 +43,17 @@ public void NullResponse()
4443
[Fact]
4544
public void EmptyResponse()
4645
{
47-
var instanceIdServiceResponse = new InstanceIdServiceResponse();
4846
Assert.Throws<ArgumentException>(() =>
4947
{
50-
new TopicManagementResponse(instanceIdServiceResponse);
48+
new TopicManagementResponse(new List<string>());
5149
});
5250
}
5351

5452
[Fact]
5553
public void UnknownError()
5654
{
57-
var json = @"{""results"": [{""error"":""NOT_A_REAL_ERROR_CODE""}]}";
58-
var instanceIdServiceResponse = JsonConvert.DeserializeObject<InstanceIdServiceResponse>(json);
59-
var response = new TopicManagementResponse(instanceIdServiceResponse);
55+
var topicManagementResults = new List<string> { "NOT_A_REAL_ERROR_CODE" };
56+
var response = new TopicManagementResponse(topicManagementResults);
6057

6158
Assert.Empty(response.Errors);
6259
Assert.Equal(0, response.SuccessCount);
@@ -68,9 +65,8 @@ public void UnknownError()
6865
[Fact]
6966
public void UnexpectedResponse()
7067
{
71-
var json = @"{""results"": [{""unexpected"":""NOT_A_REAL_CODE""}]}";
72-
var instanceIdServiceResponse = JsonConvert.DeserializeObject<InstanceIdServiceResponse>(json);
73-
var response = new TopicManagementResponse(instanceIdServiceResponse);
68+
var topicManagementResults = new List<string> { "NOT_A_REAL_CODE" };
69+
var response = new TopicManagementResponse(topicManagementResults);
7470

7571
Assert.Empty(response.Errors);
7672
Assert.Equal(1, response.SuccessCount);
@@ -79,9 +75,8 @@ public void UnexpectedResponse()
7975
[Fact]
8076
public void CountsSuccessAndErrors()
8177
{
82-
var json = @"{""results"": [{""error"": ""NOT_FOUND""}, {}, {""error"": ""INVALID_ARGUMENT""}, {}, {}]}";
83-
var instanceIdServiceResponse = JsonConvert.DeserializeObject<InstanceIdServiceResponse>(json);
84-
var response = new TopicManagementResponse(instanceIdServiceResponse);
78+
var topicManagementResults = new List<string> { "NOT_FOUND", null, "INVALID_ARGUMENT", null, null };
79+
var response = new TopicManagementResponse(topicManagementResults);
8580

8681
Assert.Equal(2, response.FailureCount);
8782
Assert.Equal(3, response.SuccessCount);
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
using System.Collections.Generic;
2+
3+
namespace FirebaseAdmin.Messaging
4+
{
5+
/// <summary>
6+
/// A topic management error.
7+
/// </summary>
8+
public sealed class ErrorInfo
9+
{
10+
// Server error codes as defined in https://developers.google.com/instance-id/reference/server
11+
// TODO: Should we handle other error codes here (e.g. PERMISSION_DENIED)?
12+
private static IReadOnlyDictionary<string, string> errorCodes;
13+
private readonly string unknownError = "unknown-error";
14+
15+
/// <summary>
16+
/// Initializes a new instance of the <see cref="ErrorInfo"/> class.
17+
/// </summary>
18+
/// <param name="index">Index of the error in the error codes.</param>
19+
/// <param name="reason">Reason for the error.</param>
20+
public ErrorInfo(int index, string reason)
21+
{
22+
errorCodes = new Dictionary<string, string>
23+
{
24+
{ "INVALID_ARGUMENT", "invalid-argument" },
25+
{ "NOT_FOUND", "registration-token-not-registered" },
26+
{ "INTERNAL", "internal-error" },
27+
{ "TOO_MANY_TOPICS", "too-many-topics" },
28+
};
29+
30+
this.Index = index;
31+
this.Reason = errorCodes.ContainsKey(reason)
32+
? errorCodes[reason] : this.unknownError;
33+
}
34+
35+
/// <summary>
36+
/// Gets the registration token to which this error is related to.
37+
/// </summary>
38+
/// <returns>An index into the original registration token list.</returns>
39+
public int Index { get; private set; }
40+
41+
/// <summary>
42+
/// Gets the nature of the error.
43+
/// </summary>
44+
/// <returns>A non-null, non-empty error message.</returns>
45+
public string Reason { get; private set; }
46+
}
47+
}

FirebaseAdmin/FirebaseAdmin/Messaging/InstanceIdClient.cs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,14 @@ private async Task<TopicManagementResponse> SendInstanceIdRequest(string topic,
112112
var json = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
113113
this.errorHandler.ThrowIfError(response, json);
114114
var instanceIdServiceResponse = JsonConvert.DeserializeObject<InstanceIdServiceResponse>(json);
115-
return new TopicManagementResponse(instanceIdServiceResponse);
115+
116+
if (instanceIdServiceResponse == null || instanceIdServiceResponse.ResultCount == 0)
117+
{
118+
throw new ArgumentException("unexpected response from topic management service");
119+
}
120+
121+
var results = instanceIdServiceResponse.Results.Select(r => r.Error).ToList();
122+
return new TopicManagementResponse(results);
116123
}
117124
catch (HttpRequestException e)
118125
{
@@ -180,5 +187,23 @@ private class InstanceIdServiceRequest
180187
[JsonProperty("registration_tokens")]
181188
public List<string> RegistrationTokens { get; set; }
182189
}
190+
191+
private class InstanceIdServiceResponse
192+
{
193+
[JsonProperty("results")]
194+
public List<InstanceIdServiceResponseElement> Results { get; private set; }
195+
196+
public int ErrorCount => Results?.Count(results => results.HasError) ?? 0;
197+
198+
public int ResultCount => Results?.Count() ?? 0;
199+
200+
public class InstanceIdServiceResponseElement
201+
{
202+
[JsonProperty("error")]
203+
public string Error { get; private set; }
204+
205+
public bool HasError => !string.IsNullOrEmpty(Error);
206+
}
207+
}
183208
}
184209
}

FirebaseAdmin/FirebaseAdmin/Messaging/InstanceIdServiceResponse.cs

Lines changed: 0 additions & 60 deletions
This file was deleted.

FirebaseAdmin/FirebaseAdmin/Messaging/TopicManagementResponse.cs

Lines changed: 12 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
using System;
1615
using System.Collections.Generic;
16+
using System.Linq;
1717

1818
namespace FirebaseAdmin.Messaging
1919
{
@@ -22,24 +22,23 @@ namespace FirebaseAdmin.Messaging
2222
/// </summary>
2323
public sealed class TopicManagementResponse
2424
{
25+
private IEnumerable<string> topicManagementResults;
26+
2527
/// <summary>
2628
/// Initializes a new instance of the <see cref="TopicManagementResponse"/> class.
2729
/// </summary>
28-
/// <param name="instanceIdServiceResponse">The results from the response produced by FCM topic management operations.</param>
29-
public TopicManagementResponse(InstanceIdServiceResponse instanceIdServiceResponse)
30+
/// <param name="topicManagementResults">The results from the response produced by FCM topic management operations.</param>
31+
public TopicManagementResponse(List<string> topicManagementResults)
3032
{
31-
if (instanceIdServiceResponse == null || instanceIdServiceResponse.ResultCount == 0)
32-
{
33-
throw new ArgumentException("unexpected response from topic management service");
34-
}
33+
this.topicManagementResults = topicManagementResults;
3534

36-
var resultErrors = new List<Error>();
37-
for (var i = 0; i < instanceIdServiceResponse.Results.Count; i++)
35+
var resultErrors = new List<ErrorInfo>();
36+
for (var i = 0; i < topicManagementResults.Count(); i++)
3837
{
39-
var result = instanceIdServiceResponse.Results[i];
40-
if (result.HasError)
38+
var topicManagementResult = topicManagementResults[i];
39+
if (!string.IsNullOrEmpty(topicManagementResult))
4140
{
42-
resultErrors.Add(new Error(i, result.Error));
41+
resultErrors.Add(new ErrorInfo(i, topicManagementResult));
4342
}
4443
else
4544
{
@@ -66,49 +65,6 @@ public TopicManagementResponse(InstanceIdServiceResponse instanceIdServiceRespon
6665
/// Gets a list of errors encountered while executing the topic management operation.
6766
/// </summary>
6867
/// <returns>A non-null list.</returns>
69-
public IReadOnlyList<Error> Errors { get; private set; }
70-
71-
/// <summary>
72-
/// A topic management error.
73-
/// </summary>
74-
public sealed class Error
75-
{
76-
// Server error codes as defined in https://developers.google.com/instance-id/reference/server
77-
// TODO: Should we handle other error codes here (e.g. PERMISSION_DENIED)?
78-
private static IReadOnlyDictionary<string, string> errorCodes;
79-
private readonly string unknownError = "unknown-error";
80-
81-
/// <summary>
82-
/// Initializes a new instance of the <see cref="Error"/> class.
83-
/// </summary>
84-
/// <param name="index">Index of the error in the error codes.</param>
85-
/// <param name="reason">Reason for the error.</param>
86-
public Error(int index, string reason)
87-
{
88-
errorCodes = new Dictionary<string, string>
89-
{
90-
{ "INVALID_ARGUMENT", "invalid-argument" },
91-
{ "NOT_FOUND", "registration-token-not-registered" },
92-
{ "INTERNAL", "internal-error" },
93-
{ "TOO_MANY_TOPICS", "too-many-topics" },
94-
};
95-
96-
this.Index = index;
97-
this.Reason = errorCodes.ContainsKey(reason)
98-
? errorCodes[reason] : this.unknownError;
99-
}
100-
101-
/// <summary>
102-
/// Gets the registration token to which this error is related to.
103-
/// </summary>
104-
/// <returns>An index into the original registration token list.</returns>
105-
public int Index { get; private set; }
106-
107-
/// <summary>
108-
/// Gets the nature of the error.
109-
/// </summary>
110-
/// <returns>A non-null, non-empty error message.</returns>
111-
public string Reason { get; private set; }
112-
}
68+
public IReadOnlyList<ErrorInfo> Errors { get; private set; }
11369
}
11470
}

0 commit comments

Comments
 (0)