Skip to content

Commit

Permalink
Merge branch 'frontend-amount-refactor'
Browse files Browse the repository at this point in the history
  • Loading branch information
thisconnect committed Apr 23, 2024
2 parents 60dc332 + cb4aa7f commit 7f33634
Show file tree
Hide file tree
Showing 20 changed files with 566 additions and 138 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
- New feature in advanced settings: Export logs
- Add specific titles to guides replacing the generic "Guide" previously used on all pages
- Android: enable transactions export feature
- Format amounts using localized decimal and group separator

## 4.42.0
- Preselect backup when there's only one backup available
Expand Down
224 changes: 224 additions & 0 deletions frontends/web/src/components/amount/amount.localized.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
/**
* Copyright 2024 Shift Crypto AG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { useContext } from 'react';
import { beforeEach, describe, expect, it, Mock, vi } from 'vitest';
import { render } from '@testing-library/react';
import { Amount } from './amount';
import { ConversionUnit } from '../../api/account';

vi.mock('react', async () => ({
...(await vi.importActual('react')),
useMemo: vi.fn().mockImplementation((fn) => fn()), // not really needed here, but in balance.test.tsx
useContext: vi.fn(),
createContext: vi.fn()
}));


describe.only('Fiat amount formatting', () => {
beforeEach(() => {
(useContext as Mock).mockReturnValue({ hideAmounts: false });
});

describe('de-AT', () => {
it('should use dot for thousand and comma for decimal', () => {
(useContext as Mock).mockReturnValue({ nativeLocale: 'de-AT' });
const { container } = render(<Amount amount="1'234'567.89" unit="EUR" />);
expect(container).toHaveTextContent('1.234.567,89');
});
});

describe('de-CH', () => {
it('should use apostrophe for thousand and dot for decimal', () => {
(useContext as Mock).mockReturnValue({ nativeLocale: 'de-CH' });
const { container } = render(<Amount amount="1'234'567.89" unit="USD" />);
expect(container).toHaveTextContent('1’234’567.89');
});
it('should use apostrophe for thousand and dot for decimal and remove trailing zeros', () => {
(useContext as Mock).mockReturnValue({ nativeLocale: 'de-CH' });
const { container } = render(<Amount amount="1'234.56789000" unit="BTC" removeBtcTrailingZeroes />);
expect(container).toHaveTextContent('1’234.56789');
});
});

describe('de-DE', () => {
it('should use apostrophe for thousand and dot for decimal', () => {
(useContext as Mock).mockReturnValue({ nativeLocale: 'de-DE' });
const { container } = render(<Amount amount="1'000" unit="USD" />);
expect(container).toHaveTextContent('1.000');
});
it('should use dot for thousand and comma for decimal', () => {
(useContext as Mock).mockReturnValue({ nativeLocale: 'de-DE' });
const { container } = render(<Amount amount="1'234'567.89" unit="EUR" />);
expect(container).toHaveTextContent('1.234.567,89');
});
});

describe('en-GB', () => {
it('should use comma for thousand and dot for decimal', () => {
(useContext as Mock).mockReturnValue({ nativeLocale: 'en-GB' });
const { container } = render(<Amount amount="1'234'567.89" unit="GBP" />);
expect(container).toHaveTextContent('1,234,567.89');
});
});

describe('en-CA', () => {
it('should use comma for thousand and dot for decimal', () => {
(useContext as Mock).mockReturnValue({ nativeLocale: 'en-CA' });
const { container } = render(<Amount amount="1'234'567.89" unit="EUR" />);
expect(container).toHaveTextContent('1,234,567.89');
});
});

// describe('en-IN', () => {
// beforeEach(() => {
// vi.mocked(i18n).language = 'en-IN';
// });
// it('should use Indian numbering system using comma and dot for decimal', () => {
// const { container } = render(<Amount amount="1'234'567.89" unit="EUR" />);
// expect(container).toHaveTextContent('12,34,567.89');
// });
// });

describe('en-UK', () => {
it('should use comma for thousand and dot for decimal and remove trailing zeros', () => {
(useContext as Mock).mockReturnValue({ nativeLocale: 'en-UK' });
const { container } = render(<Amount amount="1'234.56789000" unit="BTC" removeBtcTrailingZeroes />);
expect(container).toHaveTextContent('1,234.56789');
});
});

describe('en-US', () => {
const fiatCoins: ConversionUnit[] = ['USD', 'EUR', 'CHF'];
fiatCoins.forEach(coin => {
it('should use comma for thousand and dot for decimal', () => {
(useContext as Mock).mockReturnValue({ nativeLocale: 'en-US' });
const { container } = render(<Amount amount="1'234'567.89" unit={coin} />);
expect(container).toHaveTextContent('1,234,567.89');
});
});
});

describe('es-ES', () => {
it('should use dot for thousand and comma for decimal', () => {
(useContext as Mock).mockReturnValue({ nativeLocale: 'es-ES' });
const { container } = render(<Amount amount="1'234'567.89" unit="EUR" />);
expect(container).toHaveTextContent('1.234.567,89');
});
it('should use space for thousand and comma for decimal', () => {
(useContext as Mock).mockReturnValue({ nativeLocale: 'es-ES' });
const { container } = render(<Amount amount="1'234'567.89" unit="EUR" />);
expect(container).toHaveTextContent('1.234.567,89');
});
});

describe('es-419', () => {
it('should use space for thousand and comma for decimal', () => {
(useContext as Mock).mockReturnValue({ nativeLocale: 'es-419' });
const { container } = render(<Amount amount="1'234'567.89" unit="EUR" />);
expect(container).toHaveTextContent('1,234,567.89');
});
});

describe('fr-CA', () => {
it('should use space for thousand and comma for decimal', () => {
(useContext as Mock).mockReturnValue({ nativeLocale: 'fr-CA' });
const { container } = render(<Amount amount="1'234'567.89" unit="EUR" />);
expect(container).toHaveTextContent('1 234 567,89');
});
});

describe('fr-FR', () => {
it('should use space for thousand and comma for decimal', () => {
(useContext as Mock).mockReturnValue({ nativeLocale: 'fr-FR' });
const { container } = render(<Amount amount="1'234'567.89" unit="EUR" />);
expect(container).toHaveTextContent('1 234 567,89');
});
});

describe('id-ID', () => {
it('should use dot for thousand and comma for decimal', () => {
(useContext as Mock).mockReturnValue({ nativeLocale: 'id-ID' });
const { container } = render(<Amount amount="1'234'567.89" unit="EUR" />);
expect(container).toHaveTextContent('1.234.567,89');
});
});

describe('it-IT', () => {
it('should use dot for thousand and comma for decimal', () => {
(useContext as Mock).mockReturnValue({ nativeLocale: 'it-IT' });
const { container } = render(<Amount amount="1'234'567.89" unit="EUR" />);
expect(container).toHaveTextContent('1.234.567,89');
});
});

describe('ja-JP', () => {
it('should use comma for thousand and dot for decimal', () => {
(useContext as Mock).mockReturnValue({ nativeLocale: 'ja-JP' });
const { container } = render(<Amount amount="1'234'567.89" unit="EUR" />);
expect(container).toHaveTextContent('1,234,567.89');
});
});

describe('ko-KR', () => {
it('should use comma for thousand and dot for decimal', () => {
(useContext as Mock).mockReturnValue({ nativeLocale: 'ko-KR' });
const { container } = render(<Amount amount="1'234'567.89" unit="EUR" />);
expect(container).toHaveTextContent('1,234,567.89');
});
});

describe('nl-NL', () => {
it('should use dot for thousand and comma for decimal', () => {
(useContext as Mock).mockReturnValue({ nativeLocale: 'nl-NL' });
const { container } = render(<Amount amount="1'234'567.89" unit="EUR" />);
expect(container).toHaveTextContent('1.234.567,89');
});
});

describe('pt-BR', () => {
it('should use dot for thousand and comma for decimal', () => {
(useContext as Mock).mockReturnValue({ nativeLocale: 'pt-BR' });
const { container } = render(<Amount amount="1'234'567.89" unit="EUR" />);
expect(container).toHaveTextContent('1.234.567,89');
});
});

describe('ru-RU', () => {
it('should use space for thousand and comma for decimal', () => {
(useContext as Mock).mockReturnValue({ nativeLocale: 'ru-RU' });
const { container } = render(<Amount amount="1'234'567.89" unit="EUR" />);
expect(container).toHaveTextContent('1 234 567,89');
});
});

describe('tr-TR', () => {
it('should use space for thousand and comma for decimal', () => {
(useContext as Mock).mockReturnValue({ nativeLocale: 'tr-TR' });
const { container } = render(<Amount amount="1'234'567.89" unit="EUR" />);
expect(container).toHaveTextContent('1.234.567,89');
});
});

describe('zh-CN', () => {
it('should use comma for thousand and dot for decimal', () => {
(useContext as Mock).mockReturnValue({ nativeLocale: 'zh-CN' });
const { container } = render(<Amount amount="1'234'567.89" unit="EUR" />);
expect(container).toHaveTextContent('1,234,567.89');
});
});

});
19 changes: 13 additions & 6 deletions frontends/web/src/components/amount/amount.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2023 Shift Crypto AG
* Copyright 2023-2024 Shift Crypto AG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -13,18 +13,22 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { useContext } from 'react';
import { Mock, afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { render } from '@testing-library/react';
import { Amount } from './amount';
import { CoinUnit, ConversionUnit } from './../../api/account';

vi.mock('react', () => ({
...vi.importActual('react'),
vi.mock('react', async () => ({
...(await vi.importActual('react')),
useContext: vi.fn(),
createContext: vi.fn()
}));

vi.mock('../../i18n/i18n', () => ({
i18n: { language: 'de-CH' },
}));

const validateSpacing = (values: string[], elements: Element[]) => {
// each element in `values` is an expected
Expand All @@ -49,7 +53,10 @@ const validateSpacing = (values: string[], elements: Element[]) => {
describe('Amount formatting', () => {

beforeEach(() => {
(useContext as Mock).mockReturnValue({ hideAmounts: false });
(useContext as Mock).mockReturnValue({
hideAmounts: false,
nativeLocale: 'de-CH'
});
});

describe('hide amounts', () => {
Expand Down Expand Up @@ -261,15 +268,15 @@ describe('Amount formatting', () => {
fiatCoins.forEach(coin => {
it('1\'340.25 ' + coin + ' with removeBtcTrailingZeroes enabled stays 1\'340.25', () => {
const { container } = render(<Amount amount="1'340.25" unit={coin} removeBtcTrailingZeroes/>);
expect(container).toHaveTextContent('1\'340.25');
expect(container).toHaveTextContent('1340.25');
});
it('218.00 ' + coin + ' with removeBtcTrailingZeroes enabled stays 218.00', () => {
const { container } = render(<Amount amount="218.00" unit={coin} removeBtcTrailingZeroes/>);
expect(container).toHaveTextContent('218.00');
});
it('1\'340.25 ' + coin + ' with removeBtcTrailingZeroes disabled stays 1\'340.25', () => {
const { container } = render(<Amount amount="1'340.25" unit={coin}/>);
expect(container).toHaveTextContent('1\'340.25');
expect(container).toHaveTextContent('1340.25');
});
it('218.00 ' + coin + ' with removeBtcTrailingZeroes disabled stays 218.00', () => {
const { container } = render(<Amount amount="218.00" unit={coin}/>);
Expand Down
Loading

0 comments on commit 7f33634

Please sign in to comment.