diff --git a/apps/block_scout_web/assets/__tests__/pages/address.js b/apps/block_scout_web/assets/__tests__/pages/address.js index 5e87b5b73d..035e415074 100644 --- a/apps/block_scout_web/assets/__tests__/pages/address.js +++ b/apps/block_scout_web/assets/__tests__/pages/address.js @@ -145,86 +145,36 @@ describe('RECEIVED_NEW_INTERNAL_TRANSACTION_BATCH', () => { }) describe('RECEIVED_NEW_TRANSACTION', () => { - test('with new transaction', () => { + test('increment the transactions count', () => { const state = Object.assign({}, initialState, { - transactions: [{ transactionHash: 1, transactionHtml: 'test 1' }] + addressHash: "0x001", + transactionCount: 1 }) - const action = { - type: 'RECEIVED_NEW_TRANSACTION', - msg: { transactionHash: 2, transactionHtml: 'test 2' } - } - const output = reducer(state, action) - expect(output.transactions).toEqual([ - { transactionHash: 2, transactionHtml: 'test 2' }, - { transactionHash: 1, transactionHtml: 'test 1' } - ]) - }) - test('when channel has been disconnected', () => { - const state = Object.assign({}, initialState, { - channelDisconnected: true, - transactions: [{ transactionHash: 1, transactionHtml: 'test 1' }] - }) const action = { type: 'RECEIVED_NEW_TRANSACTION', - msg: { transactionHash: 2, transactionHtml: 'test 2' } + msg: { fromAddressHash: "0x001", transactionHash: 2, transactionHtml: 'test 2' } } - const output = reducer(state, action) - expect(output.transactions).toEqual([ - { transactionHash: 1, transactionHtml: 'test 1' } - ]) - }) - test('beyond page one', () => { - const state = Object.assign({}, initialState, { - beyondPageOne: true, - transactions: [{ transactionHash: 1, transactionHtml: 'test 1' }] - }) - const action = { - type: 'RECEIVED_NEW_TRANSACTION', - msg: { transactionHash: 2, transactionHtml: 'test 2' } - } - const output = reducer(state, action) + const newState = reducer(state, action) - expect(output.transactions).toEqual([ - { transactionHash: 1, transactionHtml: 'test 1' } - ]) + expect(newState.transactionCount).toEqual(2) }) - test('with filtered out transaction', () => { + + test('does not increment the count if the channel is disconnected', () => { const state = Object.assign({}, initialState, { - filter: 'to' + addressHash: "0x001", + transactionCount: 1, + channelDisconnected: true }) + const action = { type: 'RECEIVED_NEW_TRANSACTION', - msg: { transactionHash: 2, transactionHtml: 'test 2' } + msg: { fromAddressHash: "0x001", transactionHash: 2, transactionHtml: 'test 2' } } - const output = reducer(state, action) - expect(output.transactions).toEqual([]) - }) -}) - -describe('RECEIVED_NEXT_PAGE', () => { - test('with new transaction page', () => { - const state = Object.assign({}, initialState, { - loadingNextPage: true, - nextPageUrl: '1', - transactions: [{ transactionHash: 1, transactionHtml: 'test 1' }] - }) - const action = { - type: 'RECEIVED_NEXT_PAGE', - msg: { - nextPageUrl: '2', - transactions: [{ transactionHash: 2, transactionHtml: 'test 2' }] - } - } - const output = reducer(state, action) + const newState = reducer(state, action) - expect(output.loadingNextPage).toEqual(false) - expect(output.nextPageUrl).toEqual('2') - expect(output.transactions).toEqual([ - { transactionHash: 1, transactionHtml: 'test 1' }, - { transactionHash: 2, transactionHtml: 'test 2' } - ]) + expect(newState.transactionCount).toEqual(1) }) }) diff --git a/apps/block_scout_web/assets/__tests__/pages/address/transactions.js b/apps/block_scout_web/assets/__tests__/pages/address/transactions.js new file mode 100644 index 0000000000..c4676cd6a2 --- /dev/null +++ b/apps/block_scout_web/assets/__tests__/pages/address/transactions.js @@ -0,0 +1,124 @@ +import { reducer, initialState } from '../../../js/pages/address/transactions' + +describe('RECEIVED_NEW_TRANSACTION', () => { + test('with new transaction', () => { + const state = Object.assign({}, initialState, { + items: ['transaction html'] + }) + const action = { + type: 'RECEIVED_NEW_TRANSACTION', + msg: { transactionHtml: 'another transaction html' } + } + const output = reducer(state, action) + + expect(output.items).toEqual([ 'another transaction html', 'transaction html' ]) + }) + + test('when channel has been disconnected', () => { + const state = Object.assign({}, initialState, { + channelDisconnected: true, + items: ['transaction html'] + }) + const action = { + type: 'RECEIVED_NEW_TRANSACTION', + msg: { transactionHtml: 'another transaction html' } + } + const output = reducer(state, action) + + expect(output.items).toEqual(['transaction html']) + }) + + test('beyond page one', () => { + const state = Object.assign({}, initialState, { + beyondPageOne: true, + items: ['transaction html'] + }) + const action = { + type: 'RECEIVED_NEW_TRANSACTION', + msg: { transactionHtml: 'another transaction html' } + } + const output = reducer(state, action) + + expect(output.items).toEqual([ 'transaction html' ]) + }) + + test('adds the new transaction to state even when it is filtered by to', () => { + const state = Object.assign({}, initialState, { + addressHash: '0x001', + filter: 'to', + items: [] + }) + const action = { + type: 'RECEIVED_NEW_TRANSACTION', + msg: { + fromAddressHash: '0x002', + transactionHtml: 'transaction html', + toAddressHash: '0x001' + } + } + const output = reducer(state, action) + + expect(output.items).toEqual(['transaction html']) + }) + + test( + 'does nothing when it is filtered by to but the toAddressHash is different from addressHash', + () => { + const state = Object.assign({}, initialState, { + addressHash: '0x001', + filter: 'to', + items: [] + }) + const action = { + type: 'RECEIVED_NEW_TRANSACTION', + msg: { + fromAddressHash: '0x003', + transactionHtml: 'transaction html', + toAddressHash: '0x002' + } + } + const output = reducer(state, action) + + expect(output.items).toEqual([]) + }) + + test('adds the new transaction to state even when it is filtered by from', () => { + const state = Object.assign({}, initialState, { + addressHash: '0x001', + filter: 'from', + items: [] + }) + const action = { + type: 'RECEIVED_NEW_TRANSACTION', + msg: { + fromAddressHash: '0x001', + transactionHtml: 'transaction html', + toAddressHash: '0x002' + } + } + const output = reducer(state, action) + + expect(output.items).toEqual(['transaction html']) + }) + + test( + 'does nothing when it is filtered by from but the fromAddressHash is different from addressHash', + () => { + const state = Object.assign({}, initialState, { + addressHash: '0x001', + filter: 'to', + items: [] + }) + const action = { + type: 'RECEIVED_NEW_TRANSACTION', + msg: { + addressHash: '0x001', + transactionHtml: 'transaction html', + fromAddressHash: '0x002' + } + } + const output = reducer(state, action) + + expect(output.items).toEqual([]) + }) +}) diff --git a/apps/block_scout_web/assets/js/app.js b/apps/block_scout_web/assets/js/app.js index e1fcc24b45..30430547cb 100644 --- a/apps/block_scout_web/assets/js/app.js +++ b/apps/block_scout_web/assets/js/app.js @@ -21,6 +21,7 @@ import 'bootstrap' import './locale' import './pages/address' +import './pages/address/transactions' import './pages/address/validations' import './pages/blocks' import './pages/chain' diff --git a/apps/block_scout_web/assets/js/pages/address.js b/apps/block_scout_web/assets/js/pages/address.js index ce790e04b5..615cefc394 100644 --- a/apps/block_scout_web/assets/js/pages/address.js +++ b/apps/block_scout_web/assets/js/pages/address.js @@ -6,7 +6,6 @@ import numeral from 'numeral' import socket from '../socket' import { createStore, connectElements } from '../lib/redux_helpers.js' import { batchChannel } from '../lib/utils' -import { withInfiniteScroll, connectInfiniteScroll } from '../lib/infinite_scroll_helpers' import listMorph from '../lib/list_morph' import { updateAllCalculatedUsdValues } from '../lib/currency.js' import { loadTokenBalanceDropdown } from '../lib/token_balance_dropdown' @@ -23,18 +22,13 @@ export const initialState = { transactionCount: null, validationCount: null, - transactions: [], internalTransactions: [], internalTransactionsBatch: [], - - beyondPageOne: null, - - nextPageUrl: $('[data-selector="transactions-list"]').length ? URI(window.location).addQuery({ type: 'JSON' }).toString() : null + validatedBlocks: [], + beyondPageOne: false } -export const reducer = withInfiniteScroll(baseReducer) - -function baseReducer (state = initialState, action) { +export function reducer (state = initialState, action) { switch (action.type) { case 'PAGE_LOAD': case 'ELEMENTS_LOAD': { @@ -85,33 +79,13 @@ function baseReducer (state = initialState, action) { const transactionCount = (action.msg.fromAddressHash === state.addressHash) ? state.transactionCount + 1 : state.transactionCount - if (state.beyondPageOne || - (state.filter === 'to' && action.msg.toAddressHash !== state.addressHash) || - (state.filter === 'from' && action.msg.fromAddressHash !== state.addressHash)) { - return Object.assign({}, state, { transactionCount }) - } - - return Object.assign({}, state, { - transactions: [ - action.msg, - ...state.transactions - ], - transactionCount: transactionCount - }) + return Object.assign({}, state, { transactionCount }) } case 'RECEIVED_UPDATED_BALANCE': { return Object.assign({}, state, { balance: action.msg.balance }) } - case 'RECEIVED_NEXT_PAGE': { - return Object.assign({}, state, { - transactions: [ - ...state.transactions, - ...action.msg.transactions - ] - }) - } default: return state } @@ -152,32 +126,6 @@ const elements = { $el.empty().append(numeral(state.validationCount).format()) } }, - '[data-selector="empty-transactions-list"]': { - render ($el, state) { - if (state.transactions.length || state.loadingNextPage || state.pagingError) { - $el.hide() - } else { - $el.show() - } - } - }, - '[data-selector="transactions-list"]': { - load ($el) { - return { - transactions: $el.children().map((index, el) => ({ - transactionHash: el.dataset.transactionHash, - transactionHtml: el.outerHTML - })).toArray() - } - }, - render ($el, state, oldState) { - if (oldState.transactions === state.transactions) return - - const container = $el[0] - const newElements = _.map(state.transactions, ({ transactionHtml }) => $(transactionHtml)[0]) - return listMorph(container, newElements, { key: 'dataset.transactionHash' }) - } - }, '[data-selector="internal-transactions-list"]': { load ($el) { return { @@ -215,7 +163,6 @@ if ($addressDetailsPage.length) { beyondPageOne: !!blockNumber }) connectElements({ store, elements }) - $('[data-selector="transactions-list"]').length && connectInfiniteScroll(store) const addressChannel = socket.channel(`addresses:${addressHash}`, {}) addressChannel.join() diff --git a/apps/block_scout_web/assets/js/pages/address/transactions.js b/apps/block_scout_web/assets/js/pages/address/transactions.js new file mode 100644 index 0000000000..5876b37874 --- /dev/null +++ b/apps/block_scout_web/assets/js/pages/address/transactions.js @@ -0,0 +1,73 @@ +import $ from 'jquery' +import _ from 'lodash' +import URI from 'urijs' +import humps from 'humps' +import socket from '../../socket' +import { connectElements } from '../../lib/redux_helpers.js' +import { createAsyncLoadStore } from '../../lib/async_listing_load' + +export const initialState = { + addressHash: null, + channelDisconnected: false, + filter: null +} + +export function reducer (state, action) { + switch (action.type) { + case 'PAGE_LOAD': + case 'ELEMENTS_LOAD': { + return Object.assign({}, state, _.omit(action, 'type')) + } + case 'CHANNEL_DISCONNECTED': { + if (state.beyondPageOne) return state + + return Object.assign({}, state, { channelDisconnected: true }) + } + case 'RECEIVED_NEW_TRANSACTION': { + if (state.channelDisconnected) return state + + if (state.beyondPageOne || + (state.filter === 'to' && action.msg.toAddressHash !== state.addressHash) || + (state.filter === 'from' && action.msg.fromAddressHash !== state.addressHash)) { + return state + } + + return Object.assign({}, state, { items: [ action.msg.transactionHtml, ...state.items ] }) + } + default: + return state + } +} + +const elements = { + '[data-selector="channel-disconnected-message"]': { + render ($el, state) { + if (state.channelDisconnected) $el.show() + } + } +} + +if ($('[data-page="address-transactions"]').length) { + const store = createAsyncLoadStore(reducer, initialState, 'dataset.transactionHash') + const addressHash = $('[data-page="address-details"]')[0].dataset.pageAddressHash + const { filter, blockNumber } = humps.camelizeKeys(URI(window.location).query(true)) + + connectElements({ store, elements }) + + store.dispatch({ + type: 'PAGE_LOAD', + addressHash, + filter, + beyondPageOne: !!blockNumber + }) + + const addressChannel = socket.channel(`addresses:${addressHash}`, {}) + addressChannel.join() + addressChannel.onError(() => store.dispatch({ type: 'CHANNEL_DISCONNECTED' })) + addressChannel.on('transaction', (msg) => { + store.dispatch({ + type: 'RECEIVED_NEW_TRANSACTION', + msg: humps.camelizeKeys(msg) + }) + }) +} diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_transaction_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_transaction_controller.ex index 9160d09db5..a195f271d6 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_transaction_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_transaction_controller.ex @@ -10,7 +10,6 @@ defmodule BlockScoutWeb.AddressTransactionController do alias BlockScoutWeb.TransactionView alias Explorer.{Chain, Market} - alias Explorer.Chain.Hash alias Explorer.ExchangeRates.Token alias Phoenix.View @@ -48,29 +47,21 @@ defmodule BlockScoutWeb.AddressTransactionController do conn, :index, address, - next_page_params + Map.delete(next_page_params, "type") ) end - json( - conn, - %{ - transactions: - Enum.map(transactions, fn transaction -> - %{ - transaction_hash: Hash.to_string(transaction.hash), - transaction_html: - View.render_to_string( - TransactionView, - "_tile.html", - current_address: address, - transaction: transaction - ) - } - end), - next_page_url: next_page_url - } - ) + transactions_json = + Enum.map(transactions, fn transaction -> + View.render_to_string( + TransactionView, + "_tile.html", + current_address: address, + transaction: transaction + ) + end) + + json(conn, %{items: transactions_json, next_page_path: next_page_url}) else :error -> unprocessable_entity(conn) @@ -90,7 +81,8 @@ defmodule BlockScoutWeb.AddressTransactionController do exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(), filter: params["filter"], transaction_count: transaction_count(address), - validation_count: validation_count(address) + validation_count: validation_count(address), + current_path: current_path(conn) ) else :error -> diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address_transaction/index.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address_transaction/index.html.eex index bee040c7e9..4122e3375e 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address_transaction/index.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address_transaction/index.html.eex @@ -2,13 +2,13 @@ <%= render BlockScoutWeb.AddressView, "overview.html", assigns %> -
+
<%= render BlockScoutWeb.AddressView, "_tabs.html", assigns %>
-
+

<%= gettext "Transactions" %>

- - -
+ + +
+
+ <%= gettext "There are no transactions for this address." %> +
+
+ +
<%= gettext("Loading") %>...
- -
diff --git a/apps/block_scout_web/priv/gettext/default.pot b/apps/block_scout_web/priv/gettext/default.pot index 0687a0e605..08589e1422 100644 --- a/apps/block_scout_web/priv/gettext/default.pot +++ b/apps/block_scout_web/priv/gettext/default.pot @@ -639,6 +639,7 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:76 #: lib/block_scout_web/templates/address_token_transfer/index.html.eex:31 +#: lib/block_scout_web/templates/address_transaction/index.html.eex:75 #: lib/block_scout_web/templates/address_validation/index.html.eex:126 #: lib/block_scout_web/templates/block/index.html.eex:30 #: lib/block_scout_web/templates/block_transaction/index.html.eex:50 @@ -851,7 +852,7 @@ msgid "There are no tokens." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_transaction/index.html.eex:67 +#: lib/block_scout_web/templates/address_transaction/index.html.eex:60 msgid "There are no transactions for this address." msgstr "" @@ -1220,7 +1221,8 @@ msgstr "" #: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:72 #: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:83 #: lib/block_scout_web/templates/address_token_transfer/index.html.eex:38 -#: lib/block_scout_web/templates/address_transaction/index.html.eex:61 +#: lib/block_scout_web/templates/address_transaction/index.html.eex:69 +#: lib/block_scout_web/templates/address_transaction/index.html.eex:83 #: lib/block_scout_web/templates/block/index.html.eex:22 #: lib/block_scout_web/templates/pending_transaction/index.html.eex:33 #: lib/block_scout_web/templates/tokens/holder/index.html.eex:37 @@ -1251,11 +1253,6 @@ msgstr "" msgid "Show Raw Input" msgstr "" -#, elixir-format -#: lib/block_scout_web/templates/address_transaction/index.html.eex:64 -msgid "Error trying to fetch transactions." -msgstr "" - #, elixir-format #: lib/block_scout_web/templates/block_transaction/404.html.eex:7 msgid "Block Details" @@ -1419,6 +1416,7 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:60 #: lib/block_scout_web/templates/address_token_transfer/index.html.eex:26 +#: lib/block_scout_web/templates/address_transaction/index.html.eex:55 #: lib/block_scout_web/templates/address_validation/index.html.eex:121 #: lib/block_scout_web/templates/tokens/holder/index.html.eex:23 #: lib/block_scout_web/templates/tokens/transfer/index.html.eex:21 diff --git a/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po b/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po index f16f8735bb..ac23bbfdbc 100644 --- a/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po +++ b/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po @@ -639,6 +639,7 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:76 #: lib/block_scout_web/templates/address_token_transfer/index.html.eex:31 +#: lib/block_scout_web/templates/address_transaction/index.html.eex:75 #: lib/block_scout_web/templates/address_validation/index.html.eex:126 #: lib/block_scout_web/templates/block/index.html.eex:30 #: lib/block_scout_web/templates/block_transaction/index.html.eex:50 @@ -851,7 +852,7 @@ msgid "There are no tokens." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_transaction/index.html.eex:67 +#: lib/block_scout_web/templates/address_transaction/index.html.eex:60 msgid "There are no transactions for this address." msgstr "" @@ -1220,7 +1221,8 @@ msgstr "" #: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:72 #: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:83 #: lib/block_scout_web/templates/address_token_transfer/index.html.eex:38 -#: lib/block_scout_web/templates/address_transaction/index.html.eex:61 +#: lib/block_scout_web/templates/address_transaction/index.html.eex:69 +#: lib/block_scout_web/templates/address_transaction/index.html.eex:83 #: lib/block_scout_web/templates/block/index.html.eex:22 #: lib/block_scout_web/templates/pending_transaction/index.html.eex:33 #: lib/block_scout_web/templates/tokens/holder/index.html.eex:37 @@ -1251,11 +1253,6 @@ msgstr "" msgid "Show Raw Input" msgstr "" -#, elixir-format -#: lib/block_scout_web/templates/address_transaction/index.html.eex:64 -msgid "Error trying to fetch transactions." -msgstr "" - #, elixir-format #: lib/block_scout_web/templates/block_transaction/404.html.eex:7 msgid "Block Details" @@ -1419,6 +1416,7 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:60 #: lib/block_scout_web/templates/address_token_transfer/index.html.eex:26 +#: lib/block_scout_web/templates/address_transaction/index.html.eex:55 #: lib/block_scout_web/templates/address_validation/index.html.eex:121 #: lib/block_scout_web/templates/tokens/holder/index.html.eex:23 #: lib/block_scout_web/templates/tokens/transfer/index.html.eex:21 diff --git a/apps/block_scout_web/test/block_scout_web/controllers/address_transaction_controller_test.exs b/apps/block_scout_web/test/block_scout_web/controllers/address_transaction_controller_test.exs index 9c4704d2e3..2d5b72f154 100644 --- a/apps/block_scout_web/test/block_scout_web/controllers/address_transaction_controller_test.exs +++ b/apps/block_scout_web/test/block_scout_web/controllers/address_transaction_controller_test.exs @@ -34,15 +34,14 @@ defmodule BlockScoutWeb.AddressTransactionControllerTest do |> insert(to_address: address) |> with_block(block) - conn = get(conn, address_transaction_path(conn, :index, address), %{"type" => "JSON"}) - - {:ok, %{"transactions" => transactions}} = conn.resp_body |> Poison.decode() + conn = get(conn, address_transaction_path(conn, :index, address, %{"type" => "JSON"})) - actual_transaction_hashes = Enum.map(transactions, & &1["transaction_hash"]) + transaction_tiles = json_response(conn, 200)["items"] + transaction_hashes = Enum.map([to_transaction.hash, from_transaction.hash], &to_string(&1)) - assert json_response(conn, 200) - assert Enum.member?(actual_transaction_hashes, to_string(from_transaction.hash)) - assert Enum.member?(actual_transaction_hashes, to_string(to_transaction.hash)) + assert Enum.all?(transaction_hashes, fn transaction_hash -> + Enum.any?(transaction_tiles, &String.contains?(&1, transaction_hash)) + end) end test "includes USD exchange rate value for address in assigns", %{conn: conn} do @@ -60,7 +59,7 @@ defmodule BlockScoutWeb.AddressTransactionControllerTest do 50 |> insert_list(:transaction, from_address: address) |> with_block() - |> Enum.map(&to_string(&1.hash)) + |> Enum.map(& &1.hash) %Transaction{block_number: block_number, index: index} = :transaction @@ -69,19 +68,16 @@ defmodule BlockScoutWeb.AddressTransactionControllerTest do conn = get(conn, address_transaction_path(BlockScoutWeb.Endpoint, :index, address.hash), %{ - "type" => "JSON", "block_number" => Integer.to_string(block_number), - "index" => Integer.to_string(index) + "index" => Integer.to_string(index), + "type" => "JSON" }) - {:ok, %{"transactions" => transactions}} = conn.resp_body |> Poison.decode() + transaction_tiles = json_response(conn, 200)["items"] - actual_hashes = - transactions - |> Enum.map(& &1["transaction_hash"]) - |> Enum.reverse() - - assert second_page_hashes == actual_hashes + assert Enum.all?(second_page_hashes, fn address_hash -> + Enum.any?(transaction_tiles, &String.contains?(&1, to_string(address_hash))) + end) end test "next_page_params exist if not on last page", %{conn: conn} do @@ -92,18 +88,9 @@ defmodule BlockScoutWeb.AddressTransactionControllerTest do |> insert_list(:transaction, from_address: address) |> with_block(block) - conn = get(conn, address_transaction_path(BlockScoutWeb.Endpoint, :index, address.hash), %{"type" => "JSON"}) - - {:ok, %{"next_page_url" => actual_next_page_url}} = conn.resp_body |> Poison.decode() + conn = get(conn, address_transaction_path(conn, :index, address.hash, %{"type" => "JSON"})) - expected_next_page_url = - address_transaction_path(BlockScoutWeb.Endpoint, :index, address.hash, %{ - "block_number" => number, - "index" => 10, - "type" => "JSON" - }) - - assert expected_next_page_url == actual_next_page_url + assert json_response(conn, 200)["next_page_path"] end test "next_page_params are empty if on last page", %{conn: conn} do @@ -113,11 +100,9 @@ defmodule BlockScoutWeb.AddressTransactionControllerTest do |> insert(from_address: address) |> with_block() - conn = get(conn, address_transaction_path(BlockScoutWeb.Endpoint, :index, address.hash), %{"type" => "JSON"}) + conn = get(conn, address_transaction_path(conn, :index, address.hash, %{"type" => "JSON"})) - {:ok, %{"next_page_url" => next_page_url}} = conn.resp_body |> Poison.decode() - - refute next_page_url + refute json_response(conn, 200)["next_page_path"] end test "returns parent transaction for a contract address", %{conn: conn} do @@ -140,11 +125,11 @@ defmodule BlockScoutWeb.AddressTransactionControllerTest do conn = get(conn, address_transaction_path(conn, :index, address), %{"type" => "JSON"}) - {:ok, %{"transactions" => transactions}} = conn.resp_body |> Poison.decode() - - transaction_hashes = Enum.map(transactions, & &1["transaction_hash"]) + transaction_tiles = json_response(conn, 200)["items"] - assert [to_string(transaction.hash)] == transaction_hashes + assert Enum.all?([transaction.hash], fn transaction_hash -> + Enum.any?(transaction_tiles, &String.contains?(&1, to_string(transaction_hash))) + end) end end end