Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
065423b
React challenge 1 header n video (#1)
Miri-AP Mar 31, 2021
9055083
Mini-Challenge 3: Init Player page
Apr 2, 2021
17a28d4
Move header test and add Search to input
Apr 3, 2021
d418b21
Update videoCard to handle click and test
Apr 3, 2021
7381c71
add video state hooks and test
Apr 7, 2021
5e585b1
Add VideoPlayer and update videoCard
Apr 7, 2021
c67a498
Fix lint
Apr 7, 2021
0309f18
Add default search and get videos from youtube api
Apr 7, 2021
3baa1b4
Fix lint and update test
Apr 7, 2021
feba03d
Update header style
Apr 9, 2021
9f880ba
Update VideoPlayer style
Apr 13, 2021
689d15f
Update VideoCard style and snapshots
Apr 14, 2021
ae4bf92
Mini-Challenge 4: Use reducer to pass videoList and update style
Apr 14, 2021
5938084
Use global context to handle history and search keyword
Apr 15, 2021
1fbbe8e
Remove repeated code
Apr 15, 2021
1803697
Update snapshots
Apr 15, 2021
072f38d
remove commented code
Apr 15, 2021
dfd754e
Challenge 5: Add routing
Apr 21, 2021
d7ca199
Add login files
Apr 21, 2021
6def00e
Update snapshots
Apr 21, 2021
434b392
Add login UI
Apr 21, 2021
c2f8172
* Replace link with usehistor
Apr 22, 2021
65733a9
Add header menu
Apr 22, 2021
33b9191
Allow user to log in and out
Apr 22, 2021
e04a5c5
Handle auth
Apr 22, 2021
2fb521a
update snapshots
Apr 22, 2021
c4126ed
Fix useHistory en test
Apr 29, 2021
4d1c207
Test login api
Apr 29, 2021
5ae4fd4
add private route and test reducer
Apr 29, 2021
9b3923e
Update Test
Apr 29, 2021
72a6a53
Fix Private Page render
Apr 29, 2021
f413c8e
Add test coverage file
Apr 29, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"plugins": ["prettier"],
"rules": {
"prettier/prettier": "error",
"react/jsx-filename-extension": "error",
"react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }],
"react-hooks/exhaustive-deps": "warn",
"import/no-unresolved": ["off", { "ignore": [".css$"] }],
"import/prefer-default-export": "off",
Expand Down
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
# Wizeline Academy - 2021 React Bootcamp

Please refere to the following [GIST](https://gist.github.com/erickwize/d7311bfc972080c162c43cbb7dc80587) for further instructions

Code sandbox: https://codesandbox.io/s/core-concepts-and-styling-evtvz

# Mini-Challenge 2: Intro to Testing
## Answer the following questions first

1. Using `create-react-app`, what do we need to set up for testing?
A: `create-react-app` comes with `Jest` and `react-testing-library` by default, but in order for `Jest` to locate them they need to have one of the following conventions:
- Files with `.js` suffix in` __tests__` folders, files with `.test.js` or `.spec.js`.
Jest can also be paired with other testing libraries/utilities like Enzyme but those must me installed using `yarn add` or `npm install`.

2. What components are worth to test in your development?
A: In my opinion it would be components that have some kind of interaction that can be mimicked and function used.

3. Can you apply TDD once you already created components?
A: Yes, the concept of TDD is to test first (create failing test) then make those test pass and finally refactor, so when adding new change to that component one can start using TDD, providing little by little more more of the TDD advantages.
_TDD is a cycle that is best done in chunks._
38,900 changes: 38,900 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

49 changes: 32 additions & 17 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,32 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.11.4",
"@babel/preset-env": "^7.13.10",
"@babel/preset-react": "^7.12.13",
"@testing-library/jest-dom": "^5.11.10",
"@testing-library/react": "^10.4.9",
"@testing-library/user-event": "^12.1.3",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"jest": "^26.6.0",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-router": "^5.2.0",
"react-router-dom": "^5.2.0",
"react-scripts": "3.4.3"
"react-scripts": "^4.0.3",
"react-test-renderer": "^17.0.1",
"styled-components": "^5.2.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"test": "jest",
"test:coverage": "jest --coverage --watchAll=false",
"coverage": "react-scripts test --env=jsdom --coverage --watchAll",
"eject": "react-scripts eject",
"lint": "eslint ./src --ext .js,.jsx",
"lint:fix": "eslint ./src --ext .js,.jsx --fix"
},
"devDependencies": {
"@testing-library/react-hooks": "^5.1.1",
"eslint-config-airbnb": "^18.2.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-eslint-comments": "^3.2.0",
Expand All @@ -29,8 +37,6 @@
"eslint-plugin-prettier": "^3.1.4",
"eslint-plugin-react": "^7.20.6",
"eslint-plugin-react-hooks": "^4.1.0",
"husky": "^4.2.5",
"lint-staged": "^10.2.13",
"prettier": "^2.1.1",
"pretty-quick": "^3.0.0"
},
Expand All @@ -46,16 +52,25 @@
"last 1 safari version"
]
},
"lint-staged": {
"*.{js, jsx, css, json}": [
"yarn run lint:fix",
"pretty-quick --staged",
"git add"
]
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
"jest": {
"collectCoverageFrom": [
"src/**/**.*.{js,jsx,ts,tsx}",
"src/**/*.{js,jsx,ts,tsx}",
"!<rootDir>/node_modules/",
"!<rootDir>/path/to/dir/"
],
"coveragePathIgnorePatterns": [
"/node_modules/",
"/src/serviceWorker.js",
"/src/index.js"
],
"coverageThreshold": {
"global": {
"statements": 70,
"branches": 70,
"lines": 70,
"functions": 70
}
}
}
}
148 changes: 148 additions & 0 deletions src/__tests__/_App.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import React from 'react';
import { screen, cleanup, render, fireEvent } from '@testing-library/react';
import { renderHook, act } from '@testing-library/react-hooks';
import AppLayout from '../components/App';
import Favorites from '../pages/Favs';

import NotFound from '../pages/NotFound';
import { useVideoInfo, useVideList, reducer, initalState } from '../providers/GlobalContext';
import VideoMock from '../utils/mock/youtube-videos-mock.json';

afterEach(() => {
cleanup();
});

const MockVideoInfo = VideoMock.items[1].snippet;
const videoDataMock = {
channelId: 'UCPGzT4wecuWM0BH9mPiulXg',
channelTitle: 'Wizeline',
description:
'Follow Hector Padilla, Wizeline Director of Engineering, for a lively tour of our office. In 2018, Wizeline opened its stunning new office in Guadalajara, Jalisco, ...',
liveBroadcastContent: 'none',
publishTime: '2019-09-30T23:54:32Z',
publishedAt: '2019-09-30T23:54:32Z',
thumbnails: {
default: {
height: 90,
url: 'https://i.ytimg.com/vi/nmXMgqjQzls/default.jpg',
width: 120,
},
high: {
height: 360,
url: 'https://i.ytimg.com/vi/nmXMgqjQzls/hqdefault.jpg',
width: 480,
},
medium: {
height: 180,
url: 'https://i.ytimg.com/vi/nmXMgqjQzls/mqdefault.jpg',
width: 320,
},
},
title: 'Video Tour | Welcome to Wizeline Guadalajara',
};

it('Should render NotFound', () => {
const notFoundPage = render(<NotFound />);
expect(notFoundPage).toMatchSnapshot();
const notfound = screen.getByTestId('not-found');
expect(notfound).toBeInTheDocument();
});

it('Should render Favorites', () => {
const favorites = render(<Favorites />);
expect(favorites).toMatchSnapshot();
});

it('Should render App', () => {
act(() => {
const app = render(<AppLayout />);
expect(app).toMatchSnapshot();
});
const headerMenu = screen.getByTestId('yt-header');
expect(headerMenu).toBeInTheDocument();
});

it('Should render App Header', () => {
act(() => {
render(<AppLayout />);
});
const headerMenu = screen.getByTestId('yt-header');
expect(headerMenu).toBeInTheDocument();
const SearchInput = screen.getByPlaceholderText('Search...');
expect(SearchInput).toBeInTheDocument();
SearchInput.focus();
fireEvent.change(SearchInput, { target: { value: 'rise against' } });
expect(SearchInput.value).toBe('rise against');
fireEvent.keyDown(SearchInput, { key: 'Enter', code: 'Enter' });
});

it('Test useVideoInfo Hook', () => {
const { result } = renderHook(() => useVideoInfo());
expect(result.current.video).toEqual({});
expect(typeof result.current.updateVideoInfo).toBe('function');

act(() => {
result.current.updateVideoInfo(MockVideoInfo);
});
expect(result.current.video).toEqual(videoDataMock);
});

it('Test useVideList Hook', () => {
const { result } = renderHook(() => useVideList());
expect(result.current.videoList).toEqual([]);
expect(typeof result.current.updateVideoList).toBe('function');
act(() => {
result.current.updateVideoList([
VideoMock.items[0],
VideoMock.items[1],
VideoMock.items[3],
]);
});
const videoList = [VideoMock.items[0], VideoMock.items[1], VideoMock.items[3]];
expect(result.current.videoList).toEqual(videoList);
});

it('Test Reducer function', () => {
expect(reducer(initalState, {type: 'SET_HISTORY', payload: 'Shinee' })).toEqual({
...initalState,
history: 'Shinee',
});
expect(reducer(initalState, {type: 'SET_LIGHT_MODE' })).toEqual(initalState);
expect(reducer(initalState, {type: 'SET_DARK_MODE' })).toEqual({
...initalState,
header: {
background: '#fea79c',
input: '#0e4b79'
},
card: {
background: '#f9c7ae',
textColor: '#0e4b79',
},
background: '#0e4b79'
});
expect(reducer(initalState, {type: 'SET_SEARCH_KEYWORD', payload: 'Glass Animals' }));
expect(reducer(initalState, {type: 'SET_FAVS_LIST', payload: { 'id': videoDataMock }}));
expect(reducer(initalState, {type: 'REMOVE_USER_INFO', payload: 'Glass Animals' })).toEqual(initalState);
expect(reducer(initalState, {type: 'SET_USER_INFO', payload: {
id: '123',
name: 'Wizeline',
avatarUrl:
'https://media.glassdoor.com/sqll/868055/wizeline-squarelogo-1473976610815.png',
}})).toEqual({
...initalState,
user: {
id: '123',
name: 'Wizeline',
avatarUrl:
'https://media.glassdoor.com/sqll/868055/wizeline-squarelogo-1473976610815.png',
}
});
})

it('Test Reducer: unkown action', () => {
try {
expect(reducer(initalState, { type: 'UNKOWN_ACTION' }));
} catch (e) {
expect(e.message).toBe('ACTION NOT RECOGNIZED');
}
})
56 changes: 56 additions & 0 deletions src/__tests__/_Favs.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React from 'react';
import { cleanup, render} from '@testing-library/react';
import { useHistory } from 'react-router-dom';
import UserFavorites from '../pages/Favs';
import { GlobalContext, initalState } from '../providers/GlobalContext';

import { storage } from '../utils/storage';
import { FAVORITE_VIDEOS_KEY, AUTH_STORAGE_KEY } from '../utils/constants';

const dispatch = jest.fn();
const selectCard = jest.fn();
jest.mock('react-router-dom', () => ({
useHistory: () => ({
push: jest.fn(),
}),
}));

const favsList = {
HYyRZiwBWc8: {
channel: 'Wizeline',
channelId: 'UCPGzT4wecuWM0BH9mPiulXg',
description:
'Wizeline continues to offer a Silicon Valley culture in burgeoning innovation hubs like Mexico and Vietnam. In 2018, our Guadalajara team moved into a ...',
link: 'https://www.youtube.com/embed/HYyRZiwBWc8?autoplay=1&color=white',
thumbnail: 'https://i.ytimg.com/vi/HYyRZiwBWc8/mqdefault.jpg',
title: 'Wizeline Guadalajara | Bringing Silicon Valley to Mexico',
uploadDate: 'April 18, 2019',
videoId: 'HYyRZiwBWc8',
},
Po3VwR_NNGk: {
channel: 'El Economista TV',
channelId: 'UCXmAOGwFYxIq5qrScJeeV4g',
description:
'En el 2014, Bismarck fundó Wizeline, compañía tecnológica que trabaja con los corporativos ofreciendo una plataforma para que desarrollen software de forma ...',
link: 'https://www.youtube.com/embed/Po3VwR_NNGk?autoplay=1&color=white',
thumbnail: 'https://i.ytimg.com/vi/Po3VwR_NNGk/mqdefault.jpg',
title: 'Wizeline hace sentir a empleados como en casa',
uploadDate: 'March 4, 2019',
videoId: 'Po3VwR_NNGk',
}
}
storage.set(FAVORITE_VIDEOS_KEY, favsList);
storage.set(AUTH_STORAGE_KEY, true);

afterEach(() => {
cleanup();
});

it('Private: Not auth', () => {
const favs = render(
<GlobalContext.Provider value={{ ...initalState, favoritesList: favsList }}>
<UserFavorites selectCard={selectCard} dispatch={dispatch} />
</GlobalContext.Provider>
);
expect(favs).toMatchSnapshot();
});
70 changes: 70 additions & 0 deletions src/__tests__/_Header.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import React from 'react';
import { screen, cleanup, render, fireEvent } from '@testing-library/react';
import { act } from '@testing-library/react-hooks';
import { useHistory } from 'react-router-dom';

import HeaderMenu from '../components/Header';

jest.mock('react-router-dom', () => ({
useHistory: () => ({
push: jest.fn(),
}),
}));

afterEach(() => {
cleanup();
});

const doSearch = jest.fn();

it('Should render Header', () => {
const header = render(<HeaderMenu />);
const headerComponent = screen.getByTestId('yt-header');
expect(headerComponent).toBeInTheDocument();
expect(headerComponent).toContainHTML('Dark mode');
expect(headerComponent).toContainHTML('input');
expect(header).toMatchSnapshot();
});

it('Toggle Header Dark mode', () => {
render(<HeaderMenu />);

const switchInput = screen.getByLabelText('Dark mode', { type: 'checkbox' });
expect(switchInput).toBeInTheDocument();
fireEvent(
switchInput,
new MouseEvent('click', {
checked: true,
})
);
expect(switchInput.checked).toBe(true);
fireEvent(
switchInput,
new MouseEvent('click', {
checked: false,
})
);
expect(switchInput.checked).toBe(false);
});

it('Search value change', () => {
render(<HeaderMenu doSearch={doSearch} />);

const SearchInput = screen.getByPlaceholderText('Search...');
expect(SearchInput).toBeInTheDocument();
SearchInput.focus();
fireEvent.change(SearchInput, { target: { value: 'wizeline' } });
expect(SearchInput.value).toBe('wizeline');

fireEvent.keyDown(SearchInput, { key: 'Enter', code: 'Enter' });
setTimeout(() => {
expect(doSearch).toHaveBeenCalledWith('wizeline');
}, 10);

fireEvent.blur(SearchInput, { key: 'Enter', code: 'Enter' });
setTimeout(() => {
act(() => {
expect(doSearch).toHaveBeenCalledWith('wizeline');
});
}, 10);
});
Loading