diff --git a/apps/block_scout_web/assets/__tests__/lib/async_listing_load.js b/apps/block_scout_web/assets/__tests__/lib/async_listing_load.js new file mode 100644 index 0000000000..6e86d8a6b5 --- /dev/null +++ b/apps/block_scout_web/assets/__tests__/lib/async_listing_load.js @@ -0,0 +1,80 @@ +import { asyncReducer, asyncInitialState } from '../../js/lib/async_listing_load' + +describe('ELEMENTS_LOAD', () => { + test('sets only nextPagePath and ignores other keys', () => { + const state = Object.assign({}, asyncInitialState) + const action = { type: 'ELEMENTS_LOAD', nextPagePath: 'set', foo: 1 } + const output = asyncReducer(state, action) + + expect(output.foo).not.toEqual(1) + expect(output.nextPagePath).toEqual('set') + }) +}) + +describe('ADD_ITEM_KEY', () => { + test('sets itemKey to what was passed in the action', () => { + const expectedItemKey = 'expected.Key' + + const state = Object.assign({}, asyncInitialState) + const action = { type: 'ADD_ITEM_KEY', itemKey: expectedItemKey } + const output = asyncReducer(state, action) + + expect(output.itemKey).toEqual(expectedItemKey) + }) +}) + +describe('START_REQUEST', () => { + test('sets loading status to true', () => { + const state = Object.assign({}, asyncInitialState, { loading: false }) + const action = { type: 'START_REQUEST' } + const output = asyncReducer(state, action) + + expect(output.loading).toEqual(true) + }) +}) + +describe('REQUEST_ERROR', () => { + test('sets requestError to true', () => { + const state = Object.assign({}, asyncInitialState, { requestError: false }) + const action = { type: 'REQUEST_ERROR' } + const output = asyncReducer(state, action) + + expect(output.requestError).toEqual(true) + }) +}) + +describe('FINISH_REQUEST', () => { + test('sets loading status to false', () => { + const state = Object.assign({}, asyncInitialState, { + loading: true, + loadingFirstPage: true + }) + const action = { type: 'FINISH_REQUEST' } + const output = asyncReducer(state, action) + + expect(output.loading).toEqual(false) + expect(output.loadingFirstPage).toEqual(false) + }) +}) + +describe('ITEMS_FETCHED', () => { + test('sets the items to what was passed in the action', () => { + const expectedItems = [1, 2, 3] + + const state = Object.assign({}, asyncInitialState) + const action = { type: 'ITEMS_FETCHED', items: expectedItems } + const output = asyncReducer(state, action) + + expect(output.items).toEqual(expectedItems) + }) +}) + +describe('NAVIGATE_TO_OLDER', () => { + test('sets beyondPageOne to true', () => { + const state = Object.assign({}, asyncInitialState, { beyondPageOne: false }) + const action = { type: 'NAVIGATE_TO_OLDER' } + const output = asyncReducer(state, action) + + expect(output.beyondPageOne).toEqual(true) + }) +}) diff --git a/apps/block_scout_web/assets/js/lib/async_listing_load.js b/apps/block_scout_web/assets/js/lib/async_listing_load.js index f2ffe5fdb7..2e9e4e371b 100644 --- a/apps/block_scout_web/assets/js/lib/async_listing_load.js +++ b/apps/block_scout_web/assets/js/lib/async_listing_load.js @@ -1,85 +1,223 @@ import $ from 'jquery' +import _ from 'lodash' +import URI from 'urijs' +import humps from 'humps' +import listMorph from '../lib/list_morph' +import reduceReducers from 'reduce-reducers' +import { createStore, connectElements } from '../lib/redux_helpers.js' + /** - * This script is a generic function to load list within a tab async. See token transfers tab at Token's page as example. + * This is a generic lib to add pagination with asynchronous page loading. There are two ways of + * activating this in a page. + * + * If the page has no redux associated with, all you need is a markup with the following pattern: + * + *