Build a cash register project issue with tests

Hi there, I’m having an issue with the last test: “When the price is less than the value in the #cash element, the total cash in drawer (cid) is equal to the change due, and when the #purchase-btn element is clicked, the value in the #change-due element should be ‘Status: CLOSED’ with the change due in coins and bills sorted from highest to lowest.” I have reviewed the code and tested it manually, and everything seems to be working correctly, but the test still won’t pass.

Here is the HTML and JavaScript for you to check.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="./css/styles.css">
    <title>Cash Register</title>
</head>
<body>
    <div class="container">
        <h1>Cash Register</h1>
        <div class="cid-container">
            <header class="justify">
                <p>Denomination</p>
                <p class="amount">Amount</p>
            </header>
            <div class="change-container"></div>
        </div>

        <input type="number" id="cash">
        <button id="purchase-btn">Purchase</button>

        <div id="change-due"></div>
    </div>
    <script src="index.js"></script>
</body>
</html>
const CIDContainer = document.querySelector(".change-container");
const cashInput = document.querySelector("#cash");
const purchaseBtn = document.querySelector("#purchase-btn");
const changeDueContainer = document.querySelector("#change-due")

let price = 19.5;
let cash;
let drawerStatus = "OPEN";

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 currencyValues = {
    "ONE HUNDRED": 100,
    "TWENTY": 20,
    "TEN": 10,
    "FIVE": 5,
    "ONE": 1,
    "QUARTER": 0.25,
    "DIME": 0.1,
    "NICKEL": 0.05,
    "PENNY": 0.01
}

document.addEventListener("DOMContentLoaded", () => {
    fillCIDContainer()
})

const fillCIDContainer = () => {
    cid.forEach(value => {
        const billDiv = document.createElement("div");
        billDiv.classList.add("justify");
        billDiv.style.color = value[1] > 0 ? "green" : "red";

        const denominationP = document.createElement("p");
        const amountP = document.createElement("p");
        amountP.classList.add("amount")

        denominationP.textContent = value[0];
        amountP.textContent = `$${Number(value[1]).toFixed(2)}`

        billDiv.appendChild(denominationP);
        billDiv.appendChild(amountP);

        CIDContainer.appendChild(billDiv);
    })
}

purchaseBtn.addEventListener("click", () => {
    if (drawerStatus === "CLOSED") return;

    const cashValue = cashInput.value.replaceAll(" ", "");
    let totalCID = cid.reduce((acc, val) => Number.parseFloat((acc + val[1]).toFixed(2)), 0);
    
    cashInput.value = "";

    if (!cashValue) return;

    if(cashValue < price) {
        alert("Customer does not have enough money to purchase the item");
        return;
    }

    if (Number(cashValue) === price) {
        changeDueContainer.textContent = "No change due - customer paid with exact cash"
        return;
    }

    if (Number(cashValue - price) > totalCID) {
        drawerStatus = "INSUFFICIENT_FUNDS";
        fillChangeDueContainer({});
        fillCIDContainer();
        return;
    }

    const changeDue = getResult(price, cashValue);
    
    if (!Object.keys(changeDue).length) {
        drawerStatus = "INSUFFICIENT_FUNDS";
        fillChangeDueContainer({});
        fillCIDContainer();
        return;
    }

    totalCID = cid.reduce((acc, val) => Number.parseFloat((acc + val[1]).toFixed(2)), 0);
    drawerStatus = totalCID === 0 ? "CLOSED" : "OPEN";

    fillChangeDueContainer(changeDue);
    fillCIDContainer()
})

const getResult = (price, cash) => getChange(cash - price)

const getChange = amount => {
    const changeList = {};
    const cidAux = cid.map(item => [...item]);

    for (let i = cidAux.length - 1; i >= 0;) {
        if (!(amount - currencyValues[cidAux[i][0]] >= 0 && cidAux[i][1] > 0)) {
            i--;
            continue;
        }

        amount = Number((amount - currencyValues[cidAux[i][0]]).toFixed(2));
        cidAux[i][1] = Number.parseFloat((cidAux[i][1] - currencyValues[cidAux[i][0]]).toFixed(2));

        if (!changeList[cidAux[i][0]]) {
            changeList[cidAux[i][0]] = currencyValues[cidAux[i][0]]
        }
        else {
            changeList[cidAux[i][0]] += currencyValues[cidAux[i][0]]
        }
    }

    if (amount === 0) {
        cid = cidAux;
        return changeList;
    }

    return {};
}

const clearContainer = (container) => {
    const children = [...container.children];

    for (let i = 0; i < children.length; i++) {
        children[i].remove()
    } 
}

const fillChangeDueContainer = (changeDue) => {
    clearContainer(changeDueContainer);
    clearContainer(CIDContainer);

    changeDueContainer.textContent = `Status: ${drawerStatus}`

    for(let denomination in changeDue) {
        const denominationP = document.createElement("p");
        denominationP.textContent = `${denomination}: $${changeDue[denomination].toFixed(2)}`

        changeDueContainer.appendChild(denominationP);
    }

    console.log(cid)
}

These variables should not be in the global scope

Thank you for pointing that out. Could you help me understand how having those variables in the global scope might be affecting the code and causing the issue I’m facing?

That prevents your function from ever being used more than once

I just realized that I’m not even using the cash variable :expressionless: