Browse Source

fix(home): fix networks being loaded from disk many times

feat/auto-update
jamaljsr 5 years ago
parent
commit
15aba2b96e
  1. 1
      TODO.md
  2. 21
      src/components/home/Home.spec.tsx
  3. 33
      src/components/home/Home.tsx
  4. 4
      src/components/routing/Routes.spec.tsx
  5. 7
      src/store/models/network.ts

1
TODO.md

@ -2,7 +2,6 @@
Small Stuff
- replace sidebar with app header bar
- switch renovatebot to dependabot and use automatic security fixes
- build images if they don't exist
- generate alice/bob/carol names for lnd nodes

21
src/components/home/Home.spec.tsx

@ -1,5 +1,5 @@
import React from 'react';
import { fireEvent } from '@testing-library/react';
import { fireEvent, waitForElement } from '@testing-library/react';
import { getNetwork, injections, renderWithProviders } from 'utils/tests';
import Home from './Home';
@ -24,30 +24,35 @@ describe('Home component', () => {
expect(await findByText('error reading file')).toBeInTheDocument();
});
it('should display a list of networks', () => {
it('should display a list of networks', async () => {
const { getByText } = renderComponent();
await waitForElement(() => getByText('Click Me!'));
expect(getByText('my network 1')).toBeInTheDocument();
expect(getByText('my network 2')).toBeInTheDocument();
expect(getByText('my network 3')).toBeInTheDocument();
});
it('should contain a "Click Me!" button', () => {
it('should contain a "Click Me!" button', async () => {
const { getByText } = renderComponent();
await waitForElement(() => getByText('Click Me!'));
expect(getByText('Click Me!')).toBeInTheDocument();
});
it('should contain a link to Counter page', () => {
it('should contain a link to Counter page', async () => {
const { getByText } = renderComponent();
await waitForElement(() => getByText('Click Me!'));
expect(getByText('Network')).toBeInTheDocument();
});
it('should not show alert message', () => {
const { queryByTestId } = renderComponent();
expect(queryByTestId('success')).toBeFalsy();
it('should not show alert message', async () => {
const { queryByText, getByText } = renderComponent();
await waitForElement(() => getByText('Click Me!'));
expect(queryByText('Success Tips')).toBeNull();
});
it('should show alert after button is clicked', () => {
it('should show alert after button is clicked', async () => {
const { getByText } = renderComponent();
await waitForElement(() => getByText('Click Me!'));
const btn = getByText('Click Me!');
fireEvent.click(btn);
expect(getByText('Success Tips')).toBeInTheDocument();

33
src/components/home/Home.tsx

@ -1,35 +1,44 @@
import React, { useEffect, useState } from 'react';
import { useAsync } from 'react-async-hook';
import { Trans, useTranslation } from 'react-i18next';
import { Link } from 'react-router-dom';
import { info } from 'electron-log';
import { Alert, Button, Card, notification } from 'antd';
import { Alert, Button, Card } from 'antd';
import { useStoreActions, useStoreState } from 'store';
import { Loader } from 'components/common';
import { NETWORK, NETWORK_VIEW } from 'components/routing';
const Home = () => {
useEffect(() => info('Rendering Home component'), []);
const { t } = useTranslation();
const { networks } = useStoreState(s => s.network);
const { networks, loaded } = useStoreState(s => s.network);
const { load } = useStoreActions(s => s.network);
useEffect(() => {
load().catch((e: Error) =>
notification.error({
message: t('cmps.home.load-error-msg', 'Unable to load previously save networks'),
description: e.message,
placement: 'bottomRight',
bottom: 50,
}),
);
}, [load, t]);
const loadAsync = useAsync(() => load(), [], { executeOnMount: !loaded });
const [showAlert, setShowAlert] = useState(false);
const handleClickMe = () => setShowAlert(true);
if (loadAsync.loading) {
return <Loader />;
}
return (
<div>
{showAlert && (
<Alert message={t('cmps.home.success-text')} type="success" showIcon />
)}
{loadAsync.error && (
<Alert
type="error"
showIcon
closable
message={t(
'cmps.home.load-error-msg',
'Unable to load previously save networks',
)}
description={loadAsync.error.message}
/>
)}
<Card title={t('cmps.home.card-title')}>
<p>{t('cmps.home.card-description')}</p>
<p>

4
src/components/routing/Routes.spec.tsx

@ -1,4 +1,5 @@
import React from 'react';
import { waitForElement } from '@testing-library/react';
import { renderWithProviders } from 'utils/tests';
import { HOME, NETWORK, Routes } from 'components/routing';
@ -7,8 +8,9 @@ describe('App container', () => {
return renderWithProviders(<Routes />, { route });
};
it('should render the home page', () => {
it('should render the home page', async () => {
const { getByText } = renderComponent(HOME);
await waitForElement(() => getByText('Click Me!'));
expect(getByText('Click Me!')).toBeInTheDocument();
});

7
src/store/models/network.ts

@ -16,8 +16,10 @@ interface AddNetworkArgs {
export interface NetworkModel {
networks: Network[];
loaded: boolean;
networkById: Computed<NetworkModel, (id?: string | number) => Network>;
setNetworks: Action<NetworkModel, Network[]>;
setLoaded: Action<NetworkModel, boolean>;
load: Thunk<NetworkModel, any, StoreInjections, {}, Promise<void>>;
save: Thunk<NetworkModel, any, StoreInjections, {}, Promise<void>>;
add: Action<NetworkModel, AddNetworkArgs>;
@ -31,6 +33,7 @@ export interface NetworkModel {
const networkModel: NetworkModel = {
// state properties
networks: [],
loaded: false,
// computed properties/functions
networkById: computed(state => (id?: string | number) => {
const networkId = typeof id === 'number' ? id : parseInt(id || '');
@ -44,11 +47,15 @@ const networkModel: NetworkModel = {
setNetworks: action((state, networks) => {
state.networks = networks;
}),
setLoaded: action((state, loaded) => {
state.loaded = loaded;
}),
load: thunk(async (actions, payload, { injections }) => {
const networks = await injections.dockerService.load();
if (networks && networks.length) {
actions.setNetworks(networks);
}
actions.setLoaded(true);
}),
save: thunk(async (actions, payload, { getState, injections }) => {
await injections.dockerService.save(getState().networks);

Loading…
Cancel
Save