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

Angela engel #140

Open
wants to merge 5 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
28 changes: 28 additions & 0 deletions src/components/BubblePage.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,37 @@ const BubblePage = () => {
};

const saveEdit = (editColor) => {
axiosWithAuth()
.put(`/api/colors/${editColor.id}`, editColor)
.then((res) => {
console.log(res)

let index = colors.findIndex((color) => color.id === editColor.id);
colors[index] = editColor
setColors([
...colors
])
})
.catch((err) => {
console.log(err)
})
};

useEffect(() => {
fetchColorService().then((res) => {
setColors(res)
})
}, []);

const deleteColor = (colorToDelete) => {
axiosWithAuth()
.delete(`/api/colors/${colorToDelete.id}`)
.then((res) => {
setColors(colors.filter(color => color.id !== colorToDelete.id))
})
.catch((err) => {
console.log(err)
})
};

return (
Expand Down
17 changes: 16 additions & 1 deletion src/components/BubblePage.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,26 @@ import MutationObserver from 'mutationobserver-shim';

import { render, screen} from "@testing-library/react";
import BubblePage from './BubblePage';
jest.mock('../services/fetchColorService');

const testColor = {
color: "blue",
code: { hex: "#7fffd4" },
id: 1
}

test("Renders without errors", ()=> {

render(<BubblePage />)
});

test("Renders appropriate number of colors passed in through mock", async ()=> {
//Keep in mind that our service is called on mount for this component.
fetchColorServices.mockResolvedValueOnce(testColor);

render(<BubblePage />);
const colors = screen.getAllByTestId("color");

await waitFor(() => {
expect(colors).toHaveLength(1);
})
});
25 changes: 24 additions & 1 deletion src/components/Color.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,38 @@ import { render, screen, waitFor } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import Color from './Color';

const testColor = {
color: "blue",
code: { hex: "#7fffd4" },
id: 1
}

test("Renders without errors with blank color passed into component", () => {
render(<Color color={testColor} />);
});

test("Renders the color passed into component", () => {
render(<Color color={testColor} />);
const color = screen.queryAllByTestId("color");
expect(color).toBeInTheDocument();
});

test("Executes handleDelete and toggleEdit property when the 'x' icon is clicked", () => {
const handleDelete = jest.fn();
const toggleEdit = jest.fn();
render(<Color color={testColor} />)
const deleteKey = screen.getByTestId("delete")
userEvent.click(deleteKey)
expect(handleDelete).toBeCalled()
expect(toggleEdit).toBeCalled();
});

test("Executes setEditColor and toggleEdit property when color div is clicked", () => {

const setEditColor = jest.fn();
const toggleEdit = jest.fn();
render(<Color color={testColor} />)
const colorKey = screen.getByTestId("color")
userEvent.click(colorKey)
expect(setEditColor).toBeCalled()
expect(toggleEdit).toBeCalled();
});
13 changes: 13 additions & 0 deletions src/components/ColorList.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,24 @@ import MutationObserver from 'mutationobserver-shim';
import { render, screen} from "@testing-library/react";
import ColorList from './ColorList';

const testColor = {
color: "blue",
code: { hex: "#7fffd4" },
id: 1
}

test("Renders an empty list of colors without errors", () => {
render(<ColorList color={noColor} />)
});

test("Renders a list of colors without errors", () => {
render(<ColorList color={testColor} />)
});

test("Renders the EditForm when editing = true and does not render EditForm when editing = false", () => {
const toggleEdit = jest.fn()
render(<ColorList color={testColor} />);
let editing = screen.queryByTestId("color");
userEvent.click(editing);
expect(toggleEdit).toBeCalled();
});
70 changes: 67 additions & 3 deletions src/components/Login.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,82 @@
import React from "react";
import React, {useState} from "react";
import { useHistory } from "react-router-dom";
import axiosWithAuth from "../helpers/axiosWithAuth";

const initialValues = {
username: '',
password: ''
}

const Login = () => {
// make a post request to retrieve a token from the api
// when you have handled the token, navigate to the BubblePage route
const { push } = useHistory
const [formValues, setFormValues] = useState(initialValues)
const [error, setError] = useState()

const handleChange = (e) => {
setFormValues({
...formValues,
[e.target.name]: e.target.value
})
}

const handleSubmit = e => {
e.preventDefault();
if (formValues.username !== 'Lambda' || formValues.password !== 'School') {
setError('Username or Password incorrect')
}

axiosWithAuth()
.post('/api/login', formValues)
.then((res) => {
console.log("Axios Login Post", res)
localStorage.setItem('token', res.data.payload)
push('/bubblepage')
})
.catch((err) => {
console.log({ err })
})
}


const error = "";
//replace with error state



return (
<div>
<h1>Welcome to the Bubble App!</h1>
<div data-testid="loginForm" className="login-form">
<h2>Build login form here</h2>
</div>
<div>
<form onSubmit={handleSubmit}>
<label htmlFor="username">
Username
</label><br/>
<input
id="username"
data-testid="username"
name="username"
value={formValues.username}
onChange={handleChange}
/><br/><br/>

<label htmlFor="password">
Password
</label><br/>
<input
id="password"
data-testid="password"
name="password"
value={formValues.password}
onChange={handleChange}
/><br/>

<button>Login</button>

</form>
</div>

<p id="error" className="error">{error}</p>
</div>
Expand Down
17 changes: 16 additions & 1 deletion src/components/PrivateRoute.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,17 @@
//Task List:
//1. Build a PrivateRoute component that redirects if user is not logged in
//1. Build a PrivateRoute component that redirects if user is not logged in

import React from 'react';
import { Route, Redirect } from 'react-router-dom';

const PrivateRoute = ({component: Component, ...rest}) => {
return <Route {...rest} render={(props) => {
if (localStorage.getItem("token")) {
return(<Component {...props}/>)
} else {
return <Redirect to='/login' />
}
}} />
}

export default PrivateRoute;
14 changes: 13 additions & 1 deletion src/helpers/axiosWithAuth.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
import axios from "axios";

//Task List:
//Build and export a function used to send in our authorization token
//Build and export a function used to send in our authorization token
const axiosWithAuth = () => {
const token = localStorage.getItem('token');

return axios.create({
headers: {
Authorization: token
},
baseURL: 'http://localhost:5000'
})
}

export default axiosWithAuth;
10 changes: 9 additions & 1 deletion src/services/fetchColorService.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import axiosWithAuth from '../helpers/axiosWithAuth';

const fetchColorService = () => {

return axiosWithAuth()
.get('/api/colors')
.then((res) => {
console.log("fetchColorService ", res);
return (res.data)
})
.catch((err) => {
console.log(err);
})
}

export default fetchColorService;