Skip to content
This repository has been archived by the owner on Dec 11, 2019. It is now read-only.

Payment History receipt filenames for transactions with same date get unique suffix (#4605) #4632

Merged
merged 2 commits into from
Oct 10, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions js/about/preferences.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ const Immutable = require('immutable')
const SwitchControl = require('../components/switchControl')
const ModalOverlay = require('../components/modalOverlay')
const cx = require('../lib/classSet')
const transactionsToCSVDataURL = require('../lib/ledgerExportUtil').transactionsToCSVDataURL
const ledgerExportUtil = require('../lib/ledgerExportUtil')
const transactionsToCSVDataURL = ledgerExportUtil.transactionsToCSVDataURL
const addExportFilenamePrefixToTransactions = ledgerExportUtil.addExportFilenamePrefixToTransactions
const {getZoomValuePercentage} = require('../lib/zoom')
const config = require('../constants/config')
const appConfig = require('../constants/appConfig')
Expand Down Expand Up @@ -465,7 +467,9 @@ class PaymentHistory extends ImmutableComponent {
}

render () {
const transactions = this.props.ledgerData.get('transactions')
const transactions = Immutable.fromJS(
addExportFilenamePrefixToTransactions(this.props.ledgerData.get('transactions').toJS())
)

return <div id='paymentHistory'>
<table className='sort'>
Expand Down Expand Up @@ -502,10 +506,6 @@ class PaymentHistoryRow extends ImmutableComponent {
return formattedDateFromTimestamp(this.timestamp)
}

get numericDateStr () {
return (new Date(this.timestamp)).toLocaleDateString().replace(/\//g, '-')
}

get ledgerData () {
return this.props.ledgerData
}
Expand All @@ -528,7 +528,7 @@ class PaymentHistoryRow extends ImmutableComponent {
}

get receiptFileName () {
return `Brave_Payments_${this.numericDateStr}.csv`
return `${this.transaction.get('exportFilenamePrefix')}.csv`
}

get dataURL () {
Expand Down
41 changes: 40 additions & 1 deletion js/lib/ledgerExportUtil.js
Original file line number Diff line number Diff line change
Expand Up @@ -279,11 +279,50 @@ let getTransactionCSVText = function (transactions, viewingIds, addTotalRow) {
return getTransactionCSVRows(transactions, viewingIds, addTotalRow).join('\n')
}

/**
* Adds an `exportFilenamePrefix` field to the provided transaction(s)
* of form `Brave_Payments_${MM-D(D)-YYYY}`, with "_<n>" added for the nth time a date occurs (n > 1)
*
* @param {Object[]} transactions - an array of transaction(s) or single transaction object
*
* @returns {Object[]} transactions (with each element having an added field `exportFilenamePrefix`)
*/
let addExportFilenamePrefixToTransactions = function (transactions) {
transactions = transactions || []

if (!underscore.isArray(transactions)) {
transactions = [transactions]
}

if (!transactions.length) {
return transactions
}

var dateCountMap = {}

return transactions.map(function (transaction) {
let timestamp = transaction.submissionStamp
let numericDateStr = (new Date(timestamp)).toLocaleDateString().replace(/\//g, '-')

let dateCount = (dateCountMap[numericDateStr] ? dateCountMap[numericDateStr] : 1)
dateCountMap[numericDateStr] = dateCount + 1

if (dateCount > 1) {
numericDateStr = `${numericDateStr}_${dateCount}`
}

transaction.exportFilenamePrefix = `Brave_Payments_${numericDateStr}`

return transaction
})
}

module.exports = {
transactionsToCSVDataURL,
getTransactionCSVText,
getTransactionCSVRows,
getPublisherVoteData,
getTransactionsByViewingIds,
getTotalContribution
getTotalContribution,
addExportFilenamePrefixToTransactions
}
88 changes: 88 additions & 0 deletions test/unit/lib/ledgerExportUtilTest.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* global describe, it, before */
const assert = require('assert')
const underscore = require('underscore')
const uuid = require('node-uuid')

require('../braveUnit')

Expand All @@ -20,6 +21,9 @@ const CSV_CONTENT_TYPE = 'text/csv'
const CSV_DATA_URI_PREFIX = 'data:' + CSV_CONTENT_TYPE + ';base64,'
const EMPTY_CSV_DATA_URL = CSV_DATA_URI_PREFIX + base64Encode(EMPTY_CSV)

const EXPORT_FILENAME_CONST_PREFIX_PART = 'Brave_Payments_'
const EXPORT_FILENAME_PREFIX_EXPECTED_FORM = `${EXPORT_FILENAME_CONST_PREFIX_PART}\${MM-D(D)-YYYY}`

const exampleTransactions = require('./exampleLedgerData').transactions
const exampleTransaction = exampleTransactions[0]

Expand Down Expand Up @@ -381,8 +385,92 @@ describe('ledger export utilities test', function () {
})
})
})

describe('addExportFilenamePrefixToTransactions', function () {
it('should return an empty array if not passed any transactions (empty array, null, or undefined input)', function () {
let output

output = ledgerExportUtil.addExportFilenamePrefixToTransactions([])
assert(output && underscore.isArray(output) && output.length === 0, 'should return an empty array when given an empty array as input')

output = ledgerExportUtil.addExportFilenamePrefixToTransactions(undefined)
assert(output && underscore.isArray(output) && output.length === 0, 'should return an empty array when given undefined as input')

output = ledgerExportUtil.addExportFilenamePrefixToTransactions(null)
assert(output && underscore.isArray(output) && output.length === 0, 'should return an empty array when given null as input')
})

it('should return the same output for a single transaction given as an array or single object', function () {
let txs = [cloneTransactionWithNewViewingId(exampleTransaction)]
assert(txs[0] && !txs[0].exportFilenamePrefix, 'the example transaction should not already have "exportFilenamePrefix" defined')

let outputFromArray = ledgerExportUtil.addExportFilenamePrefixToTransactions(txs)
let outputFromObject = ledgerExportUtil.addExportFilenamePrefixToTransactions(txs[0])

assert.deepEqual(outputFromArray, outputFromObject, 'the same output should be returned for an array with 1 transaction and the transaction object itself')
})

it(`should add a field "exportFilenamePrefix" to each transaction with correct form ("${EXPORT_FILENAME_PREFIX_EXPECTED_FORM}")`, function () {
let txs = [cloneTransactionWithNewViewingId(exampleTransaction)]
assert(txs[0] && !txs[0].exportFilenamePrefix, 'the example transaction should not already have "exportFilenamePrefix" defined')
txs = ledgerExportUtil.addExportFilenamePrefixToTransactions(txs)

let tx = txs[0]
let timestamp = tx.submissionStamp
let dateStr = (new Date(timestamp)).toLocaleDateString().replace(/\//g, '-')
let expectedExportFilenamePrefix = `${EXPORT_FILENAME_CONST_PREFIX_PART}${dateStr}`

assert.equal(typeof tx.exportFilenamePrefix, 'string', 'transaction should have "exportFilenamePrefix" field with type "string"')
assert.equal(tx.exportFilenamePrefix, expectedExportFilenamePrefix, `"exportFilenamePrefix" field should have expected form: "${EXPORT_FILENAME_PREFIX_EXPECTED_FORM}", here with date string = "${dateStr}"`)
})

it('should add a distinct suffix ("_<n>") to "exportFilenamePrefix" when multiple transactions occur on same day to ensure the field value is unique', function () {
// create 3 clone transactions identical except for viewingId
// -> these will all have a submissionStamp corresponding to the same DAY
let txs = [cloneTransactionWithNewViewingId(exampleTransaction), cloneTransactionWithNewViewingId(exampleTransaction), cloneTransactionWithNewViewingId(exampleTransaction)]

let sameDaySubmissionStamp = txs[0].submissionStamp

// add one more clone transaction but modify the date to be a day later
// -> this should NOT get the distinguishing suffix
let txOnDifferentDate = cloneTransactionWithNewViewingId(exampleTransaction)
txOnDifferentDate.submissionStamp += 1000 * 3600 * 48 // shift by 48 hours (2 days)
txs.push(txOnDifferentDate)

txs.forEach(function (tx) {
assert(tx && !tx.exportFilenamePrefix, 'the example transactions should not already have "exportFilenamePrefix" defined')
})

txs = ledgerExportUtil.addExportFilenamePrefixToTransactions(txs)

let numSameDayTxProcessed = 0
txs.forEach(function (tx, idx) {
assert.equal(typeof tx.exportFilenamePrefix, 'string', 'each transactions should now have a "exportFilenamePrefix" field of type "string" defined')

if (tx.submissionStamp === sameDaySubmissionStamp) {
numSameDayTxProcessed++
}

let firstTransactionForDate = !idx || tx.submissionStamp !== sameDaySubmissionStamp
if (firstTransactionForDate) {
let errMessage = `the first transaction for a given date should NOT have the distinguishing "_<n>" suffix: "${tx.exportFilenamePrefix}" (tx idx = ${idx})`
assert.equal(tx.exportFilenamePrefix.slice(tx.exportFilenamePrefix.length - 2).indexOf('_'), -1, errMessage)
} else { // if 2nd or 3rd transaction on a given date...
assert.equal(tx.exportFilenamePrefix.slice(tx.exportFilenamePrefix.length - 2), `_${numSameDayTxProcessed}`, 'the second and third transaction for a given date SHOULD have the suffix "_<n>"')
}
})
})
})
})

// clone a transaction but give it a unique viewingId
function cloneTransactionWithNewViewingId (tx) {
let cloneTx = underscore.clone(tx)
cloneTx.viewingId = uuid.v4().toLowerCase()

return cloneTx
}

function checkColumnCountsForRows (rows) {
for (var rowIdx = 0; rowIdx < rows.length; rowIdx++) {
let row = rows[rowIdx]
Expand Down