Skip to content

Gregory brewton #63

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

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
23,785 changes: 23,768 additions & 17 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"react-dom": "^16.13.1",
"react-dropdown": "^1.7.0",
"react-scripts": "3.4.1",
"striptags": "^3.1.1"
"striptags": "^3.1.1",
"user-event": "^4.0.0"
},
"scripts": {
"start": "react-scripts start",
Expand Down
14 changes: 2 additions & 12 deletions public/manifest.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,11 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"short_name": "Testing React",
"name": "web-module-project-testing-react",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
Expand Down
3 changes: 3 additions & 0 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/* eslint-disable jsx-a11y/alt-text */
/* eslint-disable jsx-a11y/anchor-is-valid */
// eslint-disable-next-line no-unused-vars
import React, { useState } from "react";

import Display from "./components/Display";
Expand Down
5 changes: 3 additions & 2 deletions src/api/fetchShow.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const formatSeasons = (allEpisodes) => {

const fetchShow = () => {
return axios
.get("https://api.tvmaze.com/singlesearch/shows?q=stranger-things&embed=episodes")
.get("https://api.tvmaze.com/singlesearch/shows?q=stranger&embed=episodes")
.then(res => {
const { data } = res;

Expand All @@ -33,7 +33,8 @@ const fetchShow = () => {
summary: stripTags(data.summary),
seasons: formatSeasons(data._embedded.episodes)
};
});
})
.catch(err => console.error(err));
};

export default fetchShow;
2 changes: 2 additions & 0 deletions src/components/Display.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/* eslint-disable jsx-a11y/img-redundant-alt */
import React, { useState } from 'react';

// eslint-disable-next-line no-unused-vars
import Loading from "./Loading";
import Show from "./Show";

Expand Down
38 changes: 21 additions & 17 deletions src/components/Episode.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
import React from 'react';
import React from "react";

const Episode = (props)=> {
const {episode} = props;
const {id, image, name, season, number, summary, runtime} = episode;
const imgsrc = image || './stranger_things.png';
const Episode = (props) => {
const { episode } = props;
const { id, image, name, season, number, summary, runtime } = episode;
const imgsrc = image || "./stranger_things.png";

return(<div className="episode" key={id}>
<img className="episode-image" src={imgsrc} alt={imgsrc} />
<div className="episode-info">
<p className="episode-number">Season {season}, Episode {number}</p>
<h3>{name}</h3>
<p>{summary}</p>
<div className="flex-spacer" />
<p className="episode-runtime">{runtime} minutes</p>
</div>
</div>)
}
return (
<div className="episode" key={id}>
<img className="episode-image" src={imgsrc} alt={imgsrc} />
<div className="episode-info">
<p className="episode-number">
Season {season}, Episode {number}
</p>
<h3>{name}</h3>
<p data-testid="episode summary">{summary}</p>
<div className="flex-spacer" />
<p className="episode-runtime">{runtime} minutes</p>
</div>
</div>
);
};

export default Episode;
export default Episode;
8 changes: 5 additions & 3 deletions src/components/Episodes.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import React from 'react';
import Episode from './Episode';
import React from "react";
import Episode from "./Episode";

export default function Episodes(props) {
return (
<div data-testid="episodes-container" className="episodes">
{props.episodes.map(episode => <Episode episode={episode}/>)}
{props.episodes.map((episode, index) => (
<Episode key={`${index}_${Date.now()}`} episode={episode} />
))}
</div>
);
}
55 changes: 31 additions & 24 deletions src/components/Show.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,38 @@
import React from 'react';
import React from "react";
import Episodes from "./Episodes";
import Loading from './Loading';
import Loading from "./Loading";

const Show = (props) => {
const { handleSelect, selectedSeason, show } = props;

if (!show)
return <Loading />
const { handleSelect, selectedSeason, show } = props;

return(<div data-testid="show-container">
<h1>{show.name}</h1>
<p>{show.summary}</p>
if (!show) return <Loading />;
return (
<div data-testid="show-container">
<h1>{show.name}</h1>
<p>{show.summary}</p>

<label htmlFor="seasons">Select A Season</label><br/>
<select onChange={handleSelect} name="seasons" id="seasons">
<option value="none"></option>
{
show.seasons.map(season=>{
return(<option data-testid="season-option" key={season.id} value={season.id}>{season.name}</option>);
})
}
</select>
<label htmlFor="seasons">Select A Season</label>
<br />
<select onChange={handleSelect} name="seasons" id="seasons">
<option value="none"></option>
{show.seasons.map((season) => {
return (
<option
data-testid="season-option"
key={season.id}
value={season.id}
>
{season.name}
</option>
);
})}
</select>

{
(selectedSeason !== "none") && <Episodes episodes={show.seasons[selectedSeason].episodes} />
}
</div>);
}
{selectedSeason !== "none" && (
<Episodes episodes={show.seasons[selectedSeason].episodes} />
)}
</div>
);
};

export default Show;
export default Show;
57 changes: 37 additions & 20 deletions src/components/tests/Episode.test.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,51 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import Episode from './../Episode';
/* eslint-disable no-unused-vars */
import React from "react";
import {
getByTestId,
queryByTestId,
render,
screen,
} from "@testing-library/react";
import Episode from "./../Episode";

const TEST_MESSAGE = "test message";

const testEpisode = {
id:1,
name: "",
image: "http://static.tvmaze.com/uploads/images/medium_landscape/67/168918.jpg",
season: 1,
number: 1,
summary: "",
runtime: 1
}
id: 1,
name: "",
image:
"http://static.tvmaze.com/uploads/images/medium_landscape/67/168918.jpg",
season: 1,
number: 1,
summary: TEST_MESSAGE,
runtime: 1,
};

const testEpisodeWithoutImage = {
//Add in approprate test data structure here.
}
//Add in approprate test data structure here.
};

test("renders without error", () => {

render(<Episode episode={testEpisode} />);
});

test("renders the summury test passed as prop", ()=>{

test("renders the summary test passed as prop", () => {
render(<Episode episode={testEpisode} />);
const episodeSummary = screen.getByTestId("episode summary");
expect(episodeSummary).not.toBeNull();
expect(episodeSummary).toBeInTheDocument();
expect(episodeSummary).toHaveTextContent(TEST_MESSAGE);
});

test("renders default image when image is not defined", ()=>{

})
test("renders default image when image is not defined", () => {
render(<Episode episode={{ ...testEpisode, image: null }} />);
const episodeImage = screen.getByAltText("./stranger_things.png");
expect(episodeImage).not.toBeNull();
expect(episodeImage).toBeInTheDocument();

});

//Tasks
//1. Complete a test that shows the Episode component renders. Pass in the provided example episode data as a test prop.
//2. Modify the test data to display a specific summary statement. Complete a test that shows that the summary value passed in to the Episode component displays as expected. Use no more then 3 different expect statements to test the the existance of the summary value.
//3. The episode component displays a default value ('./stranger_things.png') when a image url is not provided. Create a new piece of test data with the image property set to null. Test that the alt tag of the image displayed is set to './stranger_things.png'.
//3. The episode component displays a default value ('./stranger_things.png') when a image url is not provided. Create a new piece of test data with the image property set to null. Test that the alt tag of the image displayed is set to './stranger_things.png'.
65 changes: 52 additions & 13 deletions src/components/tests/Show.test.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,71 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
/* eslint-disable no-unused-vars */
import React from "react";
import {
getByTestId,
render,
screen,
fireEvent,
waitFor,
} from "@testing-library/react";
import userEvent from "@testing-library/user-event";

import Show from './../Show';
import Show from "./../Show";

const testShow = {
//add in approprate test data structure here.
}
image: null,
name: "test_show_name",
summary: "test_show_summary",
seasons: [
{
id: 1,
name: "test_season_name",
episodes: [
{
id: 1,
name: "",
image:
"http://static.tvmaze.com/uploads/images/medium_landscape/67/168918.jpg",
season: 1,
number: 1,
summary: "test message",
runtime: 1,
},
],
},
],
};

test('renders testShow and no selected Season without errors', ()=>{
test("renders testShow and no selected Season without errors", () => {
render(<Show show={testShow} selectedSeason="none" />);
});

test('renders Loading component when prop show is null', () => {
test("renders Loading component when show={null}", () => {
render(<Show show={null} selectedSeason="none" />);
const loadingComponent = screen.getByTestId("loading-container");
expect(loadingComponent).toBeInTheDocument();
});

test('renders same number of options seasons are passed in', ()=>{
test("renders same number of options as seasons that are passed in", () => {
render(<Show show={testShow} selectedSeason="none" />);
const seasonOptions = screen.getAllByTestId("season-option");
expect(seasonOptions).toHaveLength(1);
});

test('handleSelect is called when an season is selected', () => {
test("handleSelect is called when a season is selected", async () => {
render(<Show show={testShow} selectedSeason="none" />);
const seasonOption = screen.getByTestId("season-option");
fireEvent.click(seasonOption);
const { rerender } = render(<Show show={testShow} selectedSeason="none" />);
rerender(<Show show={testShow} selectedSeason='1' />);
// expect(screen.findByTestId("episodes-container")).toBeInTheDocument();
});

test('component renders when no seasons are selected and when rerenders with a season passed in', () => {
});
test("component renders when no seasons are selected and when rerenders with a season passed in", () => {});

//Tasks:
//1. Build an example data structure that contains the show data in the correct format. A show should contain a name, a summary and an array of seasons, each with a id, name and (empty) list of episodes within them. Use console.logs within the client code if you need to to verify the structure of show data.
//2. Test that the Show component renders when your test data is passed in through show and "none" is passed in through selectedSeason.
//3. Test that the Loading component displays when null is passed into the show prop (look at the Loading component to see how to test for it's existance)
//4. Test that when your test data is passed through the show prop, the same number of season select options appears as there are seasons in your test data.
//5. Test that when an item is selected, the handleSelect function is called. Look at your code to see how to get access to the select Dom element and userEvent reference materials to see how to trigger a selection.
//6. Test that the episode component DOES NOT render when the selectedSeason props is "none" and DOES render the episode component when the selectedSeason prop has a valid season index.
//6. Test that the episode component DOES NOT render when the selectedSeason props is "none" and DOES render the episode component when the selectedSeason prop has a valid season index.