def test_get_report(self):
        """ Test get report merged from multiple files into one """
        # arrange
        vals = {
            (datetime(2018, 4, 5), datetime(2018, 4, 5, 23, 59, 59)): { 'module_1': { 'a': 1, 'c': 1 }, 'module_2': { 'x': 1, 'y': 2 } }, 
            (datetime(2018, 4, 4), datetime(2018, 4, 4, 23, 59, 59)): { 'module_1': { 'b': 2, 'c': 2 }, 'module_2': { 'x': 2 } }
        }

        def side_effect(*args):
            return vals[args]

        mock_report_builder = report_builder.ErrorReportBuilder('env', 'user', 'password')
        mock_report_builder.build_report = mock.MagicMock(side_effect=side_effect)

        qed1week = reporter.ErrorCompareReporter('env', datetime.today(), 'safeid_user', 'safeid_password', 'smtp_user', 'smtp_password')
        dates = [
            (datetime(2018, 4, 5), datetime(2018, 4, 5, 23, 59, 59)),
            (datetime(2018, 4, 4), datetime(2018, 4, 4, 23, 59, 59))
        ]
        
        # act
        report = qed1week._get_report(mock_report_builder, dates)

        # assert
        self.assertEqual(report, { 'module_1': { 'a': [1], 'b': [2], 'c': [1, 2] }, 'module_2': { 'x': [1, 2], 'y': [2] } })
    def test_prepare_report(self):
        # arrange
        qed1week = reporter.ErrorCompareReporter('env', datetime.today(), 'safeid_user', 'safeid_password', 'smtp_user', 'smtp_password')
        target_report = { 
            'Document': { 'doc_key': [1] },
            'Website': { 'error_key_1': [1], 'error_key_2': [2], 'error_key_3': [3] }
        }

        history_report = { 
            'Document': { 'doc_key': [1] },
            'Website': { 'error_key_2': [2, 3, 4, 5], 'error_key_3': [3, 4] }
        }

        def side_effect(target_errors_count, history_errors_count):
            if target_errors_count == [2] \
                and history_errors_count == [2, 3, 4, 5]:
                return [1.0, 2.0]
            elif target_errors_count == [3] \
                and history_errors_count == [3, 4]:
                return [0.0, 0.5]
            
            raise ValueError('unexpected arguments')

        qed1week._check_error_rate_increase = mock.MagicMock(side_effect=side_effect)

        # act
        (new_errors, errors_increased) = qed1week._prepare_report(target_report, history_report)

        # assert
        self.assertEqual(new_errors, { 'error_key_1': [1] })
        self.assertEqual(errors_increased, { 'error_key_2': [1.0, 2.0] })
    def test_check_error_rate_increase(self):
        # arrange
        qed1week = reporter.ErrorCompareReporter('env', datetime.today(), 'safeid_user', 'safeid_password', 'smtp_user', 'smtp_password')
        target_errors = [10]
        history_errors = [5]

        # act
        conf_int_diff = qed1week._check_error_rate_increase(target_errors, history_errors)

        # assert
        self.assertTrue(conf_int_diff[0] > 0)
    def test_get_report_dates(self):
        """ test today is Tuesday, 6 days back """
        # arrange
        today = datetime(2018, 4, 10) + timedelta(hours=8)
        qed1week = reporter.ErrorCompareReporter('env', today, 'safeid_user', 'safeid_password', 'smtp_user', 'smtp_password')
        
        # act
        target_dates, history_dates = qed1week._get_report_dates(1, 5)

        # assert
        self.assertEqual(len(target_dates), 1)
        self.assertEqual(target_dates[0], (datetime(2018, 4, 10), datetime(2018, 4, 10, 23, 59, 59)))

        self.assertEqual(len(history_dates), 5)
        self.assertEqual(history_dates[0], (datetime(2018, 4, 9), datetime(2018, 4, 9, 23, 59, 59)))
        self.assertEqual(history_dates[1], (datetime(2018, 4, 6), datetime(2018, 4, 6, 23, 59, 59)))
        self.assertEqual(history_dates[2], (datetime(2018, 4, 5), datetime(2018, 4, 5, 23, 59, 59)))
        self.assertEqual(history_dates[3], (datetime(2018, 4, 4), datetime(2018, 4, 4, 23, 59, 59)))
        self.assertEqual(history_dates[4], (datetime(2018, 4, 3), datetime(2018, 4, 3, 23, 59, 59)))
    def test_send_notification(self, mock_smtplib):
        # arrange
        qed1week = reporter.ErrorCompareReporter('env', datetime.today(), 'safeid_user', 'safeid_password', 'smtp_user', 'smtp_password')

        mock_server = mock.MagicMock()
        dummySMTP = mock.MagicMock(return_value=mock_server)

        mock_smtplib.SMTP = dummySMTP

        # act
        qed1week._send_notification('Test email', 'Test email body', 'smtp_user', 'smtp_password', ['*****@*****.**'])

        # assert
        mock_smtplib.SMTP.assert_called_with('smtp.gmail.com', 587)
        mock_server.ehlo.assert_called_once()
        mock_server.starttls.assert_called_once()
        mock_server.login.assert_called_with('smtp_user', 'smtp_password')
        mock_server.send_message.assert_called_once()
        mock_server.quit.assert_called_once()
    def test_create_notification(self):
        # arrange
        qed1week = reporter.ErrorCompareReporter('env', datetime.today(), 'safeid_user', 'safeid_password', 'smtp_user', 'smtp_password')

        target_dates = [
            (datetime(2018, 4, 9), datetime(2018, 4, 9, 23, 59, 59))
        ]

        history_dates = [
            (datetime(2018, 4, 6), datetime(2018, 4, 6, 23, 59, 59)),
            (datetime(2018, 4, 5), datetime(2018, 4, 5, 23, 59, 59))
        ]

        new_errors = { 'error_key_1': [1] }
        errors_increased = { 'error_key_2': [1.0, 2.0], 'error_key_3': [.5, .8] }

        # act
        (subject, body) = qed1week._create_notification(target_dates, history_dates, new_errors, errors_increased)

        # assert
        self.assertTrue(len(subject) > 0)
        self.assertTrue(len(body) > 0)