public void GetCacheKey_OnlyEnabledCompositeProvidersAreAssessed([Values(true, false)] bool aEnabled, [Values(true, false)] bool bEnabled, [Values(true, false)] bool cEnabled, [Values(true, false)] bool dEnabled)
        {
            var mockA = CompositeCacheKeyHelper.CreateMock("a");
            var mockB = CompositeCacheKeyHelper.CreateMock("b");
            var mockC = CompositeCacheKeyHelper.CreateMock("c");
            var mockD = CompositeCacheKeyHelper.CreateMock("d");

            mCompositeCacheKeyProviders.Add(mockA.Object);
            mCompositeCacheKeyProviders.Add(mockB.Object);
            mCompositeCacheKeyProviders.Add(mockC.Object);
            mCompositeCacheKeyProviders.Add(mockD.Object);

            Setup();

            var providerSettings = new Dictionary <string, bool>
            {
                { mockA.Object.TechnicalName, aEnabled },
                { mockB.Object.TechnicalName, bEnabled },
                { mockC.Object.TechnicalName, cEnabled },
                { mockD.Object.TechnicalName, dEnabled },
            };

            var contentItem = ContentItem.WithPart(new ItemLevelCachePart(), "Article");

            contentItem.As <ItemLevelCachePart>().ItemLevelCacheSettings["Detail"] = new ItemLevelCacheSettings {
                CompositeCacheKeyProviders = providerSettings
            };

            mSut.GetCacheKey(contentItem, "Detail");

            mockA.Verify(p => p.GetCacheKeyValue(), Times.Exactly(aEnabled ? 1 : 0));
            mockB.Verify(p => p.GetCacheKeyValue(), Times.Exactly(bEnabled ? 1 : 0));
            mockC.Verify(p => p.GetCacheKeyValue(), Times.Exactly(cEnabled ? 1 : 0));
            mockD.Verify(p => p.GetCacheKeyValue(), Times.Exactly(dEnabled ? 1 : 0));
        }
        public void GetCacheKey_CompositeProvidersAreDeterminiticallyOrdered()
        {
            // No matter which order the providers are evaluated, the resulting cache key must always be the same
            var combinationStrings = new[]
            {
                "abcd",
                "abdc",
                "acbd",
                "acdb",
                "adbc",
                "adcb",
                "badc",
                "bacd",
                "bcda",
                "bcad",
                "bdca",
                "bdac",
                "cabd",
                "cadb",
                "cbad",
                "cbda",
                "cdab",
                "cdba",
                "dacb",
                "dabc",
                "dbca",
                "dbac",
                "dcba",
                "dcab"
            };

            var providerSettings = new Dictionary <string, bool>
            {
                { "a", true },
                { "b", true },
                { "c", true },
                { "d", true },
            };

            var contentItem = ContentItem.WithPart(new ItemLevelCachePart(), "Article");

            contentItem.As <ItemLevelCachePart>().ItemLevelCacheSettings["Detail"] = new ItemLevelCacheSettings {
                CompositeCacheKeyProviders = providerSettings
            };

            var cacheKeys = new List <string>();

            foreach (var combinationString in combinationStrings)
            {
                mCompositeCacheKeyProviders.Clear();

                foreach (var c in combinationString.ToCharArray())
                {
                    mCompositeCacheKeyProviders.Add(CompositeCacheKeyHelper.CreateMock(c.ToString()).Object);
                }

                Setup();

                cacheKeys.Add(mSut.GetCacheKey(contentItem, "Detail"));
            }

            Assert.AreEqual(combinationStrings.Length, cacheKeys.Count, "The number of generated cache keys does not match the number of times get cache key should have been called. This is more than likely an issue with the test, as opposed to an issue with the service being tested.");
            Assert.AreEqual(1, cacheKeys.Distinct().Count());
        }