from __future__ import absolute_import

from sentry.testutils.cases import RuleTestCase
from sentry.rules.conditions.event_attribute import (EventAttributeCondition, MatchType)


class EventAttributeConditionTest(RuleTestCase):
    rule_cls = EventAttributeCondition

    def get_event(self):
        event = self.create_event(
            message='hello world',
            platform='php',
            data={
                'type': 'error',
                'sentry.interfaces.Http': {
                    'method': 'GET',
                    'url': 'http://example.com',
                },
                'sentry.interfaces.User': {
                    'id': '1',
                    'ip_address': '127.0.0.1',
                    'email': 'foo@example.com',
                    'username': 'foo',
                },
                'sentry.interfaces.Exception': {
                    'values': [
                        {
                            'type': 'SyntaxError',
                            'value': 'hello world',
                            'stacktrace': {
                                'frames': [
                                    {
                                        'filename': 'example.php',
                                        'module': 'example',
                                        'context_line': 'echo "hello";',
                                    }
                                ]
                            }
                        },
                    ],
                },
                'tags': [('environment', 'production')],
                'extra': {
                    'foo': {
                        'bar': 'baz',
                    },
                    'biz': ['baz'],
                    'bar': 'foo',
                }
            },
        )
        return event

    def test_render_label(self):
        rule = self.get_rule(data={
            'match': MatchType.EQUAL,
            'attribute': u'\xc3',
            'value': u'\xc4',
        })
        assert rule.render_label() == u'An event\'s \xc3 value equals \xc4'

    def test_equals(self):
        event = self.get_event()
        rule = self.get_rule(data={
            'match': MatchType.EQUAL,
            'attribute': 'platform',
            'value': 'php',
        })
        self.assertPasses(rule, event)

        rule = self.get_rule(data={
            'match': MatchType.EQUAL,
            'attribute': 'platform',
            'value': 'python',
        })
        self.assertDoesNotPass(rule, event)

    def test_does_not_equal(self):
        event = self.get_event()
        rule = self.get_rule(data={
            'match': MatchType.NOT_EQUAL,
            'attribute': 'platform',
            'value': 'php',
        })
        self.assertDoesNotPass(rule, event)

        rule = self.get_rule(data={
            'match': MatchType.NOT_EQUAL,
            'attribute': 'platform',
            'value': 'python',
        })
        self.assertPasses(rule, event)

    def test_starts_with(self):
        event = self.get_event()
        rule = self.get_rule(data={
            'match': MatchType.STARTS_WITH,
            'attribute': 'platform',
            'value': 'ph',
        })
        self.assertPasses(rule, event)

        rule = self.get_rule(data={
            'match': MatchType.STARTS_WITH,
            'attribute': 'platform',
            'value': 'py',
        })
        self.assertDoesNotPass(rule, event)

    def test_ends_with(self):
        event = self.get_event()
        rule = self.get_rule(data={
            'match': MatchType.ENDS_WITH,
            'attribute': 'platform',
            'value': 'hp',
        })
        self.assertPasses(rule, event)

        rule = self.get_rule(data={
            'match': MatchType.ENDS_WITH,
            'attribute': 'platform',
            'value': 'thon',
        })
        self.assertDoesNotPass(rule, event)

    def test_contains(self):
        event = self.get_event()
        rule = self.get_rule(data={
            'match': MatchType.CONTAINS,
            'attribute': 'platform',
            'value': 'p',
        })
        self.assertPasses(rule, event)

        rule = self.get_rule(data={
            'match': MatchType.CONTAINS,
            'attribute': 'platform',
            'value': 'z',
        })
        self.assertDoesNotPass(rule, event)

    def test_does_not_contain(self):
        event = self.get_event()
        rule = self.get_rule(data={
            'match': MatchType.NOT_CONTAINS,
            'attribute': 'platform',
            'value': 'p',
        })
        self.assertDoesNotPass(rule, event)

        rule = self.get_rule(data={
            'match': MatchType.NOT_CONTAINS,
            'attribute': 'platform',
            'value': 'z',
        })
        self.assertPasses(rule, event)

    def test_message(self):
        event = self.get_event()
        rule = self.get_rule(data={
            'match': MatchType.EQUAL,
            'attribute': 'message',
            'value': 'hello world',
        })
        self.assertPasses(rule, event)

        rule = self.get_rule(data={
            'match': MatchType.EQUAL,
            'attribute': 'message',
            'value': 'php',
        })
        self.assertDoesNotPass(rule, event)

    def test_environment(self):
        event = self.get_event()
        rule = self.get_rule(data={
            'match': MatchType.EQUAL,
            'attribute': 'environment',
            'value': 'production',
        })
        self.assertPasses(rule, event)

        rule = self.get_rule(data={
            'match': MatchType.EQUAL,
            'attribute': 'environment',
            'value': 'staging',
        })
        self.assertDoesNotPass(rule, event)

    def test_http_method(self):
        event = self.get_event()
        rule = self.get_rule(data={
            'match': MatchType.EQUAL,
            'attribute': 'http.method',
            'value': 'get',
        })
        self.assertPasses(rule, event)

        rule = self.get_rule(data={
            'match': MatchType.EQUAL,
            'attribute': 'http.method',
            'value': 'post',
        })
        self.assertDoesNotPass(rule, event)

    def test_http_url(self):
        event = self.get_event()
        rule = self.get_rule(data={
            'match': MatchType.EQUAL,
            'attribute': 'http.url',
            'value': 'http://example.com',
        })
        self.assertPasses(rule, event)

        rule = self.get_rule(data={
            'match': MatchType.EQUAL,
            'attribute': 'http.url',
            'value': 'http://foo.com',
        })
        self.assertDoesNotPass(rule, event)

    def test_user_id(self):
        event = self.get_event()
        rule = self.get_rule(data={
            'match': MatchType.EQUAL,
            'attribute': 'user.id',
            'value': '1',
        })
        self.assertPasses(rule, event)

        rule = self.get_rule(data={
            'match': MatchType.EQUAL,
            'attribute': 'user.id',
            'value': '2',
        })
        self.assertDoesNotPass(rule, event)

    def test_user_ip_address(self):
        event = self.get_event()
        rule = self.get_rule(data={
            'match': MatchType.EQUAL,
            'attribute': 'user.ip_address',
            'value': '127.0.0.1',
        })
        self.assertPasses(rule, event)

        rule = self.get_rule(data={
            'match': MatchType.EQUAL,
            'attribute': 'user.ip_address',
            'value': '2',
        })
        self.assertDoesNotPass(rule, event)

    def test_user_email(self):
        event = self.get_event()
        rule = self.get_rule(data={
            'match': MatchType.EQUAL,
            'attribute': 'user.email',
            'value': 'foo@example.com',
        })
        self.assertPasses(rule, event)

        rule = self.get_rule(data={
            'match': MatchType.EQUAL,
            'attribute': 'user.email',
            'value': '2',
        })
        self.assertDoesNotPass(rule, event)

    def test_user_username(self):
        event = self.get_event()
        rule = self.get_rule(data={
            'match': MatchType.EQUAL,
            'attribute': 'user.username',
            'value': 'foo',
        })
        self.assertPasses(rule, event)

        rule = self.get_rule(data={
            'match': MatchType.EQUAL,
            'attribute': 'user.username',
            'value': '2',
        })
        self.assertDoesNotPass(rule, event)

    def test_exception_type(self):
        event = self.get_event()
        rule = self.get_rule(data={
            'match': MatchType.EQUAL,
            'attribute': 'exception.type',
            'value': 'SyntaxError',
        })
        self.assertPasses(rule, event)

        rule = self.get_rule(data={
            'match': MatchType.EQUAL,
            'attribute': 'exception.type',
            'value': 'TypeError',
        })
        self.assertDoesNotPass(rule, event)

    def test_exception_value(self):
        event = self.get_event()
        rule = self.get_rule(data={
            'match': MatchType.EQUAL,
            'attribute': 'exception.value',
            'value': 'hello world',
        })
        self.assertPasses(rule, event)

        rule = self.get_rule(data={
            'match': MatchType.EQUAL,
            'attribute': 'exception.value',
            'value': 'foo bar',
        })
        self.assertDoesNotPass(rule, event)

    def test_stacktrace_filename(self):
        event = self.get_event()
        rule = self.get_rule(data={
            'match': MatchType.EQUAL,
            'attribute': 'stacktrace.filename',
            'value': 'example.php',
        })
        self.assertPasses(rule, event)

        rule = self.get_rule(data={
            'match': MatchType.EQUAL,
            'attribute': 'stacktrace.filename',
            'value': 'foo.php',
        })
        self.assertDoesNotPass(rule, event)

    def test_stacktrace_module(self):
        event = self.get_event()
        rule = self.get_rule(data={
            'match': MatchType.EQUAL,
            'attribute': 'stacktrace.module',
            'value': 'example',
        })
        self.assertPasses(rule, event)

        rule = self.get_rule(data={
            'match': MatchType.EQUAL,
            'attribute': 'stacktrace.module',
            'value': 'foo',
        })
        self.assertDoesNotPass(rule, event)

    def test_stacktrace_code(self):
        event = self.get_event()
        rule = self.get_rule(data={
            'match': MatchType.EQUAL,
            'attribute': 'stacktrace.code',
            'value': 'echo "hello";',
        })
        self.assertPasses(rule, event)

        rule = self.get_rule(data={
            'match': MatchType.EQUAL,
            'attribute': 'stacktrace.code',
            'value': 'foo',
        })
        self.assertDoesNotPass(rule, event)

    def test_extra_simple_value(self):
        event = self.get_event()
        rule = self.get_rule(data={
            'match': MatchType.EQUAL,
            'attribute': 'extra.bar',
            'value': 'foo',
        })
        self.assertPasses(rule, event)

        rule = self.get_rule(data={
            'match': MatchType.EQUAL,
            'attribute': 'extra.bar',
            'value': 'bar',
        })
        self.assertDoesNotPass(rule, event)

    def test_extra_nested_value(self):
        event = self.get_event()
        rule = self.get_rule(data={
            'match': MatchType.EQUAL,
            'attribute': 'extra.foo.bar',
            'value': 'baz',
        })
        self.assertPasses(rule, event)

        rule = self.get_rule(data={
            'match': MatchType.EQUAL,
            'attribute': 'extra.foo.bar',
            'value': 'bar',
        })
        self.assertDoesNotPass(rule, event)

    def test_extra_nested_list(self):
        event = self.get_event()
        rule = self.get_rule(data={
            'match': MatchType.EQUAL,
            'attribute': 'extra.biz',
            'value': 'baz',
        })
        self.assertPasses(rule, event)

        rule = self.get_rule(data={
            'match': MatchType.EQUAL,
            'attribute': 'extra.biz',
            'value': 'bar',
        })
        self.assertDoesNotPass(rule, event)

    def test_event_type(self):
        event = self.get_event()
        rule = self.get_rule(data={
            'match': MatchType.EQUAL,
            'attribute': 'type',
            'value': 'error',
        })
        self.assertPasses(rule, event)

        rule = self.get_rule(data={
            'match': MatchType.EQUAL,
            'attribute': 'type',
            'value': 'csp',
        })
        self.assertDoesNotPass(rule, event)
