Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 8fd89e8

Browse files
committedJul 12, 2020
feat: useExchange hook for handling state for the page, also getExchangeAmount util with test
1 parent 1548e07 commit 8fd89e8

File tree

4 files changed

+182
-1
lines changed

4 files changed

+182
-1
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { useExchange } from '../useExchange';
2+
import { renderHook, act } from '@testing-library/react-hooks';
3+
import { exchangeRatesData } from 'shared/utils/mockData';
4+
import { POCKET } from 'constants/currency';
5+
6+
describe('Exchange Hook', () => {
7+
it('get initIal source and destination pockets', () => {
8+
const { result } = renderHook(useExchange, {
9+
initialProps: { rates: exchangeRatesData.data.rates },
10+
});
11+
let { source, destination } = result.current;
12+
expect(source).toEqual({ currency: 'EUR', amount: 0 });
13+
expect(destination).toEqual({ currency: 'GBP', amount: 0 });
14+
});
15+
16+
it('allows to set values of source and destination pockets', () => {
17+
const { result } = renderHook(useExchange, {
18+
initialProps: { rates: exchangeRatesData.data.rates },
19+
});
20+
let { setDestination, setSource } = result.current;
21+
act(() => setDestination({ currency: 'GBP', amount: 10 }));
22+
act(() => setSource({ currency: 'USD', amount: 100 }));
23+
expect(result.current.destination).toEqual({ currency: 'GBP', amount: 10 });
24+
expect(result.current.source).toEqual({ currency: 'USD', amount: 100 });
25+
});
26+
27+
it('interchange the source and destination transaction', () => {
28+
const { result } = renderHook(useExchange, {
29+
initialProps: { rates: exchangeRatesData.data.rates },
30+
});
31+
let { setDestination, setSource } = result.current;
32+
act(() => setDestination({ currency: 'GBP', amount: 10 }));
33+
act(() => setSource({ currency: 'USD', amount: 100 }));
34+
act(() => result.current.onSwitch());
35+
expect(result.current.destination).toEqual({
36+
currency: 'USD',
37+
amount: 100,
38+
});
39+
expect(result.current.source).toEqual({ currency: 'GBP', amount: 10 });
40+
});
41+
42+
it('onAmount change in source and destination pocket', () => {
43+
const { result } = renderHook(useExchange, {
44+
initialProps: { rates: exchangeRatesData.data.rates },
45+
});
46+
const { onAmountChange } = result.current;
47+
act(() => onAmountChange(POCKET.SOURCE, 150));
48+
expect(result.current.destination).toEqual({
49+
currency: 'GBP',
50+
amount: -150,
51+
});
52+
expect(result.current.source).toEqual({ currency: 'EUR', amount: 150 });
53+
act(() => onAmountChange(POCKET.DESTINATION, 300));
54+
expect(result.current.destination).toEqual({
55+
currency: 'GBP',
56+
amount: 300,
57+
});
58+
expect(result.current.source).toEqual({ currency: 'EUR', amount: -300 });
59+
});
60+
61+
it('onCurrencyChange in source pocket', () => {
62+
const { result } = renderHook(useExchange, {
63+
initialProps: { rates: exchangeRatesData.data.rates },
64+
});
65+
const { onCurrencyChange, setSource } = result.current;
66+
act(() => setSource({ currency: 'USD', amount: 100 }));
67+
act(() => onCurrencyChange(POCKET.SOURCE, 'USD'));
68+
expect(result.current.source).toEqual({ currency: 'USD', amount: 100 });
69+
act(() => onCurrencyChange(POCKET.DESTINATION, 'EUR'));
70+
expect(result.current.destination).toEqual({ currency: 'EUR', amount: 0 });
71+
});
72+
});

‎src/pages/Exchange/useExchange.tsx

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import { useState } from 'react';
2+
import { CurrencyCode, PocketContent } from 'models/pockets';
3+
import { EUR, GBP, POCKET } from 'constants/currency';
4+
import { getExchangeAmount } from 'shared/utils/exchange';
5+
import { ExchangeRate } from 'models/exchangeRates';
6+
7+
const useExchange = ({ rates }: { rates: ExchangeRate }) => {
8+
const [source, setSource] = useState<PocketContent>({
9+
currency: EUR,
10+
amount: 0,
11+
});
12+
const [destination, setDestination] = useState<PocketContent>({
13+
currency: GBP,
14+
amount: 0,
15+
});
16+
17+
const onCurrencyChange = (
18+
typeToUpdate: string,
19+
currency: CurrencyCode,
20+
): void => {
21+
if (typeToUpdate === POCKET.SOURCE) {
22+
setSource((prevState) => ({ ...prevState, currency }));
23+
setDestination((prevState) => ({
24+
...prevState,
25+
amount: getExchangeAmount(
26+
prevState.currency,
27+
source.amount,
28+
currency,
29+
rates,
30+
),
31+
}));
32+
} else {
33+
setDestination({
34+
currency,
35+
amount: getExchangeAmount(
36+
currency,
37+
source.amount,
38+
source.currency,
39+
rates,
40+
),
41+
});
42+
}
43+
};
44+
45+
const onAmountChange = (typeToUpdate: string, amount: number): void => {
46+
if (typeToUpdate === POCKET.SOURCE) {
47+
setSource((prevState) => ({ ...prevState, amount }));
48+
setDestination((prevState) => ({
49+
...prevState,
50+
amount: getExchangeAmount(
51+
prevState.currency,
52+
amount,
53+
source.currency,
54+
rates,
55+
),
56+
}));
57+
} else {
58+
setDestination((prevState) => ({ ...prevState, amount }));
59+
setSource((prevState) => ({
60+
...prevState,
61+
amount: getExchangeAmount(
62+
prevState.currency,
63+
amount,
64+
destination.currency,
65+
rates,
66+
),
67+
}));
68+
}
69+
};
70+
71+
const onSwitch = (): void => {
72+
let tempSource = { ...source };
73+
let tempDestination = { ...destination };
74+
setDestination(tempSource);
75+
setSource(tempDestination);
76+
};
77+
78+
return {
79+
source,
80+
setSource,
81+
setDestination,
82+
destination,
83+
onAmountChange,
84+
onCurrencyChange,
85+
onSwitch,
86+
};
87+
};
88+
89+
export { useExchange };

‎src/shared/utils/__tests__/exchange.test.ts

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {
2-
calculateExchangeRate,
2+
calculateExchangeRate, getExchangeAmount,
33
} from '../exchange';
44
import { exchangeRatesData } from '../mockData';
55

@@ -18,4 +18,14 @@ describe('exchange utils', () => {
1818
calculateExchangeRate('GBP', 'EUR', { ...exchangeRatesData.data.rates }),
1919
).toEqual(-1);
2020
});
21+
22+
it('getExchangeAmount', () => {
23+
expect(
24+
getExchangeAmount('GBP', 3000, 'EUR', {
25+
...exchangeRatesData.data.rates,
26+
EUR: 1,
27+
}),
28+
).toEqual(2687.1);
29+
});
30+
2131
});

‎src/shared/utils/exchange.ts

+10
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,13 @@ export const calculateExchangeRate = (
1010
if (!fromRate || !toRate) return -1;
1111
return toRate / fromRate;
1212
};
13+
14+
export const getExchangeAmount = (
15+
toCurrency: string,
16+
amount: number,
17+
fromCurrency: string,
18+
exchangeRates: ExchangeRate,
19+
): number => {
20+
let rate = calculateExchangeRate(fromCurrency, toCurrency, exchangeRates);
21+
return Number((amount * rate).toFixed(2));
22+
};

0 commit comments

Comments
 (0)
Please sign in to comment.