Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: [#188079116] Show the License Status Check in Renewal Events #8551

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
---
notesMd: ""
urlSlug: health-care-services-firm-renewal
renewalEventDisplayName: Health Care Service Firm Renewal Deadline
expirationEventDisplayName: Health Care Service Firm Expiration
filename: health-care-services-firm-renewal
Copy link
Contributor

@FarazA22 FarazA22 Sep 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Boulder: the goal of this ticket is to add the license status component to the [licenseUrlSlug] page. This page renders the content living within content/src/licenses. The user is able to access the calendar license page by clicking the renewal/expiration link on the filings calendar. Alot of the existing functionality you added can be removed because it's already existing (i.e. mgmt/search, loading files, etc)

Copy link
Contributor

@FarazA22 FarazA22 Sep 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One approach is to add the existing component to the [licenseUrlSlug] page and create tests to validate the data renders. All the other logic is not necessary because it's working. You may want to refactor the content/src/licenses to something like content/src/licenseCalendarEvents so it's more clear.

name: Health Care Service Firm Renewal Deadline
icon: update-purple.svg
licenseName: Health Care Services
urlSlug: health-care-services-firm-renewal
previewType: renewal
summaryDescriptionMd: If you are interested in continuing to employ individuals
to provide health care, personal care, or companion services (either in-home
or facility care), you must renew your registration with the Employment and
Personnel Services within the Division of Consumer Affairs online.
aboveLicenseStatusContent: ""
---

If you are interested in continuing to employ, place, arrange for the placement of, or in any way refer, an individual to provide companion care services, health care services, or personal care services in the personal residence of a person with a disability or who is age 60 or older. You must renew your registration with the Division of Consumer Affairs online.
Expand Down
9 changes: 9 additions & 0 deletions content/src/fieldConfig/anytime-action-renewals-defaults.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"anytimeActionRenewalsDefaults": {
"LicenseDefaultText": "You can renew your license 60 days before it expires and up to 30 days after expiration. If you fail to renew your license at this point, your license will be suspended and you won't be able to provide your licensed services",
"licenseExpirationHeaderText": "EXPIRATION DATE:",
"licenseStatusHeaderText": "Current Status",
"licenseLastUpdatedText": "Last Updated:",
"licenseDefaultText": "You can renew your license 60 days before it expires and up to 30 days after expiration. If you fail to renew your license at this point, your license will be suspended and you won't be able to provide your licensed services"
}
}
61 changes: 61 additions & 0 deletions web/public/mgmt/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3557,6 +3557,67 @@ collections:
- { label: "License Status Header Text", name: "licenseStatusHeaderText", widget: "string" }
- { label: "License Last Updated Text", name: "licenseLastUpdatedText", widget: "string" }

- name: "anytime-action-license-renewals"
label: "Anytime Action With Consumer Affairs License Integrations (Renewals)"
folder: "content/src/anytime-action-license-renewals"
summary: "{{filename}} - {{name}}"
identifier_field: "{{filename}}"
slug: "{{fields.filename}}"
delete: true
sortable_fields: ["name", "filename"]
create: true
editor:
preview: true
fields:
- { label: "Internal Notes", name: "notesMd", widget: "markdown", required: false }
- {
label: "Filename (disabled after file creation)",
name: "filename",
widget: "write-once-read-only-no-space",
}
- { label: "License Name", name: "licenseName", widget: hidden, default: "" }
- { label: "Name/Title", name: "name", widget: "string" }
- label: "Icon"
name: icon
widget: "relation"
multiple: false
required: true
collection: "mappings"
search_fields: ["anytimeActionIcons.*.name"]
value_field: "anytimeActionIcons.*.filename"
display_fields: ["anytimeActionIcons.*.name"]
- { label: "Url Slug - Internal Routing", name: "urlSlug", widget: "nospace", required: true }
- { label: "Summary Description", name: "summaryDescriptionMd", widget: "markdown" }
- { label: "Below License Status Content", name: "body", widget: "markdown", required: true }
- { label: "Form", name: "form", widget: "string", required: false }
- { label: "Call To Action Text", name: "callToActionText", widget: "string", required: false }
- { label: "Call To Action Link", name: "callToActionLink", widget: "string", required: false }

- name: "anytime-action-renewals-defaults"
label: "Anytime Action Renewals Defaults"
delete: false
create: false
files:
- label: "Anytime Action Renewals Defaults"
name: "anytime-action-renewals-defaults"
file: "content/src/fieldConfig/anytime-action-renewals-defaults.json"
editor:
preview: true
fields:
- label: "Anytime Action renewals Defaults"
name: anytimeActionRenewalsDefaults
collapsed: false
widget: object
fields:
- { label: "LicenseDefaultText", name: "licenseDefaultText", widget: "string" }
- {
label: "License Expiration Header Text",
name: "licenseExpirationHeaderText",
widget: "string",
}
- { label: "License Status Header Text", name: "licenseStatusHeaderText", widget: "string" }
- { label: "License Last Updated Text", name: "licenseLastUpdatedText", widget: "string" }

- name: "anytime-action-links"
label: "Anytime Action External Link Only"
folder: "content/src/anytime-action-links"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
import { AnytimeActionLicenseRenewalElement } from "@/components/tasks/anytime-action/AnytimeActionLicenseRenewalElement";
import { getMergedConfig } from "@/contexts/configContext";
import { AnytimeActionLicenseRenewal } from "@/lib/types/types";
import { generateAnytimeActionLicenseRenewal } from "@/test/factories";
import { useMockBusiness } from "@/test/mock/mockUseUserData";
import {
defaultDateFormat,
licenseSearchDateFormat,
parseDateWithFormat,
} from "@businessnjgovnavigator/shared/";
import { randomElementFromArray } from "@businessnjgovnavigator/shared/arrayHelpers";
import { taskIdLicenseNameMapping } from "@businessnjgovnavigator/shared/license";
import { generateLicenseData, generateLicenseDetails } from "@businessnjgovnavigator/shared/test";
import { fireEvent, render, screen } from "@testing-library/react";

jest.mock("@/lib/data-hooks/useUserData", () => ({ useUserData: jest.fn() }));
const Config = getMergedConfig();

describe("<AnytimeActionLicenseRenewalElement />", () => {
beforeEach(() => {
jest.resetAllMocks();
useMockBusiness({});
});

const renderAnytimeActionLicenseRenewalElement = (overrides?: AnytimeActionLicenseRenewal): void => {
const anytimeActionLicenseRenewalElement = generateAnytimeActionLicenseRenewal({
...overrides,
});
render(
<AnytimeActionLicenseRenewalElement anytimeActionLicenseRenewal={anytimeActionLicenseRenewalElement} />
);
};

it("renders Anytime Action License Renewal Element with Active status", () => {
const licenseName = randomElementFromArray(Object.values(taskIdLicenseNameMapping));

useMockBusiness({
licenseData: generateLicenseData({
licenses: {
[licenseName]: generateLicenseDetails({
licenseStatus: "ACTIVE",
}),
},
}),
});

const anytimeActionLicense = [
generateAnytimeActionLicenseRenewal({
name: "some-license-name",
urlSlug: "some-url",
filename: "some-filename-license",
licenseName,
}),
];
renderAnytimeActionLicenseRenewalElement(anytimeActionLicense[0]);
expect(screen.getByTestId("permit-ACTIVE")).toBeInTheDocument();
});

it("renders Anytime Action License Renewal Element with company name and address", () => {
const licenseName = randomElementFromArray(Object.values(taskIdLicenseNameMapping));
const licenseAddress = {
name: "Business Sample",
addressLine1: "1 Business Way",
addressLine2: "Suite 10",
zipCode: "08211",
};

useMockBusiness({
licenseData: generateLicenseData({
licenses: {
[licenseName]: generateLicenseDetails({
licenseStatus: "ACTIVE",
nameAndAddress: {
...licenseAddress,
},
}),
},
}),
});

const anytimeActionLicense = [
generateAnytimeActionLicenseRenewal({
name: "some-license-name",
urlSlug: "some-url",
filename: "some-filename-license",
licenseName,
}),
];
const secondLineAddress = licenseAddress.addressLine2 ? ` ${licenseAddress.addressLine2}` : "";
const address =
`${licenseAddress.addressLine1}${secondLineAddress}, ${licenseAddress.zipCode} NJ`.toUpperCase();
renderAnytimeActionLicenseRenewalElement(anytimeActionLicense[0]);
expect(screen.getByText(licenseAddress.name.toUpperCase())).toBeInTheDocument();
expect(screen.getByText(address)).toBeInTheDocument();
});

it("renders Anytime Action License RenewalElement with last updated date", () => {
const licenseName = randomElementFromArray(Object.values(taskIdLicenseNameMapping));
const licenseAddress = {
name: "Business Sample",
addressLine1: "1 Business Way",
addressLine2: "Suite 10",
zipCode: "08211",
};

useMockBusiness({
licenseData: generateLicenseData({
licenses: {
[licenseName]: generateLicenseDetails({
licenseStatus: "ACTIVE",
nameAndAddress: {
...licenseAddress,
},
lastUpdatedISO: "2018-04-23T10:26:00.996Z",
}),
},
}),
});

const anytimeActionLicense = [
generateAnytimeActionLicenseRenewal({
name: "some-license-name",
urlSlug: "some-url",
filename: "some-filename-license",
licenseName,
}),
];

renderAnytimeActionLicenseRenewalElement(anytimeActionLicense[0]);
expect(
screen.getByText(
parseDateWithFormat("2018-04-23T10:26:00.996Z", defaultDateFormat).format(licenseSearchDateFormat)
)
).toBeInTheDocument();
});

it("renders Anytime Action License Renewal Element with checklist items", () => {
const licenseName = randomElementFromArray(Object.values(taskIdLicenseNameMapping));
const licenseAddress = {
name: "Business Sample",
addressLine1: "1 Business Way",
addressLine2: "Suite 10",
zipCode: "08211",
};

useMockBusiness({
licenseData: generateLicenseData({
licenses: {
[licenseName]: generateLicenseDetails({
licenseStatus: "ACTIVE",
nameAndAddress: {
...licenseAddress,
},
checklistItems: [{ title: `checklist-title-1`, status: "ACTIVE" }],
lastUpdatedISO: "2018-04-23T10:26:00.996Z",
}),
},
}),
});

const anytimeActionLicense = [
generateAnytimeActionLicenseRenewal({
name: "some-license-name",
urlSlug: "some-url",
filename: "some-filename-license",
licenseName,
}),
];

renderAnytimeActionLicenseRenewalElement(anytimeActionLicense[0]);
const applicationCheckListItems = screen.getByText(
Config.licenseSearchTask.applicationChecklistItemsText
);

expect(applicationCheckListItems).toBeInTheDocument();
fireEvent.click(applicationCheckListItems);
Copy link
Contributor

@alexander-littleton alexander-littleton Sep 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[sand] Hey just a heads up, we should probably be using userEvent here since it more realistically simulates user interactions per the documentation. I believe fireEvent is recommended to be used as a last resort when an event is not covered by userEvent.

expect(screen.getByText("checklist-title-1")).toBeInTheDocument();
});
});
Loading