diff --git a/app/.storybook/preview.tsx b/app/.storybook/preview.tsx index 7faacfb7..a45b3b8b 100644 --- a/app/.storybook/preview.tsx +++ b/app/.storybook/preview.tsx @@ -17,15 +17,14 @@ const store = new Store(); /** * Create dummy actions to use for stories */ + // mock the GRPC client to return sample data instead of making an actual request const grpc = { request: (methodDescriptor: any) => { const endpoint = `${methodDescriptor.service.serviceName}.${methodDescriptor.methodName}`; const data = sampleApiResponses[endpoint] || {}; // the calling function expects the return value to have a `toObject` function - const response: any = { - toObject: () => data, - }; + const response: any = { toObject: () => data }; return Promise.resolve(response); }, }; @@ -34,15 +33,25 @@ const actions = createActions(store, grpc); // execute actions to populate the store data with the sample API responses actions.node.getBalances(); +/** + * add the mobx store to Storybook parameters so that stories can manipulate it + */ addParameters({ store }); /** * decorator function to wrap all stories with the necessary providers */ -addDecorator(storyFn => ( +addDecorator((storyFn, ctx) => ( - {storyFn()} + + {/* wrap the component in a centered div for small components */} + {ctx.parameters.centered ? ( +
{storyFn()}
+ ) : ( + storyFn() + )} +
)); diff --git a/app/src/__stories__/NodeStatus.stories.tsx b/app/src/__stories__/NodeStatus.stories.tsx index c534f370..a216af8b 100644 --- a/app/src/__stories__/NodeStatus.stories.tsx +++ b/app/src/__stories__/NodeStatus.stories.tsx @@ -1,9 +1,31 @@ -import React from 'react'; +import React, { useEffect } from 'react'; +import { StoryContext } from '@storybook/addons'; +import { Store } from 'store'; import NodeStatus from 'components/NodeStatus'; export default { title: 'Node Status', component: NodeStatus, + parameters: { centered: true }, }; -export const Default = () => ; +export const Default = (ctx: StoryContext) => { + useEffect(() => { + // grab the store from the Storybook parameter defined in preview.tsx + const store = ctx.parameters.store as Store; + const { channelBalance, walletBalance } = store.balances || { + channelBalance: 0, + walletBalance: 0, + }; + store.balances = { channelBalance: 0, walletBalance: 0 }; + + // change back to sample data when the component is unmounted + return () => { + store.balances = { channelBalance, walletBalance }; + }; + }, []); + + return ; +}; + +export const WithBalances = () => ; diff --git a/app/src/__stories__/Tile.stories.tsx b/app/src/__stories__/Tile.stories.tsx new file mode 100644 index 00000000..f56f6492 --- /dev/null +++ b/app/src/__stories__/Tile.stories.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import Tile from 'components/common/Tile'; + +export default { + title: 'Tile', + component: Tile, + parameters: { centered: true }, +}; + +export const Empty = () => ; + +export const WithText = () => ; + +export const WithChildren = () => ( + Sample child content +); + +export const InboundLiquidity = () => ( + +); diff --git a/app/src/__tests__/action/store.spec.ts b/app/src/__tests__/action/store.spec.ts new file mode 100644 index 00000000..b31651d8 --- /dev/null +++ b/app/src/__tests__/action/store.spec.ts @@ -0,0 +1,32 @@ +import { lndListChannels } from 'util/sampleData'; +import { createActions, StoreActions } from 'action'; +import { Store } from 'store'; + +describe('SwapAction', () => { + let store: Store; + let actions: StoreActions; + + beforeEach(() => { + store = new Store(); + actions = createActions(store); + }); + + it('should compute inbound liquidity', async () => { + const inbound = lndListChannels.channelsList.reduce( + (sum, chan) => sum + chan.remoteBalance, + 0, + ); + + await actions.channel.getChannels(); + expect(store.totalInbound).toBe(inbound); + }); + + it('should compute outbound liquidity', async () => { + const outbound = lndListChannels.channelsList.reduce( + (sum, chan) => sum + chan.localBalance, + 0, + ); + await actions.channel.getChannels(); + expect(store.totalOutbound).toBe(outbound); + }); +});