@bigbinary/neetoui 3.2.76 → 3.2.79

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bigbinary/neetoui",
3
- "version": "3.2.76",
3
+ "version": "3.2.79",
4
4
  "main": "./index.js",
5
5
  "author": "BigBinary",
6
6
  "license": "MIT",
@@ -0,0 +1,117 @@
1
+ import React from "react";
2
+ import { render, screen, fireEvent } from "@testing-library/react";
3
+ import { ColorPicker } from "../lib/components";
4
+ import userEvent from "@testing-library/user-event";
5
+
6
+ describe("ColorPicker", () => {
7
+ it("should render without error", () => {
8
+ render(<ColorPicker color="#ffffff" />);
9
+ expect(screen.getByText("#ffffff")).toBeInTheDocument();
10
+ });
11
+
12
+ it("should trigger onChange when color is changed", () => {
13
+ const hex = "#000000";
14
+ const hsl = { a: 1, h: 0, l: 0, s: 0 };
15
+ const hsv = { a: 1, h: 0, v: 0, s: 0 };
16
+ const rgb = { a: 1, b: 0, g: 0, r: 0 };
17
+ const onChange = jest.fn((color) => {
18
+ expect(color.hex).toEqual(hex);
19
+ expect(color.hsl).toEqual(hsl);
20
+ expect(color.hsv).toEqual(hsv);
21
+ expect(color.rgb).toEqual(rgb);
22
+ });
23
+
24
+ render(<ColorPicker color="#ffffff" onChange={onChange} />);
25
+ userEvent.click(screen.getByText("#ffffff"));
26
+ userEvent.paste(screen.getByRole("textbox"), "000000");
27
+ expect(onChange).toHaveBeenCalledTimes(1);
28
+ });
29
+
30
+ it("should display color palette when colorPaletteProps is provided", () => {
31
+ render(<ColorPicker color="#ffffff" colorPaletteProps={{}} />);
32
+ userEvent.click(screen.getByText("#ffffff"));
33
+ expect(screen.getByTestId("color-palette")).toBeInTheDocument();
34
+ });
35
+
36
+ it("should trigger onChange when a color is selected from palette", () => {
37
+ const selectedColor = "#ffffff";
38
+ const DEFAULT_COLORS = {
39
+ "red-500": "#f56a58",
40
+ "yellow-500": "#f3cd82",
41
+ "green-500": "#00ba88",
42
+ "blue-500": "#276ef1",
43
+ };
44
+ const onChange = jest.fn();
45
+ render(
46
+ <ColorPicker
47
+ color={selectedColor}
48
+ colorPaletteProps={{
49
+ color: {
50
+ from: "red-500",
51
+ to: "red-500",
52
+ },
53
+ colorList: Object.keys(DEFAULT_COLORS).map((key) => ({
54
+ from: key,
55
+ to: key,
56
+ })),
57
+ onChange,
58
+ }}
59
+ />
60
+ );
61
+ userEvent.click(screen.getByText("#ffffff"));
62
+ const paletteItems = screen.getAllByTestId("color-palette-item");
63
+ userEvent.click(paletteItems[0]);
64
+ expect(onChange).toHaveBeenCalledTimes(1);
65
+ expect(onChange).toHaveBeenCalledWith("red-500", "red-500");
66
+ });
67
+
68
+ it("should call onChange when user touches Heu slider", () => {
69
+ const touchStart = [{ pageX: 0, pageY: 0 }];
70
+
71
+ const hex = "#000000";
72
+ const hsl = { a: 1, h: 0, l: 0, s: 0 };
73
+ const hsv = { a: 1, h: 0, v: 0, s: 0 };
74
+ const rgb = { a: 1, b: 0, g: 0, r: 0 };
75
+ const onChange = jest.fn((color) => {
76
+ expect(color.hex).toEqual(hex);
77
+ expect(color.hsl).toEqual(hsl);
78
+ expect(color.hsv).toEqual(hsv);
79
+ expect(color.rgb).toEqual(rgb);
80
+ });
81
+
82
+ render(<ColorPicker color="#ffffff" onChange={onChange} />);
83
+ userEvent.click(screen.getByText("#ffffff"));
84
+
85
+ fireEvent.touchStart(
86
+ screen.getByTestId("color-picker-hue").querySelector(".hue-horizontal"),
87
+ { touches: touchStart }
88
+ );
89
+
90
+ expect(onChange).toHaveBeenCalledTimes(1);
91
+ });
92
+
93
+ it("should call onChange when user touches Saturation selector", () => {
94
+ const touchStart = [{ pageX: 0, pageY: 0 }];
95
+
96
+ const hex = "#000000";
97
+ const hsl = { a: 1, h: 0, l: 0, s: 0 };
98
+ const hsv = { a: 1, h: 0, v: 0, s: 0 };
99
+ const rgb = { a: 1, b: 0, g: 0, r: 0 };
100
+ const onChange = jest.fn((color) => {
101
+ expect(color.hex).toEqual(hex);
102
+ expect(color.hsl).toEqual(hsl);
103
+ expect(color.hsv).toEqual(hsv);
104
+ expect(color.rgb).toEqual(rgb);
105
+ });
106
+
107
+ render(<ColorPicker color="#ffffff" onChange={onChange} />);
108
+ userEvent.click(screen.getByText("#ffffff"));
109
+
110
+ fireEvent.touchStart(
111
+ screen.getByTestId("color-picker-saturation").querySelector(".saturation-black"),
112
+ { touches: touchStart }
113
+ );
114
+
115
+ expect(onChange).toHaveBeenCalledTimes(1);
116
+ });
117
+ });
@@ -0,0 +1,75 @@
1
+ import React from "react";
2
+ import { render } from "@testing-library/react";
3
+ import { Input } from "../lib/components";
4
+ import userEvent from "@testing-library/user-event";
5
+
6
+ describe("Input", () => {
7
+ it("should render without error", () => {
8
+ const { getByLabelText } = render(<Input id="input" label="Input Label" />);
9
+ expect(getByLabelText("Input Label")).toBeInTheDocument();
10
+ });
11
+
12
+ it("should be able to type when uncontrolled", () => {
13
+ const { getByLabelText } = render(<Input id="input" label="Input Label" />);
14
+ const inputField = getByLabelText("Input Label");
15
+ userEvent.type(inputField, "sample content");
16
+ expect(inputField).toHaveValue("sample content");
17
+ });
18
+
19
+ it("should call onChange when textarea value changes", () => {
20
+ const onChange = jest.fn();
21
+ const { getByLabelText } = render(
22
+ <Input id="input" label="Input Label" onChange={onChange} />
23
+ );
24
+ userEvent.type(getByLabelText("Input Label"), "Test");
25
+ expect(onChange).toHaveBeenCalledTimes(4);
26
+ });
27
+
28
+ it("should display error message", () => {
29
+ const { getByText } = render(
30
+ <Input label="input" error={"Error message"} />
31
+ );
32
+ expect(getByText("Error message")).toBeInTheDocument();
33
+ });
34
+
35
+ it("should display helpText", () => {
36
+ const { getByText } = render(<Input label="Input" helpText="Help text" />);
37
+ expect(getByText("Help text")).toBeInTheDocument();
38
+ });
39
+
40
+ it("should be disabled if disabled is true", () => {
41
+ const { getByLabelText } = render(
42
+ <Input disabled id="input" label="Input Label" />
43
+ );
44
+ expect(getByLabelText("Input Label")).toBeDisabled();
45
+ });
46
+
47
+ it("should show suffix", () => {
48
+ const { getByText } = render(<Input label="input" suffix="suffix" />);
49
+ expect(getByText("suffix")).toBeInTheDocument();
50
+ });
51
+
52
+ it("should show prefix", () => {
53
+ const { getByText } = render(<Input label="input" prefix="prefix" />);
54
+ expect(getByText("prefix")).toBeInTheDocument();
55
+ });
56
+
57
+ it("should render asterisk when required is set to true", () => {
58
+ const { getByText } = render(<Input required label="Input" />);
59
+ const asterisk = getByText("*");
60
+ expect(asterisk).toBeInTheDocument();
61
+ });
62
+
63
+ it("should properly handle maxLength", () => {
64
+ const { getByLabelText, getByText } = render(
65
+ <Input id="input" label="Input label" maxLength={5} />
66
+ );
67
+
68
+ expect(getByText("0 / 5")).toBeInTheDocument();
69
+ expect(getByLabelText("Input label")).toHaveAttribute("maxLength", "5");
70
+
71
+ userEvent.type(getByLabelText("Input label"), "Testing maxLength");
72
+ expect(getByText("5 / 5")).toBeInTheDocument();
73
+ expect(getByLabelText("Input label")).toHaveValue("Testi");
74
+ });
75
+ });
@@ -0,0 +1,204 @@
1
+ import React from "react";
2
+ import { Table } from "../lib/components";
3
+ import { render, screen } from "@testing-library/react";
4
+ import userEvent from "@testing-library/user-event";
5
+
6
+ const columnData = [
7
+ {
8
+ dataIndex: 'id',
9
+ key: 'id',
10
+ title: 'ID',
11
+ width: 150
12
+ },
13
+ {
14
+ title: "First Name",
15
+ dataIndex: "first_name",
16
+ key: "first_name",
17
+ width: 150,
18
+ },
19
+ {
20
+ title: "Last Name",
21
+ dataIndex: "last_name",
22
+ key: "last_name",
23
+ width: 150,
24
+ }
25
+ ]
26
+
27
+ const rowData = [
28
+ {
29
+ id: 1,
30
+ first_name: "Oliver",
31
+ last_name: "Smith"
32
+ },
33
+ {
34
+ id: 2,
35
+ first_name: "Sam",
36
+ last_name: "Smith"
37
+ },
38
+ {
39
+ id: 3,
40
+ first_name: "Eve",
41
+ last_name: "Smith"
42
+ },
43
+ {
44
+ id: 4,
45
+ first_name: "Mark",
46
+ last_name: "Smith"
47
+ }
48
+ ]
49
+
50
+ describe("Table", () => {
51
+ it("should render column data without error", () => {
52
+ render(
53
+ <Table
54
+ columnData={columnData}
55
+ rowData={rowData}
56
+ />
57
+ )
58
+ const column = screen.getByText("ID")
59
+ expect(column).toBeInTheDocument();
60
+ });
61
+
62
+ it("should render row data without error", () => {
63
+ render(
64
+ <Table
65
+ columnData={columnData}
66
+ rowData={rowData}
67
+ />
68
+ )
69
+ const row = screen.getByText("1")
70
+ expect(row).toBeInTheDocument();
71
+ });
72
+
73
+ it("should render all the rows", () => {
74
+ render(
75
+ <Table
76
+ columnData={columnData}
77
+ rowData={rowData}
78
+ />
79
+ )
80
+ const row = screen.getAllByRole("row")
81
+ expect(row.length).toBe(4);
82
+ });
83
+
84
+ it("should render all the columns", () => {
85
+ render(
86
+ <Table
87
+ columnData={columnData}
88
+ rowData={rowData}
89
+ />
90
+ )
91
+ const column1 = screen.getByText("ID")
92
+ expect(column1).toBeInTheDocument();
93
+ const column2 = screen.getByText("First Name")
94
+ expect(column2).toBeInTheDocument();
95
+ const column3 = screen.getByText("Last Name")
96
+ expect(column3).toBeInTheDocument();
97
+ });
98
+
99
+ it("should have checkbox to select table row if rowSelection is set to true", () => {
100
+ render(
101
+ <Table
102
+ columnData={columnData}
103
+ rowData={rowData}
104
+ rowSelection
105
+ />
106
+ )
107
+ const checkboxes = screen.getAllByRole("checkbox")
108
+ expect(checkboxes.length).not.toBe(0);
109
+ });
110
+
111
+ it("should not have checkbox to select table row by default", () => {
112
+ render(
113
+ <Table
114
+ columnData={columnData}
115
+ rowData={rowData}
116
+ />
117
+ )
118
+ const checkbox = screen.queryByRole("checkbox")
119
+ expect(checkbox).not.toBeInTheDocument();
120
+ });
121
+
122
+ it("should call onRowSelect on row selection", () => {
123
+ const onRowSelect = jest.fn()
124
+ render(
125
+ <Table
126
+ columnData={columnData}
127
+ rowData={rowData}
128
+ onRowSelect={onRowSelect}
129
+ rowSelection
130
+ />
131
+ )
132
+ const checkbox = screen.getAllByRole("checkbox")
133
+ userEvent.click(checkbox[0])
134
+ expect(onRowSelect).toHaveBeenCalledTimes(1);
135
+ });
136
+
137
+ it("should call onRowClick on row click by default", () => {
138
+ const onRowClick = jest.fn()
139
+ render(
140
+ <Table
141
+ columnData={columnData}
142
+ rowData={rowData}
143
+ onRowClick={onRowClick}
144
+ />
145
+ )
146
+ const row = screen.getByText("1")
147
+ userEvent.click(row)
148
+ expect(onRowClick).toHaveBeenCalledTimes(1);
149
+ });
150
+
151
+ it("should not call onRowClick on row click when allowRowClick is disabled", () => {
152
+ const onRowClick = jest.fn()
153
+ render(
154
+ <Table
155
+ columnData={columnData}
156
+ rowData={rowData}
157
+ onRowClick={onRowClick}
158
+ allowRowClick={false}
159
+ />
160
+ )
161
+ const row = screen.getByText("1")
162
+ userEvent.click(row)
163
+ expect(onRowClick).toHaveBeenCalledTimes(0);
164
+ });
165
+
166
+ it("should render table with fixed height ", () => {
167
+ render(
168
+ <Table
169
+ columnData={columnData}
170
+ rowData={rowData}
171
+ fixedHeight
172
+ />
173
+ )
174
+ const row = screen.getByText("1")
175
+ expect(row).toBeInTheDocument();
176
+ });
177
+
178
+ it("should render table with rows equal to page size ", () => {
179
+ render(
180
+ <Table
181
+ columnData={columnData}
182
+ rowData={rowData}
183
+ defaultPageSize={2}
184
+ />
185
+ )
186
+ const row = screen.getAllByRole("row")
187
+ expect(row.length).toBe(2);
188
+ });
189
+
190
+ it("should call handlePageChange when page is changed ", () => {
191
+ const handlePageChange = jest.fn()
192
+ render(
193
+ <Table
194
+ columnData={columnData}
195
+ rowData={rowData}
196
+ defaultPageSize={2}
197
+ handlePageChange={handlePageChange}
198
+ />
199
+ )
200
+ const pages = screen.getAllByRole("listitem")
201
+ userEvent.click(pages[2])
202
+ expect(handlePageChange).toBeCalledTimes(1);
203
+ });
204
+ });
@@ -0,0 +1,217 @@
1
+ import React from "react";
2
+ import { Toastr, Button } from "../lib/components";
3
+ import { render, screen } from "@testing-library/react";
4
+ import userEvent from "@testing-library/user-event";
5
+ import { ToastContainer } from "react-toastify";
6
+
7
+ describe("Toastr", () => {
8
+ it("should render Info Toastr without error", async () => {
9
+ render(
10
+ <>
11
+ <ToastContainer/>
12
+ <Button
13
+ label="Info Toastr"
14
+ onClick={() => Toastr.info("This is an info toastr.")}
15
+ />
16
+ </>
17
+ );
18
+ const button = screen.getByText("Info Toastr");
19
+ userEvent.click(button);
20
+ const infoToastr = await screen.findByText("This is an info toastr.");
21
+ expect(infoToastr).toBeInTheDocument();
22
+ });
23
+
24
+ it("should render Warning Toastr without error", async () => {
25
+ render(
26
+ <>
27
+ <ToastContainer/>
28
+ <Button
29
+ label="Warning Toastr"
30
+ onClick={() => Toastr.warning("This is a warning toastr.")}
31
+ />
32
+ </>
33
+ );
34
+ const button = screen.getByText("Warning Toastr");
35
+ userEvent.click(button);
36
+ const warningToastr = await screen.findByText("This is a warning toastr.");
37
+ expect(warningToastr).toBeInTheDocument();
38
+ });
39
+
40
+ it("should render Success Toastr without error", async () => {
41
+ render(
42
+ <>
43
+ <ToastContainer/>
44
+ <Button
45
+ label="Success Toastr"
46
+ onClick={() => Toastr.success("This is a success toastr.")}
47
+ />
48
+ </>
49
+ );
50
+ const button = screen.getByText("Success Toastr");
51
+ userEvent.click(button);
52
+ const successToastr = await screen.findByText("This is a success toastr.");
53
+ expect(successToastr).toBeInTheDocument();
54
+ });
55
+
56
+ it("should render Toastr with CTA without error", async () => {
57
+ render(
58
+ <>
59
+ <ToastContainer/>
60
+ <Button
61
+ label="Toastr with CTA"
62
+ onClick={() =>
63
+ Toastr.error(
64
+ Error("Ticket marked as spam."),
65
+ "Block Customer",
66
+ () => alert("Customer blocked successfully!")
67
+ )
68
+ }
69
+ />
70
+ </>
71
+ );
72
+ const button = screen.getByText("Toastr with CTA");
73
+ userEvent.click(button);
74
+ const toastr = await screen.findByText("Ticket marked as spam.");
75
+ expect(toastr).toBeInTheDocument();
76
+ const alertMock = jest.spyOn(window,'alert').mockImplementation();
77
+ const callToAction = screen.getByText("Block Customer");
78
+ userEvent.click(callToAction);
79
+ expect(alertMock).toHaveBeenCalledTimes(1);
80
+ });
81
+
82
+ it("should render Error Toastr without error", async () => {
83
+ render(
84
+ <>
85
+ <ToastContainer/>
86
+ <Button
87
+ label="Error Toastr"
88
+ onClick={() =>
89
+ Toastr.error(Error("Some error occured!"))
90
+ }
91
+ />
92
+ </>
93
+ );
94
+ const button = screen.getByText("Error Toastr");
95
+ userEvent.click(button);
96
+ const errorToastr = await screen.findByText("Some error occured!");
97
+ expect(errorToastr).toBeInTheDocument();
98
+ });
99
+
100
+ it("should render a clickable message when the toastr has a link", async () => {
101
+ render(
102
+ <>
103
+ <ToastContainer/>
104
+ <Button
105
+ label="Info Toastr"
106
+ onClick={() => Toastr.info("https://github.com/bigbinary/neeto-ui")}
107
+ />
108
+ </>
109
+ );
110
+ const button = screen.getByText("Info Toastr");
111
+ userEvent.click(button);
112
+ const link = await screen.findByRole("link");
113
+ expect(link).toHaveAttribute("href", "https://github.com/bigbinary/neeto-ui");
114
+ })
115
+
116
+ it("should render plain text error toastr", async () => {
117
+ render(
118
+ <>
119
+ <ToastContainer/>
120
+ <Button
121
+ label="String Error"
122
+ onClick={() =>
123
+ Toastr.error("This is a plain text error toastr!")
124
+ }
125
+ />
126
+ </>
127
+ );
128
+ const button = screen.getByText("String Error");
129
+ userEvent.click(button);
130
+ const errorToastr = await screen.findByText("This is a plain text error toastr!");
131
+ expect(errorToastr).toBeInTheDocument();
132
+ });
133
+
134
+ it("should render Axios Error Toastr without error", async () => {
135
+ const onAxiosStringError = () => {
136
+ try {
137
+ // Dummy axios error object
138
+ const axiosError = {
139
+ isAxiosError: true,
140
+ config: {
141
+ url: "https://api.github.com/users/org",
142
+ },
143
+ response: {
144
+ data: {
145
+ error: "Not Found",
146
+ },
147
+ status: 404,
148
+ },
149
+ };
150
+ throw axiosError;
151
+ } catch (e) {
152
+ Toastr.error(e);
153
+ }
154
+ };
155
+ render(
156
+ <>
157
+ <ToastContainer/>
158
+ <Button label="Throw an axios error" onClick={onAxiosStringError} />
159
+ </>
160
+ );
161
+ const button = screen.getByText("Throw an axios error");
162
+ userEvent.click(button);
163
+ const axiosError = await screen.findByText("Not Found");
164
+ expect(axiosError).toBeInTheDocument();
165
+ });
166
+
167
+ it("should render Axios Error Toastr with array of error messages", async () => {
168
+ const onAxiosArrayError = () => {
169
+ try {
170
+ // Dummy axios error object
171
+ const axiosError = {
172
+ isAxiosError: true,
173
+ config: {
174
+ url: "https://api.github.com/users/org",
175
+ },
176
+ response: {
177
+ data: {
178
+ errors: ["A is required", "B is required"],
179
+ },
180
+ },
181
+ };
182
+ throw axiosError;
183
+ } catch (e) {
184
+ Toastr.error(e);
185
+ }
186
+ };
187
+ render(
188
+ <>
189
+ <ToastContainer/>
190
+ <Button
191
+ label="Throw an axios error with array of error messages"
192
+ onClick={onAxiosArrayError}
193
+ />
194
+ </>
195
+ );
196
+ const button = screen.getByText("Throw an axios error with array of error messages");
197
+ userEvent.click(button);
198
+ const axiosError = await screen.findByText("A is required B is required");
199
+ expect(axiosError).toBeInTheDocument();
200
+ });
201
+
202
+ it("should render Error Toastr with 'Something went wrong.' when there is no message passed explicitly", async () => {
203
+ render(
204
+ <>
205
+ <ToastContainer/>
206
+ <Button
207
+ label="Error Toastr"
208
+ onClick={() => Toastr.error()}
209
+ />
210
+ </>
211
+ );
212
+ const button = screen.getByText("Error Toastr");
213
+ userEvent.click(button);
214
+ const errorToastr = await screen.findByText("Something went wrong.");
215
+ expect(errorToastr).toBeInTheDocument();
216
+ });
217
+ });
@@ -0,0 +1,44 @@
1
+ import React from "react";
2
+ import { Tooltip, Typography } from "../lib/components";
3
+ import { render, screen, waitFor } from "@testing-library/react";
4
+ import userEvent from "@testing-library/user-event";
5
+
6
+ describe("Tooltip", () => {
7
+ it("should render on hover ", () => {
8
+ render(
9
+ <Tooltip content="Tooltip">
10
+ <Typography>Text</Typography>
11
+ </Tooltip>
12
+ );
13
+ const text = screen.getByText("Text")
14
+ userEvent.hover(text)
15
+ const tooltip = screen.getByText("Tooltip")
16
+ expect(tooltip).toBeInTheDocument();
17
+ });
18
+
19
+ it("should not render when user stops hovering", async () => {
20
+ render(
21
+ <Tooltip content="Tooltip" >
22
+ <Typography>Text</Typography>
23
+ </Tooltip>
24
+ );
25
+ const text = screen.getByText("Text")
26
+ userEvent.hover(text)
27
+ const tooltip = screen.getByText("Tooltip")
28
+ userEvent.unhover(text)
29
+ await waitFor(() => expect(tooltip).not.toBeVisible())
30
+ });
31
+
32
+ it("should auto hide tooltip after n milliseconds", async () => {
33
+ render(
34
+ <Tooltip content="Tooltip" hideAfter={100}>
35
+ <Typography>Text</Typography>
36
+ </Tooltip>
37
+ );
38
+
39
+ const text = screen.getByText("Text")
40
+ userEvent.hover(text)
41
+ const tooltip = screen.getByText("Tooltip")
42
+ await waitFor(() => expect(tooltip).not.toBeVisible())
43
+ });
44
+ });