Skip to content

Commit

Permalink
Merge pull request #205 from atlassian/ARC-2584-consume-new-data
Browse files Browse the repository at this point in the history
Arc-2584 consume new data
  • Loading branch information
rachellerathbone authored Nov 28, 2023
2 parents 11de4f2 + 22c0606 commit af7f8a8
Show file tree
Hide file tree
Showing 10 changed files with 325 additions and 77 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export const connectionPanelContainer = css`
box-shadow: 0px 2px 4px 0px #091E4240;
display: flex;
flex-direction: column;
padding: ${token('space.300')};
padding: ${token('space.300')} ${token('space.300')} ${token('space.0')};
margin: ${token('space.400')} auto ${token('space.400')} ${token('space.025')};
`;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,140 @@ import React from 'react';
import { render, screen } from '@testing-library/react';
import { ConnectionPanelTop } from './ConnectionPanelTop';
import { ConnectedState } from '../StatusLabel/StatusLabel';
import { addConnectedState } from './ConnectionPanel';
import { EventType, JenkinsServer } from '../../../../src/common/types';

const servers: JenkinsServer[] = [
{
name: 'server one',
uuid: '56046af9-d0eb-4efb-8896-6c9d0da884fe',
pluginConfig: {
ipAddress: '10.10.10.10',
lastUpdatedOn: new Date()
},
pipelines: [
{
name: '#74315',
lastEventType: EventType.DEPLOYMENT,
lastEventStatus: 'successful',
lastEventDate: new Date()
},
{
name: '#1234',
lastEventType: EventType.BUILD,
lastEventStatus: 'failed',
lastEventDate: new Date()
}
]
},
{
name: 'server two',
uuid: '56046af9-d0eb-4efb-8896-jsdfn8234234',
pluginConfig: {
ipAddress: '10.10.10.11',
lastUpdatedOn: new Date()
},
pipelines: []
},
{
name: 'server three',
uuid: '56046af9-d0eb-4efb-8896-ehdf34bhsdf',
pluginConfig: {
ipAddress: '10.10.10.10',
lastUpdatedOn: new Date()
},
pipelines: []
},
{
name: 'server four',
uuid: '56046af9-d0eb-4efb-8896-sjnd893rsd',
pluginConfig: {
ipAddress: '10.10.10.12',
lastUpdatedOn: new Date()
},
pipelines: [
{
name: '#3456',
lastEventType: EventType.BUILD,
lastEventStatus: 'successful',
lastEventDate: new Date()
}
]
},
{
name: 'server five',
uuid: '56046af9-d0eb-4efb-8896-ed182ende',
pluginConfig: undefined,
pipelines: [
{
name: '#6789',
lastEventType: EventType.DEPLOYMENT,
lastEventStatus: 'pending',
lastEventDate: new Date()
}
]
},
{
name: 'server six',
uuid: '56046af9-d0eb-4efb-8896-hsdbf723rh2r',
pluginConfig: {
ipAddress: '10.10.10.10',
lastUpdatedOn: new Date()
},
pipelines: []
},
{
name: 'server seven',
uuid: '56046af9-d0eb-4efb-8896-iwer23rjesu',
pluginConfig: {
ipAddress: '10.10.10.10',
lastUpdatedOn: new Date()
},
pipelines: []
}
];

describe('addConnectedState', () => {
it('should handle a single server', () => {
const singleServer: JenkinsServer[] = [servers[0]];
const result = addConnectedState(singleServer);

expect(result[0].connectedState).toEqual(ConnectedState.CONNECTED);
});

it('should correctly set state for two servers with different IPs', () => {
const twoServers: JenkinsServer[] = [servers[0], servers[1]];
const result = addConnectedState(twoServers);

expect(result[0].connectedState).toEqual(ConnectedState.CONNECTED);
expect(result[1].connectedState).toEqual(ConnectedState.PENDING);
});

it('should correctly set state for multiple servers with duplicate IPs', () => {
const multipleServers: JenkinsServer[] = [servers[0], servers[2], servers[3]];
const result = addConnectedState(multipleServers);

expect(result[0].connectedState).toEqual(ConnectedState.CONNECTED);
expect(result[1].connectedState).toEqual(ConnectedState.DUPLICATE);
expect(result[2].connectedState).toEqual(ConnectedState.CONNECTED);
});

it('should handle servers with no pluginConfig', () => {
const noPluginConfig: JenkinsServer[] = [servers[4]];
const result = addConnectedState(noPluginConfig);

expect(result[0].connectedState).toEqual(ConnectedState.PENDING);
});

it('should correctly set state for multiple servers with duplicate IPs and no pipelines', () => {
const duplicateServers: JenkinsServer[] = [servers[2], servers[5], servers[6]];
const result = addConnectedState(duplicateServers);

expect(result[0].connectedState).toEqual(ConnectedState.PENDING);
expect(result[1].connectedState).toEqual(ConnectedState.DUPLICATE);
expect(result[2].connectedState).toEqual(ConnectedState.DUPLICATE);
});
});

describe('ConnectionPanelTop', () => {
test('renders with the correct content and styles for CONNECTED state', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,28 @@ import { connectionPanelContainer } from './ConnectionPanel.styles';
import { JenkinsServer } from '../../../../src/common/types';
import { getAllJenkinsServers } from '../../api/getAllJenkinsServers';

// TODO - add DUPLICATE state once I'm pulling in new data from backend
export const addConnectedState = (servers: JenkinsServer[]): JenkinsServer[] => {
return servers.map((server: JenkinsServer) => ({
...server,
connectedState: server.pipelines.length === 0 ? ConnectedState.PENDING : ConnectedState.CONNECTED
}));
const ipAddressSet = new Set<string>();

return servers
.slice() // Create a shallow copy to avoid mutating the original array
.sort((a, b) => b.pipelines.length - a.pipelines.length)
.map((server: JenkinsServer) => {
const ipAddress = server.pluginConfig?.ipAddress;
let connectedState = ConnectedState.PENDING;

if (ipAddress && ipAddressSet.has(ipAddress)) {
connectedState = ConnectedState.DUPLICATE;
} else if (server.pipelines.length > 0 && ipAddress) {
connectedState = ConnectedState.CONNECTED;
ipAddressSet.add(ipAddress);
}

return {
...server,
connectedState
};
});
};

const ConnectionPanel = (): JSX.Element => {
Expand All @@ -31,19 +47,22 @@ const ConnectionPanel = (): JSX.Element => {
return (
<>
{jenkinsServers.map(
(server: JenkinsServer, index: number): JSX.Element => (
<div className={cx(connectionPanelContainer)} key={index}>
<ConnectionPanelTop
name={server.name}
connectedState={server.connectedState || ConnectedState.PENDING}
ipAddress="10.10.0.10"
/>
<ConnectionPanelMain
connectedState={server.connectedState || ConnectedState.PENDING}
jenkinsServer={server}
/>
</div>
)
(server: JenkinsServer, index: number): JSX.Element => {
const ipAddress = server.pluginConfig?.ipAddress;
return (
<div className={cx(connectionPanelContainer)} key={index}>
<ConnectionPanelTop
name={server.name}
connectedState={server.connectedState || ConnectedState.PENDING}
ipAddress={ipAddress}
/>
<ConnectionPanelMain
connectedState={server.connectedState || ConnectedState.PENDING}
jenkinsServer={server}
/>
</div>
);
}
)}
</>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@ import { JenkinsServer } from '../../../../src/common/types';
import { ConnectedJenkinsServers } from './ConnectedJenkinsServers';
import { SetUpGuide } from './SetUpGuide';

// TODO - remove ? for children and connectedState once set up guide is merged
type PanelProps = {
children?: ReactNode,
children: ReactNode,
connectedState?: ConnectedState,
'data-testid'?: string
};
Expand Down Expand Up @@ -74,7 +73,7 @@ const ConnectionPanelMain = ({ connectedState, jenkinsServer }: ConnectionPanelM
</TabPanel>
<TabPanel>
<Panel data-testid="setUpGuidePanel">
<SetUpGuide />
<SetUpGuide pluginConfig={jenkinsServer.pluginConfig}/>
</Panel>
</TabPanel>
</Tabs>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { ConnectedState, StatusLabel } from '../StatusLabel/StatusLabel';

type ConnectionPanelTopProps = {
connectedState: ConnectedState,
ipAddress: string,
ipAddress?: string,
name: string
};

Expand All @@ -35,7 +35,10 @@ const ConnectionPanelTop = ({ connectedState, ipAddress, name }: ConnectionPanel
<StatusLabel text={connectedState} color={textColor} backgroundColor={backgroundColor} />
</div>
<div>
<p className={cx(ipAddressStyle)}>IP address: {ipAddress}</p>
{
ipAddress &&
<p className={cx(ipAddressStyle)}>IP address: {ipAddress}</p>
}
</div>
</div>
<DropdownMenu
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import { cx } from '@emotion/css';
import Button from '@atlaskit/button';
import { token } from '@atlaskit/tokens';
import { ConnectedState } from '../StatusLabel/StatusLabel';
import {
notConnectedStateContainer,
Expand Down Expand Up @@ -43,7 +44,7 @@ const NotConnectedState = ({ connectedState }: NotConnectedStateProps): JSX.Elem
{
connectedState === ConnectedState.PENDING
? <Button>Connection settings</Button>
: <Button appearance="danger">Delete</Button>
: <Button appearance="danger" style={{ marginBottom: `${token('space.400')}` }}>Delete</Button>
}
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import React from 'react';
import { render } from '@testing-library/react';
import { PipelineEventType, SetUpGuideInstructions, SetUpGuideLink } from './SetUpGuide';

describe('SetUpGuideInstructions', () => {
const onClickMock = jest.fn();

test('renders SetUpGuideInstructions with BUILD eventType, globalSettings, and regex', () => {
const { getByText } = render(
<SetUpGuideInstructions
onClick={onClickMock}
eventType={PipelineEventType?.BUILD}
globalSettings
regex="^build$"
/>
);

expect(getByText('jiraSendBuildInfo')).toBeInTheDocument();
expect(getByText('OR')).toBeInTheDocument();
expect(getByText('^build$')).toBeInTheDocument();
});

test('renders SetUpGuideInstructions with BUILD eventType, globalSettings, and no regex', () => {
const { getByText } = render(
<SetUpGuideInstructions
onClick={onClickMock}
eventType={PipelineEventType?.BUILD}
globalSettings
/>
);

expect(getByText('No setup required')).toBeInTheDocument();
});

test('renders SetUpGuideInstructions with DEPLOYMENT eventType, globalSettings, and regex', () => {
const { getByText } = render(
<SetUpGuideInstructions
onClick={onClickMock}
eventType={PipelineEventType?.DEPLOYMENT}
globalSettings
regex="^deploy to (?<envName>.*)$"
/>
);

expect(getByText('jiraSendDeploymentInfo')).toBeInTheDocument();
expect(getByText('OR')).toBeInTheDocument();
expect(getByText('^deploy to (?<envName>.*)$')).toBeInTheDocument();
});

test('renders SetUpGuideInstructions with DEPLOYMENT eventType, globalSettings set to false', () => {
const { getByText, queryByText } = render(
<SetUpGuideInstructions
onClick={onClickMock}
eventType={PipelineEventType?.DEPLOYMENT}
globalSettings={false}
/>
);

expect(getByText('jiraSendDeploymentInfo')).toBeInTheDocument();
expect(queryByText('OR')).toBeNull();
});
});

describe('SetUpGuideLink', () => {
const onClickMock = jest.fn();

test('renders SetUpGuideLink with label', () => {
const { getByText } = render(
<SetUpGuideLink onClick={onClickMock} label="build" />
);

expect(getByText('build')).toBeInTheDocument();
});
});
Loading

0 comments on commit af7f8a8

Please sign in to comment.