public async Task KeyVaultSecretProvider_StoreSecret_Succeeds()
        {
            // Arrange
            var    keyVaultUri = Configuration.GetValue <string>("Arcus:KeyVault:Uri");
            string tenantId    = Configuration.GetTenantId();
            string clientId    = Configuration.GetServicePrincipalClientId();
            string clientKey   = Configuration.GetServicePrincipalClientSecret();

            var secretName  = $"Test-Secret-{Guid.NewGuid()}";
            var secretValue = Guid.NewGuid().ToString();

            using (TemporaryEnvironmentVariable.Create(Constants.AzureTenantIdEnvironmentVariable, tenantId))
                using (TemporaryEnvironmentVariable.Create(Constants.AzureServicePrincipalClientIdVariable, clientId))
                    using (TemporaryEnvironmentVariable.Create(Constants.AzureServicePrincipalClientSecretVariable, clientKey))
                    {
                        var keyVaultSecretProvider = new KeyVaultSecretProvider(
                            tokenCredential: new ChainedTokenCredential(new ManagedIdentityCredential(clientId), new EnvironmentCredential()),
                            vaultConfiguration: new KeyVaultConfiguration(keyVaultUri));
                        var cachedSecretProvider = new KeyVaultCachedSecretProvider(keyVaultSecretProvider);

                        // Act
                        Secret secret = await cachedSecretProvider.StoreSecretAsync(secretName, secretValue);

                        // Assert
                        Assert.NotNull(secret);
                        Assert.NotNull(secret.Value);
                        Assert.NotNull(secret.Version);
                        Secret fetchedSecret = await cachedSecretProvider.GetSecretAsync(secretName);

                        Assert.Equal(secretValue, fetchedSecret.Value);
                        Assert.Equal(secret.Version, fetchedSecret.Version);
                        Assert.Equal(secret.Expires, fetchedSecret.Expires);
                    }
        }
        public async Task StoreSecret_WithoutSecretValue_Fails()
        {
            // Arrange
            var stubProvider   = new SpyKeyVaultSecretProvider(Mock.Of <TokenCredential>(), new KeyVaultConfiguration("https://some-key.vault.azure.net"));
            var cachedProvider = new KeyVaultCachedSecretProvider(stubProvider);

            // Act / Assert
            await Assert.ThrowsAnyAsync <ArgumentException>(
                () => cachedProvider.StoreSecretAsync(secretName: "SomeKey", secretValue: null));
        }
        public async Task StoreSecret_UsesCache_WhenWithinCacheInterval()
        {
            // Arrange
            string secretName     = $"MySecret-{Guid.NewGuid()}";
            string secretValue1   = $"secret-{Guid.NewGuid()}";
            string secretValue2   = $"secret-{Guid.NewGuid()}";
            var    spyProvider    = new SpyKeyVaultSecretProvider(Mock.Of <TokenCredential>(), new KeyVaultConfiguration("https://some-key.vault.azure.net"));
            var    cachedProvider = new KeyVaultCachedSecretProvider(spyProvider);
            await cachedProvider.StoreSecretAsync(secretName, secretValue1);

            // Act
            await cachedProvider.StoreSecretAsync(secretName, secretValue2);

            // Assert
            string actual = await cachedProvider.GetRawSecretAsync(secretName);

            Assert.Equal(secretValue2, actual);
            Assert.Equal(2, spyProvider.StoreSecretCalls);
            Assert.Equal(0, spyProvider.GetRawSecretCalls);
        }