Skip to content

Commit

Permalink
Merge pull request #44 from Jesuitman/styling/userview
Browse files Browse the repository at this point in the history
Styling/userview
  • Loading branch information
tenthwalker authored Jan 7, 2024
2 parents 9dd8f1d + 10e12d3 commit 3109640
Show file tree
Hide file tree
Showing 11 changed files with 250 additions and 37 deletions.
130 changes: 126 additions & 4 deletions cypress/e2e/spec.cy.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,127 @@
describe('template spec', () => {
it('passes', () => {
cy.visit('https://example.cypress.io')
//Need to login before testing
describe('API Tests', () => {
beforeEach(() => {
cy.visit('http://localhost:3000/');
})
})
it('Fetches and displays Wikipedia page contents', () => {
cy.intercept('GET', 'https://en.wikipedia.org/w/api.php?', {
statusCode: 200,
fixture: 'wikipediaApiResponse',
}).as('fetchContents');
cy.wait('@fetchContents').then(({ response }) => {
expect(response.statusCode).to.equal(200);
});
cy.contains('Loading...').should('not.exist');
cy.contains('An error occurred').should('not.exist');
});

it('Handles error when API fails', () => {
cy.intercept('GET', 'https://en.wikipedia.org/w/api.php?', {
statusCode: 500,
body: 'Server Error',
delayMs: 200,
}).as('fetchError');
cy.wait('@fetchError').then(({ response }) => {
expect(response.statusCode).to.equal(500);
cy.contains('An error occurred').should('exist');
});
});
});

describe('App Component', () => {
beforeEach(() => {
cy.visit('http://localhost:3000/');
})

it('Loads the app properly', () => {
cy.get('.header-text').should('be.visible');
cy.get('.login-button').should('be.visible');
cy.get('.random-headline').should('be.visible');
});

it('Displays random controversies', () => {
cy.get('.result-name').should('contain', '');
cy.get('.random-headline').should('contain', 'Random Controversy');
cy.get('.card').should('be.visible');
cy.get('.card')
.children()
.first()
.within(() => {
cy.contains('h2', '');
cy.contains('p', '');
cy.contains('button', '😡Save Controversy😡');
cy.contains('button', '🤬Save as favorite controversy🤬');
});
});
});

describe('Can search for a Controversy', () => {
beforeEach(() => {
cy.visit('http://localhost:3000/');
//placeholder for login flow
});

it('Searches for a term, then clears input', () => {
cy.get('input[type="text"]').should('be.visible');
cy.get('input[type="text"]').type('SearchTerm{enter}');
cy.get('input[type="text"]').should('have.text', '');
});

it('Displays controversies for a search result', () => {
cy.get('.card').should('be.visible');
cy.get('.result-name').should('contain', '');
cy.get('.results-list')
.children()
.first()
.within(() => {
cy.contains('h2', '');
cy.contains('p', '');
cy.contains('button', '😡Save Controversy😡');
cy.contains('button', '🤬Save as favorite controversy🤬');
});
cy.get('.results-list')
.children()
.last()
.within(() => {
cy.contains('h2', '');
cy.contains('p', '');
cy.contains('button', '😡Save Controversy😡');
cy.contains('button', '🤬Save as favorite controversy🤬');
});
});
});

describe('Card Component', () => {
beforeEach(() => {
cy.visit('http://localhost:3000/');
})

it('Renders snippet properly', () => {
cy.get('.card-content').should('be.visible');
cy.get('h2').should('contain', '');
cy.get('p').should('contain', '');
});

it('Handles show more/show less functionality', () => {

});
});

describe('UserView Component', () => {
beforeEach(() => {
cy.visit('http://localhost:3000/');
//login flow placeholder
})

it('Loads page content properly', () => {
cy.get('#profile').should('be.visible');
cy.get('#profile').click();
cy.visit('http://localhost:3000/Profile');
cy.get('.filter-buttons').should('have.descendants', 'button');
// cy.get('.article').should('be.visible');
});

it('Saves controversy properly', () => {

});
});
5 changes: 0 additions & 5 deletions cypress/fixtures/example.json

This file was deleted.

3 changes: 3 additions & 0 deletions cypress/fixtures/sampleRandomCards.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"need": "one sample result with multiple wiki cards"
}
18 changes: 18 additions & 0 deletions cypress/fixtures/wikipediaApiResponse.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"query": {
"search": [
{
"title": "Example Title 1",
"snippet": "This is an example snippet for the first result."
},
{
"title": "Example Title 2",
"snippet": "Another example snippet for the second result."
},
{
"title": "Example Title 3",
"snippet": "Another example snippet for the third result."
}
]
}
}
55 changes: 29 additions & 26 deletions src/App/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import './App.css';
import Card from '../Card/Card.js';
import useSearchResults from '../hooks/useSearchResults.js';
import Profile from '../UserView/UserView.js';
import ErrorBoundary from '../Errors/ErrorBoundary.js';

function App() {
const { isLoading, isAuthenticated } = useAuth0();
Expand Down Expand Up @@ -44,38 +45,40 @@ function App() {
}

return (
<div className="App">
<header className="App-header">
<Link to="/" className="logo-link">
<h1 className='header-text'>H8rAid!</h1>
</Link>
{isAuthenticated && <button onClick={() => navigate("/profile")}>Profile</button>}
<NavBarButtons />
</header>
<Routes>
<Route path='/' element={<WikipediaSearch savedControversies={savedControversies} saveControversy={saveControversy} />} />
<Route path='/main' element={<Navigate to='/' />} />
<Route path='/profile' element={<Profile savedControversies={savedControversies} />} />
<Route path="article/:id" element={<WikipediaSearch />} />
</Routes>
{showRandomControversy && (
<ErrorBoundary>
<div className="App">
<header className="App-header">
<Link to="/" className="logo-link">
<h1 className='header-text'>H8rAid!</h1>
</Link>
{isAuthenticated && <button id='profile' onClick={() => navigate("/profile")}>Profile</button>}
<NavBarButtons />
</header>
<Routes>
<Route path='/' element={<WikipediaSearch savedControversies={savedControversies} saveControversy={saveControversy} />} />
<Route path='/main' element={<Navigate to='/' />} />
<Route path='/profile' element={<Profile savedControversies={savedControversies} />} />
<Route path="article/:id" element={<WikipediaSearch />} />
</Routes>
{showRandomControversy && (
<section className='random-view'>
<h2 className='random-headline'>Random Controversy</h2>
{controversies[0] && <h2 className='result-name'>{initialResults.title}</h2>}
<section className='results-list'>
{controversies.map((item, i) => (
<Card
key={i}
title={item.parse.title}
snippet={item.parse.text["*"]}
onSave={() => saveControversy(item.parse.text["*"])}
onSaveAsFavorite={() => saveControversy(item.parse.text["*"], true)}
/>
))}
{controversies.map((item, i) => (
<Card
key={i}
title={item.parse.title}
snippet={item.parse.text["*"]}
onSave={() => saveControversy(item.parse.text["*"])}
onSaveAsFavorite={() => saveControversy(item.parse.text["*"], true)}
/>
))}
</section>
</section>
)}
</div>
)}
</div>
</ErrorBoundary>
);
};

Expand Down
7 changes: 6 additions & 1 deletion src/Card/Card.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useState } from 'react';
import DOMPurify from 'dompurify';
import './Card.css';
import modifyRelativeUrls from '../hooks/modifyRelativeUrls';
import PropTypes from "prop-types";

const Card = ({ snippet, onSave, onSaveAsFavorite }) => {
const [showFullContent, setShowFullContent] = useState(false);
Expand All @@ -23,4 +24,8 @@ const Card = ({ snippet, onSave, onSaveAsFavorite }) => {
);
};

export default Card;
export default Card;

Card.propTypes = {
snippet: PropTypes.string.isRequired,
};
32 changes: 32 additions & 0 deletions src/Errors/ErrorBoundary.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import ErrorPage from '../Errors/Errors.js';
import React, { Component } from 'react';

class ErrorBoundary extends Component {
constructor(error) {
super(error);
this.state = {
hasError: false,
errorMessage: '',
};
}

static getDerivedStateFromError(error) {
if (error.message === 'Network response was not ok') {
return { hasError: true, errorMessage: 'Error in SpecificComponent' };
}
if(error.message === 'Error fetching Wikipedia page:') {
return{ hasError: true, errorMessage: 'Cannot fetch Wikipedia page'}
}
return { hasError: true, errorMessage: error.toString() };
}

componentsDidCatch(error, errorInfo) {
console.error('ErrorBoundary caught an error:', error, errorInfo);
}

render() {
return this.state.hasError ? <ErrorPage errorMessage={"An Error has Occurred"} /> : this.props.children;
}
}

export default ErrorBoundary;
12 changes: 12 additions & 0 deletions src/Errors/Errors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react';

const errorMessage = ({ errorMessage }) => {
return (
<div className="error-page">
<h2>Error Encountered</h2>
<p>{errorMessage}</p>
</div>
);
};

export default errorMessage;
Empty file removed src/Main/Main.css
Empty file.
17 changes: 17 additions & 0 deletions src/UserView/UserView.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.profile {
flex-direction: column;
}

.filter-buttons, .profile {
display: flex;
}

.filter-buttons {
justify-content: center;
}

@media screen and (max-width: 500px) {
.results-list {
flex-direction: column;
}
}
8 changes: 7 additions & 1 deletion src/UserView/UserView.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import React, { useState } from 'react';
import Card from '../Card/Card';
import PropTypes from "prop-types";
import './UserView.css';

const Profile = ({ savedControversies }) => {
const [showFavorites, setShowFavorites] = useState(false);
Expand Down Expand Up @@ -39,4 +41,8 @@ const Profile = ({ savedControversies }) => {
);
};

export default Profile;
export default Profile;

Profile.propTypes = {
savedControversies: PropTypes.array.isRequired,
}

0 comments on commit 3109640

Please sign in to comment.