Skip to content

Commit

Permalink
✨ feat: Implemented hook to check for value errors
Browse files Browse the repository at this point in the history
  • Loading branch information
caioaletroca committed Dec 18, 2024
1 parent 981c3cb commit 73b897d
Show file tree
Hide file tree
Showing 2 changed files with 152 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { renderHook, act } from '@testing-library/react'
import { useIntl } from 'react-intl'
import { useTransactionFormErrors } from './use-transaction-form-errors'
import { TransactionFormSchema } from './schemas'

jest.mock('react-intl', () => ({
useIntl: jest.fn()
}))

describe('useTransactionFormErrors', () => {
const intlMock = {
formatMessage: jest.fn(({ defaultMessage }) => defaultMessage)
}

beforeEach(() => {
;(useIntl as jest.Mock).mockReturnValue(intlMock)
})

it('should return no errors initially', () => {
const { result } = renderHook(() =>
useTransactionFormErrors({
value: 0,
source: [],
destination: []
} as any)
)
expect(result.current.errors).toEqual({})
})

it('should add debit error if source sum does not match value', () => {
const { result } = renderHook(() =>
useTransactionFormErrors({
value: 100,
source: [{ value: 50 }],
destination: []
} as any)
)

act(() => {
result.current.errors
})

expect(result.current.errors.debit).toBe(
'Total Debits do not match total Credits'
)
})

it('should add credit error if destination sum does not match value', () => {
const { result } = renderHook(() =>
useTransactionFormErrors({
value: '100',
source: [],
destination: [{ value: '50' }]
} as any)
)

act(() => {
result.current.errors
})

expect(result.current.errors.credit).toBe(
'Total Debits do not match total Credits'
)
})

it('should remove debit error if source sum matches value', () => {
const { result } = renderHook(() =>
useTransactionFormErrors({
value: '100',
source: [{ value: '100' }],
destination: []
} as any)
)

act(() => {
result.current.errors
})

expect(result.current.errors.debit).toBeUndefined()
})

it('should remove credit error if destination sum matches value', () => {
const { result } = renderHook(() =>
useTransactionFormErrors({
value: '100',
source: [],
destination: [{ value: '100' }]
} as any)
)

act(() => {
result.current.errors
})

expect(result.current.errors.credit).toBeUndefined()
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { useEffect, useState } from 'react'
import { useIntl } from 'react-intl'
import { TransactionFormSchema, TransactionSourceFormSchema } from './schemas'

export type TransactionFormErrors = Record<string, string>

export const useTransactionFormErrors = (values: TransactionFormSchema) => {
const intl = useIntl()
const [errors, setErrors] = useState<TransactionFormErrors>({})
const { value, source, destination } = values

const sum = (source: TransactionSourceFormSchema) =>
source.reduce((acc, curr) => acc + Number(curr.value), 0)

const addError = (key: string, value: string) => {
setErrors((prev) => ({ ...prev, [key]: value }))
}

const removeError = (key: string) => {
setErrors((prev) => {
const { [key]: _, ...rest } = prev
return rest
})
}

useEffect(() => {
const v = Number(value)

if (v !== sum(source)) {
addError(
'debit',
intl.formatMessage({
id: 'transactions.errors.debit',
defaultMessage: 'Total Debits do not match total Credits'
})
)
} else {
removeError('debit')
}

if (v !== sum(destination)) {
addError(
'credit',
intl.formatMessage({
id: 'transactions.errors.debit',
defaultMessage: 'Total Debits do not match total Credits'
})
)
} else {
removeError('credit')
}
}, [value, sum(source), sum(destination)])

return { errors }
}

0 comments on commit 73b897d

Please sign in to comment.