From 9c53ca52eca9a87d658878c9ce7b07bf97f6ed79 Mon Sep 17 00:00:00 2001 From: pamelin Date: Thu, 16 Feb 2023 11:47:09 +0000 Subject: [PATCH] fix: move webUrl construction into the st2 client Signed-off-by: pamelin --- plugins/stackstorm/config.d.ts | 4 +- .../src/api/StackStormClient.test.ts | 37 ++++++++++++++----- .../stackstorm/src/api/StackStormClient.ts | 30 ++++++++++++++- plugins/stackstorm/src/api/types.ts | 2 + .../components/ActionsList/ActionsList.tsx | 10 +---- .../ExecutionsTable/ExecutionPanel.test.tsx | 22 ++++------- .../ExecutionsTable/ExecutionPanel.tsx | 12 +++--- .../ExecutionsTable/ExecutionsTable.test.tsx | 15 +++----- .../ExecutionsTable/ExecutionsTable.tsx | 12 ++---- plugins/stackstorm/src/plugin.ts | 6 ++- 10 files changed, 89 insertions(+), 61 deletions(-) diff --git a/plugins/stackstorm/config.d.ts b/plugins/stackstorm/config.d.ts index 64276503fc..b85d682eb0 100644 --- a/plugins/stackstorm/config.d.ts +++ b/plugins/stackstorm/config.d.ts @@ -14,12 +14,12 @@ * limitations under the License. */ export interface Config { - stackstorm?: { + stackstorm: { /** * StackStorm Web UI url * Used in links to StackStorm web UI * @visibility frontend */ - webUrl?: string; + webUrl: string; }; } diff --git a/plugins/stackstorm/src/api/StackStormClient.test.ts b/plugins/stackstorm/src/api/StackStormClient.test.ts index 7166c8297b..9757bde2af 100644 --- a/plugins/stackstorm/src/api/StackStormClient.test.ts +++ b/plugins/stackstorm/src/api/StackStormClient.test.ts @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { UrlPatternDiscovery } from '@backstage/core-app-api'; +import { ConfigReader, UrlPatternDiscovery } from '@backstage/core-app-api'; import { MockFetchApi, setupRequestMockHandlers } from '@backstage/test-utils'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; @@ -177,31 +177,50 @@ describe('StackstormClient', () => { beforeEach(() => { setupHandlers(); - client = new StackstormClient({ - discoveryApi: discoveryApi, - fetchApi: new MockFetchApi(), - }); + client = StackstormClient.fromConfig( + new ConfigReader({ + stackstorm: { + webUrl: 'http://stackstorm.example.com:8080', + }, + }), + { + discoveryApi: discoveryApi, + fetchApi: new MockFetchApi(), + }, + ); }); - it('get executions should return executions with emulated pagination', async () => { + it('getExecutions should return executions with emulated pagination', async () => { const got = await client.getExecutions(2, 1); expect(got.length).toEqual(2); expect(got).toMatchObject(executions.slice(1, 3)); }); - it('get execution should return one execution', async () => { + it('getExecution should return one execution', async () => { const got = await client.getExecution('63dcac3e18ba00e09e7bb3b6'); expect(got).toMatchObject(executionWithDetails); }); - it('get packs should return list of all packs', async () => { + it('getPacks should return list of all packs', async () => { const got = await client.getPacks(); expect(got.length).toEqual(packs.length); expect(got).toMatchObject(packs); }); - it('get actions should return list of actions', async () => { + it('getActions should return list of actions', async () => { const got = await client.getActions('core'); expect(got).toMatchObject(actions); }); + + it('getExecutionHistoryUrl should return webUrl for executions', async () => { + const got = client.getExecutionHistoryUrl('123abc'); + expect(got).toEqual('http://stackstorm.example.com:8080/?#/history/123abc'); + }); + + it('getActionUrl should return webUrl for action', async () => { + const got = client.getActionUrl('core.shell'); + expect(got).toEqual( + 'http://stackstorm.example.com:8080/?#/actions/core.shell', + ); + }); }); diff --git a/plugins/stackstorm/src/api/StackStormClient.ts b/plugins/stackstorm/src/api/StackStormClient.ts index 7048ad1796..692bfbe4a6 100644 --- a/plugins/stackstorm/src/api/StackStormClient.ts +++ b/plugins/stackstorm/src/api/StackStormClient.ts @@ -14,21 +14,39 @@ * limitations under the License. */ import { Action, Execution, Pack, StackstormApi } from './types'; -import { DiscoveryApi, FetchApi } from '@backstage/core-plugin-api'; +import { ConfigApi, DiscoveryApi, FetchApi } from '@backstage/core-plugin-api'; export class StackstormClient implements StackstormApi { private readonly discoveryApi: DiscoveryApi; private readonly fetchApi: FetchApi; + private readonly webUrl: string; - constructor({ + private constructor({ discoveryApi, fetchApi, + webUrl, }: { discoveryApi: DiscoveryApi; fetchApi: FetchApi; + webUrl: string; }) { this.discoveryApi = discoveryApi; this.fetchApi = fetchApi; + this.webUrl = webUrl; + } + + static fromConfig( + config: ConfigApi, + dependencies: { + discoveryApi: DiscoveryApi; + fetchApi: FetchApi; + }, + ): StackstormClient { + return new StackstormClient({ + discoveryApi: dependencies.discoveryApi, + fetchApi: dependencies.fetchApi, + webUrl: config.getString('stackstorm.webUrl'), + }); } private async get(input: string): Promise { @@ -87,4 +105,12 @@ export class StackstormClient implements StackstormApi { const path = `/actions?${new URLSearchParams(params)}`; return this.get(path); } + + getExecutionHistoryUrl(id: string): string { + return `${this.webUrl}/?#/history/${id}`; + } + + getActionUrl(ref: string): string { + return `${this.webUrl}/?#/actions/${ref}`; + } } diff --git a/plugins/stackstorm/src/api/types.ts b/plugins/stackstorm/src/api/types.ts index 401f79c9b6..6ebf3d67a6 100644 --- a/plugins/stackstorm/src/api/types.ts +++ b/plugins/stackstorm/src/api/types.ts @@ -56,4 +56,6 @@ export interface StackstormApi { getExecution(id: string): Promise; getPacks(): Promise; getActions(pack: string): Promise; + getExecutionHistoryUrl(id: string): string; + getActionUrl(ref: string): string; } diff --git a/plugins/stackstorm/src/components/ActionsList/ActionsList.tsx b/plugins/stackstorm/src/components/ActionsList/ActionsList.tsx index e792a4f6d2..96262d7e6b 100644 --- a/plugins/stackstorm/src/components/ActionsList/ActionsList.tsx +++ b/plugins/stackstorm/src/components/ActionsList/ActionsList.tsx @@ -16,7 +16,7 @@ import React, { useState } from 'react'; import useAsync from 'react-use/lib/useAsync'; import { Progress } from '@backstage/core-components'; -import { useApi, configApiRef } from '@backstage/core-plugin-api'; +import { useApi } from '@backstage/core-plugin-api'; import { List, ListItemText, @@ -55,7 +55,6 @@ type ActionItemsProps = { export const ActionItems = ({ pack }: ActionItemsProps) => { const classes = useStyles(); const st2 = useApi(stackstormApiRef); - const config = useApi(configApiRef); const { value, loading, error } = useAsync(async (): Promise => { const data = await st2.getActions(pack.ref); @@ -76,12 +75,7 @@ export const ActionItems = ({ pack }: ActionItemsProps) => { key={a.ref} button className={classes.nested} - onClick={() => - window.open( - `${config.getString('stackstorm.webUrl')}/?#/actions/${a.ref}`, - '_blank', - ) - } + onClick={() => window.open(st2.getActionUrl(a.ref), '_blank')} > {a.runner_type} diff --git a/plugins/stackstorm/src/components/ExecutionsTable/ExecutionPanel.test.tsx b/plugins/stackstorm/src/components/ExecutionsTable/ExecutionPanel.test.tsx index 442151ebc1..53930d339f 100644 --- a/plugins/stackstorm/src/components/ExecutionsTable/ExecutionPanel.test.tsx +++ b/plugins/stackstorm/src/components/ExecutionsTable/ExecutionPanel.test.tsx @@ -13,12 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { configApiRef } from '@backstage/core-plugin-api'; -import { - MockConfigApi, - renderInTestApp, - TestApiProvider, -} from '@backstage/test-utils'; +import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; import React from 'react'; import { Execution, StackstormApi, stackstormApiRef } from '../../api'; import { ExecutionPanel } from './ExecutionPanel'; @@ -54,19 +49,16 @@ const execution: Execution = { describe('ExecutionPanel', () => { const mockApi: jest.Mocked = { getExecution: jest.fn().mockResolvedValue(execution), + getExecutionHistoryUrl: jest + .fn() + .mockResolvedValue( + 'http://stackstorm.example.com:8080/?#/history/63dcac3e18ba00e09e7bb3b6', + ), } as any; it('should render execution details', async () => { const { getByText } = await renderInTestApp( - + , ); diff --git a/plugins/stackstorm/src/components/ExecutionsTable/ExecutionPanel.tsx b/plugins/stackstorm/src/components/ExecutionsTable/ExecutionPanel.tsx index 78b0f0dd5a..47f301e910 100644 --- a/plugins/stackstorm/src/components/ExecutionsTable/ExecutionPanel.tsx +++ b/plugins/stackstorm/src/components/ExecutionsTable/ExecutionPanel.tsx @@ -15,7 +15,7 @@ */ import React from 'react'; import { CodeSnippet, Progress } from '@backstage/core-components'; -import { configApiRef, useApi } from '@backstage/core-plugin-api'; +import { useApi } from '@backstage/core-plugin-api'; import { Execution, stackstormApiRef } from '../../api'; import useAsync from 'react-use/lib/useAsync'; import { Alert } from '@material-ui/lab'; @@ -65,11 +65,9 @@ const TRow = withStyles(theme => ({ }))(TableRow); const ExecutionCard = ({ e }: { e: Execution }) => { - const config = useApi(configApiRef); + const st2 = useApi(stackstormApiRef); const classes = useStyles(); - const webUrl = `${config.getString('stackstorm.webUrl')}/?#/history/${e.id}`; - return ( @@ -139,7 +137,11 @@ const ExecutionCard = ({ e }: { e: Execution }) => { /> - diff --git a/plugins/stackstorm/src/components/ExecutionsTable/ExecutionsTable.test.tsx b/plugins/stackstorm/src/components/ExecutionsTable/ExecutionsTable.test.tsx index b53d3a2f5f..1890bfa10b 100644 --- a/plugins/stackstorm/src/components/ExecutionsTable/ExecutionsTable.test.tsx +++ b/plugins/stackstorm/src/components/ExecutionsTable/ExecutionsTable.test.tsx @@ -83,19 +83,16 @@ const executions: Execution[] = [ describe('ExecutionsTable', () => { const mockApi: jest.Mocked = { getExecutions: jest.fn().mockResolvedValue(executions), + getExecutionHistoryUrl: jest + .fn() + .mockResolvedValue( + 'http://stackstorm.example.com:8080/?#/history/123abc', + ), } as any; it('should render all executions', async () => { const { getByText } = await renderInTestApp( - + , ); diff --git a/plugins/stackstorm/src/components/ExecutionsTable/ExecutionsTable.tsx b/plugins/stackstorm/src/components/ExecutionsTable/ExecutionsTable.tsx index 289c896678..1816f1db1f 100644 --- a/plugins/stackstorm/src/components/ExecutionsTable/ExecutionsTable.tsx +++ b/plugins/stackstorm/src/components/ExecutionsTable/ExecutionsTable.tsx @@ -15,7 +15,7 @@ */ import React, { useEffect, useState } from 'react'; import { Link, Table, TableColumn } from '@backstage/core-components'; -import { useApi, configApiRef, errorApiRef } from '@backstage/core-plugin-api'; +import { useApi, errorApiRef } from '@backstage/core-plugin-api'; import { Execution, stackstormApiRef } from '../../api'; import { Status } from './Status'; import { ExecutionPanel } from './ExecutionPanel'; @@ -37,7 +37,7 @@ export const DenseTable = ({ onPageChange, onRowsPerPageChange, }: DenseTableProps) => { - const config = useApi(configApiRef); + const st2 = useApi(stackstormApiRef); const columns: TableColumn[] = [ { @@ -54,13 +54,7 @@ export const DenseTable = ({ { title: 'Execution ID', field: 'id', - render: e => ( - - {e.id} - - ), + render: e => {e.id}, }, ]; diff --git a/plugins/stackstorm/src/plugin.ts b/plugins/stackstorm/src/plugin.ts index 8e903c69e8..be4b9c065c 100644 --- a/plugins/stackstorm/src/plugin.ts +++ b/plugins/stackstorm/src/plugin.ts @@ -15,6 +15,7 @@ */ import { + configApiRef, createApiFactory, createPlugin, createRoutableExtension, @@ -35,11 +36,12 @@ export const stackstormPlugin = createPlugin({ createApiFactory({ api: stackstormApiRef, deps: { + configApi: configApiRef, discoveryApi: discoveryApiRef, fetchApi: fetchApiRef, }, - factory: ({ discoveryApi, fetchApi }) => - new StackstormClient({ + factory: ({ configApi, discoveryApi, fetchApi }) => + StackstormClient.fromConfig(configApi, { discoveryApi, fetchApi, }),