Skip to content

Commit 567a0a8

Browse files
committed
generic: add OAuth test for generic provider
1 parent 4d7a46c commit 567a0a8

File tree

1 file changed

+85
-0
lines changed

1 file changed

+85
-0
lines changed

src/shared/Core.Tests/GenericHostProviderTests.cs

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Net.Http;
34
using System.Threading.Tasks;
45
using GitCredentialManager.Authentication;
6+
using GitCredentialManager.Authentication.OAuth;
57
using GitCredentialManager.Tests.Objects;
68
using Moq;
79
using Xunit;
@@ -185,6 +187,89 @@ public async Task GenericHostProvider_CreateCredentialAsync_WiaNotSupported_Retu
185187
await TestCreateCredentialAsync_ReturnsBasicCredential(wiaSupported: false);
186188
}
187189

190+
[Fact]
191+
public async Task GenericHostProvider_GenerateCredentialAsync_OAuth_CompleteOAuthConfig_UsesOAuth()
192+
{
193+
var input = new InputArguments(new Dictionary<string, string>
194+
{
195+
["protocol"] = "https",
196+
["host"] = "example.com",
197+
});
198+
199+
const string testUserName = "TEST_OAUTH_USER";
200+
const string testAcessToken = "OAUTH_TOKEN";
201+
const string testRefreshToken = "OAUTH_REFRESH_TOKEN";
202+
const string testResource = "https://example.com/";
203+
const string expectedRefreshTokenService = "https://example.com/refresh_token";
204+
205+
var authMode = OAuthAuthenticationModes.Browser;
206+
string[] scopes = { "code:write", "code:read" };
207+
string clientId = "3eadfc62-9e91-45d3-8c60-20ccd6d0c7cf";
208+
string clientSecret = "C1DA8B93CCB5F5B93DA";
209+
string redirectUri = "http://localhost";
210+
string authzEndpoint = "/oauth/authorize";
211+
string tokenEndpoint = "/oauth/token";
212+
string deviceEndpoint = "/oauth/device";
213+
214+
string GetKey(string name) => $"{Constants.GitConfiguration.Credential.SectionName}.https://example.com.{name}";
215+
216+
var context = new TestCommandContext
217+
{
218+
Git =
219+
{
220+
Configuration =
221+
{
222+
Global =
223+
{
224+
[GetKey(Constants.GitConfiguration.Credential.OAuthClientId)] = new[] { clientId },
225+
[GetKey(Constants.GitConfiguration.Credential.OAuthClientSecret)] = new[] { clientSecret },
226+
[GetKey(Constants.GitConfiguration.Credential.OAuthRedirectUri)] = new[] { redirectUri },
227+
[GetKey(Constants.GitConfiguration.Credential.OAuthScopes)] = new[] { string.Join(' ', scopes) },
228+
[GetKey(Constants.GitConfiguration.Credential.OAuthAuthzEndpoint)] = new[] { authzEndpoint },
229+
[GetKey(Constants.GitConfiguration.Credential.OAuthTokenEndpoint)] = new[] { tokenEndpoint },
230+
[GetKey(Constants.GitConfiguration.Credential.OAuthDeviceEndpoint)] = new[] { deviceEndpoint },
231+
[GetKey(Constants.GitConfiguration.Credential.OAuthDefaultUserName)] = new[] { testUserName },
232+
}
233+
}
234+
},
235+
Settings =
236+
{
237+
RemoteUri = new Uri(testResource)
238+
}
239+
};
240+
241+
var basicAuthMock = new Mock<IBasicAuthentication>();
242+
var wiaAuthMock = new Mock<IWindowsIntegratedAuthentication>();
243+
var oauthMock = new Mock<IOAuthAuthentication>();
244+
oauthMock.Setup(x =>
245+
x.GetAuthenticationModeAsync(It.IsAny<string>(), It.IsAny<OAuthAuthenticationModes>()))
246+
.ReturnsAsync(authMode);
247+
oauthMock.Setup(x => x.GetTokenByBrowserAsync(It.IsAny<OAuth2Client>(), It.IsAny<string[]>()))
248+
.ReturnsAsync(new OAuth2TokenResult(testAcessToken, "access_token")
249+
{
250+
Scopes = scopes,
251+
RefreshToken = testRefreshToken
252+
});
253+
254+
var provider = new GenericHostProvider(context, basicAuthMock.Object, wiaAuthMock.Object, oauthMock.Object);
255+
256+
ICredential credential = await provider.GenerateCredentialAsync(input);
257+
258+
Assert.NotNull(credential);
259+
Assert.Equal(testUserName, credential.Account);
260+
Assert.Equal(testAcessToken, credential.Password);
261+
262+
Assert.True(context.CredentialStore.TryGet(expectedRefreshTokenService, null, out TestCredential refreshToken));
263+
Assert.Equal(testUserName, refreshToken.Account);
264+
Assert.Equal(testRefreshToken, refreshToken.Password);
265+
266+
oauthMock.Verify(x => x.GetAuthenticationModeAsync(testResource, OAuthAuthenticationModes.All), Times.Once);
267+
oauthMock.Verify(x => x.GetTokenByBrowserAsync(It.IsAny<OAuth2Client>(), scopes), Times.Once);
268+
oauthMock.Verify(x => x.GetTokenByDeviceCodeAsync(It.IsAny<OAuth2Client>(), scopes), Times.Never);
269+
wiaAuthMock.Verify(x => x.GetIsSupportedAsync(It.IsAny<Uri>()), Times.Never);
270+
basicAuthMock.Verify(x => x.GetCredentialsAsync(It.IsAny<string>(), It.IsAny<string>()), Times.Never);
271+
}
272+
188273
#region Helpers
189274

190275
private static async Task TestCreateCredentialAsync_ReturnsEmptyCredential(bool wiaSupported)

0 commit comments

Comments
 (0)