public void GetArgumentCacheKey_CreatesProperKey_ForUserDefinedType()
        {
            A.CallTo(() => CacheKeyRegistrationService.GetCacheKeyFormatter<TestModelDefinition>()).Returns(x => $"{x.Id}");
            A.CallTo(() => CacheKeyRegistrationService.IsFormatterRegistered(typeof(TestModelDefinition))).Returns(true);

            var model = new TestModelDefinition { Id = 100 };
            var result = CacheKeyGenerationService.GetArgumentsCacheKey(new object[] { model });

            Assert.AreEqual("TestModelDefinition::100", result);
        }
        public void Intercept_ChecksCacheAndInvokesThenCachesTheResult_WhenTheCacheDoesNotContainTheKey()
        {
            const string cacheKey = "cacheKey";
            const string region = null;
            var returnValue = new TestModelDefinition { Id = 500 };

            var methodInfo =
                typeof(TestModelDefinition).GetMethod(nameof(TestModelDefinition.TestMethod_WithCacheAttribute));

            A.CallTo(() => Invocation.GetConcreteMethodInvocationTarget()).Returns(methodInfo);
            A.CallTo(() => CacheKeyGenerationService.GetCacheKey(methodInfo, A<object[]>.Ignored)).Returns(cacheKey);
            A.CallTo(() => Cache.Contains(cacheKey, region)).Returns(false);
            A.CallTo(() => Invocation.ReturnValue).Returns(returnValue);

            Interceptor.Intercept(Invocation);

            A.CallTo(() => Invocation.Proceed()).MustHaveHappened();
            A.CallTo(() => CacheKeyGenerationService.GetCacheKey(methodInfo, A<object[]>.Ignored)).MustHaveHappened();
            A.CallTo(() => Cache.Set(A<CacheItem>.Ignored, A<CacheItemPolicy>.Ignored)).MustHaveHappened();
        }
        public void Intercept_ChecksAndReturnsCachedContent_WhenTheCacheContainsTheKey()
        {
            const string cacheKey = "cacheKey(<no_arguments>)";
            const string region = null;
            var cacheOutput = new TestModelDefinition { Id = 100 };

            var methodInfo =
                typeof(TestModelDefinition).GetMethod(nameof(TestModelDefinition.TestMethod_WithCacheAttribute));

            A.CallTo(() => Invocation.GetConcreteMethodInvocationTarget()).Returns(methodInfo);
            A.CallTo(() => CacheKeyGenerationService.GetCacheKey(methodInfo, A<object[]>.Ignored)).Returns(cacheKey);
            A.CallTo(() => Cache.Contains(cacheKey, region)).Returns(true);
            A.CallTo(() => Cache.Get(cacheKey, region)).Returns(cacheOutput);

            Interceptor.Intercept(Invocation);

            A.CallTo(() => Invocation.Proceed()).MustNotHaveHappened();
            A.CallTo(() => CacheKeyGenerationService.GetCacheKey(methodInfo, A<object[]>.Ignored)).MustHaveHappened();
            A.CallTo(() => Cache.Get(cacheKey, region)).MustHaveHappened();

            Assert.AreEqual(cacheOutput, Invocation.ReturnValue);
        }
        public void GetCacheKey_FormatsCacheKey_WhenEnumerableOutputIsDefined_AndNoParameters()
        {
            var model = new TestModelDefinition();
            var methodInfo = model.GetType().GetMethod(nameof(model.TestMethod_EnumerableReturn));

            var result = CacheKeyGenerationService.GetCacheKey(methodInfo, null);
            var expectedResult = $"Cash.Core.Tests.Models.TestModelDefinition.TestMethod_EnumerableReturn<Int32>({NullOrZeroArgumentsResult})";

            Assert.AreEqual(expectedResult, result);
        }
        public void GetCacheKey_FormatsCacheKey_WhenEnumerableParameterIsDefined()
        {
            var model = new TestModelDefinition();
            var methodInfo = model.GetType().GetMethod(nameof(model.TestMethod_EnumerableParameter));

            var result = CacheKeyGenerationService.GetCacheKey(methodInfo, new object[] { 10, 20 });
            var expectedResult = $"Cash.Core.Tests.Models.TestModelDefinition.TestMethod_EnumerableParameter(Int32::10||Int32::20)";

            Assert.AreEqual(expectedResult, result);
        }
        public void GetArgumentsCacheKey_ThrowsAnException_WhenNoProviderIsRegistered()
        {
            A.CallTo(() => CacheKeyRegistrationService.IsFormatterRegistered(typeof(TestModelDefinition))).Returns(false);

            var model = new TestModelDefinition { Id = 100 };
            var result = CacheKeyGenerationService.GetArgumentsCacheKey(new object[] { model });
        }
        public void GetArgumentCacheKey_ThrowsAnException_WhenACacheKeyProviderHasNotBeenRegistered()
        {
            A.CallTo(() => CacheKeyRegistrationService.GetCacheKeyFormatter<TestModelDefinition>()).Throws(new UnregisteredCacheTypeException(typeof(TestModelDefinition)));
            A.CallTo(() => CacheKeyRegistrationService.IsFormatterRegistered(typeof(TestModelDefinition))).Returns(true);

            var model = new TestModelDefinition { Id = 100 };
            var result = CacheKeyGenerationService.GetArgumentsCacheKey(new object[] { model });
        }