Skip to content

Commit 9efc68a

Browse files
feat: Add credential type parameter to CredentialFactory
1 parent 65f4435 commit 9efc68a

File tree

2 files changed

+282
-18
lines changed

2 files changed

+282
-18
lines changed

Src/Support/Google.Apis.Auth.Tests/OAuth2/GoogleCredentialTests.cs

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -846,6 +846,148 @@ public async Task UniverseDomain_DifferentCustomInRequestAndCredential()
846846
Assert.Null(request.Headers.Authorization?.Parameter);
847847
}
848848

849+
[Theory]
850+
[MemberData(nameof(CredentialFactory_Success_Data))]
851+
public void FromFile_WithType(string json, string credentialType, Type expectedType)
852+
{
853+
var tempFile = Path.GetTempFileName();
854+
try
855+
{
856+
File.WriteAllText(tempFile, json);
857+
var credential = CredentialFactory.FromFile(tempFile, credentialType);
858+
Assert.IsType(expectedType, credential.UnderlyingCredential);
859+
}
860+
finally
861+
{
862+
File.Delete(tempFile);
863+
}
864+
}
865+
866+
[Theory]
867+
[MemberData(nameof(CredentialFactory_Failure_Data))]
868+
public void FromFile_WithType_Failure(string json, string credentialType, string expectedMessage)
869+
{
870+
var tempFile = Path.GetTempFileName();
871+
try
872+
{
873+
File.WriteAllText(tempFile, json);
874+
var ex = Assert.Throws<InvalidOperationException>(() => CredentialFactory.FromFile(tempFile, credentialType));
875+
Assert.Equal(expectedMessage, ex.Message);
876+
}
877+
finally
878+
{
879+
File.Delete(tempFile);
880+
}
881+
}
882+
883+
[Theory]
884+
[MemberData(nameof(CredentialFactory_Success_Data))]
885+
public void FromJson_WithType(string json, string credentialType, Type expectedType)
886+
{
887+
var credential = CredentialFactory.FromJson(json, credentialType);
888+
Assert.IsType(expectedType, credential.UnderlyingCredential);
889+
}
890+
891+
[Theory]
892+
[MemberData(nameof(CredentialFactory_Failure_Data))]
893+
public void FromJson_WithType_Failure(string json, string credentialType, string expectedMessage)
894+
{
895+
var ex = Assert.Throws<InvalidOperationException>(() => CredentialFactory.FromJson(json, credentialType));
896+
Assert.Equal(expectedMessage, ex.Message);
897+
}
898+
899+
[Theory]
900+
[MemberData(nameof(CredentialFactory_Success_Data))]
901+
public async Task FromFileAsync_WithType(string json, string credentialType, Type expectedType)
902+
{
903+
var tempFile = Path.GetTempFileName();
904+
try
905+
{
906+
File.WriteAllText(tempFile, json);
907+
var credential = await CredentialFactory.FromFileAsync(tempFile, credentialType, CancellationToken.None);
908+
Assert.IsType(expectedType, credential.UnderlyingCredential);
909+
}
910+
finally
911+
{
912+
File.Delete(tempFile);
913+
}
914+
}
915+
916+
[Theory]
917+
[MemberData(nameof(CredentialFactory_Failure_Data))]
918+
public async Task FromFileAsync_WithType_Failure(string json, string credentialType, string expectedMessage)
919+
{
920+
var tempFile = Path.GetTempFileName();
921+
try
922+
{
923+
File.WriteAllText(tempFile, json);
924+
var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => CredentialFactory.FromFileAsync(tempFile, credentialType, CancellationToken.None));
925+
Assert.Equal(expectedMessage, ex.Message);
926+
}
927+
finally
928+
{
929+
File.Delete(tempFile);
930+
}
931+
}
932+
933+
public static TheoryData<string, string, Type> CredentialFactory_Success_Data() =>
934+
new TheoryData<string, string, Type>
935+
{
936+
{ FakeUserCredentialFileContents, JsonCredentialParameters.AuthorizedUserCredentialType, typeof(UserCredential) },
937+
{ FakeServiceAccountCredentialFileContents, JsonCredentialParameters.ServiceAccountCredentialType, typeof(ServiceAccountCredential) }
938+
};
939+
940+
public static TheoryData<string, string, string> CredentialFactory_Failure_Data() =>
941+
new TheoryData<string, string, string>
942+
{
943+
{ FakeUserCredentialFileContents, JsonCredentialParameters.ServiceAccountCredentialType, "The credential type authorized_user is not compatible with the requested type service_account" },
944+
{ FakeUserCredentialFileContents, "invalid_type", "The credential type authorized_user is not compatible with the requested type invalid_type" },
945+
{ "invalid_json", "any_type", "Error deserializing JSON credential data." }
946+
};
947+
948+
[Fact]
949+
public void FromStream_WrapsDeserializationException_WithBadJson()
950+
{
951+
string malformedUserCredentialFileContents = FakeUserCredentialFileContents.Replace("}","");
952+
using Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(malformedUserCredentialFileContents));
953+
var ex = Assert.Throws<InvalidOperationException>(() => CredentialFactory.FromStream<UserCredential>(stream));
954+
Assert.Equal("Error deserializing JSON credential data.", ex.Message);
955+
Assert.IsType<Newtonsoft.Json.JsonSerializationException>(ex.InnerException);
956+
}
957+
958+
[Fact]
959+
public void FromStream_WrapsDeserializationException()
960+
{
961+
var stream = new MockStream(() => throw new Exception("Underlying exception"));
962+
var ex = Assert.Throws<InvalidOperationException>(() => CredentialFactory.FromStream<UserCredential>(stream));
963+
Assert.Equal("Error deserializing JSON credential data.", ex.Message);
964+
Assert.IsType<Exception>(ex.InnerException);
965+
Assert.Equal("Underlying exception", ex.InnerException.Message);
966+
}
967+
968+
private class MockStream : Stream
969+
{
970+
private readonly Action _onRead;
971+
972+
public MockStream(Action onRead) => _onRead = onRead;
973+
974+
public override bool CanRead => true;
975+
public override bool CanSeek => false;
976+
public override bool CanWrite => false;
977+
public override long Length => throw new NotSupportedException();
978+
public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); }
979+
980+
public override void Flush() => throw new NotSupportedException();
981+
public override int Read(byte[] buffer, int offset, int count)
982+
{
983+
_onRead();
984+
return 0;
985+
}
986+
public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException();
987+
public override void SetLength(long value) => throw new NotSupportedException();
988+
public override void Write(byte[] buffer, int offset, int count) => throw new NotSupportedException();
989+
}
990+
849991
/// <summary>
850992
/// Fake implementation of <see cref="IAuthorizationCodeFlow"/> which only supports fetching the
851993
/// clock and the access method.

0 commit comments

Comments
 (0)