def get(self, request: Request) -> Response: org = Organization(id=1, slug="organization", name="My Company") project = Project(id=1, organization=org, slug="project", name="My Project") group = next(make_group_generator(get_random(request), project)) data = dict(load_data("python")) data["message"] = group.message data.pop("logentry", None) event_manager = EventManager(data) event_manager.normalize() data = event_manager.get_data() event_type = get_event_type(data) event = eventstore.create_event( event_id="a" * 32, group_id=group.id, project_id=project.id, data=data.data ) group.message = event.search_message group.data = {"type": event_type.key, "metadata": event_type.get_metadata(data)} activity = Activity(group=group, project=event.project, **self.get_activity(request, event)) return render_to_response( "sentry/debug/mail/preview.html", context={ "preview": ActivityMailPreview(request, activity), "format": request.GET.get("format"), }, )
def test_notify_users_does_email(self, mock_func): event_manager = EventManager({ "message": "hello world", "level": "error" }) event_manager.normalize() event_data = event_manager.get_data() event_type = get_event_type(event_data) event_data["type"] = event_type.key event_data["metadata"] = event_type.get_metadata(event_data) event = event_manager.save(self.project.id) group = event.group with self.tasks(): AlertRuleNotification(Notification(event=event), ActionTargetType.ISSUE_OWNERS).send() assert mock_func.call_count == 1 args, kwargs = mock_func.call_args notification = args[1] self.assertEquals(notification.project, self.project) self.assertEquals(notification.get_reference(), group) assert notification.get_subject() == "BAR-1 - hello world"
def test_notify_users_does_email(self, mock_func): UserOption.objects.create(user=self.user, key="timezone", value="Europe/Vienna") event_manager = EventManager({ "message": "hello world", "level": "error" }) event_manager.normalize() event_data = event_manager.get_data() event_type = get_event_type(event_data) event_data["type"] = event_type.key event_data["metadata"] = event_type.get_metadata(event_data) event = event_manager.save(self.project.id) group = event.group with self.tasks(): AlertRuleNotification(Notification(event=event), ActionTargetType.ISSUE_OWNERS).send() assert mock_func.call_count == 1 args, kwargs = mock_func.call_args notification = args[1] assert notification.get_user_context( self.user, {})["timezone"] == pytz.timezone("Europe/Vienna") self.assertEquals(notification.project, self.project) self.assertEquals(notification.get_reference(), group) assert notification.get_subject() == "BAR-1 - hello world"
def test_email_notification_is_not_sent_to_deleted_email(self, mock_func): """ Test that ensures if we still have some stale emails in UserOption, then upon attempting to send an email notification to those emails, these stale `UserOption` instances are deleted """ # Initial Creation user = self.create_user(email="*****@*****.**", is_active=True) self.create_member(user=user, organization=self.organization, teams=[self.team]) UserOption.objects.create(user=user, key="mail:email", value="*****@*****.**", project=self.project) # New secondary email is created useremail = UserEmail.objects.create(user=user, email="*****@*****.**", is_verified=True) # Set secondary email to be primary user.email = useremail.email user.save() # Delete first email old_useremail = UserEmail.objects.get(email="*****@*****.**") old_useremail.delete() event_manager = EventManager({ "message": "hello world", "level": "error" }) event_manager.normalize() event_data = event_manager.get_data() event_type = get_event_type(event_data) event_data["type"] = event_type.key event_data["metadata"] = event_type.get_metadata(event_data) event = event_manager.save(self.project.id) with self.tasks(): AlertRuleNotification(Notification(event=event), ActionTargetType.ISSUE_OWNERS).send() assert mock_func.call_count == 1 args, kwargs = mock_func.call_args notification = args[1] user_ids = [] for user in list(notification.get_participants().values())[0]: user_ids.append(user.id) assert "*****@*****.**" in get_email_addresses(user_ids, self.project).values() assert not len( UserOption.objects.filter(key="mail:email", value="*****@*****.**"))
def make_event_data(self, filename, url="http://example.com"): mgr = EventManager( { "tags": [("level", "error")], "stacktrace": {"frames": [{"lineno": 1, "filename": filename}]}, "request": {"url": url}, } ) mgr.normalize() data = mgr.get_data() event_type = get_event_type(data) data["type"] = event_type.key data["metadata"] = event_type.get_metadata(data) return data
def test_multiline_error(self, _send_mail): event_manager = EventManager({"message": "hello world\nfoo bar", "level": "error"}) event_manager.normalize() event_data = event_manager.get_data() event_type = get_event_type(event_data) event_data["type"] = event_type.key event_data["metadata"] = event_type.get_metadata(event_data) event = event_manager.save(self.project.id) notification = Notification(event=event) with self.options({"system.url-prefix": "http://example.com"}): self.adapter.notify(notification, ActionTargetType.ISSUE_OWNERS) assert _send_mail.call_count == 1 args, kwargs = _send_mail.call_args assert kwargs.get("subject") == "BAR-1 - hello world"
def _process_snuba_results(query_res, group: Group, id: int, user): event_ids = { row["latest_event_id"]: Event.generate_node_id(group.project_id, row["latest_event_id"]) for row in query_res } node_data = nodestore.get_multi(list(event_ids.values())) response = [] for row in query_res: response_item = { "hash": row["new_materialized_hash"], "eventCount": row["event_count"], } event_id = row["latest_event_id"] event_data = node_data.get(event_ids[event_id], None) if event_data is not None: event = Event(group.project_id, event_id, group_id=group.id, data=event_data) response_item["latestEvent"] = serialize(event, user, EventSerializer()) tree_label = get_path( event_data, "hierarchical_tree_labels", id) or get_path( event_data, "hierarchical_tree_labels", -1) # Rough approximation of what happens with Group title event_type = get_event_type(event.data) metadata = dict(event.get_event_metadata()) metadata["current_tree_label"] = tree_label # Force rendering of grouping tree labels irrespective of platform metadata["display_title_with_tree_label"] = True title = event_type.get_title(metadata) response_item["title"] = title or event.title response_item["metadata"] = metadata response.append(response_item) return response
def test_multiline_error(self, mock_func): event_manager = EventManager({ "message": "hello world\nfoo bar", "level": "error" }) event_manager.normalize() event_data = event_manager.get_data() event_type = get_event_type(event_data) event_data["type"] = event_type.key event_data["metadata"] = event_type.get_metadata(event_data) event = event_manager.save(self.project.id) with self.tasks(): AlertRuleNotification(Notification(event=event), ActionTargetType.ISSUE_OWNERS).send() assert mock_func.call_count == 1 args, kwargs = mock_func.call_args notification = args[1] assert notification.get_subject() == "BAR-1 - hello world"
def test_notify_users_does_email(self, _send_mail): event_manager = EventManager({"message": "hello world", "level": "error"}) event_manager.normalize() event_data = event_manager.get_data() event_type = get_event_type(event_data) event_data["type"] = event_type.key event_data["metadata"] = event_type.get_metadata(event_data) event = event_manager.save(self.project.id) group = event.group notification = Notification(event=event) with self.options({"system.url-prefix": "http://example.com"}): self.adapter.notify(notification, ActionTargetType.ISSUE_OWNERS) assert _send_mail.call_count == 1 args, kwargs = _send_mail.call_args self.assertEquals(kwargs.get("project"), self.project) self.assertEquals(kwargs.get("reference"), group) assert kwargs.get("subject") == "BAR-1 - hello world"
def create_event(self, grouping_config=None): input = dict(self.data) config = FingerprintingRules.from_json({ "rules": input.pop("_fingerprinting_rules"), "version": 1 }) mgr = EventManager(data=input, grouping_config=grouping_config) mgr.normalize() data = mgr.get_data() data.setdefault("fingerprint", ["{{ default }}"]) apply_server_fingerprinting(data, config) event_type = get_event_type(data) event_metadata = event_type.get_metadata(data) data.update(materialize_metadata(data, event_type, event_metadata)) evt = eventstore.create_event(data=data) return config, evt
def inner(data): mgr = EventManager( data={ "expectstaple": data, "logentry": {"message": "XXX EXPECTSTAPLE MESSAGE NOT THROUGH RELAY XXX"}, } ) mgr.normalize() data = mgr.get_data() event_type = get_event_type(data) event_metadata = event_type.get_metadata(data) data.update(materialize_metadata(data, event_type, event_metadata)) evt = eventstore.create_event(data=data) insta_snapshot( { "errors": evt.data.get("errors"), "to_json": evt.interfaces.get("expectstaple").to_json(), "metadata": evt.get_event_metadata(), "title": evt.title, } )
def alert(request): platform = request.GET.get("platform", "python") org = Organization(id=1, slug="example", name="Example") project = Project(id=1, slug="example", name="Example", organization=org) random = get_random(request) group = next(make_group_generator(random, project)) data = dict(load_data(platform)) data["message"] = group.message data["event_id"] = "44f1419e73884cd2b45c79918f4b6dc4" data.pop("logentry", None) data["environment"] = "prod" data["tags"] = [ ("logger", "javascript"), ("environment", "prod"), ("level", "error"), ("device", "Other"), ] event_manager = EventManager(data) event_manager.normalize() data = event_manager.get_data() event = event_manager.save(project.id) # Prevent CI screenshot from constantly changing event.data["timestamp"] = 1504656000.0 # datetime(2017, 9, 6, 0, 0) event_type = get_event_type(event.data) group.message = event.search_message group.data = { "type": event_type.key, "metadata": event_type.get_metadata(data) } rule = Rule(id=1, label="An example rule") # XXX: this interface_list code needs to be the same as in # src/sentry/mail/adapter.py interface_list = [] for interface in event.interfaces.values(): body = interface.to_email_html(event) if not body: continue text_body = interface.to_string(event) interface_list.append( (interface.get_title(), mark_safe(body), text_body)) return MailPreview( html_template="sentry/emails/error.html", text_template="sentry/emails/error.txt", context={ "rule": rule, "rules": get_rules([rule], org, project), "group": group, "event": event, "timezone": pytz.timezone("Europe/Vienna"), # http://testserver/organizations/example/issues/<issue-id>/?referrer=alert_email # &alert_type=email&alert_timestamp=<ts>&alert_rule_id=1 "link": get_group_settings_link(group, None, get_rules([rule], org, project), 1337), "interfaces": interface_list, "tags": event.tags, "project_label": project.slug, "alert_status_page_enabled": features.has("organizations:alert-rule-status-page", org), "commits": [{ # TODO(dcramer): change to use serializer "repository": { "status": "active", "name": "Example Repo", "url": "https://github.com/example/example", "dateCreated": "2018-02-28T23:39:22.402Z", "provider": { "id": "github", "name": "GitHub" }, "id": "1", }, "score": 2, "subject": "feat: Do something to raven/base.py", "message": "feat: Do something to raven/base.py\naptent vivamus vehicula tempus volutpat hac tortor", "id": "1b17483ffc4a10609e7921ee21a8567bfe0ed006", "shortId": "1b17483", "author": { "username": "******", "isManaged": False, "lastActive": "2018-03-01T18:25:28.149Z", "id": "1", "isActive": True, "has2fa": False, "name": "*****@*****.**", "avatarUrl": "https://secure.gravatar.com/avatar/51567a4f786cd8a2c41c513b592de9f9?s=32&d=mm", "dateJoined": "2018-02-27T22:04:32.847Z", "emails": [{ "is_verified": False, "id": "1", "email": "*****@*****.**" }], "avatar": { "avatarUuid": None, "avatarType": "letter_avatar" }, "lastLogin": "******", "email": "*****@*****.**", }, }], }, ).render(request)