Browse Source

test(network-view): add remaining unit tests for Network View screen

feat/auto-update
jamaljsr 5 years ago
committed by jamaljsr
parent
commit
42597d8bc3
  1. 42
      src/components/network/BitcoinCard.spec.tsx
  2. 38
      src/components/network/BitcoindCard.tsx
  3. 46
      src/components/network/LndCard.spec.tsx
  4. 40
      src/components/network/LndCard.tsx
  5. 45
      src/components/network/NetworkActions.spec.tsx
  6. 2
      src/components/network/NetworkActions.tsx
  7. 38
      src/components/network/NetworkView.spec.tsx
  8. 24
      src/components/network/NetworkView.tsx
  9. 7
      src/store/models/network.spec.ts
  10. 12
      src/utils/tests.tsx

42
src/components/network/BitcoinCard.spec.tsx

@ -0,0 +1,42 @@
import React from 'react';
import { renderWithProviders } from 'utils/tests';
import { BitcoinNode, Status } from 'types';
import BitcoindCard from './BitcoindCard';
describe('StatusTag Component', () => {
const node: BitcoinNode = {
id: 1,
name: 'test btc',
implementation: 'bitcoind',
status: Status.Stopped,
type: 'bitcoin',
};
const details = [
{ label: 'Block Height', value: '432' },
{ label: 'Wallet Balance', value: '54.00000000' },
{ label: 'Host', value: '159.65.239.204' },
{ label: 'Version', value: 'v0.18.1' },
];
const renderComponent = () => {
return renderWithProviders(<BitcoindCard node={node} details={details} />);
};
it('should render the name', () => {
const { getByText } = renderComponent();
expect(getByText(node.name)).toBeTruthy();
});
it('should render the details', () => {
const { getByText } = renderComponent();
expect(getByText(details[0].label)).toBeTruthy();
expect(getByText(details[0].value)).toBeTruthy();
expect(getByText(details[1].label)).toBeTruthy();
expect(getByText(details[1].value)).toBeTruthy();
expect(getByText(details[2].label)).toBeTruthy();
expect(getByText(details[2].value)).toBeTruthy();
expect(getByText(details[3].label)).toBeTruthy();
expect(getByText(details[3].value)).toBeTruthy();
});
});

38
src/components/network/BitcoindCard.tsx

@ -7,30 +7,22 @@ import logo from 'resources/bitcoin.svg';
interface Props {
node: BitcoinNode;
className?: string;
details: { label: string; value: string }[];
}
const btcDetails = [
{ label: 'Block Height', value: '432' },
{ label: 'Wallet Balance', value: '54.00000000' },
{ label: 'Host', value: '159.65.239.204:8443' },
{ label: 'Version', value: 'v0.18.1' },
];
const BitcoindCard: React.FC<Props> = ({ node, className }) => {
return (
<Card
title={<StatusBadge status={node.status} text={node.name} />}
className={className}
extra={<Avatar src={logo} shape="square" />}
actions={[
<Icon type="code" key="code" />,
<Icon type="file-text" key="logs" />,
<Icon type="ellipsis" key="ellipsis" />,
]}
>
<DetailsList details={btcDetails} />
</Card>
);
};
const BitcoindCard: React.FC<Props> = ({ node, className, details }) => (
<Card
title={<StatusBadge status={node.status} text={node.name} />}
className={className}
extra={<Avatar src={logo} shape="square" />}
actions={[
<Icon type="code" key="code" />,
<Icon type="file-text" key="logs" />,
<Icon type="ellipsis" key="ellipsis" />,
]}
>
<DetailsList details={details} />
</Card>
);
export default BitcoindCard;

46
src/components/network/LndCard.spec.tsx

@ -0,0 +1,46 @@
import React from 'react';
import { renderWithProviders } from 'utils/tests';
import { LightningNode, Status } from 'types';
import LndCard from './LndCard';
describe('StatusTag Component', () => {
const node: LightningNode = {
id: 1,
name: 'test lnd',
implementation: 'LND',
status: Status.Stopped,
type: 'lightning',
backendName: 'bitcoind-1',
};
const details = [
{ label: 'PubKey', value: '0245....5fd47' },
{ label: 'Host', value: '159.65.239.204' },
{ label: 'Synced to Chain', value: 'true' },
{ label: 'Chain Node', value: 'bitcoind1' },
{ label: 'Version', value: 'v0.7.1' },
];
const renderComponent = () => {
return renderWithProviders(<LndCard node={node} details={details} />);
};
it('should render the name', () => {
const { getByText } = renderComponent();
expect(getByText(node.name)).toBeTruthy();
});
it('should render the details', () => {
const { getByText } = renderComponent();
expect(getByText(details[0].label)).toBeTruthy();
expect(getByText(details[0].value)).toBeTruthy();
expect(getByText(details[1].label)).toBeTruthy();
expect(getByText(details[1].value)).toBeTruthy();
expect(getByText(details[2].label)).toBeTruthy();
expect(getByText(details[2].value)).toBeTruthy();
expect(getByText(details[3].label)).toBeTruthy();
expect(getByText(details[3].value)).toBeTruthy();
expect(getByText(details[4].label)).toBeTruthy();
expect(getByText(details[4].value)).toBeTruthy();
});
});

40
src/components/network/LndCard.tsx

@ -7,32 +7,22 @@ import lnd from 'resources/lnd.png';
interface Props {
node: LightningNode;
className?: string;
details: { label: string; value: string }[];
}
const lndDetails = [
{ label: 'PubKey', value: '0245....5fd47' },
{ label: 'Host', value: '159.65.239.204:9735' },
{ label: 'Channels', value: '2' },
{ label: 'Synced to Chain', value: 'true' },
{ label: 'Chain Node', value: 'bitcoind1' },
{ label: 'Version', value: 'v0.7.1' },
];
const LndCard: React.FC<Props> = ({ node, className }) => {
return (
<Card
title={<StatusBadge status={node.status} text={node.name} />}
className={className}
extra={<Avatar src={lnd} shape="square" />}
actions={[
<Icon type="code" key="code" />,
<Icon type="file-text" key="logs" />,
<Icon type="ellipsis" key="ellipsis" />,
]}
>
<DetailsList details={lndDetails} />
</Card>
);
};
const LndCard: React.FC<Props> = ({ node, details, className }) => (
<Card
title={<StatusBadge status={node.status} text={node.name} />}
className={className}
extra={<Avatar src={lnd} shape="square" />}
actions={[
<Icon type="code" key="code" />,
<Icon type="file-text" key="logs" />,
<Icon type="ellipsis" key="ellipsis" />,
]}
>
<DetailsList details={details} />
</Card>
);
export default LndCard;

45
src/components/network/NetworkActions.spec.tsx

@ -0,0 +1,45 @@
import React from 'react';
import { renderWithProviders } from 'utils/tests';
import { Status } from 'types';
import NetworkActions from './NetworkActions';
describe('NetworkActions Component', () => {
const renderComponent = (status: Status) => {
return renderWithProviders(<NetworkActions status={status} />);
};
it('should render the Starting status', () => {
const { getByText } = renderComponent(Status.Starting);
expect(getByText('Starting')).toBeTruthy();
// button should be loading
expect(getByText('Starting').parentElement).toHaveClass('ant-btn-loading');
});
it('should render the Started status', () => {
const { getByText } = renderComponent(Status.Started);
expect(getByText('Stop')).toBeTruthy();
// button should not be loading
expect(getByText('Stop').parentElement).not.toHaveClass('ant-btn-loading');
});
it('should render the Stopping status', () => {
const { getByText } = renderComponent(Status.Stopping);
expect(getByText('Stopping')).toBeTruthy();
// button should be loading
expect(getByText('Stopping').parentElement).toHaveClass('ant-btn-loading');
});
it('should render the Stopped status', () => {
const { getByText } = renderComponent(Status.Stopped);
expect(getByText('Start')).toBeTruthy();
// button should be loading
expect(getByText('Start').parentElement).not.toHaveClass('ant-btn-loading');
});
it('should render the Error status', () => {
const { getByText } = renderComponent(Status.Error);
expect(getByText('Restart')).toBeTruthy();
// button should be loading
expect(getByText('Restart').parentElement).not.toHaveClass('ant-btn-loading');
});
});

2
src/components/network/NetworkActions.tsx

@ -35,7 +35,7 @@ const config: {
icon: 'play-circle',
},
[Status.Error]: {
label: 'Stop',
label: 'Restart',
type: 'danger',
icon: 'warning',
},

38
src/components/network/NetworkView.spec.tsx

@ -0,0 +1,38 @@
import React from 'react';
import { Route } from 'react-router';
import { renderWithProviders, getNetwork } from 'utils/tests';
import NetworkView from './NetworkView';
describe('NetworkView Component', () => {
const renderComponent = (route = '/network/1') => {
const initialState = {
network: {
networks: [getNetwork(1, 'test network')],
},
};
// NetworkView needs to be rendered by the router due to
// RouteComponentProps not being easily mockable
const cmp = <Route path="/network/:id" component={NetworkView} />;
return renderWithProviders(cmp, { initialState, route });
};
it('should not render if the network is not found', () => {
const { queryByText } = renderComponent('/network/99');
expect(queryByText('test network')).toBeNull();
});
it('should render the name', () => {
const { getByText } = renderComponent();
expect(getByText('test network')).toBeTruthy();
});
it('should render correct # of LND nodes', () => {
const { queryAllByText } = renderComponent();
expect(queryAllByText(/lnd-\d/)).toHaveLength(2);
});
it('should render correct # of bitcoind nodes', () => {
const { queryAllByText } = renderComponent();
expect(queryAllByText(/bitcoind-\d/)).toHaveLength(1);
});
});

24
src/components/network/NetworkView.tsx

@ -12,6 +12,22 @@ interface MatchParams {
id?: string;
}
const btcDetails = [
{ label: 'Block Height', value: '432' },
{ label: 'Wallet Balance', value: '54.00000000' },
{ label: 'Host', value: '159.65.239.204' },
{ label: 'Version', value: 'v0.18.1' },
];
const lndDetails = [
{ label: 'PubKey', value: '0245....5fd47' },
{ label: 'Host', value: '159.65.239.204' },
{ label: 'Channels', value: '2' },
{ label: 'Synced to Chain', value: 'true' },
{ label: 'Chain Node', value: 'bitcoind1' },
{ label: 'Version', value: 'v0.7.1' },
];
const NetworkView: React.FC<RouteComponentProps<MatchParams>> = ({ match }) => {
const network = useStoreState(s => s.network.networkById(match.params.id));
if (!network) {
@ -32,16 +48,16 @@ const NetworkView: React.FC<RouteComponentProps<MatchParams>> = ({ match }) => {
<Divider>Lightning Nodes</Divider>
<Row gutter={16} data-tid="ln-nodes">
{lightning.map(node => (
<Col key={node.id} span={8}>
<LndCard node={node} className={styles.card} />
<Col key={node.id} span={12}>
<LndCard node={node} details={lndDetails} className={styles.card} />
</Col>
))}
</Row>
<Divider>Bitcoin Nodes</Divider>
<Row gutter={16} data-tid="btc-nodes">
{bitcoin.map(node => (
<Col key={node.id} span={8}>
<BitcoindCard node={node} className={styles.card} />
<Col key={node.id} span={12}>
<BitcoindCard node={node} details={btcDetails} className={styles.card} />
</Col>
))}
</Row>

7
src/store/models/network.spec.ts

@ -92,4 +92,11 @@ describe('counter model', () => {
expect(network.id).toBe(1);
expect(network.name).toBe('test');
});
it('should fail to fetch a node with invalid id', () => {
store.getActions().add(addNetworkArgs);
expect(store.getState().networkById((null as unknown) as string)).toBeUndefined();
expect(store.getState().networkById('asdf')).toBeUndefined();
expect(store.getState().networkById('99')).toBeUndefined();
});
});

12
src/utils/tests.tsx

@ -14,8 +14,8 @@ export const getNetwork = (networkId?: number, name?: string): Network => ({
nodes: {
bitcoin: [
{
id: 0,
name: 'bitcoind1',
id: 1,
name: 'bitcoind-1',
type: 'bitcoin',
implementation: 'bitcoind',
status: Status.Stopped,
@ -23,16 +23,16 @@ export const getNetwork = (networkId?: number, name?: string): Network => ({
],
lightning: [
{
id: 0,
name: 'alice',
id: 1,
name: 'lnd-1',
type: 'lightning',
implementation: 'LND',
status: Status.Stopped,
backendName: 'bitcoind1',
},
{
id: 0,
name: 'bob',
id: 2,
name: 'lnd-2',
type: 'lightning',
implementation: 'LND',
status: Status.Stopped,

Loading…
Cancel
Save