epam-ai-conductor 0.1.0

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.
Files changed (115) hide show
  1. package/README.md +46 -0
  2. package/bin/workshop.js +6 -0
  3. package/dist/auth-check.d.ts +1 -0
  4. package/dist/auth-check.js +45 -0
  5. package/dist/auth-check.js.map +1 -0
  6. package/dist/cli.d.ts +2 -0
  7. package/dist/cli.js +156 -0
  8. package/dist/cli.js.map +1 -0
  9. package/dist/content/content/module-1/task/module-1_home-task_components.md +257 -0
  10. package/dist/content/content/module-1/task/module-1_home-task_good_practices.md +69 -0
  11. package/dist/content/content/module-1/task/module-1_home-task_task.md +253 -0
  12. package/dist/content/content/module-1/tests/Button.test.tsx +22 -0
  13. package/dist/content/content/module-1/tests/CourseCard.test.tsx +64 -0
  14. package/dist/content/content/module-1/tests/CourseInfo.test.tsx +73 -0
  15. package/dist/content/content/module-1/tests/Courses.test.tsx +87 -0
  16. package/dist/content/content/module-1/tests/Header.test.tsx +23 -0
  17. package/dist/content/content/module-1/tests/Input.test.tsx +36 -0
  18. package/dist/content/content/module-1/tests/helpers.test.ts +13 -0
  19. package/dist/content/content/module-1/theory/module-1_elements-render.md +66 -0
  20. package/dist/content/content/module-1/theory/module-1_hooks_useEffect.md +178 -0
  21. package/dist/content/content/module-1/theory/module-1_hooks_useState.md +131 -0
  22. package/dist/content/content/module-1/theory/module-1_react.md +64 -0
  23. package/dist/content/content/module-1/theory/module-1_spa.md +74 -0
  24. package/dist/content/content/module-2/task/module-2_home-task_components.md +313 -0
  25. package/dist/content/content/module-2/task/module-2_home-task_good_practices.md +35 -0
  26. package/dist/content/content/module-2/task/module-2_home-task_task.md +210 -0
  27. package/dist/content/content/module-2/tests/App.test.tsx +54 -0
  28. package/dist/content/content/module-2/tests/Login.test.tsx +73 -0
  29. package/dist/content/content/module-2/tests/Registration.test.tsx +70 -0
  30. package/dist/content/content/module-2/tests/SearchBar.test.tsx +39 -0
  31. package/dist/content/content/module-2/theory/module-2_custom-hooks.md +201 -0
  32. package/dist/content/content/module-2/theory/module-2_hooks.md +117 -0
  33. package/dist/content/content/module-2/theory/module-2_react-router.md +328 -0
  34. package/dist/content/content/module-3/task/module-3_home-task_components.md +94 -0
  35. package/dist/content/content/module-3/task/module-3_home-task_good_practices.md +26 -0
  36. package/dist/content/content/module-3/task/module-3_home-task_task.md +170 -0
  37. package/dist/content/content/module-3/tests/App.test.tsx +54 -0
  38. package/dist/content/content/module-3/tests/Courses.test.tsx +87 -0
  39. package/dist/content/content/module-3/tests/CreateAuthor.test.tsx +44 -0
  40. package/dist/content/content/module-3/tests/CreateCourse.test.tsx +122 -0
  41. package/dist/content/content/module-3/theory/module-3_redux-hooks.md +194 -0
  42. package/dist/content/content/module-3/theory/module-3_state-actions-reducers.md +445 -0
  43. package/dist/content/content/module-4/task/module-4_home-task_components.md +187 -0
  44. package/dist/content/content/module-4/task/module-4_home-task_task.md +139 -0
  45. package/dist/content/content/module-4/tests/App.test.tsx +54 -0
  46. package/dist/content/content/module-4/tests/Courses.test.tsx +87 -0
  47. package/dist/content/content/module-4/tests/CreateCourse.test.tsx +122 -0
  48. package/dist/content/content/module-4/tests/Login.test.tsx +73 -0
  49. package/dist/content/content/module-4/theory/module-4_async-redux.md +99 -0
  50. package/dist/content/content/module-4/theory/module-4_private-routes.md +55 -0
  51. package/dist/content/content/module-5/task/module-5_home-task_instruction.md +68 -0
  52. package/dist/content/content/module-5/task/module-5_home-task_task.md +154 -0
  53. package/dist/content/content/module-5/tests/App.test.tsx +54 -0
  54. package/dist/content/content/module-5/tests/CourseCard.test.tsx +64 -0
  55. package/dist/content/content/module-5/tests/Courses.test.tsx +87 -0
  56. package/dist/content/content/module-5/tests/Header.test.tsx +23 -0
  57. package/dist/content/content/module-5/theory/module-5_react-testing-library_example.md +379 -0
  58. package/dist/content/content/module-5/theory/module-5_redux-writing-tests.md +246 -0
  59. package/dist/content/module-1/task/module-1_home-task_components.md +257 -0
  60. package/dist/content/module-1/task/module-1_home-task_good_practices.md +69 -0
  61. package/dist/content/module-1/task/module-1_home-task_task.md +253 -0
  62. package/dist/content/module-1/tests/Button.test.tsx +22 -0
  63. package/dist/content/module-1/tests/CourseCard.test.tsx +64 -0
  64. package/dist/content/module-1/tests/CourseInfo.test.tsx +73 -0
  65. package/dist/content/module-1/tests/Courses.test.tsx +87 -0
  66. package/dist/content/module-1/tests/Header.test.tsx +23 -0
  67. package/dist/content/module-1/tests/Input.test.tsx +36 -0
  68. package/dist/content/module-1/tests/helpers.test.ts +13 -0
  69. package/dist/content/module-1/theory/module-1_elements-render.md +66 -0
  70. package/dist/content/module-1/theory/module-1_hooks_useEffect.md +178 -0
  71. package/dist/content/module-1/theory/module-1_hooks_useState.md +131 -0
  72. package/dist/content/module-1/theory/module-1_react.md +64 -0
  73. package/dist/content/module-1/theory/module-1_spa.md +74 -0
  74. package/dist/content/module-2/task/module-2_home-task_components.md +313 -0
  75. package/dist/content/module-2/task/module-2_home-task_good_practices.md +35 -0
  76. package/dist/content/module-2/task/module-2_home-task_task.md +210 -0
  77. package/dist/content/module-2/tests/App.test.tsx +54 -0
  78. package/dist/content/module-2/tests/Login.test.tsx +73 -0
  79. package/dist/content/module-2/tests/Registration.test.tsx +70 -0
  80. package/dist/content/module-2/tests/SearchBar.test.tsx +39 -0
  81. package/dist/content/module-2/theory/module-2_custom-hooks.md +201 -0
  82. package/dist/content/module-2/theory/module-2_hooks.md +117 -0
  83. package/dist/content/module-2/theory/module-2_react-router.md +328 -0
  84. package/dist/content/module-3/task/module-3_home-task_components.md +94 -0
  85. package/dist/content/module-3/task/module-3_home-task_good_practices.md +26 -0
  86. package/dist/content/module-3/task/module-3_home-task_task.md +170 -0
  87. package/dist/content/module-3/tests/App.test.tsx +54 -0
  88. package/dist/content/module-3/tests/Courses.test.tsx +87 -0
  89. package/dist/content/module-3/tests/CreateAuthor.test.tsx +44 -0
  90. package/dist/content/module-3/tests/CreateCourse.test.tsx +122 -0
  91. package/dist/content/module-3/theory/module-3_redux-hooks.md +194 -0
  92. package/dist/content/module-3/theory/module-3_state-actions-reducers.md +445 -0
  93. package/dist/content/module-4/task/module-4_home-task_components.md +187 -0
  94. package/dist/content/module-4/task/module-4_home-task_task.md +139 -0
  95. package/dist/content/module-4/tests/App.test.tsx +54 -0
  96. package/dist/content/module-4/tests/Courses.test.tsx +87 -0
  97. package/dist/content/module-4/tests/CreateCourse.test.tsx +122 -0
  98. package/dist/content/module-4/tests/Login.test.tsx +73 -0
  99. package/dist/content/module-4/theory/module-4_async-redux.md +99 -0
  100. package/dist/content/module-4/theory/module-4_private-routes.md +55 -0
  101. package/dist/content/module-5/task/module-5_home-task_instruction.md +68 -0
  102. package/dist/content/module-5/task/module-5_home-task_task.md +154 -0
  103. package/dist/content/module-5/tests/App.test.tsx +54 -0
  104. package/dist/content/module-5/tests/CourseCard.test.tsx +64 -0
  105. package/dist/content/module-5/tests/Courses.test.tsx +87 -0
  106. package/dist/content/module-5/tests/Header.test.tsx +23 -0
  107. package/dist/content/module-5/theory/module-5_react-testing-library_example.md +379 -0
  108. package/dist/content/module-5/theory/module-5_redux-writing-tests.md +246 -0
  109. package/dist/content-loader.d.ts +7 -0
  110. package/dist/content-loader.js +26 -0
  111. package/dist/content-loader.js.map +1 -0
  112. package/dist/context-builder.d.ts +2 -0
  113. package/dist/context-builder.js +116 -0
  114. package/dist/context-builder.js.map +1 -0
  115. package/package.json +40 -0
@@ -0,0 +1,154 @@
1
+ ---
2
+ sidebar_position: 1
3
+ sidebar_label: "TASK"
4
+ title: "Module 5. React Tests"
5
+ ---
6
+
7
+ This is the last part of the application.
8
+ In this assignment,
9
+ you should continue to work on your project with a slight modification.
10
+ This module was designed to teach how to work with tests in React.
11
+
12
+ ## Prerequisite:
13
+
14
+ You need to add a new script for your application and install `Jest` as devDependency module.
15
+
16
+ 1. Go to your project directory
17
+
18
+ 2. Add a command `npm run test:nowatch` to the **prepublish** script in the `package.json` file.
19
+
20
+ Result in the package.json:
21
+
22
+ ```js
23
+ "prepublish": "npm run eslint:fix && npm run test:nowatch"
24
+ ```
25
+
26
+ Result in the app:
27
+ If some of your unit tests are failed you will not be able to commit your changes.
28
+
29
+ 3. Install `Jest`.
30
+
31
+ :::info
32
+ If Create React App was used to create the project, this step can be skipped as CRA ships with Jest.
33
+ :::
34
+
35
+ ```http request
36
+ npm i jest --save-dev
37
+ ```
38
+
39
+ 4. Create new folders and `.test.js` file with tests:
40
+
41
+ ```
42
+ src
43
+ |
44
+ |-- components
45
+ | |-- Header
46
+ | | |__ tests
47
+ | | | |__ header.test.js //file for tests
48
+ | | |
49
+ | | |__ ...
50
+ | |
51
+ | |
52
+ | |-- Courses
53
+ | | |-- tests
54
+ | | | |__ courses.test.js //file for tests
55
+ | | |
56
+ | | |__ components
57
+ | | |__ CourseCard
58
+ | | | |__ tests
59
+ | | | | |__ courseCard.test.js //file for tests
60
+ | | | |
61
+ | | | |__ ...
62
+ | | |
63
+ | | |__ ...
64
+ | |
65
+ | |__ ...
66
+ |
67
+ |-- store
68
+ | |-- tests
69
+ | | |__ reducer.test.js //file for tests
70
+ | |
71
+ | |__ ...
72
+ |
73
+ |__ // ...
74
+ ```
75
+
76
+ 5. Run your tests.
77
+
78
+ ```http request
79
+ npm run test
80
+ ```
81
+
82
+ :::info
83
+ Use `.test.js` extension for files with tests
84
+ :::
85
+
86
+ :::caution
87
+ When you run your tests (`npm run test`) they will crash because you
88
+ have files with a `.test.js` extension without tests.
89
+ This problem will go away when you add tests to these files.
90
+ ![](./images/testError.jpg)
91
+ :::
92
+
93
+ ## Criteria (20 points max)
94
+
95
+ ### Add test for **Header**:
96
+
97
+ - [2 points] - **Header** should have logo and user's name.
98
+
99
+ ### Add tests for **CourseCard**:
100
+
101
+ - [1 point] - **CourseCard** should display title.
102
+
103
+ - [1 point] - **CourseCard** should display description.
104
+
105
+ - [1 point] - **CourseCard** should display duration in the correct format.
106
+
107
+ - [2 point] - **CourseCard** should display authors list.
108
+
109
+ - [1 point] - **CourseCard** should display created date in the correct format.
110
+
111
+ ### Add tests for **Courses**:
112
+
113
+ - [2 points] - **Courses** should display amount of CourseCard equal length of courses array.
114
+
115
+ - [3 points] - **CourseForm** should be shown after a click on the "Add new course" button.
116
+
117
+ ### Add tests for **coursesReducer**:
118
+
119
+ - [1 point] - **reducer** should return the initial state.
120
+
121
+ - [1 point] - **reducer** should handle SAVE_COURSE and returns new state.
122
+
123
+ ### Script in the `package.json`:
124
+
125
+ - [5 points] - pre-commit hook works correctly:
126
+ - There is no ability to commit changes if some of unit tests are failed.
127
+
128
+ :::info
129
+ To run all task run `npm run test:nowatch`
130
+ :::
131
+
132
+ ### EXTRA TASK:
133
+
134
+ ### Add tests for **CourseForm** (update or create mode):
135
+
136
+ :::note
137
+ If you decided to do the extra task, YOU ARE A STAR ⭐
138
+ Don't forget to create appropriate folder and test file.
139
+
140
+ By the way, it's the last task in this course. Thank you for coming to the end 😎
141
+
142
+ :::
143
+
144
+ - **CourseForm** should show authors lists (all and course authors).
145
+
146
+ - **CourseForm** 'Create author' button click should call dispatch.
147
+
148
+ - **CourseForm** 'Add author' button click should add an author to the course authors list.
149
+
150
+ - **CourseForm** 'Delete author' button click should delete an author from the course list.
151
+
152
+ :::info
153
+ Find information about tests writing in the [INSTRUCTIONS](instruction).
154
+ :::
@@ -0,0 +1,54 @@
1
+ import "@testing-library/jest-dom";
2
+ import { render, screen } from "@testing-library/react";
3
+ import { MemoryRouter } from "react-router-dom";
4
+ import App from "../App";
5
+
6
+ describe("App", () => {
7
+ test("renders Login component when token is not present", () => {
8
+ localStorage.removeItem("token");
9
+ render(
10
+ <MemoryRouter initialEntries={["/"]}>
11
+ <App />
12
+ </MemoryRouter>
13
+ );
14
+
15
+ expect(
16
+ screen.getByText(/If you don't have an account you can/)
17
+ ).toBeInTheDocument();
18
+ });
19
+
20
+ test("renders Courses component when token is present", () => {
21
+ localStorage.setItem("token", "token");
22
+ render(
23
+ <MemoryRouter initialEntries={["/"]}>
24
+ <App />
25
+ </MemoryRouter>
26
+ );
27
+
28
+ const courseElements = screen.getAllByTestId("courseCard");
29
+
30
+ expect(courseElements[0]).toBeInTheDocument();
31
+ });
32
+
33
+ test("renders Registration component", () => {
34
+ render(
35
+ <MemoryRouter initialEntries={["/registration"]}>
36
+ <App />
37
+ </MemoryRouter>
38
+ );
39
+
40
+ expect(screen.getByLabelText("name")).toBeInTheDocument();
41
+ expect(screen.getByLabelText("email")).toBeInTheDocument();
42
+ expect(screen.getByLabelText("password")).toBeInTheDocument();
43
+ });
44
+
45
+ test("renders course add component", () => {
46
+ render(
47
+ <MemoryRouter initialEntries={["/courses/add"]}>
48
+ <App />
49
+ </MemoryRouter>
50
+ );
51
+
52
+ expect(screen.getByTestId("titleInput")).toBeInTheDocument();
53
+ });
54
+ });
@@ -0,0 +1,64 @@
1
+ import "@testing-library/jest-dom";
2
+ import { render, screen } from "@testing-library/react";
3
+ import { CourseCard } from "../components/Courses/components/CourseCard/CourseCard";
4
+
5
+ describe('CourseCard component', () => {
6
+ const course = {
7
+ id: "1",
8
+ title: "Course Title",
9
+ description: "Course Description",
10
+ creationDate: "08/03/2021",
11
+ duration: 60,
12
+ authors: [
13
+ "27cc3006-e93a-4748-8ca8-73d06aa93b6d",
14
+ "f762978b-61eb-4096-812b-ebde22838167",
15
+ ],
16
+ };
17
+
18
+ test("Should contain title", () => {
19
+ render(<CourseCard course={course} />);
20
+
21
+ const titleElement = screen.getByText("Course Title");
22
+
23
+ expect(titleElement).toBeInTheDocument();
24
+ });
25
+
26
+ test("Should contain description", () => {
27
+ render(<CourseCard course={course} />);
28
+ const descriptionElement = screen.getByText("Course Description");
29
+ expect(descriptionElement).toBeInTheDocument();
30
+ });
31
+
32
+ test("Should contain duration", () => {
33
+ render(<CourseCard course={course} />);
34
+
35
+ const durationElement = screen.getByText(/01:00 hour/);
36
+
37
+ expect(durationElement).toBeInTheDocument();
38
+ });
39
+
40
+ test("Should contain date", () => {
41
+ render(<CourseCard course={course} />);
42
+
43
+ const creationDateElement = screen.getByText(/08.03.2021/);
44
+
45
+ expect(creationDateElement).toBeInTheDocument();
46
+ });
47
+
48
+ test("Should contain authors list", () => {
49
+ render(<CourseCard course={course} />);
50
+
51
+ const creationDateElement = screen.getByText(/Vasiliy Dobkin, Nicolas Kim/);
52
+
53
+ expect(creationDateElement).toBeInTheDocument();
54
+ });
55
+
56
+ test("Should contain authors list", () => {
57
+ render(<CourseCard course={course} />);
58
+
59
+ const creationDateElement = screen.getByText(/Show course/);
60
+
61
+ expect(creationDateElement).toBeInTheDocument();
62
+ });
63
+ })
64
+
@@ -0,0 +1,87 @@
1
+ import "@testing-library/jest-dom";
2
+ import { render, screen } from "@testing-library/react";
3
+ import { Courses } from "../components/Courses/Courses";
4
+
5
+ describe('Courses component', () => {
6
+ const mockedCoursesList = [
7
+ {
8
+ id: "1",
9
+ title: "Course 1",
10
+ description: "Course 1 description",
11
+ creationDate: "2022-01-01",
12
+ duration: 60,
13
+ authors: [
14
+ "27cc3006-e93a-4748-8ca8-73d06aa93b6d",
15
+ "f762978b-61eb-4096-812b-ebde22838167",
16
+ ],
17
+ },
18
+ {
19
+ id: "2",
20
+ title: "Course 2",
21
+ description: "Course 2 description",
22
+ creationDate: "2022-02-01",
23
+ duration: 90,
24
+ authors: ["df32994e-b23d-497c-9e4d-84e4dc02882f"],
25
+ },
26
+ ];
27
+ const onAddClick = jest.fn();
28
+
29
+ test("Should render list of courses", () => {
30
+ render(<Courses courseList={mockedCoursesList} onAddClick={onAddClick} setSelectedCourseId={(id) => {}}/>);
31
+
32
+ const courseElements = screen.getAllByTestId("courseCard");
33
+
34
+ expect(courseElements[0]).toBeInTheDocument();
35
+ expect(courseElements).toHaveLength(2);
36
+ });
37
+
38
+ test("Should render 'Add new course' button", () => {
39
+ render(<Courses courseList={mockedCoursesList} onAddClick={onAddClick} setSelectedCourseId={(id) => {}}/>);
40
+
41
+ const button = screen.getByText(/Add new course/);
42
+
43
+ expect(button).toBeInTheDocument();
44
+ });
45
+
46
+ test("Should render EmptyCourseList component if no courses", () => {
47
+ const mockedEmptyCoursesList: [] = [];
48
+ render(<Courses courseList={mockedEmptyCoursesList} onAddClick={onAddClick} setSelectedCourseId={(id) => {}}/>);
49
+
50
+ const emptyContainerElement = screen.getByTestId("emptyContainer");
51
+ const addButtonElement = screen.getByTestId("addCourse");
52
+
53
+ expect(emptyContainerElement).toBeInTheDocument();
54
+ expect(addButtonElement).toBeInTheDocument();
55
+ });
56
+ })
57
+
58
+ describe('EmptyCourseList', () => {
59
+ const mockedEmptyCoursesList: [] = [];
60
+ const onAddClick = jest.fn();
61
+
62
+ test("Should render title", () => {
63
+ render(<Courses courseList={mockedEmptyCoursesList} onAddClick={onAddClick} setSelectedCourseId={(id) => {}}/>);
64
+
65
+ const title = screen.getByText(/Your List Is Empty/);
66
+
67
+ expect(title).toBeInTheDocument();
68
+ });
69
+
70
+ test("Should render subtitle", () => {
71
+ render(<Courses courseList={mockedEmptyCoursesList} onAddClick={onAddClick} setSelectedCourseId={(id) => {}}/>);
72
+
73
+ const subTitle = screen.getByText(/Please use/);
74
+
75
+ expect(subTitle).toBeInTheDocument();
76
+ });
77
+
78
+ test("Should render button", () => {
79
+ render(<Courses courseList={mockedEmptyCoursesList} onAddClick={onAddClick} setSelectedCourseId={(id) => {}}/>);
80
+
81
+ const button = screen.getByText('ADD NEW COURSE');
82
+
83
+ expect(button).toBeInTheDocument();
84
+ });
85
+ })
86
+
87
+
@@ -0,0 +1,23 @@
1
+ import "@testing-library/jest-dom";
2
+ import { render, screen } from "@testing-library/react";
3
+ import { Header } from "../components/Header/Header";
4
+
5
+ describe('Header component', () => {
6
+ test("Should render logo", () => {
7
+ render(<Header />);
8
+
9
+ const imageElement = screen.getByRole("img");
10
+
11
+ expect(imageElement).toBeInTheDocument();
12
+ });
13
+
14
+ test("Should render logout button", () => {
15
+ render(<Header />);
16
+
17
+ const logoutButtonElement = screen.getByRole("button");
18
+
19
+ expect(logoutButtonElement).toBeInTheDocument();
20
+ });
21
+ })
22
+
23
+