public async Task SecretProviderCachingExtensions_TwoCallsWithinCacheInterval_ShouldGetSameValueTwice()
        {
            // Arrange
            string secretKeyValue     = Guid.NewGuid().ToString("N");
            var    testSecretProvider = new TestSecretProviderStub(secretKeyValue);
            string keyName            = "MyValue";

            // Act
            ICachedSecretProvider cachedSecretProvider = testSecretProvider.WithCaching(TimeSpan.FromSeconds(3));
            var firstValue = await cachedSecretProvider.GetRawSecretAsync(keyName);

            testSecretProvider.SecretValue = Guid.NewGuid().ToString("N"); // Change actual value on the internal secret provider !
            var secondValue = await cachedSecretProvider.GetRawSecretAsync(keyName);

            // Assert
            Assert.Equal(firstValue, secondValue);
            Assert.Equal(1, testSecretProvider.CallsMadeSinceCreation);
        }
        /// <summary>
        /// Retrieves the secret value, based on the given name
        /// </summary>
        /// <param name="secretName">The name of the secret key</param>
        /// <param name="ignoreCache">Indicates if the cache should be used or skipped</param>
        /// <returns>Returns a <see cref="Task{TResult}"/> that contains the secret key</returns>
        /// <exception cref="ArgumentException">The name must not be empty</exception>
        /// <exception cref="ArgumentNullException">The name must not be null</exception>
        /// <exception cref="SecretNotFoundException">The secret was not found, using the given name</exception>
        public async Task <string> GetRawSecretAsync(string secretName, bool ignoreCache)
        {
            Guard.NotNullOrWhitespace(secretName, nameof(secretName), "Requires a non-blank secret name when mutating secret names");

            string secretValue = await SafeguardMutateSecretAsync(secretName, mutatedSecretName =>
            {
                return(_implementation.GetRawSecretAsync(mutatedSecretName, ignoreCache));
            });

            return(secretValue);
        }
        public async Task SecretProviderCachingExtensions_TwoCallsOutsideCacheInterval_ShouldGetDifferentValue()
        {
            // Arrange
            string secretKeyValue     = Guid.NewGuid().ToString("N");
            var    testSecretProvider = new TestSecretProviderStub(secretKeyValue);

            string keyName = "MyValue";

            // Act
            ICachedSecretProvider cachedSecretProvider = testSecretProvider.WithCaching(TimeSpan.FromMilliseconds(100));
            var firstValue = await cachedSecretProvider.GetRawSecretAsync(keyName);

            await Task.Delay(TimeSpan.FromMilliseconds(150));

            string newSecretValue = Guid.NewGuid().ToString("N");

            testSecretProvider.SecretValue = newSecretValue; // Change actual value on the internal secret provider !
            var secondValue = await cachedSecretProvider.GetRawSecretAsync(keyName);

            // Assert
            Assert.Equal(secretKeyValue, firstValue);
            Assert.Equal(newSecretValue, secondValue);
            Assert.Equal(2, testSecretProvider.CallsMadeSinceCreation);
        }
 /// <summary>
 /// Retrieves the secret value, based on the given name.
 /// </summary>
 /// <param name="secretName">The name of the secret key</param>
 /// <param name="ignoreCache">Indicates if the cache should be used or skipped</param>
 /// <returns>Returns a <see cref="T:System.Threading.Tasks.Task`1" /> that contains the secret key</returns>
 /// <exception cref="T:System.ArgumentException">The name must not be empty</exception>
 /// <exception cref="T:System.ArgumentNullException">The name must not be null</exception>
 /// <exception cref="T:Arcus.Security.Core.SecretNotFoundException">The secret was not found, using the given name</exception>
 public async Task <string> GetRawSecretAsync(string secretName, bool ignoreCache)
 {
     Guard.NotNullOrWhitespace(secretName, nameof(secretName), "Requires a non-blank secret name to access the secret");
     return(await WhenAuthorized(() => _cachedSecretProvider.GetRawSecretAsync(secretName, ignoreCache)));
 }