From a8607eff533f14218bf0db13d9a24023915e3075 Mon Sep 17 00:00:00 2001 From: Christopher Scott Date: Thu, 5 Dec 2019 08:31:17 -0800 Subject: [PATCH] Make the AzureServiceTokenProvider mockable (#8464) --- .../MockUtil.cs | 21 +++++++++++++++++++ .../AzureServiceTokenProviderTests.cs | 9 ++++++++ .../AzureServiceTokenProvider.cs | 12 +++++------ ...ft.Azure.Services.AppAuthentication.csproj | 2 +- .../Properties/AssemblyInfo.cs | 4 ++-- 5 files changed, 39 insertions(+), 9 deletions(-) create mode 100644 sdk/mgmtcommon/AppAuthentication/Azure.Services.AppAuthentication.TestCommon/MockUtil.cs diff --git a/sdk/mgmtcommon/AppAuthentication/Azure.Services.AppAuthentication.TestCommon/MockUtil.cs b/sdk/mgmtcommon/AppAuthentication/Azure.Services.AppAuthentication.TestCommon/MockUtil.cs new file mode 100644 index 000000000000..4545d78fbc86 --- /dev/null +++ b/sdk/mgmtcommon/AppAuthentication/Azure.Services.AppAuthentication.TestCommon/MockUtil.cs @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Reflection; +using Xunit; + +namespace Microsoft.Azure.Services.AppAuthentication.TestCommon +{ + public class MockUtil + { + public static void AssertPublicMethodsAreVirtual() + { + foreach (MethodInfo methodInfo in typeof(T).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly)) + { + Assert.True(methodInfo.IsVirtual, $"Method {methodInfo.Name} is not virtual"); + } + } + } +} \ No newline at end of file diff --git a/sdk/mgmtcommon/AppAuthentication/Azure.Services.AppAuthentication.Unit.Tests/AzureServiceTokenProviderTests.cs b/sdk/mgmtcommon/AppAuthentication/Azure.Services.AppAuthentication.Unit.Tests/AzureServiceTokenProviderTests.cs index 60cdce5b5138..353dc77b5cba 100644 --- a/sdk/mgmtcommon/AppAuthentication/Azure.Services.AppAuthentication.Unit.Tests/AzureServiceTokenProviderTests.cs +++ b/sdk/mgmtcommon/AppAuthentication/Azure.Services.AppAuthentication.Unit.Tests/AzureServiceTokenProviderTests.cs @@ -304,5 +304,14 @@ public void DiscoveryTestBothFail() Environment.SetEnvironmentVariable(Constants.MsiAppServiceEndpointEnv,null); Environment.SetEnvironmentVariable(Constants.MsiAppServiceSecretEnv, null); } + + /// + /// Ensure that all public methods are marked virtual to maintain mockability + /// + [Fact] + public void RemainMockable() + { + MockUtil.AssertPublicMethodsAreVirtual(); + } } } diff --git a/sdk/mgmtcommon/AppAuthentication/Azure.Services.AppAuthentication/AzureServiceTokenProvider.cs b/sdk/mgmtcommon/AppAuthentication/Azure.Services.AppAuthentication/AzureServiceTokenProvider.cs index 7731aaa4a5f4..2315f28a11cf 100644 --- a/sdk/mgmtcommon/AppAuthentication/Azure.Services.AppAuthentication/AzureServiceTokenProvider.cs +++ b/sdk/mgmtcommon/AppAuthentication/Azure.Services.AppAuthentication/AzureServiceTokenProvider.cs @@ -44,7 +44,7 @@ public class AzureServiceTokenProvider /// KeyVaultClient keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback)); /// /// - public TokenCallback KeyVaultTokenCallback => async (authority, resource, scope) => + public virtual TokenCallback KeyVaultTokenCallback => async (authority, resource, scope) => { var authResult = await GetAuthResultAsyncImpl(resource, authority).ConfigureAwait(false); return authResult.AccessToken; @@ -53,7 +53,7 @@ public class AzureServiceTokenProvider /// /// The principal used to acquire token. This will be of type "User" for local development scenarios, and "App" when client credentials flow is used. /// - public Principal PrincipalUsed => _principalUsed; + public virtual Principal PrincipalUsed => _principalUsed; /// /// Creates an instance of the AzureServiceTokenProvider class. @@ -240,7 +240,7 @@ private List GetTokenProviders() /// Access token /// Thrown if resource is null or empty. /// Thrown if access token cannot be acquired. - public async Task GetAccessTokenAsync(string resource, string tenantId = default(string), + public virtual async Task GetAccessTokenAsync(string resource, string tenantId = default(string), CancellationToken cancellationToken = default(CancellationToken)) { var authResult = await GetAuthenticationResultAsync(resource, tenantId, cancellationToken).ConfigureAwait(false); @@ -248,7 +248,7 @@ private List GetTokenProviders() return authResult.AccessToken; } - public Task GetAccessTokenAsync(string resource, string tenantId) + public virtual Task GetAccessTokenAsync(string resource, string tenantId) { return GetAccessTokenAsync(resource, tenantId, default(CancellationToken)); } @@ -267,7 +267,7 @@ public Task GetAccessTokenAsync(string resource, string tenantId) /// Access token /// Thrown if resource is null or empty. /// Thrown if access token cannot be acquired. - public Task GetAuthenticationResultAsync(string resource, string tenantId = default(string), + public virtual Task GetAuthenticationResultAsync(string resource, string tenantId = default(string), CancellationToken cancellationToken = default(CancellationToken)) { if (string.IsNullOrWhiteSpace(resource)) @@ -280,7 +280,7 @@ public Task GetAccessTokenAsync(string resource, string tenantId) return GetAuthResultAsyncImpl(resource, authority, cancellationToken); } - public Task GetAuthenticationResultAsync(string resource, string tenantId) + public virtual Task GetAuthenticationResultAsync(string resource, string tenantId) { return GetAuthenticationResultAsync(resource, tenantId, default(CancellationToken)); } diff --git a/sdk/mgmtcommon/AppAuthentication/Azure.Services.AppAuthentication/Microsoft.Azure.Services.AppAuthentication.csproj b/sdk/mgmtcommon/AppAuthentication/Azure.Services.AppAuthentication/Microsoft.Azure.Services.AppAuthentication.csproj index 69d8953d6967..a88ea0b1b1f3 100644 --- a/sdk/mgmtcommon/AppAuthentication/Azure.Services.AppAuthentication/Microsoft.Azure.Services.AppAuthentication.csproj +++ b/sdk/mgmtcommon/AppAuthentication/Azure.Services.AppAuthentication/Microsoft.Azure.Services.AppAuthentication.csproj @@ -2,7 +2,7 @@ Microsoft.Azure.Services.AppAuthentication Enables a service to authenticate to Azure services using the developer's Azure Active Directory/ Microsoft account during development, and authenticate as itself (using OAuth 2.0 Client Credentials flow) when deployed to Azure. - 1.3.1 + 1.4.0 Microsoft.Azure.Services.AppAuthentication Azure Authentication AppAuthentication diff --git a/sdk/mgmtcommon/AppAuthentication/Azure.Services.AppAuthentication/Properties/AssemblyInfo.cs b/sdk/mgmtcommon/AppAuthentication/Azure.Services.AppAuthentication/Properties/AssemblyInfo.cs index 4c2731e10440..ebc9ad69cab5 100644 --- a/sdk/mgmtcommon/AppAuthentication/Azure.Services.AppAuthentication/Properties/AssemblyInfo.cs +++ b/sdk/mgmtcommon/AppAuthentication/Azure.Services.AppAuthentication/Properties/AssemblyInfo.cs @@ -4,8 +4,8 @@ [assembly: AssemblyTitle("Microsoft.Azure.Services.AppAuthentication")] [assembly: AssemblyDescription("Enables a service to authenticate to Azure services using the developer's Azure Active Directory/ Microsoft account during development, and authenticate as itself (using OAuth 2.0 Client Credentials flow) when deployed to Azure.")] -[assembly: AssemblyVersion("1.3.1.0")] -[assembly: AssemblyFileVersion("1.3.1.0")] +[assembly: AssemblyVersion("1.4.0.0")] +[assembly: AssemblyFileVersion("1.4.0.0")] [assembly: AssemblyCompany("Microsoft Corporation")] [assembly: AssemblyProduct("Microsoft Azure")] [assembly: AssemblyCopyright("Copyright (c) Microsoft Corporation. All rights reserved.")]