diff --git a/.changeset/kind-beers-chew.md b/.changeset/kind-beers-chew.md
new file mode 100644
index 0000000000..5fb939ea6b
--- /dev/null
+++ b/.changeset/kind-beers-chew.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-api-docs': minor
+---
+
+Define a default for oauth2RedirectUrl option of swagger-ui-react to match documentation
diff --git a/plugins/api-docs/README.md b/plugins/api-docs/README.md
index 792a7fb0b7..79c4581e79 100644
--- a/plugins/api-docs/README.md
+++ b/plugins/api-docs/README.md
@@ -261,3 +261,5 @@ createApiFactory({
},
})
```
+
+In the same way as the `requestInterceptor` you can override any property of Swagger UI
diff --git a/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinition.test.tsx b/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinition.test.tsx
index adbd069908..d150525b05 100644
--- a/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinition.test.tsx
+++ b/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinition.test.tsx
@@ -16,10 +16,15 @@
import { renderInTestApp } from '@backstage/test-utils';
import { waitFor } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
import React from 'react';
import { OpenApiDefinition } from './OpenApiDefinition';
describe('', () => {
+ beforeEach(() => {
+ window.open = jest.fn();
+ });
+
it('renders openapi spec', async () => {
const definition = `
openapi: "3.0.0"
@@ -35,7 +40,7 @@ paths:
get:
summary: List all artists
responses:
- "200":
+ "200":
description: Success
`;
@@ -55,6 +60,86 @@ paths:
});
});
+ it('renders openapi spec with oauth2', async () => {
+ const user = userEvent.setup();
+
+ const definition = `
+openapi: "3.0.0"
+info:
+ version: 1.0.0
+ title: Artist API
+ license:
+ name: MIT
+servers:
+ - url: http://artist.spotify.net/v1
+components:
+ securitySchemes:
+ oauth:
+ type: oauth2
+ description: OAuth2 service
+ flows:
+ authorizationCode:
+ authorizationUrl: https://api.example.com/oauth2/authorize
+ tokenUrl: https://api.example.com/oauth2/token
+ scopes:
+ read_pets: read your pets
+ write_pets: modify pets in your account
+security:
+ oauth:
+ - [read_pets, write_pets]
+paths:
+ /artists:
+ get:
+ summary: List all artists
+ responses:
+ "200":
+ description: Success
+ `;
+
+ const requestInterceptor = (req: any) => req;
+
+ const { findByRole, getByRole, getByLabelText } = await renderInTestApp(
+ ,
+ );
+
+ const authorizePopup = await findByRole('button', { name: /authorize/i });
+
+ await user.click(authorizePopup);
+
+ const clientId = getByRole('textbox', { name: /client_id:/i });
+ const clientSecret = getByLabelText(/client_secret:/i);
+
+ const readPets = getByRole('checkbox', {
+ name: /read_pets read your pets/i,
+ });
+
+ await user.type(clientId, 'my-client-id');
+
+ expect(clientId).toHaveValue('my-client-id');
+
+ await user.type(clientSecret, 'my-client-secret');
+
+ expect(clientSecret).toHaveValue('my-client-secret');
+ await user.click(readPets);
+
+ expect(readPets).toBeChecked();
+
+ const authorizeButton = await findByRole('button', {
+ name: /apply given oauth2 credentials/i,
+ });
+
+ await user.click(authorizeButton);
+
+ expect(window.open).toHaveBeenCalledWith(
+ expect.stringContaining(
+ 'https://api.example.com/oauth2/authorize?response_type=code&client_id=my-client-id&redirect_uri=http%3A%2F%2Flocalhost%2Foauth2-redirect.html&scope=read_pets&state=',
+ ),
+ );
+ });
+
it('renders error if definition is missing', async () => {
const { getByText } = await renderInTestApp(
,
diff --git a/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinition.tsx b/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinition.tsx
index a2ebbbc7e3..ee23e75ff2 100644
--- a/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinition.tsx
+++ b/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinition.tsx
@@ -16,7 +16,7 @@
import { makeStyles } from '@material-ui/core/styles';
import React, { useEffect, useState } from 'react';
-import SwaggerUI from 'swagger-ui-react';
+import SwaggerUI, { SwaggerUIProps } from 'swagger-ui-react';
import 'swagger-ui-react/swagger-ui.css';
const useStyles = makeStyles(theme => ({
@@ -136,12 +136,11 @@ const useStyles = makeStyles(theme => ({
export type OpenApiDefinitionProps = {
definition: string;
- requestInterceptor?: (req: any) => any | Promise;
-};
+} & Omit;
export const OpenApiDefinition = ({
definition,
- requestInterceptor,
+ ...swaggerUiProps
}: OpenApiDefinitionProps) => {
const classes = useStyles();
@@ -159,8 +158,9 @@ export const OpenApiDefinition = ({
);