public async Task GetCategories_Uses_Cache_When_Data_Available()
        {
            var cacheService = new MockCacheService();
            cacheService.DataExistsAndIsValidAsyncDelegate = s => Task.FromResult(true);
            
            var categories = new List<Category>
            {
                new Category{ Id = 1},
                new Category{ Id = 2}
            };

            cacheService.GetDataDelegate = (string s) =>
            {
                if (s == "Categories0")
                    return new ReadOnlyCollection<Category>(categories);

                return new ReadOnlyCollection<Category>(null);
            };

            var productCatalogService = new MockProductCatalogService();
            productCatalogService.GetCategoriesAsyncDelegate = (depth) => Task.FromResult(new ReadOnlyCollection<Category>(null));

            var target = new ProductCatalogRepository(productCatalogService, cacheService);

            var returnedCategories = await target.GetCategoriesAsync(0);

            Assert.AreEqual(2, returnedCategories.Count);
            Assert.AreEqual(1, returnedCategories[0].Id);
            Assert.AreEqual(2, returnedCategories[1].Id);
        }
        public async Task GetCategories_Calls_Service_When_Cache_Miss()
        {
            var cacheService = new MockCacheService();
            cacheService.DataExistsAndIsValidAsyncDelegate = s => Task.FromResult(false);
            cacheService.SaveExternalDataAsyncDelegate = s => Task.FromResult(new Uri("http://test.org"));
            cacheService.SaveDataAsyncDelegate = (s, c) => Task.FromResult(new Uri("http://test.org"));

            var productCatalogService = new MockProductCatalogService();
            var categories = new List<Category>
            {
                new Category{ Id = 1},
                new Category{ Id = 2}
            };

            productCatalogService.GetCategoriesAsyncDelegate = (depth) => Task.FromResult(new ReadOnlyCollection<Category>(categories));
            productCatalogService.GetSubcategoriesAsyncDelegate = (i) => Task.FromResult(new ReadOnlyCollection<Category>(null));
            
            var target = new ProductCatalogRepository(productCatalogService, cacheService);
            var returnedCategories = await target.GetCategoriesAsync(0);

            Assert.AreEqual(2, returnedCategories.Count);
            Assert.AreEqual(1, returnedCategories[0].Id);
            Assert.AreEqual(2, returnedCategories[1].Id);
        }
        public async Task GetCategories_Saves_Data_To_Cache()
        {
            var cacheService = new MockCacheService();
            cacheService.DataExistsAndIsValidAsyncDelegate = s => Task.FromResult(false);
            cacheService.SaveExternalDataAsyncDelegate = s => Task.FromResult(new Uri("http://test.org"));

            cacheService.SaveDataAsyncDelegate = (s, o) =>
            {
                var collection = (ReadOnlyCollection<Category>)o;
                Assert.AreEqual("Categories0", s);
                Assert.AreEqual(2, collection.Count);
                Assert.AreEqual(1, collection[0].Id);
                Assert.AreEqual(2, collection[1].Id);
                return Task.FromResult(new Uri("http://test.org"));
            };

            var productCatalogService = new MockProductCatalogService();
            var categories = new List<Category>
                                 {
                                     new Category{ Id = 1},
                                     new Category{ Id = 2}
                                 };
            productCatalogService.GetCategoriesAsyncDelegate = (depth) => Task.FromResult(new ReadOnlyCollection<Category>(categories));
            productCatalogService.GetSubcategoriesAsyncDelegate =
                i => Task.FromResult(new ReadOnlyCollection<Category>(null));

            var target = new ProductCatalogRepository(productCatalogService, cacheService);

            await target.GetCategoriesAsync(0);
        }