Skip to content

Commit

Permalink
wip - connection wizard
Browse files Browse the repository at this point in the history
  • Loading branch information
rachellerathbone committed Dec 11, 2023
2 parents 9c39d43 + 6854342 commit cf5fc74
Show file tree
Hide file tree
Showing 10 changed files with 339 additions and 60 deletions.
1 change: 1 addition & 0 deletions app/jenkins-for-jira-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"@types/react-dom": "17.0.20",
"@types/react-router": "5.1.20",
"@types/uuid": "8.3.4",
"algoliasearch": "^4.20.0",
"eslint-plugin-react-hooks": "4.6.0",
"launchdarkly-react-client-sdk": "^3.0.8",
"moment": "2.29.4",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,13 @@ export const setUpGuideUpdateAvailableContainer = css`
width: 55%;
`;

export const setUpGuideUpdateAvailableLoadingContainer = css`
margin-top: ${token('space.1000')};
padding: ${token('space.1000')};
min-height: 180px;
text-align: center;
`;

export const setUpGuideUpdateAvailableIconContainer = css`
margin: ${token('space.0')} auto;
text-align: center;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
import React from 'react';
import {
act,
fireEvent,
render,
screen,
waitFor
act, fireEvent, render, screen, waitFor
} from '@testing-library/react';
import { ConnectionPanelTop } from './ConnectionPanelTop';
import { ConnectedState } from '../StatusLabel/StatusLabel';
import { addConnectedState, ConnectionPanel } from './ConnectionPanel';
import { EventType, JenkinsServer } from '../../../../src/common/types';
import * as getAllJenkinsServersModule from '../../api/getAllJenkinsServers';
import { ConnectionPanelMain } from './ConnectionPanelMain';

const servers: JenkinsServer[] = [
{
Expand Down Expand Up @@ -301,7 +298,7 @@ describe('Connection Panel Suite', () => {

// TODO - add test for Connection settings - will be done when I build the new set up Jenkins screen

test('should handle server disconnection and refreshing correctly', async () => {
test('should handle server disconnection and refreshing servers correctly', async () => {
jest.spyOn(getAllJenkinsServersModule, 'getAllJenkinsServers').mockResolvedValueOnce(servers);

render(<ConnectionPanel jenkinsServers={servers} setJenkinsServers={jest.fn()}/>);
Expand All @@ -326,7 +323,6 @@ describe('Connection Panel Suite', () => {

describe('Connection Panel Main', () => {
const setJenkinsServers = jest.fn();

test('should render panel content for PENDING server', async () => {
jest.spyOn(getAllJenkinsServersModule, 'getAllJenkinsServers').mockResolvedValueOnce([servers[7]]);

Expand All @@ -350,8 +346,9 @@ describe('Connection Panel Suite', () => {
test('should render panel content for CONNECTED server without pipeline data', async () => {
jest.spyOn(getAllJenkinsServersModule, 'getAllJenkinsServers').mockResolvedValueOnce([servers[1]]);

render(<ConnectionPanel jenkinsServers={servers} setJenkinsServers={setJenkinsServers} />);

await act(async () => {
render(<ConnectionPanel jenkinsServers={servers} setJenkinsServers={setJenkinsServers} />);
await waitFor(() => {
expect(screen.getByText('No data received')).toBeInTheDocument();
expect(screen.queryByText('Pipeline')).not.toBeInTheDocument();
Expand Down Expand Up @@ -463,6 +460,57 @@ describe('Connection Panel Suite', () => {
expect(updateAvailableText).toBeInTheDocument();
});
});

test('should handle refreshing the panel for a server CONNECTED with pipeline data but no plugin config', async () => {
jest.spyOn(getAllJenkinsServersModule, 'getAllJenkinsServers').mockResolvedValueOnce([servers[4]]);

const { rerender } =
render(<ConnectionPanel jenkinsServers={servers} setJenkinsServers={setJenkinsServers} />);

await waitFor(() => {
expect(screen.getByText('CONNECTED')).toBeInTheDocument();
expect(screen.getByText('Pipeline')).toBeInTheDocument();
expect(screen.getByText('Event')).toBeInTheDocument();
expect(screen.getByText('Received')).toBeInTheDocument();
expect(screen.queryByText('Refresh')).not.toBeInTheDocument();
expect(screen.queryByText('To receive build and deployment data from this server:')).not.toBeInTheDocument();
});

await waitFor(() => {
fireEvent.click(screen.getByText('Set up guide'));
});

await waitFor(() => {
expect(screen.getByText('Refresh')).toBeInTheDocument();
expect(screen.queryByText('To receive build and deployment data from this server:')).not.toBeInTheDocument();

const updatedServerData = {
...servers[1],
pluginConfig: {
ipAddress: '10.10.10.12',
lastUpdatedOn: new Date()
}
};

jest.spyOn(getAllJenkinsServersModule, 'getAllJenkinsServers').mockResolvedValueOnce([updatedServerData]);

// Rerender the component with the updated data
rerender(<ConnectionPanelMain
connectedState={ConnectedState.CONNECTED}
jenkinsServer={updatedServerData}
refreshServers={jest.fn()}
/>);
});

await waitFor(() => {
fireEvent.click(screen.getByText('Set up guide'));
});

await waitFor(() => {
fireEvent.click(screen.getByText('Refresh'));
expect(screen.getByText('To receive build and deployment data from this server:')).toBeInTheDocument();
});
});
});
});
});
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import React from 'react';
import { cx } from '@emotion/css';
import Button, { Appearance, ButtonGroup } from '@atlaskit/button';
import Spinner from '@atlaskit/spinner';
import { ConnectedState } from '../StatusLabel/StatusLabel';
import {
connectionPanelContainerContainer,
connectionPanelContainerHeader,
connectionPanelContainerParagraph
connectionPanelContainerParagraph,
notConnectedSpinnerContainer
} from './ConnectionPanel.styles';
import { ConnectionPendingIcon } from '../icons/ConnectionPendingIcon';
import { NoDataIcon } from '../icons/NoDataIcon';
Expand All @@ -21,7 +23,8 @@ type NotConnectedStateProps = {
secondButtonLabel?: string,
buttonOneOnClick(data?: any): void,
buttonTwoOnClick?(): void,
testId?: string
testId?: string,
isLoading: boolean
};

const ConnectionPanelContent = ({
Expand All @@ -34,7 +37,8 @@ const ConnectionPanelContent = ({
secondButtonLabel,
buttonOneOnClick,
buttonTwoOnClick,
testId
testId,
isLoading
}: NotConnectedStateProps): JSX.Element => {
let icon;

Expand All @@ -48,24 +52,32 @@ const ConnectionPanelContent = ({

return (
<div className={cx(connectionPanelContainerContainer)}>
{icon}
<h3 className={cx(connectionPanelContainerHeader)}>{contentHeader}</h3>
<p className={cx(connectionPanelContainerParagraph)}>{contentInstructionOne}</p>
<p className={cx(connectionPanelContainerParagraph)}>{contentInstructionTwo}</p>
<ButtonGroup>
<Button
appearance={buttonAppearance}
onClick={buttonOneOnClick}
testId={testId}
>
{firstButtonLabel}
</Button>
{
secondButtonLabel
? <Button onClick={buttonTwoOnClick}>{secondButtonLabel}</Button>
: <></>
}
</ButtonGroup>
{
isLoading
? <div className={cx(notConnectedSpinnerContainer)}>
<Spinner size='large' />
</div>
: <>
{icon}
<h3 className={cx(connectionPanelContainerHeader)}>{contentHeader}</h3>
<p className={cx(connectionPanelContainerParagraph)}>{contentInstructionOne}</p>
<p className={cx(connectionPanelContainerParagraph)}>{contentInstructionTwo}</p>
<ButtonGroup>
<Button
appearance={buttonAppearance}
onClick={buttonOneOnClick}
testId={testId}
>
{firstButtonLabel}
</Button>
{
secondButtonLabel
? <Button onClick={buttonTwoOnClick}>{secondButtonLabel}</Button>
: <></>
}
</ButtonGroup>
</>
}
</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import React, { ReactNode, useState } from 'react';
import { cx } from '@emotion/css';
import Tabs, { Tab, TabList, TabPanel } from '@atlaskit/tabs';
import Spinner from '@atlaskit/spinner';
import {
connectionPanelMainContainer,
connectionPanelMainConnectedTabs,
connectionPanelMainNotConnectedTabs,
setUpGuideContainer,
setUpGuideUpdateAvailableContainer, connectionPanelMainConnectedPendingSetUp
setUpGuideUpdateAvailableContainer,
connectionPanelMainConnectedPendingSetUp,
setUpGuideUpdateAvailableLoadingContainer
} from './ConnectionPanel.styles';
import { ConnectedState } from '../StatusLabel/StatusLabel';
import { NotConnectedState } from './NotConnectedState';
Expand All @@ -15,6 +18,7 @@ import { ConnectedJenkinsServers } from './ConnectedJenkinsServers';
import { SetUpGuide, UpdateAvailable } from './SetUpGuide';
import { InProductHelpDrawer } from '../InProductHelpDrawer/InProductHelpDrawer';
import { ConnectionPanelContent } from './ConnectionPanelContent';
import { getJenkinsServerWithSecret } from '../../api/getJenkinsServerWithSecret';

type PanelProps = {
children: ReactNode,
Expand Down Expand Up @@ -56,6 +60,8 @@ const ConnectionPanelMain = ({
}: ConnectionPanelMainProps): JSX.Element => {
const [isDrawerOpen, setIsDrawerOpen] = useState(false);
const [selectedTabIndex, setSelectedTabIndex] = useState(0);
const [isLoading, setIsLoading] = useState(false);
const [updatedServer, setUpdatedServer] = useState<JenkinsServer>();

const openDrawer = () => {
setIsDrawerOpen(true);
Expand All @@ -69,10 +75,48 @@ const ConnectionPanelMain = ({
setSelectedTabIndex(index);
};

const handleRefreshPanel = () => {
// TODO - ARC-2738 refresh functionality
const handleRefreshPanel = async () => {
setIsLoading(true);
try {
const server = await getJenkinsServerWithSecret(jenkinsServer.uuid);
setUpdatedServer(server);
} catch (e) {
console.error('No Jenkins server found.');
}

setIsLoading(false);
};

let setUpGuideUpdateAvailableContent;

if (isLoading) {
setUpGuideUpdateAvailableContent = (
<Panel data-testid="updateAvailable">
<div className={cx(setUpGuideUpdateAvailableLoadingContainer)}>
<Spinner size='large' />
</div>
</Panel>
);
} else if (jenkinsServer.pluginConfig || updatedServer?.pluginConfig) {
setUpGuideUpdateAvailableContent = (
<Panel data-testid="setUpGuidePanel">
<SetUpGuide pluginConfig={jenkinsServer.pluginConfig} openDrawer={openDrawer} />
</Panel>
);
} else {
setUpGuideUpdateAvailableContent = (
<Panel data-testid="updateAvailable">
<div className={cx(setUpGuideUpdateAvailableContainer)}>
<UpdateAvailable
handleRefreshPanel={handleRefreshPanel}
jenkinsServer={jenkinsServer}
openDrawer={openDrawer}
/>
</div>
</Panel>
);
}

return (
<div className={cx(connectionPanelMainContainer)}>
<InProductHelpDrawer isDrawerOpen={isDrawerOpen} setIsDrawerOpen={setIsDrawerOpen} />
Expand All @@ -83,6 +127,8 @@ const ConnectionPanelMain = ({
jenkinsServer={jenkinsServer}
refreshServers={refreshServers}
handleRefreshPanel={handleRefreshPanel}
isLoading={isLoading}
setIsLoading={setIsLoading}
/>
: <Tabs id="connection-panel-tabs" selected={selectedTabIndex} onChange={handleTabSelect}>
<TabList>
Expand Down Expand Up @@ -115,6 +161,7 @@ const ConnectionPanelMain = ({
secondButtonLabel="Refresh"
buttonOneOnClick={handleClickSetupGuide}
buttonTwoOnClick={handleRefreshPanel}
isLoading={isLoading}
/>
}
</Panel>
Expand All @@ -124,26 +171,13 @@ const ConnectionPanelMain = ({
jenkinsServer={jenkinsServer}
refreshServers={refreshServers}
handleRefreshPanel={handleRefreshPanel}
isLoading={isLoading}
setIsLoading={setIsLoading}
/>
</Panel>
}
</TabPanel>
<TabPanel>
{
jenkinsServer.pluginConfig
? <Panel data-testid="setUpGuidePanel">
<SetUpGuide
pluginConfig={jenkinsServer.pluginConfig}
openDrawer={openDrawer}
/>
</Panel>
: <Panel data-testid="updateAvailable">
<div className={cx(setUpGuideUpdateAvailableContainer)}>
<UpdateAvailable openDrawer={openDrawer} />
</div>
</Panel>
}
</TabPanel>
<TabPanel>{setUpGuideUpdateAvailableContent}</TabPanel>
</Tabs>
}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,16 @@ describe('NotConnectedState', () => {

const refreshServers = jest.fn();
const handleRefreshPanel = jest.fn();
const setIsLoading = jest.fn();

test('renders with connected state DUPLICATE', () => {
render(<NotConnectedState
connectedState={ConnectedState.DUPLICATE}
jenkinsServer={mockServer}
refreshServers={refreshServers}
handleRefreshPanel={handleRefreshPanel}
isLoading={false}
setIsLoading={setIsLoading}
/>);
expect(screen.getByText('Duplicate server')).toBeInTheDocument();
expect(screen.getByText('Delete')).toBeInTheDocument();
Expand All @@ -40,6 +43,8 @@ describe('NotConnectedState', () => {
jenkinsServer={mockServer}
refreshServers={refreshServers}
handleRefreshPanel={handleRefreshPanel}
isLoading={false}
setIsLoading={setIsLoading}
/>);
expect(screen.getByText('Connection pending')).toBeInTheDocument();
expect(screen.getByText('Refresh')).toBeInTheDocument();
Expand All @@ -53,6 +58,8 @@ describe('NotConnectedState', () => {
jenkinsServer={mockServer}
refreshServers={refreshServers}
handleRefreshPanel={handleRefreshPanel}
isLoading={false}
setIsLoading={setIsLoading}
/>);

fireEvent.click(screen.getByText('Delete'));
Expand Down
Loading

0 comments on commit cf5fc74

Please sign in to comment.