Skip to content

Commit 3c3d836

Browse files
committed
Merged with upstream
2 parents f394a3b + 1a887cb commit 3c3d836

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+24580
-342
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ bin/
22
obj/
33
.vscode/
44
.vs/
5+
.idea/

CONTRIBUTING.md

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ Run the following commands from the command line to get your local environmentse
100100
```bash
101101
$ git clone https://github.com/firebase/firebase-admin-dotnet.git
102102
$ cd firebase-admin-dotnet/FirebaseAdmin # Change into the FirebaseAdmin solution directory
103-
$ dotnet restore # Install dependencies
103+
$ dotnet restore # Install dependencies
104104
```
105105

106106
### Running Tests
@@ -119,6 +119,24 @@ To run the unit test suite:
119119
$ dotnet test FirebaseAdmin.Tests
120120
```
121121

122+
To invoke code coverage tools, run the unit tests as follows:
123+
124+
```bash
125+
$ dotnet test FirebaseAdmin.Tests /p:CollectCoverage=true
126+
```
127+
128+
The above command calculates and displays a code coverage summary. To produce a more detailed
129+
code coverage report, you can use a tool like
130+
[Report Generator](https://github.com/danielpalme/ReportGenerator):
131+
132+
```bash
133+
$ dotnet test FirebaseAdmin.Tests /p:CollectCoverage=true /p:CoverletOutputFormat=opencover
134+
$ dotnet path/to/ReportGenerator.dll -reports:./FirebaseAdmin.Tests/coverage.opencover.xml -targetdir:./reports
135+
```
136+
137+
This generates a collection of HTML code coverage reports in a local subdirectory named
138+
`reports/`.
139+
122140
The integration test suite requires a service account JSON key file, and an API key for a Firebase
123141
project. Create a new project in the [Firebase console](https://console.firebase.google.com) if
124142
you do not already have one. Use a separate, dedicated project for integration tests since the
@@ -143,4 +161,3 @@ Here are some highlights of the directory structure and notable source files
143161
* `FirebaseAdmin.Tests/` - Unit tests directory.
144162
* `FirebaseAdmin.IntegrationTests/` - Integration tests directory.
145163
* `FirebaseAdmin.Snippets/` - Example code snippets for the SDK.
146-

FirebaseAdmin/FirebaseAdmin.IntegrationTests/FirebaseAuthTest.cs

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,10 @@ public async Task SetCustomUserClaimsWithWrongUid()
118118
{
119119
var customClaims = new Dictionary<string, object>();
120120

121-
await Assert.ThrowsAsync<FirebaseException>(
121+
var exception = await Assert.ThrowsAsync<FirebaseAuthException>(
122122
async () => await FirebaseAuth.DefaultInstance.SetCustomUserClaimsAsync("non.existing", customClaims));
123+
124+
Assert.Equal(AuthErrorCode.UserNotFound, exception.AuthErrorCode);
123125
}
124126

125127
[Fact]
@@ -150,8 +152,10 @@ public async Task CreateUserWithParams()
150152
Assert.False(user.Disabled);
151153

152154
// Cannot recreate the same user.
153-
await Assert.ThrowsAsync<FirebaseException>(
155+
var exception = await Assert.ThrowsAsync<FirebaseAuthException>(
154156
async () => await FirebaseAuth.DefaultInstance.CreateUserAsync(args));
157+
158+
Assert.Equal(AuthErrorCode.UidAlreadyExists, exception.AuthErrorCode);
155159
}
156160
finally
157161
{
@@ -247,23 +251,29 @@ public async Task UserLifecycle()
247251
{
248252
// Delete user
249253
await FirebaseAuth.DefaultInstance.DeleteUserAsync(uid);
250-
await Assert.ThrowsAsync<FirebaseException>(
254+
var exception = await Assert.ThrowsAsync<FirebaseAuthException>(
251255
async () => await FirebaseAuth.DefaultInstance.GetUserAsync(uid));
256+
257+
Assert.Equal(AuthErrorCode.UserNotFound, exception.AuthErrorCode);
252258
}
253259
}
254260

255261
[Fact]
256262
public async Task GetUserNonExistingUid()
257263
{
258-
await Assert.ThrowsAsync<FirebaseException>(
264+
var exception = await Assert.ThrowsAsync<FirebaseAuthException>(
259265
async () => await FirebaseAuth.DefaultInstance.GetUserAsync("non.existing"));
266+
267+
Assert.Equal(AuthErrorCode.UserNotFound, exception.AuthErrorCode);
260268
}
261269

262270
[Fact]
263271
public async Task GetUserNonExistingEmail()
264272
{
265-
await Assert.ThrowsAsync<FirebaseException>(
273+
var exception = await Assert.ThrowsAsync<FirebaseAuthException>(
266274
async () => await FirebaseAuth.DefaultInstance.GetUserByEmailAsync("[email protected]"));
275+
276+
Assert.Equal(AuthErrorCode.UserNotFound, exception.AuthErrorCode);
267277
}
268278

269279
[Fact]
@@ -273,15 +283,20 @@ public async Task UpdateUserNonExistingUid()
273283
{
274284
Uid = "non.existing",
275285
};
276-
await Assert.ThrowsAsync<FirebaseException>(
286+
287+
var exception = await Assert.ThrowsAsync<FirebaseAuthException>(
277288
async () => await FirebaseAuth.DefaultInstance.UpdateUserAsync(args));
289+
290+
Assert.Equal(AuthErrorCode.UserNotFound, exception.AuthErrorCode);
278291
}
279292

280293
[Fact]
281294
public async Task DeleteUserNonExistingUid()
282295
{
283-
await Assert.ThrowsAsync<FirebaseException>(
296+
var exception = await Assert.ThrowsAsync<FirebaseAuthException>(
284297
async () => await FirebaseAuth.DefaultInstance.DeleteUserAsync("non.existing"));
298+
299+
Assert.Equal(AuthErrorCode.UserNotFound, exception.AuthErrorCode);
285300
}
286301

287302
[Fact]

FirebaseAdmin/FirebaseAdmin.IntegrationTests/FirebaseMessagingTest.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
// limitations under the License.
1414

1515
using System;
16+
using System.Collections.Generic;
1617
using System.Text.RegularExpressions;
1718
using System.Threading.Tasks;
1819
using FirebaseAdmin.Messaging;
@@ -120,5 +121,29 @@ public async Task SendMulticast()
120121
Assert.NotNull(response.Responses[0].Exception);
121122
Assert.NotNull(response.Responses[1].Exception);
122123
}
124+
125+
[Fact]
126+
public async Task SubscribeToTopic()
127+
{
128+
var response = await FirebaseMessaging.DefaultInstance.SubscribeToTopicAsync("test-topic", new List<string> { "token1", "token2" });
129+
Assert.NotNull(response);
130+
Assert.Equal(2, response.FailureCount);
131+
Assert.Equal("invalid-argument", response.Errors[0].Reason);
132+
Assert.Equal(0, response.Errors[0].Index);
133+
Assert.Equal("invalid-argument", response.Errors[1].Reason);
134+
Assert.Equal(1, response.Errors[1].Index);
135+
}
136+
137+
[Fact]
138+
public async Task UnsubscribeFromTopic()
139+
{
140+
var response = await FirebaseMessaging.DefaultInstance.UnsubscribeFromTopicAsync("test-topic", new List<string> { "token1", "token2" });
141+
Assert.NotNull(response);
142+
Assert.Equal(2, response.FailureCount);
143+
Assert.Equal("invalid-argument", response.Errors[0].Reason);
144+
Assert.Equal(0, response.Errors[0].Index);
145+
Assert.Equal("invalid-argument", response.Errors[1].Reason);
146+
Assert.Equal(1, response.Errors[1].Index);
147+
}
123148
}
124149
}

FirebaseAdmin/FirebaseAdmin.Tests/Auth/AuthErrorHandlerTest.cs

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

15+
using System;
1516
using System.Collections.Generic;
1617
using System.Net;
1718
using System.Net.Http;
1819
using System.Text;
20+
using FirebaseAdmin.Util;
1921
using Xunit;
2022

2123
namespace FirebaseAdmin.Auth.Tests
@@ -67,8 +69,7 @@ public void KnownErrorCode(
6769
Content = new StringContent(json, Encoding.UTF8, "application/json"),
6870
};
6971

70-
var error = Assert.Throws<FirebaseAuthException>(
71-
() => AuthErrorHandler.Instance.ThrowIfError(resp, json));
72+
var error = AuthErrorHandler.Instance.HandleHttpErrorResponse(resp, json);
7273

7374
Assert.Equal(expectedCode, error.ErrorCode);
7475
Assert.Equal(expectedAuthCode, error.AuthErrorCode);
@@ -93,8 +94,7 @@ public void KnownErrorCodeWithDetails(
9394
Content = new StringContent(json, Encoding.UTF8, "application/json"),
9495
};
9596

96-
var error = Assert.Throws<FirebaseAuthException>(
97-
() => AuthErrorHandler.Instance.ThrowIfError(resp, json));
97+
var error = AuthErrorHandler.Instance.HandleHttpErrorResponse(resp, json);
9898

9999
Assert.Equal(expectedCode, error.ErrorCode);
100100
Assert.Equal(expectedAuthCode, error.AuthErrorCode);
@@ -117,8 +117,7 @@ public void UnknownErrorCode()
117117
Content = new StringContent(json, Encoding.UTF8, "application/json"),
118118
};
119119

120-
var error = Assert.Throws<FirebaseAuthException>(
121-
() => AuthErrorHandler.Instance.ThrowIfError(resp, json));
120+
var error = AuthErrorHandler.Instance.HandleHttpErrorResponse(resp, json);
122121

123122
Assert.Equal(ErrorCode.Internal, error.ErrorCode);
124123
Assert.Equal(
@@ -141,8 +140,7 @@ public void UnspecifiedErrorCode()
141140
Content = new StringContent(json, Encoding.UTF8, "application/json"),
142141
};
143142

144-
var error = Assert.Throws<FirebaseAuthException>(
145-
() => AuthErrorHandler.Instance.ThrowIfError(resp, json));
143+
var error = AuthErrorHandler.Instance.HandleHttpErrorResponse(resp, json);
146144

147145
Assert.Equal(ErrorCode.Internal, error.ErrorCode);
148146
Assert.Equal(
@@ -163,8 +161,7 @@ public void NoDetails()
163161
Content = new StringContent(json, Encoding.UTF8, "application/json"),
164162
};
165163

166-
var error = Assert.Throws<FirebaseAuthException>(
167-
() => AuthErrorHandler.Instance.ThrowIfError(resp, json));
164+
var error = AuthErrorHandler.Instance.HandleHttpErrorResponse(resp, json);
168165

169166
Assert.Equal(ErrorCode.Unavailable, error.ErrorCode);
170167
Assert.Equal(
@@ -185,8 +182,7 @@ public void NonJson()
185182
Content = new StringContent(text, Encoding.UTF8, "text/plain"),
186183
};
187184

188-
var error = Assert.Throws<FirebaseAuthException>(
189-
() => AuthErrorHandler.Instance.ThrowIfError(resp, text));
185+
var error = AuthErrorHandler.Instance.HandleHttpErrorResponse(resp, text);
190186

191187
Assert.Equal(ErrorCode.Unavailable, error.ErrorCode);
192188
Assert.Equal(
@@ -196,5 +192,43 @@ public void NonJson()
196192
Assert.Same(resp, error.HttpResponse);
197193
Assert.Null(error.InnerException);
198194
}
195+
196+
[Fact]
197+
public void DeserializeException()
198+
{
199+
var text = "plain text";
200+
var resp = new HttpResponseMessage()
201+
{
202+
StatusCode = HttpStatusCode.ServiceUnavailable,
203+
Content = new StringContent(text, Encoding.UTF8, "text/plain"),
204+
};
205+
var inner = new Exception("Deserialization error");
206+
207+
var error = AuthErrorHandler.Instance.HandleDeserializeException(
208+
inner, new ResponseInfo(resp, text));
209+
210+
Assert.Equal(ErrorCode.Unknown, error.ErrorCode);
211+
Assert.Equal(
212+
$"Error while parsing Auth service response. Deserialization error: {text}",
213+
error.Message);
214+
Assert.Equal(AuthErrorCode.UnexpectedResponse, error.AuthErrorCode);
215+
Assert.Same(resp, error.HttpResponse);
216+
Assert.Same(inner, error.InnerException);
217+
}
218+
219+
[Fact]
220+
public void HttpRequestException()
221+
{
222+
var exception = new HttpRequestException("network error");
223+
224+
var error = AuthErrorHandler.Instance.HandleHttpRequestException(exception);
225+
226+
Assert.Equal(ErrorCode.Unknown, error.ErrorCode);
227+
Assert.Equal(
228+
"Unknown error while making a remote service call: network error", error.Message);
229+
Assert.Null(error.AuthErrorCode);
230+
Assert.Null(error.HttpResponse);
231+
Assert.Same(exception, error.InnerException);
232+
}
199233
}
200234
}

FirebaseAdmin/FirebaseAdmin.Tests/Auth/FirebaseUserManagerTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -733,11 +733,11 @@ public async Task ListUsersNonJsonResponse()
733733

734734
Assert.Equal(ErrorCode.Unknown, exception.ErrorCode);
735735
Assert.Equal(AuthErrorCode.UnexpectedResponse, exception.AuthErrorCode);
736+
Assert.NotNull(exception.InnerException);
736737
Assert.Equal(
737-
"Error while parsing Auth service response.",
738+
$"Error while parsing Auth service response. {exception.InnerException.Message}: not json",
738739
exception.Message);
739740
Assert.NotNull(exception.HttpResponse);
740-
Assert.NotNull(exception.InnerException);
741741

742742
Assert.Single(handler.Requests);
743743
var query = this.ExtractQueryParams(handler.Requests[0]);

FirebaseAdmin/FirebaseAdmin.Tests/FirebaseAdmin.Tests.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
44
<TargetFramework>netcoreapp2.0</TargetFramework>
@@ -10,6 +10,7 @@
1010
</PropertyGroup>
1111

1212
<ItemGroup>
13+
<PackageReference Include="coverlet.msbuild" Version="2.6.3" />
1314
<PackageReference Include="Google.Apis.Auth" Version="1.40.0" />
1415
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.6.0" />
1516
<PackageReference Include="xunit" Version="2.3.1" />

FirebaseAdmin/FirebaseAdmin.Tests/HttpErrorHandlerTest.cs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ public class HttpErrorHandlerTest
3535
new object[] { HttpStatusCode.ServiceUnavailable, ErrorCode.Unavailable },
3636
};
3737

38+
private static readonly TestHttpErrorHandler ErrorHandler = new TestHttpErrorHandler();
39+
3840
[Theory]
3941
[MemberData(nameof(HttpErrorCodes))]
4042
public void KnownHttpStatusCode(HttpStatusCode statusCode, ErrorCode expected)
@@ -46,8 +48,7 @@ public void KnownHttpStatusCode(HttpStatusCode statusCode, ErrorCode expected)
4648
Content = new StringContent(json, Encoding.UTF8, "application/json"),
4749
};
4850

49-
var handler = new HttpErrorHandler();
50-
var error = Assert.Throws<FirebaseException>(() => handler.ThrowIfError(resp, json));
51+
var error = ErrorHandler.HandleHttpErrorResponse(resp, json);
5152

5253
Assert.Equal(expected, error.ErrorCode);
5354
Assert.Equal(
@@ -68,8 +69,7 @@ public void NonJsonResponse(HttpStatusCode statusCode, ErrorCode expected)
6869
Content = new StringContent(text, Encoding.UTF8, "text/plain"),
6970
};
7071

71-
var handler = new HttpErrorHandler();
72-
var error = Assert.Throws<FirebaseException>(() => handler.ThrowIfError(resp, text));
72+
var error = ErrorHandler.HandleHttpErrorResponse(resp, text);
7373

7474
Assert.Equal(expected, error.ErrorCode);
7575
Assert.Equal(
@@ -89,8 +89,7 @@ public void UnknownHttpStatusCode()
8989
Content = new StringContent(json, Encoding.UTF8, "application/json"),
9090
};
9191

92-
var handler = new HttpErrorHandler();
93-
var error = Assert.Throws<FirebaseException>(() => handler.ThrowIfError(resp, json));
92+
var error = ErrorHandler.HandleHttpErrorResponse(resp, json);
9493

9594
Assert.Equal(ErrorCode.Unknown, error.ErrorCode);
9695
Assert.Equal(
@@ -99,5 +98,13 @@ public void UnknownHttpStatusCode()
9998
Assert.Same(resp, error.HttpResponse);
10099
Assert.Null(error.InnerException);
101100
}
102-
}
101+
102+
private class TestHttpErrorHandler : HttpErrorHandler<FirebaseException>
103+
{
104+
protected override FirebaseException CreateException(FirebaseExceptionArgs args)
105+
{
106+
return new FirebaseException(args.Code, args.Message, response: args.HttpResponse);
107+
}
108+
}
109+
}
103110
}

0 commit comments

Comments
 (0)