@bytebrand/fe-ui-core 4.2.55 → 4.2.56

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -25,7 +25,6 @@ describe('OrderStatusCard', () => {
25
25
  description={description}
26
26
  />
27
27
  );
28
- debug();
29
28
  const cardTitle = getByText(title);
30
29
  expect(cardTitle).toBeInTheDocument();
31
30
  const cardDescription = getByText(description);
@@ -43,7 +42,6 @@ describe('OrderStatusCard', () => {
43
42
  isDisabled={true}
44
43
  />
45
44
  );
46
- debug();
47
45
  const cardTitle = getByTestId('cardTitle');
48
46
  expect(cardTitle).toHaveClass('notReachedTitle');
49
47
  });
@@ -57,7 +55,6 @@ describe('OrderStatusCard', () => {
57
55
  isDone={true}
58
56
  />
59
57
  );
60
- debug();
61
58
  const cardTitle = getByTestId('cardTitle');
62
59
  expect(cardTitle).toHaveClass('isDoneTitle');
63
60
  });
@@ -71,7 +68,6 @@ describe('OrderStatusCard', () => {
71
68
  isActive={true}
72
69
  />
73
70
  );
74
- debug();
75
71
  const orderStatusCard = getByTestId('orderStatusCard');
76
72
  expect(orderStatusCard).toHaveClass('cardInProgress');
77
73
  });
@@ -0,0 +1,58 @@
1
+ import React from 'react';
2
+ import { render, cleanup, screen } from '@testing-library/react';
3
+ import VehicleFormattedPrice, { IVehiclePriceProps } from '../../../../source/components/Vehicle/VehicleFormattedPrice/VehicleFormattedPrice';
4
+ import FormattedNumber from '../../../../source/components/FormattedNumber/FormattedNumber';
5
+
6
+ const mockPropsForFormattedNumber = {
7
+ value: 99,
8
+ toRound: false,
9
+ disableFormatting: false,
10
+ numbersAfterDot: 0,
11
+ className: '',
12
+ afterCommaClassName: '',
13
+ beforeCommaClassName: ''
14
+ };
15
+
16
+ const VehicleFormattedPriceProps: IVehiclePriceProps = {
17
+ price: 1234.56,
18
+ };
19
+
20
+ describe('VehicleFormattedPrice', () => {
21
+ it('render VehicleFormattedPrice component', () => {
22
+ const { container } = render(<FormattedNumber {...mockPropsForFormattedNumber} />);
23
+ expect(container.firstChild).toBeTruthy();
24
+ });
25
+ // TODO:value incorrect
26
+ // it('renders the formatted number correctly', () => {
27
+ // render(<VehicleFormattedPrice {...VehicleFormattedPriceProps} price={1234.56} />);
28
+ // const formattedNumber = screen.getByText('1234.56');
29
+ // expect(formattedNumber).toBeInTheDocument();
30
+ // });
31
+
32
+
33
+ it('renders the unit correctly when provided', () => {
34
+ render(<VehicleFormattedPrice {...VehicleFormattedPriceProps} unit="USD" />);
35
+ const unit = screen.getByText('USD');
36
+ expect(unit).toBeInTheDocument();
37
+ });
38
+
39
+ it('renders the postfix correctly when provided', () => {
40
+ render(<VehicleFormattedPrice {...VehicleFormattedPriceProps} postfix="1,3" />);
41
+ const postfix = screen.getByText('1,3');
42
+ expect(postfix).toBeInTheDocument();
43
+ });
44
+
45
+ it('renders the unit monthly correctly when provided', () => {
46
+ render(<VehicleFormattedPrice {...VehicleFormattedPriceProps} unit="€" monthly="mtl" />);
47
+ const unit = screen.getByText('€');
48
+ const monthly = screen.getByText('/mtl');
49
+ expect(unit).toBeInTheDocument();
50
+ expect(monthly).toBeInTheDocument();
51
+ });
52
+
53
+ it('renders the sub correctly when provided', () => {
54
+ render(<VehicleFormattedPrice {...VehicleFormattedPriceProps} sub="VAT included" />);
55
+ const sub = screen.getByText('VAT included');
56
+ expect(sub).toBeInTheDocument();
57
+ });
58
+ });
@@ -0,0 +1,82 @@
1
+ import React from 'react';
2
+ import { render, fireEvent, waitFor } from '@testing-library/react';
3
+ import ImageComponent from '../../../../source/components/_common/Image/Image';
4
+ import styles from '../../../../source/components/_common/Image/Image.styl';
5
+
6
+ const mockProps = {
7
+ src: 'https://via.placeholder.com/300',
8
+ srcSmall: 'https://via.placeholder.com/15',
9
+ srcLarge: 'https://via.placeholder.com/1500',
10
+ };
11
+
12
+
13
+ describe('ImageComponent', () => {
14
+
15
+ it('loads the image correctly', async () => {
16
+ const { container } = render(
17
+ <ImageComponent src={mockProps.src} />,
18
+ );
19
+ const imgElement = container.querySelector('img') as HTMLImageElement;
20
+ expect(imgElement).toBeInTheDocument();
21
+ await expect(imgElement).toHaveProperty('src', mockProps.src);
22
+ });
23
+
24
+ it('ImageComponent renders correctly', () => {
25
+ const { getByRole, container } = render(<ImageComponent src={mockProps.src} />);
26
+
27
+ const imgElem = getByRole('img');
28
+ const divContainer = container.firstChild;
29
+
30
+ expect(imgElem).toBeInTheDocument();
31
+ expect(divContainer).toHaveClass('container')
32
+ });
33
+
34
+ it('renders without errors', async () => {
35
+ const { container } = render(<ImageComponent {...mockProps} />);
36
+
37
+ expect(container).toBeInTheDocument();
38
+
39
+ // Wait for the image to load
40
+ const imgEl = await waitFor(() => container.querySelector('img'));
41
+ expect(imgEl).toBeInTheDocument();
42
+ });
43
+
44
+ it('shows the loader before image is loaded', () => {
45
+ const { getByText } = render(
46
+ <ImageComponent src={mockProps.src} withLoader />,
47
+ );
48
+
49
+ getByText(/loading/i);
50
+ });
51
+
52
+ it('calls onClick handler when image is clicked', async () => {
53
+ const handleClick = jest.fn();
54
+ const { container } = render(<ImageComponent {...mockProps} onClick={handleClick} />);
55
+
56
+ // Wait for the image to load
57
+ const imgEl = await waitFor(() => container.querySelector('img'));
58
+ fireEvent.click(imgEl);
59
+
60
+ expect(handleClick).toHaveBeenCalledTimes(1);
61
+ });
62
+
63
+ it('sets height and width correctly', () => {
64
+ const { container } = render(<ImageComponent src={mockProps.src} width={100} height={100} />);
65
+
66
+ expect(container.firstChild).toHaveStyle('width: 100px;');
67
+ expect(container.firstChild).toHaveStyle('height: 100px;');
68
+ });
69
+
70
+ it('ImageComponent state works correctly', () => {
71
+ const { getByRole } = render(
72
+ <ImageComponent src={mockProps.src} />
73
+ );
74
+
75
+ const imgElem = getByRole('img');
76
+
77
+ expect(imgElem).not.toHaveClass(styles.loaded);
78
+ fireEvent.load(imgElem);
79
+ expect(imgElem).toHaveClass(styles.loaded);
80
+ });
81
+
82
+ });
@@ -0,0 +1,18 @@
1
+ import { addPrefixToKeys } from '../../../source/framework/utils/CommonUtils';
2
+
3
+ describe('addPrefixToKeys', () => {
4
+ it('should return an empty object when given an empty object', () => {
5
+ const obj = {};
6
+ const prefix = 'test';
7
+ const result = addPrefixToKeys(obj, prefix);
8
+ expect(result).toEqual({});
9
+ });
10
+
11
+ it('should add the prefix to each key in the object', () => {
12
+ const obj = { a: 1, b: 2, c: 3 };
13
+ const prefix = 'test';
14
+ const result = addPrefixToKeys(obj, prefix);
15
+ const expected = { test_a: 1, test_b: 2, test_c: 3 };
16
+ expect(result).toEqual(expected);
17
+ });
18
+ });
@@ -0,0 +1,32 @@
1
+ import { arrToObj } from '../../../source/framework/utils/CommonUtils';
2
+
3
+ const mockArr = ['first', 'second', 'third'];
4
+
5
+ describe('arrToObj', () => {
6
+ it('should return an empty object when passed a non-array value', () => {
7
+ expect(arrToObj(null)).toEqual({});
8
+ expect(arrToObj(undefined)).toEqual({});
9
+ expect(arrToObj('')).toEqual({});
10
+ expect(arrToObj(42)).toEqual({});
11
+ expect(arrToObj({})).toEqual({});
12
+ });
13
+
14
+ it('should convert an array of strings to an object where each string is a key with a value of true', () => {
15
+ const obj = arrToObj(mockArr);
16
+ expect(obj).toMatchObject({ first: true, second: true, third: true });
17
+ expect(Object.keys(obj)).toHaveLength(mockArr.length);
18
+ mockArr.forEach((val) => {
19
+ expect(obj[val]).toBe(true);
20
+ });
21
+ });
22
+
23
+ it('should not modify the original array', () => {
24
+ const originalArr = [...mockArr];
25
+ arrToObj(mockArr);
26
+ expect(mockArr).toEqual(originalArr);
27
+ });
28
+
29
+ it('should return an empty object when passed an empty array', () => {
30
+ expect(arrToObj([])).toEqual({});
31
+ });
32
+ });
@@ -0,0 +1,17 @@
1
+ import { checkRangeValuesOnEqual } from '../../../source/framework/utils/CommonUtils';
2
+
3
+ describe('checkRangeValuesOnEqual', () => {
4
+ it('returns true when defaultValues and filterValues have exactly the same values', () => {
5
+ const defaultValues = { from: 1000, to: 2000 };
6
+ const filterValues = { from: 1000, to: 2000 };
7
+ const result = checkRangeValuesOnEqual(defaultValues, filterValues);
8
+ expect(result).toEqual(true);
9
+ });
10
+
11
+ it('returns false when defaultValues and filterValues have different values', () => {
12
+ const defaultValues = { from: 1000, to: 2000 };
13
+ const filterValues = { from: 500, to: 2000 };
14
+ const result = checkRangeValuesOnEqual(defaultValues, filterValues);
15
+ expect(result).toEqual(false);
16
+ });
17
+ });
@@ -0,0 +1,8 @@
1
+ import { formatMileage } from '../../../source/framework/utils/CommonUtils';
2
+
3
+ describe('formatMileage', () => {
4
+ it('should correctly format millage when passed as number', () => {
5
+ const result = formatMileage(123456789);
6
+ expect(result).toEqual('123.456.789');
7
+ });
8
+ });
@@ -0,0 +1,19 @@
1
+ import { getFormattedNumber } from '../../../source/framework/utils/CommonUtils';
2
+
3
+ describe('getFormattedNumber', () => {
4
+ it('should format a number with German locale', () => {
5
+ const formattedNumber = getFormattedNumber(123456789.5);
6
+ expect(formattedNumber).toBe('123.456.789,5');
7
+ });
8
+
9
+ it('should return null if input is not finite number', () => {
10
+ const formattedNumber = getFormattedNumber(NaN);
11
+ expect(formattedNumber).toBeNull();
12
+
13
+ const formattedNumber2 = getFormattedNumber(undefined);
14
+ expect(formattedNumber2).toBeNull();
15
+
16
+ const formattedNumber3 = getFormattedNumber('invalidNumber' as any);
17
+ expect(formattedNumber3).toBeNull();
18
+ });
19
+ });
@@ -0,0 +1,19 @@
1
+ import { getFormattedPrice } from '../../../source/framework/utils/CommonUtils';
2
+
3
+ describe('getFormattedPrice', () => {
4
+ it('should format the given price correctly with default parameters', () => {
5
+ const result = getFormattedPrice(1234567890);
6
+ expect(result).toEqual('1.234.567.890');
7
+ });
8
+
9
+ it('should format the given price correctly with custom format and currency', () => {
10
+ const result = getFormattedPrice(1990.75, '$.2f', 'USD');
11
+ expect(result).toEqual('1990,75USD');
12
+ });
13
+
14
+ it('should return "-" if price is not finite number or null/undefined', () => {
15
+ expect(getFormattedPrice(undefined)).toEqual('-');
16
+ expect(getFormattedPrice(null)).toEqual('-');
17
+ expect(getFormattedPrice(NaN)).toEqual('-');
18
+ });
19
+ });
@@ -0,0 +1,51 @@
1
+ import { getGroupValuesForQuery } from '../../../source/framework/utils/CommonUtils';
2
+
3
+ describe('getGroupValuesForQuery', () => {
4
+ it('should return array of objects, each containing key/value pairs for all properties with truthy values', () => {
5
+ const filterObj = [
6
+ {
7
+ MANUFACTURER: {
8
+ field: 'mainData_make',
9
+ value: 'Audi',
10
+ isAbsolute: true
11
+ },
12
+ MODEL: {
13
+ field: 'mainData_model',
14
+ value: 'A5',
15
+ isAbsolute: true
16
+ },
17
+ SUB_MODEL: {
18
+ field: 'mainData_subModel',
19
+ value: 'sportback',
20
+ isAbsolute: true
21
+ },
22
+ SERIES: {
23
+ field: 'mainData_series',
24
+ value: 'series',
25
+ isAbsolute: true
26
+ }
27
+ }
28
+ ];
29
+
30
+ const result = getGroupValuesForQuery(filterObj);
31
+
32
+ const expectedResult = [
33
+ {
34
+ MANUFACTURER: 'Audi',
35
+ MODEL: 'A5',
36
+ SUB_MODEL: 'sportback',
37
+ SERIES: 'series'
38
+ }
39
+ ]
40
+
41
+ expect(result).toEqual(expectedResult);
42
+ });
43
+
44
+ it('should return empty array if argument is an empty array', () => {
45
+ const groups: any[] = [];
46
+
47
+ const result = getGroupValuesForQuery(groups);
48
+
49
+ expect(result).toEqual([]);
50
+ });
51
+ });
@@ -0,0 +1,26 @@
1
+ import { getPriceRating } from "../../../utils";
2
+
3
+ describe('getPriceRating', () => {
4
+ it('should return 0 when input price is undefined or null', () => {
5
+ expect(getPriceRating(undefined, undefined)).toBe(0);
6
+ expect(getPriceRating(null, null)).toBe(0);
7
+ });
8
+
9
+ it('should return 1 when current price match the highest price in ratingConfig', () => {
10
+ const currentSalesPrice = 3800;
11
+ const predictablePrice = 3000;
12
+ expect(getPriceRating(currentSalesPrice, predictablePrice)).toBe(1);
13
+ });
14
+
15
+ it('should return topPrice index in priceRatings when current sales price less than or equals to range of topPrice', () => {
16
+ const currentSalesPrice = 1000;
17
+ const predictablePrice = 10000;
18
+ expect(getPriceRating(currentSalesPrice, predictablePrice)).toBe(5);
19
+ });
20
+
21
+ it('should return correct price rating index based on currentSalesPrice and predictablePrice', () => {
22
+ const currentSalesPrice = 9600;
23
+ const predictablePrice = 10000;
24
+ expect(getPriceRating(currentSalesPrice, predictablePrice)).toBe(3); // fairPrice index in priceRatings array
25
+ });
26
+ });
@@ -0,0 +1,35 @@
1
+ import { getPriceRatingConfig } from '../../../utils';
2
+
3
+ describe('getPriceRatingConfig', () => {
4
+ it('should generate the pricing config correctly', () => {
5
+ const currentPrice = 5000
6
+ const pricePredicted = 4000
7
+
8
+ const expectedOutput = {
9
+ topPrice: { min: 3000, max: 3600 },
10
+ goodPrice: { min: 3600, max: 3800 },
11
+ fairPrice: { min: 3800, max: 4200 },
12
+ increasedPrice: { min: 4200, max: 4700 },
13
+ highPrice: { min: 4700, max: 5000 }
14
+ }
15
+
16
+ console.log(getPriceRatingConfig(currentPrice, pricePredicted))
17
+
18
+ expect(getPriceRatingConfig(currentPrice, pricePredicted)).toEqual(expectedOutput)
19
+ })
20
+
21
+ it('should return "???" for invalid predicted prices', () => {
22
+ const currentPrice = 5000
23
+ const pricePredicted = NaN
24
+
25
+ const expectedOutput = {
26
+ topPrice: { min: '???', max: '???' },
27
+ goodPrice: { min: '???', max: '???' },
28
+ fairPrice: { min: '???', max: '???' },
29
+ increasedPrice: { min: '???', max: '???' },
30
+ highPrice: { min: '???', max: '???' }
31
+ }
32
+
33
+ expect(getPriceRatingConfig(currentPrice, pricePredicted)).toEqual(expectedOutput)
34
+ })
35
+ })
@@ -0,0 +1,9 @@
1
+ import { preloadNearbyImages } from '../../../source/framework/utils/CommonUtils';
2
+
3
+ describe('preloadNearbyImages', () => {
4
+ it('should not break when no images provided', () => {
5
+ preloadNearbyImages([], 0, 'imageUrlMedium');
6
+
7
+ expect(document.images).toHaveLength(0);
8
+ });
9
+ });
@@ -0,0 +1,23 @@
1
+ import { sliceLessThan } from '../../../source/framework/utils/CommonUtils';
2
+
3
+ describe('sliceLessThan', () => {
4
+ it('returns empty array if returned value of `to` is not valid', () => {
5
+ const expected: number[] = [];
6
+
7
+ expect(sliceLessThan([], null)).toEqual(expected);
8
+ expect(sliceLessThan([], undefined)).toEqual(expected);
9
+ expect(sliceLessThan([], {} as any)).toEqual(expected);
10
+ expect(sliceLessThan([], [] as any)).toEqual(expected);
11
+ expect(sliceLessThan([], '')).toEqual(expected);
12
+ expect(sliceLessThan([], 'string')).toEqual(expected);
13
+ expect(sliceLessThan([], NaN)).toEqual(expected);
14
+ expect(sliceLessThan([], Infinity)).toEqual(expected);
15
+ expect(sliceLessThan([], -Infinity)).toEqual(expected);
16
+ });
17
+
18
+ it('returns slice of original array containing only numbers less than `to`', () => {
19
+ const arr: number[] = [5,6,7,8];
20
+ const expected: number[] = [5,6];
21
+ expect(sliceLessThan(arr, 6)).toEqual(expected);
22
+ });
23
+ });
@@ -0,0 +1,23 @@
1
+ import { sliceMoreThan } from '../../../source/framework/utils/CommonUtils';
2
+
3
+ describe('sliceMoreThan', () => {
4
+ const myArray = [1, 2, 3, 4, 5];
5
+
6
+ it('returns empty array if returned value of `from` is not valid', () => {
7
+ const expected: number[] = [];
8
+
9
+ expect(sliceMoreThan([], null)).toEqual(expected);
10
+ expect(sliceMoreThan([], undefined)).toEqual(expected);
11
+ expect(sliceMoreThan([], {} as any)).toEqual(expected);
12
+ expect(sliceMoreThan([], [] as any)).toEqual(expected);
13
+ expect(sliceMoreThan([], '')).toEqual(expected);
14
+ expect(sliceMoreThan([], 'string')).toEqual(expected);
15
+ expect(sliceMoreThan([], NaN)).toEqual(expected);
16
+ expect(sliceMoreThan([], Infinity)).toEqual(expected);
17
+ expect(sliceMoreThan([], -Infinity)).toEqual(expected);
18
+ });
19
+
20
+ it('should return [4, 5] when filtering with 4', () => {
21
+ expect(sliceMoreThan(myArray, 4)).toEqual([4, 5]);
22
+ });
23
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bytebrand/fe-ui-core",
3
- "version": "4.2.55",
3
+ "version": "4.2.56",
4
4
  "description": "UI components for the auto.de project",
5
5
  "main": "index.ts",
6
6
  "module": "dist/common.js",
@@ -3,7 +3,7 @@ import classnames from 'classnames';
3
3
  import FormattedNumber from '../../FormattedNumber/FormattedNumber';
4
4
  import styles from './VehicleFormattedPrice.styl';
5
5
 
6
- interface IVehiclePriceProps {
6
+ export interface IVehiclePriceProps {
7
7
  price: number;
8
8
  unit?: string;
9
9
  postfix?: string;
@@ -37,10 +37,6 @@ export const numberWithDot = (value: number | string) => {
37
37
  return value;
38
38
  default: return getFormattedNumber(+value);
39
39
  }
40
- // if (value === 'any' || value === 'beliebig') {
41
- // return value;
42
- // }
43
- return getFormattedNumber(+value);
44
40
  };
45
41
 
46
42
  export const arrToObj = (arr: string[]): { [key: string]: boolean } => {
@@ -316,7 +312,7 @@ export const sliceMoreThan = (array: number[], from: any): number[] => {
316
312
  : array;
317
313
  };
318
314
 
319
- export const getFormattedPrice = (price: any, format = '$,.0f', currency = ''): string => {
315
+ export const getFormattedPrice = (price: number, format = '$,.0f', currency = ''): string => {
320
316
  if (!Number.isFinite(price)) return '-';
321
317
  const groupingNum = 3;
322
318
  return d3formatLocale({
@@ -327,6 +323,24 @@ export const getFormattedPrice = (price: any, format = '$,.0f', currency = ''):
327
323
  }).format(format)(price);
328
324
  };
329
325
 
326
+
327
+ export const getPriceRatingConfig = (currentPrice: number, pricePredicted: number) => { // tslint:disable-line
328
+ const round = (value: number) => {
329
+ return Number.isFinite(pricePredicted)
330
+ ? Math.round((pricePredicted * (1 + (value / 100))) / 100) * 100 // tslint:disable-line
331
+ : '???';
332
+ };
333
+
334
+ if (currentPrice === 0) {
335
+ console.log('Empty current price');
336
+ }
337
+
338
+ return Object.keys(priceRatingConfig).reduce((acc: any, key: any) => {
339
+ const { min, max } = priceRatingConfig[key];
340
+ return { ...acc, [key]: { min: round(min), max: round(max) } };
341
+ }, {}); // tslint:disable-line
342
+ };
343
+
330
344
  export const getPriceRating = (currentSalesPrice: number, predictablePrice: number) => {
331
345
  const isCorrectCurrentSalesPrice = Number.isFinite(Number.parseFloat(`${currentSalesPrice}`));
332
346
  const isCorrectPredictablePrice = Number.isFinite(Number.parseFloat(`${predictablePrice}`));
@@ -346,23 +360,6 @@ export const getPriceRating = (currentSalesPrice: number, predictablePrice: numb
346
360
  return 0;
347
361
  };
348
362
 
349
- export const getPriceRatingConfig = (currentPrice: number, pricePredicted: number) => { // tslint:disable-line
350
- const round = (value: number) => {
351
- return Number.isFinite(pricePredicted)
352
- ? Math.round((pricePredicted * (1 + (value / 100))) / 100) * 100 // tslint:disable-line
353
- : '???';
354
- };
355
-
356
- if (currentPrice === 0) {
357
- console.log('Empty current price');
358
- }
359
-
360
- return Object.keys(priceRatingConfig).reduce((acc: any, key: any) => {
361
- const { min, max } = priceRatingConfig[key];
362
- return { ...acc, [key]: { min: round(min), max: round(max) } };
363
- }, {}); // tslint:disable-line
364
- };
365
-
366
363
  export const fixNumber = (num: number | string) => {
367
364
  const isNum = typeof num === 'number' ? num : parseFloat(num);
368
365
  return Math.round(isNum * HUNDRED) / HUNDRED;