public void Constructor_ValidInput_DetailsCorrect()
        {
            // Fixture setup
            var expectedTitle = "News title";
            var expectedText = "News text";
            Uri expectedImageSource = null;

            var expectedPublicationDate = DateTimeOffset.Now;
            var channelName = "News channel";
            var expectedPublicationDetails = expectedPublicationDate.ToString("dd.MM.yyy - HH:mm") + " • " + channelName;

            var newsChannel = new NewsChannel(channelName, new Uri("http://news.com/rss"));
            var newsItem = new NewsItem(expectedTitle, expectedText, expectedPublicationDate, expectedImageSource);

            // Exercise system
            var viewModel = new NewsDetailsViewModel(newsChannel, newsItem);

            // Verify outcome
            Assert.AreEqual(viewModel.Title, expectedTitle);
            Assert.AreEqual(viewModel.Text, expectedText);
            Assert.AreEqual(viewModel.PublicationDate, expectedPublicationDate);
            Assert.AreEqual(viewModel.ImageSource, expectedImageSource);
            Assert.AreEqual(viewModel.PublicationDetails, expectedPublicationDetails);

            // Teardown
        }
        public void Constructor_NullNewsItem_ExceptionThrown()
        {
            // Fixture setup
            var newsChannel = new NewsChannel("News channel", new Uri("http://news.com/rss"));
            NewsItem newsItem = null;

            // Exercise system
            // Verify outcome
            Assert.ThrowsException<ArgumentNullException>
                (() => new NewsDetailsViewModel(newsChannel, newsItem));

            // Teardown
        }
      protected override async void OnNavigatedTo(NavigationEventArgs e)
      {
         if (e.NavigationMode == NavigationMode.New)
         {
            var vm = new NewsFeedViewModel(new HttpClientProxy(), new SyndicationFeedDecorator(), new StatusBarProxy());

            Feed.DataContext = vm;
            Feed.FeedItemSelected += OnFeedItemSelected;

            var lentaRu = new NewsChannel("Lenta.ru", new Uri("http://lenta.ru/rss"));
            var gazetaRu = new NewsChannel("Gazeta.ru", new Uri("http://www.gazeta.ru/export/rss/lenta.xml"));
            await vm.GetLatestNewsAsync(lentaRu, gazetaRu);
         }
      }
		public async Task GetLatestNewsAsync_NullRssParser_ExceptionThrown()
		{
			// Fixture setup
			var name = "News channel";
			var feedUri = new Uri("http://news.com/rss");

			IHttpClient httpClient = new HttpClientMock();
			IRssParser rssParser = null;

			var newsChannel = new NewsChannel(name, feedUri);

			// Exercise system
			var task = newsChannel.GetLatestNewsAsync(httpClient, rssParser);

			// Verify outcome
			await AssertEx.ThrowsExceptionAsync<ArgumentNullException>(() => task);

			// Teardown
		}
		public async Task GetLatestNewsAsync_MockForTwoNewsChannels_ValidNewsItemsSortingOrder()
		{
			// Fixture setup
			var firstItem = new NewsItem("First item", "News text", DateTimeOffset.Now, null);
			var secondItem = new NewsItem("Second item", "News text", firstItem.PublicationDate.AddSeconds(1), null);

			var requestCounter = 0;
			Func<string, NewsFeed> parsingFunc = rss =>
			{
				requestCounter++;
				if (requestCounter == 1) return new NewsFeed(new[] { firstItem });
				return new NewsFeed(new[] { secondItem });
			};

			IHttpClient httpClient = new HttpClientMock();
			IRssParser rssParser = new RssParserMock { CustomParsingFunction = parsingFunc };
			IProgressIndicator progressIndicator = new ProgressIndicatorMock();

			var viewModel = new NewsFeedViewModel(httpClient, rssParser, progressIndicator);
			var newsChannel = new NewsChannel("News channel", new Uri("http://news.com/rss"));

			var expectedFirstItemTitle = secondItem.Title;

			// Exercise system
			await viewModel.GetLatestNewsAsync(newsChannel, newsChannel);

			// Verify outcome
			Assert.AreEqual(viewModel.News[0].Title, expectedFirstItemTitle);

			// Teardown
		}
		public async Task GetLatestNewsAsync_MockForTwoNewsChannels_ValidItemCount()
		{
			// Fixture setup
			var newsItem = new NewsItem("News item", "News text", DateTimeOffset.Now, null);
			Func<string, NewsFeed> parsingFunc = rss => new NewsFeed(new[] { newsItem });

			IHttpClient httpClient = new HttpClientMock();
			IRssParser rssParser = new RssParserMock { CustomParsingFunction = parsingFunc };
			IProgressIndicator progressIndicator = new ProgressIndicatorMock();

			var viewModel = new NewsFeedViewModel(httpClient, rssParser, progressIndicator);
			var newsChannel = new NewsChannel("News channel", new Uri("http://news.com/rss"));

			var expectedNewsCount = 2;

			// Exercise system
			await viewModel.GetLatestNewsAsync(newsChannel, newsChannel);

			// Verify outcome
			Assert.AreEqual(viewModel.News.Count, expectedNewsCount);

			// Teardown
		}
		public async Task GetLatestNewsAsync_NullNewsFeedFromNewsChannel_ExceptionThrown()
		{
			// Fixture setup
			IHttpClient httpClient = new HttpClientMock();
			IRssParser rssParser = new RssParserMock();
			IProgressIndicator progressIndicator = new ProgressIndicatorMock();

			var viewModel = new NewsFeedViewModel(httpClient, rssParser, progressIndicator);
			var newsChannel = new NewsChannel("News channel", new Uri("http://news.com/rss"));

			// Exercise system
			var task = viewModel.GetLatestNewsAsync(newsChannel);

			// Verify outcome
			await AssertEx.ThrowsExceptionAsync<NullReferenceException>(() => task);

			// Teardown
		}
		public async Task GetLatestNewsAsync_UsingLentaRuSampleData_ValidNewsFeed()
		{
			// Fixture setup
			var name = "News channel";
			var feedUri = new Uri("http://news.com/rss");

			IHttpClient httpClient = new HttpClientMock {SampleDataPreference = SampleDataPreference.LentaRu};
			IRssParser rssParser = new SyndicationFeedDecorator();

			var newsChannel = new NewsChannel(name, feedUri);

			var expectedCount = 3;
			var expectedFirstItemTitle = "На побережье французского острова в Индийском океане нашли обломок самолета";
			var expectedFirstItemText = "На побережье французского острова Реюньон, расположенного в Индийском океане к востоку от Мадагаскара, найден обломок неизвестного самолета. Специалисты считают, что трехметровая деталь могла принадлежать малайзийскому «Боингу», который пропал в ночь на 8 марта 2014 года.";
			var expectedFirstItemPublicationDate = new DateTimeOffset(2015, 7, 29, 19, 23, 0, TimeSpan.FromHours(3));
			var expectedFirstItemImageSource = new Uri("http://icdn.lenta.ru/images/2015/07/29/18/20150729183227894/pic_df052e4cec4b74c4b14d369026bcef69.jpg");

			// Exercise system
			var newsFeed = await newsChannel.GetLatestNewsAsync(httpClient, rssParser);
			var feedItems = newsFeed.Items.ToList();
			var firstItem = feedItems[0];

			// Verify outcome
			Assert.AreEqual(feedItems.Count, expectedCount);
			Assert.AreEqual(firstItem.Title, expectedFirstItemTitle);
			Assert.AreEqual(firstItem.Text, expectedFirstItemText);
			Assert.AreEqual(firstItem.PublicationDate, expectedFirstItemPublicationDate);
			Assert.AreEqual(firstItem.ImageSource, expectedFirstItemImageSource);

			// Teardown
		}
		public async Task GetLatestNewsAsync_UsingGazetaRuSampleData_NoHtmlSpecialEntitiesInText()
		{
			// Fixture setup
			var name = "News channel";
			var feedUri = new Uri("http://news.com/rss");

			IHttpClient httpClient = new HttpClientMock { SampleDataPreference = SampleDataPreference.GazetaRu };
			IRssParser rssParser = new SyndicationFeedDecorator();

			var newsChannel = new NewsChannel(name, feedUri);

			var expectedResult = false;

			// Exercise system
			var newsFeed = await newsChannel.GetLatestNewsAsync(httpClient, rssParser);
			var feedItems = newsFeed.Items.ToList();
			var thirdItem = feedItems[2];
			var itemContainsQuotationMark = thirdItem.Text.Contains("&quot;");

			// Verify outcome
			Assert.AreEqual(itemContainsQuotationMark, expectedResult);

			// Teardown
		}
		public async Task GetLatestNewsAsync_UsingGazetaRuSampleData_ValidNewsFeed()
		{
			// Fixture setup
			var name = "News channel";
			var feedUri = new Uri("http://news.com/rss");

			IHttpClient httpClient = new HttpClientMock { SampleDataPreference = SampleDataPreference.GazetaRu };
			IRssParser rssParser = new SyndicationFeedDecorator();

			var newsChannel = new NewsChannel(name, feedUri);

			var expectedCount = 3;
			var expectedFirstItemTitle = "Минюст включил Национальный фонд в поддержку демократии в список нежелательных организаций";
			var expectedFirstItemText = "Министерство юстиции России включило Национальный фонд в поддержку демократии в список иностранных и международных неправительственных организаций, деятельность которых на территории страны признана нежелательной. Об этом сообщается на ...";
			var expectedFirstItemPublicationDate = new DateTimeOffset(2015, 7, 29, 19, 17, 5, TimeSpan.FromHours(3));
			Uri expectedFirstItemImageSource = null;

			// Exercise system
			var newsFeed = await newsChannel.GetLatestNewsAsync(httpClient, rssParser);
			var feedItems = newsFeed.Items.ToList();
			var firstItem = feedItems[0];

			// Verify outcome
			Assert.AreEqual(feedItems.Count, expectedCount);
			Assert.AreEqual(firstItem.Title, expectedFirstItemTitle);
			Assert.AreEqual(firstItem.Text, expectedFirstItemText);
			Assert.AreEqual(firstItem.PublicationDate, expectedFirstItemPublicationDate);
			Assert.AreEqual(firstItem.ImageSource, expectedFirstItemImageSource);

			// Teardown
		}