-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
9692bb0
commit c82cf9f
Showing
6 changed files
with
338 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import 'bootstrap/dist/css/bootstrap.min.css'; | ||
import './../App.css'; | ||
import Button from "react-bootstrap/Button" | ||
import Grid from '@mui/material/Grid'; | ||
import { Redirect, Link } from "react-router-dom"; | ||
|
||
function Customer() { | ||
return ( | ||
localStorage.getItem('role') === 'CUSTOMER' || localStorage.getItem('role') === 'ADMIN' ? | ||
<div> | ||
<h1 style={{ paddingBlock: "20px" }}>Customer</h1> | ||
<Grid container spacing={2}> | ||
<Grid item xs={12} sm={6} md={4}> | ||
<Link to="/BrowseProducts"><Button size='huge' variant="outline-success"> <h1>Browse Products</h1> </Button> </Link> | ||
</Grid> | ||
<Grid item xs={12} sm={6} md={4}> | ||
<Link to='/PlaceOrder'><Button size='huge' variant="outline-success"> <h1>Place Order</h1> </Button></Link> | ||
</Grid> | ||
</Grid> | ||
</div> | ||
: | ||
<Redirect to="/ErrorHandler"></Redirect> | ||
); | ||
} | ||
|
||
export { Customer } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import * as React from "react"; | ||
import * as ReactDOM from "react-dom"; | ||
import {getQueriesForElement} from '@testing-library/dom'; | ||
|
||
import {Customer} from "./Customer"; | ||
import { BrowserRouter as Router} from "react-router-dom"; | ||
|
||
function render(comp) { | ||
const root = document.createElement("div"); | ||
ReactDOM.render(comp, root); | ||
return getQueriesForElement(root); | ||
} | ||
|
||
test ("renders correctly", () => { | ||
|
||
localStorage.setItem("role", "CUSTOMER"); | ||
const {getByText, getByAltText} = render( | ||
<Router> | ||
<Customer/> | ||
</Router> | ||
); | ||
|
||
getByText("Customer"); | ||
getByText("Browse Products"); | ||
getByText("Place Order"); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import 'bootstrap/dist/css/bootstrap.min.css'; | ||
import './../App.css'; | ||
import Button from "react-bootstrap/Button" | ||
import Grid from '@mui/material/Grid'; | ||
import { Redirect, Link } from "react-router-dom"; | ||
|
||
function Farmer() { | ||
return ( | ||
localStorage.getItem('role') === 'FARMER' ? | ||
<div> | ||
<h1 style={{ paddingBlock: "20px" }}>Farmer</h1> | ||
<Grid container spacing={2}> | ||
<Grid item xs={12} sm={6} md={4}> | ||
<Link to="/ProductsForecast"><Button size='huge' variant="outline-success"> <h1>Communicate Products Prevision</h1> </Button> </Link> | ||
</Grid> | ||
</Grid> | ||
</div> | ||
: | ||
<Redirect to="/ErrorHandler"></Redirect> | ||
); | ||
} | ||
|
||
export { Farmer } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import * as React from "react"; | ||
import * as ReactDOM from "react-dom"; | ||
import {getQueriesForElement} from '@testing-library/dom'; | ||
|
||
import {Farmer} from "./Farmer"; | ||
import { BrowserRouter as Router} from "react-router-dom"; | ||
|
||
function render(comp) { | ||
const root = document.createElement("div"); | ||
ReactDOM.render(comp, root); | ||
return getQueriesForElement(root); | ||
} | ||
|
||
test ("renders correctly", () => { | ||
|
||
localStorage.setItem("role", "FARMER"); | ||
const {getByText} = render( | ||
<Router> | ||
<Farmer/> | ||
</Router> | ||
); | ||
|
||
getByText("Farmer"); | ||
getByText("Communicate Products Prevision"); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
import 'bootstrap/dist/css/bootstrap.min.css'; | ||
import './../App.css'; | ||
import {useState, useEffect} from 'react'; | ||
import {Link} from 'react-router-dom'; | ||
import Row from 'react-bootstrap/Row'; | ||
import Spinner from 'react-bootstrap/Spinner'; | ||
import Col from 'react-bootstrap/Col'; | ||
import Button from 'react-bootstrap/Button'; | ||
import Alert from 'react-bootstrap/Alert'; | ||
import {Formik, Form, Field} from 'formik'; | ||
import * as Yup from 'yup'; | ||
import {API} from './../API/API'; | ||
import {Redirect} from "react-router-dom"; | ||
import { Collapse } from '@mui/material'; | ||
|
||
function PlaceOrder(props) { | ||
const [customer, setCustomer] = useState(""); | ||
const [order, setOrder] = useState(null); | ||
const [error, setError] = useState(false); | ||
const [customerError, setCustomerError] = useState(false); | ||
const [customerSuccess, setCustomerSuccess] = useState(false); | ||
const [deleteError, setDeleteError] = useState(false); | ||
const [sendError, setSendError] = useState(false); | ||
const [sendSuccess, setSendSuccess] = useState(false); | ||
const [triggerError, setTriggerError] = useState(false); | ||
const [loading, setLoading] = useState(true); | ||
|
||
/***************************************************************************/ | ||
//let email = '[email protected]' //dovrebbe essere recuperata dalla sessione | ||
//const username = localStorage.getItem("username"); | ||
//const username = props.loggedUser; //requires hooks system from App.js (where loggedUser state is located) | ||
/***************************************************************************/ | ||
|
||
async function _getCart() { | ||
const prod = await API.getCart({'email': localStorage.getItem("username")}, props.setErrorMessage); | ||
if (prod === null) { | ||
setTriggerError(true); | ||
setLoading(false) | ||
return; | ||
} | ||
if (prod === undefined) { | ||
setError(true); | ||
setOrder([]); | ||
} else | ||
setOrder(prod); | ||
} | ||
|
||
|
||
useEffect(() => { | ||
_getCart(); | ||
}, []); | ||
|
||
|
||
const dropOrder = async () => { | ||
let outcome = await API.dropOrder({'email': localStorage.getItem("username")}); | ||
if (outcome) | ||
setOrder(null); | ||
else | ||
setDeleteError(true); | ||
} | ||
|
||
const placeOrder = async () => { | ||
setSendError(false); | ||
setSendSuccess(false); | ||
let outcome; | ||
if (props.loggedUserRole === "EMPLOYEE") | ||
outcome = await API.placeOrder({'email': localStorage.getItem("username"), 'customer': customer}); | ||
else | ||
outcome = await API.placeOrder({'email': "", 'customer': localStorage.getItem("username")}); | ||
if (outcome) { | ||
setOrder(null); | ||
setSendSuccess(true); | ||
} else | ||
setSendError(true); | ||
} | ||
|
||
/*TIME MACHINE MANAGEMENT*/ | ||
const [itsTime, setItsTime] = useState(false) | ||
useEffect(() => { | ||
let checkTime = (time, date) => { | ||
if ((date === 'Sat' && time >= '09:00') || (date === 'Sun' && time < '23:00')) | ||
setItsTime(true); | ||
else | ||
setItsTime(false); | ||
} | ||
checkTime(props.time, props.date); | ||
}, [props.date, props.time]) | ||
|
||
if (triggerError === true) { | ||
return ( | ||
<Redirect to="/ErrorHandler"></Redirect> | ||
); | ||
} | ||
|
||
if (loading === true) { | ||
<Spinner animation="border" role="status"> | ||
<span className="visually-hidden">Loading...</span> | ||
</Spinner> | ||
} | ||
|
||
return ( | ||
<> | ||
<h1>Place Order</h1> | ||
{itsTime ? null : | ||
<Alert variant='warning'> It's possible to place orders only from Saturday at 9am to Sunday at | ||
11pm</Alert>} | ||
{error ? <Alert variant='danger'>Something went wrong, couldn't retrieve order</Alert> : null} | ||
<div id="container" className="pagecontent"> | ||
<ul className="list-group">{printOrder(order)}</ul> | ||
</div> | ||
<div id="container" className="pagecontent"> | ||
{props.loggedUserRole === "EMPLOYEE" ? <> | ||
<h2>Whose order is this?</h2> | ||
<Formik | ||
initialValues={{email: ''}} | ||
validationSchema={Yup.object({ | ||
email: Yup.string().email().required() | ||
})} | ||
onSubmit={async (values) => { | ||
setCustomerSuccess(false); | ||
setCustomerError(false); | ||
setCustomer(null); | ||
let presentEmail = await API.customerExistsByMail(values.email) | ||
setCustomerError(!presentEmail); | ||
if (presentEmail) { | ||
console.log("CHECKPOINT, EMAIL:" + values.email + " ORDER:" + JSON.stringify(order) + " itsTime:" + itsTime); | ||
setCustomer(values.email); | ||
setCustomerSuccess(true); | ||
} | ||
}} | ||
validateOnChange={false} | ||
validateOnBlur={false} | ||
> | ||
{({values, errors, touched}) => | ||
<Form> | ||
Email:<Field style={{margin: '20px'}} name="email" type="text"/> | ||
<Button style={{margin: '20px'}} type="submit" variant="success">Submit | ||
customer</Button> | ||
{errors.email && touched.email ? errors.email : null} | ||
{customerError ? <Alert variant='danger'> User not found </Alert> : null} | ||
{customerSuccess ? | ||
<Alert variant='success'> User found, you can now place their order </Alert> : null} | ||
{deleteError ? | ||
<Alert variant='danger'> Something went wrong emptying your cart </Alert> : null} | ||
{sendError ? | ||
<Alert variant='danger'> Something went wrong sending your order </Alert> : null} | ||
{sendSuccess ? <Alert variant='success'> Order sent successfully </Alert> : null} | ||
</Form> | ||
} | ||
</Formik> | ||
</> | ||
: | ||
""} | ||
</div> | ||
<Row> | ||
<Col xs={4}><Link to={'/'+localStorage.getItem("role")}><Button variant='secondary'>Back</Button></Link></Col> | ||
<Col xs={4}><Button disabled={order === null ? true : false} variant='danger' onClick={dropOrder}>Delete | ||
order</Button></Col> | ||
<Col xs={4}><Button disabled={(!itsTime || order === null || customer === null) ? true : false} | ||
variant='success' onClick={placeOrder}>Send order</Button></Col> | ||
</Row> | ||
</> | ||
); | ||
} | ||
|
||
function printOrder(prod) { | ||
let output = []; | ||
let total = 0; | ||
if (prod === null) | ||
return (<h2>The cart is empty </h2>); | ||
for (let p of prod) { | ||
output.push(<OrderEntry product={p}/>); | ||
total += p.price * p.quantityAvailable; | ||
} | ||
output.push( | ||
<li className='list-group-item'> | ||
<h2>Total: {total} €</h2> | ||
</li> | ||
) | ||
return output; | ||
} | ||
|
||
function OrderEntry(props) { | ||
return ( | ||
<li className="list-group-item"> | ||
{props.product.name} : {props.product.quantityAvailable} {props.product.unitOfMeasurement}<br/> | ||
SUBTOTAL: {props.product.price * props.product.quantityAvailable}€ | ||
</li> | ||
); | ||
} | ||
|
||
|
||
export {PlaceOrder, printOrder} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import * as React from "react"; | ||
import {render, fireEvent, waitFor } from '@testing-library/react'; | ||
import {BrowserRouter as Router} from "react-router-dom"; | ||
|
||
import {PlaceOrder} from "./PlaceOrder"; | ||
import {API} from "./../API/API"; | ||
|
||
const mockAddToCard = (API.addToCart = jest.fn()); | ||
const mockGetCart = (API.getCart = jest.fn()); | ||
|
||
test("renders correctly", async() => { | ||
|
||
localStorage.setItem("role", "CUSTOMER"); | ||
localStorage.setItem("username", "[email protected]"); | ||
mockAddToCard.mockResolvedValueOnce(true); | ||
mockGetCart.mockResolvedValueOnce([{endAvailability: null, | ||
farmer: 5, | ||
imageUrl: "https://images.unsplash.com/photo-1560806887-1e4cd0b6cbd6", | ||
name: "Apples", | ||
price: 2.5, | ||
productId: 7, | ||
quantityAvailable: 1, | ||
quantityBaskets: 1, | ||
quantityDelivered: 0, | ||
quantityForecast: 0, | ||
quantityOrdered: 0, | ||
startAvailability: null, | ||
totalQuantity: 50, | ||
unitOfMeasurement: "Kg"}]); | ||
|
||
expect(API.addToCart({"productId":7 ,"email": '[email protected]',"quantity": 1})).toBeTruthy(); | ||
|
||
const {getByText} = render( | ||
<Router> | ||
<PlaceOrder/> | ||
</Router> | ||
); | ||
|
||
//getByText("Apples"); | ||
|
||
//expect(mockAddToCard).toBeCalledTimes(1); | ||
//expect(mockAddToCard).toBeCalledWith({"productId":7 ,"email": 'mario.rossi@gmail.com',"quantity": 1}); | ||
expect(mockGetCart).toBeCalledTimes(1); | ||
expect(mockGetCart).toBeCalledWith({'email': localStorage.getItem("username")}, undefined); | ||
}); |