public async Task FindSeriesAsync_NoMatchingSeriesName_ReturnsNone()
        {
            var client = new TvDbClientV2(new JsonConnection(new TestHttpClient(), new JsonSerialiser(), this.logManager),
                                          this.fileCache, this.applicationPaths, this.logManager, new JsonSerialiser(), new PluginConfiguration
            {
                TvDbApiKey = Secrets.TvDbApiKey
            });

            var seriesResult = await client.FindSeriesAsync("NotASeries");

            seriesResult.IsSome.Should().BeFalse();
        }
        public async Task GetSeriesAsync_FailedResponse_ReturnsNone()
        {
            this.jsonConnection.GetAsync(Arg.Any <GetSeriesRequest>(), Arg.Any <Option <string> >())
            .Returns(new FailedRequest(HttpStatusCode.BadRequest, "Failed"));

            var tvDbClient = new TvDbClientV2(this.jsonConnection, this.fileCache, this.applicationPaths, this.logManager,
                                              new JsonSerialiser(), new PluginConfiguration());

            var seriesResult = await tvDbClient.GetSeriesAsync(4);

            seriesResult.IsSome.Should().BeFalse();
        }
        public async Task GetEpisodesAsync_LocalEpisodeData_ReturnsLocalEpisodeData()
        {
            var episode = new TvDbEpisodeData(1, "Test", 1L, 2, 3, 4, new DateTime(2017, 1, 2, 3, 4, 5), "Overview", 3.77f, 12);

            this.fileCache.GetFileContent(Arg.Any <TvDbSeriesEpisodesFileSpec>())
            .Returns(new TvDbEpisodeCollection(new[] { episode }));

            var tvDbClient = new TvDbClientV2(this.jsonConnection, this.fileCache, this.applicationPaths, this.logManager,
                                              new JsonSerialiser(), new PluginConfiguration());

            var episodes = await tvDbClient.GetEpisodesAsync(4);

            episodes.IsSome.Should().BeTrue();
            episodes.ValueUnsafe().Should().BeEquivalentTo(new[] { episode });
        }
        public async Task GetEpisodesAsync_LocalEpisodeData_DoesNotRequestEpisodeData()
        {
            var episode = new TvDbEpisodeData(1, "Test", 1L, 2, 3, 4, new DateTime(2017, 1, 2, 3, 4, 5), "Overview", 3.77f, 12);

            this.fileCache.GetFileContent(Arg.Any <TvDbSeriesEpisodesFileSpec>())
            .Returns(new TvDbEpisodeCollection(new[] { episode }));

            var tvDbClient = new TvDbClientV2(this.jsonConnection, this.fileCache, this.applicationPaths, this.logManager,
                                              new JsonSerialiser(), new PluginConfiguration());

            await tvDbClient.GetEpisodesAsync(4);

            await this.jsonConnection.DidNotReceiveWithAnyArgs()
            .GetAsync <GetEpisodesRequest.Response>(null, Option <string> .None);
        }
        public async Task GetSeriesAsync_NoLocalSeriesData_ReturnsNewSeriesData()
        {
            var series = new TvDbSeriesData(4, "TestSeries", new DateTime(2017, 1, 1, 1, 1, 1), string.Empty, 2,
                                            AirDay.Monday, string.Empty, 4f, new[] { "Alias1", "Alias2" }, new[] { "Genre1", "Genre2" },
                                            "Overview");

            this.jsonConnection.GetAsync(Arg.Any <GetSeriesRequest>(), Arg.Any <Option <string> >())
            .Returns(new Response <GetSeriesRequest.Response>(new GetSeriesRequest.Response(series)));

            var tvDbClient = new TvDbClientV2(this.jsonConnection, this.fileCache, this.applicationPaths, this.logManager,
                                              new JsonSerialiser(), new PluginConfiguration());

            var seriesResult = await tvDbClient.GetSeriesAsync(4);

            seriesResult.IsSome.Should().BeTrue();
            seriesResult.ValueUnsafe().Should().Be(series);
        }
        public async Task GetSeriesAsync_NoLocalSeriesData_RequestsSeriesData()
        {
            var series = new TvDbSeriesData(4, "TestSeries", new DateTime(2017, 1, 1, 1, 1, 1), string.Empty, 2,
                                            AirDay.Monday, string.Empty, 4f, new[] { "Alias1", "Alias2" }, new[] { "Genre1", "Genre2" },
                                            "Overview");

            this.jsonConnection.GetAsync(Arg.Any <GetSeriesRequest>(), Arg.Any <Option <string> >())
            .Returns(new Response <GetSeriesRequest.Response>(new GetSeriesRequest.Response(series)));

            var tvDbClient = new TvDbClientV2(this.jsonConnection, this.fileCache, this.applicationPaths, this.logManager,
                                              new JsonSerialiser(), new PluginConfiguration());

            await tvDbClient.GetSeriesAsync(4);

            await this.jsonConnection.ReceivedWithAnyArgs(1)
            .GetAsync <GetSeriesRequest.Response>(null, Option <string> .None);
        }
        public async Task GetEpisodesAsync_MultiPageResponse_RequestsAllPages()
        {
            var page1Episode       = new TvDbEpisodeSummaryData(1, "Test1", 1L, 2, 3, 4, new DateTime(2017, 1, 2, 3, 4, 5), "Overview");
            var page1EpisodeDetail = new TvDbEpisodeData(1, "Test", 1L, 2, 3, 4, new DateTime(2017, 1, 2, 3, 4, 5), "Overview", 33.4f, 12);

            var page2Episode       = new TvDbEpisodeSummaryData(2, "Test2", 5L, 6, 7, 8, new DateTime(2017, 1, 2, 3, 4, 5), "Overview");
            var page2EpisodeDetail = new TvDbEpisodeData(2, "Test2", 5L, 6, 7, 8, new DateTime(2017, 1, 2, 3, 4, 5), "Overview", 33.4f, 12);

            this.jsonConnection
            .GetAsync(Arg.Is <GetEpisodesRequest>(r => r.Url == "https://api.thetvdb.com/series/4/episodes?page=1"),
                      Arg.Any <Option <string> >())
            .Returns(new Response <GetEpisodesRequest.Response>(new GetEpisodesRequest.Response(
                                                                    new[] { page1Episode },
                                                                    new GetEpisodesRequest.PageLinks(1, 2, 2, Option <int> .None))));
            this.jsonConnection.GetAsync(Arg.Is <GetEpisodeDetailsRequest>(r => r.Url.EndsWith("1")), Arg.Any <Option <string> >())
            .Returns(new Response <GetEpisodeDetailsRequest.Response>(
                         new GetEpisodeDetailsRequest.Response(page1EpisodeDetail)));

            this.jsonConnection
            .GetAsync(Arg.Is <GetEpisodesRequest>(r => r.Url == "https://api.thetvdb.com/series/4/episodes?page=2"),
                      Arg.Any <Option <string> >())
            .Returns(new Response <GetEpisodesRequest.Response>(new GetEpisodesRequest.Response(
                                                                    new[] { page2Episode },
                                                                    new GetEpisodesRequest.PageLinks(2, 2, Option <int> .None, 1))));
            this.jsonConnection.GetAsync(Arg.Is <GetEpisodeDetailsRequest>(r => r.Url.EndsWith("2")), Arg.Any <Option <string> >())
            .Returns(new Response <GetEpisodeDetailsRequest.Response>(
                         new GetEpisodeDetailsRequest.Response(page2EpisodeDetail)));

            var tvDbClient = new TvDbClientV2(this.jsonConnection, this.fileCache, this.applicationPaths, this.logManager,
                                              new JsonSerialiser(), new PluginConfiguration());

            await tvDbClient.GetEpisodesAsync(4);

            await this.jsonConnection.Received(1)
            .GetAsync(Arg.Is <GetEpisodesRequest>(r => r.Url == "https://api.thetvdb.com/series/4/episodes?page=1"),
                      Arg.Any <Option <string> >());

            await this.jsonConnection.Received(1)
            .GetAsync(Arg.Is <GetEpisodesRequest>(r => r.Url == "https://api.thetvdb.com/series/4/episodes?page=2"),
                      Arg.Any <Option <string> >());

            await this.jsonConnection.ReceivedWithAnyArgs(2)
            .GetAsync <GetEpisodeDetailsRequest.Response>(null, Option <string> .None);
        }
        public async Task GetSeriesAsync_ValidSeriesId_ReturnsSeriesData()
        {
            var client = new TvDbClientV2(new JsonConnection(new TestHttpClient(), new JsonSerialiser(), this.logManager),
                                          this.fileCache, this.applicationPaths, this.logManager, new JsonSerialiser(), new PluginConfiguration
            {
                TvDbApiKey = Secrets.TvDbApiKey
            });

            var seriesResult = await client.GetSeriesAsync(80675);

            seriesResult.IsSome.Should().BeTrue();

            var series = seriesResult.ValueUnsafe();

            series.Should().BeEquivalentTo(new TvDbSeriesData(80675, "Mobile Suit Gundam 00",
                                                              new DateTime(2007, 10, 6), "Tokyo Broadcasting System", 30, AirDay.Saturday, "6:00 PM",
                                                              9.4f, new string[] { }, new[] { "Animation", "Drama", "Science-Fiction" },
                                                              "2307 AD.\r\nAs fossil fuels became exhausted, humanity found a new energy source to change their situation: A large-scale solar power system with three enormous orbiting elevators. However, only a few large countries and their allies reaped the benefits.\r\nThree superpowers had ownership of the three orbiting elevators: The Union, based in the United States Of America, The People`s Reform League, made up of China, Russia, and India, and Europe`s AEU. The superpowers continue playing a large zero-sum game for their own dignity and respective prosperity. Even though it is the 24th century, humanity has yet to become one.\r\nIn this world where war has no end, a private militia appears advocating the eradication of war through force. Each possessing a mobile suit Gundam, they are Celestial Being. The armed intervention by the Gundams against all acts of war begins."));
        }
        public async Task GetEpisodeAsync_NoLocalEpisodeData_ReturnsNewEpisodeData()
        {
            var episode       = new TvDbEpisodeSummaryData(1, "Test", 1L, 2, 3, 4, new DateTime(2017, 1, 2, 3, 4, 5), "Overview");
            var episodeDetail = new TvDbEpisodeData(1, "Test", 1L, 2, 3, 4, new DateTime(2017, 1, 2, 3, 4, 5), "Overview", 33.4f, 12);

            this.jsonConnection.GetAsync(Arg.Any <GetEpisodesRequest>(), Arg.Any <Option <string> >())
            .Returns(new Response <GetEpisodesRequest.Response>(new GetEpisodesRequest.Response(new[] { episode },
                                                                                                new GetEpisodesRequest.PageLinks(1, 1, Option <int> .None, Option <int> .None))));
            this.jsonConnection.GetAsync(Arg.Any <GetEpisodeDetailsRequest>(), Arg.Any <Option <string> >())
            .Returns(new Response <GetEpisodeDetailsRequest.Response>(
                         new GetEpisodeDetailsRequest.Response(episodeDetail)));

            var tvDbClient = new TvDbClientV2(this.jsonConnection, this.fileCache, this.applicationPaths, this.logManager,
                                              new JsonSerialiser(), new PluginConfiguration());

            var episodes = await tvDbClient.GetEpisodesAsync(4);

            episodes.IsSome.Should().BeTrue();
            episodes.ValueUnsafe().Should().BeEquivalentTo(new[] { episodeDetail });
        }
        public async Task GetEpisodeAsync_NoLocalEpisodeData_SavesNewEpisodeData()
        {
            var episode       = new TvDbEpisodeSummaryData(1, "Test", 1L, 2, 3, 4, new DateTime(2017, 1, 2, 3, 4, 5), "Overview");
            var episodeDetail = new TvDbEpisodeData(1, "Test", 1L, 2, 3, 4, new DateTime(2017, 1, 2, 3, 4, 5), "Overview", 33.4f, 12);

            this.jsonConnection.GetAsync(Arg.Any <GetEpisodesRequest>(), Arg.Any <Option <string> >())
            .Returns(new Response <GetEpisodesRequest.Response>(new GetEpisodesRequest.Response(new[] { episode },
                                                                                                new GetEpisodesRequest.PageLinks(1, 1, Option <int> .None, Option <int> .None))));
            this.jsonConnection.GetAsync(Arg.Any <GetEpisodeDetailsRequest>(), Arg.Any <Option <string> >())
            .Returns(new Response <GetEpisodeDetailsRequest.Response>(
                         new GetEpisodeDetailsRequest.Response(episodeDetail)));

            var tvDbClient = new TvDbClientV2(this.jsonConnection, this.fileCache, this.applicationPaths, this.logManager,
                                              new JsonSerialiser(), new PluginConfiguration());

            await tvDbClient.GetEpisodesAsync(4);

            this.fileCache.Received(1)
            .SaveFile(Arg.Any <TvDbSeriesEpisodesFileSpec>(),
                      Arg.Is <TvDbEpisodeCollection>(d => d.Episodes.Single() == episodeDetail));
        }
        public async Task GetEpisodesAsync_ValidSeriesId_ReturnsEpisodes()
        {
            var client = new TvDbClientV2(new JsonConnection(new TestHttpClient(), new JsonSerialiser(), this.logManager),
                                          this.fileCache, this.applicationPaths, this.logManager, new JsonSerialiser(), new PluginConfiguration
            {
                TvDbApiKey = Secrets.TvDbApiKey
            });

            var episodesResult = await client.GetEpisodesAsync(80675);

            episodesResult.IsSome.Should().BeTrue();
            var episodes = episodesResult.ValueUnsafe().ToList();

            episodes.Should().HaveCount(57);

            episodes[0]
            .Should().BeEquivalentTo(new TvDbEpisodeData(340368, "Celestial Being", 1L, 1, 1, 1496255818,
                                                         new DateTime(2007, 10, 6),
                                                         "Celestial Being, a private army dedicated to eradicating war, begins demonstrating the powers of their new \"MS-GUNDAM\" suits by interrupting the public demonstration of AEU's latest Mobile Suit, the AEU Enact and by protecting the Human Reform League's Space Elevator, \"Tenchu\" from being attacked by terrorists when their mobile suits had attempted to launch rockets on the \"Tenchu\", earning a news appearance from various TV news channels where Celestial Being's goals were publicly stated by Aeoria Schenberg.",
                                                         8.2f, 5));
        }