Skip to content

Commit

Permalink
Merge pull request #156 from Arquisoft/develop - new tests
Browse files Browse the repository at this point in the history
New tests and fixes to master
  • Loading branch information
sebaslh01 authored May 1, 2022
2 parents ea6f45f + 06179f9 commit 054546b
Show file tree
Hide file tree
Showing 8 changed files with 366 additions and 53 deletions.
6 changes: 1 addition & 5 deletions webapp/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Header from './components/fragments/NavBar';
import Footer from './components/fragments/Footer';
import { ItemCart } from './shared/shareddtypes';
import './css/App.css';
import { BrowserRouter as Router, Routes, Route, useSearchParams } from 'react-router-dom';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';

import AboutUs from "./components/other/about_us"
import SOLIDLogin from "./components/user/SOLIDLogin";
Expand All @@ -15,7 +15,6 @@ import Shipping from './components/checkout-shipping/Shipping';
import MainProducts from './components/products/MainProducts';
import ProductPage from './components/products/ProductPage';


import ShoppingCart from './components/cart/ShoppingCart';
import Checkout from './components/checkout-shipping/Checkout';
import AdminView from './components/administrator/AdminView';
Expand All @@ -31,9 +30,6 @@ function App(): JSX.Element {

const [cart, setCart] = useState<ItemCart[]>([]);




const refreshCartList = () => {
setCart(getCart());
}
Expand Down
9 changes: 4 additions & 5 deletions webapp/src/components/cart/CartItem.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { useState, useEffect } from 'react';
import { ItemCart, Product } from "../../shared/shareddtypes";
import { addToCart, baseApiEndPoint, getProductImages } from '../../api/api';

import Typography from "@mui/material/Typography";

import Button from "@mui/material/Button";
import { Card } from "@mui/material";
import DeleteIcon from '@mui/icons-material/Delete';
import './../../css/CartItem.css'

type CartItemProps = {
item: ItemCart;
updateTotal: () => void;
Expand Down Expand Up @@ -35,14 +34,14 @@ function CartItem(props: CartItemProps) {
useEffect(() => {
setQuantity(props.item.quantity);
getImage();
}, [props.item.quantity]);
}, [props.item.product.image]);



return (

// <div className="card-item">
<Card id="card-item">
<Card data-testid={"it"+props.item.product.id} id={props.item.product.id} className="card-item">
<img className="item-img" src={imgPath} alt={props.item.product.name} />
<div className="item-info">

Expand Down Expand Up @@ -74,7 +73,7 @@ function CartItem(props: CartItemProps) {
+
</Button>

<Button
<Button data-testid={props.item.product.id+"-delete"}
onClick={() => props.deleteItem(props.item.product)}
color="error" size="medium" startIcon={<DeleteIcon />}
>
Expand Down
55 changes: 13 additions & 42 deletions webapp/src/components/cart/ShoppingCart.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useState, useEffect } from 'react';
import { ItemCart, Product } from "../../shared/shareddtypes";
import { addToCart, deleteFromCart, getCart } from '../../api/api';
import { deleteFromCart, getCart } from '../../api/api';

import Typography from "@mui/material/Typography";
import Stack from "@mui/material/Stack";
Expand All @@ -19,59 +19,28 @@ const Img =
display: "block"
});

function addProduct(product: Product): void {
addToCart({ product: product, quantity: 1 });
}

function ShoppingCart(props: ShoppingCartProps): JSX.Element {

const [total, setTotal] = useState<number>(0);

const updateTotal = async () => {
let cart = await getCart();
let cart = getCart();
setTotal(cart.reduce((acc, item) => acc + item.product.price * item.quantity, 0));
};


const deleteItem = async (product: Product) => {
await deleteFromCart(product.id);
updateTotal();
//set props.items to the new items
let i = props.items.findIndex(item => item.product.id === product.id);
if (i >= 0) {
delete props.items[i];
reorganizeProps();
}

props.refreshCartList();
};


function reorganizeProps(): void {
let temp: ItemCart[] = [];

//copy all non empty elements
props.items.forEach(item => {
if (item != undefined)
temp.push(item);
deleteFromCart(product.id).then(() => {
updateTotal();
props.refreshCartList();
});

//empty props.items
props.items.length = 0;

//copy back to props.items
temp.forEach(item => {
props.items.push(item);
});

}

};



useEffect(() => {
setTotal(props.items.reduce((acc, item) => acc + item.product.price * item.quantity, 0));
}, [props.items]);


}, []);



Expand All @@ -85,7 +54,9 @@ function ShoppingCart(props: ShoppingCartProps): JSX.Element {
);
}
else {
//console.log("Length: " + props.items.length)

console.log("Length: " + props.items.length)
console.log(props.items);
let res = props.items.map((item: ItemCart) => {
if (item !== null && item.quantity > 0) {
return <CartItem refreshCartList={props.refreshCartList} updateTotal={updateTotal} deleteItem={deleteItem} item={item} />
Expand Down
143 changes: 143 additions & 0 deletions webapp/src/components/cart/tests/Cart.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import { fireEvent, render,screen, waitFor } from "@testing-library/react";
import { BrowserRouter as Router } from "react-router-dom";
import ShoppingCart from "../ShoppingCart";
import { ItemCart, Product } from "../../../shared/shareddtypes";

import * as api from '../../../api/api';
const doNothing = () => {
//this is intentional for testing purposes. We won't be using a proper refreshCarList so we'll pass this empty function. to the component
};
const fakeProd: Product = {} as Product;

/**
* Test that the shopping cart is rendered correctly
* when empty
*/
test("Cart empty is rendered correctly", async () => {


const { getByText } = render(
<Router>
<ShoppingCart
items={[]}
refreshCartList={doNothing}
/>
</Router>
)

// The expected messages
expect(getByText("Shopping cart")).toBeInTheDocument();
expect(getByText("The shopping cart is empty")).toBeInTheDocument();

// The total ammount must be 0
expect(getByText("0.00 €")).toBeInTheDocument();
});

/**
* Test that the shopping cart is rendered correctly
* when containing several products
*/
test("Cart with products is rendered correctly", async () => {

const itemCarts: ItemCart[] = [
{
product: {
id: "1234",
name: "P1",
description: "P1 description",
price: 0.1,
image: "",
category: "Testing",
reviews: [],
product: fakeProd,
_id: "1234",
quantity: 2
},
quantity: 2
},
{
product: {
id: "4321",
name: "P2",
description: "P2 description",
price: 6.7,
image: "",
category: "Testing",
reviews: [],
product: fakeProd,
_id: "4321",
quantity: 1
},
quantity: 1
}
];

const { getByText } = render(
<Router>
<ShoppingCart
items={itemCarts}
refreshCartList={doNothing}
/>
</Router>
)

// The expected messages
expect(getByText("Shopping cart")).toBeInTheDocument();
expect(getByText("P1 description")).toBeInTheDocument();
expect(getByText("P2 description")).toBeInTheDocument();

// The total ammount must be 0.1 * 2 + 6.7 = 6.9
expect(getByText("6.90 €")).toBeInTheDocument();
});

/**
* Test that the shopping cart is rendered correctly
* after some or all of the items are deleted
*/
test("Cart can have its products deleted", async () => {
const cartWithOneItem: ItemCart[] = [
{
product: {
id: "9999",
name: "P0",
description: "P0 description",
price: 0.5,
image: "",
category: "Testing",
reviews: [],
product: fakeProd,
_id: "9999",
quantity: 2
},
quantity: 2
}
];

const mockAPI = jest.spyOn(api, "deleteFromCart");
const { getByText } = render(
<Router>
<ShoppingCart
items={cartWithOneItem}
refreshCartList={doNothing}
/>
</Router>
)

// The initial total ammount must be 0.5 * 2 = 1.0
expect(getByText("1.00 €")).toBeInTheDocument();
expect(screen.getByTestId('it9999')).toBeInTheDocument();
fireEvent.click(getByText("-"));

// The product should still be there, and ammount should update
expect(getByText("P0 description")).toBeInTheDocument();
expect(getByText("0.5 €")).toBeInTheDocument();

// Reduce quantity should be disabled (quantity = 1)
expect(getByText("-")).toBeDisabled();
expect(screen.getByTestId("9999-delete")).toBeInTheDocument();

fireEvent.click(screen.getByTestId("9999-delete"));

await waitFor(() => expect(mockAPI).toHaveBeenCalledTimes(1));
//we cannot test view is changed as this is done by the function 'refreshCarList'.
});
Loading

0 comments on commit 054546b

Please sign in to comment.