diff --git a/frontend/cypress/e2e/canDetail.cy.js b/frontend/cypress/e2e/canDetail.cy.js index ff60365116..575397ad5a 100644 --- a/frontend/cypress/e2e/canDetail.cy.js +++ b/frontend/cypress/e2e/canDetail.cy.js @@ -182,7 +182,6 @@ describe("CAN detail page", () => { cy.get("[data-cy='can-budget-fy-card']").should("contain", "0"); cy.get("#budget-amount").type(can504.budgetAmount); cy.get("#budget-amount").clear(); - cy.get(".usa-error-message").should("exist").contains("This is required information"); cy.get("#budget-amount").type(can504.budgetAmount); cy.get(".usa-error-message").should("not.exist"); cy.get("#add-fy-budget").click(); @@ -197,16 +196,57 @@ describe("CAN detail page", () => { .and("contain", `FY ${currentFiscalYear}`) .and("contain", "$5,000,000.00"); }); + it("handle funding received form", () => { + cy.visit(`/cans/${can504.number}/funding`); + cy.get("#fiscal-year-select").select(currentFiscalYear); + cy.get("#edit").click(); + // check that all buttons (saved, all funding received) are disabled + cy.get("[data-cy=add-funding-received-btn]").should("be.disabled"); + cy.get("[data-cy=save-btn]").should("be.disabled"); + // enter amount into input + cy.get("#funding-received-amount").type("1_000_000"); + cy.get("#funding-received-amount").blur(); + cy.get("[data-cy=add-funding-received-btn]").should("be.enabled"); + // clear and check validation + cy.get("#funding-received-amount").clear(); + cy.get("[data-cy=add-funding-received-btn]").should("be.disabled"); + // Test received amount over budget amount + cy.get("#funding-received-amount").type("6_000_000"); + cy.get("[data-cy=add-funding-received-btn]").should("be.disabled"); + cy.get(".usa-error-message").should("exist").contains("Amount cannot exceed FY Budget"); + cy.get("#funding-received-amount").clear(); + cy.get("#funding-received-amount").type("1_000_000"); + cy.get("#funding-received-amount").blur(); + cy.get("[data-cy=add-funding-received-btn]").should("be.enabled"); + // enter and click on add funding received + cy.get("#notes").type("Test notes"); + cy.get("[data-cy=add-funding-received-btn]").click(); + // check card on the right + cy.get("[data-cy=budget-received-card]").should("exist").and("contain", "1,000,000.00"); + // click on button at bottom of form + cy.get("[data-cy=save-btn]").click(); + // check success alert + cy.get(".usa-alert__body").should("contain", `The CAN ${can504.nickname} has been successfully updated.`); + // check that table and card are updated + cy.get("[data-cy=budget-received-card]") + .should("exist") + .and("contain", "Received $1,000,000.00 of $5,000,000.00"); + cy.get("tbody").children().should("contain", "2025").and("contain", "$1,000,000.00").and("contain", "20%"); + }); it("handles cancelling from budget form", () => { cy.visit(`/cans/${can504.number}/funding`); cy.get("#fiscal-year-select").select(currentFiscalYear); cy.get("#edit").click(); - cy.get("#carry-forward-card").should("contain", "0"); + cy.get("#carry-forward-card").should("contain", "$ 5,000,000.00"); cy.get("[data-cy='can-budget-fy-card']").should("contain", "5,000,000.00"); cy.get("#budget-amount").type("6_000_000"); cy.get("#add-fy-budget").click(); cy.get("[data-cy='can-budget-fy-card']").should("contain", "6,000,000.00"); cy.get("#save-changes").should("be.enabled"); + // test funding received form + cy.get("#funding-received-amount").type("1_000_000"); + cy.get("[data-cy=add-funding-received-btn]").click(); + // cancel changes cy.get("[data-cy=cancel-button]").should("be.enabled"); cy.get("[data-cy=cancel-button]").click(); cy.get(".usa-modal__heading").should( @@ -214,11 +254,15 @@ describe("CAN detail page", () => { "Are you sure you want to cancel editing? Your changes will not be saved." ); cy.get("[data-cy='confirm-action']").click(); - cy.get("[data-cy=budget-received-card]").should("exist").and("contain", "Received $0.00 of $5,000,000.00"); + cy.get("[data-cy=budget-received-card]") + .should("exist") + .and("contain", "Received $1,000,000.00 of $5,000,000.00"); cy.get("[data-cy=can-budget-fy-card]") .should("exist") .and("contain", "CAN Budget by FY") .and("contain", `FY ${currentFiscalYear}`) .and("contain", "$5,000,000.00"); + // check table has one row + cy.get("tbody").children().should("have.length", 1); }); }); diff --git a/frontend/src/api/opsAPI.js b/frontend/src/api/opsAPI.js index 1536f99d43..d48fca42a2 100644 --- a/frontend/src/api/opsAPI.js +++ b/frontend/src/api/opsAPI.js @@ -230,6 +230,15 @@ export const opsApi = createApi({ }), invalidatesTags: ["Cans", "CanFunding"] }), + addCanFundingReceived: builder.mutation({ + query: ({ data }) => ({ + url: `/cans-funding-received/`, + method: "POST", + headers: { "Content-Type": "application/json" }, + body: data + }), + invalidatesTags: ["Cans", "CanFunding"] + }), getCanFundingSummary: builder.query({ query: ({ ids, fiscalYear, activePeriod, transfer, portfolio, fyBudgets }) => { const queryParams = []; @@ -433,6 +442,7 @@ export const { useUpdateCanMutation, useAddCanFundingBudgetsMutation, useUpdateCanFundingBudgetMutation, + useAddCanFundingReceivedMutation, useGetCanFundingSummaryQuery, useGetNotificationsByUserIdQuery, useGetNotificationsByUserIdAndAgreementIdQuery, diff --git a/frontend/src/components/CANs/CANBudgetForm/CANBudgetForm.jsx b/frontend/src/components/CANs/CANBudgetForm/CANBudgetForm.jsx index 07f727ed60..5c4c6ceac2 100644 --- a/frontend/src/components/CANs/CANBudgetForm/CANBudgetForm.jsx +++ b/frontend/src/components/CANs/CANBudgetForm/CANBudgetForm.jsx @@ -3,6 +3,7 @@ import icons from "../../../uswds/img/sprite.svg"; /** * @typedef {Object} CANBudgetFormProps + * @property {string} totalFunding * @property {string} budgetAmount * @property {(arg: string) => string} cn * @property {Object} res @@ -17,14 +18,13 @@ import icons from "../../../uswds/img/sprite.svg"; * @param {CANBudgetFormProps} props * @returns {JSX.Element} - The component JSX. */ -const CANBudgetForm = ({ budgetAmount, cn, res, fiscalYear, handleAddBudget, runValidate, setBudgetAmount }) => { +const CANBudgetForm = ({ totalFunding, budgetAmount, cn, res, fiscalYear, handleAddBudget, runValidate, setBudgetAmount }) => { const fillColor = budgetAmount ? "#005ea2" : "#757575"; return (
{ handleAddBudget(e); - setBudgetAmount(""); }} >
@@ -38,6 +38,7 @@ const CANBudgetForm = ({ budgetAmount, cn, res, fiscalYear, handleAddBudget, run value={budgetAmount || ""} messages={res.getErrors("budget-amount")} className={cn("budget-amount")} + placeholder={`$${totalFunding}`} />