Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

minichallenge4 solved #85

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
38 changes: 32 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,41 @@
"dependencies": {
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^10.4.9",
"@testing-library/react-hooks": "^7.0.1",
"@testing-library/user-event": "^12.1.3",
"jest-environment-jsdom-sixteen": "^2.0.0",
"axios": "^0.21.1",
"dotenv": "^8.2.0",
"enzyme": "^3.11.0",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-router": "^5.2.0",
"react-router-dom": "^5.2.0",
"react-scripts": "3.4.3"
"react-scripts": "3.4.3",
"styled-components": "^5.3.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"test": "react-scripts test --env=jest-environment-jsdom-sixteen",
"test:coverage": "npm run test -- --coverage --watchAll=false",
"eject": "react-scripts eject",
"lint": "eslint ./src --ext .js,.jsx",
"lint:fix": "eslint ./src --ext .js,.jsx --fix"
},
"devDependencies": {
"eslint": "^6.8.0",
"eslint-config-airbnb": "^18.2.0",
"eslint-config-google": "^0.14.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-eslint-comments": "^3.2.0",
"eslint-plugin-import": "^2.22.0",
"eslint-plugin-jsx-a11y": "^6.3.1",
"eslint-plugin-prettier": "^3.1.4",
"eslint-plugin-react": "^7.20.6",
"eslint-plugin-react": "^7.24.0",
"eslint-plugin-react-hooks": "^4.1.0",
"husky": "^4.2.5",
"jest-html-reporter": "^3.4.1",
"lint-staged": "^10.2.13",
"prettier": "^2.1.1",
"pretty-quick": "^3.0.0"
Expand All @@ -54,8 +64,24 @@
]
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
"hooks": {}
},
"jest": {
"coveragePathIgnorePatterns": [
Copy link

@ghost ghost Aug 13, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should remove the next files for this config:

"/src/providers",
"/src/providers",
"/src/config",
"/src/helpers/",
"/src/utils/",
"/src/index.js",
"/src/components/Fortune",
"/pages/NotFound",
"/components/App/"

They are part of the current app, so they should be included on the code coverage testing.

Please remove and update the code coverage report.

Any question or comment let me know.

"/node_modules/",
"/src/img/",
"/src/mocks",
"/src/providers",
"/src/config",
"/src/helpers/",
"/src/utils/",
"/src/index.js",
"/src/components/Fortune",
"/src/components/Private",
"/pages/Login",
"/pages/Secret",
"/pages/NotFound",
"/components/App/"
]
}
}
52 changes: 52 additions & 0 deletions src/__tests__/header.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import {render,screen} from '@testing-library/react'
import React from 'react';
import ThemeState from '../context/theme/themeState';
import VideoState from '../context/video/VideoState';
import Header from '../components/Header'

describe('Header component tests',()=>{

beforeEach(() => {
render(<VideoState><ThemeState><Header/></ThemeState></VideoState>)
});

test('should containt a toggle button',()=>{
const toggle=screen.getByRole('checkbox')
expect(toggle).toBeInTheDocument()
})

test('Toggle button should be checkbox type',()=>{
const toggle=screen.getByRole('checkbox')
expect(toggle).toHaveAttribute('type', 'checkbox')
})

test('Toggle button should containt a label',()=>{
const toggle=screen.queryByLabelText(/Light Mode/i)
expect(toggle).toBeInTheDocument()
})

test('should containt a login component',()=>{
const login=screen.getByTestId(/avatar_login/i)
expect(login).toBeInTheDocument()
})

test('should containt a search form',()=>{
const search=screen.getByTestId(/search_form/i)
expect(search).toBeInTheDocument()
})

test('search field should be disabled',()=>{
const search=screen.getByTestId(/search_field/i)
expect(search).not.toHaveAttribute('disabled')
})

test('should containt a hamburguer menu',()=>{
const menu=screen.getByTestId(/hamburguerMenu/i)
expect(menu).toBeInTheDocument()
})

test('menu should be type checkbox',()=>{
const menu=screen.getByTestId(/hamburguerMenu/i)
expect(menu).toHaveAttribute('type', 'checkbox')
})
})
18 changes: 18 additions & 0 deletions src/__tests__/home.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { render, screen } from '@testing-library/react';
import React from 'react';
import ThemeState from '../context/theme/themeState';
import VideoState from '../context/video/videoState';


import Home from '../pages/Home';

describe('Home view tests', () => {
beforeEach(() => {
render(<VideoState><ThemeState><Home/></ThemeState></VideoState>)
});

test('should containt specific title', () => {
const title = screen.getByText(/Youtube challenge/i)
expect(title).toBeInTheDocument();
});
});
37 changes: 37 additions & 0 deletions src/__tests__/useVideoApi.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from 'react';
import useVideoApi from '../hooks/useVideoApi';
import { renderHook, act } from '@testing-library/react-hooks';

describe('UseVideoApi tests', () => {
test('shouldn´t return any videos', async () => {
const { result } = renderHook(() => useVideoApi());
const { data, loading, error } = result.current;
expect(data).toBe(null);
expect(error).toBe(null);
expect(loading).toBe(false);
});

test('should return a video array', async () => {
const params = { q: 'wizeline' };
const { result, waitForNextUpdate } = renderHook(() => useVideoApi());
const { fetchVideos } = result.current;
await act(async() => fetchVideos({ params }));
waitForNextUpdate();
const { data,error,loading } = result.current;
expect(data.items.length).toBe(24);
expect(error).toBe(null);
expect(loading).toBe(false);
});

test('should return a video array with the related videos', async () => {
const params = { relatedToVideoId: "lWQ69WX7-hA", type: 'video' };
const { result, waitForNextUpdate } = renderHook(() => useVideoApi());
const { fetchVideos } = result.current;
await act(async() => fetchVideos({ params }));
waitForNextUpdate();
const { data,error,loading } = result.current;
expect(data.items.length).toBe(24);
expect(error).toBe(null);
expect(loading).toBe(false);
});
});
55 changes: 55 additions & 0 deletions src/__tests__/videoCard.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { render, screen } from '@testing-library/react';
import React from 'react';

import VideoCard from '../components/VideoCard';
import ThemeState from '../context/theme/themeState';
import VideoState from '../context/video/videoState';

describe('VideoCard component tests', () => {
const video = {
url: 'https://i.ytimg.com/vi/nmXMgqjQzls/mqdefault.jpg',
title: 'Video Tour | Welcome to Wizeline Guadalajara',
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, ...',
publishedAt: '2014-09-27',
};
beforeEach(() => {
render(
<VideoState>
<ThemeState>
<VideoCard
image={video.url}
title={video.title}
description={video.description}
createdAt={video.publishedAt}
/>
</ThemeState>
</VideoState>
);
});

test('should containt a card container', () => {
const card = screen.getByTestId(/card_container/i);
expect(card).toBeInTheDocument();
});

test('should containt a header image', () => {
const cardImage = screen.getByTestId(/img_header/i);
expect(cardImage.src).toBe(video.url);
});

test('should containt a card title', () => {
const cardTitle = screen.queryByText(video.title);
expect(cardTitle).toBeInTheDocument();
});

test('should containt a card description', () => {
const cardDescription = screen.queryByText(video.description);
expect(cardDescription).toBeInTheDocument();
});

test('should containt a video creation date', () => {
const videoCreation = screen.queryByText(video.publishedAt);
expect(videoCreation).toBeInTheDocument();
});
});
44 changes: 44 additions & 0 deletions src/__tests__/videoDetails.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { render, screen,waitFor } from '@testing-library/react';
import React from 'react';
import ThemeState from '../context/theme/themeState';
import VideoState from '../context/video/videoState';
import VideoDetails from '../pages/Details';
import {createMemoryHistory} from 'history'
import {Router} from 'react-router-dom'

describe('Details view tests', () => {
beforeEach(() => {
const history = createMemoryHistory()
const videoId="lWQ69WX7-hA"
history.push(`/video/${videoId}`)
render(
<Router history={history}>
<VideoState>
<ThemeState>
<VideoDetails />
</ThemeState>
</VideoState>
</Router>
);
});

test('should containt a main container', () => {
const container = screen.getByTestId(/container-details/i);
expect(container).toBeInTheDocument();
});

test('should containt a video description', () => {
// const titleVideo = screen.findByText(/una librería para crear interfaces web/i);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remember to remove commented code

waitFor(()=>expect(screen.findByText(/una librería para crear interfaces web/i)).toBeInTheDocument());
});

test('should containt a video title', () => {
// const titleVideo = screen.findByText(/una librería para crear interfaces web/i);
waitFor(()=>expect(screen.findByText(/Qué es React/i)).toBeInTheDocument());
});

test('should containt a video iframe', () => {
// const titleVideo = screen.findByText(/una librería para crear interfaces web/i);
waitFor(()=>expect(screen.findByRole(/iframe/i)).toBeInTheDocument());
});
});
27 changes: 27 additions & 0 deletions src/__tests__/videoList.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { render, screen} from '@testing-library/react';
import React from 'react';
import VideoList from '../components/VideoList';
import ThemeState from '../context/theme/themeState';
import VideoState from '../context/video/videoState';

describe('VideoList component tests', () => {
beforeEach(() => {
render(<VideoState><ThemeState><VideoList/></ThemeState></VideoState>)
});

test('should containt a list container', () => {
const list = screen.getByTestId(/container_videos/i);
expect(list).toBeInTheDocument();
});


test('shouldn´t containt a card video list', () => {
const list = screen.queryAllByTestId(/list_videos/i);
expect(list.length).toBe(0);
});

test('should containt a card video list',async () => {
const list = screen.findAllByTestId(/list_videos/i);
expect((await list).length).toBe(24)
});
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This are good test cases, but remember to mock the api call.https://jestjs.io/docs/mock-functions

42 changes: 9 additions & 33 deletions src/components/App/App.component.jsx
Original file line number Diff line number Diff line change
@@ -1,56 +1,32 @@
import React, { useLayoutEffect } from 'react';
import React, { useContext } from 'react';
import { BrowserRouter, Switch, Route } from 'react-router-dom';

import AuthProvider from '../../providers/Auth';
import HomePage from '../../pages/Home';
import LoginPage from '../../pages/Login';
import NotFound from '../../pages/NotFound';
import SecretPage from '../../pages/Secret';
import Private from '../Private';
import Fortune from '../Fortune';
import Layout from '../Layout';
import { random } from '../../utils/fns';
import VideoDetails from '../../pages/Details';
import GlobalStyle from '../../utils/globalStyles.styled';
import ThemeContext from '../../context/theme/themeContext';

function App() {
useLayoutEffect(() => {
const { body } = document;

function rotateBackground() {
const xPercent = random(100);
const yPercent = random(100);
body.style.setProperty('--bg-position', `${xPercent}% ${yPercent}%`);
}

const intervalId = setInterval(rotateBackground, 3000);
body.addEventListener('click', rotateBackground);

return () => {
clearInterval(intervalId);
body.removeEventListener('click', rotateBackground);
};
}, []);

const themeContext = useContext(ThemeContext);
const { theme } = themeContext;
return (
<BrowserRouter>
<AuthProvider>
<GlobalStyle theme={theme}/>
<Layout>
<Switch>
<Route exact path="/">
<HomePage />
</Route>
<Route exact path="/login">
<LoginPage />
<Route exact path="/video/:id">
<VideoDetails />
</Route>
<Private exact path="/secret">
<SecretPage />
</Private>
<Route path="*">
<NotFound />
</Route>
</Switch>
<Fortune />
</Layout>
</AuthProvider>
</BrowserRouter>
);
}
Expand Down
Loading