Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {
import ApiApplicationDetails from 'sentry/views/settings/account/apiApplications/details';

describe('ApiApplicationDetails', () => {
const oauthBaseUrl = 'https://sentry-jest-tests.example.com/oauth';

it('renders basic details for confidential client', async () => {
MockApiClient.addMockResponse({
url: '/api-applications/abcd/',
Expand Down Expand Up @@ -55,6 +57,10 @@ describe('ApiApplicationDetails', () => {
expect(screen.getByLabelText('Client Secret')).toBeInTheDocument();
expect(screen.getByLabelText('Authorization URL')).toBeInTheDocument();
expect(screen.getByLabelText('Token URL')).toBeInTheDocument();
expect(screen.getByDisplayValue(`${oauthBaseUrl}/authorize/`)).toBeInTheDocument();
expect(screen.getByDisplayValue(`${oauthBaseUrl}/token/`)).toBeInTheDocument();
expect(screen.queryByLabelText('Device Authorization URL')).not.toBeInTheDocument();
expect(screen.queryByLabelText('Device Verification URL')).not.toBeInTheDocument();
});

it('handles client secret rotation', async () => {
Expand Down Expand Up @@ -160,6 +166,10 @@ describe('ApiApplicationDetails', () => {
expect(screen.getByLabelText('Client ID')).toBeInTheDocument();
expect(screen.getByDisplayValue('public-app')).toBeInTheDocument();
expect(screen.getByDisplayValue('Public CLI App')).toBeInTheDocument();
expect(screen.getByDisplayValue(`${oauthBaseUrl}/authorize/`)).toBeInTheDocument();
expect(screen.getByDisplayValue(`${oauthBaseUrl}/token/`)).toBeInTheDocument();
expect(screen.getByDisplayValue(`${oauthBaseUrl}/device/code/`)).toBeInTheDocument();
expect(screen.getByDisplayValue(`${oauthBaseUrl}/device/`)).toBeInTheDocument();
});

it('renders confidential client with client secret section', async () => {
Expand Down Expand Up @@ -202,5 +212,7 @@ describe('ApiApplicationDetails', () => {
expect(
screen.queryByText(/This is a public client, designed for CLIs/)
).not.toBeInTheDocument();
expect(screen.queryByLabelText('Device Authorization URL')).not.toBeInTheDocument();
expect(screen.queryByLabelText('Device Verification URL')).not.toBeInTheDocument();
});
});
21 changes: 19 additions & 2 deletions static/app/views/settings/account/apiApplications/details.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {Fragment} from 'react';
import styled from '@emotion/styled';
import trimEnd from 'lodash/trimEnd';

import {Alert} from '@sentry/scraps/alert';
import {Tag} from '@sentry/scraps/badge';
Expand Down Expand Up @@ -54,6 +55,7 @@ function ApiApplicationsDetails() {
const queryClient = useQueryClient();

const urlPrefix = ConfigStore.get('urlPrefix');
const oauthBaseUrl = `${trimEnd(urlPrefix, '/')}/oauth`;

const {
data: app,
Expand Down Expand Up @@ -173,12 +175,27 @@ function ApiApplicationsDetails() {
)}

<FieldGroup label={t('Authorization URL')} flexibleControlStateSize>
<TextCopyInput>{`${urlPrefix}/oauth/authorize/`}</TextCopyInput>
<TextCopyInput>{`${oauthBaseUrl}/authorize/`}</TextCopyInput>
</FieldGroup>

<FieldGroup label={t('Token URL')} flexibleControlStateSize>
<TextCopyInput>{`${urlPrefix}/oauth/token/`}</TextCopyInput>
<TextCopyInput>{`${oauthBaseUrl}/token/`}</TextCopyInput>
</FieldGroup>

{app.isPublic && (
<Fragment>
<FieldGroup
label={t('Device Authorization URL')}
flexibleControlStateSize
>
<TextCopyInput>{`${oauthBaseUrl}/device/code/`}</TextCopyInput>
</FieldGroup>

<FieldGroup label={t('Device Verification URL')} flexibleControlStateSize>
<TextCopyInput>{`${oauthBaseUrl}/device/`}</TextCopyInput>
</FieldGroup>
</Fragment>
)}
</PanelBody>
</Panel>
</Form>
Expand Down
Loading