The tests of the “Cash Register” project do not pass, but it seems to me that the behavior of the application is as expected. Running the application in the browser seems to give the right results.
The project is this:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Cash Register</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<header>
<div id="author">francisford Coppola Connection</div>
<div id="title">Cash Register</div>
</header>
<main>
<div id="input-side">
<form>
<div id="input-container">
<div>
<label for="cash">Enter cash from customer:</label>
<input type="number" name="cash" id="cash" />
</div>
</div>
<div id="button-container">
<button type="button" id="purchase-btn">Purchase</button>
</div>
</form>
</div>
<div id="output-side">
<div id="price-container">
<span class="price">Price:</span>
<div id="price"></div>
</div>
<div id="div-container">
<div id="change-due-container">
<span class="change">Change Due</span>
<div id="change-due"></div>
</div>
<div id="change-in-drawer-container">
<span class="change">Change in Drawer</span>
<div id="change-in-drawer"></div>
</div>
</div>
</div>
</main>
<script src="script.js"></script>
</body>
</html>
CSS
:root {
--shady-lady: #b59db5;
--camelot: #823462;
--grape: #3f1947;
--green-pea: #226651;
--summer-green: #92c1a6;
--antique-white: #faebd7;
}
*,
::after,
::before {
padding: 0;
margin: 0;
box-sizing: border-box;
}
html {
font-family: Cambria, Cochin, Georgia, Times, 'Times New Roman', serif;
font-size: 15px;
}
body {
background-color: var(--grape);
color: var(--antique-white);
}
header {
top: 0;
left: 0;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
gap: 3rem;
margin-top: 4rem;
}
#author {
font-size: 3rem;
font-weight: bold;
color: var(--summer-green);
}
#title {
font-size: 5rem;
font-weight: bold;
}
main {
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
border: 1px solid var(--shady-lady);
padding: 10px;
width: 60%;
margin: 7rem auto;
}
#input-side,
#output-side {
border: 1px solid var(--shady-lady);
padding: 5px;
}
#input-side {
width: 100%;
}
form {
display: flex;
flex-direction: row;
justify-content: center;
}
#input-container,
#button-container {
display: flex;
padding: 5px;
width: 100%;
}
#input-container {
display: flex;
flex-direction: row;
justify-content: flex-end;
}
label[for='cash'],
#cash {
display: block;
font-size: 1.5rem;
}
#cash {
padding-left: 0.33rem;
}
#button-container {
align-items: flex-end;
}
#purchase-btn {
height: 2rem;
padding: 0 1rem;
}
#output-side {
width: 75%;
}
#price-container {
display: flex;
flex-direction: row;
justify-content: center;
position: relative;
top: 0;
left: 0;
width: 100%;
}
#price-container div {
background-color: var(--summer-green);
color: var(--camelot);
font-size: 1.5rem;
font-weight: bold;
text-align: center;
width: 15rem;
height: 1.5rem;
margin-left: 1rem;
}
#div-container {
display: flex;
gap: 10px;
}
#change-due-container,
#change-in-drawer-container {
display: block;
width: 49%;
margin-top: 0.5rem;
}
#change-due,
#change-in-drawer {
width: 100%;
height: 17rem;
background-color: var(--summer-green);
color: var(--camelot);
font-size: 1.1rem;
margin-top: 0.33rem;
padding: 1rem;
}
span.price {
font-size: 1.5rem;
}
span.change {
font-size: 1.2rem;
}
JS
let price = 1.87;
let cid = [
['PENNY', 1.01],
['NICKEL', 2.05],
['DIME', 3.1],
['QUARTER', 4.25],
['ONE', 90],
['FIVE', 55],
['TEN', 20],
['TWENTY', 60],
['ONE HUNDRED', 100],
];
const drawerContent = [
{ figure: 'one hundred', value: 100 },
{ figure: 'twenty', value: 20 },
{ figure: 'ten', value: 10 },
{ figure: 'five', value: 5 },
{ figure: 'one', value: 1 },
{ figure: 'quarter', value: 0.25 },
{ figure: 'dime', value: 0.1 },
{ figure: 'nickel', value: 0.05 },
{ figure: 'penny', value: 0.01 },
];
const cashInput = document.getElementById('cash');
const purchaseButton = document.getElementById('purchase-btn');
const priceDiv = document.getElementById('price');
const changeDueDiv = document.getElementById('change-due');
const changeInDrawerDiv = document.getElementById('change-in-drawer');
priceDiv.textContent = price;
const updateDrawerContent = () => {
for (const line of cid) {
drawerContent.find((el) => el.figure == line[0].toLowerCase()).amount = line[1];
}
};
updateDrawerContent();
const updateChangeInDrawerText = () => {
let drawerContentText = '';
for (const figure of drawerContent) {
drawerContentText += '<p><strong>' + figure.figure + ':</strong> ' + figure.amount + '</p>';
}
changeInDrawerDiv.innerHTML = `${drawerContentText}`;
};
updateChangeInDrawerText(cid);
const handlePurchaseButton = () => {
const cashAmount = parseFloat(cashInput.value) || null;
const priceAmount = parseFloat(priceDiv.textContent) || null;
if (cashAmount === null || cashAmount === undefined) {
alert('You must indicate how much money the customer has paid');
return;
}
if (cashAmount < priceAmount) {
alert('Customer does not have enough money to purchase the item');
return;
}
if (cashAmount === priceAmount) {
changeDueDiv.textContent = 'No change due - customer paid with exact cash';
return;
}
let changeAmount = cashAmount - priceAmount;
let hasChanged = false;
const totalDrawer = cid.reduce((totalAmount, figure) => totalAmount + figure[1], 0);
let status = '';
if (totalDrawer < changeAmount) {
status = 'INSUFFICIENT_FUNDS';
changeDueDiv.textContent = `Status: ${status}`;
return;
}
while (changeAmount > 0) {
const currChangeAmount = changeAmount;
for (const figure of drawerContent) {
if (changeAmount >= parseFloat(figure.value) && parseFloat(figure.amount) > 0) {
changeAmount = Number((changeAmount - figure.value).toFixed(2));
figure.amount = Number((figure.amount - figure.value).toFixed(2));
hasChanged = true;
break;
}
}
if (!hasChanged || currChangeAmount == changeAmount) {
hasChanged = false;
break;
}
}
if (!hasChanged) {
status = 'INSUFFICIENT_FUNDS';
changeDueDiv.textContent = `Status: ${status}`;
updateDrawerContent();
return;
} else if (totalDrawer == cashAmount - priceAmount) {
status = '<p>Status: CLOSED</p>';
for (const line of cid.reverse()) {
const difference = (line[1] - drawerContent.find((el) => el.figure == line[0].toLowerCase()).amount).toFixed(2);
status += difference <= 0 ? '' : `<p>${line[0]}: $${difference}</p>`;
}
changeDueDiv.innerHTML = status;
updateChangeInDrawerText();
} else {
status = '<p>Status: OPEN</p>';
for (const line of cid.reverse()) {
const difference = (line[1] - drawerContent.find((el) => el.figure == line[0].toLowerCase()).amount).toFixed(2);
status += difference <= 0 ? '' : `<p>${line[0]}: $${difference}</p>`;
}
changeDueDiv.innerHTML = status;
updateChangeInDrawerText();
}
};
purchaseButton.addEventListener('click', handlePurchaseButton);
These are the errors detected by tests with screenshots of the application in the browser:
When the value in the #cash element is less than price, an alert should appear with the text "Customer does not have enough money to purchase the item".
When the value in the #cash element is equal to price, the value in the #change-due element should be "No change due - customer paid with exact cash.
-
When price is 19.5, the value in the #cash element is 20, cid is
[ ["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100] ]
and the #purchase-btn element is clicked, the value in the #change-due element should be “Status: OPEN QUARTER: $0.5”.
-
When price is 3.26, the value in the #cash element is 100, cid is
[ ["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100] ]
and the #purchase-btn element is clicked, the value in the #change-due element should be “Status: OPEN TWENTY: $60 TEN:
$20 FIVE: $15 ONE: $1 QUARTER: $0.5 DIME: $0.2 PENNY: $0.04”.
-
When price is 19.5, the value in the #cash element is 20, cid is
[ ["PENNY", 0.5], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0] ]
and the #purchase-btn element is clicked, the value in the #change-due element should be “Status: CLOSED PENNY: $0.5”.
What could be the problem?













