redux#Store TypeScript Examples

The following examples show how to use redux#Store. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: reducer.test.ts    From cuiswap with GNU General Public License v3.0 7 votes vote down vote up
describe('mint reducer', () => {
  let store: Store<MintState>

  beforeEach(() => {
    store = createStore(reducer, {
      independentField: Field.CURRENCY_A,
      typedValue: '',
      otherTypedValue: ''
    })
  })

  describe('typeInput', () => {
    it('sets typed value', () => {
      store.dispatch(typeInput({ field: Field.CURRENCY_A, typedValue: '1.0', noLiquidity: false }))
      expect(store.getState()).toEqual({ independentField: Field.CURRENCY_A, typedValue: '1.0', otherTypedValue: '' })
    })
    it('clears other value', () => {
      store.dispatch(typeInput({ field: Field.CURRENCY_A, typedValue: '1.0', noLiquidity: false }))
      store.dispatch(typeInput({ field: Field.CURRENCY_B, typedValue: '1.0', noLiquidity: false }))
      expect(store.getState()).toEqual({ independentField: Field.CURRENCY_B, typedValue: '1.0', otherTypedValue: '' })
    })
  })
})
Example #2
Source File: reducer.test.ts    From interface-v2 with GNU General Public License v3.0 6 votes vote down vote up
describe('swap reducer', () => {
  let store: Store<SwapState>;

  beforeEach(() => {
    store = createStore(reducer, {
      [Field.OUTPUT]: { currencyId: '' },
      [Field.INPUT]: { currencyId: '' },
      typedValue: '',
      independentField: Field.INPUT,
      recipient: null,
    });
  });

  describe('selectToken', () => {
    it('changes token', () => {
      store.dispatch(
        selectCurrency({
          field: Field.OUTPUT,
          currencyId: '0x0000',
        }),
      );

      expect(store.getState()).toEqual({
        [Field.OUTPUT]: { currencyId: '0x0000' },
        [Field.INPUT]: { currencyId: '' },
        typedValue: '',
        independentField: Field.INPUT,
        recipient: null,
      });
    });
  });
});
Example #3
Source File: ws-middleware.ts    From react-spring-messenger-project with MIT License 6 votes vote down vote up
/**
 * Update groups sidebar with new messages
 *
 * @param store
 * @param value
 * @param userId
 */
function updateGroupsWithLastMessageSent(store: Store, value: FullMessageModel, userId: number) {
    const groupIdToUpdate = value.groupId;
    const groups: GroupModel[] = store.getState().WebSocketReducer.wsUserGroups;
    let groupToPlaceInFirstPosition = groups.findIndex((elt) => elt.id === groupIdToUpdate);
    if (groupToPlaceInFirstPosition === -1) {
        return
    }
    let groupsArray = [...groups];
    let item = {...groupsArray[groupToPlaceInFirstPosition]};
    item.lastMessage = value.message;
    item.lastMessageDate = value.time;
    item.lastMessageSeen = value.isMessageSeen;
    item.lastMessageSender = value.sender;
    groupsArray.splice(groupToPlaceInFirstPosition, 1);
    groupsArray.unshift(item);
    store.dispatch({type: SET_WS_GROUPS, payload: groupsArray})
}
Example #4
Source File: reducer.test.ts    From sybil-interface with GNU General Public License v3.0 6 votes vote down vote up
describe('swap reducer', () => {
  let store: Store<UserState>

  beforeEach(() => {
    store = createStore(reducer, initialState)
  })

  describe('updateVersion', () => {
    it('has no timestamp originally', () => {
      expect(store.getState().lastUpdateVersionTimestamp).toBeUndefined()
    })
    it('sets the lastUpdateVersionTimestamp', () => {
      const time = new Date().getTime()
      store.dispatch(updateVersion())
      expect(store.getState().lastUpdateVersionTimestamp).toBeGreaterThanOrEqual(time)
    })
    it('sets allowed slippage and deadline', () => {
      store = createStore(reducer, {
        ...initialState,
        userDeadline: undefined,
        userSlippageTolerance: undefined,
      } as any)
      store.dispatch(updateVersion())
    })
  })
})
Example #5
Source File: devStoreConfig.ts    From react-app-architecture with Apache License 2.0 6 votes vote down vote up
devStoreConfig = (preloadedState: Partial<RootState>): Store => {
  const store = createStore(
    rootReducer,
    preloadedState,
    applyMiddleware(thunk, logger, crashReporter),
  );

  // @ts-ignore
  if (module.hot) {
    // Enable Webpack hot module replacement for reducers
    // @ts-ignore
    module.hot.accept('../reducers', () => {
      const nextRootReducer = require('../reducers');
      store.replaceReducer(nextRootReducer);
    });
  }

  return store;
}
Example #6
Source File: renderUtils.tsx    From diagram-maker with Apache License 2.0 6 votes vote down vote up
export function render<NodeType, EdgeType>(
  store: Store<DiagramMakerData<NodeType, EdgeType>>,
  container: HTMLElement,
  configService: ConfigService<NodeType, EdgeType>,
) {
  const ConnectedView = getConnectedView();
  return Preact.render(
    <Provider store={store}>
      <ConnectedView configService={configService} />
    </Provider>,
    container,
  );
}
Example #7
Source File: index.spec.tsx    From che-dashboard-next with Eclipse Public License 2.0 6 votes vote down vote up
function createStore(cheCliTool: string, helpTitle: string): Store {
  return new FakeStoreBuilder()
    .withBranding({
      helpTitle: helpTitle,
      configuration: {
        cheCliTool
      },
      docs: {
      }
    } as BrandingData)
    .build();
}
Example #8
Source File: reducer.test.ts    From cheeseswap-interface with GNU General Public License v3.0 6 votes vote down vote up
describe('swap reducer', () => {
  let store: Store<UserState>

  beforeEach(() => {
    store = createStore(reducer, initialState)
  })

  describe('updateVersion', () => {
    it('has no timestamp originally', () => {
      expect(store.getState().lastUpdateVersionTimestamp).toBeUndefined()
    })
    it('sets the lastUpdateVersionTimestamp', () => {
      const time = new Date().getTime()
      store.dispatch(updateVersion())
      expect(store.getState().lastUpdateVersionTimestamp).toBeGreaterThanOrEqual(time)
    })
    it('sets allowed slippage and deadline', () => {
      store = createStore(reducer, {
        ...initialState,
        userDeadline: undefined,
        userSlippageTolerance: undefined
      } as any)
      store.dispatch(updateVersion())
      expect(store.getState().userDeadline).toEqual(DEFAULT_DEADLINE_FROM_NOW)
      expect(store.getState().userSlippageTolerance).toEqual(INITIAL_ALLOWED_SLIPPAGE)
    })
  })
})
Example #9
Source File: persistEverything.ts    From nosgestesclimat-site with MIT License 6 votes vote down vote up
persistEverything = (options: OptionsType = {}) => (
	store: Store<RootState, Action>
): void => {
	const listener = () => {
		const state = store.getState()
		safeLocalStorage.setItem(
			LOCAL_STORAGE_KEY,
			JSON.stringify(omit(options.except || [], state))
		)
	}
	store.subscribe(debounce(1000, listener))
}
Example #10
Source File: configureStore.ts    From firebase-tools-ui with Apache License 2.0 6 votes vote down vote up
export default function configureStore(): Store<AppState> {
  const composeEnhancers =
    (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
  const sagaMiddleware = createSagaMiddleware();
  const store = createStore(
    rootReducer,
    composeEnhancers(applyMiddleware(sagaMiddleware))
  );
  sagaMiddleware.run(rootSaga);
  return store;
}
Example #11
Source File: PersistManager.ts    From foca with MIT License 6 votes vote down vote up
init(store: Store, hydrate: boolean) {
    this.unsubscrbeStore = store.subscribe(() => {
      this.initialized && this.update(store);
    });

    return Promise.all(this.list.map((item) => item.init())).then(() => {
      hydrate && store.dispatch(actionHydrate(this.collect()));
      this.initialized = true;
    });
  }
Example #12
Source File: reducer.test.ts    From glide-frontend with GNU General Public License v3.0 6 votes vote down vote up
describe('application reducer', () => {
  let store: Store<ApplicationState>

  beforeEach(() => {
    store = createStore(reducer, {
      blockNumber: {
        [ChainId.MAINNET]: 3,
      },
    })
  })

  describe('updateBlockNumber', () => {
    it('updates block number', () => {
      store.dispatch(updateBlockNumber({ chainId: ChainId.MAINNET, blockNumber: 4 }))
      expect(store.getState().blockNumber[ChainId.MAINNET]).toEqual(4)
    })
    it('no op if late', () => {
      store.dispatch(updateBlockNumber({ chainId: ChainId.MAINNET, blockNumber: 2 }))
      expect(store.getState().blockNumber[ChainId.MAINNET]).toEqual(3)
    })
    it('works with non-set chains', () => {
      store.dispatch(updateBlockNumber({ chainId: ChainId.TESTNET, blockNumber: 2 }))
      expect(store.getState().blockNumber).toEqual({
        [ChainId.MAINNET]: 3,
        [ChainId.TESTNET]: 2,
      })
    })
  })
})
Example #13
Source File: RawDataConverter.ts    From alchemist with MIT License 6 votes vote down vote up
public static replaceArrayBuffer(obj: ActionDescriptor[]|ActionDescriptor): ActionDescriptor[]|ActionDescriptor {
		const store:Store<CombinedState<{inspector: IInspectorState;}>, AnyAction> = (window as any)._rootStore;
		const settings = getInspectorSettings(store.getState());
		if (!settings.makeRawDataEasyToInspect) {
			return obj;
		}
		rec(obj);
		return obj;

		function rec(data:any) {
			for (const key in data) {
				if (Object.prototype.hasOwnProperty.call(data, key)) {
					if (Array.isArray(data)) {
						for (const item of data) {
							rec(item);
						}
					}
					else if (data[key] instanceof ArrayBuffer) {
						const uint = new Uint8Array(data[key]);
						const arr: number[] = Array.from(uint);

						if (settings.makeRawDataEasyToInspect) {
							data[key] = {
								"_rawData": "alchemistFakeType",
								"_data": arr,
							};							
						} else {
							data[key] = "<ArrayBuffer> This value was ignored for performance reasons. Turn this on in Alchemist > Settings > Support raw data type";
						}
					}
					else if (typeof data[key] === "object") {
						rec(data[key]);
					}
				}				
			}
		}
	}
Example #14
Source File: store.ts    From foodie with MIT License 6 votes vote down vote up
localStorageMiddleware = (store: Store) => {
    return (next: Dispatch<void>) => (action: any) => {
        const result = next(action);
        try {
            const { settings } = store.getState();
            localStorage.setItem('foodie_theme', JSON.stringify(settings.theme));
        } catch (e) {
            console.log('Error while saving in localStorage', e);
        }
        return result;
    };
}
Example #15
Source File: App.store.tsx    From tezos-academy with MIT License 6 votes vote down vote up
export function configureStore(preloadedState: any) {
  const composeEnhancer = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
    ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({ trace: true, traceLimit: 25 })
    : compose

  const store: Store<State> = offline(storeOfflineConfig)(createStore)(
    reducers(history) as any,
    preloadedState,
    composeEnhancer(
      applyMiddleware(routerMiddleware(history)),
      applyMiddleware(thunk),
      applyMiddleware(reduxOfflineThunkMiddleware()),
    ),
  )

  return store
}
Example #16
Source File: store.ts    From slice-machine with Apache License 2.0 6 votes vote down vote up
export default function configureStore(
  preloadedState: Partial<SliceMachineStoreType> = {}
): { store: Store<SliceMachineStoreType>; persistor: Persistor } {
  const middlewares = [sagaMiddleware, routerMiddleware];
  const enhancers = [applyMiddleware(...middlewares)];

  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
  const composeEnhancers =
    process.env.NODE_ENV !== "production" &&
    typeof window === "object" &&
    window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
      ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
      : compose;

  const rootReducer = createReducer();

  const persistedReducer = persistReducer(persistConfig, rootReducer);
  const store: Store<SliceMachineStoreType> = createStore(
    persistedReducer,
    preloadedState,
    // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-call
    composeEnhancers(...enhancers)
  );
  const persistor = persistStore(store);
  sagaMiddleware.run(rootSaga);

  return { store, persistor };
}
Example #17
Source File: events.ts    From Protoman with MIT License 6 votes vote down vote up
function setupListenersWithStore(ipcRenderer: IpcRenderer, store: Store): void {
  ipcRenderer.on(ipcChannels.IMPORT_SUCCESS, (event, [data]) => {
    const obj = JSON.parse(new TextDecoder().decode(data));
    const col = validateCollection(obj);
    if (col) {
      store.dispatch(importCollection(col));
      message.success('Import Success: Make sure the protofile paths are valid');
    } else {
      message.error('Import Error: Invalid collection format');
    }
  });
}
Example #18
Source File: storage.tsx    From reactant with MIT License 6 votes vote down vote up
afterCreateStore(store: Store) {
    const { replaceReducer } = store;
    // eslint-disable-next-line no-param-reassign
    store.replaceReducer = (reducer: Reducer) => {
      replaceReducer(reducer);
      this.persistor = persistStore(store, null, () => {
        // TODO: check
        this.rehydrated = true;
        this.onRehydrate?.();
      });
    };
    this.persistor = persistStore(store, null, () => {
      this.rehydrated = true;
      this.onRehydrate?.();
    });
  }
Example #19
Source File: KliveStore.ts    From kliveide with MIT License 5 votes vote down vote up
/**
   * Initializes this instance with the specified redux store
   * @param store
   */
  constructor(public readonly store: Store) {
    this._prevState = store.getState();
    this._unsubscribe = store.subscribe(() => this.processStateChanges());
  }
Example #20
Source File: store.ts    From Tiquet with MIT License 5 votes vote down vote up
store: Store = createStore(rootReducer, composeWithDevTools(applyMiddleware(thunk)))
Example #21
Source File: createApp.tsx    From redux-with-domain with MIT License 5 votes vote down vote up
_store: Store
Example #22
Source File: reducer.test.ts    From interface-v2 with GNU General Public License v3.0 5 votes vote down vote up
describe('mint reducer', () => {
  let store: Store<MintState>;

  beforeEach(() => {
    store = createStore(reducer, {
      independentField: Field.CURRENCY_A,
      typedValue: '',
      otherTypedValue: '',
    });
  });

  describe('typeInput', () => {
    it('sets typed value', () => {
      store.dispatch(
        typeInput({
          field: Field.CURRENCY_A,
          typedValue: '1.0',
          noLiquidity: false,
        }),
      );
      expect(store.getState()).toEqual({
        independentField: Field.CURRENCY_A,
        typedValue: '1.0',
        otherTypedValue: '',
      });
    });
    it('clears other value', () => {
      store.dispatch(
        typeInput({
          field: Field.CURRENCY_A,
          typedValue: '1.0',
          noLiquidity: false,
        }),
      );
      store.dispatch(
        typeInput({
          field: Field.CURRENCY_B,
          typedValue: '1.0',
          noLiquidity: false,
        }),
      );
      expect(store.getState()).toEqual({
        independentField: Field.CURRENCY_B,
        typedValue: '1.0',
        otherTypedValue: '',
      });
    });
  });
});
Example #23
Source File: ws-middleware.ts    From react-spring-messenger-project with MIT License 5 votes vote down vote up
function initWsAndSubscribe(wsClient: Client, store: Store, reduxModel: ReduxModel) {
    const wsUserTokenValue = reduxModel.userToken;
    const userId = reduxModel.userId;
    if (wsClient) {
        wsClient.onConnect = () => {
            store.dispatch(store.dispatch(wsHealthCheckConnected(true)))
            mainSubscribe = wsClient.subscribe(`/topic/user/${userId}`, (res: IMessage) => {
                const data: OutputTransportDTO = JSON.parse(res.body);
                switch (data.action) {
                    case TransportActionEnum.INIT_USER_DATA:
                        store.dispatch(setWsUserGroups(data.object as GroupModel[]))
                        break;
                    case TransportActionEnum.FETCH_GROUP_MESSAGES:
                        const result = data.object as WrapperMessageModel
                        store.dispatch(setGroupMessages(result.messages))
                        store.dispatch(setAllMessagesFetched(result.lastMessage))
                        break;
                    case TransportActionEnum.ADD_CHAT_HISTORY:
                        const wrapper = data.object as WrapperMessageModel
                        store.dispatch(setAllMessagesFetched(wrapper.lastMessage))
                        const newMessages = wrapper.messages
                        const currentMessages: FullMessageModel[] = store.getState().WebSocketReducer.chatHistory;
                        store.dispatch(setGroupMessages(newMessages.concat(currentMessages)))
                        break;
                    case TransportActionEnum.SEND_GROUP_MESSAGE:
                        break;
                    case TransportActionEnum.NOTIFICATION_MESSAGE:
                        const message = data.object as FullMessageModel;
                        store.dispatch(setCurrentActiveGroup(message.groupUrl));
                        updateGroupsWithLastMessageSent(store, message, userId || 0);
                        store.dispatch(addChatHistory(message))
                        if (message.userId !== userId) {
                            playNotificationSound();
                        }
                        break;
                    default:
                        break;
                }
            });
            publishWs(wsClient, new TransportModel(userId || 0, TransportActionEnum.INIT_USER_DATA, wsUserTokenValue));
        }

        wsClient.onWebSocketClose = () => {
            console.log("ERROR DURING HANDSHAKE WITH SERVER")
            store.dispatch(wsHealthCheckConnected(false))
        }
        wsClient.activate();
    }
}
Example #24
Source File: reducer.test.ts    From sybil-interface with GNU General Public License v3.0 5 votes vote down vote up
describe('application reducer', () => {
  let store: Store<ApplicationState>

  beforeEach(() => {
    store = createStore(reducer, {
      popupList: [],
      blockNumber: {
        [ChainId.MAINNET]: 3,
      },
      openModal: null,
      modalDelegatee: null,
    })
  })

  describe('addPopup', () => {
    it('adds the popup to list with a generated id', () => {
      store.dispatch(addPopup({ content: { txn: { hash: 'abc', summary: 'test', success: true } } }))
      const list = store.getState().popupList
      expect(list).toHaveLength(1)
      expect(typeof list[0].key).toEqual('string')
      expect(list[0].show).toEqual(true)
      expect(list[0].content).toEqual({ txn: { hash: 'abc', summary: 'test', success: true } })
      expect(list[0].removeAfterMs).toEqual(15000)
    })

    it('replaces any existing popups with the same key', () => {
      store.dispatch(addPopup({ key: 'abc', content: { txn: { hash: 'abc', summary: 'test', success: true } } }))
      store.dispatch(addPopup({ key: 'abc', content: { txn: { hash: 'def', summary: 'test2', success: false } } }))
      const list = store.getState().popupList
      expect(list).toHaveLength(1)
      expect(list[0].key).toEqual('abc')
      expect(list[0].show).toEqual(true)
      expect(list[0].content).toEqual({ txn: { hash: 'def', summary: 'test2', success: false } })
      expect(list[0].removeAfterMs).toEqual(15000)
    })
  })

  describe('setOpenModal', () => {
    it('set wallet modal', () => {
      store.dispatch(setOpenModal(ApplicationModal.WALLET))
      expect(store.getState().openModal).toEqual(ApplicationModal.WALLET)
      store.dispatch(setOpenModal(ApplicationModal.WALLET))
      expect(store.getState().openModal).toEqual(ApplicationModal.WALLET)
      store.dispatch(setOpenModal(null))
      expect(store.getState().openModal).toEqual(null)
    })
  })

  describe('updateBlockNumber', () => {
    it('updates block number', () => {
      store.dispatch(updateBlockNumber({ chainId: ChainId.MAINNET, blockNumber: 4 }))
      expect(store.getState().blockNumber[ChainId.MAINNET]).toEqual(4)
    })
    it('no op if late', () => {
      store.dispatch(updateBlockNumber({ chainId: ChainId.MAINNET, blockNumber: 2 }))
      expect(store.getState().blockNumber[ChainId.MAINNET]).toEqual(3)
    })
    it('works with non-set chains', () => {
      store.dispatch(updateBlockNumber({ chainId: ChainId.ROPSTEN, blockNumber: 2 }))
      expect(store.getState().blockNumber).toEqual({
        [ChainId.MAINNET]: 3,
        [ChainId.ROPSTEN]: 2,
      })
    })
  })

  describe('removePopup', () => {
    beforeEach(() => {
      store.dispatch(addPopup({ key: 'abc', content: { txn: { hash: 'abc', summary: 'test', success: true } } }))
    })
    it('hides the popup', () => {
      expect(store.getState().popupList[0].show).toBe(true)
      store.dispatch(removePopup({ key: 'abc' }))
      expect(store.getState().popupList).toHaveLength(1)
      expect(store.getState().popupList[0].show).toBe(false)
    })
  })
})
Example #25
Source File: store.ts    From animation-editor with MIT License 5 votes vote down vote up
storeInstance: Store<ApplicationState> = createStore(reducers, initialState)
Example #26
Source File: DiagramMaker.ts    From diagram-maker with Apache License 2.0 5 votes vote down vote up
/**
   * DiagramMaker store.
   * Currently used for dispatching, fetching state & listening to updates.
   * Will be moved to API and closed out.
   */
  public readonly store: Store<DiagramMakerData<NodeType, EdgeType>>;
Example #27
Source File: SamplesListGallery.spec.tsx    From che-dashboard-next with Eclipse Public License 2.0 5 votes vote down vote up
function createFakeStoreWithoutMetadata(): Store {
  return createFakeStore();
}
Example #28
Source File: server.ts    From clearflask with Apache License 2.0 5 votes vote down vote up
static async _dispatch(msg: any, store: Store<any, any>, storeOther?: Store<any, any>): Promise<any> {
    try {
      var result = await store.dispatch(msg);
      if (storeOther) await storeOther.dispatch(msg);
    } catch (response) {
      if (!isProd()) {
        console.trace("Dispatch error: ", msg, response);
      }
      try {
        if (response && response.status === 429 && response.headers && response.headers.has && response.headers.has('x-cf-challenge')) {
          const challengeSubscriber = Object.values(challengeSubscribers)[0];
          if (!challengeSubscriber) {
            Object.values(errorSubscribers).forEach(subscriber => subscriber && subscriber("Failed to show captcha challenge", true));
            throw response;
          }
          var solution: string | undefined = await challengeSubscriber(response.headers.get('x-cf-challenge'));
          if (solution) {
            return msg.meta.retry({ 'x-cf-solution': solution });
          }
        }
        var errorMsg: string = '';
        var isUserFacing = false;
        if (response && response.json) {
          try {
            var body = await response.json();
            if (body && body.userFacingMessage) {
              errorMsg = body.userFacingMessage;
              isUserFacing = true;
            }
          } catch (err) {
          }
        }
        var action = msg && msg.meta && msg.meta.action || 'unknown action';
        if (errorMsg && isUserFacing) {
          // errorMsg already set above
        } else if (response.status && response.status === 403) {
          errorMsg = `Action not allowed`;
          isUserFacing = true;
          ServerAdmin.get().onForbidenAttemptRebind();
        } else if (response.status && response.status >= 100 && response.status < 300) {
          errorMsg = `${response.status} failed ${action}`;
        } else if (response.status && response.status >= 300 && response.status < 600) {
          errorMsg = `${response.status} failed ${action}`;
          isUserFacing = true;
        } else {
          errorMsg = `Connection failure processing ${action}`;
          isUserFacing = true;
        }
        Object.values(errorSubscribers).forEach(subscriber => subscriber && subscriber(errorMsg, isUserFacing));
      } catch (err) {
        console.log("Error dispatching error: ", err);
        Object.values(errorSubscribers).forEach(subscriber => subscriber && subscriber("Unknown error occurred, please try again", true));
      }
      throw response;
    }
    return result.value;
  }
Example #29
Source File: reducer.test.ts    From dyp with Do What The F*ck You Want To Public License 5 votes vote down vote up
describe('application reducer', () => {
  let store: Store<ApplicationState>

  beforeEach(() => {
    store = createStore(reducer, {
      popupList: [],
      blockNumber: {
        [ChainId.MAINNET]: 3
      },
      openModal: null
    })
  })

  describe('addPopup', () => {
    it('adds the popup to list with a generated id', () => {
      store.dispatch(addPopup({ content: { txn: { hash: 'abc', summary: 'test', success: true } } }))
      const list = store.getState().popupList
      expect(list).toHaveLength(1)
      expect(typeof list[0].key).toEqual('string')
      expect(list[0].show).toEqual(true)
      expect(list[0].content).toEqual({ txn: { hash: 'abc', summary: 'test', success: true } })
      expect(list[0].removeAfterMs).toEqual(15000)
    })

    it('replaces any existing popups with the same key', () => {
      store.dispatch(addPopup({ key: 'abc', content: { txn: { hash: 'abc', summary: 'test', success: true } } }))
      store.dispatch(addPopup({ key: 'abc', content: { txn: { hash: 'def', summary: 'test2', success: false } } }))
      const list = store.getState().popupList
      expect(list).toHaveLength(1)
      expect(list[0].key).toEqual('abc')
      expect(list[0].show).toEqual(true)
      expect(list[0].content).toEqual({ txn: { hash: 'def', summary: 'test2', success: false } })
      expect(list[0].removeAfterMs).toEqual(15000)
    })
  })

  describe('setOpenModal', () => {
    it('set wallet modal', () => {
      store.dispatch(setOpenModal(ApplicationModal.WALLET))
      expect(store.getState().openModal).toEqual(ApplicationModal.WALLET)
      store.dispatch(setOpenModal(ApplicationModal.WALLET))
      expect(store.getState().openModal).toEqual(ApplicationModal.WALLET)
      store.dispatch(setOpenModal(ApplicationModal.CLAIM_POPUP))
      expect(store.getState().openModal).toEqual(ApplicationModal.CLAIM_POPUP)
      store.dispatch(setOpenModal(null))
      expect(store.getState().openModal).toEqual(null)
    })
  })

  describe('updateBlockNumber', () => {
    it('updates block number', () => {
      store.dispatch(updateBlockNumber({ chainId: ChainId.MAINNET, blockNumber: 4 }))
      expect(store.getState().blockNumber[ChainId.MAINNET]).toEqual(4)
    })
    it('no op if late', () => {
      store.dispatch(updateBlockNumber({ chainId: ChainId.MAINNET, blockNumber: 2 }))
      expect(store.getState().blockNumber[ChainId.MAINNET]).toEqual(3)
    })
    it('works with non-set chains', () => {
      store.dispatch(updateBlockNumber({ chainId: ChainId.ROPSTEN, blockNumber: 2 }))
      expect(store.getState().blockNumber).toEqual({
        [ChainId.MAINNET]: 3,
        [ChainId.ROPSTEN]: 2
      })
    })
  })

  describe('removePopup', () => {
    beforeEach(() => {
      store.dispatch(addPopup({ key: 'abc', content: { txn: { hash: 'abc', summary: 'test', success: true } } }))
    })
    it('hides the popup', () => {
      expect(store.getState().popupList[0].show).toBe(true)
      store.dispatch(removePopup({ key: 'abc' }))
      expect(store.getState().popupList).toHaveLength(1)
      expect(store.getState().popupList[0].show).toBe(false)
    })
  })
})