parent
0a80f12985
commit
a55c602836
@ -1,300 +1,327 @@ |
|||||||
import { reducer, initialState } from '../../js/pages/address' |
import { reducer, initialState } from '../../js/pages/address' |
||||||
|
|
||||||
describe('PAGE_LOAD', () => { |
describe('RECEIVED_NEW_BLOCK', () => { |
||||||
test('page 1 without filter', () => { |
test('with new block', () => { |
||||||
const state = initialState |
const state = Object.assign({}, initialState, { |
||||||
const action = { |
validationCount: 30, |
||||||
type: 'PAGE_LOAD', |
validatedBlocks: [{ blockNumber: 1, blockHtml: 'test 1' }] |
||||||
addressHash: '1234', |
|
||||||
beyondPageOne: false, |
|
||||||
pendingTransactionHashes: ['1'] |
|
||||||
} |
|
||||||
const output = reducer(state, action) |
|
||||||
|
|
||||||
expect(output.addressHash).toBe('1234') |
|
||||||
expect(output.beyondPageOne).toBe(false) |
|
||||||
expect(output.filter).toBe(undefined) |
|
||||||
expect(output.pendingTransactionHashes).toEqual(['1']) |
|
||||||
}) |
}) |
||||||
test('page 2 without filter', () => { |
|
||||||
const state = initialState |
|
||||||
const action = { |
const action = { |
||||||
type: 'PAGE_LOAD', |
type: 'RECEIVED_NEW_BLOCK', |
||||||
addressHash: '1234', |
msg: { blockNumber: 2, blockHtml: 'test 2' } |
||||||
beyondPageOne: true, |
|
||||||
pendingTransactionHashes: ['1'] |
|
||||||
} |
} |
||||||
const output = reducer(state, action) |
const output = reducer(state, action) |
||||||
|
|
||||||
expect(output.addressHash).toBe('1234') |
expect(output.validationCount).toEqual(31) |
||||||
expect(output.beyondPageOne).toBe(true) |
expect(output.validatedBlocks).toEqual([ |
||||||
expect(output.filter).toBe(undefined) |
{ blockNumber: 2, blockHtml: 'test 2' }, |
||||||
expect(output.pendingTransactionHashes).toEqual(['1']) |
{ blockNumber: 1, blockHtml: 'test 1' } |
||||||
|
]) |
||||||
|
}) |
||||||
|
test('when channel has been disconnected', () => { |
||||||
|
const state = Object.assign({}, initialState, { |
||||||
|
channelDisconnected: true, |
||||||
|
validationCount: 30, |
||||||
|
validatedBlocks: [{ blockNumber: 1, blockHtml: 'test 1' }] |
||||||
}) |
}) |
||||||
test('page 1 with "to" filter', () => { |
|
||||||
const state = initialState |
|
||||||
const action = { |
const action = { |
||||||
type: 'PAGE_LOAD', |
type: 'RECEIVED_NEW_BLOCK', |
||||||
addressHash: '1234', |
msg: { blockNumber: 2, blockHtml: 'test 2' } |
||||||
beyondPageOne: false, |
|
||||||
filter: 'to' |
|
||||||
} |
} |
||||||
const output = reducer(state, action) |
const output = reducer(state, action) |
||||||
|
|
||||||
expect(output.addressHash).toBe('1234') |
expect(output.validationCount).toEqual(30) |
||||||
expect(output.beyondPageOne).toBe(false) |
expect(output.validatedBlocks).toEqual([ |
||||||
expect(output.filter).toBe('to') |
{ blockNumber: 1, blockHtml: 'test 1' } |
||||||
|
]) |
||||||
}) |
}) |
||||||
test('page 2 with "to" filter', () => { |
test('beyond page one', () => { |
||||||
const state = initialState |
const state = Object.assign({}, initialState, { |
||||||
const action = { |
|
||||||
type: 'PAGE_LOAD', |
|
||||||
addressHash: '1234', |
|
||||||
beyondPageOne: true, |
beyondPageOne: true, |
||||||
filter: 'to' |
validationCount: 30, |
||||||
|
validatedBlocks: [{ blockNumber: 1, blockHtml: 'test 1' }] |
||||||
|
}) |
||||||
|
const action = { |
||||||
|
type: 'RECEIVED_NEW_BLOCK', |
||||||
|
msg: { blockNumber: 2, blockHtml: 'test 2' } |
||||||
} |
} |
||||||
const output = reducer(state, action) |
const output = reducer(state, action) |
||||||
|
|
||||||
expect(output.addressHash).toBe('1234') |
expect(output.validationCount).toEqual(31) |
||||||
expect(output.beyondPageOne).toBe(true) |
expect(output.validatedBlocks).toEqual([ |
||||||
expect(output.filter).toBe('to') |
{ blockNumber: 1, blockHtml: 'test 1' } |
||||||
|
]) |
||||||
}) |
}) |
||||||
}) |
}) |
||||||
|
|
||||||
test('CHANNEL_DISCONNECTED', () => { |
describe('RECEIVED_NEW_INTERNAL_TRANSACTION_BATCH', () => { |
||||||
const state = initialState |
test('with new internal transaction', () => { |
||||||
|
const state = Object.assign({}, initialState, { |
||||||
|
internalTransactions: [{ internalTransactionHtml: 'test 1' }] |
||||||
|
}) |
||||||
const action = { |
const action = { |
||||||
type: 'CHANNEL_DISCONNECTED' |
type: 'RECEIVED_NEW_INTERNAL_TRANSACTION_BATCH', |
||||||
|
msgs: [{ internalTransactionHtml: 'test 2' }] |
||||||
} |
} |
||||||
const output = reducer(state, action) |
const output = reducer(state, action) |
||||||
|
|
||||||
expect(output.channelDisconnected).toBe(true) |
expect(output.internalTransactions).toEqual([ |
||||||
}) |
{ internalTransactionHtml: 'test 2' }, |
||||||
|
{ internalTransactionHtml: 'test 1' } |
||||||
test('RECEIVED_UPDATED_BALANCE', () => { |
]) |
||||||
const state = initialState |
}) |
||||||
|
test('with batch of new internal transactions', () => { |
||||||
|
const state = Object.assign({}, initialState, { |
||||||
|
internalTransactions: [{ internalTransactionHtml: 'test 1' }] |
||||||
|
}) |
||||||
const action = { |
const action = { |
||||||
type: 'RECEIVED_UPDATED_BALANCE', |
type: 'RECEIVED_NEW_INTERNAL_TRANSACTION_BATCH', |
||||||
msg: { |
msgs: [ |
||||||
balance: 'hello world' |
{ internalTransactionHtml: 'test 2' }, |
||||||
} |
{ internalTransactionHtml: 'test 3' }, |
||||||
|
{ internalTransactionHtml: 'test 4' }, |
||||||
|
{ internalTransactionHtml: 'test 5' }, |
||||||
|
{ internalTransactionHtml: 'test 6' }, |
||||||
|
{ internalTransactionHtml: 'test 7' }, |
||||||
|
{ internalTransactionHtml: 'test 8' }, |
||||||
|
{ internalTransactionHtml: 'test 9' }, |
||||||
|
{ internalTransactionHtml: 'test 10' }, |
||||||
|
{ internalTransactionHtml: 'test 11' }, |
||||||
|
{ internalTransactionHtml: 'test 12' }, |
||||||
|
{ internalTransactionHtml: 'test 13' } |
||||||
|
] |
||||||
} |
} |
||||||
const output = reducer(state, action) |
const output = reducer(state, action) |
||||||
|
|
||||||
expect(output.balance).toBe('hello world') |
expect(output.internalTransactions).toEqual([ |
||||||
}) |
{ internalTransactionHtml: 'test 1' } |
||||||
|
]) |
||||||
describe('RECEIVED_NEW_PENDING_TRANSACTION', () => { |
expect(output.internalTransactionsBatch).toEqual([ |
||||||
test('single transaction', () => { |
{ internalTransactionHtml: 'test 13' }, |
||||||
const state = initialState |
{ internalTransactionHtml: 'test 12' }, |
||||||
|
{ internalTransactionHtml: 'test 11' }, |
||||||
|
{ internalTransactionHtml: 'test 10' }, |
||||||
|
{ internalTransactionHtml: 'test 9' }, |
||||||
|
{ internalTransactionHtml: 'test 8' }, |
||||||
|
{ internalTransactionHtml: 'test 7' }, |
||||||
|
{ internalTransactionHtml: 'test 6' }, |
||||||
|
{ internalTransactionHtml: 'test 5' }, |
||||||
|
{ internalTransactionHtml: 'test 4' }, |
||||||
|
{ internalTransactionHtml: 'test 3' }, |
||||||
|
{ internalTransactionHtml: 'test 2' }, |
||||||
|
]) |
||||||
|
}) |
||||||
|
test('after batch of new internal transactions', () => { |
||||||
|
const state = Object.assign({}, initialState, { |
||||||
|
internalTransactionsBatch: [{ internalTransactionHtml: 'test 1' }] |
||||||
|
}) |
||||||
const action = { |
const action = { |
||||||
type: 'RECEIVED_NEW_PENDING_TRANSACTION', |
type: 'RECEIVED_NEW_INTERNAL_TRANSACTION_BATCH', |
||||||
msg: { |
msgs: [ |
||||||
transactionHash: '0x00', |
{ internalTransactionHtml: 'test 2' } |
||||||
transactionHtml: 'test' |
] |
||||||
} |
|
||||||
} |
} |
||||||
const output = reducer(state, action) |
const output = reducer(state, action) |
||||||
|
|
||||||
expect(output.newPendingTransactions).toEqual(['test']) |
expect(output.internalTransactionsBatch).toEqual([ |
||||||
expect(output.transactionCount).toEqual(null) |
{ internalTransactionHtml: 'test 2' }, |
||||||
|
{ internalTransactionHtml: 'test 1' } |
||||||
|
]) |
||||||
}) |
}) |
||||||
test('single transaction after single transaction', () => { |
test('when channel has been disconnected', () => { |
||||||
const state = Object.assign({}, initialState, { |
const state = Object.assign({}, initialState, { |
||||||
newPendingTransactions: ['test 1'] |
channelDisconnected: true, |
||||||
|
internalTransactions: [{ internalTransactionHtml: 'test 1' }] |
||||||
}) |
}) |
||||||
const action = { |
const action = { |
||||||
type: 'RECEIVED_NEW_PENDING_TRANSACTION', |
type: 'RECEIVED_NEW_INTERNAL_TRANSACTION_BATCH', |
||||||
msg: { |
msgs: [{ internalTransactionHtml: 'test 2' }] |
||||||
transactionHash: '0x02', |
|
||||||
transactionHtml: 'test 2' |
|
||||||
} |
|
||||||
} |
} |
||||||
const output = reducer(state, action) |
const output = reducer(state, action) |
||||||
|
|
||||||
expect(output.newPendingTransactions).toEqual(['test 1', 'test 2']) |
expect(output.internalTransactions).toEqual([ |
||||||
expect(output.pendingTransactionHashes.length).toEqual(1) |
{ internalTransactionHtml: 'test 1' } |
||||||
|
]) |
||||||
}) |
}) |
||||||
test('after disconnection', () => { |
test('beyond page one', () => { |
||||||
const state = Object.assign({}, initialState, { |
const state = Object.assign({}, initialState, { |
||||||
channelDisconnected: true |
beyondPageOne: true, |
||||||
|
internalTransactions: [{ internalTransactionHtml: 'test 1' }] |
||||||
}) |
}) |
||||||
const action = { |
const action = { |
||||||
type: 'RECEIVED_NEW_PENDING_TRANSACTION', |
type: 'RECEIVED_NEW_INTERNAL_TRANSACTION_BATCH', |
||||||
msg: { |
msgs: [{ internalTransactionHtml: 'test 2' }] |
||||||
transactionHash: '0x00', |
|
||||||
transactionHtml: 'test' |
|
||||||
} |
|
||||||
} |
} |
||||||
const output = reducer(state, action) |
const output = reducer(state, action) |
||||||
|
|
||||||
expect(output.newPendingTransactions).toEqual([]) |
expect(output.internalTransactions).toEqual([ |
||||||
expect(output.pendingTransactionHashes).toEqual([]) |
{ internalTransactionHtml: 'test 1' } |
||||||
|
]) |
||||||
}) |
}) |
||||||
test('on page 2', () => { |
test('with filtered out internal transaction', () => { |
||||||
const state = Object.assign({}, initialState, { |
const state = Object.assign({}, initialState, { |
||||||
beyondPageOne: true |
filter: 'to' |
||||||
}) |
}) |
||||||
const action = { |
const action = { |
||||||
type: 'RECEIVED_NEW_PENDING_TRANSACTION', |
type: 'RECEIVED_NEW_INTERNAL_TRANSACTION_BATCH', |
||||||
msg: { |
msgs: [{ internalTransactionHtml: 'test 2' }] |
||||||
transactionHash: '0x00', |
|
||||||
transactionHtml: 'test' |
|
||||||
} |
|
||||||
} |
} |
||||||
const output = reducer(state, action) |
const output = reducer(state, action) |
||||||
|
|
||||||
expect(output.newPendingTransactions).toEqual([]) |
expect(output.internalTransactions).toEqual([]) |
||||||
expect(output.pendingTransactionHashes).toEqual([]) |
|
||||||
}) |
}) |
||||||
}) |
}) |
||||||
|
|
||||||
describe('RECEIVED_NEW_TRANSACTION', () => { |
describe('RECEIVED_NEW_PENDING_TRANSACTION', () => { |
||||||
test('single transaction', () => { |
test('with new pending transaction', () => { |
||||||
const state = Object.assign({}, initialState, { |
const state = Object.assign({}, initialState, { |
||||||
addressHash: '0x111' |
pendingTransactions: [{ transactionHash: 1, transactionHtml: 'test 1' }] |
||||||
}) |
}) |
||||||
const action = { |
const action = { |
||||||
type: 'RECEIVED_NEW_TRANSACTION', |
type: 'RECEIVED_NEW_PENDING_TRANSACTION', |
||||||
msg: { |
msg: { transactionHash: 2, transactionHtml: 'test 2' } |
||||||
transactionHtml: 'test' |
|
||||||
} |
|
||||||
} |
} |
||||||
const output = reducer(state, action) |
const output = reducer(state, action) |
||||||
|
|
||||||
expect(output.newTransactions).toEqual([{ transactionHtml: 'test' }]) |
expect(output.pendingTransactions).toEqual([ |
||||||
expect(output.transactionCount).toEqual(null) |
{ transactionHash: 2, transactionHtml: 'test 2' }, |
||||||
|
{ transactionHash: 1, transactionHtml: 'test 1' } |
||||||
|
]) |
||||||
}) |
}) |
||||||
test('single transaction after single transaction', () => { |
test('when channel has been disconnected', () => { |
||||||
const state = Object.assign({}, initialState, { |
const state = Object.assign({}, initialState, { |
||||||
newTransactions: [{ transactionHtml: 'test 1' }] |
channelDisconnected: true, |
||||||
|
pendingTransactions: [{ transactionHash: 1, transactionHtml: 'test 1' }] |
||||||
}) |
}) |
||||||
const action = { |
const action = { |
||||||
type: 'RECEIVED_NEW_TRANSACTION', |
type: 'RECEIVED_NEW_PENDING_TRANSACTION', |
||||||
msg: { |
msg: { transactionHash: 2, transactionHtml: 'test 2' } |
||||||
transactionHtml: 'test 2' |
|
||||||
} |
|
||||||
} |
} |
||||||
const output = reducer(state, action) |
const output = reducer(state, action) |
||||||
|
|
||||||
expect(output.newTransactions).toEqual([ |
expect(output.pendingTransactions).toEqual([ |
||||||
{ transactionHtml: 'test 1' }, |
{ transactionHash: 1, transactionHtml: 'test 1' } |
||||||
{ transactionHtml: 'test 2' } |
|
||||||
]) |
]) |
||||||
}) |
}) |
||||||
test('after disconnection', () => { |
test('beyond page one', () => { |
||||||
const state = Object.assign({}, initialState, { |
const state = Object.assign({}, initialState, { |
||||||
channelDisconnected: true |
beyondPageOne: true, |
||||||
|
pendingTransactions: [{ transactionHash: 1, transactionHtml: 'test 1' }] |
||||||
}) |
}) |
||||||
const action = { |
const action = { |
||||||
type: 'RECEIVED_NEW_TRANSACTION', |
type: 'RECEIVED_NEW_PENDING_TRANSACTION', |
||||||
msg: { |
msg: { transactionHash: 2, transactionHtml: 'test 2' } |
||||||
transactionHtml: 'test' |
|
||||||
} |
|
||||||
} |
} |
||||||
const output = reducer(state, action) |
const output = reducer(state, action) |
||||||
|
|
||||||
expect(output.newTransactions).toEqual([]) |
expect(output.pendingTransactions).toEqual([ |
||||||
|
{ transactionHash: 1, transactionHtml: 'test 1' } |
||||||
|
]) |
||||||
}) |
}) |
||||||
test('on page 2', () => { |
test('with filtered out pending transaction', () => { |
||||||
const state = Object.assign({}, initialState, { |
const state = Object.assign({}, initialState, { |
||||||
beyondPageOne: true, |
filter: 'to' |
||||||
transactionCount: 1, |
|
||||||
addressHash: '0x111' |
|
||||||
}) |
}) |
||||||
const action = { |
const action = { |
||||||
type: 'RECEIVED_NEW_TRANSACTION', |
type: 'RECEIVED_NEW_PENDING_TRANSACTION', |
||||||
msg: { |
msg: { transactionHash: 2, transactionHtml: 'test 2' } |
||||||
transactionHtml: 'test' |
|
||||||
} |
|
||||||
} |
} |
||||||
const output = reducer(state, action) |
const output = reducer(state, action) |
||||||
|
|
||||||
expect(output.newTransactions).toEqual([]) |
expect(output.pendingTransactions).toEqual([]) |
||||||
expect(output.transactionCount).toEqual(1) |
|
||||||
}) |
}) |
||||||
test('transaction from current address with "from" filter', () => { |
}) |
||||||
|
|
||||||
|
describe('RECEIVED_NEW_TRANSACTION', () => { |
||||||
|
test('with new transaction', () => { |
||||||
const state = Object.assign({}, initialState, { |
const state = Object.assign({}, initialState, { |
||||||
addressHash: '1234', |
pendingTransactions: [{ transactionHash: 2, transactionHtml: 'test' }], |
||||||
filter: 'from' |
transactions: [{ transactionHash: 1, transactionHtml: 'test 1' }] |
||||||
}) |
}) |
||||||
const action = { |
const action = { |
||||||
type: 'RECEIVED_NEW_TRANSACTION', |
type: 'RECEIVED_NEW_TRANSACTION', |
||||||
msg: { |
msg: { transactionHash: 2, transactionHtml: 'test 2' } |
||||||
fromAddressHash: '1234', |
|
||||||
transactionHtml: 'test' |
|
||||||
} |
|
||||||
} |
} |
||||||
const output = reducer(state, action) |
const output = reducer(state, action) |
||||||
|
|
||||||
expect(output.newTransactions).toEqual([ |
expect(output.pendingTransactions).toEqual([ |
||||||
{ fromAddressHash: '1234', transactionHtml: 'test' } |
{ transactionHash: 2, transactionHtml: 'test 2', validated: true } |
||||||
|
]) |
||||||
|
expect(output.transactions).toEqual([ |
||||||
|
{ transactionHash: 2, transactionHtml: 'test 2' }, |
||||||
|
{ transactionHash: 1, transactionHtml: 'test 1' } |
||||||
]) |
]) |
||||||
}) |
}) |
||||||
test('transaction from current address with "to" filter', () => { |
test('when channel has been disconnected', () => { |
||||||
const state = Object.assign({}, initialState, { |
const state = Object.assign({}, initialState, { |
||||||
addressHash: '1234', |
channelDisconnected: true, |
||||||
filter: 'to' |
pendingTransactions: [{ transactionHash: 2, transactionHtml: 'test' }], |
||||||
|
transactions: [{ transactionHash: 1, transactionHtml: 'test 1' }] |
||||||
}) |
}) |
||||||
const action = { |
const action = { |
||||||
type: 'RECEIVED_NEW_TRANSACTION', |
type: 'RECEIVED_NEW_TRANSACTION', |
||||||
msg: { |
msg: { transactionHash: 2, transactionHtml: 'test 2' } |
||||||
fromAddressHash: '1234', |
|
||||||
transactionHtml: 'test' |
|
||||||
} |
|
||||||
} |
} |
||||||
const output = reducer(state, action) |
const output = reducer(state, action) |
||||||
|
|
||||||
expect(output.newTransactions).toEqual([]) |
expect(output.pendingTransactions).toEqual([ |
||||||
|
{ transactionHash: 2, transactionHtml: 'test' } |
||||||
|
]) |
||||||
|
expect(output.transactions).toEqual([ |
||||||
|
{ transactionHash: 1, transactionHtml: 'test 1' } |
||||||
|
]) |
||||||
}) |
}) |
||||||
test('transaction to current address with "to" filter', () => { |
test('beyond page one', () => { |
||||||
const state = Object.assign({}, initialState, { |
const state = Object.assign({}, initialState, { |
||||||
addressHash: '1234', |
beyondPageOne: true, |
||||||
filter: 'to' |
transactions: [{ transactionHash: 1, transactionHtml: 'test 1' }] |
||||||
}) |
}) |
||||||
const action = { |
const action = { |
||||||
type: 'RECEIVED_NEW_TRANSACTION', |
type: 'RECEIVED_NEW_TRANSACTION', |
||||||
msg: { |
msg: { transactionHash: 2, transactionHtml: 'test 2' } |
||||||
toAddressHash: '1234', |
|
||||||
transactionHtml: 'test' |
|
||||||
} |
|
||||||
} |
} |
||||||
const output = reducer(state, action) |
const output = reducer(state, action) |
||||||
|
|
||||||
expect(output.newTransactions).toEqual([ |
expect(output.pendingTransactions).toEqual([]) |
||||||
{ toAddressHash: '1234', transactionHtml: 'test' } |
expect(output.transactions).toEqual([ |
||||||
|
{ transactionHash: 1, transactionHtml: 'test 1' } |
||||||
]) |
]) |
||||||
}) |
}) |
||||||
test('transaction to current address with "from" filter', () => { |
test('with filtered out transaction', () => { |
||||||
const state = Object.assign({}, initialState, { |
const state = Object.assign({}, initialState, { |
||||||
addressHash: '1234', |
filter: 'to' |
||||||
filter: 'from' |
|
||||||
}) |
}) |
||||||
const action = { |
const action = { |
||||||
type: 'RECEIVED_NEW_TRANSACTION', |
type: 'RECEIVED_NEW_TRANSACTION', |
||||||
msg: { |
msg: { transactionHash: 2, transactionHtml: 'test 2' } |
||||||
toAddressHash: '1234', |
|
||||||
transactionHtml: 'test' |
|
||||||
} |
|
||||||
} |
} |
||||||
const output = reducer(state, action) |
const output = reducer(state, action) |
||||||
|
|
||||||
expect(output.newTransactions).toEqual([]) |
expect(output.transactions).toEqual([]) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
describe('RECEIVED_NEXT_TRANSACTIONS_PAGE', () => { |
||||||
|
test('with new transaction page', () => { |
||||||
|
const state = Object.assign({}, initialState, { |
||||||
|
loadingNextPage: true, |
||||||
|
nextPage: '1', |
||||||
|
transactions: [{ transactionHash: 1, transactionHtml: 'test 1' }] |
||||||
}) |
}) |
||||||
test('single transaction collated from pending', () => { |
|
||||||
const state = initialState |
|
||||||
const action = { |
const action = { |
||||||
type: 'RECEIVED_NEW_TRANSACTION', |
type: 'RECEIVED_NEXT_TRANSACTIONS_PAGE', |
||||||
msg: { |
msg: { |
||||||
transactionHash: '0x00', |
nextPage: '2', |
||||||
transactionHtml: 'test' |
transactions: [{ transactionHash: 2, transactionHtml: 'test 2' }] |
||||||
} |
} |
||||||
} |
} |
||||||
const output = reducer(state, action) |
const output = reducer(state, action) |
||||||
|
|
||||||
expect(output.newTransactions).toEqual([ |
expect(output.loadingNextPage).toEqual(false) |
||||||
{ transactionHash: '0x00', transactionHtml: 'test' } |
expect(output.nextPage).toEqual('2') |
||||||
|
expect(output.transactions).toEqual([ |
||||||
|
{ transactionHash: 1, transactionHtml: 'test 1' }, |
||||||
|
{ transactionHash: 2, transactionHtml: 'test 2' } |
||||||
]) |
]) |
||||||
expect(output.transactionCount).toEqual(null) |
|
||||||
}) |
}) |
||||||
}) |
}) |
||||||
|
Loading…
Reference in new issue