def _validate_calculated_question(self, calculation, question,
                                      target_total, currency):
        messages = None
        if 'validation' in question:
            messages = question['validation'].get('messages')

        validator = SumCheck(messages=messages, currency=currency)

        calculation_type = self._get_calculation_type(
            calculation['calculation_type'])

        formatted_values = self._get_formatted_calculation_values(
            calculation['answers_to_calculate'])

        calculation_total = self._get_calculation_total(
            calculation_type, formatted_values)

        # Validate grouped answers meet calculation_type criteria
        try:
            validator(self, calculation['conditions'], calculation_total,
                      target_total)
        except validators.ValidationError as e:
            self.question_errors[question['id']] = str(e)
            return False

        return True
    def test_bespoke_message_playback(self):
        message = {'TOTAL_SUM_NOT_EQUALS': 'Test %(total)s'}
        validator = SumCheck(messages=message)

        mock_form = Mock()

        conditions = ['equals']
        calculation_total = 10
        target_total = 11.5

        with self.assertRaises(ValidationError) as ite:
            validator(mock_form, conditions, calculation_total, target_total)

        self.assertEqual('Test {}'.format(target_total), str(ite.exception))
    def test_invalid_multiple_conditions(self):
        validator = SumCheck()

        mock_form = Mock()

        conditions = ['less than', 'greater than']
        calculation_total = 10
        target_total = 11.5

        with self.assertRaises(Exception) as ite:
            validator(mock_form, conditions, calculation_total, target_total)

        self.assertEqual(
            'There are multiple conditions, but equals is not one of them. We only support <= and >=',
            str(ite.exception))
    def test_currency_playback(self):
        validator = SumCheck(currency='EUR')

        mock_form = Mock()

        conditions = ['equals']
        calculation_total = 10
        target_total = 11.5

        with self.assertRaises(ValidationError) as ite:
            validator(mock_form, conditions, calculation_total, target_total)

        self.assertEqual(
            error_messages['TOTAL_SUM_NOT_EQUALS'] %
            dict(total=format_playback_value(target_total, currency='EUR')),
            str(ite.exception))
    def test_greater_or_equal_condition_check(self):
        validator = SumCheck()

        mock_form = Mock()

        conditions = ['greater than', 'equals']
        calculation_total = 11.99
        target_total = 12.5

        with self.assertRaises(ValidationError) as ite:
            validator(mock_form, conditions, calculation_total, target_total)

        self.assertEqual(
            error_messages['TOTAL_SUM_NOT_GREATER_THAN_OR_EQUALS'] %
            dict(total=format_playback_value(target_total)),
            str(ite.exception))
    def test_less_than_condition_check(self):
        validator = SumCheck()

        mock_form = Mock()

        conditions = ['less than']
        calculation_total = 11.99
        target_total = 11.5

        with self.assertRaises(ValidationError) as ite:
            validator(mock_form, conditions, calculation_total, target_total)

        self.assertEqual(
            error_messages['TOTAL_SUM_NOT_LESS_THAN'] %
            dict(total=format_playback_value(target_total)),
            str(ite.exception))