Skip to content

Commit

Permalink
feat: add sorting and filtering to earn report (#451)
Browse files Browse the repository at this point in the history
* feat: add sorting and filtering to earn report

* dev: remove conf duration from earn table

* fix: smaller header for utxo input count

* ui: add pagination to earn report

* refactor: rename itemsPerPage to pageSizes

* review: improved header wording

* review: align input count column contents

* review: remove pagination from Earn Report component

* test: add happy path tests for Earn Report parsing

* test: show handling unexpected/malformed data in Earn Report

* review: rearrange Earn Report columns; move Earned column to front
  • Loading branch information
theborakompanioni authored Aug 5, 2022
1 parent 2097b35 commit bd8fd97
Show file tree
Hide file tree
Showing 5 changed files with 530 additions and 143 deletions.
44 changes: 43 additions & 1 deletion src/components/EarnReport.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,54 @@
}

.overlayContainer .earnReportContainer {
display: flex;
flex-direction: column;
gap: 2.5rem;
background-color: var(--bs-body-bg);
}

@media only screen and (min-width: 768px) {
.overlayContainer .earnReportContainer {
border-radius: 0.5rem;
padding: 2rem;
border-radius: 0.5rem;
}
}

.overlayContainer .earnReportContainer > .titleBar {
min-height: 3.6rem;
display: flex;
justify-content: space-between;
flex-direction: column;
align-items: flex-start;
gap: 0.5rem;
padding: 0 0 0.8rem 0;
background-color: var(--bs-gray-100);
}

@media only screen and (min-width: 768px) {
.overlayContainer .earnReportContainer > .titleBar {
align-items: center;
padding: 0.8rem 1rem;
border-radius: 0.6rem;
}
}

@media only screen and (min-width: 768px) {
.overlayContainer .earnReportContainer > .titleBar {
flex-direction: row;
}
}

:root[data-theme='dark'] .overlayContainer .earnReportContainer > .titleBar {
background-color: var(--bs-gray-800);
}

.overlayContainer .earnReportContainer > .titleBar .refreshButton {
display: flex;
justify-content: center;
align-items: center;
width: 2rem;
height: 2rem;
padding: 0.1rem;
border: none;
}
89 changes: 89 additions & 0 deletions src/components/EarnReport.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { yieldgenReportToEarnReportEntries } from './EarnReport'

const EXPECTED_HEADER_LINE =
'timestamp,cj amount/satoshi,my input count,my input value/satoshi,cjfee/satoshi,earned/satoshi,confirm time/min,notes\n'

describe('Earn Report', () => {
it('should parse empty data correctly', () => {
const entries = yieldgenReportToEarnReportEntries([])
expect(entries.length).toBe(0)
})

it('should parse data only containing headers correctly', () => {
const entries = yieldgenReportToEarnReportEntries([EXPECTED_HEADER_LINE])

expect(entries.length).toBe(0)
})

it('should parse expected data structure correctly', () => {
const exampleData = [
EXPECTED_HEADER_LINE,
'2008/10/31 02:42:54,,,,,,,Connected\n',
'2009/01/03 02:54:42,14999989490,4,20000005630,250,250,0.42,\n',
'2009/01/03 03:03:32,10000000000,3,15000016390,250,250,0.8,\n',
'2009/01/03 03:04:47,4999981140,1,5000016640,250,250,0,\n',
'2009/01/03 03:06:07,1132600000,1,2500000000,250,250,13.37,\n',
'2009/01/03 03:07:27,8867393010,2,10000000000,250,250,42,\n',
'2009/01/03 03:08:52,1132595980,1,1367400250,250,250,0.17,\n',
]

const entries = yieldgenReportToEarnReportEntries(exampleData)

expect(entries.length).toBe(7)

const firstEntry = entries[0]
expect(firstEntry.timestamp.toUTCString()).toBe('Fri, 31 Oct 2008 02:42:54 GMT')
expect(firstEntry.cjTotalAmount).toBe(null)
expect(firstEntry.inputCount).toBe(null)
expect(firstEntry.inputAmount).toBe(null)
expect(firstEntry.fee).toBe(null)
expect(firstEntry.earnedAmount).toBe(null)
expect(firstEntry.confirmationDuration).toBe(null)
expect(firstEntry.notes).toBe('Connected\n')

const lastEntry = entries[entries.length - 1]
expect(lastEntry.timestamp.toUTCString()).toBe('Sat, 03 Jan 2009 03:08:52 GMT')
expect(lastEntry.cjTotalAmount).toBe(1132595980)
expect(lastEntry.inputCount).toBe(1)
expect(lastEntry.inputAmount).toBe(1367400250)
expect(lastEntry.fee).toBe(250)
expect(lastEntry.earnedAmount).toBe(250)
expect(lastEntry.confirmationDuration).toBe(0.17)
expect(lastEntry.notes).toBe('\n')
})

it('should handle unexpected/malformed data in a sane way', () => {
const unexpectedHeader = EXPECTED_HEADER_LINE + ',foo,bar'
const emptyLine = '' // should be skipped
const onlyNewLine = '\n' // should be skipped
const shortLine = '2009/01/03 04:04:04,,,' // should be skipped
const longLine = '2009/01/03 05:05:05,,,,,,,,,,,,,,,,,,,,,,,' // should be parsed
const malformedLine = 'this,is,a,malformed,line,with,some,unexpected,data' // should be parsed

const exampleData = [unexpectedHeader, emptyLine, onlyNewLine, shortLine, longLine, malformedLine]

const entries = yieldgenReportToEarnReportEntries(exampleData)

expect(entries.length).toBe(2)

const firstEntry = entries[0]
expect(firstEntry.timestamp.toUTCString()).toBe('Sat, 03 Jan 2009 05:05:05 GMT')
expect(firstEntry.cjTotalAmount).toBe(null)
expect(firstEntry.inputCount).toBe(null)
expect(firstEntry.inputAmount).toBe(null)
expect(firstEntry.fee).toBe(null)
expect(firstEntry.earnedAmount).toBe(null)
expect(firstEntry.confirmationDuration).toBe(null)
expect(firstEntry.notes).toBe(null)

const secondEntry = entries[1]
expect(secondEntry.timestamp.toUTCString()).toBe('Invalid Date')
expect(secondEntry.cjTotalAmount).toBe(NaN)
expect(secondEntry.inputCount).toBe(NaN)
expect(secondEntry.inputAmount).toBe(NaN)
expect(secondEntry.fee).toBe(NaN)
expect(secondEntry.earnedAmount).toBe(NaN)
expect(secondEntry.confirmationDuration).toBe(NaN)
expect(secondEntry.notes).toBe('unexpected')
})
})
Loading

0 comments on commit bd8fd97

Please sign in to comment.