text: # -*- coding: utf-8 -*-
  ########################################################################
  #                                                                      #
  # Тесты для модуля RSS-parser                                          #
  #                                                                      #
  # MIT License                                                          #
  # Copyright (c) 2021 Michael Nikitenko                                 #
  #                                                                      #
  ########################################################################
  
  
  import unittest
  from unittest.mock import Mock, patch
  from time import sleep
  
  from nose.tools import assert_is_not_none
  
  from rss_parser import timeout, get_img_file_and_img_url, get_rss_feed_data, find_new_posts, ParsingTimeoutError, \
      RSS_URL, fill_data_by_images
  from tests.utils import generate_rss_mock_feed
  
  
  class TestRSSParser(unittest.TestCase):
      def setUp(self):
          self.mock_feed = generate_rss_mock_feed()
          self.feed_data = [{'title': 'Test title', 'url': 'http://www.yanao.ru/presscenter/news/76459/'},
                            {'title': 'Test title', 'url': 'http://www.yanao.ru/presscenter/news/76447/'}, ]
  
      def test_timeout(self):
          """Тестирование декоратора timeout"""
  
          @timeout(1)
          def case_with_timeout_one_second():
              """Если функция работала дольше, чем таймаут"""
              sleep(2)
  
          @timeout(0)
          def case_with_timeout_zero_seconds():
              """Если таймаут равен 0 секунд"""
              sleep(2)
  
          @timeout(-1)
          def case_with_timeout_negative_argument():
              """Если таймаут равен бесконечности"""
              sleep(0.1)
  
          @timeout(-2)
          def case_with_timeout_minus_two():
              """Если таймаут равен бесконечности, но число неправильное"""
              sleep(0.1)
  
          @timeout(3)
          def case_with_timeout_more_than_executing_time():
              """Если время выполнения меньше чем таймаут и функция возвращает значение True"""
              return True
  
          self.assertRaises(ParsingTimeoutError, case_with_timeout_one_second)
          self.assertRaises(ParsingTimeoutError, case_with_timeout_zero_seconds)
          self.assertRaises(ParsingTimeoutError, case_with_timeout_negative_argument)
          self.assertRaises(ParsingTimeoutError, case_with_timeout_minus_two)
          self.assertTrue(case_with_timeout_more_than_executing_time())
  
      def test_get_rss_feed_data(self):
          """Тестирование получения RSS-ленты"""
          with patch('rss_parser.feedparser.parse') as mock_get:
              """Тестируем на мокнутых данных"""
              mock_get.return_value = self.mock_feed
              feed_data = get_rss_feed_data('https://www.yanao.ru/presscenter/news/rss/')
              self.assertIsInstance(feed_data, list)
  
          with self.assertRaises(ValueError):
              """Тестируем на случай если неправильно указан URL RSS-ленты"""
              get_rss_feed_data('https://www.yanao.ru/presscenter/news/rss/a')
  
      def test_fill_data_by_images(self):
          """Тестируем парсинг картинки поста"""
          result = fill_data_by_images(self.feed_data)
          self.assertIsInstance(result, list)
          for r in result:
              self.assertIsInstance(r, dict)
  
      @patch('db_engine.cursor')
      @patch('rss_parser.fill_data_by_images')
      def test_find_new_posts(self, mock_data, mock_cursor):
          """Тестируем получение новых постов"""
          mock_cursor.fetchall.return_value = [{'title': 'title1', 'url': 'url1', 'img': 'img1', 'img_url': 'img_url1'},
                                       {'title': 'title2', 'url': 'url2', 'img': 'img2', 'img_url': 'img_url2'},
                                       {'title': 'title3', 'url': 'url3', 'img': 'img3', 'img_url': 'img_url3'}]
          mock_data.return_value = [{'title': 'title1', 'url': 'url1', 'img': 'img1', 'img_url': 'img_url1'},
                                    {'title': 'title2', 'url': 'url2', 'img': 'img2', 'img_url': 'img_url2'},
                                    {'title': 'title3', 'url': 'url3', 'img': 'img3', 'img_url': 'img_url3'},
                                    {'title': 'title4', 'url': 'url4', 'img': 'img4', 'img_url': 'img_url4'},
                                    {'title': 'title5', 'url': 'url5', 'img': 'img5', 'img_url': 'img_url5'}]
          expected = [{'title': 'title4', 'url': 'url4', 'img': 'img4', 'img_url': 'img_url4'},
                      {'title': 'title5', 'url': 'url5', 'img': 'img5', 'img_url': 'img_url5'}]
          unexpected = [{'title': 'title1', 'url': 'url1', 'img': 'img1', 'img_url': 'img_url1'},
                        {'title': 'title2', 'url': 'url2', 'img': 'img2', 'img_url': 'img_url2'},
                        {'title': 'title3', 'url': 'url3', 'img': 'img3', 'img_url': 'img_url3'}]
          result = find_new_posts()
          self.assertIsInstance(result, list)
          self.assertEqual(result, expected)
          self.assertNotEqual(result, unexpected)
  