Skip to content

Commit d3ff568

Browse files
authored
chore: More unit tests (#236)
* chore: Increased unit test coverage for Auth APIs * chore: More unit tests
1 parent 53fcb3f commit d3ff568

File tree

8 files changed

+164
-27
lines changed

8 files changed

+164
-27
lines changed
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// Copyright 2020, Google Inc. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
using System;
16+
using System.Collections.Generic;
17+
using Xunit;
18+
19+
namespace FirebaseAdmin.Auth.Tests
20+
{
21+
/// <summary>
22+
/// Represents the result of the
23+
/// <see cref="AbstractFirebaseAuth.DeleteUsersAsync(IReadOnlyList{string})"/> API.
24+
/// </summary>
25+
public sealed class DeleteUsersResultTest
26+
{
27+
[Fact]
28+
public void NullErrors()
29+
{
30+
var result = new DeleteUsersResult(2, null);
31+
32+
Assert.Equal(2, result.SuccessCount);
33+
Assert.Equal(0, result.FailureCount);
34+
Assert.Empty(result.Errors);
35+
}
36+
37+
[Fact]
38+
public void EmptyErrors()
39+
{
40+
var result = new DeleteUsersResult(2, new List<ErrorInfo>());
41+
42+
Assert.Equal(2, result.SuccessCount);
43+
Assert.Equal(0, result.FailureCount);
44+
Assert.Empty(result.Errors);
45+
}
46+
47+
[Fact]
48+
public void Errors()
49+
{
50+
var errors = new List<ErrorInfo>()
51+
{
52+
{ new ErrorInfo(1, "test") },
53+
};
54+
var result = new DeleteUsersResult(2, errors);
55+
56+
Assert.Equal(1, result.SuccessCount);
57+
Assert.Equal(1, result.FailureCount);
58+
var error = Assert.Single(result.Errors);
59+
Assert.Equal(1, error.Index);
60+
Assert.Equal("test", error.Reason);
61+
}
62+
63+
[Fact]
64+
public void TooManyErrors()
65+
{
66+
var errors = new List<ErrorInfo>()
67+
{
68+
{ new ErrorInfo(1, "test") },
69+
{ new ErrorInfo(2, "test") },
70+
{ new ErrorInfo(3, "test") },
71+
};
72+
73+
var exception = Assert.Throws<ArgumentException>(
74+
() => new DeleteUsersResult(2, errors));
75+
76+
Assert.Equal(
77+
"More errors encountered (3) than users (2). Errors: test, test, test",
78+
exception.Message);
79+
}
80+
}
81+
}

FirebaseAdmin/FirebaseAdmin.Tests/Auth/FirebaseAuthTest.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
using System.Collections.Generic;
1717
using System.Text;
1818
using System.Threading.Tasks;
19+
using FirebaseAdmin.Auth.Jwt;
1920
using Google.Apis.Auth.OAuth2;
2021
using Xunit;
2122

@@ -125,6 +126,20 @@ public void TenantManagerNoProjectId()
125126
ex.Message);
126127
}
127128

129+
[Fact]
130+
public void ServiceAccountId()
131+
{
132+
FirebaseApp.Create(new AppOptions
133+
{
134+
Credential = MockCredential,
135+
ServiceAccountId = "test-service-account",
136+
});
137+
138+
var tokenFactory = FirebaseAuth.DefaultInstance.TokenFactory;
139+
140+
Assert.IsType<FixedAccountIAMSigner>(tokenFactory.Signer);
141+
}
142+
128143
[Fact]
129144
public async Task ImportUsersPasswordNoHash()
130145
{

FirebaseAdmin/FirebaseAdmin.Tests/Auth/Multitenancy/TenantAwareFirebaseAuthTest.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,22 @@ public class TenantAwareFirebaseAuthTest : IDisposable
2222
{
2323
private const string MockTenantId = "tenant1";
2424

25+
[Fact]
26+
public void NullTenantId()
27+
{
28+
var args = TenantAwareFirebaseAuth.Args.CreateDefault(null);
29+
30+
Assert.Throws<ArgumentException>(() => new TenantAwareFirebaseAuth(args));
31+
}
32+
33+
[Fact]
34+
public void EmptyTenantId()
35+
{
36+
var args = TenantAwareFirebaseAuth.Args.CreateDefault(string.Empty);
37+
38+
Assert.Throws<ArgumentException>(() => new TenantAwareFirebaseAuth(args));
39+
}
40+
2541
[Fact]
2642
public void UseAfterDelete()
2743
{

FirebaseAdmin/FirebaseAdmin.Tests/Auth/UserIdentifierTest.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,44 @@ public void InvalidUidIdentifier()
2626
() => new UidIdentifier("too long " + new string('.', 128)));
2727
}
2828

29+
[Fact]
30+
public void UidIdentifier()
31+
{
32+
var identifier = new UidIdentifier("firebase");
33+
34+
Assert.Equal("UidIdentifier(firebase)", identifier.ToString());
35+
}
36+
2937
[Fact]
3038
public void InvalidEmailIdentifier()
3139
{
3240
Assert.Throws<ArgumentException>(
3341
() => new EmailIdentifier("invalid email addr"));
3442
}
3543

44+
[Fact]
45+
public void EmailIdentifier()
46+
{
47+
var identifier = new EmailIdentifier("[email protected]");
48+
49+
Assert.Equal("EmailIdentifier([email protected])", identifier.ToString());
50+
}
51+
3652
[Fact]
3753
public void InvalidPhoneIdentifier()
3854
{
3955
Assert.Throws<ArgumentException>(
4056
() => new PhoneIdentifier("invalid phone number"));
4157
}
4258

59+
[Fact]
60+
public void PhoneIdentifier()
61+
{
62+
var identifier = new PhoneIdentifier("+1234567890");
63+
64+
Assert.Equal("PhoneIdentifier(+1234567890)", identifier.ToString());
65+
}
66+
4367
[Fact]
4468
public void InvalidProviderIdentifier()
4569
{
@@ -49,5 +73,13 @@ public void InvalidProviderIdentifier()
4973
Assert.Throws<ArgumentException>(
5074
() => new ProviderIdentifier("valid-id", string.Empty));
5175
}
76+
77+
[Fact]
78+
public void ProviderIdentifier()
79+
{
80+
var identifier = new ProviderIdentifier("google.com", "firebase");
81+
82+
Assert.Equal("ProviderIdentifier(google.com, firebase)", identifier.ToString());
83+
}
5284
}
5385
}

FirebaseAdmin/FirebaseAdmin/Auth/DeleteUsersResult.cs

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
using System;
1616
using System.Collections.Generic;
1717
using System.Linq;
18-
using FirebaseAdmin.Auth.Users;
1918

2019
namespace FirebaseAdmin.Auth
2120
{
@@ -25,26 +24,16 @@ namespace FirebaseAdmin.Auth
2524
/// </summary>
2625
public sealed class DeleteUsersResult
2726
{
28-
internal DeleteUsersResult(int users, BatchDeleteResponse response)
27+
internal DeleteUsersResult(int users, IReadOnlyList<ErrorInfo> errors)
2928
{
30-
var errors = new List<ErrorInfo>();
31-
if (response.Errors != null)
29+
errors = errors ?? new List<ErrorInfo>();
30+
if (users < errors.Count)
3231
{
33-
if (users < response.Errors.Count)
34-
{
35-
string errorMessages =
36-
string.Join(",", response.Errors.Select(errorInfo => errorInfo.Message));
37-
throw new InvalidOperationException(string.Format(
38-
"Internal error: More errors encountered ({0}) than users ({1}). Errors: {2}",
39-
response.Errors.Count,
40-
users,
41-
errorMessages));
42-
}
43-
44-
foreach (BatchDeleteResponse.ErrorInfo error in response.Errors)
45-
{
46-
errors.Add(new ErrorInfo(error.Index, error.Message));
47-
}
32+
string errorMessages = string.Join(
33+
", ", errors.Select(errorInfo => errorInfo.Reason));
34+
throw new ArgumentException(
35+
$"More errors encountered ({errors.Count}) than users "
36+
+ $"({users}). Errors: {errorMessages}");
4837
}
4938

5039
this.Errors = errors;

FirebaseAdmin/FirebaseAdmin/Auth/Jwt/FirebaseTokenFactory.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ internal class FirebaseTokenFactory : IDisposable
6060
"nonce",
6161
"sub");
6262

63-
private readonly ISigner signer;
6463
private readonly IClock clock;
6564

6665
internal FirebaseTokenFactory(ISigner signer, IClock clock, string tenantId = null)
@@ -70,16 +69,18 @@ internal FirebaseTokenFactory(ISigner signer, IClock clock, string tenantId = nu
7069
throw new ArgumentException("Tenant ID must not be empty.");
7170
}
7271

73-
this.signer = signer.ThrowIfNull(nameof(signer));
7472
this.clock = clock.ThrowIfNull(nameof(clock));
73+
this.Signer = signer.ThrowIfNull(nameof(signer));
7574
this.TenantId = tenantId;
7675
}
7776

77+
internal ISigner Signer { get; }
78+
7879
internal string TenantId { get; }
7980

8081
public void Dispose()
8182
{
82-
this.signer.Dispose();
83+
this.Signer.Dispose();
8384
}
8485

8586
internal static FirebaseTokenFactory Create(FirebaseApp app, string tenantId = null)
@@ -140,7 +141,7 @@ internal async Task<string> CreateCustomTokenAsync(
140141
};
141142

142143
var issued = (int)(this.clock.UtcNow - UnixEpoch).TotalSeconds;
143-
var keyId = await this.signer.GetKeyIdAsync(cancellationToken).ConfigureAwait(false);
144+
var keyId = await this.Signer.GetKeyIdAsync(cancellationToken).ConfigureAwait(false);
144145
var payload = new CustomTokenPayload()
145146
{
146147
Uid = uid,
@@ -158,7 +159,7 @@ internal async Task<string> CreateCustomTokenAsync(
158159
}
159160

160161
return await JwtUtils.CreateSignedJwtAsync(
161-
header, payload, this.signer, cancellationToken).ConfigureAwait(false);
162+
header, payload, this.Signer, cancellationToken).ConfigureAwait(false);
162163
}
163164

164165
internal class CustomTokenPayload : JsonWebToken.Payload

FirebaseAdmin/FirebaseAdmin/Auth/ProviderIdentifier.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public ProviderIdentifier(string providerId, string providerUid)
4343
/// <inheritdoc/>
4444
public override string ToString()
4545
{
46-
return "ProviderIdentifier(" + this.providerId + ", " + this.providerUid + ")";
46+
return $"ProviderIdentifier({this.providerId}, {this.providerUid})";
4747
}
4848

4949
internal override void Populate(GetAccountInfoRequest payload)

FirebaseAdmin/FirebaseAdmin/Auth/Users/FirebaseUserManager.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
using System;
1616
using System.Collections.Generic;
17+
using System.Linq;
1718
using System.Net.Http;
1819
using System.Threading;
1920
using System.Threading.Tasks;
@@ -338,8 +339,10 @@ internal async Task<DeleteUsersResult> DeleteUsersAsync(
338339
};
339340
var response = await this.PostAndDeserializeAsync<BatchDeleteResponse>(
340341
"accounts:batchDelete", payload, cancellationToken).ConfigureAwait(false);
341-
342-
return new DeleteUsersResult(uids.Count, response.Result);
342+
var errors = response.Result.Errors?
343+
.Select((error) => new ErrorInfo(error.Index, error.Message))
344+
.ToList();
345+
return new DeleteUsersResult(uids.Count, errors);
343346
}
344347

345348
internal async Task RevokeRefreshTokensAsync(string uid, CancellationToken cancellationToken)

0 commit comments

Comments
 (0)