From 62310404b7775077b58fc614dd96c1fe09b8b39d Mon Sep 17 00:00:00 2001 From: Guillaume Rahbari Date: Fri, 27 Oct 2023 11:54:36 +0200 Subject: [PATCH] fix(api-docs): override oauth2RedirectUrl Signed-off-by: Guillaume Rahbari --- .changeset/kind-beers-chew.md | 5 ++ plugins/api-docs/README.md | 2 + .../OpenApiDefinition.test.tsx | 87 ++++++++++++++++++- .../OpenApiDefinition.tsx | 10 +-- 4 files changed, 98 insertions(+), 6 deletions(-) create mode 100644 .changeset/kind-beers-chew.md 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 = ({ );