def test_stacktrace_wins_over_http(http_comp_hash, stack_comp_hash):
    # this was a regression, and a very important one
    http_comp_hash.return_value = [['baz']]
    stack_comp_hash.return_value = [['foo', 'bar']]
    event = Event(
        data={
            'stacktrace': {
                'frames': [{
                    'lineno': 1,
                    'filename': 'foo.py',
                }],
            },
            'request': {
                'url': 'http://example.com'
            },
        },
        platform='python',
        message='Foo bar',
    )
    hashes = event.get_hashes()
    assert len(hashes) == 1
    hash_one = hashes[0]
    stack_comp_hash.assert_called_once_with('python')
    assert not http_comp_hash.called
    assert hash_one == md5_from_hash(['foo', 'bar'])
示例#2
0
def new_event(request):
    platform = request.GET.get("platform", "python")
    org = Organization(id=1, slug="example", name="Example")
    team = Team(id=1, slug="example", name="Example", organization=org)
    project = Project(id=1, slug="example", name="Example", team=team, organization=org)
    group = Group(id=1, project=project, message="This is an example event.", level=logging.ERROR)

    event = Event(id=1, project=project, group=group, message=group.message, data=load_data(platform))

    rule = Rule(label="An example rule")

    interface_list = []
    for interface in event.interfaces.itervalues():
        body = interface.to_email_html(event)
        if not body:
            continue
        interface_list.append((interface.get_title(), mark_safe(body)))

    return MailPreview(
        html_template="sentry/emails/error.html",
        text_template="sentry/emails/error.html",
        context={
            "rule": rule,
            "group": group,
            "event": event,
            "link": "http://example.com/link",
            "interfaces": interface_list,
            "tags": event.get_tags(),
            "project_label": project.name,
            "tags": [("logger", "javascript"), ("environment", "prod"), ("level", "error"), ("device", "Other")],
        },
    ).render()
示例#3
0
    def create_event(self, event_id=None, **kwargs):
        if event_id is None:
            event_id = uuid4().hex
        if 'group' not in kwargs:
            kwargs['group'] = self.group
        kwargs.setdefault('project', kwargs['group'].project)
        kwargs.setdefault('data', copy.deepcopy(DEFAULT_EVENT_DATA))
        if kwargs.get('tags'):
            tags = kwargs.pop('tags')
            if isinstance(tags, dict):
                tags = tags.items()
            kwargs['data']['tags'] = tags

        kwargs['data'].setdefault('errors', [{
            'type': EventError.INVALID_DATA,
            'name': 'foobar',
        }])

        event = Event(
            event_id=event_id,
            **kwargs
        )
        EventMapping.objects.create(
            project_id=event.project.id,
            event_id=event_id,
            group=event.group,
        )
        # emulate EventManager refs
        event.data.bind_ref(event)
        event.save()
        return event
示例#4
0
文件: tests.py 项目: Natim/sentry
    def test_notify_users_renders_interfaces_with_utf8(self, _send_mail):
        group = Group(
            id=2,
            first_seen=timezone.now(),
            last_seen=timezone.now(),
            project=self.project,
        )

        stacktrace = Mock(spec=Stacktrace)
        stacktrace.to_email_html.return_value = u'רונית מגן'
        stacktrace.get_title.return_value = 'Stacktrace'

        event = Event()
        event.group = group
        event.project = self.project
        event.message = 'hello world'
        event.interfaces = {'sentry.interfaces.Stacktrace': stacktrace}

        notification = Notification(event=event)

        with self.settings(SENTRY_URL_PREFIX='http://example.com'):
            self.plugin.notify(notification)

        stacktrace.get_title.assert_called_once_with()
        stacktrace.to_email_html.assert_called_once_with(event)
示例#5
0
    def create_event(self, event_id=None, **kwargs):
        if event_id is None:
            event_id = uuid4().hex
        if 'group' not in kwargs:
            kwargs['group'] = self.group
        kwargs.setdefault('project', kwargs['group'].project)
        kwargs.setdefault('message', kwargs['group'].message)
        kwargs.setdefault('data', LEGACY_DATA.copy())
        if kwargs.get('tags'):
            tags = kwargs.pop('tags')
            if isinstance(tags, dict):
                tags = tags.items()
            kwargs['data']['tags'] = tags

        kwargs['data'].setdefault('errors', [{
            'type': EventError.INVALID_DATA,
            'name': 'foobar',
        }])

        event = Event(
            event_id=event_id,
            **kwargs
        )
        # emulate EventManager refs
        event.data.bind_ref(event)
        event.save()
        return event
示例#6
0
文件: tests.py 项目: rkeilty/sentry
    def test_notify_users_renders_interfaces_with_utf8_fix_issue_422(self, _send_mail):
        group = Group(
            id=2,
            first_seen=timezone.now(),
            last_seen=timezone.now(),
            project=self.project,
        )

        stacktrace = Mock(spec=Stacktrace)
        stacktrace.to_email_html.return_value = u'רונית מגן'
        stacktrace.get_title.return_value = 'Stacktrace'

        event = Event()
        event.group = group
        event.project = self.project
        event.message = 'Soubor ji\xc5\xbe existuje'
        event.interfaces = {'sentry.interfaces.Stacktrace': stacktrace}

        notification = Notification(event=event)

        with self.options({'system.url-prefix': 'http://example.com'}):
            self.plugin.notify(notification)

        stacktrace.get_title.assert_called_once_with()
        stacktrace.to_email_html.assert_called_once_with(event)
示例#7
0
    def test_notify_users_renders_interfaces_with_utf8_fix_issue_422(self, _send_mail):
        group = Group(
            id=2,
            first_seen=timezone.now(),
            last_seen=timezone.now(),
            project=self.project,
        )

        stacktrace = Mock(spec=Stacktrace)
        stacktrace.to_email_html.return_value = u'רונית מגן'
        stacktrace.get_title.return_value = 'Stacktrace'

        event = Event()
        event.group = group
        event.project = self.project
        event.message = 'Soubor ji\xc5\xbe existuje'
        event.interfaces = {'sentry.interfaces.Stacktrace': stacktrace}

        notification = Notification(event=event)

        with self.options({'system.url-prefix': 'http://example.com'}):
            self.plugin.notify(notification)

        stacktrace.get_title.assert_called_once_with()
        stacktrace.to_email_html.assert_called_once_with(event)
示例#8
0
def test_event_hash_variant(infile):
    with open(os.path.join(_fixture_path, infile + '.json')) as f:
        input = json.load(f)
    with open(os.path.join(_fixture_path, infile + '.out')) as f:
        refval = f.read().decode('utf-8').rstrip()

    mgr = EventManager(data=input)
    mgr.normalize()
    evt = Event(data=mgr.get_data())

    rv = []
    for (key, value) in sorted(evt.get_grouping_variants().items()):
        if rv:
            rv.append('-' * 74)
        rv.append('%s:' % key)
        dump_variant(value, rv, 1)
    output = '\n'.join(rv)
    if not refval:
        log(output)
    log(repr(evt.get_hashes()))

    assert sorted(evt.get_hashes()) == sorted(
        filter(None,
               [x.get_hash() for x in evt.get_grouping_variants().values()]))

    assert refval == output
示例#9
0
文件: tests.py 项目: unnKoel/sentry
    def test_notify_users_with_owners(self):
        event_all_users = Event(
            group=self.group,
            message=self.group.message,
            project=self.project,
            datetime=self.group.last_seen,
            data=self.make_event_data('foo.cbl'),
        )
        self.assert_notify(event_all_users, [self.user.email, self.user2.email])

        event_team = Event(
            group=self.group,
            message=self.group.message,
            project=self.project,
            datetime=self.group.last_seen,
            data=self.make_event_data('foo.py'),
        )
        self.assert_notify(event_team, [self.user.email, self.user2.email])

        event_single_user = Event(
            group=self.group,
            message=self.group.message,
            project=self.project,
            datetime=self.group.last_seen,
            data=self.make_event_data('foo.jx'),
        )
        self.assert_notify(event_single_user, [self.user2.email])

        # Make sure that disabling mail alerts works as expected
        UserOption.objects.set_value(
            user=self.user2, key='mail:alert', value=0, project=self.project
        )
        event_all_users = Event(
            group=self.group,
            message=self.group.message,
            project=self.project,
            datetime=self.group.last_seen,
            data=self.make_event_data('foo.cbl'),
        )
        self.assert_notify(event_all_users, [self.user.email])
示例#10
0
    def test_notify_users_renders_interfaces_with_utf8(self, _send_mail):
        group = Group(
            id=2,
            first_seen=timezone.now(),
            last_seen=timezone.now(),
            project=self.project,
        )

        stacktrace = Mock(spec=Stacktrace)
        stacktrace.to_email_html.return_value = u'רונית מגן'
        stacktrace.get_title.return_value = 'Stacktrace'

        event = Event()
        event.group = group
        event.project = self.project
        event.message = 'hello world'
        event.interfaces = {'sentry.interfaces.Stacktrace': stacktrace}

        notification = Notification(event=event)

        with self.settings(SENTRY_URL_PREFIX='http://example.com'):
            self.plugin.notify(notification)

        stacktrace.get_title.assert_called_once_with()
        stacktrace.to_email_html.assert_called_once_with(event)
示例#11
0
文件: mail.py 项目: sintong93/sentry
def assigned(request):

    org = Organization(
        id=1,
        slug='example',
        name='Example',
    )
    team = Team(
        id=1,
        slug='example',
        name='Example',
        organization=org,
    )
    project = Project(
        id=1,
        slug='example',
        name='Example',
        team=team,
        organization=org,
    )
    group = Group(
        id=1,
        project=project,
        message='This is an example event.',
    )
    event = Event(
        id=1,
        project=project,
        group=group,
        message=group.message,
        data=load_data('python'),
    )
    assigned = Activity(
        group=event.group,
        event=event,
        project=event.project,
        type=Activity.ASSIGNED,
        user=request.user,
        data={'text': 'This is an example note!'},
    )

    return MailPreview(
        html_template='sentry/emails/activity/assigned.html',
        text_template='sentry/emails/activity/assigned.txt',
        context={
            'data': assigned.data,
            'author': assigned.user,
            'date': assigned.datetime,
            'group': group,
            'link': group.get_absolute_url(),
        },
    ).render()
示例#12
0
    def test_simple(self):
        configure_sdk()
        Hub.current.bind_client(Hub.main.client)

        with self.tasks():
            event_id = raven.captureMessage("internal client test")

        event = nodestore.get(
            Event.generate_node_id(settings.SENTRY_PROJECT, event_id))

        assert event["project"] == settings.SENTRY_PROJECT
        assert event["event_id"] == event_id
        assert event["logentry"]["formatted"] == "internal client test"
示例#13
0
    def get_child_relations_bulk(self, instance_list):
        from sentry.models import Event

        node_ids = []
        for i in instance_list:
            node_id = Event.generate_node_id(i.project_id, i.event_id)
            node_ids.append(node_id)
            # Unbind the NodeField so it doesn't attempt to get
            # get deleted a second time after NodeDeletionTask
            # runs, when the Event itself is deleted.
            i.data = None

        return [BaseRelation({"nodes": node_ids}, NodeDeletionTask)]
示例#14
0
    def create_event(self, event_id=None, **kwargs):
        if event_id is None:
            event_id = uuid4().hex
        if 'group' not in kwargs:
            kwargs['group'] = self.group
        kwargs.setdefault('project', kwargs['group'].project)
        kwargs.setdefault('message', kwargs['group'].message)
        kwargs.setdefault('data', LEGACY_DATA.copy())
        if kwargs.get('tags'):
            tags = kwargs.pop('tags')
            if isinstance(tags, dict):
                tags = tags.items()
            kwargs['data']['tags'] = tags

        event = Event(
            event_id=event_id,
            **kwargs
        )
        # emulate EventManager refs
        event.data.bind_ref(event)
        event.save()
        return event
    def inner(data):
        mgr = EventManager(data={"stacktrace": data})
        mgr.normalize()
        evt = Event(data=mgr.get_data())

        interface = evt.interfaces.get('stacktrace')

        insta_snapshot({
            'errors': evt.data.get('errors'),
            'to_json': interface and interface.to_json(),
            'get_stacktrace': interface and interface.get_stacktrace(evt),
            'to_string': interface and interface.to_string(evt),
        })
示例#16
0
 def test_get_stacktrace_with_module(self):
     event = mock.Mock(spec=Event())
     interface = Stacktrace.to_python(
         dict(frames=[{
             'module': 'foo'
         }, {
             'module': 'bar'
         }]))
     result = interface.get_stacktrace(event)
     self.assertEquals(
         result,
         'Stacktrace (most recent call last):\n\n  Module "foo"\n  Module "bar"'
     )
示例#17
0
def group_event_details_json(request, team, project, group_id,
                             event_id_or_latest):
    group = get_object_or_404(Group, pk=group_id, project=project)

    if event_id_or_latest == 'latest':
        # It's possible that a message would not be created under certain
        # circumstances (such as a post_save signal failing)
        event = group.get_latest_event() or Event()
    else:
        event = get_object_or_404(group.event_set, pk=event_id_or_latest)

    return HttpResponse(json.dumps(event.as_dict()),
                        mimetype='application/json')
示例#18
0
 def test_to_html_render_call(self, render_to_string, get_traceback):
     event = mock.Mock(spec=Event())
     get_traceback.return_value = 'bar'
     interface = Stacktrace(frames=[{'lineno': 1, 'filename': 'foo.py'}])
     result = interface.to_html(event)
     get_traceback.assert_called_once_with(event, newest_first=False)
     render_to_string.assert_called_once_with('sentry/partial/interfaces/stacktrace.html', {
         'event': event,
         'frames': [{'function': None, 'abs_path': None, 'start_lineno': None, 'lineno': 1, 'context': [], 'vars': [], 'in_app': True, 'filename': 'foo.py'}],
         'stacktrace': 'bar',
         'system_frames': 0,
         'newest_first': False,
     })
     self.assertEquals(result, render_to_string.return_value)
示例#19
0
    def get(self, request, organization, project, team, group_id, event_id_or_latest):
        group = get_object_or_404(Group, pk=group_id, project=project)

        if event_id_or_latest == 'latest':
            # It's possible that a message would not be created under certain
            # circumstances (such as a post_save signal failing)
            event = group.get_latest_event() or Event(group=group)
        else:
            event = get_object_or_404(group.event_set, pk=event_id_or_latest)

        Event.objects.bind_nodes([event], 'data')
        GroupMeta.objects.populate_cache([group])

        return HttpResponse(json.dumps(event.as_dict()), mimetype='application/json')
示例#20
0
 def test_get_stacktrace_with_filename_and_function(self):
     event = mock.Mock(spec=Event())
     interface = Stacktrace(frames=[{
         'filename': 'foo',
         'function': 'biz'
     }, {
         'filename': 'bar',
         'function': 'baz'
     }])
     result = interface.get_stacktrace(event)
     self.assertEquals(
         result,
         'Stacktrace (most recent call last):\n\n  File "foo", in biz\n  File "bar", in baz'
     )
示例#21
0
    def inner(data):
        mgr = EventManager(data={"threads": data})
        mgr.normalize()
        evt = Event(data=mgr.get_data())

        interface = evt.interfaces.get("threads")
        insta_snapshot({
            "errors":
            evt.data.get("errors"),
            "to_json":
            interface and interface.to_json(),
            "api_context":
            interface and interface.get_api_context(),
        })
示例#22
0
 def build_event(frames):
     return Event(
         data={
             'sentry.interfaces.Exception': {
                 'values': [
                     {
                         'stacktrace': {
                             'frames': frames,
                         },
                     },
                 ],
             },
         },
     )
示例#23
0
    def inner(data):
        mgr = EventManager(data={"csp": data})
        mgr.normalize()
        evt = Event(data=mgr.get_data())

        interface = evt.interfaces.get("csp")

        insta_snapshot({
            "errors": evt.data.get("errors"),
            "to_json": interface and interface.to_json(),
            "message": interface and interface.get_message(),
            "culprit": interface and interface.get_culprit(),
            "origin": interface and interface.get_origin(),
            "tags": interface and interface.get_tags(),
        })
示例#24
0
def test_event_hash_variant(insta_snapshot, config_name, test_name, log):
    with open(os.path.join(_fixture_path, test_name + '.json')) as f:
        input = json.load(f)

    grouping_config = {
        'id': config_name,
    }
    mgr = EventManager(data=input, grouping_config=grouping_config)
    mgr.normalize()
    data = mgr.get_data()
    evt = Event(data=data, platform=data['platform'])

    rv = []
    for (key, value) in sorted(evt.get_grouping_variants().items()):
        if rv:
            rv.append('-' * 74)
        rv.append('%s:' % key)
        dump_variant(value, rv, 1)
    output = '\n'.join(rv)
    log(repr(evt.get_hashes()))

    assert evt.get_grouping_config() == grouping_config

    insta_snapshot(output)
示例#25
0
def group(request, project, group):
    # It's possible that a message would not be created under certain
    # circumstances (such as a post_save signal failing)
    event = group.get_latest_event() or Event(group=group)

    return render_to_response('sentry/groups/details.html', {
        'project': project,
        'page': 'details',
        'group': group,
        'event': event,
        'interface_list': _get_rendered_interfaces(event),
        'json_data': event.data.get('extra', {}),
        'version_data': event.data.get('modules', None),
        'can_admin_event': can_admin_group(request.user, group),
    }, request)
示例#26
0
    def inner(data):
        mgr = EventManager(data={"csp": data})
        mgr.normalize()
        evt = Event(data=mgr.get_data())

        interface = evt.interfaces.get('csp')

        insta_snapshot({
            'errors': evt.data.get('errors'),
            'to_json': interface and interface.to_json(),
            'message': interface and interface.get_message(),
            'culprit': interface and interface.get_culprit(),
            'origin': interface and interface.get_origin(),
            'tags': interface and interface.get_tags()
        })
示例#27
0
文件: mail.py 项目: zhiqunq/sentry
def new_note(request):
    team = Team(
        id=1,
        slug='example',
        name='Example',
    )
    project = Project(
        id=1,
        slug='example',
        name='Example',
        team=team,
    )
    group = Group(
        id=1,
        project=project,
        message='This is an example event.',
    )
    event = Event(
        id=1,
        project=project,
        group=group,
        message=group.message,
        data=load_data('python'),
    )
    note = Activity(
        group=event.group,
        event=event,
        project=event.project,
        type=Activity.NOTE,
        user=request.user,
        data={'text': 'This is an example note!'},
    )

    preview = MailPreview(
        html_template='sentry/emails/new_note.html',
        text_template='sentry/emails/new_note.txt',
        context={
            'text': note.data['text'],
            'author': note.user,
            'date': note.datetime,
            'group': group,
            'link': group.get_absolute_url(),
        },
    )

    return render_to_response('sentry/debug/mail/preview.html', {
        'preview': preview,
    })
示例#28
0
    def test_get_send_to_with_user_owners(self):
        event = Event(
            group=self.group,
            message=self.group.message,
            project=self.project,
            datetime=self.group.last_seen,
            data=self.make_event_data('foo.cbl')
        )
        assert (sorted(set([self.user.pk, self.user2.pk])) == sorted(
            self.plugin.get_send_to(self.project, event.data)))

        # Make sure that disabling mail alerts works as expected
        UserOption.objects.set_value(
            user=self.user2, key='mail:alert', value=0, project=self.project
        )
        assert set([self.user.pk]) == self.plugin.get_send_to(self.project, event.data)
示例#29
0
文件: groups.py 项目: Supy/sentry
def render_with_group_context(group, template, context, request=None):
    # It's possible that a message would not be created under certain
    # circumstances (such as a post_save signal failing)
    event = group.get_latest_event() or Event()
    event.group = group

    context.update({
        'project': group.project,
        'group': group,
        'event': event,
        'json_data': event.data.get('extra', {}),
        'version_data': event.data.get('modules', None),
        'can_admin_event': can_admin_group(request.user, group),
    })

    return render_to_response(template, context, request)
示例#30
0
    def test_dupe_message_id(self, eventstream_insert):
        # Saves the latest event to nodestore and eventstream
        project_id = 1
        event_id = "a" * 32
        node_id = Event.generate_node_id(project_id, event_id)

        manager = EventManager(make_event(event_id=event_id, message="first"))
        manager.normalize()
        manager.save(project_id)
        assert nodestore.get(node_id)["logentry"]["formatted"] == "first"

        manager = EventManager(make_event(event_id=event_id, message="second"))
        manager.normalize()
        manager.save(project_id)
        assert nodestore.get(node_id)["logentry"]["formatted"] == "second"

        assert eventstream_insert.call_count == 2
示例#31
0
    def test_encoding(self):
        configure_sdk()
        Hub.current.bind_client(Hub.main.client)

        class NotJSONSerializable:
            pass

        with self.tasks():
            event_id = raven.captureMessage(
                "check the req", extra={"request": NotJSONSerializable()})

        event = nodestore.get(
            Event.generate_node_id(settings.SENTRY_PROJECT, event_id))

        assert event["project"] == settings.SENTRY_PROJECT
        assert event["logentry"]["formatted"] == "check the req"
        assert "NotJSONSerializable" in event["extra"]["request"]
示例#32
0
def group(request, team, project, group, event_id=None):
    # It's possible that a message would not be created under certain
    # circumstances (such as a post_save signal failing)
    activity_qs = Activity.objects.order_by('-datetime').select_related('user')
    if event_id:
        event = get_object_or_404(group.event_set, id=event_id)
        activity_qs = activity_qs.filter(
            Q(event=event) | Q(event__isnull=True), )
    else:
        event = group.get_latest_event() or Event()

    # bind params to group in case they get hit
    event.group = group
    event.project = project

    # filter out dupes
    activity_items = set()
    activity = []
    for item in activity_qs.filter(group=group)[:10]:
        sig = (item.event_id, item.type, item.ident, item.user_id)
        if sig not in activity_items:
            activity_items.add(sig)
            activity.append(item)

    # trim to latest 5
    activity = activity[:5]

    context = {
        'page': 'details',
        'activity': activity,
    }

    is_public = group_is_public(group, request.user)

    if is_public:
        template = 'sentry/groups/public_details.html'
        context['PROJECT_LIST'] = [project]
    else:
        template = 'sentry/groups/details.html'

    return render_with_group_context(group,
                                     template,
                                     context,
                                     request,
                                     event=event,
                                     is_public=is_public)
示例#33
0
    def inner(data):
        mgr = EventManager(data={"exception": data})
        mgr.normalize()
        evt = Event(data=mgr.get_data())

        interface = evt.interfaces.get('exception')

        insta_snapshot({
            'errors':
            evt.data.get('errors'),
            'to_json':
            interface and interface.to_json(),
            'get_api_context':
            interface and interface.get_api_context(),
            'to_string':
            interface and interface.to_string(evt),
        })
示例#34
0
    def inner(data):
        mgr = EventManager(data={"stacktrace": data})
        mgr.normalize()
        evt = Event(data=mgr.get_data())

        interface = evt.interfaces.get("stacktrace")

        insta_snapshot({
            "errors":
            evt.data.get("errors"),
            "to_json":
            interface and interface.to_json(),
            "get_stacktrace":
            interface and interface.get_stacktrace(evt),
            "to_string":
            interface and interface.to_string(evt),
        })
示例#35
0
    def test_simple(self):
        event_id = "a" * 32
        project = self.create_project()
        node_id = Event.generate_node_id(project.id, event_id)
        group = self.create_group(project=project)
        event = self.create_event(group=group, event_id=event_id)
        EventAttachment.objects.create(
            event_id=event.event_id,
            project_id=event.project_id,
            file=File.objects.create(name="hello.png", type="image/png"),
            name="hello.png",
        )
        UserReport.objects.create(event_id=event.event_id,
                                  project_id=event.project_id,
                                  name="Jane Doe")
        key = "key"
        value = "value"
        tk = tagstore.create_tag_key(project_id=project.id,
                                     environment_id=self.environment.id,
                                     key=key)
        tv = tagstore.create_tag_value(project_id=project.id,
                                       environment_id=self.environment.id,
                                       key=key,
                                       value=value)
        tagstore.create_event_tags(
            event_id=event.id,
            group_id=group.id,
            project_id=project.id,
            environment_id=self.environment.id,
            tags=[(tk.key, tv.value)],
        )
        assert nodestore.get(node_id) is not None
        deletion = ScheduledDeletion.schedule(event, days=0)
        deletion.update(in_progress=True)

        with self.tasks():
            run_deletion(deletion.id)

        assert not Event.objects.filter(id=event.id).exists()
        assert not EventAttachment.objects.filter(
            event_id=event.event_id, project_id=project.id).exists()
        assert not UserReport.objects.filter(event_id=event.event_id,
                                             project_id=project.id).exists()
        assert not EventTag.objects.filter(event_id=event.id).exists()

        assert nodestore.get(node_id) is None
示例#36
0
    def get(self, request):
        org = Organization(
            id=1,
            slug='organization',
            name='My Company',
        )
        team = Team(
            id=1,
            slug='team',
            name='My Team',
            organization=org,
        )
        project = Project(
            id=1,
            organization=org,
            team=team,
            slug='project',
            name='My Project',
        )

        group = next(
            make_group_generator(
                get_random(request),
                project,
            ),
        )

        event = Event(
            id=1,
            project=project,
            group=group,
            message=group.message,
            data=load_data('python'),
            datetime=datetime(2016, 6, 13, 3, 8, 24, tzinfo=timezone.utc),
        )

        activity = Activity(
            group=event.group, project=event.project,
            **self.get_activity(request, event)
        )

        return render_to_response('sentry/debug/mail/preview.html', {
            'preview': ActivityMailPreview(activity),
            'format': request.GET.get('format'),
        })