diff --git a/src/sentry/static/sentry/app/views/settings/organizationDeveloperSettings/sentryApplicationRow.jsx b/src/sentry/static/sentry/app/views/settings/organizationDeveloperSettings/sentryApplicationRow.jsx index 2a2937f96df5..d68cb57962e0 100644 --- a/src/sentry/static/sentry/app/views/settings/organizationDeveloperSettings/sentryApplicationRow.jsx +++ b/src/sentry/static/sentry/app/views/settings/organizationDeveloperSettings/sentryApplicationRow.jsx @@ -107,7 +107,7 @@ export default class SentryApplicationRow extends React.PureComponent { const isInstalled = this.isInstalled; return ( - + diff --git a/tests/acceptance/test_organization_developer_settings.py b/tests/acceptance/test_organization_developer_settings.py new file mode 100644 index 000000000000..5096ac9de46e --- /dev/null +++ b/tests/acceptance/test_organization_developer_settings.py @@ -0,0 +1,37 @@ +from __future__ import absolute_import + +from sentry.testutils import AcceptanceTestCase + + +class OrganizationDeveloperSettingsAcceptanceTest(AcceptanceTestCase): + """ + As a developer, I can create an integration, install it, and uninstall it + """ + + def setUp(self): + super(OrganizationDeveloperSettingsAcceptanceTest, self).setUp() + self.login_as(self.user) + self.org_developer_settings_path = u'/settings/{}/developer-settings/'.format( + self.organization.slug) + + def load_page(self, url): + self.browser.get(url) + self.browser.wait_until_not('.loading-indicator') + + def test_create_new_integration(self): + with self.feature('organizations:sentry-apps'): + + self.load_page(self.org_developer_settings_path) + + self.browser.click('[aria-label="Create New Integration"]') + + self.browser.element('input[name="name"]').send_keys('Tesla') + self.browser.element('input[name="author"]').send_keys('Elon Musk') + self.browser.element('input[name="webhookUrl"]').send_keys( + 'https://example.com/webhook') + + self.browser.click('[aria-label="Save Changes"]') + + self.browser.wait_until('.ref-success') + + assert self.browser.find_element_by_link_text('Tesla') diff --git a/tests/acceptance/test_organization_integration.py b/tests/acceptance/test_organization_integration.py index 3e5a248369db..123d9e6d1d47 100644 --- a/tests/acceptance/test_organization_integration.py +++ b/tests/acceptance/test_organization_integration.py @@ -12,34 +12,7 @@ class OrganizationIntegrationAcceptanceTestCase(AcceptanceTestCase): def setUp(self): super(OrganizationIntegrationAcceptanceTestCase, self).setUp() - self.user = self.create_user('foo@example.com') - 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.model = Integration.objects.create( - provider='example', - external_id='example', - name='Test Integration', - metadata={ - 'domain_name': 'example-test.com', - }, - ) - self.org_integration = self.model.add_organization(self.org, self.user) self.login_as(self.user) - self.integration_settings_path = 'sentry-api-0-organization-integrations' def load_page(self, url): diff --git a/tests/acceptance/test_organization_sentry_app.py b/tests/acceptance/test_organization_sentry_app.py new file mode 100644 index 000000000000..fec06709ecff --- /dev/null +++ b/tests/acceptance/test_organization_sentry_app.py @@ -0,0 +1,119 @@ +from __future__ import absolute_import + +from exam import mock + + +from sentry.testutils import AcceptanceTestCase +from tests.acceptance.page_objects.organization_integration_settings import ( + OrganizationIntegrationSettingsPage +) + + +class OrganizationSentryAppAcceptanceTestCase(AcceptanceTestCase): + """ + As a user, I can install and uninstall a Sentry App + """ + + def setUp(self): + super(OrganizationSentryAppAcceptanceTestCase, self).setUp() + self.user = self.create_user('foo@example.com') + self.org = self.create_organization( + name='Tesla', + owner=None, + ) + self.team = self.create_team(organization=self.org, name='Tesla Motors') + self.project = self.create_project( + organization=self.org, + teams=[self.team], + name='Model S', + ) + self.create_member( + user=self.user, + organization=self.org, + role='owner', + teams=[self.team], + ) + + self.sentry_app = self.create_sentry_app( + name='Tesla App', + published=True, + organization=self.org + ) + + self.login_as(self.user) + + self.org_integration_settings_path = u'/settings/{}/integrations/'.format( + self.org.slug) + + self.provider = mock.Mock() + self.provider.key = 'tesla-app' + self.provider.name = 'Tesla App' + + def load_page(self, url): + self.browser.get(url) + self.browser.wait_until_not('.loading-indicator') + + def test_install_sentry_app(self): + self.load_page(self.org_integration_settings_path) + + org_settings_page = OrganizationIntegrationSettingsPage( + browser=self.browser + ) + + provider_element = org_settings_page.get_provider(self.provider) + + # assert installation rather than upgrade button + assert provider_element.install_button.label == 'Install' + assert provider_element.install_button.icon_href == '#icon-circle-add' + + provider_element.install_button.click() + + # need to press install twice + install_selecter = '.modal-dialog [aria-label="Install"]' + self.browser.wait_until(install_selecter) + self.browser.click(install_selecter) + self.browser.wait_until(install_selecter) + self.browser.click(install_selecter) + + self.browser.wait_until('.ref-success') + + # provider_element might be rerendered + provider_element = org_settings_page.get_provider(self.provider) + + # assert we see the uninstall option + assert provider_element.install_button.label == 'Uninstall' + assert provider_element.install_button.icon_href == '#icon-trash' + + def test_uninstall_sentry_app(self): + # add the installation + self.installation = self.create_sentry_app_installation( + slug=self.sentry_app.slug, + organization=self.org, + user=self.user, + ) + + self.load_page(self.org_integration_settings_path) + + org_settings_page = OrganizationIntegrationSettingsPage( + browser=self.browser + ) + + provider_element = org_settings_page.get_provider(self.provider) + + # assert we see the uninstall option + assert provider_element.install_button.label == 'Uninstall' + assert provider_element.install_button.icon_href == '#icon-trash' + + provider_element.install_button.click() + self.browser.wait_until(org_settings_page.modal_selector) + + self.browser.click('.modal-dialog [aria-label="Confirm"]') + + self.browser.wait_until('.ref-success') + + # provider_element might be rerendered + provider_element = org_settings_page.get_provider(self.provider) + + # assert we see the install option now + assert provider_element.install_button.label == 'Install' + assert provider_element.install_button.icon_href == '#icon-circle-add' diff --git a/tests/js/spec/views/settings/organizationIntegrations/__snapshots__/sentryAppInstallations.spec.jsx.snap b/tests/js/spec/views/settings/organizationIntegrations/__snapshots__/sentryAppInstallations.spec.jsx.snap index 82f9c67f7546..6c9cf9a10784 100644 --- a/tests/js/spec/views/settings/organizationIntegrations/__snapshots__/sentryAppInstallations.spec.jsx.snap +++ b/tests/js/spec/views/settings/organizationIntegrations/__snapshots__/sentryAppInstallations.spec.jsx.snap @@ -111,14 +111,17 @@ exports[`Sentry App Installations when Apps exist displays all Apps owned by the showPublishStatus={false} >