public async Task GetScheduleAsync_When_Second_Call_And_Expired_Then_Returns_New_Schedule(TimeSpan addToCurrentExpiredDate)
        {
            IHdoScheduleProvider innerProvider = Substitute.For <IHdoScheduleProvider>();
            var firstHdoSchedule           = new HdoSchedule(TEST_PROVIDER_NAME, Enumerable.Empty <HdoScheduleIntervalDefinition>());
            var newScheduleAfterExpiration = new HdoSchedule(TEST_PROVIDER_NAME, Enumerable.Empty <HdoScheduleIntervalDefinition>());

            innerProvider.GetScheduleAsync(Arg.Any <IDictionary <string, string> >())
            .Returns(firstHdoSchedule, newScheduleAfterExpiration);
            var validFor = TimeSpan.FromHours(1);
            var now      = DateTime.Now;

            var         timeAfterExpiration = now + validFor + addToCurrentExpiredDate;
            var         isFirstCall         = true;
            HdoSchedule hdoSchedule;

            using (var cachedHdoProvider = new CachedHdoProvider(innerProvider, validFor, () => isFirstCall ? now : timeAfterExpiration))
            {
                var _ = await cachedHdoProvider.GetScheduleAsync(new Dictionary <string, string>());

                isFirstCall = false;

                hdoSchedule = await cachedHdoProvider.GetScheduleAsync(new Dictionary <string, string>());
            }

            Assert.AreSame(newScheduleAfterExpiration, hdoSchedule);
        }
        public async Task GetScheduleAsync_When_Second_Call_And_Not_Expired_Then_Returns_Same_Schedule()
        {
            IHdoScheduleProvider innerProvider = Substitute.For <IHdoScheduleProvider>();
            var expectedHdoSchedule            = new HdoSchedule(TEST_PROVIDER_NAME, Enumerable.Empty <HdoScheduleIntervalDefinition>());

            innerProvider.GetScheduleAsync(Arg.Any <IDictionary <string, string> >())
            .Returns(expectedHdoSchedule);
            var         validFor       = TimeSpan.FromHours(1);
            var         now            = DateTime.Now;
            var         secondCallTime = now.AddSeconds(1);
            var         isFirstCall    = true;
            HdoSchedule hdoSchedule2;

            using (var cachedHdoProvider = new CachedHdoProvider(innerProvider, validFor, () => isFirstCall
                                                             ? now
                                                             : secondCallTime))
            {
                var _ = await cachedHdoProvider.GetScheduleAsync(new Dictionary <string, string>());

                isFirstCall = false;

                hdoSchedule2 = await cachedHdoProvider.GetScheduleAsync(new Dictionary <string, string>());
            }

            Assert.AreSame(expectedHdoSchedule, hdoSchedule2);
        }
        public void Ctor_When_Inner_Provider_Is_Null_Then_Throws_ArgumentNullException()
        {
            IHdoScheduleProvider nullHdoProvider = null;
            var validFor = TimeSpan.FromHours(1);

            Assert.Catch <ArgumentNullException>(() =>
            {
                var _ = new CachedHdoProvider(nullHdoProvider, validFor);
            });
        }
        public async Task GetScheduleAsync_When_Using_Different_Args_Then_Returns_Different_Schedule()
        {
            IHdoScheduleProvider innerProvider = Substitute.For <IHdoScheduleProvider>();
            var expectedHdoSchedule            = new HdoSchedule(TEST_PROVIDER_NAME, Enumerable.Empty <HdoScheduleIntervalDefinition>());
            var expectedHdoSchedule2           = new HdoSchedule(TEST_PROVIDER_NAME, Enumerable.Empty <HdoScheduleIntervalDefinition>());

            var firstDictionary = new Dictionary <string, string>
            {
                ["key1"] = "value1"
            };

            var secondDictionary = new Dictionary <string, string>
            {
                ["key1"] = "value1",
                ["key2"] = "value2"
            };

            innerProvider.GetScheduleAsync(firstDictionary)
            .Returns(expectedHdoSchedule);

            innerProvider.GetScheduleAsync(secondDictionary)
            .Returns(expectedHdoSchedule2);

            var         validFor = TimeSpan.FromHours(1);
            var         now      = DateTime.Now;
            HdoSchedule hdoSchedule;
            HdoSchedule hdoSchedule2;
            HdoSchedule secondCallHdoSchedule;
            HdoSchedule secondCallHdoSchedule2;

            using (var cachedHdoProvider = new CachedHdoProvider(innerProvider, validFor))
            {
                hdoSchedule = await cachedHdoProvider.GetScheduleAsync(firstDictionary);

                hdoSchedule2 = await cachedHdoProvider.GetScheduleAsync(secondDictionary);

                secondCallHdoSchedule = await cachedHdoProvider.GetScheduleAsync(firstDictionary);

                secondCallHdoSchedule2 = await cachedHdoProvider.GetScheduleAsync(secondDictionary);
            }

            Assert.AreSame(expectedHdoSchedule, hdoSchedule);
            Assert.AreSame(expectedHdoSchedule2, hdoSchedule2);
            Assert.AreSame(expectedHdoSchedule, secondCallHdoSchedule);
            Assert.AreSame(expectedHdoSchedule2, secondCallHdoSchedule2);
        }
        public async Task GetScheduleAsync_When_First_Call_Then_Returns_Data_From_Underlying_ProviderAsync()
        {
            IHdoScheduleProvider innerProvider = Substitute.For <IHdoScheduleProvider>();
            var expectedHdoSchedule            = new HdoSchedule(TEST_PROVIDER_NAME, Enumerable.Empty <HdoScheduleIntervalDefinition>());

            innerProvider.GetScheduleAsync(Arg.Any <IDictionary <string, string> >())
            .Returns(expectedHdoSchedule);
            var         validFor = TimeSpan.FromHours(1);
            var         now      = DateTime.Now;
            HdoSchedule hdoSchedule;

            using (var cachedHdoProvider = new CachedHdoProvider(innerProvider, validFor, () => now))
            {
                hdoSchedule = await cachedHdoProvider.GetScheduleAsync(new Dictionary <string, string>());
            }

            Assert.AreSame(expectedHdoSchedule, hdoSchedule);
        }