Skip to content

Commit 890dabd

Browse files
author
Said Shah
committed
Merge branch 'main' of github.com:AndcultureCode/AndcultureCode.JavaScript.React.Components into main
2 parents 42f60a7 + b3abb08 commit 890dabd

File tree

8 files changed

+298
-9
lines changed

8 files changed

+298
-9
lines changed
Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,60 @@
11
import React from "react";
2+
import faker from "faker";
3+
import { PasswordInput } from "./password-input";
4+
import { render, fireEvent } from "@testing-library/react";
5+
import uuid from "uuid";
6+
import { InputTypes } from "../constants/input-types";
27

38
describe("PasswordInput", () => {
4-
test.skip("TODO - https://github.com/AndcultureCode/AndcultureCode.JavaScript.React.Components/issues/7", () => {});
9+
test("when given default props, renders input", () => {
10+
// Arrange
11+
const testDataId = "testDataId";
12+
13+
// Act
14+
const { getByTestId } = render(
15+
<PasswordInput
16+
isVisible={true}
17+
id={uuid()}
18+
onChange={() => {}}
19+
testId={testDataId}
20+
/>
21+
);
22+
23+
// Assert
24+
expect(getByTestId(testDataId)).not.toBeNil();
25+
});
26+
27+
test("when onChange prop set, calls handler upon change", () => {
28+
// Arrange
29+
let isChecked = false;
30+
const handleChange = () => (isChecked = true);
31+
const testDataId = "testDataId";
32+
33+
// Act
34+
const { getByTestId } = render(
35+
<PasswordInput
36+
isVisible={true}
37+
id={uuid()}
38+
onChange={handleChange}
39+
testId={testDataId}
40+
/>
41+
);
42+
fireEvent.change(getByTestId(testDataId), {
43+
target: { value: faker.random.word() },
44+
});
45+
46+
// Assert
47+
expect(isChecked).toBeTrue();
48+
});
49+
50+
test("when isVisible prop set to false, renders with type password", () => {
51+
// Arrange & Act
52+
const { container } = render(
53+
<PasswordInput onChange={() => {}} isVisible={false} id={uuid()} />
54+
);
55+
const htmlInputElement = container.getElementsByTagName("input");
56+
57+
// Assert
58+
expect(htmlInputElement[0].type).toBe(InputTypes.Password);
59+
});
560
});

src/atoms/forms/password-input.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ const PasswordInput: React.FC<PasswordInputProps> = (
3939

4040
return (
4141
<input
42-
data-test-id={testId}
42+
data-testid={testId}
4343
disabled={disabled}
4444
id={id}
4545
maxLength={20}
Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,27 @@
11
import React from "react";
2+
import { TextInputIcon } from "./text-input-icon";
3+
import faker from "faker";
4+
import { render, fireEvent } from "@testing-library/react";
5+
import uuid from "uuid";
6+
import { Icons } from "../constants/icons";
27

38
describe("TextInputIcon", () => {
4-
test.skip("TODO - https://github.com/AndcultureCode/AndcultureCode.JavaScript.React.Components/issues/9", () => {});
9+
test("when default props, renders icon with input", () => {
10+
// Arrange
11+
const dataTestId = "dataTestId";
12+
const icon = Icons.Checkmark;
13+
14+
// Act
15+
const { getByTestId } = render(
16+
<TextInputIcon
17+
icon={icon}
18+
id={uuid()}
19+
onChange={() => {}}
20+
testId={dataTestId}
21+
/>
22+
);
23+
24+
// Assert
25+
expect(getByTestId(dataTestId)).not.toBeNil();
26+
});
527
});
Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,64 @@
11
import React from "react";
2+
import { TextInput } from "./text-input";
3+
import faker from "faker";
4+
import { render, fireEvent } from "@testing-library/react";
5+
import uuid from "uuid";
26

37
describe("TextInput", () => {
4-
test.skip("TODO - https://github.com/AndcultureCode/AndcultureCode.JavaScript.React.Components/issues/9", () => {});
8+
test("when default props, renders input", () => {
9+
// Arrange
10+
const dataTestId = "dataTestId";
11+
12+
// Act
13+
const { getByTestId } = render(
14+
<TextInput testId={dataTestId} onChange={() => {}} id={uuid()} />
15+
);
16+
17+
// Assert
18+
expect(getByTestId(dataTestId)).not.toBeNil();
19+
});
20+
21+
test("when onChange set, calls handler upon change", () => {
22+
// Arrange
23+
let isChecked = false;
24+
const dataTestId = "dataTestId";
25+
const handleChange = () => (isChecked = true);
26+
27+
// Act
28+
const { getByTestId } = render(
29+
<TextInput
30+
testId={dataTestId}
31+
onChange={handleChange}
32+
id={uuid()}
33+
/>
34+
);
35+
36+
fireEvent.change(getByTestId(dataTestId), {
37+
target: { value: faker.random.word() },
38+
});
39+
40+
// Assert
41+
expect(isChecked).toBeTrue();
42+
});
43+
44+
test("when maxLength prop set, renders with given value", () => {
45+
// Arrange
46+
const dataTestId = "dataTestId";
47+
const maximumLength = 999;
48+
49+
// Act
50+
const { getByTestId } = render(
51+
<TextInput
52+
id={uuid()}
53+
maxLength={maximumLength}
54+
onChange={() => {}}
55+
testId={dataTestId}
56+
/>
57+
);
58+
59+
// Assert
60+
expect(getByTestId(dataTestId).getAttribute("maxLength")).toBe(
61+
maximumLength.toString()
62+
);
63+
});
564
});

src/atoms/forms/text-input.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ const TextInput: React.FC<TextInputProps> = (props: TextInputProps) => {
4040
return (
4141
<input
4242
aria-labelledby={ariaLabelledBy}
43-
data-test-id={testId}
43+
data-testid={testId}
4444
disabled={disabled}
4545
id={id}
4646
placeholder={placeholder}
Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,104 @@
11
import React from "react";
2+
import faker from "faker";
3+
import {
4+
ProgressBar,
5+
ProgressBarStyles,
6+
ProgressBarErrorClass,
7+
} from "./progress-bar";
8+
import { render } from "@testing-library/react";
29

310
describe("ProgressBar", () => {
4-
test.skip("TODO - https://github.com/AndcultureCode/AndcultureCode.JavaScript.React.Components/issues/13", () => {});
11+
test("when default props, renders progress bar", () => {
12+
// Arrange
13+
const dataTestId = "dataTestId";
14+
15+
// Act
16+
const { getByTestId } = render(
17+
<ProgressBar value={faker.random.number(100)} testId={dataTestId} />
18+
);
19+
20+
// Assert
21+
expect(getByTestId(dataTestId)).not.toBeNil();
22+
});
23+
24+
test("when cssClassName set, renders with class name", () => {
25+
// Arrange
26+
const testCssClassName = "testCssClassName";
27+
28+
// Act
29+
const { container } = render(
30+
<ProgressBar
31+
cssClassName={testCssClassName}
32+
value={faker.random.number(100)}
33+
/>
34+
);
35+
const result = container.getElementsByClassName(testCssClassName);
36+
37+
// Assert
38+
expect(result).toHaveLength(1);
39+
});
40+
41+
test.each`
42+
style
43+
${ProgressBarStyles.Thick}
44+
${ProgressBarStyles.Thin}
45+
`("when style prop set, renders with $style", ({ style }) => {
46+
// Arrange
47+
const randomInt = faker.random.number(100);
48+
49+
// Act
50+
const { container } = render(
51+
<ProgressBar value={randomInt} style={style} />
52+
);
53+
const result = container.getElementsByClassName(style);
54+
55+
// Assert
56+
expect(result).toHaveLength(1);
57+
});
58+
59+
test(`when isErrored prop set, renders with ${ProgressBarErrorClass} class name`, () => {
60+
// Arrange
61+
const randomInt = faker.random.number(100);
62+
63+
// Act
64+
const { container } = render(
65+
<ProgressBar value={randomInt} isErrored={true} />
66+
);
67+
const result = container.getElementsByClassName(ProgressBarErrorClass);
68+
69+
// Assert
70+
expect(result).toHaveLength(1);
71+
});
72+
73+
test(`when value prop set > 100, renders with value 100`, () => {
74+
// Arrange
75+
const incorrectValue = 110;
76+
const maximumValue = 100;
77+
const dataTestId = "dataTestId";
78+
79+
// Act
80+
const { getByTestId } = render(
81+
<ProgressBar value={incorrectValue} testId={dataTestId} />
82+
);
83+
84+
// Assert
85+
expect(getByTestId(dataTestId).innerHTML).toContain(maximumValue);
86+
expect(getByTestId(dataTestId).innerHTML).not.toContain(incorrectValue);
87+
});
88+
89+
test(`when value prop set < 0, renders with value 0`, () => {
90+
// Arrange
91+
const incorrectValue = -10;
92+
const minimumValue = 0;
93+
const dataTestId = "dataTestId";
94+
95+
// Act
96+
const { getByTestId } = render(
97+
<ProgressBar value={incorrectValue} testId={dataTestId} />
98+
);
99+
100+
// Assert
101+
expect(getByTestId(dataTestId).innerHTML).toContain(minimumValue);
102+
expect(getByTestId(dataTestId).innerHTML).not.toContain(incorrectValue);
103+
});
5104
});

src/atoms/progress-bar/progress-bar.tsx

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
import React from "react";
22
import { StringUtils } from "andculturecode-javascript-core";
33

4+
// -------------------------------------------------------------------------------------------------
5+
// #region Constants
6+
// -------------------------------------------------------------------------------------------------
7+
8+
export const ProgressBarErrorClass = "-error";
9+
10+
// #endregion Constants
11+
412
// -------------------------------------------------------------------------------------------------
513
// #region Enums
614
// -------------------------------------------------------------------------------------------------
@@ -20,6 +28,12 @@ interface ProgressBarProps {
2028
cssClassName?: string;
2129
isErrored?: boolean;
2230
style?: ProgressBarStyles;
31+
32+
/**
33+
* Unique identifier used to select the underlying <div> for functional/e2e testing
34+
*/
35+
testId?: string;
36+
2337
value: number;
2438
}
2539

@@ -42,7 +56,7 @@ const ProgressBar: React.FC<ProgressBarProps> = (props: ProgressBarProps) => {
4256
}
4357

4458
if (props.isErrored) {
45-
classNames.push("-error");
59+
classNames.push(ProgressBarErrorClass);
4660
}
4761

4862
// value must be an integer 0 < value < 100
@@ -57,7 +71,7 @@ const ProgressBar: React.FC<ProgressBarProps> = (props: ProgressBarProps) => {
5771
}
5872

5973
return (
60-
<div className={classNames.join(" ")}>
74+
<div className={classNames.join(" ")} data-testid={props.testId}>
6175
<div className={`${CSS_CLASS_NAME}__bar -w-${value}`} />
6276
</div>
6377
);

src/molecules/form-fields/checkbox-form-field.test.tsx

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from "react";
2-
import { render } from "@testing-library/react";
2+
import { render, fireEvent } from "@testing-library/react";
33
import { CheckboxFormField } from "./checkbox-form-field";
44
import faker from "faker";
55

@@ -20,4 +20,44 @@ describe("CheckboxFormField", () => {
2020
// Assert
2121
expect(getByLabelText(expected)).not.toBeNull();
2222
});
23+
24+
test("when errorsMessage prop set, renders with error message", () => {
25+
// Arrange
26+
const label = faker.random.words();
27+
const testErrorMessage = "testErrorMessage";
28+
29+
// Act
30+
const { getByText } = render(
31+
<CheckboxFormField
32+
checked={false}
33+
errorMessage={testErrorMessage}
34+
label={label}
35+
onChange={() => {}}
36+
/>
37+
);
38+
39+
// Assert
40+
expect(getByText(testErrorMessage)).not.toBeNil();
41+
});
42+
43+
test("when onChange set, calls handler upon change", () => {
44+
// Arrange
45+
let isChecked = false;
46+
const handleChange = () => (isChecked = true);
47+
const label = faker.random.word();
48+
49+
// Act
50+
const { getByText } = render(
51+
<CheckboxFormField
52+
checked={isChecked}
53+
label={label}
54+
onChange={handleChange}
55+
/>
56+
);
57+
58+
fireEvent.click(getByText(label));
59+
60+
// Assert
61+
expect(isChecked).toBeTrue();
62+
});
2363
});

0 commit comments

Comments
 (0)