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

Commit

Permalink
Merge pull request #4632 from willy-b/payment-history-multi-same-day-…
Browse files Browse the repository at this point in the history
…csv-filenames-4605-rebase-2

Payment History receipt filenames for transactions with same date get unique suffix (#4605)
  • Loading branch information
diracdeltas authored Oct 10, 2016
2 parents 3bce7a8 + 40d6a01 commit f4418d6
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 8 deletions.
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 @@ -464,7 +466,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 @@ -501,10 +505,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 @@ -527,7 +527,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

0 comments on commit f4418d6

Please sign in to comment.