fix(api-docs): override oauth2RedirectUrl

Signed-off-by: Guillaume Rahbari <guillaume.rahbari@protonmail.com>
This commit is contained in:
Guillaume Rahbari
2023-10-27 11:54:36 +02:00
parent 8562255396
commit 62310404b7
4 changed files with 98 additions and 6 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-api-docs': minor
---
Define a default for oauth2RedirectUrl option of swagger-ui-react to match documentation
+2
View File
@@ -261,3 +261,5 @@ createApiFactory({
},
})
```
In the same way as the `requestInterceptor` you can override any property of Swagger UI
@@ -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('<OpenApiDefinition />', () => {
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(
<OpenApiDefinition
definition={definition}
requestInterceptor={requestInterceptor}
/>,
);
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(
<OpenApiDefinition definition="" />,
@@ -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<any>;
};
} & Omit<SwaggerUIProps, 'spec'>;
export const OpenApiDefinition = ({
definition,
requestInterceptor,
...swaggerUiProps
}: OpenApiDefinitionProps) => {
const classes = useStyles();
@@ -159,8 +158,9 @@ export const OpenApiDefinition = ({
<SwaggerUI
spec={def}
url=""
requestInterceptor={requestInterceptor}
deepLinking
oauth2RedirectUrl={`${window.location.protocol}//${window.location.host}/oauth2-redirect.html`}
{...swaggerUiProps}
/>
</div>
);