def test_doesnt_update_verify_install_if_internal(self): self.create_project(organization=self.org) sentry_app = self.create_internal_integration(name="Internal", organization=self.org) updater = Updater(sentry_app=sentry_app, user=self.user) updater.verify_install = True with self.assertRaises(APIError): updater.call()
def post(self, request, sentry_app): # check status of app to make sure it is unpublished if sentry_app.is_published: return Response({"detail": "Cannot publish already published integration."}, status=400) if sentry_app.is_internal: return Response({"detail": "Cannot publish internal integration."}, status=400) if sentry_app.is_publish_request_inprogress: return Response({"detail": "Publish request in progress."}, status=400) Updater.run( user=request.user, sentry_app=sentry_app, status=SentryAppStatus.PUBLISH_REQUEST_INPROGRESS_STR, ) message = f"User {request.user.email} of organization {sentry_app.owner.slug} wants to publish {sentry_app.slug}\n" for question_pair in request.data.get("questionnaire"): message += "\n\n>{}\n{}".format(question_pair["question"], question_pair["answer"]) subject = "Sentry Integration Publication Request from %s" % sentry_app.owner.slug email.send_mail( subject, message, options.get("mail.from"), ["*****@*****.**"], reply_to=[request.user.email], ) return Response(status=201)
def post(self, request: Request, sentry_app) -> Response: # check status of app to make sure it is unpublished if sentry_app.is_published: return Response( {"detail": "Cannot publish already published integration."}, status=400) if sentry_app.is_internal: return Response({"detail": "Cannot publish internal integration."}, status=400) if sentry_app.is_publish_request_inprogress: return Response({"detail": "Publish request in progress."}, status=400) if not SentryAppAvatar.objects.filter( sentry_app=sentry_app, color=True, avatar_type=SentryAppAvatarTypes.UPLOAD.value).exists(): return Response( {"detail": "Must upload a logo for the integration."}, status=400) if (self.has_ui_component(sentry_app) and not SentryAppAvatar.objects.filter( sentry_app=sentry_app, color=False, avatar_type=SentryAppAvatarTypes.UPLOAD.value, ).exists()): return Response( { "detail": "Must upload an icon for issue and stack trace linking integrations." }, status=400, ) Updater.run( user=request.user, sentry_app=sentry_app, status=SentryAppStatus.PUBLISH_REQUEST_INPROGRESS_STR, ) message = f"User {request.user.email} of organization {sentry_app.owner.slug} wants to publish {sentry_app.slug}\n" for question_pair in request.data.get("questionnaire"): message += "\n\n>{}\n{}".format(question_pair["question"], question_pair["answer"]) subject = "Sentry Integration Publication Request from %s" % sentry_app.owner.slug email.send_mail( subject, message, options.get("mail.from"), ["*****@*****.**"], reply_to=[request.user.email], ) return Response(status=201)
def test_doesnt_update_app_with_invalid_event_permissions(self): sentry_app = self.create_sentry_app( name="sentry", organization=self.org, scopes=("project:read",) ) updater = Updater(sentry_app=sentry_app, user=self.user) updater.events = ("issue",) with self.assertRaises(APIError): updater.call()
def test_doesnt_update_published_app_scopes(self): sentry_app = self.create_sentry_app( name="sentry", organization=self.org, scopes=("project:read",), published=True ) updater = Updater(sentry_app=sentry_app, user=self.user) updater.scopes = ("project:read", "project:write") with self.assertRaises(APIError): updater.call()
def setUp(self): self.user = self.create_user() self.sentry_app = Creator.run( name='nulldb', user=self.user, scopes=('project:read', ), webhook_url='http://example.com', ) self.updater = Updater(sentry_app=self.sentry_app)
def test_delete_service_hook_on_update(self): self.create_project(organization=self.org) internal_app = self.create_internal_integration( name="Internal", organization=self.org, webhook_url="https://sentry.io/hook" ) assert len(ServiceHook.objects.filter(application=internal_app.application)) == 1 updater = Updater(sentry_app=internal_app, user=self.user) updater.webhook_url = "" updater.call() assert len(ServiceHook.objects.filter(application=internal_app.application)) == 0
def test_doesnt_update_app_with_invalid_event_permissions(self): sentry_app = self.create_sentry_app( name='sentry', organization=self.org, scopes=('project:read',), ) updater = Updater(sentry_app=sentry_app, user=self.user) updater.events = ('issue',) with self.assertRaises(APIError): updater.call()
def setUp(self): self.user = self.create_user() self.org = self.create_organization(owner=self.user) self.sentry_app = self.create_sentry_app( name="nulldb", organization=self.org, scopes=("project:read",), schema={"elements": [self.create_issue_link_schema()]}, ) self.updater = Updater(sentry_app=self.sentry_app, user=self.user)
def setUp(self): self.user = self.create_user() self.org = self.create_organization(owner=self.user) self.sentry_app = self.create_sentry_app( name='nulldb', organization=self.org, scopes=('project:read', ), ) self.updater = Updater(sentry_app=self.sentry_app)
def test_doesnt_update_app_with_invalid_event_permissions(self): sentry_app = self.create_sentry_app( name='sentry', organization=self.org, scopes=('project:read', ), ) updater = Updater(sentry_app=sentry_app) updater.events = ('issue', ) with self.assertRaises(APIError): updater.call()
def setUp(self): self.user = self.create_user() self.org = self.create_organization(owner=self.user) self.sentry_app = self.create_sentry_app( name='nulldb', organization=self.org, scopes=('project:read', ), schema={'elements': [self.create_issue_link_schema()]}, ) self.updater = Updater(sentry_app=self.sentry_app)
def test_doesnt_update_published_app_scopes(self): sentry_app = self.create_sentry_app( name='sentry', organization=self.org, scopes=('project:read',), published=True, ) updater = Updater(sentry_app=sentry_app, user=self.user) updater.scopes = ('project:read', 'project:write', ) with self.assertRaises(APIError): updater.call()
def test_doesnt_update_published_app_scopes(self): sentry_app = self.create_sentry_app( name='sentry', organization=self.org, scopes=('project:read',), published=True, ) updater = Updater(sentry_app=sentry_app) updater.scopes = ('project:read', 'project:write', ) with self.assertRaises(APIError): updater.call()
def test_updates_service_hook_events(self): sentry_app = self.create_sentry_app( name='sentry', organization=self.org, scopes=('project:read', 'event:read',), events=('event.alert',), ) self.create_sentry_app_installation(slug='sentry') updater = Updater(sentry_app=sentry_app, events=('issue',), user=self.user) updater.call() assert set(sentry_app.events) == expand_events(['issue']) service_hook = ServiceHook.objects.filter(application=sentry_app.application)[0] assert set(service_hook.events) == expand_events(['issue'])
def test_updates_service_hook_events(self): sentry_app = self.create_sentry_app( name="sentry", organization=self.org, scopes=("project:read", "event:read"), events=("event.alert",), ) self.create_sentry_app_installation(slug="sentry") updater = Updater(sentry_app=sentry_app, events=("issue",), user=self.user) updater.call() assert set(sentry_app.events) == expand_events(["issue"]) service_hook = ServiceHook.objects.filter(application=sentry_app.application)[0] assert set(service_hook.events) == expand_events(["issue"])
def test_doesnt_update_published_app_scopes(self): sentry_app = Creator.run( name='sentry', organization=self.org, scopes=('project:read',), webhook_url='http://example.com', ) sentry_app.update(status=SentryAppStatus.PUBLISHED) updater = Updater(sentry_app=sentry_app) updater.scopes = ('project:read', 'project:write', ) with self.assertRaises(APIError): updater.call()
def test_update_scopes_internal_integration(self): self.create_project(organization=self.org) sentry_app = self.create_internal_integration( scopes=("project:read",), organization=self.org ) updater = Updater(sentry_app=sentry_app, user=self.user) updater.scopes = ("project:read", "project:write") updater.call() assert sentry_app.get_scopes() == ["project:read", "project:write"] assert ApiToken.objects.get(application=sentry_app.application).get_scopes() == [ "project:read", "project:write", ]
class TestUpdater(TestCase): def setUp(self): self.user = self.create_user() self.sentry_app = Creator.run( name='nulldb', user=self.user, scopes=('project:read',), webhook_url='http://example.com', ) self.updater = Updater(sentry_app=self.sentry_app) def test_updates_name(self): self.updater.name = 'A New Thing' self.updater.call() assert self.sentry_app.name == 'A New Thing' def test_updates_scopes(self): self.updater.scopes = ('project:read', 'project:write', ) self.updater.call() assert self.sentry_app.get_scopes() == \ ['project:read', 'project:write'] def test_rejects_scope_subtractions(self): self.updater.scopes = (None, ) with self.assertRaises(ValidationError): self.updater.call() def test_updates_webhook_url(self): self.updater.webhook_url = 'http://example.com/hooks' self.updater.call() assert self.sentry_app.webhook_url == 'http://example.com/hooks'
def put(self, request, sentry_app): if not features.has('organizations:internal-catchall', sentry_app.owner, actor=request.user): return Response(status=404) serializer = SentryAppSerializer(data=request.DATA, partial=True) if serializer.is_valid(): result = serializer.object updated_app = Updater.run( sentry_app=sentry_app, name=result.get('name'), webhook_url=result.get('webhookUrl'), redirect_url=result.get('redirectUrl'), is_alertable=result.get('isAlertable'), scopes=result.get('scopes'), events=result.get('events'), overview=result.get('overview'), ) return Response(serialize(updated_app, request.user)) return Response(serializer.errors, status=400)
def put(self, request, sentry_app): if not features.has('organizations:sentry-apps', sentry_app.owner, actor=request.user): return Response(status=404) serializer = SentryAppSerializer( sentry_app, data=request.data, partial=True, ) if serializer.is_valid(): result = serializer.validated_data updated_app = Updater.run( user=request.user, sentry_app=sentry_app, name=result.get('name'), author=result.get('author'), status=result.get('status'), webhook_url=result.get('webhookUrl'), redirect_url=result.get('redirectUrl'), is_alertable=result.get('isAlertable'), scopes=result.get('scopes'), events=result.get('events'), schema=result.get('schema'), overview=result.get('overview'), ) return Response(serialize(updated_app, request.user)) return Response(serializer.errors, status=400)
def test_updates_webhook_url(self): sentry_app = self.create_sentry_app( name="sentry", organization=self.org, scopes=("project:read", "event:read"), events=("event.alert",), ) self.create_sentry_app_installation(slug="sentry") updater = Updater( sentry_app=sentry_app, webhook_url="http://example.com/hooks", user=self.user ) updater.call() assert sentry_app.webhook_url == "http://example.com/hooks" service_hook = ServiceHook.objects.get(application=sentry_app.application) assert service_hook.url == "http://example.com/hooks" assert set(service_hook.events) == expand_events(["event.alert"])
def put(self, request, sentry_app): if self._has_hook_events(request) and not features.has( "organizations:integrations-event-hooks", sentry_app.owner, actor=request.user ): return Response( { "non_field_errors": [ "Your organization does not have access to the 'error' resource subscription." ] }, status=403, ) # isInternal is not field of our model but it is a field of the serializer data = request.data.copy() data["isInternal"] = sentry_app.status == SentryAppStatus.INTERNAL serializer = SentryAppSerializer(sentry_app, data=data, partial=True, access=request.access) if serializer.is_valid(): result = serializer.validated_data updated_app = Updater.run( user=request.user, sentry_app=sentry_app, name=result.get("name"), author=result.get("author"), status=result.get("status"), webhook_url=result.get("webhookUrl"), redirect_url=result.get("redirectUrl"), is_alertable=result.get("isAlertable"), verify_install=result.get("verifyInstall"), scopes=result.get("scopes"), events=result.get("events"), schema=result.get("schema"), overview=result.get("overview"), allowed_origins=result.get("allowedOrigins"), ) return Response(serialize(updated_app, request.user, access=request.access)) # log any errors with schema if "schema" in serializer.errors: for error_message in serializer.errors["schema"]: name = "sentry_app.schema_validation_error" log_info = { "schema": json.dumps(request.data["schema"]), "user_id": request.user.id, "sentry_app_id": sentry_app.id, "sentry_app_name": sentry_app.name, "organization_id": sentry_app.owner.id, "error_message": error_message, } logger.info(name, extra=log_info) analytics.record(name, **log_info) return Response(serializer.errors, status=400)
def setUp(self): self.user = self.create_user() self.sentry_app = Creator.run( name='nulldb', user=self.user, scopes=('project:read',), webhook_url='http://example.com', ) self.updater = Updater(sentry_app=self.sentry_app)
def put(self, request, sentry_app): serializer = SentryAppSerializer(data=request.DATA, partial=True) if serializer.is_valid(): result = serializer.object updated_app = Updater.run( sentry_app=sentry_app, name=result.get('name'), webhook_url=result.get('webhook_url'), scopes=result.get('scopes'), ) return Response(serialize(updated_app, request.user)) return Response(serializer.errors, status=400)
def setUp(self): self.user = self.create_user() self.org = self.create_organization(owner=self.user) self.sentry_app = self.create_sentry_app( name='nulldb', organization=self.org, scopes=('project:read',), schema={'elements': [self.create_issue_link_schema()]}, ) self.updater = Updater( sentry_app=self.sentry_app, user=self.user, )
def test_update_webhook_published_app(self): sentry_app = self.create_sentry_app( name="sentry", organization=self.org, scopes=("project:read",), published=True ) updater = Updater(sentry_app=sentry_app, user=self.user) # pass in scopes but as the same value updater.scopes = ["project:read"] updater.webhook_url = "http://example.com/hooks" updater.call() assert sentry_app.webhook_url == "http://example.com/hooks"
def put(self, request, sentry_app): if not features.has('organizations:sentry-apps', sentry_app.owner, actor=request.user): return Response(status=404) if self._has_hook_events(request) and not features.has( 'organizations:integrations-event-hooks', sentry_app.owner, actor=request.user): return Response( { "non_field_errors": [ "Your organization does not have access to the 'error' resource subscription.", ] }, status=403) serializer = SentryAppSerializer( sentry_app, data=request.data, partial=True, ) if serializer.is_valid(): result = serializer.validated_data updated_app = Updater.run( user=request.user, sentry_app=sentry_app, name=result.get('name'), author=result.get('author'), status=result.get('status'), webhook_url=result.get('webhookUrl'), redirect_url=result.get('redirectUrl'), is_alertable=result.get('isAlertable'), verify_install=result.get('verifyInstall'), scopes=result.get('scopes'), events=result.get('events'), schema=result.get('schema'), overview=result.get('overview'), ) return Response(serialize(updated_app, request.user)) return Response(serializer.errors, status=400)
def test_create_service_hook_on_update(self): self.create_project(organization=self.org) internal_app = self.create_internal_integration( name="Internal", organization=self.org, webhook_url=None, scopes=("event:read",) ) assert len(ServiceHook.objects.filter(application=internal_app.application)) == 0 updater = Updater(sentry_app=internal_app, user=self.user) updater.webhook_url = "https://sentry.io/hook" updater.events = ("issue",) updater.call() service_hook = ServiceHook.objects.get(application=internal_app.application) assert service_hook.url == "https://sentry.io/hook" assert set(service_hook.events) == expand_events(["issue"])
def put(self, request, sentry_app): if not features.has('organizations:sentry-apps', sentry_app.owner, actor=request.user): return Response(status=404) data = { 'user': request.user, 'sentry_app': sentry_app, 'name': request.json_body.get('name'), 'status': request.json_body.get('status'), 'author': request.json_body.get('author'), 'webhookUrl': request.json_body.get('webhookUrl'), 'redirectUrl': request.json_body.get('redirectUrl'), 'isAlertable': request.json_body.get('isAlertable'), 'scopes': request.json_body.get('scopes'), 'events': request.json_body.get('events'), 'schema': request.json_body.get('schema'), 'overview': request.json_body.get('overview'), } serializer = SentryAppSerializer( instance=sentry_app, data=data, partial=True, ) if serializer.is_valid(): result = serializer.object data['redirect_url'] = data['redirectUrl'] data['webhook_url'] = data['webhookUrl'] data['is_alertable'] = data['isAlertable'] data['scopes'] = result.get('scopes') data['events'] = result.get('events') updated_app = Updater.run(**data) return Response(serialize(updated_app, request.user)) return Response(serializer.errors, status=400)
class TestUpdater(TestCase): def setUp(self): self.user = self.create_user() self.org = self.create_organization(owner=self.user) self.sentry_app = Creator.run( name='nulldb', organization=self.org, scopes=('project:read', ), webhook_url='http://example.com', ) self.updater = Updater(sentry_app=self.sentry_app) def test_updates_name(self): self.updater.name = 'A New Thing' self.updater.call() assert self.sentry_app.name == 'A New Thing' def test_updates_scopes(self): self.updater.scopes = ( 'project:read', 'project:write', ) self.updater.call() assert self.sentry_app.get_scopes() == \ ['project:read', 'project:write'] def test_rejects_scope_subtractions(self): self.updater.scopes = (None, ) with self.assertRaises(ValidationError): self.updater.call() def test_updates_webhook_url(self): self.updater.webhook_url = 'http://example.com/hooks' self.updater.call() assert self.sentry_app.webhook_url == 'http://example.com/hooks'
class TestUpdater(TestCase): def setUp(self): self.user = self.create_user() self.org = self.create_organization(owner=self.user) self.sentry_app = self.create_sentry_app( name='nulldb', organization=self.org, scopes=('project:read', ), ) self.updater = Updater(sentry_app=self.sentry_app) def test_updates_name(self): self.updater.name = 'A New Thing' self.updater.call() assert self.sentry_app.name == 'A New Thing' def test_updates_unpublished_app_scopes(self): self.updater.scopes = ( 'project:read', 'project:write', ) self.updater.call() assert self.sentry_app.get_scopes() == \ ['project:read', 'project:write'] def test_doesnt_update_published_app_scopes(self): sentry_app = self.create_sentry_app( name='sentry', organization=self.org, scopes=('project:read', ), published=True, ) updater = Updater(sentry_app=sentry_app) updater.scopes = ( 'project:read', 'project:write', ) with self.assertRaises(APIError): updater.call() def test_updates_webhook_url(self): self.updater.webhook_url = 'http://example.com/hooks' self.updater.call() assert self.sentry_app.webhook_url == 'http://example.com/hooks'
class TestUpdater(TestCase): def setUp(self): self.user = self.create_user() self.org = self.create_organization(owner=self.user) self.sentry_app = self.create_sentry_app( name='nulldb', organization=self.org, scopes=('project:read',), schema={'elements': [self.create_issue_link_schema()]}, ) self.updater = Updater( sentry_app=self.sentry_app, user=self.user, ) def test_updates_name(self): self.updater.name = 'A New Thing' self.updater.call() assert self.sentry_app.name == 'A New Thing' def test_updates_unpublished_app_scopes(self): self.updater.scopes = ('project:read', 'project:write', ) self.updater.call() assert self.sentry_app.get_scopes() == \ ['project:read', 'project:write'] def test_doesnt_update_published_app_scopes(self): sentry_app = self.create_sentry_app( name='sentry', organization=self.org, scopes=('project:read',), published=True, ) updater = Updater(sentry_app=sentry_app, user=self.user) updater.scopes = ('project:read', 'project:write', ) with self.assertRaises(APIError): updater.call() def test_doesnt_update_app_with_invalid_event_permissions(self): sentry_app = self.create_sentry_app( name='sentry', organization=self.org, scopes=('project:read',), ) updater = Updater(sentry_app=sentry_app, user=self.user) updater.events = ('issue',) with self.assertRaises(APIError): updater.call() def test_updates_service_hook_events(self): sentry_app = self.create_sentry_app( name='sentry', organization=self.org, scopes=('project:read', 'event:read',), events=('event.alert',), ) self.create_sentry_app_installation(slug='sentry') updater = Updater(sentry_app=sentry_app, events=('issue',), user=self.user) updater.call() assert set(sentry_app.events) == expand_events(['issue']) service_hook = ServiceHook.objects.filter(application=sentry_app.application)[0] assert set(service_hook.events) == expand_events(['issue']) def test_updates_webhook_url(self): self.updater.webhook_url = 'http://example.com/hooks' self.updater.call() assert self.sentry_app.webhook_url == 'http://example.com/hooks' def test_updates_redirect_url(self): self.updater.redirect_url = 'http://example.com/finish-setup' self.updater.call() assert self.sentry_app.redirect_url == 'http://example.com/finish-setup' def test_updates_is_alertable(self): self.updater.is_alertable = True self.updater.call() assert self.sentry_app.is_alertable def test_updates_schema(self): ui_component = SentryAppComponent.objects.get(sentry_app_id=self.sentry_app.id) self.updater.schema = { 'elements': [self.create_alert_rule_action_schema()], } self.updater.call() new_ui_component = SentryAppComponent.objects.get(sentry_app_id=self.sentry_app.id) assert not ui_component.type == new_ui_component.type assert self.sentry_app.schema == { 'elements': [self.create_alert_rule_action_schema()], } def test_updates_overview(self): self.updater.overview = 'Description of my very cool application' self.updater.call() assert self.updater.overview == 'Description of my very cool application'
class TestUpdater(TestCase): def setUp(self): self.user = self.create_user() self.org = self.create_organization(owner=self.user) self.sentry_app = self.create_sentry_app( name='nulldb', organization=self.org, scopes=('project:read',), schema={'elements': [self.create_issue_link_schema()]}, ) self.updater = Updater( sentry_app=self.sentry_app, user=self.user, ) def test_updates_name(self): self.updater.name = 'A New Thing' self.updater.call() assert self.sentry_app.name == 'A New Thing' def test_updates_unpublished_app_scopes(self): self.updater.scopes = ('project:read', 'project:write', ) self.updater.call() assert self.sentry_app.get_scopes() == \ ['project:read', 'project:write'] def test_doesnt_update_published_app_scopes(self): sentry_app = self.create_sentry_app( name='sentry', organization=self.org, scopes=('project:read',), published=True, ) updater = Updater(sentry_app=sentry_app, user=self.user) updater.scopes = ('project:read', 'project:write', ) with self.assertRaises(APIError): updater.call() def test_doesnt_update_app_with_invalid_event_permissions(self): sentry_app = self.create_sentry_app( name='sentry', organization=self.org, scopes=('project:read',), ) updater = Updater(sentry_app=sentry_app, user=self.user) updater.events = ('issue',) with self.assertRaises(APIError): updater.call() def test_updates_service_hook_events(self): sentry_app = self.create_sentry_app( name='sentry', organization=self.org, scopes=('project:read', 'event:read',), events=('event.alert',), ) self.create_sentry_app_installation(slug='sentry') updater = Updater(sentry_app=sentry_app, events=('issue',), user=self.user) updater.call() assert set(sentry_app.events) == expand_events(['issue']) service_hook = ServiceHook.objects.filter(application=sentry_app.application)[0] assert set(service_hook.events) == expand_events(['issue']) def test_updates_webhook_url(self): self.updater.webhook_url = 'http://example.com/hooks' self.updater.call() assert self.sentry_app.webhook_url == 'http://example.com/hooks' def test_updates_redirect_url(self): self.updater.redirect_url = 'http://example.com/finish-setup' self.updater.call() assert self.sentry_app.redirect_url == 'http://example.com/finish-setup' def test_updates_is_alertable(self): self.updater.is_alertable = True self.updater.call() assert self.sentry_app.is_alertable def test_updates_schema(self): ui_component = SentryAppComponent.objects.get(sentry_app_id=self.sentry_app.id) self.updater.schema = { 'elements': [self.create_alert_rule_action_schema()], } self.updater.call() new_ui_component = SentryAppComponent.objects.get(sentry_app_id=self.sentry_app.id) assert not ui_component.type == new_ui_component.type assert self.sentry_app.schema == { 'elements': [self.create_alert_rule_action_schema()], } def test_updates_overview(self): self.updater.overview = 'Description of my very cool application' self.updater.call() assert self.sentry_app.overview == 'Description of my very cool application' def test_update_status_if_superuser(self): self.updater.status = 'published' self.user.is_superuser = True self.updater.call() assert self.sentry_app.status == SentryAppStatus.PUBLISHED def test_doesnt_update_status_if_not_superuser(self): self.updater.status = 'published' self.updater.call() assert self.sentry_app.status == SentryAppStatus.UNPUBLISHED
class TestUpdater(TestCase): def setUp(self): self.user = self.create_user() self.org = self.create_organization(owner=self.user) self.sentry_app = self.create_sentry_app( name="nulldb", organization=self.org, scopes=("project:read", ), schema={"elements": [self.create_issue_link_schema()]}, ) self.updater = Updater(sentry_app=self.sentry_app, user=self.user) def test_updates_name(self): self.updater.name = "A New Thing" self.updater.call() assert self.sentry_app.name == "A New Thing" def test_updates_unpublished_app_scopes(self): self.updater.scopes = ("project:read", "project:write") self.updater.call() assert self.sentry_app.get_scopes() == [ "project:read", "project:write" ] def test_doesnt_update_published_app_scopes(self): sentry_app = self.create_sentry_app(name="sentry", organization=self.org, scopes=("project:read", ), published=True) updater = Updater(sentry_app=sentry_app, user=self.user) updater.scopes = ("project:read", "project:write") with self.assertRaises(APIError): updater.call() def test_doesnt_update_app_with_invalid_event_permissions(self): sentry_app = self.create_sentry_app(name="sentry", organization=self.org, scopes=("project:read", )) updater = Updater(sentry_app=sentry_app, user=self.user) updater.events = ("issue", ) with self.assertRaises(APIError): updater.call() def test_doesnt_update_verify_install_if_internal(self): self.create_project(organization=self.org) sentry_app = self.create_internal_integration(name="Internal", organization=self.org) updater = Updater(sentry_app=sentry_app, user=self.user) updater.verify_install = True with self.assertRaises(APIError): updater.call() def test_updates_service_hook_events(self): sentry_app = self.create_sentry_app( name="sentry", organization=self.org, scopes=("project:read", "event:read"), events=("event.alert", ), ) self.create_sentry_app_installation(slug="sentry") updater = Updater(sentry_app=sentry_app, events=("issue", ), user=self.user) updater.call() assert set(sentry_app.events) == expand_events(["issue"]) service_hook = ServiceHook.objects.filter( application=sentry_app.application)[0] assert set(service_hook.events) == expand_events(["issue"]) def test_updates_webhook_url(self): self.updater.webhook_url = "http://example.com/hooks" self.updater.call() assert self.sentry_app.webhook_url == "http://example.com/hooks" def test_updates_redirect_url(self): self.updater.redirect_url = "http://example.com/finish-setup" self.updater.call() assert self.sentry_app.redirect_url == "http://example.com/finish-setup" def test_updates_is_alertable(self): self.updater.is_alertable = True self.updater.call() assert self.sentry_app.is_alertable def test_updates_schema(self): ui_component = SentryAppComponent.objects.get( sentry_app_id=self.sentry_app.id) self.updater.schema = { "elements": [self.create_alert_rule_action_schema()] } self.updater.call() new_ui_component = SentryAppComponent.objects.get( sentry_app_id=self.sentry_app.id) assert not ui_component.type == new_ui_component.type assert self.sentry_app.schema == { "elements": [self.create_alert_rule_action_schema()] } def test_updates_overview(self): self.updater.overview = "Description of my very cool application" self.updater.call() assert self.sentry_app.overview == "Description of my very cool application" def test_update_status_if_superuser(self): self.updater.status = "published" self.user.is_superuser = True self.updater.call() assert self.sentry_app.status == SentryAppStatus.PUBLISHED def test_doesnt_update_status_if_not_superuser(self): self.updater.status = "published" self.updater.call() assert self.sentry_app.status == SentryAppStatus.UNPUBLISHED
class TestUpdater(TestCase): def setUp(self): self.user = self.create_user() self.org = self.create_organization(owner=self.user) self.sentry_app = self.create_sentry_app( name="nulldb", organization=self.org, scopes=("project:read",), schema={"elements": [self.create_issue_link_schema()]}, ) self.updater = Updater(sentry_app=self.sentry_app, user=self.user) def test_updates_name(self): self.updater.name = "A New Thing" self.updater.call() assert self.sentry_app.name == "A New Thing" def test_update_scopes_internal_integration(self): self.create_project(organization=self.org) sentry_app = self.create_internal_integration( scopes=("project:read",), organization=self.org ) updater = Updater(sentry_app=sentry_app, user=self.user) updater.scopes = ("project:read", "project:write") updater.call() assert sentry_app.get_scopes() == ["project:read", "project:write"] assert ApiToken.objects.get(application=sentry_app.application).get_scopes() == [ "project:read", "project:write", ] def test_updates_unpublished_app_scopes(self): # create both expired token and not expired tokens ApiToken.objects.create( application=self.sentry_app.application, user=self.sentry_app.proxy_user, scopes=self.sentry_app.scopes, scope_list=self.sentry_app.scope_list, expires_at=(timezone.now() + timedelta(hours=1)), ) ApiToken.objects.create( application=self.sentry_app.application, user=self.sentry_app.proxy_user, scopes=self.sentry_app.scopes, scope_list=self.sentry_app.scope_list, expires_at=(timezone.now() - timedelta(hours=1)), ) self.updater.scopes = ("project:read", "project:write") self.updater.call() assert self.sentry_app.get_scopes() == ["project:read", "project:write"] tokens = ApiToken.objects.filter(application=self.sentry_app.application).order_by( "expires_at" ) assert tokens[0].get_scopes() == ["project:read"] assert tokens[1].get_scopes() == ["project:read", "project:write"] def test_doesnt_update_published_app_scopes(self): sentry_app = self.create_sentry_app( name="sentry", organization=self.org, scopes=("project:read",), published=True ) updater = Updater(sentry_app=sentry_app, user=self.user) updater.scopes = ("project:read", "project:write") with self.assertRaises(APIError): updater.call() def test_update_webhook_published_app(self): sentry_app = self.create_sentry_app( name="sentry", organization=self.org, scopes=("project:read",), published=True ) updater = Updater(sentry_app=sentry_app, user=self.user) # pass in scopes but as the same value updater.scopes = ["project:read"] updater.webhook_url = "http://example.com/hooks" updater.call() assert sentry_app.webhook_url == "http://example.com/hooks" def test_doesnt_update_app_with_invalid_event_permissions(self): sentry_app = self.create_sentry_app( name="sentry", organization=self.org, scopes=("project:read",) ) updater = Updater(sentry_app=sentry_app, user=self.user) updater.events = ("issue",) with self.assertRaises(APIError): updater.call() def test_doesnt_update_verify_install_if_internal(self): self.create_project(organization=self.org) sentry_app = self.create_internal_integration(name="Internal", organization=self.org) updater = Updater(sentry_app=sentry_app, user=self.user) updater.verify_install = True with self.assertRaises(APIError): updater.call() def test_updates_service_hook_events(self): sentry_app = self.create_sentry_app( name="sentry", organization=self.org, scopes=("project:read", "event:read"), events=("event.alert",), ) self.create_sentry_app_installation(slug="sentry") updater = Updater(sentry_app=sentry_app, events=("issue",), user=self.user) updater.call() assert set(sentry_app.events) == expand_events(["issue"]) service_hook = ServiceHook.objects.filter(application=sentry_app.application)[0] assert set(service_hook.events) == expand_events(["issue"]) def test_updates_webhook_url(self): sentry_app = self.create_sentry_app( name="sentry", organization=self.org, scopes=("project:read", "event:read"), events=("event.alert",), ) self.create_sentry_app_installation(slug="sentry") updater = Updater( sentry_app=sentry_app, webhook_url="http://example.com/hooks", user=self.user ) updater.call() assert sentry_app.webhook_url == "http://example.com/hooks" service_hook = ServiceHook.objects.get(application=sentry_app.application) assert service_hook.url == "http://example.com/hooks" assert set(service_hook.events) == expand_events(["event.alert"]) def test_updates_redirect_url(self): self.updater.redirect_url = "http://example.com/finish-setup" self.updater.call() assert self.sentry_app.redirect_url == "http://example.com/finish-setup" def test_updates_is_alertable(self): self.updater.is_alertable = True self.updater.call() assert self.sentry_app.is_alertable def test_updates_schema(self): ui_component = SentryAppComponent.objects.get(sentry_app_id=self.sentry_app.id) self.updater.schema = {"elements": [self.create_alert_rule_action_schema()]} self.updater.call() new_ui_component = SentryAppComponent.objects.get(sentry_app_id=self.sentry_app.id) assert not ui_component.type == new_ui_component.type assert self.sentry_app.schema == {"elements": [self.create_alert_rule_action_schema()]} def test_updates_overview(self): self.updater.overview = "Description of my very cool application" self.updater.call() assert self.sentry_app.overview == "Description of my very cool application" def test_update_status_if_superuser(self): self.updater.status = "published" self.user.is_superuser = True self.updater.call() assert self.sentry_app.status == SentryAppStatus.PUBLISHED def test_doesnt_update_status_if_not_superuser(self): self.updater.status = "published" self.updater.call() assert self.sentry_app.status == SentryAppStatus.UNPUBLISHED def test_create_service_hook_on_update(self): self.create_project(organization=self.org) internal_app = self.create_internal_integration( name="Internal", organization=self.org, webhook_url=None, scopes=("event:read",) ) assert len(ServiceHook.objects.filter(application=internal_app.application)) == 0 updater = Updater(sentry_app=internal_app, user=self.user) updater.webhook_url = "https://sentry.io/hook" updater.events = ("issue",) updater.call() service_hook = ServiceHook.objects.get(application=internal_app.application) assert service_hook.url == "https://sentry.io/hook" assert set(service_hook.events) == expand_events(["issue"]) def test_delete_service_hook_on_update(self): self.create_project(organization=self.org) internal_app = self.create_internal_integration( name="Internal", organization=self.org, webhook_url="https://sentry.io/hook" ) assert len(ServiceHook.objects.filter(application=internal_app.application)) == 1 updater = Updater(sentry_app=internal_app, user=self.user) updater.webhook_url = "" updater.call() assert len(ServiceHook.objects.filter(application=internal_app.application)) == 0