def test_no_accounts_received(self, mock_render_to_response, mock_get_user_info): responses.reset() responses.add( responses.GET, "https://app.vssps.visualstudio.com/_apis/accounts", json={ "value": [], "count": 0 }, status=200, ) view = AccountConfigView() request = Mock() request.POST = {} request.user = self.user pipeline = Mock() pipeline.fetch_state = lambda key: { "data": { "access_token": "1234567890" } } pipeline.organization = self.organization view.dispatch(request, pipeline) assert mock_get_user_info.called is True assert mock_render_to_response.called is True assert mock_render_to_response.call_args[1]["context"] == { "no_accounts": True }
class OrganizationRateLimitsTest(AcceptanceTestCase): def setUp(self): super().setUp() self.user = self.create_user("*****@*****.**") self.org = self.create_organization(name="Rowdy Tiger", owner=None) self.team = self.create_team(organization=self.org, name="Mariachi Band") self.project = self.create_project(organization=self.org, teams=[self.team], name="Bengal") self.create_member(user=self.user, organization=self.org, role="owner", teams=[self.team]) self.login_as(self.user) self.path = f"/organizations/{self.org.slug}/rate-limits/" @patch("sentry.app.quotas.get_maximum_quota", Mock(return_value=(100, 60))) def test_with_rate_limits(self): self.project.update(first_event=timezone.now()) self.browser.get(self.path) self.browser.wait_until_not(".loading-indicator") self.browser.wait_until_test_id("rate-limit-editor") self.browser.snapshot("organization rate limits with quota") assert self.browser.element_exists_by_test_id("rate-limit-editor") @patch("sentry.app.quotas.get_maximum_quota", Mock(return_value=(0, 60))) def test_without_rate_limits(self): self.project.update(first_event=timezone.now()) self.browser.get(self.path) self.browser.wait_until_not(".loading-indicator") self.browser.wait_until_test_id("rate-limit-editor") self.browser.snapshot("organization rate limits without quota") assert self.browser.element_exists_by_test_id("rate-limit-editor")
def test_rule_processor(self, mock_processor): event = self.store_event(data={"message": "testing"}, project_id=self.project.id) cache_key = write_event_to_cache(event) mock_callback = Mock() mock_futures = [Mock()] mock_processor.return_value.apply.return_value = [(mock_callback, mock_futures)] post_process_group( is_new=True, is_regression=False, is_new_group_environment=True, cache_key=cache_key, group_id=event.group_id, ) mock_processor.assert_called_once_with(EventMatcher(event), True, False, True, False) mock_processor.return_value.apply.assert_called_once_with() mock_callback.assert_called_once_with(EventMatcher(event), mock_futures)
def test_service_hook_fires_on_alert(self, mock_processor, mock_process_service_hook): event = self.store_event(data={}, project_id=self.project.id) cache_key = write_event_to_cache(event) mock_callback = Mock() mock_futures = [Mock()] mock_processor.return_value.apply.return_value = [(mock_callback, mock_futures)] hook = self.create_service_hook( project=self.project, organization=self.project.organization, actor=self.user, events=["event.alert"], ) with self.feature("projects:servicehooks"): post_process_group( is_new=False, is_regression=False, is_new_group_environment=False, cache_key=cache_key, group_id=event.group_id, ) mock_process_service_hook.delay.assert_called_once_with( servicehook_id=hook.id, event=EventMatcher(event))
def test_group_refresh(self, mock_processor): event = self.store_event(data={"message": "testing"}, project_id=self.project.id) cache_key = write_event_to_cache(event) group1 = event.group group2 = self.create_group(project=self.project) assert event.group_id == group1.id assert event.group == group1 with self.tasks(): merge_groups([group1.id], group2.id) mock_callback = Mock() mock_futures = [Mock()] mock_processor.return_value.apply.return_value = [(mock_callback, mock_futures)] post_process_group( is_new=True, is_regression=False, is_new_group_environment=True, cache_key=cache_key, group_id=event.group_id, ) # Ensure that rule processing sees the merged group. mock_processor.assert_called_with(EventMatcher(event, group=group2), True, False, True, False)
class MailPluginShouldNotifyTest(TestCase): @fixture def plugin(self): return MailPlugin() @mock.patch("sentry.mail.adapter.MailAdapter.get_sendable_users", Mock(return_value=[])) def test_should_notify_no_sendable_users_has_issue_alerts_targeting(self): self.group.project.flags.has_issue_alerts_targeting = True self.group.project.save() assert not self.plugin.should_notify(group=self.group, event=Mock()) @mock.patch("sentry.mail.adapter.MailAdapter.get_sendable_users", Mock(return_value=[])) def test_should_notify_no_sendable_users_not_has_issue_alerts_targeting( self): self.group.project.flags.has_issue_alerts_targeting = False self.group.project.save() assert not self.plugin.should_notify(group=self.group, event=Mock()) @mock.patch("sentry.mail.adapter.MailAdapter.get_sendable_users", Mock(return_value=[1])) def test_should_notify_sendable_users_has_issue_alerts_targetting(self): self.group.project.flags.has_issue_alerts_targeting = True self.group.project.save() assert not self.plugin.should_notify(group=self.group, event=Mock()) @mock.patch("sentry.mail.adapter.MailAdapter.get_sendable_users", Mock(return_value=[1])) def test_should_notify_sendable_users_not_has_issue_alerts_targetting( self): self.group.project.flags.has_issue_alerts_targeting = False self.group.project.save() assert self.plugin.should_notify(group=self.group, event=Mock())
def test_handler(self): mock_handler = Mock() mock_method = getattr(mock_handler.return_value, self.method) mock_method.return_value = "test" type = AlertRuleTriggerAction.Type.EMAIL AlertRuleTriggerAction.register_type("something", type, [])(mock_handler) trigger = AlertRuleTriggerAction(type=type.value) assert getattr(trigger, self.method)(Mock(), Mock()) == mock_method.return_value
def test_handled(self): mock_handler = Mock() type = AlertRuleTriggerAction.Type.EMAIL AlertRuleTriggerAction.register_type("something", type, [])(mock_handler) trigger = AlertRuleTriggerAction(type=AlertRuleTriggerAction.Type.EMAIL.value) incident = Mock() project = Mock() trigger.build_handler(incident, project) mock_handler.assert_called_once_with(trigger, incident, project) assert not self.metrics.incr.called
def test_user_success(self): user = self.create_user() organization = self.create_organization(owner=user) project = self.create_project(organization=organization) hook = HerokuReleaseHook(project) hook.set_refs = Mock() req = Mock() req.POST = {"head_long": "abcd123", "url": "http://example.com", "user": user.email} hook.handle(req) assert Release.objects.filter(version=req.POST["head_long"]).exists() assert hook.set_refs.call_count == 1
def test_show_notify_event_service_action(self): rules = RuleRegistry() rule = Mock() rule.id = APP_ACTION rule.rule_type = "action/lol" node = rule.return_value node.id = rule.id node.label = "hello" node.prompt = "hello" node.is_enabled.return_value = True node.form_fields = {} node.get_services.return_value = [Mock()] rules.add(rule) self.run_mock_rules_test(1, {}, rules=rules)
def test_basic_flow(self, mock_sha): sha = Mock() sha.hexdigest.return_value = "secret-token" mock_sha.return_value = sha self.assert_setup_flow() integration = Integration.objects.get(provider=self.provider.key) assert integration.external_id == "gitlab.example.com:4" assert integration.name == "Cool" assert integration.metadata == { "instance": "gitlab.example.com", "scopes": ["api"], "icon": u"https://gitlab.example.com/uploads/group/avatar/4/foo.jpg", "domain_name": u"gitlab.example.com/cool-group", "verify_ssl": True, "base_url": "https://gitlab.example.com", "webhook_secret": "secret-token", "group_id": self.default_group_id, "include_subgroups": True, } oi = OrganizationIntegration.objects.get( integration=integration, organization=self.organization ) assert oi.config == {} idp = IdentityProvider.objects.get(type="gitlab") identity = Identity.objects.get( idp=idp, user=self.user, external_id="gitlab.example.com:user_id_1" ) assert identity.status == IdentityStatus.VALID assert identity.data == {"access_token": "xxxxx-xxxxxxxxx-xxxxxxxxxx-xxxxxxxxxxxx"}
def test_normal(self): cluster_name = settings.KAFKA_TOPICS[self.topic]["cluster"] conf = { "bootstrap.servers": settings.KAFKA_CLUSTERS[cluster_name]["bootstrap.servers"], "session.timeout.ms": 6000, } producer = Producer(conf) producer.produce(self.topic, json.dumps(self.valid_wrapper)) producer.flush() mock_callback = Mock() mock_callback.side_effect = KeyboardInterrupt() register_subscriber(self.registration_key)(mock_callback) sub = QuerySubscription.objects.create( project=self.project, type=self.registration_key, subscription_id=self.subscription_id, dataset="something", query="hello", aggregation=0, time_window=1, resolution=1, ) consumer = QuerySubscriptionConsumer("hi", topic=self.topic, commit_batch_size=1) consumer.run() mock_callback.assert_called_once_with(self.valid_payload, sub)
def test_webhook_subscription_created_once(self, mock_get_scopes): self.assert_installation() state = { "account": {"accountName": self.vsts_account_name, "accountId": self.vsts_account_id}, "base_url": self.vsts_base_url, "identity": { "data": { "access_token": self.access_token, "expires_in": "3600", "refresh_token": self.refresh_token, "token_type": "jwt-bearer", } }, } # The above already created the Webhook, so subsequent calls to # ``build_integration`` should omit that data. provider = VstsIntegrationProvider() pipeline = Mock() pipeline.organization = self.organization provider.set_pipeline(pipeline) data = provider.build_integration(state) assert "subscription" in data["metadata"] assert ( Integration.objects.get(provider="vsts").metadata["subscription"] == data["metadata"]["subscription"] )
def test_normal(self): cluster_name = settings.KAFKA_TOPICS[self.topic]["cluster"] conf = { "bootstrap.servers": settings.KAFKA_CLUSTERS[cluster_name]["bootstrap.servers"], "session.timeout.ms": 6000, } producer = Producer(conf) producer.produce(self.topic, json.dumps(self.valid_wrapper)) producer.flush() mock_callback = Mock() mock_callback.side_effect = KeyboardInterrupt() register_subscriber(self.registration_key)(mock_callback) sub = self.create_subscription() consumer = QuerySubscriptionConsumer("hi", topic=self.topic, commit_batch_size=1) consumer.run() payload = self.valid_payload payload["values"] = payload["result"] payload["timestamp"] = parse_date( payload["timestamp"]).replace(tzinfo=pytz.utc) mock_callback.assert_called_once_with(payload, sub)
def test_subscription_registered(self): registration_key = "registered_test" mock_callback = Mock() register_subscriber(registration_key)(mock_callback) with self.tasks(): snuba_query = create_snuba_query( QueryDatasets.EVENTS, "hello", QueryAggregations.TOTAL, timedelta(minutes=10), timedelta(minutes=1), None, ) sub = create_snuba_subscription(self.project, registration_key, snuba_query) sub.refresh_from_db() data = self.valid_wrapper data["payload"]["subscription_id"] = sub.subscription_id self.consumer.handle_message(self.build_mock_message(data)) data = deepcopy(data) data["payload"]["values"] = data["payload"]["result"] data["payload"]["timestamp"] = parse_date( data["payload"]["timestamp"]).replace(tzinfo=pytz.utc) mock_callback.assert_called_once_with(data["payload"], sub)
def test_update_comment(self): org = self.organization self.user.name = "Sentry Admin" self.user.save() self.login_as(self.user) integration = Integration.objects.create(provider="jira", name="Example Jira") integration.add_organization(org, self.user) installation = integration.get_installation(org.id) group_note = Mock() comment = "hello world\nThis is a comment.\n\n\n I've changed it" group_note.data = {} group_note.data["text"] = comment group_note.data["external_id"] = "123" with mock.patch.object(MockJiraApiClient, "update_comment") as mock_update_comment: def get_client(): return MockJiraApiClient() with mock.patch.object(installation, "get_client", get_client): installation.update_comment(1, self.user.id, group_note) assert mock_update_comment.call_args[0] == ( 1, "123", "Sentry Admin wrote:\n\n{quote}%s{quote}" % comment, )
def test_exchange_token(self): def redirect_url(): return "https://app.vssps.visualstudio.com/oauth2/authorize" view = VSTSOAuth2CallbackView( access_token_url="https://app.vssps.visualstudio.com/oauth2/token", client_id="vsts-client-id", client_secret="vsts-client-secret", ) request = Mock() pipeline = Mock() pipeline.redirect_url = redirect_url responses.add( responses.POST, "https://app.vssps.visualstudio.com/oauth2/token", json={ "access_token": "xxxxxxxxx", "token_type": "jwt-bearer", "expires_in": "3599", "refresh_token": "zzzzzzzzzz", }, ) result = view.exchange_token(request, pipeline, "oauth-code") mock_request = responses.calls[0].request req_params = parse_qs(mock_request.body) assert req_params["grant_type"] == [ "urn:ietf:params:oauth:grant-type:jwt-bearer" ] assert req_params["assertion"] == ["oauth-code"] assert req_params["redirect_uri"] == [ "https://app.vssps.visualstudio.com/oauth2/authorize" ] assert req_params["client_assertion_type"] == [ "urn:ietf:params:oauth:client-assertion-type:jwt-bearer" ] assert req_params["client_assertion"] == ["vsts-client-secret"] assert result["access_token"] == "xxxxxxxxx" assert result["token_type"] == "jwt-bearer" assert result["expires_in"] == "3599" assert result["refresh_token"] == "zzzzzzzzzz"
def test_rule_processor(self, mock_processor): event = self.store_event(data={}, project_id=self.project.id) mock_callback = Mock() mock_futures = [Mock()] mock_processor.return_value.apply.return_value = [(mock_callback, mock_futures)] post_process_group(event=event, is_new=True, is_regression=False, is_new_group_environment=True) mock_processor.assert_called_once_with(event, True, False, True, False) mock_processor.return_value.apply.assert_called_once_with() mock_callback.assert_called_once_with(event, mock_futures)
def test_exchange_token_no_json(self): responses.add(responses.POST, "https://example.org/oauth/token", body="") pipeline = IdentityProviderPipeline(request=Mock(), provider_key="dummy") code = "auth-code" result = self.view.exchange_token(None, pipeline, code) assert "token" not in result assert "error" in result assert "error_description" in result assert "JSON" in result["error_description"]
def test_exchange_token_success(self): responses.add( responses.POST, "https://example.org/oauth/token", json={"token": "a-fake-token"} ) pipeline = IdentityProviderPipeline(request=Mock(), provider_key="dummy") code = "auth-code" result = self.view.exchange_token(None, pipeline, code) assert "token" in result assert "a-fake-token" == result["token"]
def test_bad_version(self): project = self.create_project() user = self.create_user() hook = HerokuReleaseHook(project) req = Mock() req.POST = {"head_long": "", "url": "http://example.com", "user": user.email} with self.assertRaises(HookValidationError): hook.handle(req)
def test_shutdown(self): self.producer.produce(self.topic, json.dumps(self.valid_wrapper)) valid_wrapper_2 = deepcopy(self.valid_wrapper) valid_wrapper_2["payload"]["values"]["hello"] = 25 valid_wrapper_3 = deepcopy(valid_wrapper_2) valid_wrapper_3["payload"]["values"]["hello"] = 5000 self.producer.produce(self.topic, json.dumps(valid_wrapper_2)) self.producer.flush() counts = [0] def mock_callback(*args, **kwargs): counts[0] += 1 if counts[0] > 1: raise KeyboardInterrupt() mock = Mock() mock.side_effect = mock_callback register_subscriber(self.registration_key)(mock) sub = QuerySubscription.objects.create( project=self.project, type=self.registration_key, subscription_id=self.subscription_id, dataset="something", query="hello", aggregation=0, time_window=1, resolution=1, ) consumer = QuerySubscriptionConsumer("hi", topic=self.topic, commit_batch_size=100) consumer.run() valid_payload = self.valid_payload valid_payload["timestamp"] = parse_date( valid_payload["timestamp"]).replace(tzinfo=pytz.utc) valid_wrapper_2["payload"]["timestamp"] = parse_date( valid_wrapper_2["payload"]["timestamp"]).replace(tzinfo=pytz.utc) mock.assert_has_calls( [call(valid_payload, sub), call(valid_wrapper_2["payload"], sub)]) # Offset should be committed for the first message, so second run should process # the second message again self.producer.produce(self.topic, json.dumps(valid_wrapper_3)) self.producer.flush() mock.reset_mock() counts[0] = 0 consumer.run() valid_wrapper_3["payload"]["timestamp"] = parse_date( valid_wrapper_3["payload"]["timestamp"]).replace(tzinfo=pytz.utc) mock.assert_has_calls([ call(valid_wrapper_2["payload"], sub), call(valid_wrapper_3["payload"], sub) ])
class LinkSharedEventTest(BaseEventTest): @responses.activate @patch( "sentry.integrations.slack.endpoints.event.match_link", # match_link will be called twice, for each our links. Resolve into # two unique links and one duplicate. side_effect=[ ("mock_link", {"arg1": "value1"}), ("mock_link", {"arg1", "value2"}), ("mock_link", {"arg1": "value1"}), ], ) @patch( "sentry.integrations.slack.endpoints.event.link_handlers", { "mock_link": Handler( matcher=re.compile(r"test"), arg_mapper=make_type_coercer({}), fn=Mock(return_value={"link1": "unfurl", "link2": "unfurl"}), ) }, ) def share_links(self, mock_match_link): responses.add(responses.POST, "https://slack.com/api/chat.unfurl", json={"ok": True}) resp = self.post_webhook(event_data=json.loads(LINK_SHARED_EVENT)) assert resp.status_code == 200, resp.content assert len(mock_match_link.mock_calls) == 3 data = dict(parse_qsl(responses.calls[0].request.body)) unfurls = json.loads(data["unfurls"]) # We only have two unfurls since one link was duplicated assert len(unfurls) == 2 assert unfurls["link1"] == "unfurl" assert unfurls["link2"] == "unfurl" return data def test_valid_token(self): data = self.share_links() assert data["token"] == "xoxb-xxxxxxxxx-xxxxxxxxxx-xxxxxxxxxxxx" def test_user_access_token(self): # this test is needed to make sure that classic bots installed by on-prem users # still work since they needed to use a user_access_token for unfurl self.integration.metadata.update( { "user_access_token": "xoxt-xxxxxxxxx-xxxxxxxxxx-xxxxxxxxxxxx", "access_token": "xoxm-xxxxxxxxx-xxxxxxxxxx-xxxxxxxxxxxx", } ) self.integration.save() data = self.share_links() assert data["token"] == "xoxt-xxxxxxxxx-xxxxxxxxxx-xxxxxxxxxxxx"
def setUp(self): super(ProcessUpdateTest, self).setUp() self.old_handlers = AlertRuleTriggerAction._type_registrations AlertRuleTriggerAction._type_registrations = {} self.email_action_handler = Mock() AlertRuleTriggerAction.register_type("email", AlertRuleTriggerAction.Type.EMAIL, [])( self.email_action_handler ) self._run_tasks = self.tasks() self._run_tasks.__enter__()
def test_email_mismatch(self): user = self.create_user() organization = self.create_organization(owner=user) project = self.create_project(organization=organization) hook = HerokuReleaseHook(project) req = Mock() req.POST = {"head_long": "v999", "url": "http://example.com", "user": "******"} hook.handle(req) assert Release.objects.filter(version=req.POST["head_long"]).exists()
def test_with_expected_errors(self, mock_get_logger): mock_log = Mock() mock_get_logger.return_value = mock_log def simple(a): raise ValueError() assert safe_execute(simple, 1, expected_errors=(ValueError,)) is None assert mock_log.info.called assert mock_log.error.called is False
def test_adds_type(self): sub = self.create_subscription(QuerySubscription.Status.CREATING) with patch("sentry.snuba.tasks._snuba_pool") as pool: resp = Mock() resp.status = 202 resp.data = json.dumps({"subscription_id": "123"}) pool.urlopen.return_value = resp create_subscription_in_snuba(sub.id) request_body = json.loads(pool.urlopen.call_args[1]["body"]) assert ["type", "=", "error"] in request_body["conditions"]
def test_with_authorization_and_no_auth(self): responses.add(responses.GET, "http://example.com", json={}) auth = Mock() auth.tokens = {"access_token": "access-token"} resp = AuthApiClient(auth=auth).get("http://example.com", auth=None) assert resp.status_code == 200 request = responses.calls[-1].request assert not request.headers.get("Authorization")
def test_simple(self): request = Mock() request.GET = QueryDict("member=1&cursor=foo") request.method = "GET" request.path = "/api/0/organizations/" endpoint = Endpoint() result = endpoint.build_cursor_link(request, "next", "1492107369532:0:0") assert result == ( "<http://testserver/api/0/organizations/?member=1&cursor=1492107369532:0:0>;" ' rel="next"; results="true"; cursor="1492107369532:0:0"')
def test_unicode_path(self): request = Mock() request.GET = {"member": ["1"]} request.method = "GET" request.path = "/api/0/organizations/üuuuu/" endpoint = Endpoint() result = endpoint.build_cursor_link(request, "next", "1492107369532:0:0") assert result == ( "<http://testserver/api/0/organizations/%C3%BCuuuu/?member=%5B%271%27%5D&cursor=1492107369532:0:0>;" ' rel="next"; results="true"; cursor="1492107369532:0:0"')