diff --git a/.vscode/settings.json b/.vscode/settings.json index f2e33e6d9e..84221c8762 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,12 +1,6 @@ { "editor.formatOnSave": true, - "tailwindCSS.experimental.classRegex": [ - ["cva\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"] - ], + "tailwindCSS.experimental.classRegex": [["cva\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"]], "typescript.tsdk": "node_modules/typescript/lib", - "cSpell.words": [ - "Cpoc", - "Cpocs", - "opensearch" - ] + "cSpell.words": ["Cpoc", "Cpocs", "opensearch"] } diff --git a/bin/app.ts b/bin/app.ts index b874a0c7a2..4c0634f209 100644 --- a/bin/app.ts +++ b/bin/app.ts @@ -4,10 +4,7 @@ import * as cdk from "aws-cdk-lib"; import { ParentStack } from "../lib/stacks/parent"; import { DeploymentConfig } from "../lib/config/deployment-config"; import { getSecret, validateEnvVariable } from "shared-utils"; -import { - IamPathAspect, - IamPermissionsBoundaryAspect, -} from "../lib/local-aspects"; +import { IamPathAspect, IamPermissionsBoundaryAspect } from "../lib/local-aspects"; async function main() { try { @@ -36,9 +33,7 @@ async function main() { }); cdk.Aspects.of(app).add( - new IamPermissionsBoundaryAspect( - deploymentConfig.config.iamPermissionsBoundary, - ), + new IamPermissionsBoundaryAspect(deploymentConfig.config.iamPermissionsBoundary), ); cdk.Aspects.of(app).add(new IamPathAspect(deploymentConfig.config.iamPath)); } catch (error) { diff --git a/bin/cli/src/commands/deploy.ts b/bin/cli/src/commands/deploy.ts index 7ccbba928a..f363153ef0 100644 --- a/bin/cli/src/commands/deploy.ts +++ b/bin/cli/src/commands/deploy.ts @@ -1,17 +1,8 @@ import { Argv } from "yargs"; -import { - checkIfAuthenticated, - runCommand, - project, - region, - writeUiEnvFile, -} from "../lib/"; +import { checkIfAuthenticated, runCommand, project, region, writeUiEnvFile } from "../lib/"; import path from "path"; import { execSync } from "child_process"; -import { - CloudFrontClient, - CreateInvalidationCommand, -} from "@aws-sdk/client-cloudfront"; +import { CloudFrontClient, CreateInvalidationCommand } from "@aws-sdk/client-cloudfront"; import { GetParameterCommand, SSMClient } from "@aws-sdk/client-ssm"; export const deploy = { @@ -22,11 +13,7 @@ export const deploy = { }, handler: async (options: { stage: string; stack?: string }) => { await checkIfAuthenticated(); - await runCommand( - "cdk", - ["deploy", "-c", `stage=${options.stage}`, "--all"], - ".", - ); + await runCommand("cdk", ["deploy", "-c", `stage=${options.stage}`, "--all"], "."); await writeUiEnvFile(options.stage); @@ -57,16 +44,8 @@ export const deploy = { // There's a mime type issue when aws s3 syncing files up // Empirically, this issue never presents itself if the bucket is cleared just before. // Until we have a neat way of ensuring correct mime types, we'll remove all files from the bucket. - await runCommand( - "aws", - ["s3", "rm", `s3://${s3BucketName}/`, "--recursive"], - ".", - ); - await runCommand( - "aws", - ["s3", "sync", buildDir, `s3://${s3BucketName}/`], - ".", - ); + await runCommand("aws", ["s3", "rm", `s3://${s3BucketName}/`, "--recursive"], "."); + await runCommand("aws", ["s3", "sync", buildDir, `s3://${s3BucketName}/`], "."); const cloudfrontClient = new CloudFrontClient({ region, @@ -82,9 +61,7 @@ export const deploy = { }, }; - await cloudfrontClient.send( - new CreateInvalidationCommand(invalidationParams), - ); + await cloudfrontClient.send(new CreateInvalidationCommand(invalidationParams)); console.log( `Deployed UI to S3 bucket ${s3BucketName} and invalidated CloudFront distribution ${cloudfrontDistributionId}`, diff --git a/bin/cli/src/commands/destroy.ts b/bin/cli/src/commands/destroy.ts index 5444e3c0ae..1e0c245824 100644 --- a/bin/cli/src/commands/destroy.ts +++ b/bin/cli/src/commands/destroy.ts @@ -4,21 +4,10 @@ import { DeleteStackCommand, waitUntilStackDeleteComplete, } from "@aws-sdk/client-cloudformation"; -import { - checkIfAuthenticated, - confirmDestroyCommand, - project, - region, -} from "../lib"; +import { checkIfAuthenticated, confirmDestroyCommand, project, region } from "../lib"; -const waitForStackDeleteComplete = async ( - client: CloudFormationClient, - stackName: string, -) => { - return waitUntilStackDeleteComplete( - { client, maxWaitTime: 3600 }, - { StackName: stackName }, - ); +const waitForStackDeleteComplete = async (client: CloudFormationClient, stackName: string) => { + return waitUntilStackDeleteComplete({ client, maxWaitTime: 3600 }, { StackName: stackName }); }; export const destroy = { @@ -33,15 +22,7 @@ export const destroy = { demandOption: false, default: true, }), - handler: async ({ - stage, - wait, - verify, - }: { - stage: string; - wait: boolean; - verify: boolean; - }) => { + handler: async ({ stage, wait, verify }: { stage: string; wait: boolean; verify: boolean }) => { await checkIfAuthenticated(); const stackName = `${project}-${stage}`; diff --git a/bin/cli/src/commands/get-cost.ts b/bin/cli/src/commands/get-cost.ts index 7679785cce..142a636b5a 100644 --- a/bin/cli/src/commands/get-cost.ts +++ b/bin/cli/src/commands/get-cost.ts @@ -1,8 +1,5 @@ import { Argv } from "yargs"; -import { - CostExplorerClient, - GetCostAndUsageCommand, -} from "@aws-sdk/client-cost-explorer"; +import { CostExplorerClient, GetCostAndUsageCommand } from "@aws-sdk/client-cost-explorer"; import { checkIfAuthenticated, setStageFromBranch, project } from "../lib"; export const getCost = { @@ -34,21 +31,14 @@ export const getCost = { const dailyCosts = await getDailyStackCosts(tags, start, end); const yesterdayCost = dailyCosts[dailyCosts.length - 1].cost; - const averageDailyCost = - dailyCosts.reduce((acc, day) => acc + day.cost, 0) / dailyCosts.length; + const averageDailyCost = dailyCosts.reduce((acc, day) => acc + day.cost, 0) / dailyCosts.length; console.log(`Daily costs for the last 14 days:`); dailyCosts.forEach((day) => { console.log(`${day.date}: $${day.cost.toFixed(2)}`); }); - console.log( - `Average daily cost over the past 14 days: $${averageDailyCost.toFixed( - 2, - )}`, - ); - console.log( - `Yesterday, the stack ${stage} cost $${yesterdayCost.toFixed(2)}.`, - ); + console.log(`Average daily cost over the past 14 days: $${averageDailyCost.toFixed(2)}`); + console.log(`Yesterday, the stack ${stage} cost $${yesterdayCost.toFixed(2)}.`); }, }; @@ -90,9 +80,7 @@ export async function getDailyStackCosts( return results.map((result) => ({ date: result.TimePeriod?.Start || "", - cost: result.Total?.BlendedCost?.Amount - ? parseFloat(result.Total.BlendedCost.Amount) - : 0, + cost: result.Total?.BlendedCost?.Amount ? parseFloat(result.Total.BlendedCost.Amount) : 0, })); } catch (error) { throw new Error(`Failed to fetch cost: ${error}`); diff --git a/bin/cli/src/commands/logs.ts b/bin/cli/src/commands/logs.ts index 91009385f0..8f7d306711 100644 --- a/bin/cli/src/commands/logs.ts +++ b/bin/cli/src/commands/logs.ts @@ -1,11 +1,5 @@ import { Argv } from "yargs"; -import { - checkIfAuthenticated, - runCommand, - project, - region, - setStageFromBranch, -} from "../lib/"; +import { checkIfAuthenticated, runCommand, project, region, setStageFromBranch } from "../lib/"; import { ResourceGroupsTaggingAPIClient, GetResourcesCommand, @@ -24,13 +18,11 @@ export const logs = { command: "logs", describe: "Stream a lambda's cloudwatch logs.", builder: (yargs: Argv) => - yargs - .option("stage", { type: "string", demandOption: false }) - .option("functionName", { - alias: "f", - type: "string", - demandOption: true, - }), + yargs.option("stage", { type: "string", demandOption: false }).option("functionName", { + alias: "f", + type: "string", + demandOption: true, + }), handler: async (options: { stage?: string; functionName: string }) => { await checkIfAuthenticated(); const stage = options.stage || (await setStageFromBranch()); @@ -77,11 +69,7 @@ export const logs = { const lambdaLogGroup = await getLambdaLogGroup(lambda); // Stream the logs - await runCommand( - "awslogs", - ["get", lambdaLogGroup, "-s10m", "--watch"], - ".", - ); + await runCommand("awslogs", ["get", lambdaLogGroup, "-s10m", "--watch"], "."); }, }; @@ -115,9 +103,7 @@ async function getLambdasWithTags(tags: Tag[]): Promise { } // Extract Lambda function ARNs from the response - const lambdaArns = data.ResourceTagMappingList.map( - (resource) => resource.ResourceARN!, - ); + const lambdaArns = data.ResourceTagMappingList.map((resource) => resource.ResourceARN!); // Fetch Lambda function names from their ARNs const lambdaNames = await Promise.all( diff --git a/bin/cli/src/commands/open.ts b/bin/cli/src/commands/open.ts index 32b0ec432f..7de1e19cdd 100644 --- a/bin/cli/src/commands/open.ts +++ b/bin/cli/src/commands/open.ts @@ -1,21 +1,11 @@ import { Argv } from "yargs"; -import { - checkIfAuthenticated, - openUrl, - project, - setStageFromBranch, -} from "../lib"; +import { checkIfAuthenticated, openUrl, project, setStageFromBranch } from "../lib"; import { GetParameterCommand, SSMClient } from "@aws-sdk/client-ssm"; -const createOpenCommand = ( - name: string, - describe: string, - exportName: string, -) => ({ +const createOpenCommand = (name: string, describe: string, exportName: string) => ({ command: name, describe: describe, - builder: (yargs: Argv) => - yargs.option("stage", { type: "string", demandOption: false }), + builder: (yargs: Argv) => yargs.option("stage", { type: "string", demandOption: false }), handler: async (options: { stage?: string }) => { await checkIfAuthenticated(); const stage = options.stage || (await setStageFromBranch()); diff --git a/bin/cli/src/commands/test.ts b/bin/cli/src/commands/test.ts index 172e030a20..4c0cf188f9 100644 --- a/bin/cli/src/commands/test.ts +++ b/bin/cli/src/commands/test.ts @@ -16,9 +16,7 @@ export const test = { }) .check((argv) => { if (argv.coverage && argv.ui) { - throw new Error( - "You cannot use both --watch and --ui at the same time.", - ); + throw new Error("You cannot use both --watch and --ui at the same time."); } return true; }); diff --git a/bin/cli/src/commands/ui.ts b/bin/cli/src/commands/ui.ts index 5c16344aee..bc19729f4a 100644 --- a/bin/cli/src/commands/ui.ts +++ b/bin/cli/src/commands/ui.ts @@ -1,10 +1,5 @@ import { Argv } from "yargs"; -import { - checkIfAuthenticated, - runCommand, - setStageFromBranch, - writeUiEnvFile, -} from "../lib"; +import { checkIfAuthenticated, runCommand, setStageFromBranch, writeUiEnvFile } from "../lib"; export const ui = { command: "ui", diff --git a/bin/cli/src/commands/watch.ts b/bin/cli/src/commands/watch.ts index 57d42ba726..12e43cfc34 100644 --- a/bin/cli/src/commands/watch.ts +++ b/bin/cli/src/commands/watch.ts @@ -1,10 +1,5 @@ import { Argv } from "yargs"; -import { - checkIfAuthenticated, - runCommand, - setStageFromBranch, - writeUiEnvFile, -} from "../lib/"; +import { checkIfAuthenticated, runCommand, setStageFromBranch, writeUiEnvFile } from "../lib/"; export const watch = { command: "watch", @@ -18,10 +13,6 @@ export const watch = { await writeUiEnvFile(stage); - await runCommand( - "cdk", - ["watch", "-c", `stage=${stage}`, "--no-rollback"], - ".", - ); + await runCommand("cdk", ["watch", "-c", `stage=${stage}`, "--no-rollback"], "."); }, }; diff --git a/bin/cli/src/lib/env.ts b/bin/cli/src/lib/env.ts index 7c5609529b..98d68d4baa 100644 --- a/bin/cli/src/lib/env.ts +++ b/bin/cli/src/lib/env.ts @@ -1,9 +1,7 @@ export function validateEnvVariable(variableName: string): string { const value = process.env[variableName]; if (!value) { - throw new Error( - `Environment variable ${variableName} is required but not set`, - ); + throw new Error(`Environment variable ${variableName} is required but not set`); } return value; } diff --git a/bin/cli/src/lib/sts.ts b/bin/cli/src/lib/sts.ts index dbf3beb4a8..3b0c418bee 100644 --- a/bin/cli/src/lib/sts.ts +++ b/bin/cli/src/lib/sts.ts @@ -8,17 +8,12 @@ export async function checkIfAuthenticated(): Promise { await client.send(command); } catch (error) { if (error instanceof Error) { - if ( - error.message.includes("Could not load credentials from any providers") - ) { + if (error.message.includes("Could not load credentials from any providers")) { console.error( `\x1b[31m\x1b[1mERROR: This command requires AWS credentials available to your terminal. Please configure AWS credentials and try again.\x1b[0m`, ); } else { - console.error( - "Error occurred while checking authentication:", - error.message, - ); + console.error("Error occurred while checking authentication:", error.message); } } else { console.error("An unknown error occurred:", error); diff --git a/bin/cli/tsconfig.json b/bin/cli/tsconfig.json index e6cf1f168d..60b2c84d60 100644 --- a/bin/cli/tsconfig.json +++ b/bin/cli/tsconfig.json @@ -7,9 +7,7 @@ "incremental": true /* Enable incremental compilation */, "target": "ES2020" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */, "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, - "lib": [ - "ES2021" - ] /* Specify library files to be included in the compilation. */, + "lib": ["ES2021"] /* Specify library files to be included in the compilation. */, // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ diff --git a/bun.lockb b/bun.lockb old mode 100644 new mode 100755 index b16cf8952e..4dad98675f Binary files a/bun.lockb and b/bun.lockb differ diff --git a/eslint.config.mjs b/eslint.config.mjs index a6a142d197..455e69463b 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,11 +1,13 @@ // @ts-check +import { fixupPluginRules, includeIgnoreFile } from "@eslint/compat"; +import eslint from "@eslint/js"; +import eslintConfigPrettier from "eslint-config-prettier"; +import prettier from "eslint-plugin-prettier"; import react from "eslint-plugin-react"; import eslintReactHooks from "eslint-plugin-react-hooks"; -import eslint from "@eslint/js"; +import path from "path"; import tseslint from "typescript-eslint"; -import { fixupPluginRules, includeIgnoreFile } from "@eslint/compat"; import { fileURLToPath } from "url"; -import path from "path"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); @@ -15,12 +17,13 @@ export default tseslint.config( eslint.configs.recommended, ...tseslint.configs.recommended, includeIgnoreFile(gitignorePath), + eslintConfigPrettier, { plugins: { - // @ts-expect-error Types mismatch for eslint-plugin-react react, // @ts-expect-error https://github.com/facebook/react/pull/28773#issuecomment-2147149016 "react-hooks": fixupPluginRules(eslintReactHooks), + prettier, }, languageOptions: { ecmaVersion: 2020, @@ -40,11 +43,12 @@ export default tseslint.config( }, rules: { - "@typescript-eslint/no-empty-interface": "off", + "prettier/prettier": "error", "react/react-in-jsx-scope": "off", "react/jsx-no-useless-fragment": ["error", { allowExpressions: true }], "react-hooks/rules-of-hooks": "error", "react-hooks/exhaustive-deps": "warn", + "@typescript-eslint/no-empty-interface": "off", "@typescript-eslint/no-unused-vars": [ "error", { diff --git a/lib/lambda/getCpocs.test.ts b/lib/lambda/getCpocs.test.ts index 79c86c3491..c50f172e0b 100644 --- a/lib/lambda/getCpocs.test.ts +++ b/lib/lambda/getCpocs.test.ts @@ -3,7 +3,7 @@ import { APIGatewayEvent } from "aws-lambda"; import { handler } from "./getCpocs"; import { mockedServiceServer } from "mocks/server"; import { emptyCpocSearchHandler, errorCpocSearchHandler } from "mocks"; -import { cpocs } from "mocks/data/cpocs"; +import { cpocsList } from "mocks/data/cpocs"; describe("getCpocs Handler", () => { it("should return 400 if event body is missing", async () => { @@ -35,7 +35,7 @@ describe("getCpocs Handler", () => { const body = JSON.parse(res.body); expect(res.statusCode).toEqual(200); - expect(body.hits.hits).toEqual(cpocs); + expect(body.hits.hits).toEqual(cpocsList); }); it("should return 500 if an error occurs during processing", async () => { diff --git a/lib/lambda/getSubTypes.test.ts b/lib/lambda/getSubTypes.test.ts index 7c34e22793..abb94ef66b 100644 --- a/lib/lambda/getSubTypes.test.ts +++ b/lib/lambda/getSubTypes.test.ts @@ -9,11 +9,11 @@ import { TYPE_TWO_ID, TYPE_THREE_ID, DO_NOT_USE_TYPE_ID, - ERROR_AUTHORITY_ID, medicaidSubtypes, chipSubtypes, } from "mocks/data/types"; -import { TestSubtypeItemResult } from "mocks"; +import { TestSubtypeItemResult, errorSubtypeSearchHandler } from "mocks"; +import { mockedServiceServer as mockedServer } from "mocks/server"; describe("getSubTypes Handler", () => { it("should return 400 if event body is missing", async () => { @@ -25,12 +25,10 @@ describe("getSubTypes Handler", () => { expect(res.body).toEqual(JSON.stringify({ message: "Event body required" })); }); - // TODO - should this be removed? when will the result be empty and not - // just a result with an empty hit array - it.skip("should return 400 if no subtypes are found", async () => { + it("should return 400 if authority id is undefined", async () => { const event = { body: JSON.stringify({ - authorityId: NOT_FOUND_AUTHORITY_ID, + authorityId: undefined, typeIds: [TYPE_ONE_ID, TYPE_TWO_ID], }), } as APIGatewayEvent; @@ -38,9 +36,38 @@ describe("getSubTypes Handler", () => { const res = await handler(event); expect(res.statusCode).toEqual(400); - expect(res.body).toEqual( - JSON.stringify({ message: "No record found for the given authority" }), - ); + expect(res.body).toEqual(JSON.stringify({ message: "Authority Id is required" })); + }); + + it("should return 500 if there is a server error", async () => { + mockedServer.use(errorSubtypeSearchHandler); + + const event = { + body: JSON.stringify({ + authorityId: MEDICAID_SPA_AUTHORITY_ID, + typeIds: [TYPE_ONE_ID, TYPE_TWO_ID], + }), + } as APIGatewayEvent; + + const res = await handler(event); + + expect(res.statusCode).toEqual(500); + expect(res.body).toEqual(JSON.stringify({ message: "Internal server error" })); + }); + + it("should return 200 and no hits if no subtypes are found", async () => { + const event = { + body: JSON.stringify({ + authorityId: NOT_FOUND_AUTHORITY_ID, + typeIds: [TYPE_ONE_ID, TYPE_TWO_ID], + }), + } as APIGatewayEvent; + + const res = await handler(event); + const body = JSON.parse(res.body); + + expect(res.statusCode).toEqual(200); + expect(body.hits.hits).toEqual([]); }); it("should return 200 with the result if subtypes are found", async () => { @@ -76,18 +103,4 @@ describe("getSubTypes Handler", () => { expect(type?._source?.name?.match(/Do Not Use/)).toBeFalsy(); }); }); - - it("should return 500 if an error occurs during processing", async () => { - const event = { - body: JSON.stringify({ - authorityId: ERROR_AUTHORITY_ID, - typeIds: [TYPE_ONE_ID, TYPE_TWO_ID], - }), - } as APIGatewayEvent; - - const res = await handler(event); - - expect(res.statusCode).toEqual(500); - expect(res.body).toEqual(JSON.stringify({ message: "Internal server error" })); - }); }); diff --git a/lib/lambda/getSubTypes.ts b/lib/lambda/getSubTypes.ts index 95ae6ff9f3..39a9c5f3b0 100644 --- a/lib/lambda/getSubTypes.ts +++ b/lib/lambda/getSubTypes.ts @@ -59,6 +59,12 @@ export const getSubTypes = async (event: APIGatewayEvent) => { }); } const body = JSON.parse(event.body) as GetSubTypesBody; + if (!body.authorityId) { + return response({ + statusCode: 400, + body: { message: "Authority Id is required" }, + }); + } try { const result = await querySubTypes(body.authorityId, body.typeIds); diff --git a/lib/lambda/getTypes.test.ts b/lib/lambda/getTypes.test.ts index 4cfce9211f..370a417b82 100644 --- a/lib/lambda/getTypes.test.ts +++ b/lib/lambda/getTypes.test.ts @@ -5,11 +5,11 @@ import { CHIP_SPA_AUTHORITY_ID, MEDICAID_SPA_AUTHORITY_ID, NOT_FOUND_AUTHORITY_ID, - ERROR_AUTHORITY_ID, medicaidTypes, chipTypes, } from "mocks/data/types"; -import { TestTypeItemResult } from "mocks"; +import { TestTypeItemResult, errorTypeSearchHandler } from "mocks"; +import { mockedServiceServer as mockedServer } from "mocks/server"; describe("getTypes Handler", () => { it("should return 400 if event body is missing", async () => { @@ -21,19 +21,40 @@ describe("getTypes Handler", () => { expect(res.body).toEqual(JSON.stringify({ message: "Event body required" })); }); - // TODO - should this be removed? when will the result be empty and not - // just a result with an empty hit array - it.skip("should return 400 if no types are found", async () => { + it("should return 400 if authority id is undefined", async () => { const event = { - body: JSON.stringify({ authorityId: NOT_FOUND_AUTHORITY_ID }), + body: JSON.stringify({ authorityId: undefined }), } as APIGatewayEvent; const res = await handler(event); expect(res.statusCode).toEqual(400); - expect(res.body).toEqual( - JSON.stringify({ message: "No record found for the given authority" }), - ); + expect(res.body).toEqual(JSON.stringify({ message: "Authority Id is required" })); + }); + + it("should return 500 if there is a server error", async () => { + mockedServer.use(errorTypeSearchHandler); + + const event = { + body: JSON.stringify({ authorityId: MEDICAID_SPA_AUTHORITY_ID }), + } as APIGatewayEvent; + + const res = await handler(event); + + expect(res.statusCode).toEqual(500); + expect(res.body).toEqual(JSON.stringify({ message: "Internal server error" })); + }); + + it("should return 200 and no hits if no types are found", async () => { + const event = { + body: JSON.stringify({ authorityId: NOT_FOUND_AUTHORITY_ID }), + } as APIGatewayEvent; + + const res = await handler(event); + const body = JSON.parse(res.body); + + expect(res.statusCode).toEqual(200); + expect(body.hits.hits).toEqual([]); }); it("should return 200 with the result if types are found", async () => { @@ -63,15 +84,4 @@ describe("getTypes Handler", () => { expect(type?._source?.name?.match(/Do Not Use/)).toBeFalsy(); }); }); - - it("should return 500 if an error occurs during processing", async () => { - const event = { - body: JSON.stringify({ authorityId: ERROR_AUTHORITY_ID }), - } as APIGatewayEvent; - - const res = await handler(event); - - expect(res.statusCode).toEqual(500); - expect(res.body).toEqual(JSON.stringify({ message: "Internal server error" })); - }); }); diff --git a/lib/lambda/getTypes.ts b/lib/lambda/getTypes.ts index ff3f5c0e2f..6f87a24903 100644 --- a/lib/lambda/getTypes.ts +++ b/lib/lambda/getTypes.ts @@ -52,6 +52,12 @@ export const getTypes = async (event: APIGatewayEvent) => { }); } const body = JSON.parse(event.body) as GetTypesBody; + if (!body.authorityId) { + return response({ + statusCode: 400, + body: { message: "Authority Id is required" }, + }); + } try { const result = await queryTypes(body.authorityId); if (!result) diff --git a/lib/lambda/postAuth.test.ts b/lib/lambda/postAuth.test.ts new file mode 100644 index 0000000000..480a06ae74 --- /dev/null +++ b/lib/lambda/postAuth.test.ts @@ -0,0 +1,99 @@ +import { describe, it, expect, vi, afterAll } from "vitest"; +import { Context } from "aws-lambda"; +import { handler } from "./postAuth"; +import { + makoStateSubmitter, + setMockUsername, + superUser, + TEST_IDM_USERS, + USER_POOL_ID, +} from "mocks"; + +const callback = vi.fn(); +describe("process emails Handler", () => { + afterAll(() => { + setMockUsername(makoStateSubmitter); + }); + it("should return an error due to missing arn", async () => { + delete process.env.idmAuthzApiKeyArn; + + await expect(handler({ test: "test" }, {} as Context, callback)).rejects.toThrowError( + "ERROR: process.env.idmAuthzApiKeyArn is required", + ); + }); + it("should return an error due to a missing endpoint", async () => { + delete process.env.idmAuthzApiEndpoint; + await expect(handler({ test: "test" }, {} as Context, callback)).rejects.toThrowError( + "ERROR: process.env.idmAuthzApiEndpoint is required", + ); + }); + it("should return an error due to the arn being incorrect", async () => { + process.env.idmAuthzApiKeyArn = "bad-ARN"; // pragma: allowlist secret + await expect(handler({ test: "test" }, {} as Context, callback)).rejects.toThrowError( + "Failed to fetch secret bad-ARN: Secret bad-ARN has no SecretString field present in response", + ); + }); + + it("should return the request if it is missing an identity", async () => { + const consoleSpy = vi.spyOn(console, "log"); + const missingIdentity = await handler( + { + request: { + userAttributes: TEST_IDM_USERS.testStateIDMUserMissingIdentity, + }, + }, + {} as Context, + callback, + ); + expect(consoleSpy).toBeCalledWith("User is not managed externally. Nothing to do."); + expect(missingIdentity).toStrictEqual({ + request: { + userAttributes: TEST_IDM_USERS.testStateIDMUserMissingIdentity, + }, + }); + }); + it("should log an error since it cannot authorize the user", async () => { + const errorSpy = vi.spyOn(console, "error"); + const missingIdentity = await handler( + { + request: { + userAttributes: TEST_IDM_USERS.testStateIDMUser, + }, + }, + {} as Context, + callback, + ); + const error = new Error("Network response was not ok. Response was 401: Unauthorized"); + expect(errorSpy).toHaveBeenCalledWith("Error performing post auth:", error); + expect(errorSpy).toBeCalledTimes(1); + expect(missingIdentity).toStrictEqual({ + request: { + userAttributes: TEST_IDM_USERS.testStateIDMUser, + }, + }); + }); + it("should return the user and update the user in the service", async () => { + const consoleSpy = vi.spyOn(console, "log"); + const validUser = await handler( + { + request: { + userAttributes: TEST_IDM_USERS.testStateIDMUserGood, + }, + userName: superUser.Username, + userPoolId: USER_POOL_ID, + }, + {} as Context, + callback, + ); + expect(consoleSpy).toBeCalledWith( + `Attributes for user ${superUser.Username} updated successfully.`, + ); + expect(validUser).toStrictEqual({ + request: { + userAttributes: TEST_IDM_USERS.testStateIDMUserGood, + }, + userName: superUser.Username, + userPoolId: USER_POOL_ID, + }); + }); +}); diff --git a/lib/lambda/postAuth.ts b/lib/lambda/postAuth.ts index 433ac8e94c..f27c2bf882 100644 --- a/lib/lambda/postAuth.ts +++ b/lib/lambda/postAuth.ts @@ -8,17 +8,16 @@ import { import { getSecret } from "shared-utils"; // Initialize Cognito client -const client = new CognitoIdentityProviderClient({}); - +const client = new CognitoIdentityProviderClient({ + region: process.env.region || process.env.REGION_A || "us-east-1", +}); export const handler: Handler = async (event) => { - console.log(JSON.stringify(event, null, 2)); - // Check if idmInfoSecretArn is provided if (!process.env.idmAuthzApiKeyArn) { throw "ERROR: process.env.idmAuthzApiKeyArn is required"; } if (!process.env.idmAuthzApiEndpoint) { - throw "ERROR: process.env.idmAuthzApiKeyArn is required"; + throw "ERROR: process.env.idmAuthzApiEndpoint is required"; } const apiEndpoint: string = process.env.idmAuthzApiEndpoint; @@ -32,7 +31,6 @@ export const handler: Handler = async (event) => { const { request } = event; const { userAttributes } = request; - if (!userAttributes.identities) { console.log("User is not managed externally. Nothing to do."); } else { @@ -40,18 +38,14 @@ export const handler: Handler = async (event) => { try { const username = userAttributes["custom:username"]; // This is the four-letter IDM username - const response = await fetch( - `${apiEndpoint}/api/v1/authz/id/all?userId=${username}`, - { - method: "GET", - headers: { - "Content-Type": "application/json", - "x-api-key": apiKey, - }, + const response = await fetch(`${apiEndpoint}/api/v1/authz/id/all?userId=${username}`, { + method: "GET", + headers: { + "Content-Type": "application/json", + "x-api-key": apiKey, }, - ); + }); if (!response.ok) { - console.log(response); throw new Error( `Network response was not ok. Response was ${response.status}: ${response.statusText}`, ); @@ -108,22 +102,14 @@ async function updateUserAttributes(params: any): Promise { const user = await client.send(getUserCommand); // Check for existing "custom:cms-roles" - const cmsRolesAttribute = user.UserAttributes?.find( - (attr) => attr.Name === "custom:cms-roles", - ); + const cmsRolesAttribute = user.UserAttributes?.find((attr) => attr.Name === "custom:cms-roles"); const existingRoles = - cmsRolesAttribute && cmsRolesAttribute.Value - ? cmsRolesAttribute.Value.split(",") - : []; + cmsRolesAttribute && cmsRolesAttribute.Value ? cmsRolesAttribute.Value.split(",") : []; // Check for existing "custom:state" - const stateAttribute = user.UserAttributes?.find( - (attr) => attr.Name === "custom:state", - ); + const stateAttribute = user.UserAttributes?.find((attr) => attr.Name === "custom:state"); const existingStates = - stateAttribute && stateAttribute.Value - ? stateAttribute.Value.split(",") - : []; + stateAttribute && stateAttribute.Value ? stateAttribute.Value.split(",") : []; // Prepare for updating user attributes const attributeData: any = { @@ -146,8 +132,7 @@ async function updateUserAttributes(params: any): Promise { ), ) : new Set(["onemac-micro-super"]); // Ensure "onemac-micro-super" is always included - attributeData.UserAttributes[rolesIndex].Value = - Array.from(newRoles).join(","); + attributeData.UserAttributes[rolesIndex].Value = Array.from(newRoles).join(","); } else { // Add "custom:cms-roles" with "onemac-micro-super" attributeData.UserAttributes.push({ @@ -165,14 +150,9 @@ async function updateUserAttributes(params: any): Promise { if (stateIndex !== -1) { // Only merge if new states are not empty const newStates = attributeData.UserAttributes[stateIndex].Value - ? new Set( - attributeData.UserAttributes[stateIndex].Value.split(",").concat( - "ZZ", - ), - ) + ? new Set(attributeData.UserAttributes[stateIndex].Value.split(",").concat("ZZ")) : new Set(["ZZ"]); // Ensure "ZZ" is always included - attributeData.UserAttributes[stateIndex].Value = - Array.from(newStates).join(","); + attributeData.UserAttributes[stateIndex].Value = Array.from(newStates).join(","); } else { // Add "custom:state" with "ZZ" attributeData.UserAttributes.push({ diff --git a/lib/lambda/processEmails.ts b/lib/lambda/processEmails.ts index 2b4d22e372..0d62cd5e05 100644 --- a/lib/lambda/processEmails.ts +++ b/lib/lambda/processEmails.ts @@ -154,7 +154,10 @@ export function validateEmailTemplate(template: any) { } export async function processAndSendEmails(record: any, id: string, config: ProcessEmailConfig) { - const templates = await getEmailTemplates(record.event, record.authority); + const templates = await getEmailTemplates( + record.event, + record.authority.toLowerCase(), + ); if (!templates) { console.log( diff --git a/lib/lambda/processEmailsHandler.test.ts b/lib/lambda/processEmailsHandler.test.ts new file mode 100644 index 0000000000..91017c9649 --- /dev/null +++ b/lib/lambda/processEmailsHandler.test.ts @@ -0,0 +1,134 @@ +import { describe, it, expect, vi } from "vitest"; +import { Context } from "aws-lambda"; +import { SESClient } from "@aws-sdk/client-ses"; +import { handler } from "./processEmails"; +import { KafkaRecord, KafkaEvent } from "shared-types"; +import { Authority } from "shared-types"; + +const nms = "new-medicaid-submission"; +const ncs = "new-chip-submission"; +const tempExtension = "temp-extension"; +const withdrawPackage = "withdraw-package"; +const contractingInitial = "contracting-initial"; +const capitatedInitial = "capitated-initial"; + +describe("process emails Handler", () => { + it.each([ + [`should send an email for ${nms} with ${Authority.MED_SPA}`, Authority.MED_SPA, nms], + [`should send an email for ${nms} with ${Authority.CHIP_SPA}`, Authority.CHIP_SPA, nms], + [`should send an email for ${nms} with ${Authority["1915b"]}`, Authority["1915b"], nms], + [`should send an email for ${nms} with ${Authority["1915c"]}`, Authority["1915c"], nms], + [`should send an email for ${ncs} with ${Authority.MED_SPA}`, Authority.MED_SPA, ncs], + [`should send an email for ${ncs} with ${Authority.CHIP_SPA}`, Authority.CHIP_SPA, ncs], + [`should send an email for ${ncs} with ${Authority["1915b"]}`, Authority["1915b"], ncs], + [`should send an email for ${ncs} with ${Authority["1915c"]}`, Authority["1915c"], ncs], + [ + `should send an email for ${tempExtension} with ${Authority.MED_SPA}`, + Authority.MED_SPA, + tempExtension, + ], + [ + `should send an email for ${tempExtension} with ${Authority.CHIP_SPA}`, + Authority.CHIP_SPA, + tempExtension, + ], + [ + `should send an email for ${tempExtension} with ${Authority["1915b"]}`, + Authority["1915b"], + tempExtension, + ], + [ + `should send an email for ${tempExtension} with ${Authority["1915c"]}`, + Authority["1915c"], + tempExtension, + ], + [ + `should send an email for ${withdrawPackage} with ${Authority.MED_SPA}`, + Authority.MED_SPA, + withdrawPackage, + ], + [ + `should send an email for ${withdrawPackage} with ${Authority.CHIP_SPA}`, + Authority.CHIP_SPA, + withdrawPackage, + ], + [ + `should send an email for ${withdrawPackage} for ${ncs} with ${Authority["1915b"]}`, + Authority["1915b"], + withdrawPackage, + ], + [ + `should send an email for ${withdrawPackage} with ${Authority["1915c"]}`, + Authority["1915c"], + withdrawPackage, + ], + [ + `should send an email for ${contractingInitial} with ${Authority.MED_SPA}`, + Authority.MED_SPA, + contractingInitial, + ], + [ + `should send an email for ${contractingInitial} with ${Authority.CHIP_SPA}`, + Authority.CHIP_SPA, + contractingInitial, + ], + [ + `should send an email for ${contractingInitial} with ${Authority["1915b"]}`, + Authority["1915b"], + contractingInitial, + ], + [ + `should send an email for ${contractingInitial} with ${Authority["1915c"]}`, + Authority["1915c"], + contractingInitial, + ], + [ + `should send an email for ${capitatedInitial} with ${Authority.MED_SPA}`, + Authority.MED_SPA, + capitatedInitial, + ], + [ + `should send an email for ${capitatedInitial} with ${Authority.CHIP_SPA}`, + Authority.CHIP_SPA, + capitatedInitial, + ], + [ + `should send an email for ${capitatedInitial} with ${Authority["1915b"]}`, + Authority["1915b"], + capitatedInitial, + ], + [ + `should send an email for ${capitatedInitial} with ${Authority["1915c"]}`, + Authority["1915c"], + capitatedInitial, + ], + ])("%s", async (_, auth, eventType) => { + const callback = vi.fn(); + const secSPY = vi.spyOn(SESClient.prototype, "send"); + const mockEvent: KafkaEvent = { + records: { + "mock-topic": [ + { + key: Buffer.from("VA").toString("base64"), + value: Buffer.from( + JSON.stringify({ + origin: "mako", + event: eventType, + authority: auth, + }), + ).toString("base64"), + headers: {}, + timestamp: 1732645041557, + offset: "0", + partition: 0, + topic: "mock-topic", + } as unknown as KafkaRecord, + ], + }, + eventSource: "", + bootstrapServers: "", + }; + await handler(mockEvent, {} as Context, callback); + expect(secSPY).toHaveBeenCalledTimes(2); + }); +}); diff --git a/lib/lambda/sinkChangelog.test.ts b/lib/lambda/sinkChangelog.test.ts index 0135b18dfb..4813300a62 100644 --- a/lib/lambda/sinkChangelog.test.ts +++ b/lib/lambda/sinkChangelog.test.ts @@ -31,7 +31,7 @@ import { } from "mocks/data/submit/changelog"; const OPENSEARCH_INDEX = `${OPENSEARCH_INDEX_NAMESPACE}changelog`; -const TOPIC = "aws.onemac.migration.cdc"; +const TOPIC = "--mako--branch-name--aws.onemac.migration.cdc"; const TEST_ITEM = items[TEST_ITEM_ID]; const TEST_ITEM_KEY = Buffer.from(TEST_ITEM_ID).toString("base64"); const TEST_ITEM_UPDATE_ID = "MD-0005.R01.01"; @@ -160,9 +160,9 @@ describe("syncing Changelog events", () => { it("should handle a valid admin id update", async () => { const event = createKafkaEvent({ - [`${TOPIC}-02`]: [ + [`${TOPIC}-03`]: [ createKafkaRecord({ - topic: `${TOPIC}-01`, + topic: `${TOPIC}-03`, key: TEST_ITEM_UPDATE_KEY, value: convertObjToBase64({ id: TEST_ITEM_UPDATE_ID, @@ -196,9 +196,9 @@ describe("syncing Changelog events", () => { it("should handle a valid admin value update", async () => { const event = createKafkaEvent({ - [`${TOPIC}-02`]: [ + [`${TOPIC}-03`]: [ createKafkaRecord({ - topic: `${TOPIC}-02`, + topic: `${TOPIC}-03`, key: TEST_ITEM_KEY, value: convertObjToBase64({ id: TEST_ITEM_ID, @@ -237,9 +237,9 @@ describe("syncing Changelog events", () => { it("should handle a valid admin value and id update", async () => { const event = createKafkaEvent({ - [`${TOPIC}-02`]: [ + [`${TOPIC}-03`]: [ createKafkaRecord({ - topic: `${TOPIC}-02`, + topic: `${TOPIC}-03`, key: TEST_ITEM_KEY, value: convertObjToBase64({ id: TEST_ITEM_ID, @@ -254,7 +254,7 @@ describe("syncing Changelog events", () => { offset: 3, }), createKafkaRecord({ - topic: `${TOPIC}-02`, + topic: `${TOPIC}-03`, key: TEST_ITEM_UPDATE_KEY, value: convertObjToBase64({ id: TEST_ITEM_UPDATE_ID, @@ -348,9 +348,9 @@ describe("syncing Changelog events", () => { it("should handle a valid admin delete", async () => { const event = createKafkaEvent({ - [`${TOPIC}-02`]: [ + [`${TOPIC}-03`]: [ createKafkaRecord({ - topic: `${TOPIC}-02`, + topic: `${TOPIC}-03`, key: TEST_ITEM_KEY, value: convertObjToBase64({ id: TEST_ITEM_ID, @@ -484,9 +484,9 @@ describe("syncing Changelog events", () => { it("should skip invalid admin id update", async () => { const event = createKafkaEvent({ - [`${TOPIC}-02`]: [ + [`${TOPIC}-03`]: [ createKafkaRecord({ - topic: `${TOPIC}-02`, + topic: `${TOPIC}-03`, key: TEST_ITEM_UPDATE_KEY, value: convertObjToBase64({ id: TEST_ITEM_UPDATE_ID, diff --git a/lib/lambda/sinkCpocs.test.ts b/lib/lambda/sinkCpocs.test.ts index b2ad02db9e..f03453de09 100644 --- a/lib/lambda/sinkCpocs.test.ts +++ b/lib/lambda/sinkCpocs.test.ts @@ -1,55 +1,224 @@ -import { describe, expect, it, vi } from "vitest"; -import { handler as sinkCpocLamda } from "./sinkCpocs"; -import * as sinkLib from "../libs/sink-lib"; -import { ErrorType } from "../libs/sink-lib"; - -// key: base64EncodedString and when decoded is a string based id of a record -// value: base64EncodedString and when decoded is a json string with the entire record - -// const kafkaRecord: KafkaRecord = { -// topic: "testprefix--aws.seatool.debezium.cdc.SEA.dbo.Officers-xyz", -// headers: {}, -// key: Buffer.from("OH-0001.R00.00").toString("base64"), -// value: Buffer.from(JSON.stringify({})).toString("base64"), -// offset: 1, -// partition: 1, -// timestamp: new Date().getTime(), -// timestampType: "", -// }; - -// export function getTopic(topicPartition: string) { -// return topicPartition.split("--").pop()?.split("-").slice(0, -1)[0]; -// } -vi.stubEnv("osDomain", "testDomain"); - -describe("test sink cpoc", () => { - it("calls log error when topic is undefined", async () => { - const logErrorSpy = vi - .spyOn(sinkLib, "logError") - .mockImplementation(({ type }: { type: ErrorType }) => { - console.log({ type }); - }); - try { - await sinkCpocLamda( - { - bootstrapServers: "123", - eventSource: "", - records: { - bad: [], - }, - }, - {} as any, +import { describe, expect, it, vi, afterEach } from "vitest"; +import { handler } from "./sinkCpocs"; +import { Context } from "aws-lambda"; +import * as os from "libs/opensearch-lib"; +import * as sink from "../libs/sink-lib"; +import { + convertObjToBase64, + createKafkaEvent, + createKafkaRecord, + OPENSEARCH_DOMAIN, + OPENSEARCH_INDEX_NAMESPACE, +} from "mocks"; +import cpocs, { MUHAMMAD_BASHAR_ID } from "mocks/data/cpocs"; + +const OPENSEARCH_INDEX = `${OPENSEARCH_INDEX_NAMESPACE}cpocs`; +const TOPIC = "--mako--branch-name--aws.seatool.debezium.cdc.SEA.dbo.Officers"; +const MUHAMMAD_BASHAR_KEY = Buffer.from(`${MUHAMMAD_BASHAR_ID}`).toString("base64"); +const MUHAMMAD_BASHAR = cpocs[MUHAMMAD_BASHAR_ID]; + +describe("test sync cpoc", () => { + const bulkUpdateDataSpy = vi.spyOn(os, "bulkUpdateData"); + const logErrorSpy = vi.spyOn(sink, "logError"); + + afterEach(() => { + vi.clearAllMocks(); + }); + + it("should throw an error if the topic is undefined", async () => { + await expect(() => + handler( + createKafkaEvent({ + undefined: [], + }), + {} as Context, + vi.fn(), + ), + ).rejects.toThrowError("topic (undefined) is invalid"); + + expect(logErrorSpy).toHaveBeenCalledWith({ type: sink.ErrorType.BADTOPIC }); + expect(logErrorSpy).toHaveBeenCalledWith( + expect.objectContaining({ + type: sink.ErrorType.UNKNOWN, + }), + ); + }); + + it("should throw an error if the topic is invalid", async () => { + await expect(() => + handler( + createKafkaEvent({ + "invalid-topic": [], + }), + {} as Context, vi.fn(), - ); - } catch { - expect(logErrorSpy).toHaveBeenCalledWith({ type: ErrorType.BADTOPIC }); - } - expect(logErrorSpy).toHaveBeenLastCalledWith( - expect.objectContaining({ type: ErrorType.UNKNOWN }), + ), + ).rejects.toThrowError("topic (invalid-topic) is invalid"); + + expect(logErrorSpy).toHaveBeenCalledWith({ type: sink.ErrorType.BADTOPIC }); + expect(logErrorSpy).toHaveBeenCalledWith( + expect.objectContaining({ + type: sink.ErrorType.UNKNOWN, + }), + ); + }); + + it("should skip if the key is invalid", async () => { + await handler( + createKafkaEvent({ + [`${TOPIC}-xyz`]: [ + createKafkaRecord({ + topic: `${TOPIC}-xyz`, + // @ts-expect-error need key undefined for test + key: undefined, + value: convertObjToBase64({ + id: MUHAMMAD_BASHAR_ID, + }), + }), + ], + }), + {} as Context, + vi.fn(), + ); + + expect(bulkUpdateDataSpy).toHaveBeenCalledWith(OPENSEARCH_DOMAIN, OPENSEARCH_INDEX, []); + expect(logErrorSpy).toHaveBeenCalledWith( + expect.objectContaining({ + type: sink.ErrorType.BADPARSE, + }), + ); + }); + + it("should skip if record has no value", async () => { + await handler( + createKafkaEvent({ + [`${TOPIC}-xyz`]: [ + createKafkaRecord({ + topic: `${TOPIC}-xyz`, + key: MUHAMMAD_BASHAR_KEY, + // @ts-expect-error needs to be undefined for the test + value: undefined, + }), + ], + }), + {} as Context, + vi.fn(), + ); + + expect(bulkUpdateDataSpy).toHaveBeenCalledWith(OPENSEARCH_DOMAIN, OPENSEARCH_INDEX, []); + expect(logErrorSpy).not.toHaveBeenCalled(); + }); + + it("should skip if there is no payload", async () => { + await handler( + createKafkaEvent({ + [`${TOPIC}-xyz`]: [ + createKafkaRecord({ + topic: `${TOPIC}-xyz`, + key: MUHAMMAD_BASHAR_KEY, + value: convertObjToBase64({ + id: MUHAMMAD_BASHAR_KEY, + }), + }), + ], + }), + {} as Context, + vi.fn(), + ); + + expect(bulkUpdateDataSpy).toHaveBeenCalledWith(OPENSEARCH_DOMAIN, OPENSEARCH_INDEX, []); + expect(logErrorSpy).toHaveBeenCalledWith( + expect.objectContaining({ + type: sink.ErrorType.BADPARSE, + }), + ); + }); + + it("should skip if there is no record", async () => { + await handler( + createKafkaEvent({ + [`${TOPIC}-xyz`]: [ + createKafkaRecord({ + topic: `${TOPIC}-xyz`, + key: MUHAMMAD_BASHAR_KEY, + value: convertObjToBase64({ + payload: { + after: undefined, + }, + }), + }), + ], + }), + {} as Context, + vi.fn(), ); + + expect(bulkUpdateDataSpy).toHaveBeenCalledWith(OPENSEARCH_DOMAIN, OPENSEARCH_INDEX, [ + { + id: `${MUHAMMAD_BASHAR_ID}`, + delete: true, + }, + ]); + expect(logErrorSpy).not.toHaveBeenCalled(); }); - it("has an empty array set in docs when given one undefined value", () => { - // spy on the bulkDataUpdateWrapper to determine if this test is true + it("should handle an invalid record", async () => { + await handler( + createKafkaEvent({ + [`${TOPIC}-xyz`]: [ + createKafkaRecord({ + topic: `${TOPIC}-xyz`, + key: MUHAMMAD_BASHAR_KEY, + value: convertObjToBase64({ + payload: { + after: { + Officer_ID: MUHAMMAD_BASHAR_ID, + }, + }, + }), + }), + ], + }), + {} as Context, + vi.fn(), + ); + + expect(bulkUpdateDataSpy).toHaveBeenCalledWith(OPENSEARCH_DOMAIN, OPENSEARCH_INDEX, []); + expect(logErrorSpy).toHaveBeenCalledWith( + expect.objectContaining({ + type: sink.ErrorType.VALIDATION, + }), + ); + }); + + it("should handle a valid record", async () => { + await handler( + createKafkaEvent({ + [`${TOPIC}-xyz`]: [ + createKafkaRecord({ + topic: `${TOPIC}-xyz`, + key: MUHAMMAD_BASHAR_KEY, + value: convertObjToBase64({ + payload: { + after: { + Officer_ID: MUHAMMAD_BASHAR_ID, + First_Name: MUHAMMAD_BASHAR._source?.firstName, + Last_Name: MUHAMMAD_BASHAR._source?.lastName, + Email: MUHAMMAD_BASHAR._source?.email, + }, + }, + }), + }), + ], + }), + {} as Context, + vi.fn(), + ); + + expect(bulkUpdateDataSpy).toHaveBeenCalledWith(OPENSEARCH_DOMAIN, OPENSEARCH_INDEX, [ + { + ...MUHAMMAD_BASHAR._source, + }, + ]); }); }); diff --git a/lib/lambda/sinkMainProcessors.test.ts b/lib/lambda/sinkMainProcessors.test.ts index 2f0dae2530..c4b05ab5a9 100644 --- a/lib/lambda/sinkMainProcessors.test.ts +++ b/lib/lambda/sinkMainProcessors.test.ts @@ -68,7 +68,7 @@ describe("insertOneMacRecordsFromKafkaIntoMako", () => { [ "app-k", appkBase, - SEATOOL_STATUS.PENDING, + SEATOOL_STATUS.SUBMITTED, { title: appkBase.title, proposedDate: appkBase.proposedEffectiveDate, @@ -80,7 +80,7 @@ describe("insertOneMacRecordsFromKafkaIntoMako", () => { [ "capitated-initial", capitatedInitial, - SEATOOL_STATUS.PENDING, + SEATOOL_STATUS.SUBMITTED, { proposedDate: capitatedInitial.proposedEffectiveDate, additionalInformation: capitatedInitial.additionalInformation, @@ -91,7 +91,7 @@ describe("insertOneMacRecordsFromKafkaIntoMako", () => { [ "capitated-amendment", capitatedAmendmentBase, - SEATOOL_STATUS.PENDING, + SEATOOL_STATUS.SUBMITTED, { proposedDate: capitatedAmendmentBase.proposedEffectiveDate, additionalInformation: capitatedAmendmentBase.additionalInformation, @@ -102,7 +102,7 @@ describe("insertOneMacRecordsFromKafkaIntoMako", () => { [ "capitated-renewal", capitatedRenewal, - SEATOOL_STATUS.PENDING, + SEATOOL_STATUS.SUBMITTED, { proposedDate: capitatedRenewal.proposedEffectiveDate, additionalInformation: capitatedRenewal.additionalInformation, @@ -113,7 +113,7 @@ describe("insertOneMacRecordsFromKafkaIntoMako", () => { [ "contracting-initial", contractingInitial, - SEATOOL_STATUS.PENDING, + SEATOOL_STATUS.SUBMITTED, { proposedDate: contractingInitial.proposedEffectiveDate, additionalInformation: contractingInitial.additionalInformation, @@ -124,7 +124,7 @@ describe("insertOneMacRecordsFromKafkaIntoMako", () => { [ "contracting-amendment", contractingAmendment, - SEATOOL_STATUS.PENDING, + SEATOOL_STATUS.SUBMITTED, { proposedDate: contractingAmendment.proposedEffectiveDate, additionalInformation: contractingAmendment.additionalInformation, @@ -135,7 +135,7 @@ describe("insertOneMacRecordsFromKafkaIntoMako", () => { [ "contracting-renewal", contractingRenewal, - SEATOOL_STATUS.PENDING, + SEATOOL_STATUS.SUBMITTED, { proposedDate: contractingRenewal.proposedEffectiveDate, additionalInformation: contractingRenewal.additionalInformation, @@ -146,7 +146,7 @@ describe("insertOneMacRecordsFromKafkaIntoMako", () => { [ "new-chip-submission", newChipSubmission, - SEATOOL_STATUS.PENDING, + SEATOOL_STATUS.SUBMITTED, { proposedDate: newChipSubmission.proposedEffectiveDate, additionalInformation: newChipSubmission.additionalInformation, @@ -157,7 +157,7 @@ describe("insertOneMacRecordsFromKafkaIntoMako", () => { [ "new-medicaid-submission", newMedicaidSubmission, - SEATOOL_STATUS.PENDING, + SEATOOL_STATUS.SUBMITTED, { proposedDate: newMedicaidSubmission.proposedEffectiveDate, additionalInformation: newMedicaidSubmission.additionalInformation, @@ -226,9 +226,10 @@ describe("insertOneMacRecordsFromKafkaIntoMako", () => { { raiReceivedDate: ISO_DATETIME, raiWithdrawEnabled: false, - seatoolStatus: SEATOOL_STATUS.PENDING_RAI, - cmsStatus: statusToDisplayToCmsUser[SEATOOL_STATUS.PENDING_RAI], - stateStatus: statusToDisplayToStateUser[SEATOOL_STATUS.PENDING_RAI], + seatoolStatus: SEATOOL_STATUS.SUBMITTED, + cmsStatus: statusToDisplayToCmsUser[SEATOOL_STATUS.SUBMITTED], + stateStatus: statusToDisplayToStateUser[SEATOOL_STATUS.SUBMITTED], + initialIntakeNeeded: true, locked: true, }, ], @@ -236,9 +237,10 @@ describe("insertOneMacRecordsFromKafkaIntoMako", () => { "withdraw-rai", withdrawRai, { - seatoolStatus: SEATOOL_STATUS.PENDING_RAI, - cmsStatus: statusToDisplayToCmsUser[SEATOOL_STATUS.PENDING_RAI], - stateStatus: statusToDisplayToStateUser[SEATOOL_STATUS.PENDING_RAI], + seatoolStatus: SEATOOL_STATUS.RAI_RESPONSE_WITHDRAW_REQUESTED, + cmsStatus: statusToDisplayToCmsUser[SEATOOL_STATUS.RAI_RESPONSE_WITHDRAW_REQUESTED], + stateStatus: statusToDisplayToStateUser[SEATOOL_STATUS.RAI_RESPONSE_WITHDRAW_REQUESTED], + secondClock: false, raiWithdrawEnabled: false, locked: true, }, @@ -254,12 +256,12 @@ describe("insertOneMacRecordsFromKafkaIntoMako", () => { "withdraw-package", withdrawPackage, { - seatoolStatus: SEATOOL_STATUS.WITHDRAWN, - cmsStatus: statusToDisplayToCmsUser[SEATOOL_STATUS.WITHDRAWN], - stateStatus: statusToDisplayToStateUser[SEATOOL_STATUS.WITHDRAWN], + seatoolStatus: SEATOOL_STATUS.WITHDRAW_REQUESTED, + cmsStatus: statusToDisplayToCmsUser[SEATOOL_STATUS.WITHDRAW_REQUESTED], + stateStatus: statusToDisplayToStateUser[SEATOOL_STATUS.WITHDRAW_REQUESTED], locked: true, - finalDispositionDate: ISO_DATETIME, - initialIntakeNeeded: false, + secondClock: false, + initialIntakeNeeded: true, raiWithdrawEnabled: false, }, ], diff --git a/lib/lambda/sinkSubtypes.test.ts b/lib/lambda/sinkSubtypes.test.ts new file mode 100644 index 0000000000..cb950e65dd --- /dev/null +++ b/lib/lambda/sinkSubtypes.test.ts @@ -0,0 +1,200 @@ +import { describe, expect, it, vi, afterEach } from "vitest"; +import { handler } from "./sinkSubtypes"; +import { Context } from "aws-lambda"; +import * as os from "libs/opensearch-lib"; +import * as sink from "../libs/sink-lib"; +import { + convertObjToBase64, + createKafkaEvent, + createKafkaRecord, + OPENSEARCH_DOMAIN, + OPENSEARCH_INDEX_NAMESPACE, +} from "mocks"; +import { subtypes } from "mocks/data/types"; + +const OPENSEARCH_INDEX = `${OPENSEARCH_INDEX_NAMESPACE}subtypes`; +const TEST_SUBTYPE = subtypes[0]; +const TEST_SUBTYPE_ID = TEST_SUBTYPE._source.id; +const TEST_SUBTYPE_KEY = Buffer.from(`${TEST_SUBTYPE_ID}`).toString("base64"); +const TOPIC = `--mako--branch-name--aws.seatool.debezium.cdc.SEA.dbo.Type-${TEST_SUBTYPE_ID}`; + +describe("test sync subtypes", () => { + const bulkUpdateDataSpy = vi.spyOn(os, "bulkUpdateData"); + const logErrorSpy = vi.spyOn(sink, "logError"); + + afterEach(() => { + vi.clearAllMocks(); + }); + + it("should throw an error if the topic is undefined", async () => { + await expect(() => + handler( + createKafkaEvent({ + undefined: [], + }), + {} as Context, + vi.fn(), + ), + ).rejects.toThrowError("topic (undefined) is invalid"); + + expect(logErrorSpy).toHaveBeenCalledWith({ type: sink.ErrorType.BADTOPIC }); + expect(logErrorSpy).toHaveBeenCalledWith( + expect.objectContaining({ + type: sink.ErrorType.UNKNOWN, + }), + ); + }); + + it("should throw an error if the topic is invalid", async () => { + await expect(() => + handler( + createKafkaEvent({ + "invalid-topic": [], + }), + {} as Context, + vi.fn(), + ), + ).rejects.toThrowError("topic (invalid-topic) is invalid"); + + expect(logErrorSpy).toHaveBeenCalledWith({ type: sink.ErrorType.BADTOPIC }); + expect(logErrorSpy).toHaveBeenCalledWith( + expect.objectContaining({ + type: sink.ErrorType.UNKNOWN, + }), + ); + }); + + it("should skip if the record has no value", async () => { + await handler( + createKafkaEvent({ + [TOPIC]: [ + createKafkaRecord({ + topic: TOPIC, + key: TEST_SUBTYPE_KEY, + // @ts-expect-error needs to be undefined for test + value: undefined, + }), + ], + }), + {} as Context, + vi.fn(), + ); + + expect(bulkUpdateDataSpy).toHaveBeenCalledWith(OPENSEARCH_DOMAIN, OPENSEARCH_INDEX, []); + expect(logErrorSpy).toHaveBeenCalledWith( + expect.objectContaining({ + type: sink.ErrorType.BADPARSE, + }), + ); + }); + + it("should skip if there is no payload", async () => { + await handler( + createKafkaEvent({ + [TOPIC]: [ + createKafkaRecord({ + topic: TOPIC, + key: TEST_SUBTYPE_KEY, + value: convertObjToBase64({ + id: TEST_SUBTYPE._source.id, + }), + }), + ], + }), + {} as Context, + vi.fn(), + ); + + expect(bulkUpdateDataSpy).toHaveBeenCalledWith(OPENSEARCH_DOMAIN, OPENSEARCH_INDEX, []); + expect(logErrorSpy).toHaveBeenCalledWith( + expect.objectContaining({ + type: sink.ErrorType.BADPARSE, + }), + ); + }); + + it("should skip if there is no record", async () => { + await handler( + createKafkaEvent({ + [TOPIC]: [ + createKafkaRecord({ + topic: TOPIC, + key: TEST_SUBTYPE_KEY, + value: convertObjToBase64({ + payload: { + after: undefined, + }, + }), + }), + ], + }), + {} as Context, + vi.fn(), + ); + + expect(bulkUpdateDataSpy).toHaveBeenCalledWith(OPENSEARCH_DOMAIN, OPENSEARCH_INDEX, []); + expect(logErrorSpy).not.toHaveBeenCalled(); + }); + + it("should handle an invalid record", async () => { + await handler( + createKafkaEvent({ + [TOPIC]: [ + createKafkaRecord({ + topic: TOPIC, + key: TEST_SUBTYPE_KEY, + value: convertObjToBase64({ + payload: { + after: { + Type_Id: TEST_SUBTYPE._source.id, + }, + }, + }), + }), + ], + }), + {} as Context, + vi.fn(), + ); + + expect(bulkUpdateDataSpy).toHaveBeenCalledWith(OPENSEARCH_DOMAIN, OPENSEARCH_INDEX, []); + expect(logErrorSpy).toHaveBeenCalledWith( + expect.objectContaining({ + type: sink.ErrorType.VALIDATION, + }), + ); + }); + + it("should handle a valid record", async () => { + const { id, typeId, name, authorityId } = TEST_SUBTYPE._source; + await handler( + createKafkaEvent({ + [TOPIC]: [ + createKafkaRecord({ + topic: TOPIC, + key: TEST_SUBTYPE_KEY, + value: convertObjToBase64({ + payload: { + after: { + Type_Id: id, + Type_Name: name, + Type_Class: typeId, + Plan_Type_ID: authorityId, + }, + }, + }), + }), + ], + }), + {} as Context, + vi.fn(), + ); + + expect(bulkUpdateDataSpy).toHaveBeenCalledWith(OPENSEARCH_DOMAIN, OPENSEARCH_INDEX, [ + { + ...TEST_SUBTYPE._source, + }, + ]); + expect(logErrorSpy).not.toHaveBeenCalled(); + }); +}); diff --git a/lib/lambda/sinkSubtypes.ts b/lib/lambda/sinkSubtypes.ts index ed460ec4f4..d6139c26be 100644 --- a/lib/lambda/sinkSubtypes.ts +++ b/lib/lambda/sinkSubtypes.ts @@ -10,12 +10,12 @@ export const handler: Handler = async (event) => { for (const topicPartition of Object.keys(event.records)) { const topic = getTopic(topicPartition); switch (topic) { - case undefined: - logError({ type: ErrorType.BADTOPIC }); - throw new Error(); case "aws.seatool.debezium.cdc.SEA.dbo.Type": await subtypes(event.records[topicPartition], topicPartition); break; + default: + logError({ type: ErrorType.BADTOPIC }); + throw new Error(`topic (${topicPartition}) is invalid`); } } } catch (error) { diff --git a/lib/lambda/sinkTypes.test.ts b/lib/lambda/sinkTypes.test.ts new file mode 100644 index 0000000000..116efb5a49 --- /dev/null +++ b/lib/lambda/sinkTypes.test.ts @@ -0,0 +1,199 @@ +import { describe, expect, it, vi, afterEach } from "vitest"; +import { handler } from "./sinkTypes"; +import { Context } from "aws-lambda"; +import * as os from "libs/opensearch-lib"; +import * as sink from "../libs/sink-lib"; +import { + convertObjToBase64, + createKafkaEvent, + createKafkaRecord, + OPENSEARCH_DOMAIN, + OPENSEARCH_INDEX_NAMESPACE, +} from "mocks"; +import { types } from "mocks/data/types"; + +const OPENSEARCH_INDEX = `${OPENSEARCH_INDEX_NAMESPACE}types`; +const TEST_TYPE = types[0]; +const TEST_TYPE_ID = TEST_TYPE._source.id; +const TEST_TYPE_KEY = Buffer.from(`${TEST_TYPE_ID}`).toString("base64"); +const TOPIC = `--mako--branch-name--aws.seatool.debezium.cdc.SEA.dbo.SPA_Type-${TEST_TYPE_ID}`; + +describe("test sync types", () => { + const bulkUpdateDataSpy = vi.spyOn(os, "bulkUpdateData"); + const logErrorSpy = vi.spyOn(sink, "logError"); + + afterEach(() => { + vi.clearAllMocks(); + }); + + it("should throw an error if the topic is undefined", async () => { + await expect(() => + handler( + createKafkaEvent({ + undefined: [], + }), + {} as Context, + vi.fn(), + ), + ).rejects.toThrowError("topic (undefined) is invalid"); + + expect(logErrorSpy).toHaveBeenCalledWith({ type: sink.ErrorType.BADTOPIC }); + expect(logErrorSpy).toHaveBeenCalledWith( + expect.objectContaining({ + type: sink.ErrorType.UNKNOWN, + }), + ); + }); + + it("should throw an error if the topic is invalid", async () => { + await expect(() => + handler( + createKafkaEvent({ + "invalid-topic": [], + }), + {} as Context, + vi.fn(), + ), + ).rejects.toThrowError("topic (invalid-topic) is invalid"); + + expect(logErrorSpy).toHaveBeenCalledWith({ type: sink.ErrorType.BADTOPIC }); + expect(logErrorSpy).toHaveBeenCalledWith( + expect.objectContaining({ + type: sink.ErrorType.UNKNOWN, + }), + ); + }); + + it("should skip if the record has no value", async () => { + await handler( + createKafkaEvent({ + [TOPIC]: [ + createKafkaRecord({ + topic: TOPIC, + key: TEST_TYPE_KEY, + // @ts-expect-error needs to be undefined for test + value: undefined, + }), + ], + }), + {} as Context, + vi.fn(), + ); + + expect(bulkUpdateDataSpy).toHaveBeenCalledWith(OPENSEARCH_DOMAIN, OPENSEARCH_INDEX, []); + expect(logErrorSpy).toHaveBeenCalledWith( + expect.objectContaining({ + type: sink.ErrorType.BADPARSE, + }), + ); + }); + + it("should skip if there is no payload", async () => { + await handler( + createKafkaEvent({ + [TOPIC]: [ + createKafkaRecord({ + topic: TOPIC, + key: TEST_TYPE_KEY, + value: convertObjToBase64({ + id: TEST_TYPE._source.id, + }), + }), + ], + }), + {} as Context, + vi.fn(), + ); + + expect(bulkUpdateDataSpy).toHaveBeenCalledWith(OPENSEARCH_DOMAIN, OPENSEARCH_INDEX, []); + expect(logErrorSpy).toHaveBeenCalledWith( + expect.objectContaining({ + type: sink.ErrorType.BADPARSE, + }), + ); + }); + + it("should skip if there is no record", async () => { + await handler( + createKafkaEvent({ + [TOPIC]: [ + createKafkaRecord({ + topic: TOPIC, + key: TEST_TYPE_KEY, + value: convertObjToBase64({ + payload: { + after: undefined, + }, + }), + }), + ], + }), + {} as Context, + vi.fn(), + ); + + expect(bulkUpdateDataSpy).toHaveBeenCalledWith(OPENSEARCH_DOMAIN, OPENSEARCH_INDEX, []); + expect(logErrorSpy).not.toHaveBeenCalled(); + }); + + it("should handle an invalid record", async () => { + await handler( + createKafkaEvent({ + [TOPIC]: [ + createKafkaRecord({ + topic: TOPIC, + key: TEST_TYPE_KEY, + value: convertObjToBase64({ + payload: { + after: { + SPA_Type_ID: TEST_TYPE._source.id, + }, + }, + }), + }), + ], + }), + {} as Context, + vi.fn(), + ); + + expect(bulkUpdateDataSpy).toHaveBeenCalledWith(OPENSEARCH_DOMAIN, OPENSEARCH_INDEX, []); + expect(logErrorSpy).toHaveBeenCalledWith( + expect.objectContaining({ + type: sink.ErrorType.VALIDATION, + }), + ); + }); + + it("should handle a valid record", async () => { + const { id, name, authorityId } = TEST_TYPE._source; + await handler( + createKafkaEvent({ + [TOPIC]: [ + createKafkaRecord({ + topic: TOPIC, + key: TEST_TYPE_KEY, + value: convertObjToBase64({ + payload: { + after: { + SPA_Type_ID: id, + SPA_Type_Name: name, + Plan_Type_ID: authorityId, + }, + }, + }), + }), + ], + }), + {} as Context, + vi.fn(), + ); + + expect(bulkUpdateDataSpy).toHaveBeenCalledWith(OPENSEARCH_DOMAIN, OPENSEARCH_INDEX, [ + { + ...TEST_TYPE._source, + }, + ]); + expect(logErrorSpy).not.toHaveBeenCalled(); + }); +}); diff --git a/lib/lambda/sinkTypes.ts b/lib/lambda/sinkTypes.ts index 922bb476b8..d6b5cce5f0 100644 --- a/lib/lambda/sinkTypes.ts +++ b/lib/lambda/sinkTypes.ts @@ -10,12 +10,12 @@ export const handler: Handler = async (event) => { for (const topicPartition of Object.keys(event.records)) { const topic = getTopic(topicPartition); switch (topic) { - case undefined: - logError({ type: ErrorType.BADTOPIC }); - throw new Error(); case "aws.seatool.debezium.cdc.SEA.dbo.SPA_Type": await types(event.records[topicPartition], topicPartition); break; + default: + logError({ type: ErrorType.BADTOPIC }); + throw new Error(`topic (${topicPartition}) is invalid`); } } } catch (error) { diff --git a/lib/lambda/submit/index.test.ts b/lib/lambda/submit/index.test.ts index 405fbd8499..293265b87c 100644 --- a/lib/lambda/submit/index.test.ts +++ b/lib/lambda/submit/index.test.ts @@ -1,18 +1,18 @@ import { describe, it, expect } from "vitest"; import { submit } from "./index"; import { APIGatewayEvent } from "node_modules/shared-types"; -import { getRequestContext } from "mocks"; -import { events } from "mocks/data/submit/base"; +import { getRequestContext, NOT_FOUND_ITEM_ID } from "mocks"; +import { events, uploadSubsequentDocuments } from "mocks/data/submit/base"; describe("submit Lambda function", () => { - it("should have no body", async () => { + it("should handle a submission with no body", async () => { const event = {} as APIGatewayEvent; const result = await submit(event); expect(result.statusCode).toEqual(400); expect(result.body).toEqual('"Event body required"'); }); - it("should have no event in the body", async () => { + it("should handle a submission with no event in the body", async () => { const event = { body: `{"event": ""}`, } as unknown as APIGatewayEvent; @@ -21,7 +21,7 @@ describe("submit Lambda function", () => { expect(result.body).toEqual('{"message":"Bad Request - Missing event name in body"}'); }); - it("should have a bad event in the body", async () => { + it("should handle a submission with a bad event in the body", async () => { const event = { body: `{"event": "Not a real event"}`, } as unknown as APIGatewayEvent; @@ -30,6 +30,21 @@ describe("submit Lambda function", () => { expect(result.body).toEqual('{"message":"Bad Request - Unknown event type Not a real event"}'); }); + it("should handle an upload-subsequent-document with an invalid item ID", async () => { + const event = { + body: JSON.stringify({ + ...uploadSubsequentDocuments, + id: NOT_FOUND_ITEM_ID, + waiverNumber: NOT_FOUND_ITEM_ID, + }), + requestContext: getRequestContext(), + } as unknown as APIGatewayEvent; + const result = await submit(event); + + expect(result.statusCode).toEqual(500); + expect(result.body).toEqual('{"message":"Internal server error"}'); + }); + describe("successfully submit event types", () => { it.each(events.map((event) => [event.event, JSON.stringify(event)]))( "should successfully submit %s event", diff --git a/lib/lambda/submit/index.ts b/lib/lambda/submit/index.ts index e93023e4a5..3b6975845c 100644 --- a/lib/lambda/submit/index.ts +++ b/lib/lambda/submit/index.ts @@ -33,11 +33,7 @@ export const submit = async (event: APIGatewayEvent) => { try { const eventBody = await submissionPayloads[body.event](event); - await produceMessage( - process.env.topicName as string, - body.id, - JSON.stringify(eventBody), - ); + await produceMessage(process.env.topicName as string, body.id, JSON.stringify(eventBody)); return response({ statusCode: 200, diff --git a/lib/lambda/submit/submissionPayloads/app-k.ts b/lib/lambda/submit/submissionPayloads/app-k.ts index 3253d27ee8..ab36f31841 100644 --- a/lib/lambda/submit/submissionPayloads/app-k.ts +++ b/lib/lambda/submit/submissionPayloads/app-k.ts @@ -1,18 +1,12 @@ import { events } from "shared-types/events"; -import { - isAuthorized, - getAuthDetails, - lookupUserAttributes, -} from "libs/api/auth/user"; +import { isAuthorized, getAuthDetails, lookupUserAttributes } from "libs/api/auth/user"; import { type APIGatewayEvent } from "aws-lambda"; import { itemExists } from "libs/api/package"; export const appK = async (event: APIGatewayEvent) => { if (!event.body) return; - const parsedResult = events["app-k"].baseSchema.safeParse( - JSON.parse(event.body), - ); + const parsedResult = events["app-k"].baseSchema.safeParse(JSON.parse(event.body)); if (!parsedResult.success) { throw parsedResult.error; } @@ -28,10 +22,7 @@ export const appK = async (event: APIGatewayEvent) => { } const authDetails = getAuthDetails(event); - const userAttr = await lookupUserAttributes( - authDetails.userId, - authDetails.poolId, - ); + const userAttr = await lookupUserAttributes(authDetails.userId, authDetails.poolId); const submitterEmail = userAttr.email; const submitterName = `${userAttr.given_name} ${userAttr.family_name}`; diff --git a/lib/lambda/submit/submissionPayloads/capitated-initial.ts b/lib/lambda/submit/submissionPayloads/capitated-initial.ts index 4cecba5a28..7debb8cebd 100644 --- a/lib/lambda/submit/submissionPayloads/capitated-initial.ts +++ b/lib/lambda/submit/submissionPayloads/capitated-initial.ts @@ -1,18 +1,12 @@ import { events } from "shared-types/events"; -import { - isAuthorized, - getAuthDetails, - lookupUserAttributes, -} from "../../../libs/api/auth/user"; +import { isAuthorized, getAuthDetails, lookupUserAttributes } from "../../../libs/api/auth/user"; import { type APIGatewayEvent } from "aws-lambda"; import { itemExists } from "libs/api/package"; export const capitatedInitial = async (event: APIGatewayEvent) => { if (!event.body) return; - const parsedResult = events["capitated-initial"].baseSchema.safeParse( - JSON.parse(event.body), - ); + const parsedResult = events["capitated-initial"].baseSchema.safeParse(JSON.parse(event.body)); if (!parsedResult.success) { throw parsedResult.error; } @@ -28,10 +22,7 @@ export const capitatedInitial = async (event: APIGatewayEvent) => { } const authDetails = getAuthDetails(event); - const userAttr = await lookupUserAttributes( - authDetails.userId, - authDetails.poolId, - ); + const userAttr = await lookupUserAttributes(authDetails.userId, authDetails.poolId); const submitterEmail = userAttr.email; const submitterName = `${userAttr.given_name} ${userAttr.family_name}`; diff --git a/lib/lambda/submit/submissionPayloads/capitated-renewal.ts b/lib/lambda/submit/submissionPayloads/capitated-renewal.ts index 6d89027c15..f5aa4bc5dc 100644 --- a/lib/lambda/submit/submissionPayloads/capitated-renewal.ts +++ b/lib/lambda/submit/submissionPayloads/capitated-renewal.ts @@ -1,20 +1,14 @@ // can/should add the additional frontend checks here import { events } from "shared-types/events"; -import { - isAuthorized, - getAuthDetails, - lookupUserAttributes, -} from "../../../libs/api/auth/user"; +import { isAuthorized, getAuthDetails, lookupUserAttributes } from "../../../libs/api/auth/user"; import { type APIGatewayEvent } from "aws-lambda"; import { itemExists } from "libs/api/package"; export const capitatedRenewal = async (event: APIGatewayEvent) => { if (!event.body) return; - const parsedResult = events["capitated-renewal"].baseSchema.safeParse( - JSON.parse(event.body), - ); + const parsedResult = events["capitated-renewal"].baseSchema.safeParse(JSON.parse(event.body)); if (!parsedResult.success) { throw parsedResult.error; } @@ -30,10 +24,7 @@ export const capitatedRenewal = async (event: APIGatewayEvent) => { } const authDetails = getAuthDetails(event); - const userAttr = await lookupUserAttributes( - authDetails.userId, - authDetails.poolId, - ); + const userAttr = await lookupUserAttributes(authDetails.userId, authDetails.poolId); const submitterEmail = userAttr.email; const submitterName = `${userAttr.given_name} ${userAttr.family_name}`; diff --git a/lib/lambda/submit/submissionPayloads/contracting-amendment.ts b/lib/lambda/submit/submissionPayloads/contracting-amendment.ts index f9eb70e633..3167db306d 100644 --- a/lib/lambda/submit/submissionPayloads/contracting-amendment.ts +++ b/lib/lambda/submit/submissionPayloads/contracting-amendment.ts @@ -1,20 +1,14 @@ // can/should add the additional frontend checks here import { events } from "shared-types/events"; -import { - isAuthorized, - getAuthDetails, - lookupUserAttributes, -} from "../../../libs/api/auth/user"; +import { isAuthorized, getAuthDetails, lookupUserAttributes } from "../../../libs/api/auth/user"; import { type APIGatewayEvent } from "aws-lambda"; import { itemExists } from "libs/api/package"; export const contractingAmendment = async (event: APIGatewayEvent) => { if (!event.body) return; - const parsedResult = events["contracting-amendment"].baseSchema.safeParse( - JSON.parse(event.body), - ); + const parsedResult = events["contracting-amendment"].baseSchema.safeParse(JSON.parse(event.body)); if (!parsedResult.success) { throw parsedResult.error; } @@ -30,10 +24,7 @@ export const contractingAmendment = async (event: APIGatewayEvent) => { } const authDetails = getAuthDetails(event); - const userAttr = await lookupUserAttributes( - authDetails.userId, - authDetails.poolId, - ); + const userAttr = await lookupUserAttributes(authDetails.userId, authDetails.poolId); const submitterEmail = userAttr.email; const submitterName = `${userAttr.given_name} ${userAttr.family_name}`; diff --git a/lib/lambda/submit/submissionPayloads/contracting-initial.ts b/lib/lambda/submit/submissionPayloads/contracting-initial.ts index a05a29422b..3c2ef84dce 100644 --- a/lib/lambda/submit/submissionPayloads/contracting-initial.ts +++ b/lib/lambda/submit/submissionPayloads/contracting-initial.ts @@ -1,18 +1,12 @@ import { events } from "shared-types/events"; -import { - isAuthorized, - getAuthDetails, - lookupUserAttributes, -} from "../../../libs/api/auth/user"; +import { isAuthorized, getAuthDetails, lookupUserAttributes } from "../../../libs/api/auth/user"; import { type APIGatewayEvent } from "aws-lambda"; import { itemExists } from "libs/api/package"; export const contractingInitial = async (event: APIGatewayEvent) => { if (!event.body) return; - const parsedResult = events["contracting-initial"].baseSchema.safeParse( - JSON.parse(event.body), - ); + const parsedResult = events["contracting-initial"].baseSchema.safeParse(JSON.parse(event.body)); if (!parsedResult.success) { throw parsedResult.error; } @@ -28,10 +22,7 @@ export const contractingInitial = async (event: APIGatewayEvent) => { } const authDetails = getAuthDetails(event); - const userAttr = await lookupUserAttributes( - authDetails.userId, - authDetails.poolId, - ); + const userAttr = await lookupUserAttributes(authDetails.userId, authDetails.poolId); const submitterEmail = userAttr.email; const submitterName = `${userAttr.given_name} ${userAttr.family_name}`; diff --git a/lib/lambda/submit/submissionPayloads/contracting-renewal.ts b/lib/lambda/submit/submissionPayloads/contracting-renewal.ts index bb1f60cff0..6adb5d2535 100644 --- a/lib/lambda/submit/submissionPayloads/contracting-renewal.ts +++ b/lib/lambda/submit/submissionPayloads/contracting-renewal.ts @@ -1,20 +1,14 @@ // can/should add the additional frontend checks here import { events } from "shared-types/events"; -import { - isAuthorized, - getAuthDetails, - lookupUserAttributes, -} from "../../../libs/api/auth/user"; +import { isAuthorized, getAuthDetails, lookupUserAttributes } from "../../../libs/api/auth/user"; import { type APIGatewayEvent } from "aws-lambda"; import { itemExists } from "libs/api/package"; export const contractingRenewal = async (event: APIGatewayEvent) => { if (!event.body) return; - const parsedResult = events["contracting-renewal"].baseSchema.safeParse( - JSON.parse(event.body), - ); + const parsedResult = events["contracting-renewal"].baseSchema.safeParse(JSON.parse(event.body)); if (!parsedResult.success) { throw parsedResult.error; } @@ -30,10 +24,7 @@ export const contractingRenewal = async (event: APIGatewayEvent) => { } const authDetails = getAuthDetails(event); - const userAttr = await lookupUserAttributes( - authDetails.userId, - authDetails.poolId, - ); + const userAttr = await lookupUserAttributes(authDetails.userId, authDetails.poolId); const submitterEmail = userAttr.email; const submitterName = `${userAttr.given_name} ${userAttr.family_name}`; diff --git a/lib/lambda/submit/submissionPayloads/new-chip-submission.ts b/lib/lambda/submit/submissionPayloads/new-chip-submission.ts index b79cf7bbd0..822f58a695 100644 --- a/lib/lambda/submit/submissionPayloads/new-chip-submission.ts +++ b/lib/lambda/submit/submissionPayloads/new-chip-submission.ts @@ -1,18 +1,12 @@ import { events } from "shared-types/events"; -import { - isAuthorized, - getAuthDetails, - lookupUserAttributes, -} from "../../../libs/api/auth/user"; +import { isAuthorized, getAuthDetails, lookupUserAttributes } from "../../../libs/api/auth/user"; import { type APIGatewayEvent } from "aws-lambda"; import { itemExists } from "libs/api/package"; export const newChipSubmission = async (event: APIGatewayEvent) => { if (!event.body) return; - const parsedResult = events["new-chip-submission"].baseSchema.safeParse( - JSON.parse(event.body), - ); + const parsedResult = events["new-chip-submission"].baseSchema.safeParse(JSON.parse(event.body)); if (!parsedResult.success) { throw parsedResult.error; } @@ -28,10 +22,7 @@ export const newChipSubmission = async (event: APIGatewayEvent) => { } const authDetails = getAuthDetails(event); - const userAttr = await lookupUserAttributes( - authDetails.userId, - authDetails.poolId, - ); + const userAttr = await lookupUserAttributes(authDetails.userId, authDetails.poolId); const submitterEmail = userAttr.email; const submitterName = `${userAttr.given_name} ${userAttr.family_name}`; diff --git a/lib/lambda/submit/submissionPayloads/new-medicaid-submission.ts b/lib/lambda/submit/submissionPayloads/new-medicaid-submission.ts index 91ed571e7d..046916a656 100644 --- a/lib/lambda/submit/submissionPayloads/new-medicaid-submission.ts +++ b/lib/lambda/submit/submissionPayloads/new-medicaid-submission.ts @@ -1,9 +1,5 @@ import { events } from "shared-types/events"; -import { - isAuthorized, - getAuthDetails, - lookupUserAttributes, -} from "../../../libs/api/auth/user"; +import { isAuthorized, getAuthDetails, lookupUserAttributes } from "../../../libs/api/auth/user"; import { type APIGatewayEvent } from "aws-lambda"; import { itemExists } from "libs/api/package"; @@ -28,10 +24,7 @@ export const newMedicaidSubmission = async (event: APIGatewayEvent) => { } const authDetails = getAuthDetails(event); - const userAttr = await lookupUserAttributes( - authDetails.userId, - authDetails.poolId, - ); + const userAttr = await lookupUserAttributes(authDetails.userId, authDetails.poolId); const submitterEmail = userAttr.email; const submitterName = `${userAttr.given_name} ${userAttr.family_name}`; diff --git a/lib/lambda/submit/submissionPayloads/temporary-extension.ts b/lib/lambda/submit/submissionPayloads/temporary-extension.ts index 9b8ca9919c..87f3dba1de 100644 --- a/lib/lambda/submit/submissionPayloads/temporary-extension.ts +++ b/lib/lambda/submit/submissionPayloads/temporary-extension.ts @@ -1,20 +1,14 @@ // can/should add the additional frontend checks here import { events } from "shared-types/events"; -import { - isAuthorized, - getAuthDetails, - lookupUserAttributes, -} from "../../../libs/api/auth/user"; +import { isAuthorized, getAuthDetails, lookupUserAttributes } from "../../../libs/api/auth/user"; import { type APIGatewayEvent } from "aws-lambda"; import { itemExists } from "libs/api/package"; export const temporaryExtension = async (event: APIGatewayEvent) => { if (!event.body) return; - const parsedResult = events["temporary-extension"].baseSchema.safeParse( - JSON.parse(event.body), - ); + const parsedResult = events["temporary-extension"].baseSchema.safeParse(JSON.parse(event.body)); if (!parsedResult.success) { throw parsedResult.error; } @@ -34,10 +28,7 @@ export const temporaryExtension = async (event: APIGatewayEvent) => { } const authDetails = getAuthDetails(event); - const userAttr = await lookupUserAttributes( - authDetails.userId, - authDetails.poolId, - ); + const userAttr = await lookupUserAttributes(authDetails.userId, authDetails.poolId); const submitterEmail = userAttr.email; const submitterName = `${userAttr.given_name} ${userAttr.family_name}`; diff --git a/lib/lambda/submit/submissionPayloads/toggle-withdraw-rai.ts b/lib/lambda/submit/submissionPayloads/toggle-withdraw-rai.ts index 49b5a82552..b98c5a5e85 100644 --- a/lib/lambda/submit/submissionPayloads/toggle-withdraw-rai.ts +++ b/lib/lambda/submit/submissionPayloads/toggle-withdraw-rai.ts @@ -1,18 +1,12 @@ import { events } from "shared-types/events"; -import { - isAuthorized, - getAuthDetails, - lookupUserAttributes, -} from "../../../libs/api/auth/user"; +import { isAuthorized, getAuthDetails, lookupUserAttributes } from "../../../libs/api/auth/user"; import { type APIGatewayEvent } from "aws-lambda"; import { itemExists } from "libs/api/package"; export const toggleWithdrawRai = async (event: APIGatewayEvent) => { if (!event.body) return; - const parsedResult = events["toggle-withdraw-rai"].baseSchema.safeParse( - JSON.parse(event.body), - ); + const parsedResult = events["toggle-withdraw-rai"].baseSchema.safeParse(JSON.parse(event.body)); if (!parsedResult.success) { throw parsedResult.error; @@ -28,10 +22,7 @@ export const toggleWithdrawRai = async (event: APIGatewayEvent) => { } const authDetails = getAuthDetails(event); - const userAttr = await lookupUserAttributes( - authDetails.userId, - authDetails.poolId, - ); + const userAttr = await lookupUserAttributes(authDetails.userId, authDetails.poolId); const submitterEmail = userAttr.email; const submitterName = `${userAttr.given_name} ${userAttr.family_name}`; diff --git a/lib/lambda/submit/submissionPayloads/withdraw-rai.ts b/lib/lambda/submit/submissionPayloads/withdraw-rai.ts index 1aee37305f..cf28796321 100644 --- a/lib/lambda/submit/submissionPayloads/withdraw-rai.ts +++ b/lib/lambda/submit/submissionPayloads/withdraw-rai.ts @@ -1,18 +1,12 @@ import { events } from "shared-types/events"; -import { - isAuthorized, - getAuthDetails, - lookupUserAttributes, -} from "../../../libs/api/auth/user"; +import { isAuthorized, getAuthDetails, lookupUserAttributes } from "../../../libs/api/auth/user"; import { type APIGatewayEvent } from "aws-lambda"; import { itemExists } from "libs/api/package"; export const withdrawRai = async (event: APIGatewayEvent) => { if (!event.body) return; - const parsedResult = events["withdraw-rai"].baseSchema.safeParse( - JSON.parse(event.body), - ); + const parsedResult = events["withdraw-rai"].baseSchema.safeParse(JSON.parse(event.body)); if (!parsedResult.success) { throw parsedResult.error; @@ -28,10 +22,7 @@ export const withdrawRai = async (event: APIGatewayEvent) => { } const authDetails = getAuthDetails(event); - const userAttr = await lookupUserAttributes( - authDetails.userId, - authDetails.poolId, - ); + const userAttr = await lookupUserAttributes(authDetails.userId, authDetails.poolId); const submitterEmail = userAttr.email; const submitterName = `${userAttr.given_name} ${userAttr.family_name}`; diff --git a/lib/lambda/update/adminChangeSchemas.ts b/lib/lambda/update/adminChangeSchemas.ts index 274c8b4af0..4404d97749 100644 --- a/lib/lambda/update/adminChangeSchemas.ts +++ b/lib/lambda/update/adminChangeSchemas.ts @@ -47,4 +47,4 @@ export const transformedUpdateIdSchema = updateIdAdminChangeSchema.transform((da packageId: data.id, id: `${data.id}`, timestamp: Date.now(), -})); \ No newline at end of file +})); diff --git a/lib/libs/api/kafka.ts b/lib/libs/api/kafka.ts index 8d92a814f1..1885a291ba 100644 --- a/lib/libs/api/kafka.ts +++ b/lib/libs/api/kafka.ts @@ -19,11 +19,7 @@ export function getProducer() { return kafka.producer(); } -export async function produceMessage( - topic: string, - key: string, - value: string, -) { +export async function produceMessage(topic: string, key: string, value: string) { producer = producer || getProducer(); await producer.connect(); @@ -35,11 +31,7 @@ export async function produceMessage( }; console.log( "About to send the following message to kafka\n" + - JSON.stringify( - { ...message, value: JSON.parse(message.value as string) }, - null, - 2, - ), + JSON.stringify({ ...message, value: JSON.parse(message.value as string) }, null, 2), ); try { await producer.send({ diff --git a/lib/libs/api/statusMemo.ts b/lib/libs/api/statusMemo.ts index ce050dfefe..73f5fcdc1b 100644 --- a/lib/libs/api/statusMemo.ts +++ b/lib/libs/api/statusMemo.ts @@ -1,7 +1,7 @@ export function buildStatusMemoQuery( id: string, msg: string, - operation: "insert" | "update" = "update" + operation: "insert" | "update" = "update", ) { const printable = new Date().toLocaleString("en-US", { timeZone: "America/New_York", diff --git a/lib/libs/email/content/index.ts b/lib/libs/email/content/index.ts index 7ae4b2c128..2b3e35790c 100644 --- a/lib/libs/email/content/index.ts +++ b/lib/libs/email/content/index.ts @@ -1,8 +1,8 @@ -export * from "./new-submission"; +export * from "./newSubmission"; export * from "./tempExtension"; -export * from "./respondToRai"; export * from "./withdrawRai"; export * from "./withdrawPackage"; +export * from "./withdrawConfirmation"; export * from "./email-components"; export * from "./respondToRai"; -export * from "./upload-subsequent-documents"; +export * from "./uploadSubsequentDocuments"; diff --git a/lib/libs/email/content/new-submission/emailTemplates/AppKCMS.tsx b/lib/libs/email/content/newSubmission/emailTemplates/AppKCMS.tsx similarity index 100% rename from lib/libs/email/content/new-submission/emailTemplates/AppKCMS.tsx rename to lib/libs/email/content/newSubmission/emailTemplates/AppKCMS.tsx diff --git a/lib/libs/email/content/new-submission/emailTemplates/AppKState.tsx b/lib/libs/email/content/newSubmission/emailTemplates/AppKState.tsx similarity index 100% rename from lib/libs/email/content/new-submission/emailTemplates/AppKState.tsx rename to lib/libs/email/content/newSubmission/emailTemplates/AppKState.tsx diff --git a/lib/libs/email/content/new-submission/emailTemplates/ChipSpaCMS.tsx b/lib/libs/email/content/newSubmission/emailTemplates/ChipSpaCMS.tsx similarity index 93% rename from lib/libs/email/content/new-submission/emailTemplates/ChipSpaCMS.tsx rename to lib/libs/email/content/newSubmission/emailTemplates/ChipSpaCMS.tsx index d6ec0a379d..a4d9c67679 100644 --- a/lib/libs/email/content/new-submission/emailTemplates/ChipSpaCMS.tsx +++ b/lib/libs/email/content/newSubmission/emailTemplates/ChipSpaCMS.tsx @@ -7,10 +7,11 @@ import { } from "../../email-components"; import { BaseEmailTemplate } from "../../email-templates"; -export const ChipSpaCMSEmail = (props: { +export const ChipSpaCMSEmail = ({ + variables, +}: { variables: Events["NewChipSubmission"] & CommonEmailVariables; }) => { - const variables = props.variables; const previewText = `CHIP SPA ${variables.id} Submitted`; const heading = "The OneMAC Submission Portal received a CHIP State Plan Amendment:"; return ( diff --git a/lib/libs/email/content/new-submission/emailTemplates/ChipSpaState.tsx b/lib/libs/email/content/newSubmission/emailTemplates/ChipSpaState.tsx similarity index 100% rename from lib/libs/email/content/new-submission/emailTemplates/ChipSpaState.tsx rename to lib/libs/email/content/newSubmission/emailTemplates/ChipSpaState.tsx diff --git a/lib/libs/email/content/new-submission/emailTemplates/MedSpaCMS.tsx b/lib/libs/email/content/newSubmission/emailTemplates/MedSpaCMS.tsx similarity index 100% rename from lib/libs/email/content/new-submission/emailTemplates/MedSpaCMS.tsx rename to lib/libs/email/content/newSubmission/emailTemplates/MedSpaCMS.tsx diff --git a/lib/libs/email/content/new-submission/emailTemplates/MedSpaState.tsx b/lib/libs/email/content/newSubmission/emailTemplates/MedSpaState.tsx similarity index 100% rename from lib/libs/email/content/new-submission/emailTemplates/MedSpaState.tsx rename to lib/libs/email/content/newSubmission/emailTemplates/MedSpaState.tsx diff --git a/lib/libs/email/content/new-submission/emailTemplates/Waiver1915bCMS.tsx b/lib/libs/email/content/newSubmission/emailTemplates/Waiver1915bCMS.tsx similarity index 100% rename from lib/libs/email/content/new-submission/emailTemplates/Waiver1915bCMS.tsx rename to lib/libs/email/content/newSubmission/emailTemplates/Waiver1915bCMS.tsx diff --git a/lib/libs/email/content/new-submission/emailTemplates/Waiver1915bState.tsx b/lib/libs/email/content/newSubmission/emailTemplates/Waiver1915bState.tsx similarity index 100% rename from lib/libs/email/content/new-submission/emailTemplates/Waiver1915bState.tsx rename to lib/libs/email/content/newSubmission/emailTemplates/Waiver1915bState.tsx diff --git a/lib/libs/email/content/new-submission/emailTemplates/index.tsx b/lib/libs/email/content/newSubmission/emailTemplates/index.tsx similarity index 100% rename from lib/libs/email/content/new-submission/emailTemplates/index.tsx rename to lib/libs/email/content/newSubmission/emailTemplates/index.tsx diff --git a/lib/libs/email/content/new-submission/index.tsx b/lib/libs/email/content/newSubmission/index.tsx similarity index 95% rename from lib/libs/email/content/new-submission/index.tsx rename to lib/libs/email/content/newSubmission/index.tsx index b915675978..a7a967f2f3 100644 --- a/lib/libs/email/content/new-submission/index.tsx +++ b/lib/libs/email/content/newSubmission/index.tsx @@ -1,5 +1,4 @@ import { Events, Authority, EmailAddresses, CommonEmailVariables } from "shared-types"; -import { formatActionType } from "shared-utils"; import { AuthoritiesWithUserTypesTemplate } from "../.."; import { MedSpaCMSEmail, @@ -78,9 +77,7 @@ export const newSubmission: AuthoritiesWithUserTypesTemplate = { ) => { return { to: [`${variables.submitterName} <${variables.submitterEmail}>`], - subject: `Your ${formatActionType(variables.actionType)} ${ - variables.id - } has been submitted to CMS`, + subject: `Your ${variables.authority} ${variables.id} has been submitted to CMS`, body: await render(), }; }, diff --git a/lib/libs/email/content/upload-subsequent-documents/emailTemplates/AppKCMS.tsx b/lib/libs/email/content/uploadSubsequentDocuments/emailTemplates/AppKCMS.tsx similarity index 100% rename from lib/libs/email/content/upload-subsequent-documents/emailTemplates/AppKCMS.tsx rename to lib/libs/email/content/uploadSubsequentDocuments/emailTemplates/AppKCMS.tsx diff --git a/lib/libs/email/content/upload-subsequent-documents/emailTemplates/AppKState.tsx b/lib/libs/email/content/uploadSubsequentDocuments/emailTemplates/AppKState.tsx similarity index 100% rename from lib/libs/email/content/upload-subsequent-documents/emailTemplates/AppKState.tsx rename to lib/libs/email/content/uploadSubsequentDocuments/emailTemplates/AppKState.tsx diff --git a/lib/libs/email/content/upload-subsequent-documents/emailTemplates/ChipSpaCMS.tsx b/lib/libs/email/content/uploadSubsequentDocuments/emailTemplates/ChipSpaCMS.tsx similarity index 100% rename from lib/libs/email/content/upload-subsequent-documents/emailTemplates/ChipSpaCMS.tsx rename to lib/libs/email/content/uploadSubsequentDocuments/emailTemplates/ChipSpaCMS.tsx diff --git a/lib/libs/email/content/upload-subsequent-documents/emailTemplates/ChipSpaState.tsx b/lib/libs/email/content/uploadSubsequentDocuments/emailTemplates/ChipSpaState.tsx similarity index 100% rename from lib/libs/email/content/upload-subsequent-documents/emailTemplates/ChipSpaState.tsx rename to lib/libs/email/content/uploadSubsequentDocuments/emailTemplates/ChipSpaState.tsx diff --git a/lib/libs/email/content/upload-subsequent-documents/emailTemplates/MedSpaCMS.tsx b/lib/libs/email/content/uploadSubsequentDocuments/emailTemplates/MedSpaCMS.tsx similarity index 92% rename from lib/libs/email/content/upload-subsequent-documents/emailTemplates/MedSpaCMS.tsx rename to lib/libs/email/content/uploadSubsequentDocuments/emailTemplates/MedSpaCMS.tsx index 873c4c9acb..f606bdcf5a 100644 --- a/lib/libs/email/content/upload-subsequent-documents/emailTemplates/MedSpaCMS.tsx +++ b/lib/libs/email/content/uploadSubsequentDocuments/emailTemplates/MedSpaCMS.tsx @@ -7,11 +7,11 @@ import { } from "../../email-components"; import { BaseEmailTemplate } from "../../email-templates"; -export const MedSpaCMSEmail = (props: { +export const MedSpaCMSEmail = ({ + variables, +}: { variables: Events["UploadSubsequentDocuments"] & CommonEmailVariables; }) => { - const variables = props.variables; - return ( { +export const AppKCMSEmail = ({ + variables, + relatedEvent, +}: { + variables: Events["WithdrawRai"] & CommonEmailVariables & { emails: EmailAddresses }; + relatedEvent: Events["RespondToRai"]; +}) => { const previewText = `Withdraw Formal RAI Response for Waiver Package ${relatedEvent.id}`; - const heading = `Withdraw Formal RAI Response for Waiver Package ${relatedEvent.id}`; - + const heading = `The OneMAC Submission Portal received a request to withdraw the Formal RAI Response. You are receiving this email notification as the Formal RAI for ${relatedEvent.id} was withdrawn by ${variables.submitterName} ${variables.submitterEmail}.`; return ( { applicationEndpointUrl={variables.applicationEndpointUrl} footerContent={} > - { - const { variables, relatedEvent } = { ...props }; +export const AppKStateEmail = ({ + variables, + relatedEvent, +}: { + variables: Events["WithdrawRai"] & CommonEmailVariables & { emails: EmailAddresses }; + relatedEvent: Events["RespondToRai"]; +}) => { const previewText = `Withdraw Formal RAI Response for Waiver Package ${relatedEvent.id}`; const heading = `The OneMAC Submission Portal received a request to withdraw the Formal RAI Response. You are receiving this email notification as the Formal RAI for ${relatedEvent.id} was withdrawn by ${variables.submitterName} ${variables.submitterEmail}.`; return ( @@ -23,10 +28,10 @@ export const AppKStateEmail = (props: WithdrawRAIProps) => { diff --git a/lib/libs/email/content/withdrawRai/emailTemplates/Waiver1915bCMS.tsx b/lib/libs/email/content/withdrawRai/emailTemplates/Waiver1915bCMS.tsx index 10464ab011..18e049e21b 100644 --- a/lib/libs/email/content/withdrawRai/emailTemplates/Waiver1915bCMS.tsx +++ b/lib/libs/email/content/withdrawRai/emailTemplates/Waiver1915bCMS.tsx @@ -1,7 +1,14 @@ -import { WithdrawRAI, PackageDetails, BasicFooter, WithdrawRAIProps } from "../../email-components"; +import { CommonEmailVariables, Events, EmailAddresses } from "shared-types"; +import { WithdrawRAI, PackageDetails, BasicFooter } from "../../email-components"; import { BaseEmailTemplate } from "../../email-templates"; -export const Waiver1915bCMSEmail = ({ variables, relatedEvent }: WithdrawRAIProps) => { +export const Waiver1915bCMSEmail = ({ + variables, + relatedEvent, +}: { + variables: Events["WithdrawRai"] & CommonEmailVariables & { emails: EmailAddresses }; + relatedEvent: Events["RespondToRai"]; +}) => { const previewText = `Waiver Package ${relatedEvent.id} withdrawn`; const heading = `Withdraw Formal RAI Response for Waiver Package ${relatedEvent.id}`; diff --git a/lib/libs/email/content/withdrawRai/emailTemplates/Waiver1915bState.tsx b/lib/libs/email/content/withdrawRai/emailTemplates/Waiver1915bState.tsx index 00c9d80614..d2f41403c4 100644 --- a/lib/libs/email/content/withdrawRai/emailTemplates/Waiver1915bState.tsx +++ b/lib/libs/email/content/withdrawRai/emailTemplates/Waiver1915bState.tsx @@ -1,30 +1,31 @@ -import { - WithdrawRAI, - PackageDetails, - FollowUpNotice, - MailboxNotice, - WithdrawRAIProps, -} from "../../email-components"; +import { CommonEmailVariables, EmailAddresses, Events } from "shared-types"; +import { WithdrawRAI, PackageDetails, FollowUpNotice, MailboxNotice } from "../../email-components"; import { BaseEmailTemplate } from "../../email-templates"; -export const Waiver1915bStateEmail = (props: WithdrawRAIProps) => { - const previewText = `Waiver ${props.relatedEvent.id} Withdrawn`; +export const Waiver1915bStateEmail = ({ + variables, + relatedEvent, +}: { + variables: Events["WithdrawRai"] & CommonEmailVariables & { emails: EmailAddresses }; + relatedEvent: Events["RespondToRai"]; +}) => { + const previewText = `Waiver ${relatedEvent.id} Withdrawn`; const heading = "This response confirms you have withdrawn a Waiver from CMS for review"; return ( } > - + diff --git a/lib/libs/email/content/withdrawRai/emailTemplates/index.tsx b/lib/libs/email/content/withdrawRai/emailTemplates/index.tsx index 6a9b3d4662..669a424035 100644 --- a/lib/libs/email/content/withdrawRai/emailTemplates/index.tsx +++ b/lib/libs/email/content/withdrawRai/emailTemplates/index.tsx @@ -1,4 +1,4 @@ -export { Waiver1915bCMSEmail } from "./Waiver1915bCMS"; -export { Waiver1915bStateEmail } from "./Waiver1915bState"; export { AppKCMSEmail } from "./AppKCMS"; export { AppKStateEmail } from "./AppKState"; +export { Waiver1915bCMSEmail } from "./Waiver1915bCMS"; +export { Waiver1915bStateEmail } from "./Waiver1915bState"; diff --git a/lib/libs/email/content/withdrawRai/index.tsx b/lib/libs/email/content/withdrawRai/index.tsx index eb7e6bc152..5dde78064f 100644 --- a/lib/libs/email/content/withdrawRai/index.tsx +++ b/lib/libs/email/content/withdrawRai/index.tsx @@ -2,7 +2,7 @@ import { CommonEmailVariables, EmailAddresses, Events, Authority } from "shared- import { AuthoritiesWithUserTypesTemplate, getLatestMatchingEvent } from "../.."; import { Waiver1915bCMSEmail, Waiver1915bStateEmail, AppKCMSEmail } from "./emailTemplates"; import { render } from "@react-email/render"; -import { EmailProcessingError } from "../../errors"; +import { EmailProcessingError } from "libs/email/errors"; const getWithdrawRaiEvent = async (id: string) => { const event = await getLatestMatchingEvent(id, "WithdrawRai"); @@ -20,7 +20,10 @@ export const withdrawRai: AuthoritiesWithUserTypesTemplate = { variables: Events["WithdrawRai"] & CommonEmailVariables & { emails: EmailAddresses }, ) => { try { - const relatedEvent = await getLatestMatchingEvent(variables.id, "RespondToRai"); + const relatedEvent = (await getLatestMatchingEvent( + variables.id, + "respond-to-rai", + )) as unknown as Events["RespondToRai"]; if (!relatedEvent) { throw new EmailProcessingError( `Failed to find original RAI response event for withdrawal (ID: ${variables.id})`, @@ -41,7 +44,7 @@ export const withdrawRai: AuthoritiesWithUserTypesTemplate = { ], subject: `Withdraw Formal RAI Response for Waiver Package ${variables.id}`, body: await render( - , + , ), }; } catch (error) { @@ -53,7 +56,10 @@ export const withdrawRai: AuthoritiesWithUserTypesTemplate = { variables: Events["WithdrawRai"] & CommonEmailVariables & { emails: EmailAddresses }, ) => { try { - const relatedEvent = await getWithdrawRaiEvent(variables.id); + const relatedEvent = (await getLatestMatchingEvent( + variables.id, + "respond-to-rai", + )) as unknown as Events["RespondToRai"]; if (!relatedEvent) { throw new EmailProcessingError( `Failed to find original RAI response event for withdrawal (ID: ${variables.id})`, @@ -69,7 +75,7 @@ export const withdrawRai: AuthoritiesWithUserTypesTemplate = { to: variables.allStateUsersEmails || [], subject: `Withdraw Formal RAI Response for Waiver Package ${variables.id}`, body: await render( - , + , ), }; } catch (error) { @@ -83,7 +89,10 @@ export const withdrawRai: AuthoritiesWithUserTypesTemplate = { variables: Events["WithdrawRai"] & CommonEmailVariables & { emails: EmailAddresses }, ) => { try { - const relatedEvent = await getWithdrawRaiEvent(variables.id); + const relatedEvent = (await getLatestMatchingEvent( + variables.id, + "respond-to-rai", + )) as unknown as Events["RespondToRai"]; if (!relatedEvent) { throw new EmailProcessingError( `Failed to find original RAI response event for withdrawal (ID: ${variables.id})`, @@ -103,9 +112,7 @@ export const withdrawRai: AuthoritiesWithUserTypesTemplate = { ...variables.emails.srtEmails, ], subject: `Withdraw Formal RAI Response for Waiver Package ${relatedEvent.id}`, - body: await render( - , - ), + body: await render(), }; } catch (error) { console.error(error); diff --git a/lib/libs/email/getAllStateUsers.ts b/lib/libs/email/getAllStateUsers.ts index e2b2572679..d0f7cf3bc9 100644 --- a/lib/libs/email/getAllStateUsers.ts +++ b/lib/libs/email/getAllStateUsers.ts @@ -37,10 +37,13 @@ export const getAllStateUsers = async ({ const stateAttribute = user.Attributes?.find((attr) => attr.Name === "custom:state"); return stateAttribute?.Value?.split(",").includes(state); }).map((user) => { - const attributes = user.Attributes?.reduce((acc, attr) => { - acc[attr.Name as any] = attr.Value; - return acc; - }, {} as Record); + const attributes = user.Attributes?.reduce( + (acc, attr) => { + acc[attr.Name as any] = attr.Value; + return acc; + }, + {} as Record, + ); return { firstName: attributes?.["given_name"], lastName: attributes?.["family_name"], diff --git a/lib/libs/email/index.ts b/lib/libs/email/index.ts index 27f9002b3d..da2eea2fff 100644 --- a/lib/libs/email/index.ts +++ b/lib/libs/email/index.ts @@ -101,7 +101,10 @@ export async function getEmailTemplates( } // I think this needs to be written to handle not finding any matching events and so forth -export async function getLatestMatchingEvent(id: string, actionType: string): Promise { +export async function getLatestMatchingEvent( + id: string, + actionType: string, +): Promise { try { const item = await getPackageChangelog(id); diff --git a/lib/libs/email/mock-data/withdraw-rai.ts b/lib/libs/email/mock-data/withdraw-rai.ts index fe6ee50a33..32b31b3801 100644 --- a/lib/libs/email/mock-data/withdraw-rai.ts +++ b/lib/libs/email/mock-data/withdraw-rai.ts @@ -16,7 +16,6 @@ export const emailTemplateValue: Omit ], label: "CMS Form 179", }, - }, additionalInformation: "This some additional information about the request to withdraw and what makes it important.", diff --git a/lib/libs/email/preview/Initial Submissions/CMS/CHIP_SPA.tsx b/lib/libs/email/preview/InitialSubmissions/CMS/CHIP_SPA.tsx similarity index 89% rename from lib/libs/email/preview/Initial Submissions/CMS/CHIP_SPA.tsx rename to lib/libs/email/preview/InitialSubmissions/CMS/CHIP_SPA.tsx index 82d19a4fe4..019ff3aa50 100644 --- a/lib/libs/email/preview/Initial Submissions/CMS/CHIP_SPA.tsx +++ b/lib/libs/email/preview/InitialSubmissions/CMS/CHIP_SPA.tsx @@ -1,4 +1,4 @@ -import { ChipSpaCMSEmail } from "libs/email/content/new-submission/emailTemplates/ChipSpaCMS"; +import { ChipSpaCMSEmail } from "libs/email/content/newSubmission/emailTemplates"; import { emailTemplateValue } from "libs/email/mock-data/new-submission"; import * as attachments from "libs/email/mock-data/attachments"; diff --git a/lib/libs/email/preview/Initial Submissions/CMS/InitialSubmissionCMS.test.tsx b/lib/libs/email/preview/InitialSubmissions/CMS/InitialSubmissionCMS.test.tsx similarity index 100% rename from lib/libs/email/preview/Initial Submissions/CMS/InitialSubmissionCMS.test.tsx rename to lib/libs/email/preview/InitialSubmissions/CMS/InitialSubmissionCMS.test.tsx diff --git a/lib/libs/email/preview/Initial Submissions/CMS/Medicaid_SPA.tsx b/lib/libs/email/preview/InitialSubmissions/CMS/Medicaid_SPA.tsx similarity index 90% rename from lib/libs/email/preview/Initial Submissions/CMS/Medicaid_SPA.tsx rename to lib/libs/email/preview/InitialSubmissions/CMS/Medicaid_SPA.tsx index b7e3c7340a..d177d47f83 100644 --- a/lib/libs/email/preview/Initial Submissions/CMS/Medicaid_SPA.tsx +++ b/lib/libs/email/preview/InitialSubmissions/CMS/Medicaid_SPA.tsx @@ -1,4 +1,4 @@ -import { MedSpaCMSEmail } from "../../../content/new-submission/emailTemplates/MedSpaCMS"; +import { MedSpaCMSEmail } from "../../../content/newSubmission/emailTemplates/MedSpaCMS"; import { emailTemplateValue } from "../../../mock-data/new-submission"; import * as attachments from "../../../mock-data/attachments"; diff --git a/lib/libs/email/preview/Initial Submissions/CMS/Temp_Extension.tsx b/lib/libs/email/preview/InitialSubmissions/CMS/Temp_Extension.tsx similarity index 100% rename from lib/libs/email/preview/Initial Submissions/CMS/Temp_Extension.tsx rename to lib/libs/email/preview/InitialSubmissions/CMS/Temp_Extension.tsx diff --git a/lib/libs/email/preview/Initial Submissions/CMS/Waiver_Capitated.tsx b/lib/libs/email/preview/InitialSubmissions/CMS/Waiver_Capitated.tsx similarity index 96% rename from lib/libs/email/preview/Initial Submissions/CMS/Waiver_Capitated.tsx rename to lib/libs/email/preview/InitialSubmissions/CMS/Waiver_Capitated.tsx index 941d7331e3..ac56fc751b 100644 --- a/lib/libs/email/preview/Initial Submissions/CMS/Waiver_Capitated.tsx +++ b/lib/libs/email/preview/InitialSubmissions/CMS/Waiver_Capitated.tsx @@ -1,5 +1,5 @@ -import { Waiver1915bCMSEmail } from "libs/email/content/new-submission/emailTemplates/Waiver1915bCMS"; -import { emailTemplateValue } from "../../../mock-data/new-submission"; +import { Waiver1915bCMSEmail } from "libs/email/content/newSubmission/emailTemplates"; +import { emailTemplateValue } from "libs/email/mock-data/new-submission"; export const Waiver1915bCMSCapitatedInitialEmailPreview = () => { return ( diff --git a/lib/libs/email/preview/Initial Submissions/CMS/Waiver_Contracting.tsx b/lib/libs/email/preview/InitialSubmissions/CMS/Waiver_Contracting.tsx similarity index 95% rename from lib/libs/email/preview/Initial Submissions/CMS/Waiver_Contracting.tsx rename to lib/libs/email/preview/InitialSubmissions/CMS/Waiver_Contracting.tsx index 18b1831615..baa42ffb87 100644 --- a/lib/libs/email/preview/Initial Submissions/CMS/Waiver_Contracting.tsx +++ b/lib/libs/email/preview/InitialSubmissions/CMS/Waiver_Contracting.tsx @@ -1,5 +1,5 @@ -import { Waiver1915bCMSEmail } from "libs/email/content/new-submission/emailTemplates/Waiver1915bCMS"; -import { emailTemplateValue } from "../../../mock-data/new-submission"; +import { Waiver1915bCMSEmail } from "libs/email/content/newSubmission/emailTemplates"; +import { emailTemplateValue } from "libs/email/mock-data/new-submission"; export const Waiver1915bCMSContractingInitialEmailPreview = () => { return ( diff --git a/lib/libs/email/preview/Initial Submissions/CMS/__snapshots__/AppK.tsx b/lib/libs/email/preview/InitialSubmissions/CMS/__snapshots__/AppK.tsx similarity index 88% rename from lib/libs/email/preview/Initial Submissions/CMS/__snapshots__/AppK.tsx rename to lib/libs/email/preview/InitialSubmissions/CMS/__snapshots__/AppK.tsx index 617696b365..7bcfedf6ac 100644 --- a/lib/libs/email/preview/Initial Submissions/CMS/__snapshots__/AppK.tsx +++ b/lib/libs/email/preview/InitialSubmissions/CMS/__snapshots__/AppK.tsx @@ -1,4 +1,4 @@ -import { AppKCMSEmail } from "../../../../content/new-submission/emailTemplates"; +import { AppKCMSEmail } from "../../../../content/newSubmission/emailTemplates"; import { emailTemplateValue } from "../../../../mock-data/new-submission"; import * as attachments from "../../../../mock-data/attachments"; const AppKCMSEmailPreview = () => { diff --git a/lib/libs/email/preview/Initial Submissions/CMS/__snapshots__/InitialSubmissionCMS.test.tsx.snap b/lib/libs/email/preview/InitialSubmissions/CMS/__snapshots__/InitialSubmissionCMS.test.tsx.snap similarity index 100% rename from lib/libs/email/preview/Initial Submissions/CMS/__snapshots__/InitialSubmissionCMS.test.tsx.snap rename to lib/libs/email/preview/InitialSubmissions/CMS/__snapshots__/InitialSubmissionCMS.test.tsx.snap diff --git a/lib/libs/email/preview/Initial Submissions/State/AppK.tsx b/lib/libs/email/preview/InitialSubmissions/State/AppK.tsx similarity index 88% rename from lib/libs/email/preview/Initial Submissions/State/AppK.tsx rename to lib/libs/email/preview/InitialSubmissions/State/AppK.tsx index 93d6b44c9c..f6c1647eb6 100644 --- a/lib/libs/email/preview/Initial Submissions/State/AppK.tsx +++ b/lib/libs/email/preview/InitialSubmissions/State/AppK.tsx @@ -1,4 +1,4 @@ -import { AppKStateEmail } from "../../../content/new-submission/emailTemplates"; +import { AppKStateEmail } from "../../../content/newSubmission/emailTemplates"; import { emailTemplateValue } from "../../../mock-data/new-submission"; import * as attachments from "../../../mock-data/attachments"; diff --git a/lib/libs/email/preview/Initial Submissions/State/CHIP_SPA.tsx b/lib/libs/email/preview/InitialSubmissions/State/CHIP_SPA.tsx similarity index 89% rename from lib/libs/email/preview/Initial Submissions/State/CHIP_SPA.tsx rename to lib/libs/email/preview/InitialSubmissions/State/CHIP_SPA.tsx index 0da31143fb..a5823077a1 100644 --- a/lib/libs/email/preview/Initial Submissions/State/CHIP_SPA.tsx +++ b/lib/libs/email/preview/InitialSubmissions/State/CHIP_SPA.tsx @@ -1,5 +1,5 @@ import { emailTemplateValue } from "libs/email/mock-data/new-submission"; -import { ChipSpaStateEmail } from "libs/email/content/new-submission/emailTemplates"; +import { ChipSpaStateEmail } from "libs/email/content/newSubmission/emailTemplates/ChipSpaState"; import * as attachments from "libs/email/mock-data/attachments"; const ChipSpaStateEmailPreview = () => { return ( diff --git a/lib/libs/email/preview/Initial Submissions/State/InitialSubmissionState.test.tsx b/lib/libs/email/preview/InitialSubmissions/State/InitialSubmissionState.test.tsx similarity index 100% rename from lib/libs/email/preview/Initial Submissions/State/InitialSubmissionState.test.tsx rename to lib/libs/email/preview/InitialSubmissions/State/InitialSubmissionState.test.tsx diff --git a/lib/libs/email/preview/Initial Submissions/State/Medicaid_SPA.tsx b/lib/libs/email/preview/InitialSubmissions/State/Medicaid_SPA.tsx similarity index 91% rename from lib/libs/email/preview/Initial Submissions/State/Medicaid_SPA.tsx rename to lib/libs/email/preview/InitialSubmissions/State/Medicaid_SPA.tsx index 1f3a2e2132..3ea4e1ffb6 100644 --- a/lib/libs/email/preview/Initial Submissions/State/Medicaid_SPA.tsx +++ b/lib/libs/email/preview/InitialSubmissions/State/Medicaid_SPA.tsx @@ -1,4 +1,4 @@ -import { MedSpaStateEmail } from "../../../content/new-submission/emailTemplates"; +import { MedSpaStateEmail } from "../../../content/newSubmission/emailTemplates"; import { emailTemplateValue } from "../../../mock-data/new-submission"; import * as attachments from "../../../mock-data/attachments"; diff --git a/lib/libs/email/preview/Initial Submissions/State/Temp_Extension.tsx b/lib/libs/email/preview/InitialSubmissions/State/Temp_Extension.tsx similarity index 100% rename from lib/libs/email/preview/Initial Submissions/State/Temp_Extension.tsx rename to lib/libs/email/preview/InitialSubmissions/State/Temp_Extension.tsx diff --git a/lib/libs/email/preview/Initial Submissions/State/Waiver_Capitated.tsx b/lib/libs/email/preview/InitialSubmissions/State/Waiver_Capitated.tsx similarity index 98% rename from lib/libs/email/preview/Initial Submissions/State/Waiver_Capitated.tsx rename to lib/libs/email/preview/InitialSubmissions/State/Waiver_Capitated.tsx index 91781bfa5c..14039778e2 100644 --- a/lib/libs/email/preview/Initial Submissions/State/Waiver_Capitated.tsx +++ b/lib/libs/email/preview/InitialSubmissions/State/Waiver_Capitated.tsx @@ -1,4 +1,4 @@ -import { Waiver1915bStateEmail } from "../../../content/new-submission/emailTemplates/Waiver1915bState"; +import { Waiver1915bStateEmail } from "../../../content/newSubmission/emailTemplates/Waiver1915bState"; import { emailTemplateValue } from "../../../mock-data/new-submission"; export const Waiver1915bStateCapitatedInitialEmailPreview = () => { diff --git a/lib/libs/email/preview/Initial Submissions/State/Waiver_Contracting.tsx b/lib/libs/email/preview/InitialSubmissions/State/Waiver_Contracting.tsx similarity index 97% rename from lib/libs/email/preview/Initial Submissions/State/Waiver_Contracting.tsx rename to lib/libs/email/preview/InitialSubmissions/State/Waiver_Contracting.tsx index 1f5261da70..4faee3f0c4 100644 --- a/lib/libs/email/preview/Initial Submissions/State/Waiver_Contracting.tsx +++ b/lib/libs/email/preview/InitialSubmissions/State/Waiver_Contracting.tsx @@ -1,4 +1,4 @@ -import { Waiver1915bStateEmail } from "../../../content/new-submission/emailTemplates/Waiver1915bState"; +import { Waiver1915bStateEmail } from "../../../content/newSubmission/emailTemplates/Waiver1915bState"; import { emailTemplateValue } from "../../../mock-data/new-submission"; export const Waiver1915bContractingStateInitialEmailPreview = () => { diff --git a/lib/libs/email/preview/Initial Submissions/State/__snapshots__/InitialSubmissionState.test.tsx.snap b/lib/libs/email/preview/InitialSubmissions/State/__snapshots__/InitialSubmissionState.test.tsx.snap similarity index 100% rename from lib/libs/email/preview/Initial Submissions/State/__snapshots__/InitialSubmissionState.test.tsx.snap rename to lib/libs/email/preview/InitialSubmissions/State/__snapshots__/InitialSubmissionState.test.tsx.snap diff --git a/lib/libs/email/preview/Initial_Submissions/CMS/Temp_Extension.tsx b/lib/libs/email/preview/Initial_Submissions/CMS/Temp_Extension.tsx new file mode 100644 index 0000000000..44c222ebf1 --- /dev/null +++ b/lib/libs/email/preview/Initial_Submissions/CMS/Temp_Extension.tsx @@ -0,0 +1,14 @@ +import { TempExtCMSEmail } from "../../../content/tempExtension/emailTemplates"; +import { emailTemplateValue } from "../../../mock-data/temp-extension"; + +const TempExtCMSPreview = () => { + return ( + + ); +}; + +export default TempExtCMSPreview; diff --git a/lib/libs/email/preview/Respond to Rai/CMS/AppK.tsx b/lib/libs/email/preview/RespondToRai/CMS/AppK.tsx similarity index 100% rename from lib/libs/email/preview/Respond to Rai/CMS/AppK.tsx rename to lib/libs/email/preview/RespondToRai/CMS/AppK.tsx diff --git a/lib/libs/email/preview/Respond to Rai/CMS/CHIP_SPA.tsx b/lib/libs/email/preview/RespondToRai/CMS/CHIP_SPA.tsx similarity index 100% rename from lib/libs/email/preview/Respond to Rai/CMS/CHIP_SPA.tsx rename to lib/libs/email/preview/RespondToRai/CMS/CHIP_SPA.tsx diff --git a/lib/libs/email/preview/Respond to Rai/CMS/Medicaid_SPA.tsx b/lib/libs/email/preview/RespondToRai/CMS/Medicaid_SPA.tsx similarity index 100% rename from lib/libs/email/preview/Respond to Rai/CMS/Medicaid_SPA.tsx rename to lib/libs/email/preview/RespondToRai/CMS/Medicaid_SPA.tsx diff --git a/lib/libs/email/preview/Respond to Rai/CMS/ResToRaiCMS.test.tsx b/lib/libs/email/preview/RespondToRai/CMS/ResToRaiCMS.test.tsx similarity index 100% rename from lib/libs/email/preview/Respond to Rai/CMS/ResToRaiCMS.test.tsx rename to lib/libs/email/preview/RespondToRai/CMS/ResToRaiCMS.test.tsx diff --git a/lib/libs/email/preview/Respond to Rai/CMS/Waiver_Capitated.tsx b/lib/libs/email/preview/RespondToRai/CMS/Waiver_Capitated.tsx similarity index 100% rename from lib/libs/email/preview/Respond to Rai/CMS/Waiver_Capitated.tsx rename to lib/libs/email/preview/RespondToRai/CMS/Waiver_Capitated.tsx diff --git a/lib/libs/email/preview/Respond to Rai/CMS/__snapshots__/ResToRaiCMS.test.tsx.snap b/lib/libs/email/preview/RespondToRai/CMS/__snapshots__/ResToRaiCMS.test.tsx.snap similarity index 100% rename from lib/libs/email/preview/Respond to Rai/CMS/__snapshots__/ResToRaiCMS.test.tsx.snap rename to lib/libs/email/preview/RespondToRai/CMS/__snapshots__/ResToRaiCMS.test.tsx.snap diff --git a/lib/libs/email/preview/Respond to Rai/State/AppK.tsx b/lib/libs/email/preview/RespondToRai/State/AppK.tsx similarity index 100% rename from lib/libs/email/preview/Respond to Rai/State/AppK.tsx rename to lib/libs/email/preview/RespondToRai/State/AppK.tsx diff --git a/lib/libs/email/preview/Respond to Rai/State/CHIP_SPA.tsx b/lib/libs/email/preview/RespondToRai/State/CHIP_SPA.tsx similarity index 100% rename from lib/libs/email/preview/Respond to Rai/State/CHIP_SPA.tsx rename to lib/libs/email/preview/RespondToRai/State/CHIP_SPA.tsx diff --git a/lib/libs/email/preview/Respond to Rai/State/Medicaid_SPA.tsx b/lib/libs/email/preview/RespondToRai/State/Medicaid_SPA.tsx similarity index 100% rename from lib/libs/email/preview/Respond to Rai/State/Medicaid_SPA.tsx rename to lib/libs/email/preview/RespondToRai/State/Medicaid_SPA.tsx diff --git a/lib/libs/email/preview/Respond to Rai/State/ResToRaiState.test.tsx b/lib/libs/email/preview/RespondToRai/State/ResToRaiState.test.tsx similarity index 100% rename from lib/libs/email/preview/Respond to Rai/State/ResToRaiState.test.tsx rename to lib/libs/email/preview/RespondToRai/State/ResToRaiState.test.tsx diff --git a/lib/libs/email/preview/Respond to Rai/State/Waiver_Capitated.tsx b/lib/libs/email/preview/RespondToRai/State/Waiver_Capitated.tsx similarity index 92% rename from lib/libs/email/preview/Respond to Rai/State/Waiver_Capitated.tsx rename to lib/libs/email/preview/RespondToRai/State/Waiver_Capitated.tsx index e50ba37acd..bc53bb7412 100644 --- a/lib/libs/email/preview/Respond to Rai/State/Waiver_Capitated.tsx +++ b/lib/libs/email/preview/RespondToRai/State/Waiver_Capitated.tsx @@ -1,6 +1,6 @@ import { WaiverStateEmail } from "libs/email/content/respondToRai/emailTemplates"; import { emailTemplateValue } from "libs/email/mock-data/respond-to-rai"; -import * as attachments from "../../../mock-data/attachments"; +import * as attachments from "libs/email/mock-data/attachments"; export default () => { return ( diff --git a/lib/libs/email/preview/Respond to Rai/State/__snapshots__/ResToRaiState.test.tsx.snap b/lib/libs/email/preview/RespondToRai/State/__snapshots__/ResToRaiState.test.tsx.snap similarity index 100% rename from lib/libs/email/preview/Respond to Rai/State/__snapshots__/ResToRaiState.test.tsx.snap rename to lib/libs/email/preview/RespondToRai/State/__snapshots__/ResToRaiState.test.tsx.snap diff --git a/lib/libs/email/preview/Upload Subsequent Documents/CMS/AppK.tsx b/lib/libs/email/preview/UploadSubsequentDocuments/CMS/AppK.tsx similarity index 87% rename from lib/libs/email/preview/Upload Subsequent Documents/CMS/AppK.tsx rename to lib/libs/email/preview/UploadSubsequentDocuments/CMS/AppK.tsx index b18abb99bb..58a5412c26 100644 --- a/lib/libs/email/preview/Upload Subsequent Documents/CMS/AppK.tsx +++ b/lib/libs/email/preview/UploadSubsequentDocuments/CMS/AppK.tsx @@ -1,4 +1,4 @@ -import { AppKCMSEmail } from "../../../content/upload-subsequent-documents/emailTemplates"; +import { AppKCMSEmail } from "../../../content/uploadSubsequentDocuments/emailTemplates"; import { emailTemplateValue } from "../../../mock-data/new-submission"; import * as attachments from "../../../mock-data/attachments"; const AppKCMSEmailPreview = () => { diff --git a/lib/libs/email/preview/Upload Subsequent Documents/CMS/CHIP_SPA.tsx b/lib/libs/email/preview/UploadSubsequentDocuments/CMS/CHIP_SPA.tsx similarity index 89% rename from lib/libs/email/preview/Upload Subsequent Documents/CMS/CHIP_SPA.tsx rename to lib/libs/email/preview/UploadSubsequentDocuments/CMS/CHIP_SPA.tsx index 94c86da233..6020a1b165 100644 --- a/lib/libs/email/preview/Upload Subsequent Documents/CMS/CHIP_SPA.tsx +++ b/lib/libs/email/preview/UploadSubsequentDocuments/CMS/CHIP_SPA.tsx @@ -1,4 +1,4 @@ -import { ChipSpaCMSEmail } from "libs/email/content/upload-subsequent-documents/emailTemplates"; +import { ChipSpaCMSEmail } from "libs/email/content/uploadSubsequentDocuments/emailTemplates"; import { emailTemplateValue } from "libs/email/mock-data/upload-subsequent-documents"; import * as attachments from "libs/email/mock-data/attachments"; diff --git a/lib/libs/email/preview/Upload Subsequent Documents/CMS/MED_SPA.tsx b/lib/libs/email/preview/UploadSubsequentDocuments/CMS/MED_SPA.tsx similarity index 90% rename from lib/libs/email/preview/Upload Subsequent Documents/CMS/MED_SPA.tsx rename to lib/libs/email/preview/UploadSubsequentDocuments/CMS/MED_SPA.tsx index 74b4f57c42..dd114250af 100644 --- a/lib/libs/email/preview/Upload Subsequent Documents/CMS/MED_SPA.tsx +++ b/lib/libs/email/preview/UploadSubsequentDocuments/CMS/MED_SPA.tsx @@ -1,4 +1,4 @@ -import { MedSpaCMSEmail } from "libs/email/content/upload-subsequent-documents/emailTemplates"; +import { MedSpaCMSEmail } from "libs/email/content/uploadSubsequentDocuments/emailTemplates"; import { emailTemplateValue } from "libs/email/mock-data/upload-subsequent-documents"; import * as attachments from "libs/email/mock-data/attachments"; diff --git a/lib/libs/email/preview/Upload Subsequent Documents/CMS/UpSubDocCMS.test.tsx b/lib/libs/email/preview/UploadSubsequentDocuments/CMS/UpSubDocCMS.test.tsx similarity index 100% rename from lib/libs/email/preview/Upload Subsequent Documents/CMS/UpSubDocCMS.test.tsx rename to lib/libs/email/preview/UploadSubsequentDocuments/CMS/UpSubDocCMS.test.tsx diff --git a/lib/libs/email/preview/Upload Subsequent Documents/CMS/Waiver1915b.tsx b/lib/libs/email/preview/UploadSubsequentDocuments/CMS/Waiver1915b.tsx similarity index 88% rename from lib/libs/email/preview/Upload Subsequent Documents/CMS/Waiver1915b.tsx rename to lib/libs/email/preview/UploadSubsequentDocuments/CMS/Waiver1915b.tsx index 5e72eaf2ed..e96a8bfab4 100644 --- a/lib/libs/email/preview/Upload Subsequent Documents/CMS/Waiver1915b.tsx +++ b/lib/libs/email/preview/UploadSubsequentDocuments/CMS/Waiver1915b.tsx @@ -1,4 +1,4 @@ -import { WaiversEmailCMS } from "libs/email/content/upload-subsequent-documents/emailTemplates/Waiver1915BCMS"; +import { WaiversEmailCMS } from "libs/email/content/uploadSubsequentDocuments/emailTemplates/Waiver1915BCMS"; import { emailTemplateValue } from "libs/email/mock-data/upload-subsequent-documents"; import * as attachments from "libs/email/mock-data/attachments"; diff --git a/lib/libs/email/preview/Upload Subsequent Documents/CMS/__snapshots__/UpSubDocCMS.test.tsx.snap b/lib/libs/email/preview/UploadSubsequentDocuments/CMS/__snapshots__/UpSubDocCMS.test.tsx.snap similarity index 100% rename from lib/libs/email/preview/Upload Subsequent Documents/CMS/__snapshots__/UpSubDocCMS.test.tsx.snap rename to lib/libs/email/preview/UploadSubsequentDocuments/CMS/__snapshots__/UpSubDocCMS.test.tsx.snap diff --git a/lib/libs/email/preview/Upload Subsequent Documents/State/AppK.tsx b/lib/libs/email/preview/UploadSubsequentDocuments/State/AppK.tsx similarity index 67% rename from lib/libs/email/preview/Upload Subsequent Documents/State/AppK.tsx rename to lib/libs/email/preview/UploadSubsequentDocuments/State/AppK.tsx index 62b6e62897..1d88221486 100644 --- a/lib/libs/email/preview/Upload Subsequent Documents/State/AppK.tsx +++ b/lib/libs/email/preview/UploadSubsequentDocuments/State/AppK.tsx @@ -1,6 +1,6 @@ -import { AppKStateEmail } from "../../../content/upload-subsequent-documents/emailTemplates"; -import { emailTemplateValue } from "../../../mock-data/new-submission"; -import * as attachments from "../../../mock-data/attachments"; +import { AppKStateEmail } from "libs/email/content/uploadSubsequentDocuments/emailTemplates/AppKState"; +import { emailTemplateValue } from "libs/email/mock-data/new-submission"; +import * as attachments from "libs/email/mock-data/attachments"; const AppKStateEmailPreview = () => { return ( { return ( - { return ( diff --git a/lib/libs/email/preview/Upload Subsequent Documents/State/UpSubDocState.test.tsx b/lib/libs/email/preview/UploadSubsequentDocuments/State/UpSubDocState.test.tsx similarity index 100% rename from lib/libs/email/preview/Upload Subsequent Documents/State/UpSubDocState.test.tsx rename to lib/libs/email/preview/UploadSubsequentDocuments/State/UpSubDocState.test.tsx diff --git a/lib/libs/email/preview/Upload Subsequent Documents/State/Waiver1915b.tsx b/lib/libs/email/preview/UploadSubsequentDocuments/State/Waiver1915b.tsx similarity index 88% rename from lib/libs/email/preview/Upload Subsequent Documents/State/Waiver1915b.tsx rename to lib/libs/email/preview/UploadSubsequentDocuments/State/Waiver1915b.tsx index 9ce41a53ac..7811021bd2 100644 --- a/lib/libs/email/preview/Upload Subsequent Documents/State/Waiver1915b.tsx +++ b/lib/libs/email/preview/UploadSubsequentDocuments/State/Waiver1915b.tsx @@ -1,4 +1,4 @@ -import { WaiversEmailState } from "libs/email/content/upload-subsequent-documents/emailTemplates/Waiver1915BState"; +import { WaiversEmailState } from "libs/email/content/uploadSubsequentDocuments/emailTemplates/Waiver1915BState"; import { emailTemplateValue } from "libs/email/mock-data/upload-subsequent-documents"; import * as attachments from "libs/email/mock-data/attachments"; diff --git a/lib/libs/email/preview/Upload Subsequent Documents/State/__snapshots__/UpSubDocState.test.tsx.snap b/lib/libs/email/preview/UploadSubsequentDocuments/State/__snapshots__/UpSubDocState.test.tsx.snap similarity index 96% rename from lib/libs/email/preview/Upload Subsequent Documents/State/__snapshots__/UpSubDocState.test.tsx.snap rename to lib/libs/email/preview/UploadSubsequentDocuments/State/__snapshots__/UpSubDocState.test.tsx.snap index a1a2f3801d..08ae6cd292 100644 --- a/lib/libs/email/preview/Upload Subsequent Documents/State/__snapshots__/UpSubDocState.test.tsx.snap +++ b/lib/libs/email/preview/UploadSubsequentDocuments/State/__snapshots__/UpSubDocState.test.tsx.snap @@ -1406,9 +1406,9 @@ exports[`Upload Subsequent Document CMS Email Snapshot Test > renders a ChipSPA
- Additional documents submitted for CHIP SPA CO-24-1234 + Action required: review new documents for CHIP SPA CO-24-1234 in OneMAC.
-  ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ +  ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏
renders a ChipSPA

- You’ve successfully submitted the following to CMS reviewers for CHIP SPA CO-24-1234 + New documents have been submitted for CHIP SPA CO-24-1234 in OneMAC.

renders a ChipSPA
- - - - - - - -
-

- Name - : -

-
-

- George Harrison -

-
- - - - - - - -
-

- Email Address - : -

-
-

- george@example.com -

-
renders a ChipSPA style="width: 100%; border-top: 1px solid #0071BD; margin: 16px 0px;" />

- If you have questions or did not expect this email, please contact your CPOC. + How to Access:

+
    +
  • +

    + These documents can be found in OneMAC through this link + + + https://mako-dev.cms.gov/ + + . +

    +
  • +
  • +

    + If you are not already logged in, click “Login” at the top of the page and log in using your Enterprise User Administration (EUA) credentials. +

    +
  • +
  • +

    + After you logged in, click the submission ID number on the dashboard page to view details. +

    +
  • +

@@ -2309,9 +2265,9 @@ exports[`Upload Subsequent Document CMS Email Snapshot Test > renders a ChipSPA

- Additional documents submitted for CHIP SPA CO-24-1234 + Action required: review new documents for CHIP SPA CO-24-1234 in OneMAC.
-  ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ +  ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏
renders a ChipSPA

- You’ve successfully submitted the following to CMS reviewers for CHIP SPA CO-24-1234 + New documents have been submitted for CHIP SPA CO-24-1234 in OneMAC.

renders a ChipSPA
- - - - - - - -
-

- Name - : -

-
-

- George Harrison -

-
- - - - - - - -
-

- Email Address - : -

-
-

- george@example.com -

-
renders a ChipSPA style="width: 100%; border-top: 1px solid #0071BD; margin: 16px 0px;" />

- If you have questions or did not expect this email, please contact your CPOC. + How to Access:

+
    +
  • +

    + These documents can be found in OneMAC through this link + + + https://mako-dev.cms.gov/ + + . +

    +
  • +
  • +

    + If you are not already logged in, click “Login” at the top of the page and log in using your Enterprise User Administration (EUA) credentials. +

    +
  • +
  • +

    + After you logged in, click the submission ID number on the dashboard page to view details. +

    +
  • +

@@ -3711,9 +3623,9 @@ exports[`Upload Subsequent Document CMS Email Snapshot Test > renders a Medicaid

- Additional documents submitted for CHIP SPA CO-24-1234 + Action required: review new documents for CHIP SPA CO-24-1234 in OneMAC.
-  ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ +  ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏
renders a Medicaid

- You’ve successfully submitted the following to CMS reviewers for CHIP SPA CO-24-1234 + New documents have been submitted for CHIP SPA CO-24-1234 in OneMAC.

renders a Medicaid
- - - - - - - -
-

- Name - : -

-
-

- George Harrison -

-
- - - - - - - -
-

- Email Address - : -

-
-

- george@example.com -

-
renders a Medicaid style="width: 100%; border-top: 1px solid #0071BD; margin: 16px 0px;" />

- If you have questions or did not expect this email, please contact your CPOC. + How to Access:

+
    +
  • +

    + These documents can be found in OneMAC through this link + + + https://mako-dev.cms.gov/ + + . +

    +
  • +
  • +

    + If you are not already logged in, click “Login” at the top of the page and log in using your Enterprise User Administration (EUA) credentials. +

    +
  • +
  • +

    + After you logged in, click the submission ID number on the dashboard page to view details. +

    +
  • +

@@ -6912,9 +6780,9 @@ exports[`Upload Subsequent Document CMS Email Snapshot Test > renders a Waiver C

- Additional documents submitted for CHIP SPA CO-24-1234 + Action required: review new documents for CHIP SPA CO-24-1234 in OneMAC.
-  ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ +  ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏
renders a Waiver C

- You’ve successfully submitted the following to CMS reviewers for CHIP SPA CO-24-1234 + New documents have been submitted for CHIP SPA CO-24-1234 in OneMAC.

renders a Waiver C
- - - - - - - -
-

- Name - : -

-
-

- George Harrison -

-
- - - - - - - -
-

- Email Address - : -

-
-

- george@example.com -

-
renders a Waiver C style="width: 100%; border-top: 1px solid #0071BD; margin: 16px 0px;" />

- If you have questions or did not expect this email, please contact your CPOC. + How to Access:

+
    +
  • +

    + These documents can be found in OneMAC through this link + + + https://mako-dev.cms.gov/ + + . +

    +
  • +
  • +

    + If you are not already logged in, click “Login” at the top of the page and log in using your Enterprise User Administration (EUA) credentials. +

    +
  • +
  • +

    + After you logged in, click the submission ID number on the dashboard page to view details. +

    +
  • +

diff --git a/lib/libs/email/preview/Withdraw Package/CMS/AppK.tsx b/lib/libs/email/preview/WithdrawPackage/CMS/AppK.tsx similarity index 100% rename from lib/libs/email/preview/Withdraw Package/CMS/AppK.tsx rename to lib/libs/email/preview/WithdrawPackage/CMS/AppK.tsx diff --git a/lib/libs/email/preview/Withdraw Package/CMS/CHIP_SPA.tsx b/lib/libs/email/preview/WithdrawPackage/CMS/CHIP_SPA.tsx similarity index 100% rename from lib/libs/email/preview/Withdraw Package/CMS/CHIP_SPA.tsx rename to lib/libs/email/preview/WithdrawPackage/CMS/CHIP_SPA.tsx diff --git a/lib/libs/email/preview/Withdraw Package/CMS/Medicaid_SPA.tsx b/lib/libs/email/preview/WithdrawPackage/CMS/Medicaid_SPA.tsx similarity index 100% rename from lib/libs/email/preview/Withdraw Package/CMS/Medicaid_SPA.tsx rename to lib/libs/email/preview/WithdrawPackage/CMS/Medicaid_SPA.tsx diff --git a/lib/libs/email/preview/Withdraw Package/CMS/Waiver_Capitated.tsx b/lib/libs/email/preview/WithdrawPackage/CMS/Waiver_Capitated.tsx similarity index 100% rename from lib/libs/email/preview/Withdraw Package/CMS/Waiver_Capitated.tsx rename to lib/libs/email/preview/WithdrawPackage/CMS/Waiver_Capitated.tsx diff --git a/lib/libs/email/preview/Withdraw Package/CMS/WithdrawPackageCMS.test.tsx b/lib/libs/email/preview/WithdrawPackage/CMS/WithdrawPackageCMS.test.tsx similarity index 100% rename from lib/libs/email/preview/Withdraw Package/CMS/WithdrawPackageCMS.test.tsx rename to lib/libs/email/preview/WithdrawPackage/CMS/WithdrawPackageCMS.test.tsx diff --git a/lib/libs/email/preview/Withdraw Package/CMS/__snapshots__/WithdrawPackageCMS.test.tsx.snap b/lib/libs/email/preview/WithdrawPackage/CMS/__snapshots__/WithdrawPackageCMS.test.tsx.snap similarity index 100% rename from lib/libs/email/preview/Withdraw Package/CMS/__snapshots__/WithdrawPackageCMS.test.tsx.snap rename to lib/libs/email/preview/WithdrawPackage/CMS/__snapshots__/WithdrawPackageCMS.test.tsx.snap diff --git a/lib/libs/email/preview/Withdraw Package/State/AppK.tsx b/lib/libs/email/preview/WithdrawPackage/State/AppK.tsx similarity index 100% rename from lib/libs/email/preview/Withdraw Package/State/AppK.tsx rename to lib/libs/email/preview/WithdrawPackage/State/AppK.tsx diff --git a/lib/libs/email/preview/Withdraw Package/State/CHIP_SPA.tsx b/lib/libs/email/preview/WithdrawPackage/State/CHIP_SPA.tsx similarity index 100% rename from lib/libs/email/preview/Withdraw Package/State/CHIP_SPA.tsx rename to lib/libs/email/preview/WithdrawPackage/State/CHIP_SPA.tsx diff --git a/lib/libs/email/preview/Withdraw Package/State/Medicaid_SPA.tsx b/lib/libs/email/preview/WithdrawPackage/State/Medicaid_SPA.tsx similarity index 100% rename from lib/libs/email/preview/Withdraw Package/State/Medicaid_SPA.tsx rename to lib/libs/email/preview/WithdrawPackage/State/Medicaid_SPA.tsx diff --git a/lib/libs/email/preview/Withdraw Package/State/Waiver_Capitated.tsx b/lib/libs/email/preview/WithdrawPackage/State/Waiver_Capitated.tsx similarity index 100% rename from lib/libs/email/preview/Withdraw Package/State/Waiver_Capitated.tsx rename to lib/libs/email/preview/WithdrawPackage/State/Waiver_Capitated.tsx diff --git a/lib/libs/email/preview/Withdraw Package/State/WithdrawPackageState.test.tsx b/lib/libs/email/preview/WithdrawPackage/State/WithdrawPackageState.test.tsx similarity index 100% rename from lib/libs/email/preview/Withdraw Package/State/WithdrawPackageState.test.tsx rename to lib/libs/email/preview/WithdrawPackage/State/WithdrawPackageState.test.tsx diff --git a/lib/libs/email/preview/Withdraw Package/State/__snapshots__/WithdrawPackageState.test.tsx.snap b/lib/libs/email/preview/WithdrawPackage/State/__snapshots__/WithdrawPackageState.test.tsx.snap similarity index 100% rename from lib/libs/email/preview/Withdraw Package/State/__snapshots__/WithdrawPackageState.test.tsx.snap rename to lib/libs/email/preview/WithdrawPackage/State/__snapshots__/WithdrawPackageState.test.tsx.snap diff --git a/lib/libs/env.ts b/lib/libs/env.ts index 9c00fcf01d..f84024c037 100644 --- a/lib/libs/env.ts +++ b/lib/libs/env.ts @@ -1,8 +1,6 @@ export function checkEnvVars(requiredVars: string[]) { const missingVars = requiredVars.filter((v) => !process.env[v]); if (missingVars.length > 0) { - throw new Error( - `Missing required environment variables: ${missingVars.join(", ")}` - ); + throw new Error(`Missing required environment variables: ${missingVars.join(", ")}`); } } diff --git a/lib/libs/handler-lib.ts b/lib/libs/handler-lib.ts index 8abfce1ad4..5eb9dc0035 100644 --- a/lib/libs/handler-lib.ts +++ b/lib/libs/handler-lib.ts @@ -1,14 +1,7 @@ -import type { - APIGatewayEvent, - APIGatewayProxyResult, - Context, -} from "aws-lambda"; +import type { APIGatewayEvent, APIGatewayProxyResult, Context } from "aws-lambda"; export const handler = async ( - handler: ( - event?: APIGatewayEvent, - context?: Context, - ) => Promise, + handler: (event?: APIGatewayEvent, context?: Context) => Promise, ) => { const handlerResponse = await handler(); diff --git a/lib/libs/tests/env.test.ts b/lib/libs/tests/env.test.ts index d5bca41466..07d78284a8 100644 --- a/lib/libs/tests/env.test.ts +++ b/lib/libs/tests/env.test.ts @@ -13,12 +13,12 @@ describe("checkEnvVars", () => { test("should throw an error when a required environment variable is missing", () => { process.env.FOO = "bar"; expect(() => checkEnvVars(["FOO", "BAZ"])).toThrowError( - "Missing required environment variables: BAZ" + "Missing required environment variables: BAZ", ); }); test("should throw an error when multiple required environment variables are missing", () => { expect(() => checkEnvVars(["FOO", "BAZ"])).toThrowError( - "Missing required environment variables: FOO, BAZ" + "Missing required environment variables: FOO, BAZ", ); }); }); diff --git a/lib/libs/topics-lib.ts b/lib/libs/topics-lib.ts index 4248a23866..2ab882b3d8 100644 --- a/lib/libs/topics-lib.ts +++ b/lib/libs/topics-lib.ts @@ -7,10 +7,7 @@ interface TopicConfig { // Add other properties as needed } -export async function createTopics( - brokerString: string, - topicsConfig: TopicConfig[], -) { +export async function createTopics(brokerString: string, topicsConfig: TopicConfig[]) { const topics = topicsConfig; const brokers = brokerString.split(","); @@ -25,10 +22,7 @@ export async function createTopics( await admin.connect(); // Fetch topics from MSK and filter out __ internal management topic - const existingTopicList = _.filter( - await admin.listTopics(), - (n) => !n.startsWith("_"), - ); + const existingTopicList = _.filter(await admin.listTopics(), (n) => !n.startsWith("_")); console.log("Existing topics:", JSON.stringify(existingTopicList, null, 2)); @@ -54,8 +48,7 @@ export async function createTopics( topicsMetadata, (topicConfig, topicMetadata) => _.get(topicConfig, "topic") === _.get(topicMetadata, "name") && - _.get(topicConfig, "numPartitions") > - _.get(topicMetadata, "partitions", []).length, + _.get(topicConfig, "numPartitions") > _.get(topicMetadata, "partitions", []).length, ); // Create a collection to update topic partitioning @@ -81,14 +74,8 @@ export async function createTopics( console.log("Topics to Create:", JSON.stringify(topicsToCreate, null, 2)); console.log("Topics to Update:", JSON.stringify(topicsToUpdate, null, 2)); - console.log( - "Partitions to Update:", - JSON.stringify(partitionConfig, null, 2), - ); - console.log( - "Topic configuration options:", - JSON.stringify(configs, null, 2), - ); + console.log("Partitions to Update:", JSON.stringify(partitionConfig, null, 2)); + console.log("Topic configuration options:", JSON.stringify(configs, null, 2)); // Create topics that don't exist in MSK await admin.createTopics({ topics: topicsToCreate }); diff --git a/lib/libs/webforms/ABP1/v202401.ts b/lib/libs/webforms/ABP1/v202401.ts index 1f208e4b7c..cb661fb6a3 100644 --- a/lib/libs/webforms/ABP1/v202401.ts +++ b/lib/libs/webforms/ABP1/v202401.ts @@ -62,8 +62,7 @@ export const v202401: FormSchema = { value: "extend_medicaid_earnings", }, { - label: - "Extended Medicaid Due to Spousal Support Collections", + label: "Extended Medicaid Due to Spousal Support Collections", value: "extend_medicaid_spousal_support_collect", }, { @@ -81,8 +80,7 @@ export const v202401: FormSchema = { { label: "Children with Title IV-E Adoption Assistance, Foster Care or Guardianship Care", - value: - "children_title_IV-E_adoption_assist_foster_guardianship_care", + value: "children_title_IV-E_adoption_assist_foster_guardianship_care", }, { label: "Former Foster Care Children", @@ -97,15 +95,12 @@ export const v202401: FormSchema = { value: "ssi_beneficiaries", }, { - label: - "Aged, Blind and Disabled Individuals in 209(b) States", + label: "Aged, Blind and Disabled Individuals in 209(b) States", value: "aged_blind_disabled_individuals_209b_states", }, { - label: - "Individuals Receiving Mandatory State Supplements", - value: - "individuals_receiving_mandatory_state_supplements", + label: "Individuals Receiving Mandatory State Supplements", + value: "individuals_receiving_mandatory_state_supplements", }, { label: "Individuals Who Are Essential Spouses", @@ -122,20 +117,17 @@ export const v202401: FormSchema = { { label: "Individuals Who Lost Eligibility for SSI/SSP Due to an Increase in OASDI Benefits in 1972", - value: - "lost_eligibility_SSI_SSP_increase_in_OASDI_benefits_1972", + value: "lost_eligibility_SSI_SSP_increase_in_OASDI_benefits_1972", }, { label: "Individuals Eligible for SSI/SSP but for OASDI COLA increases since April, 1977", - value: - "eligible_SSI_SSP_but_for_OASDI_COLA_increases_April_1977", + value: "eligible_SSI_SSP_but_for_OASDI_COLA_increases_April_1977", }, { label: "Disabled Widows and Widowers Ineligible for SSI due to Increase in OASDI", - value: - "disabled_widows_ineligible_SSI_due_to_increase_OASDI", + value: "disabled_widows_ineligible_SSI_due_to_increase_OASDI", }, { label: @@ -168,13 +160,11 @@ export const v202401: FormSchema = { value: "qualifying_individuals", }, { - label: - "Optional Coverage of Parents and Other Caretaker Relatives", + label: "Optional Coverage of Parents and Other Caretaker Relatives", value: "opt_coverage_parents_other_caretaker_relatives", }, { - label: - "Reasonable Classifications of Individuals under Age 21", + label: "Reasonable Classifications of Individuals under Age 21", value: "reasonable_class_under_21", }, { @@ -190,15 +180,13 @@ export const v202401: FormSchema = { value: "opt_targeted_low_income_children", }, { - label: - "Individuals Electing COBRA Continuation Coverage", + label: "Individuals Electing COBRA Continuation Coverage", value: "individuals_electing_COBRA_cont_converage", }, { label: "Certain Individuals Needing Treatment for Breast or Cervical Cancer", - value: - "individuals_need_treatment_for_breasts_cervical_cancer", + value: "individuals_need_treatment_for_breasts_cervical_cancer", }, { label: "Individuals with Tuberculosis", @@ -207,25 +195,21 @@ export const v202401: FormSchema = { { label: "Aged, Blind or Disabled Individuals Eligible for but Not Receiving Cash", - value: - "aged_blind_disabled_eligible_but_not_receiving_cash", + value: "aged_blind_disabled_eligible_but_not_receiving_cash", }, { - label: - "Individuals Eligible for Cash except for Institutionalization", + label: "Individuals Eligible for Cash except for Institutionalization", value: "eligible_cash_except_for_institutionalization", }, { label: "Individuals Receiving Home and Community Based Services under Institutional Rules", - value: - "receiving_home_community_services_under_inst_rule", + value: "receiving_home_community_services_under_inst_rule", }, { label: "Optional State Supplement - 1634 States and SSI Criteria States with 1616 Agreements", - value: - "opt_state_supp_1634_states_SSI_criteria_states_1616_agreements", + value: "opt_state_supp_1634_states_SSI_criteria_states_1616_agreements", }, { label: @@ -263,8 +247,7 @@ export const v202401: FormSchema = { value: "ticket_work_medical_imp_group", }, { - label: - "Family Opportunity Act Children with Disabilities", + label: "Family Opportunity Act Children with Disabilities", value: "family_opportunity_act_children_disabilities", }, { @@ -288,8 +271,7 @@ export const v202401: FormSchema = { value: "med_needy_aged_blind_disabled", }, { - label: - "Medically Needy Blind or Disabled Individuals Eligible in 1973", + label: "Medically Needy Blind or Disabled Individuals Eligible in 1973", value: "med_needy_blind_disabled_eligible_1973", }, ], @@ -321,8 +303,7 @@ export const v202401: FormSchema = { ], }, { - description: - "Is enrollment available for all individuals in these eligibility groups?", + description: "Is enrollment available for all individuals in these eligibility groups?", slots: [ { rhf: "Select", @@ -384,13 +365,11 @@ export const v202401: FormSchema = { props: { options: [ { - label: - "Households with income at or below the standard", + label: "Households with income at or below the standard", value: "income_target_below", }, { - label: - "Households with income above the standard", + label: "Households with income above the standard", value: "income_target_above", }, ], @@ -433,14 +412,12 @@ export const v202401: FormSchema = { rules: { pattern: { value: /^\d*\.?\d+$/, - message: - "Must be a positive percentage", + message: "Must be a positive percentage", }, required: "* Required", }, name: "federal_poverty_level_percentage", - label: - "Enter the federal poverty level percentage", + label: "Enter the federal poverty level percentage", }, ], }, @@ -459,8 +436,7 @@ export const v202401: FormSchema = { rules: { pattern: { value: /^\d*\.?\d+$/, - message: - "Must be a positive percentage", + message: "Must be a positive percentage", }, required: "* Required", }, @@ -474,16 +450,14 @@ export const v202401: FormSchema = { { rhf: "Input", name: "other_percentage", - label: - "Enter the other percentage", + label: "Enter the other percentage", props: { icon: "%", }, rules: { pattern: { value: /^\d*\.?\d+$/, - message: - "Must be a positive percentage", + message: "Must be a positive percentage", }, required: "* Required", }, @@ -495,8 +469,7 @@ export const v202401: FormSchema = { rules: { required: "* Required", pattern: { - value: - noLeadingTrailingWhitespace, + value: noLeadingTrailingWhitespace, message: "Must not have leading or trailing whitespace.", }, @@ -536,10 +509,8 @@ export const v202401: FormSchema = { label: "Household Size", name: "household_size", props: { - placeholder: - "enter size", - className: - "w-[300px]", + placeholder: "enter size", + className: "w-[300px]", }, rules: { pattern: { @@ -547,8 +518,7 @@ export const v202401: FormSchema = { message: "Must be a positive integer value", }, - required: - "* Required", + required: "* Required", }, }, { @@ -556,21 +526,17 @@ export const v202401: FormSchema = { name: "standard", label: "Standard ($)", props: { - className: - "w-[200px]", - placeholder: - "enter amount", + className: "w-[200px]", + placeholder: "enter amount", icon: "$", }, rules: { pattern: { - value: - /^\d*(?:\.\d{1,2})?$/, + value: /^\d*(?:\.\d{1,2})?$/, message: "Must be a positive number, maximum of two decimals, no commas. e.g. 1234.56", }, - required: - "* Required", + required: "* Required", }, }, ], @@ -593,21 +559,18 @@ export const v202401: FormSchema = { slots: [ { rhf: "Input", - label: - "Incremental amount ($)", + label: "Incremental amount ($)", name: "dollar_incremental_amount_statewide_std", props: { icon: "$", }, rules: { pattern: { - value: - /^\d*(?:\.\d{1,2})?$/, + value: /^\d*(?:\.\d{1,2})?$/, message: "Must be all numbers, no commas. e.g. 1234.56", }, - required: - "* Required", + required: "* Required", }, }, ], @@ -633,8 +596,7 @@ export const v202401: FormSchema = { props: { ...DefaultFieldGroupProps, appendText: "Add Region", - removeText: - "Remove Region", + removeText: "Remove Region", }, fields: [ { @@ -642,11 +604,9 @@ export const v202401: FormSchema = { name: "name_of_region", label: "Region Name", rules: { - required: - "* Required", + required: "* Required", pattern: { - value: - /^\S(.*\S)?$/, + value: /^\S(.*\S)?$/, message: "Must not have leading or trailing whitespace.", }, @@ -657,11 +617,9 @@ export const v202401: FormSchema = { name: "region_description", label: "Description", rules: { - required: - "* Required", + required: "* Required", pattern: { - value: - noLeadingTrailingWhitespace, + value: noLeadingTrailingWhitespace, message: "Must not have leading or trailing whitespace.", }, @@ -671,53 +629,42 @@ export const v202401: FormSchema = { rhf: "FieldArray", name: "income_definition_region_statewide_arr", props: { - appendText: - "Add household size", + appendText: "Add household size", }, fields: [ { rhf: "Input", - label: - "Household Size", + label: "Household Size", name: "household_size", props: { - placeholder: - "enter size", - className: - "w-[300px]", + placeholder: "enter size", + className: "w-[300px]", }, rules: { pattern: { - value: - /^[0-9]\d*$/, + value: /^[0-9]\d*$/, message: "Must be a positive integer value", }, - required: - "* Required", + required: "* Required", }, }, { rhf: "Input", name: "standard", - label: - "Standard ($)", + label: "Standard ($)", props: { - className: - "w-[200px]", - placeholder: - "enter amount", + className: "w-[200px]", + placeholder: "enter amount", icon: "$", }, rules: { pattern: { - value: - /^\d*(?:\.\d{1,2})?$/, + value: /^\d*(?:\.\d{1,2})?$/, message: "Must be all numbers, no commas. e.g. 1234.56", }, - required: - "* Required", + required: "* Required", }, }, ], @@ -743,15 +690,13 @@ export const v202401: FormSchema = { icon: "$", }, rules: { - pattern: - { - value: - /^\d*(?:\.\d{1,2})?$/, - message: - "Must be all numbers, no commas. e.g. 1234.56", - }, - required: - "* Required", + pattern: { + value: + /^\d*(?:\.\d{1,2})?$/, + message: + "Must be all numbers, no commas. e.g. 1234.56", + }, + required: "* Required", }, }, ], @@ -768,8 +713,7 @@ export const v202401: FormSchema = { ], }, { - label: - "Standard varies by living arrangement", + label: "Standard varies by living arrangement", value: "living_standard", form: [ @@ -780,23 +724,18 @@ export const v202401: FormSchema = { name: "income_definition_specific_statewide_group_liv_arrange", props: { ...DefaultFieldGroupProps, - appendText: - "Add Living Arrangement", - removeText: - "Remove living arrangement", + appendText: "Add Living Arrangement", + removeText: "Remove living arrangement", }, fields: [ { rhf: "Input", name: "name_of_living_arrangement", - label: - "Name of living arrangement", + label: "Name of living arrangement", rules: { - required: - "* Required", + required: "* Required", pattern: { - value: - /^\S(.*\S)?$/, + value: /^\S(.*\S)?$/, message: "Must not have leading or trailing whitespace.", }, @@ -807,11 +746,9 @@ export const v202401: FormSchema = { name: "living_arrangement_description", label: "Description", rules: { - required: - "* Required", + required: "* Required", pattern: { - value: - noLeadingTrailingWhitespace, + value: noLeadingTrailingWhitespace, message: "Must not have leading or trailing whitespace.", }, @@ -821,53 +758,42 @@ export const v202401: FormSchema = { rhf: "FieldArray", name: "income_definition_specific_statewide_arr", props: { - appendText: - "Add household size", + appendText: "Add household size", }, fields: [ { rhf: "Input", - label: - "Household Size", + label: "Household Size", name: "household_size", props: { - placeholder: - "enter size", - className: - "w-[300px]", + placeholder: "enter size", + className: "w-[300px]", }, rules: { pattern: { - value: - /^[0-9]\d*$/, + value: /^[0-9]\d*$/, message: "Must be a positive integer value", }, - required: - "* Required", + required: "* Required", }, }, { rhf: "Input", name: "standard", - label: - "Standard ($)", + label: "Standard ($)", props: { - className: - "w-[200px]", - placeholder: - "enter amount", + className: "w-[200px]", + placeholder: "enter amount", icon: "$", }, rules: { pattern: { - value: - /^\d*(?:\.\d{1,2})?$/, + value: /^\d*(?:\.\d{1,2})?$/, message: "Must be all numbers, no commas. e.g. 1234.56", }, - required: - "* Required", + required: "* Required", }, }, ], @@ -893,15 +819,13 @@ export const v202401: FormSchema = { icon: "$", }, rules: { - pattern: - { - value: - /^\d*(?:\.\d{1,2})?$/, - message: - "Must be all numbers, no commas. e.g. 1234.56", - }, - required: - "* Required", + pattern: { + value: + /^\d*(?:\.\d{1,2})?$/, + message: + "Must be all numbers, no commas. e.g. 1234.56", + }, + required: "* Required", }, }, ], @@ -918,8 +842,7 @@ export const v202401: FormSchema = { ], }, { - label: - "Standard varies in some other way", + label: "Standard varies in some other way", value: "other_standard", form: [ @@ -930,10 +853,8 @@ export const v202401: FormSchema = { name: "income_definition_specific_statewide_group_other", props: { ...DefaultFieldGroupProps, - appendText: - "Add some other way", - removeText: - "Remove some other way", + appendText: "Add some other way", + removeText: "Remove some other way", }, fields: [ { @@ -941,11 +862,9 @@ export const v202401: FormSchema = { name: "name_of_group", label: "Name", rules: { - required: - "* Required", + required: "* Required", pattern: { - value: - /^\S(.*\S)?$/, + value: /^\S(.*\S)?$/, message: "Must not have leading or trailing whitespace.", }, @@ -956,11 +875,9 @@ export const v202401: FormSchema = { name: "group_description", label: "Description", rules: { - required: - "* Required", + required: "* Required", pattern: { - value: - noLeadingTrailingWhitespace, + value: noLeadingTrailingWhitespace, message: "Must not have leading or trailing whitespace.", }, @@ -970,53 +887,42 @@ export const v202401: FormSchema = { rhf: "FieldArray", name: "income_definition_specific_statewide_arr", props: { - appendText: - "Add household size", + appendText: "Add household size", }, fields: [ { rhf: "Input", - label: - "Household Size", + label: "Household Size", name: "household_size", props: { - placeholder: - "enter size", - className: - "w-[300px]", + placeholder: "enter size", + className: "w-[300px]", }, rules: { pattern: { - value: - /^[0-9]\d*$/, + value: /^[0-9]\d*$/, message: "Must be a positive integer value", }, - required: - "* Required", + required: "* Required", }, }, { rhf: "Input", name: "standard", - label: - "Standard ($)", + label: "Standard ($)", props: { - className: - "w-[200px]", - placeholder: - "enter amount", + className: "w-[200px]", + placeholder: "enter amount", icon: "$", }, rules: { pattern: { - value: - /^\d*(?:\.\d{1,2})?$/, + value: /^\d*(?:\.\d{1,2})?$/, message: "Must be all numbers, no commas. e.g. 1234.56", }, - required: - "* Required", + required: "* Required", }, }, ], @@ -1042,15 +948,13 @@ export const v202401: FormSchema = { icon: "$", }, rules: { - pattern: - { - value: - /^\d*(?:\.\d{1,2})?$/, - message: - "Must be all numbers, no commas. e.g. 1234.56", - }, - required: - "* Required", + pattern: { + value: + /^\d*(?:\.\d{1,2})?$/, + message: + "Must be all numbers, no commas. e.g. 1234.56", + }, + required: "* Required", }, }, ], @@ -1080,8 +984,7 @@ export const v202401: FormSchema = { }, { value: "health", - label: - "Disease, condition, diagnosis, or disorder (check all that apply)", + label: "Disease, condition, diagnosis, or disorder (check all that apply)", slots: [ { rhf: "Checkbox", @@ -1133,8 +1036,7 @@ export const v202401: FormSchema = { { label: "Asthma", value: "asthma" }, { label: "Obesity", value: "obesity" }, { - label: - "Other disease, condition, diagnosis, or disorder", + label: "Other disease, condition, diagnosis, or disorder", value: "other", slots: [ { @@ -1145,8 +1047,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -1169,8 +1070,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -1242,8 +1142,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -1265,8 +1164,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -1288,8 +1186,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -1311,8 +1208,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, diff --git a/lib/libs/webforms/ABP1/v202402.ts b/lib/libs/webforms/ABP1/v202402.ts index 470f051824..795aff1471 100644 --- a/lib/libs/webforms/ABP1/v202402.ts +++ b/lib/libs/webforms/ABP1/v202402.ts @@ -57,15 +57,13 @@ export const v202402: FormSchema = { value: "adult", }, { - label: - "Aged, blind, and disabled individuals in 209(b) states", + label: "Aged, blind, and disabled individuals in 209(b) states", value: "aged_blind_disabled_individuals_209b_states", }, { label: "Aged, blind, or disabled individuals eligible for but not receiving cash", - value: - "aged_blind_disabled_eligible_but_not_receiving_cash", + value: "aged_blind_disabled_eligible_but_not_receiving_cash", }, { label: "Blind or disabled individuals eligible in 1937", @@ -74,8 +72,7 @@ export const v202402: FormSchema = { { label: "Certain individuals needing treatment for breast or cervical cancer", - value: - "individuals_need_treatment_for_breasts_cervical_cancer", + value: "individuals_need_treatment_for_breasts_cervical_cancer", }, { label: "Children with non-IV-E adoption assistance", @@ -84,8 +81,7 @@ export const v202402: FormSchema = { { label: "Children with Title IV-E adoption assistance, foster care, or guardianship care", - value: - "children_title_IV-E_adoption_assist_foster_guardianship_care", + value: "children_title_IV-E_adoption_assist_foster_guardianship_care", }, { label: "Deemed newborns", @@ -104,17 +100,14 @@ export const v202402: FormSchema = { { label: "Disabled widows and widowers ineligible for SSI due to increase in OASDI", - value: - "disabled_widows_ineligible_SSI_due_to_increase_OASDI", + value: "disabled_widows_ineligible_SSI_due_to_increase_OASDI", }, { - label: - "Extended Medicaid due to spousal support collections", + label: "Extended Medicaid due to spousal support collections", value: "extend_medicaid_spousal_support_collect", }, { - label: - "Family Opportunity Act children with disabilities", + label: "Family Opportunity Act children with disabilities", value: "family_opportunity_act_children_disabilities", }, { @@ -126,31 +119,26 @@ export const v202402: FormSchema = { value: "independent_foster_care_adolescents", }, { - label: - "Individuals eligible for cash except for institutionalization", + label: "Individuals eligible for cash except for institutionalization", value: "eligible_cash_except_for_institutionalization", }, { label: "Individuals eligible for SSI/SSP but for OASDI COLA increases since April 1977", - value: - "eligible_SSI_SSP_but_for_OASDI_COLA_increases_April_1977", + value: "eligible_SSI_SSP_but_for_OASDI_COLA_increases_April_1977", }, { label: "Individuals receiving home and community-based services under institutional rules", - value: - "receiving_home_community_services_under_inst_rule", + value: "receiving_home_community_services_under_inst_rule", }, { label: "Individuals receiving hospice care", value: "hospice_care", }, { - label: - "Individuals receiving mandatory state supplements", - value: - "individuals_receiving_mandatory_state_supplements", + label: "Individuals receiving mandatory state supplements", + value: "individuals_receiving_mandatory_state_supplements", }, { label: "Individuals who are essential spouses", @@ -159,8 +147,7 @@ export const v202402: FormSchema = { { label: "Individuals who lost eligibility for SSI/SSP due to an increase in OASDI benefits in 1972", - value: - "lost_eligibility_SSI_SSP_increase_in_OASDI_benefits_1972", + value: "lost_eligibility_SSI_SSP_increase_in_OASDI_benefits_1972", }, { label: "Individuals with tuberculosis", @@ -171,8 +158,7 @@ export const v202402: FormSchema = { value: "infants_children_under_19", }, { - label: - "Institutionalized individuals continuously eligible since 1973", + label: "Institutionalized individuals continuously eligible since 1973", value: "institutionalized_eligible_1973", }, { @@ -185,10 +171,8 @@ export const v202402: FormSchema = { value: "med_needy_aged_blind_disabled", }, { - label: - "Medically needy blind or disabled individuals eligible in 1973", - value: - "med_needy_aged_blind_disabled_individuals_eligible_in_1973", + label: "Medically needy blind or disabled individuals eligible in 1973", + value: "med_needy_aged_blind_disabled_individuals_eligible_in_1973", }, { label: "Medically needy children age 18 through 20", @@ -207,15 +191,13 @@ export const v202402: FormSchema = { value: "med_needy_pregnant_women", }, { - label: - "Optional coverage of parents and other caretaker relatives", + label: "Optional coverage of parents and other caretaker relatives", value: "opt_coverage_parents_other_caretaker_relatives", }, { label: "Optional state supplement - 1634 states and SSI criteria states with 1616 agreements", - value: - "opt_state_supp_1634_states_SSI_criteria_states_1616_agreements", + value: "opt_state_supp_1634_states_SSI_criteria_states_1616_agreements", }, { label: @@ -244,8 +226,7 @@ export const v202402: FormSchema = { value: "qualified_disabled_children_under_19", }, { - label: - "Reasonable classifications of individuals under age 21", + label: "Reasonable classifications of individuals under age 21", value: "reasonable_class_under_21", }, { @@ -302,8 +283,7 @@ export const v202402: FormSchema = { ], }, { - description: - "Is enrollment available for all individuals in these eligibility groups?", + description: "Is enrollment available for all individuals in these eligibility groups?", slots: [ { rhf: "Select", @@ -364,13 +344,11 @@ export const v202402: FormSchema = { props: { options: [ { - label: - "Households with income at or below the standard", + label: "Households with income at or below the standard", value: "income_target_below", }, { - label: - "Households with income above the standard", + label: "Households with income above the standard", value: "income_target_above", }, ], @@ -415,14 +393,12 @@ export const v202402: FormSchema = { rules: { pattern: { value: /^\d*\.?\d+$/, - message: - "Must be a positive percentage", + message: "Must be a positive percentage", }, required: "* Required", }, name: "fed-poverty-level-percent", - label: - "Percentage of federal poverty level", + label: "Percentage of federal poverty level", labelClassName: "font-bold", }, ], @@ -434,8 +410,7 @@ export const v202402: FormSchema = { { rhf: "Input", name: "ssi-fed-benefit-percentage", - label: - "Percentage of SSI federal benefit", + label: "Percentage of SSI federal benefit", labelClassName: "font-bold", props: { icon: "%", @@ -445,8 +420,7 @@ export const v202402: FormSchema = { rules: { pattern: { value: /^\d*\.?\d+$/, - message: - "Must be a positive percentage", + message: "Must be a positive percentage", }, required: "* Required", }, @@ -470,8 +444,7 @@ export const v202402: FormSchema = { rules: { pattern: { value: /^\d*\.?\d+$/, - message: - "Must be a positive percentage", + message: "Must be a positive percentage", }, required: "* Required", }, @@ -484,8 +457,7 @@ export const v202402: FormSchema = { rules: { required: "* Required", pattern: { - value: - noLeadingTrailingWhitespace, + value: noLeadingTrailingWhitespace, message: "Must not have leading or trailing whitespace.", }, @@ -520,19 +492,16 @@ export const v202402: FormSchema = { rhf: "FieldArray", name: "income-def-specific-state", props: { - appendText: - "Add standard", + appendText: "Add standard", }, fields: [ { rhf: "Input", label: "Household size", name: "house-size", - labelClassName: - "font-bold", + labelClassName: "font-bold", props: { - className: - "w-[150px]", + className: "w-[150px]", }, rules: { pattern: { @@ -540,30 +509,25 @@ export const v202402: FormSchema = { message: "Must be a positive integer value", }, - required: - "* Required", + required: "* Required", }, }, { rhf: "Input", name: "standard", label: "Standard", - labelClassName: - "font-bold", + labelClassName: "font-bold", props: { - className: - "w-[200px]", + className: "w-[200px]", icon: "$", }, rules: { pattern: { - value: - /^\d*(?:\.\d{1,2})?$/, + value: /^\d*(?:\.\d{1,2})?$/, message: "Must be a positive number, maximum of two decimals, no commas. e.g. 1234.56", }, - required: - "* Required", + required: "* Required", }, }, ], @@ -573,8 +537,7 @@ export const v202402: FormSchema = { name: "is-increment-amount", label: "Is there an additional incremental amount?", - labelClassName: - "font-bold", + labelClassName: "font-bold", horizontalLayout: true, props: { @@ -613,8 +576,7 @@ export const v202402: FormSchema = { }, rules: { pattern: { - value: - /^\d*(?:\.\d{1,2})?$/, + value: /^\d*(?:\.\d{1,2})?$/, message: "Must be all numbers, no commas. e.g. 1234.56", }, @@ -637,22 +599,18 @@ export const v202402: FormSchema = { props: { ...DefaultFieldGroupProps, appendText: "Add region", - removeText: - "Remove region", + removeText: "Remove region", }, fields: [ { rhf: "Input", name: "name-of-region", label: "Region name", - labelClassName: - "font-bold", + labelClassName: "font-bold", rules: { - required: - "* Required", + required: "* Required", pattern: { - value: - /^\S(.*\S)?$/, + value: /^\S(.*\S)?$/, message: "Must not have leading or trailing whitespace.", }, @@ -662,14 +620,11 @@ export const v202402: FormSchema = { rhf: "Textarea", name: "region-descript", label: "Describe", - labelClassName: - "font-bold", + labelClassName: "font-bold", rules: { - required: - "* Required", + required: "* Required", pattern: { - value: - noLeadingTrailingWhitespace, + value: noLeadingTrailingWhitespace, message: "Must not have leading or trailing whitespace.", }, @@ -679,52 +634,42 @@ export const v202402: FormSchema = { rhf: "FieldArray", name: "add-house-size", props: { - appendText: - "Add household size", + appendText: "Add household size", }, fields: [ { rhf: "Input", - label: - "Household size", - labelClassName: - "font-bold", + label: "Household size", + labelClassName: "font-bold", name: "house-size", props: { - className: - "w-[150px]", + className: "w-[150px]", }, rules: { pattern: { - value: - /^[0-9]\d*$/, + value: /^[0-9]\d*$/, message: "Must be a positive integer value", }, - required: - "* Required", + required: "* Required", }, }, { rhf: "Input", name: "standard", label: "Standard", - labelClassName: - "font-bold", + labelClassName: "font-bold", props: { - className: - "w-[200px]", + className: "w-[200px]", icon: "$", }, rules: { pattern: { - value: - /^\d*(?:\.\d{1,2})?$/, + value: /^\d*(?:\.\d{1,2})?$/, message: "Must be all numbers, no commas. e.g. 1234.56", }, - required: - "* Required", + required: "* Required", }, }, ], @@ -734,8 +679,7 @@ export const v202402: FormSchema = { name: "is-increment-amount", label: "Is there an additional incremental amount?", - labelClassName: - "font-bold", + labelClassName: "font-bold", horizontalLayout: true, props: { @@ -753,23 +697,19 @@ export const v202402: FormSchema = { }, { rhf: "Input", - label: - "Incremental amount", + label: "Incremental amount", name: "increment-amount", - labelClassName: - "font-bold", + labelClassName: "font-bold", props: { icon: "$", - className: - "w-[200px]", + className: "w-[200px]", }, dependency: { conditions: [ { name: "is-increment-amount", type: "expectedValue", - expectedValue: - "yes", + expectedValue: "yes", }, ], effect: { @@ -778,13 +718,11 @@ export const v202402: FormSchema = { }, rules: { pattern: { - value: - /^\d*(?:\.\d{1,2})?$/, + value: /^\d*(?:\.\d{1,2})?$/, message: "Must be all numbers, no commas. e.g. 1234.56", }, - required: - "* Required", + required: "* Required", }, }, ], @@ -794,8 +732,7 @@ export const v202402: FormSchema = { ], }, { - label: - "Standard varies by living arrangement", + label: "Standard varies by living arrangement", value: "living_standard", form: [ @@ -806,25 +743,19 @@ export const v202402: FormSchema = { name: "liv-arrange", props: { ...DefaultFieldGroupProps, - appendText: - "Add living arrangement", - removeText: - "Remove living arrangement", + appendText: "Add living arrangement", + removeText: "Remove living arrangement", }, fields: [ { rhf: "Input", name: "name-of-liv-arrange", - label: - "Name of living arrangement", - labelClassName: - "font-bold", + label: "Name of living arrangement", + labelClassName: "font-bold", rules: { - required: - "* Required", + required: "* Required", pattern: { - value: - /^\S(.*\S)?$/, + value: /^\S(.*\S)?$/, message: "Must not have leading or trailing whitespace.", }, @@ -834,14 +765,11 @@ export const v202402: FormSchema = { rhf: "Textarea", name: "liv-arrange-descript", label: "Describe", - labelClassName: - "font-bold", + labelClassName: "font-bold", rules: { - required: - "* Required", + required: "* Required", pattern: { - value: - noLeadingTrailingWhitespace, + value: noLeadingTrailingWhitespace, message: "Must not have leading or trailing whitespace.", }, @@ -851,52 +779,42 @@ export const v202402: FormSchema = { rhf: "FieldArray", name: "add-house-size", props: { - appendText: - "Add household size", + appendText: "Add household size", }, fields: [ { rhf: "Input", - label: - "Household size", - labelClassName: - "font-bold", + label: "Household size", + labelClassName: "font-bold", name: "house-size", props: { - className: - "w-[150px]", + className: "w-[150px]", }, rules: { pattern: { - value: - /^[0-9]\d*$/, + value: /^[0-9]\d*$/, message: "Must be a positive integer value", }, - required: - "* Required", + required: "* Required", }, }, { rhf: "Input", name: "standard", label: "Standard", - labelClassName: - "font-bold", + labelClassName: "font-bold", props: { - className: - "w-[200px]", + className: "w-[200px]", icon: "$", }, rules: { pattern: { - value: - /^\d*(?:\.\d{1,2})?$/, + value: /^\d*(?:\.\d{1,2})?$/, message: "Must be all numbers, no commas. e.g. 1234.56", }, - required: - "* Required", + required: "* Required", }, }, ], @@ -906,8 +824,7 @@ export const v202402: FormSchema = { name: "is-increment-amount", label: "Is there an additional incremental amount?", - labelClassName: - "font-bold", + labelClassName: "font-bold", horizontalLayout: true, props: { @@ -926,23 +843,19 @@ export const v202402: FormSchema = { { rhf: "Input", - label: - "Incremental amount", + label: "Incremental amount", name: "increment-amount", - labelClassName: - "font-bold", + labelClassName: "font-bold", props: { icon: "$", - className: - "w-[200px]", + className: "w-[200px]", }, dependency: { conditions: [ { name: "is-increment-amount", type: "expectedValue", - expectedValue: - "yes", + expectedValue: "yes", }, ], effect: { @@ -951,13 +864,11 @@ export const v202402: FormSchema = { }, rules: { pattern: { - value: - /^\d*(?:\.\d{1,2})?$/, + value: /^\d*(?:\.\d{1,2})?$/, message: "Must be all numbers, no commas. e.g. 1234.56", }, - required: - "* Required", + required: "* Required", }, }, ], @@ -967,8 +878,7 @@ export const v202402: FormSchema = { ], }, { - label: - "Standard varies in some other way", + label: "Standard varies in some other way", value: "other_standard", form: [ @@ -979,24 +889,19 @@ export const v202402: FormSchema = { name: "add-other-way", props: { ...DefaultFieldGroupProps, - appendText: - "Add other way", - removeText: - "Remove other way", + appendText: "Add other way", + removeText: "Remove other way", }, fields: [ { rhf: "Input", name: "name-of-group", label: "Name", - labelClassName: - "font-bold", + labelClassName: "font-bold", rules: { - required: - "* Required", + required: "* Required", pattern: { - value: - /^\S(.*\S)?$/, + value: /^\S(.*\S)?$/, message: "Must not have leading or trailing whitespace.", }, @@ -1006,14 +911,11 @@ export const v202402: FormSchema = { rhf: "Textarea", name: "group-descript", label: "Describe", - labelClassName: - "font-bold", + labelClassName: "font-bold", rules: { - required: - "* Required", + required: "* Required", pattern: { - value: - noLeadingTrailingWhitespace, + value: noLeadingTrailingWhitespace, message: "Must not have leading or trailing whitespace.", }, @@ -1023,52 +925,42 @@ export const v202402: FormSchema = { rhf: "FieldArray", name: "add-house-size", props: { - appendText: - "Add household size", + appendText: "Add household size", }, fields: [ { rhf: "Input", - label: - "Household size", + label: "Household size", name: "house-size", - labelClassName: - "font-bold", + labelClassName: "font-bold", props: { - className: - "w-[150px]", + className: "w-[150px]", }, rules: { pattern: { - value: - /^[0-9]\d*$/, + value: /^[0-9]\d*$/, message: "Must be a positive integer value", }, - required: - "* Required", + required: "* Required", }, }, { rhf: "Input", name: "standard", label: "Standard", - labelClassName: - "font-bold", + labelClassName: "font-bold", props: { - className: - "w-[200px]", + className: "w-[200px]", icon: "$", }, rules: { pattern: { - value: - /^\d*(?:\.\d{1,2})?$/, + value: /^\d*(?:\.\d{1,2})?$/, message: "Must be all numbers, no commas. e.g. 1234.56", }, - required: - "* Required", + required: "* Required", }, }, ], @@ -1078,8 +970,7 @@ export const v202402: FormSchema = { name: "is-increment-amount", label: "Is there an additional incremental amount?", - labelClassName: - "font-bold", + labelClassName: "font-bold", horizontalLayout: true, props: { @@ -1097,23 +988,19 @@ export const v202402: FormSchema = { }, { rhf: "Input", - label: - "Incremental amount", + label: "Incremental amount", name: "increment-amount", - labelClassName: - "font-bold", + labelClassName: "font-bold", props: { icon: "$", - className: - "w-[200px]", + className: "w-[200px]", }, dependency: { conditions: [ { name: "is-increment-amount", type: "expectedValue", - expectedValue: - "yes", + expectedValue: "yes", }, ], effect: { @@ -1122,13 +1009,11 @@ export const v202402: FormSchema = { }, rules: { pattern: { - value: - /^\d*(?:\.\d{1,2})?$/, + value: /^\d*(?:\.\d{1,2})?$/, message: "Must be all numbers, no commas. e.g. 1234.56", }, - required: - "* Required", + required: "* Required", }, }, ], @@ -1203,8 +1088,7 @@ export const v202402: FormSchema = { { label: "Asthma", value: "asthma" }, { label: "Obesity", value: "obesity" }, { - label: - "Other disease, condition, diagnosis, or disorder", + label: "Other disease, condition, diagnosis, or disorder", value: "other", slots: [ { @@ -1216,8 +1100,7 @@ export const v202402: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -1241,8 +1124,7 @@ export const v202402: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -1260,8 +1142,7 @@ export const v202402: FormSchema = { sectionId: "geo-area", form: [ { - description: - "Will this benefit package be available to the entire state/territory?", + description: "Will this benefit package be available to the entire state/territory?", slots: [ { rhf: "Select", @@ -1314,8 +1195,7 @@ export const v202402: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -1337,8 +1217,7 @@ export const v202402: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -1360,8 +1239,7 @@ export const v202402: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -1383,8 +1261,7 @@ export const v202402: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, diff --git a/lib/libs/webforms/ABP10/v202401.ts b/lib/libs/webforms/ABP10/v202401.ts index 6804214e3c..f7c4b066a6 100644 --- a/lib/libs/webforms/ABP10/v202401.ts +++ b/lib/libs/webforms/ABP10/v202401.ts @@ -48,8 +48,7 @@ export const v202401: FormSchema = { label: "Describe the approach", labelClassName: "font-bold", name: "approach-description", - formItemClassName: - "ml-[0.6rem] px-4 my-2 border-l-4 border-l-primary", + formItemClassName: "ml-[0.6rem] px-4 my-2 border-l-4 border-l-primary", rules: { required: "* Required", pattern: { @@ -97,8 +96,7 @@ export const v202401: FormSchema = { { label: "The state or territory assures that all providers of Alternative Benefit Plan benefits shall meet the provider qualification requirements of the base benchmark plan and/or the Medicaid state plan.", - value: - "providers_of_alternative_benefit_plan_meets_provider_qualifications", + value: "providers_of_alternative_benefit_plan_meets_provider_qualifications", }, ], }, diff --git a/lib/libs/webforms/ABP2A/v202401.ts b/lib/libs/webforms/ABP2A/v202401.ts index e941a55fba..02cfe564b4 100644 --- a/lib/libs/webforms/ABP2A/v202401.ts +++ b/lib/libs/webforms/ABP2A/v202401.ts @@ -39,8 +39,7 @@ export const v202401: FormSchema = { { rhf: "Textarea", name: "explain-how-state-territory-aligned", - description: - "Explain how the state has fully aligned its benefits.", + description: "Explain how the state has fully aligned its benefits.", descriptionAbove: true, descriptionClassName: "font-bold text-black", rules: { @@ -97,8 +96,7 @@ export const v202401: FormSchema = { { label: "The state/territory must have a process in place to identify individuals that meet the exemption criteria, and the state/territory must comply with requirements related to providing the option of enrollment in an ABP defined using Section 1937 requirements or an ABP defined as the state/territory's approved Medicaid state plan not subject to Section 1937 requirements.", - value: - "state_territory_must_have_a_process_that_meets_exemption_criteria", + value: "state_territory_must_have_a_process_that_meets_exemption_criteria", }, { styledLabel: [ @@ -143,8 +141,7 @@ export const v202401: FormSchema = { classname: "block py-1", }, ], - value: - "state_territory_assures_it_will_inform_the_individual", + value: "state_territory_assures_it_will_inform_the_individual", }, ], }, @@ -198,8 +195,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -211,8 +207,7 @@ export const v202401: FormSchema = { { rhf: "Upload", name: "provide-copy_upload", - description: - "Provide a copy of the letter, email, or other communication.", + description: "Provide a copy of the letter, email, or other communication.", descriptionAbove: true, descriptionClassName: "font-bold text-black", rules: { @@ -224,8 +219,7 @@ export const v202401: FormSchema = { rhf: "Input", name: "when-to-inform", descriptionAbove: true, - description: - "When did/will the state/territory inform the individuals?", + description: "When did/will the state/territory inform the individuals?", rules: { required: "* Required", pattern: { @@ -280,8 +274,7 @@ export const v202401: FormSchema = { text: "C. Chose to enroll in ABP coverage subject to Section 1937 requirements or defined as the state/territory's approved Medicaid state plan not subject to Section 1937 requirements", }, ], - value: - "state_territory_will_document_exempt_individuals_eligibility", + value: "state_territory_will_document_exempt_individuals_eligibility", }, ], }, @@ -318,8 +311,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -333,8 +325,7 @@ export const v202401: FormSchema = { name: "what-docu-will-be-maintained", descriptionAbove: true, descriptionClassName: "font-bold text-black", - description: - "What documentation will be maintained in the eligibility file?", + description: "What documentation will be maintained in the eligibility file?", formItemClassName: "pb-6 border-b-[1px] border-[#AEB0B5]", rules: { required: "* Required", @@ -348,13 +339,11 @@ export const v202401: FormSchema = { { label: "Signed documentation from the individual consenting to enrollment in the ABP", - value: - "signed_documentation_from_individual_consenting_enrollment_ABP", + value: "signed_documentation_from_individual_consenting_enrollment_ABP", }, { label: "Other", - value: - "what_documentation_will_be_maintained_in_the_eligibility_file_other", + value: "what_documentation_will_be_maintained_in_the_eligibility_file_other", slots: [ { rhf: "Textarea", @@ -365,8 +354,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, diff --git a/lib/libs/webforms/ABP2B/v202401.ts b/lib/libs/webforms/ABP2B/v202401.ts index 068496928b..afa42bd6de 100644 --- a/lib/libs/webforms/ABP2B/v202401.ts +++ b/lib/libs/webforms/ABP2B/v202401.ts @@ -61,8 +61,7 @@ export const v202401: FormSchema = { classname: "block pt-1", }, ], - value: - "effectively_inform_voluntarily_enroll_and_may_disenroll", + value: "effectively_inform_voluntarily_enroll_and_may_disenroll", }, { styledLabel: [ @@ -82,8 +81,7 @@ export const v202401: FormSchema = { classname: "block pt-1", }, ], - value: - "inform_individuals_of_abp_benefits_and_costs_of_different_packages", + value: "inform_individuals_of_abp_benefits_and_costs_of_different_packages", }, ], }, @@ -127,8 +125,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -140,8 +137,7 @@ export const v202401: FormSchema = { { rhf: "Upload", name: "provide-copy", - description: - "Provide a copy of the letter, email, or other communication.", + description: "Provide a copy of the letter, email, or other communication.", descriptionAbove: true, descriptionClassName: "font-bold text-black", rules: { @@ -153,8 +149,7 @@ export const v202401: FormSchema = { rhf: "Input", name: "when-to-inform", descriptionAbove: true, - description: - "When did/will the state/territory inform the individuals?", + description: "When did/will the state/territory inform the individuals?", rules: { required: "* Required", pattern: { @@ -209,8 +204,7 @@ export const v202401: FormSchema = { text: " C. Chose to enroll in ABP coverage subject to Section 1937 requirements or defined as the state/territory's approved Medicaid state plan not subject to Section 1937 requirements", }, ], - value: - "state_territory_will_document_exempt_individuals_eligibility", + value: "state_territory_will_document_exempt_individuals_eligibility", }, ], }, @@ -247,8 +241,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -262,8 +255,7 @@ export const v202401: FormSchema = { name: "what-docu-will-be-maintained", descriptionAbove: true, descriptionClassName: "font-bold text-black", - description: - "What documentation will be maintained in the eligibility file?", + description: "What documentation will be maintained in the eligibility file?", formItemClassName: "pb-6 border-b-[1px] border-[#AEB0B5]", rules: { required: "* Required", @@ -277,13 +269,11 @@ export const v202401: FormSchema = { { label: "Signed documentation from the individual consenting to enrollment in the ABP", - value: - "signed_documentation_from_individual_consenting_enrollment_ABP", + value: "signed_documentation_from_individual_consenting_enrollment_ABP", }, { label: "Other", - value: - "what_documentation_will_be_maintained_in_the_eligibility_file_other", + value: "what_documentation_will_be_maintained_in_the_eligibility_file_other", slots: [ { rhf: "Textarea", @@ -294,8 +284,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, diff --git a/lib/libs/webforms/ABP2C/v202401.ts b/lib/libs/webforms/ABP2C/v202401.ts index c1bd304b2b..48840b5e11 100644 --- a/lib/libs/webforms/ABP2C/v202401.ts +++ b/lib/libs/webforms/ABP2C/v202401.ts @@ -69,8 +69,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -89,8 +88,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -109,8 +107,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -162,8 +159,7 @@ export const v202401: FormSchema = { { name: "how-id-become-exempt", rhf: "Checkbox", - label: - "How will the state/territory identify if an individual becomes exempt?", + label: "How will the state/territory identify if an individual becomes exempt?", labelClassName: "font-bold text-black", rules: { required: "* Required" }, props: { @@ -201,8 +197,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -249,8 +244,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, diff --git a/lib/libs/webforms/ABP3/v202401.ts b/lib/libs/webforms/ABP3/v202401.ts index 09a7c505e9..ed0f380888 100644 --- a/lib/libs/webforms/ABP3/v202401.ts +++ b/lib/libs/webforms/ABP3/v202401.ts @@ -2,8 +2,7 @@ import { FormSchema } from "shared-types"; import { noLeadingTrailingWhitespace } from "shared-utils/regex"; export const v202401: FormSchema = { - header: - "ABP 3: Selection of benchmark or benchmark-equivalent benefit package", + header: "ABP 3: Selection of benchmark or benchmark-equivalent benefit package", formId: "abp3", sections: [ { @@ -11,8 +10,7 @@ export const v202401: FormSchema = { sectionId: "benefit-package", form: [ { - description: - "For the population defined in section 1, the state/territory wants to:", + description: "For the population defined in section 1, the state/territory wants to:", slots: [ { rhf: "Radio", @@ -168,22 +166,19 @@ export const v202401: FormSchema = { rhf: "Radio", name: "approved-state-plan-opts", rules: { - required: - "* Required", + required: "* Required", }, props: { options: [ { label: "Benefits provided in the approved state plan", - value: - "approved_state_plan", + value: "approved_state_plan", }, { label: "All benefits provided in the approved state plan plus additional benefits", - value: - "additional_benefits", + value: "additional_benefits", }, { label: @@ -194,8 +189,7 @@ export const v202401: FormSchema = { { label: "A partial list of benefits provided in the approved state plan", - value: - "partial_list_of_benefits", + value: "partial_list_of_benefits", }, { label: @@ -227,8 +221,7 @@ export const v202401: FormSchema = { rules: { required: "* Required", pattern: { - value: - noLeadingTrailingWhitespace, + value: noLeadingTrailingWhitespace, message: "Must not have leading or trailing whitespace.", }, @@ -351,8 +344,7 @@ export const v202401: FormSchema = { slots: [ { rhf: "Select", - label: - "Is the base benchmark plan the same as the Section 1937 coverage option?", + label: "Is the base benchmark plan the same as the Section 1937 coverage option?", labelClassName: "font-bold", name: "same-as-sect-1937", rules: { required: "* Required" }, diff --git a/lib/libs/webforms/ABP3_1/v202401.ts b/lib/libs/webforms/ABP3_1/v202401.ts index fb730e2502..28bf45194a 100644 --- a/lib/libs/webforms/ABP3_1/v202401.ts +++ b/lib/libs/webforms/ABP3_1/v202401.ts @@ -2,8 +2,7 @@ import { FormSchema } from "shared-types"; import { noLeadingTrailingWhitespace } from "shared-utils/regex"; export const v202401: FormSchema = { - header: - "ABP 3.1 Selection of benchmark or benchmark-equivalent benefit package", + header: "ABP 3.1 Selection of benchmark or benchmark-equivalent benefit package", formId: "abp3-1", sections: [ { @@ -11,8 +10,7 @@ export const v202401: FormSchema = { sectionId: "benefit-package-details", form: [ { - description: - "For the population defined in Section 1, the state/territory wants to:", + description: "For the population defined in Section 1, the state/territory wants to:", slots: [ { rhf: "Radio", @@ -108,8 +106,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: /^\S(.*\S)?$/, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -132,8 +129,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: /^\S(.*\S)?$/, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -174,8 +170,7 @@ export const v202401: FormSchema = { { label: "Benefits provided in the approved state plan plus additional benefits", - value: - "additional_benefits", + value: "additional_benefits", }, { label: @@ -186,8 +181,7 @@ export const v202401: FormSchema = { { label: "A partial list of benefits provided in the approved state plan", - value: - "partial_list", + value: "partial_list", }, { label: @@ -198,8 +192,7 @@ export const v202401: FormSchema = { ], }, rules: { - required: - "* Required", + required: "* Required", }, }, ], @@ -226,8 +219,7 @@ export const v202401: FormSchema = { rules: { required: "* Required", pattern: { - value: - noLeadingTrailingWhitespace, + value: noLeadingTrailingWhitespace, message: "Must not have leading or trailing whitespace.", }, @@ -280,8 +272,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: /^\S(.*\S)?$/, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -304,8 +295,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: /^\S(.*\S)?$/, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -360,8 +350,7 @@ export const v202401: FormSchema = { { name: "is-ehb-bench-plan-same-section-1937", rhf: "Select", - label: - "Is the EHB-benchmark plan the same as the Section 1937 coverage option?", + label: "Is the EHB-benchmark plan the same as the Section 1937 coverage option?", labelClassName: "font-bold", rules: { required: "* Required", @@ -541,8 +530,7 @@ export const v202401: FormSchema = { value: "largest_three_state_FEHBP_plans", }, { - label: - "The largest insured commercial, non-Medicaid HMO", + label: "The largest insured commercial, non-Medicaid HMO", value: "larged_insured_commercial", }, ], @@ -585,8 +573,7 @@ export const v202401: FormSchema = { value: "largest_three_state_FEHBP_plans", }, { - label: - "The largest insured commercial, non-Medicaid HMO", + label: "The largest insured commercial, non-Medicaid HMO", value: "larged_insured_commercial", }, ], @@ -1063,10 +1050,8 @@ export const v202401: FormSchema = { ], }, { - label: - "Mental health and substance use disorders", - value: - "mental_health_and_substance_use_disorders", + label: "Mental health and substance use disorders", + value: "mental_health_and_substance_use_disorders", slots: [ { rhf: "Select", @@ -1297,10 +1282,8 @@ export const v202401: FormSchema = { ], }, { - label: - "Rehabilitative and habilitative services and devices", - value: - "rehabilitative_and_habilitative_services_and_devices", + label: "Rehabilitative and habilitative services and devices", + value: "rehabilitative_and_habilitative_services_and_devices", slots: [ { rhf: "Select", @@ -1649,10 +1632,8 @@ export const v202401: FormSchema = { ], }, { - label: - "Pediatric services, including oral and vision care", - value: - "pediatric_services_including_oral_and_vision_care", + label: "Pediatric services, including oral and vision care", + value: "pediatric_services_including_oral_and_vision_care", slots: [ { rhf: "Select", diff --git a/lib/libs/webforms/ABP4/v202401.ts b/lib/libs/webforms/ABP4/v202401.ts index f810654b46..feb2fd5e42 100644 --- a/lib/libs/webforms/ABP4/v202401.ts +++ b/lib/libs/webforms/ABP4/v202401.ts @@ -46,8 +46,7 @@ export const v202401: FormSchema = { rhf: "WrappedGroup", name: "wrapped", props: { - wrapperClassName: - "ml-[0.6rem] px-4 border-l-4 border-l-primary pb-6", + wrapperClassName: "ml-[0.6rem] px-4 border-l-4 border-l-primary pb-6", }, dependency: { conditions: [ @@ -67,8 +66,7 @@ export const v202401: FormSchema = { props: { options: [ { - label: - "See approved Attachment 4.18-F or G for description.", + label: "See approved Attachment 4.18-F or G for description.", value: "true", }, ], @@ -86,8 +84,7 @@ export const v202401: FormSchema = { { rhf: "Textarea", name: "other-info-about-requirements", - label: - "Other information about cost-sharing requirements (optional)", + label: "Other information about cost-sharing requirements (optional)", labelClassName: "font-bold", rules: { pattern: { diff --git a/lib/libs/webforms/ABP5/v202401.ts b/lib/libs/webforms/ABP5/v202401.ts index 5f655fc0e0..08e9e5d399 100644 --- a/lib/libs/webforms/ABP5/v202401.ts +++ b/lib/libs/webforms/ABP5/v202401.ts @@ -151,8 +151,7 @@ function subsectionFormFields({ }, { rhf: "Input", - label: - "Other information about this benefit source, including the name of the source plan", + label: "Other information about this benefit source, including the name of the source plan", labelClassName: "font-bold", name: "source-other-info_input", formItemClassName: "ml-[0.6rem] px-4 my-2 border-l-4 border-l-primary", @@ -176,8 +175,7 @@ function subsectionFormFields({ }, { rhf: "Input", - label: - "Other information about this benefit source, including the name of the source plan", + label: "Other information about this benefit source, including the name of the source plan", labelClassName: "font-bold", name: "secretary-other-info_input", formItemClassName: "ml-[0.6rem] px-4 my-2 border-l-4 border-l-primary", @@ -357,8 +355,7 @@ function subsection({ ? ([ { rhf: "Radio", - label: - "Is there an EHB-benchmark benefit duplicated or substituted?", + label: "Is there an EHB-benchmark benefit duplicated or substituted?", labelClassName: "font-bold", name: "benefit-dupe-or-sub", rules: { required: "* Required" }, @@ -379,8 +376,7 @@ function subsection({ required: "* Required", pattern: { value: /^\S(.*\S)?$/, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -403,8 +399,7 @@ function subsection({ required: "* Required", pattern: { value: /^\S(.*\S)?$/, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -449,8 +444,7 @@ export const v202401: FormSchema = { slots: [ { rhf: "Select", - label: - "Does this description of benefits align with the traditional state plan?", + label: "Does this description of benefits align with the traditional state plan?", labelClassName: "font-bold", name: "benefits-align", rules: { required: "* Required" }, @@ -475,8 +469,7 @@ export const v202401: FormSchema = { slots: [ { rhf: "Select", - label: - "Does the state/territory propose a benchmark-equivalent benefit package?", + label: "Does the state/territory propose a benchmark-equivalent benefit package?", labelClassName: "font-bold", name: "benchmark-equivalent-pkg", rules: { required: "* Required" }, @@ -676,8 +669,7 @@ export const v202401: FormSchema = { }, { rhf: "Input", - label: - "Coverage that exceeds the minimum requirements or other information", + label: "Coverage that exceeds the minimum requirements or other information", labelClassName: "font-bold", name: "other-info", rules: { @@ -690,8 +682,7 @@ export const v202401: FormSchema = { }, { rhf: "Radio", - label: - "Is there an EHB-benchmark benefit duplicated or substituted?", + label: "Is there an EHB-benchmark benefit duplicated or substituted?", labelClassName: "font-bold", name: "benefit-dup-or-sub", rules: { required: "* Required" }, @@ -712,8 +703,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: /^\S(.*\S)?$/, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -736,8 +726,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: /^\S(.*\S)?$/, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -754,8 +743,7 @@ export const v202401: FormSchema = { ], }, subsection({ - title: - "7. Essential health benefit: Rehabilitative and habilitative services and devices", + title: "7. Essential health benefit: Rehabilitative and habilitative services and devices", sectionName: "rehabilitative-and-habilitative", dependency: initialDependency, headerSlots: [ @@ -789,8 +777,7 @@ export const v202401: FormSchema = { "The state/territory must provide, at a minimum, a broad range of preventive services, including “A” and “B” services recommended by the United States Preventive Services Task Force; vaccines recommended by the Advisory Committee for Immunization Practices (ACIP); preventive care and screening for infants, children, and adults recommended by the Health Resources and Services Administration (HRSA) Bright Futures program; and additional preventive services for women recommended by the Institute of Medicine (IOM).", }), subsection({ - title: - "10. Essential health benefit: Pediatric services including oral and vision care", + title: "10. Essential health benefit: Pediatric services including oral and vision care", sectionName: "pediatric", dependency: initialDependency, benefitProvided: "Medicaid State Plan EPSDT Benefits", @@ -808,8 +795,7 @@ export const v202401: FormSchema = { props: { options: [ { - label: - "11. Other covered benefits that are not essential health benefits", + label: "11. Other covered benefits that are not essential health benefits", optionlabelClassName: "text-2xl font-bold p-4 bg-gray-300 py-4 px-8 w-full leading-9 text-primary", value: "other_covered_benefits_benefit", @@ -854,15 +840,13 @@ export const v202401: FormSchema = { fields: [ { rhf: "Input", - label: - "Base benchmark benefit that was substituted", + label: "Base benchmark benefit that was substituted", labelClassName: "font-bold", rules: { required: "* Required", pattern: { value: /^\S(.*\S)?$/, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, name: "benchmark-subbed", @@ -884,8 +868,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, diff --git a/lib/libs/webforms/ABP6/v202401.ts b/lib/libs/webforms/ABP6/v202401.ts index 81c153a4c5..12394a4adf 100644 --- a/lib/libs/webforms/ABP6/v202401.ts +++ b/lib/libs/webforms/ABP6/v202401.ts @@ -55,8 +55,7 @@ export const v202401: FormSchema = { { type: "greaterThanField", fieldName: "abp6_desc-of-ben_agg-actuarial-ben-plan", - message: - "Must be greater than or equal to value entered above.", + message: "Must be greater than or equal to value entered above.", }, ], }, @@ -82,8 +81,7 @@ export const v202401: FormSchema = { }, { value: "acturaial_report", - label: - "The state/territory has included a copy of the actuarial report.", + label: "The state/territory has included a copy of the actuarial report.", slots: [ { name: "actuarial-report", @@ -148,8 +146,7 @@ export const v202401: FormSchema = { }, { value: "standard_utilization_price_factors", - label: - "Using a standardized set of utilization and price factors", + label: "Using a standardized set of utilization and price factors", }, { value: "using_standard_representative_pop", @@ -186,8 +183,7 @@ export const v202401: FormSchema = { "The state/territory assures, as required by Section 1937(b)(2)(A) and 42 CFR 440.335, that benchmark-equivalent coverage shall include coverage for the following categories of services: inpatient and outpatient hospital services, physicians' surgical and medical services, laboratory and x-ray services, prescription drugs, well-baby and well-child care, including age-appropriate immunizations, emergency services, mental health benefits, family planning services and supplies, and other appropriate preventive services as designated by the Secretary.", }, { - value: - "inlcuded_desc_of_ben_and_val_as_percentage_of_equivalent", + value: "inlcuded_desc_of_ben_and_val_as_percentage_of_equivalent", label: "The state/territory has included a description of the benefits included and the actuarial value of the category as a percentage of the actuarial value of the coverage for the benefits included in the benchmark-equivalent benefit plan.", }, @@ -295,8 +291,7 @@ export const v202401: FormSchema = { sectionId: "addtnl-info", form: [ { - description: - "Other information about benchmark-equivalent assurances (optional)", + description: "Other information about benchmark-equivalent assurances (optional)", slots: [ { name: "description", diff --git a/lib/libs/webforms/ABP7/v202401.ts b/lib/libs/webforms/ABP7/v202401.ts index 6b2ee49be5..420ea228b4 100644 --- a/lib/libs/webforms/ABP7/v202401.ts +++ b/lib/libs/webforms/ABP7/v202401.ts @@ -6,8 +6,7 @@ export const v202401: FormSchema = { formId: "abp7", sections: [ { - title: - "Early and Periodic Screening, Diagnostic, and Treatment (EPSDT) assurances", + title: "Early and Periodic Screening, Diagnostic, and Treatment (EPSDT) assurances", sectionId: "epsdt-assurances", form: [ { @@ -18,8 +17,7 @@ export const v202401: FormSchema = { { rhf: "Select", name: "does-abp-include-beneficiaries-under-21", - label: - "Does the Alternative Benefit Plan (ABP) include beneficiaries under age 21?", + label: "Does the Alternative Benefit Plan (ABP) include beneficiaries under age 21?", labelClassName: "font-bold", rules: { required: "* Required" }, props: { @@ -128,10 +126,8 @@ export const v202401: FormSchema = { value: "risk_based_capitation", }, { - label: - "Administrative services contract", - value: - "administrative_services_contract", + label: "Administrative services contract", + value: "administrative_services_contract", }, { label: "Other", @@ -145,8 +141,7 @@ export const v202401: FormSchema = { rules: { required: "* Required", pattern: { - value: - noLeadingTrailingWhitespace, + value: noLeadingTrailingWhitespace, message: "Must not have leading or trailing whitespace.", }, @@ -215,8 +210,7 @@ export const v202401: FormSchema = { { label: "The state/territory assures that it meets the minimum requirements for prescription drug coverage in Section 1937 of the Act and implementing regulations at 42 CFR 440.347. Coverage is at least the greater of one drug in each United States Pharmacopeia (USP) category and class or the same number of prescription drugs in each category and class as the base benchmark.", - value: - "assures_min_requirements_for_perscription_drug_coverage", + value: "assures_min_requirements_for_perscription_drug_coverage", }, { label: @@ -227,14 +221,12 @@ export const v202401: FormSchema = { { label: "The state/territory assures that when it pays for outpatient prescription drugs covered under an ABP, it meets the requirements of Section 1927 of the Act and implementing regulations at 42 CFR 440.345, except for those requirements that are directly contrary to amount, duration, and scope of coverage permitted under Section 1937 of the Act.", - value: - "assures_outpatient_prescription_drugs_coverage_under_abp", + value: "assures_outpatient_prescription_drugs_coverage_under_abp", }, { label: "The state/territory assures that when conducting prior authorization of prescription drugs under an ABP, it complies with prior authorization program requirements in Section 1927(d)(5) of the Act.", - value: - "assures_prior_authorization_of_drugs_under_abp_prior", + value: "assures_prior_authorization_of_drugs_under_abp_prior", }, ], }, @@ -258,8 +250,7 @@ export const v202401: FormSchema = { { label: "The state/territory assures that substituted benefits are actuarially equivalent to the benefits they replaced from the base benchmark plan and that the state/territory has actuarial certification for substituted benefits available for inspection if requested by CMS.", - value: - "assures_substituted_benefits_are_actuarially_equivalent", + value: "assures_substituted_benefits_are_actuarially_equivalent", }, { label: @@ -280,8 +271,7 @@ export const v202401: FormSchema = { { label: "The state/territory assures that it will comply with the mental health and substance use disorder parity requirements of Section 1937(b)(6) of the Act by ensuring that the financial requirements and treatment limitations applicable to mental health or substance use disorder benefits comply with Section 2705(a) of the Public Health Service Act in the same manner as such requirements apply to a group health plan.", - value: - "assures_compliy_with_mental_healthy_and_substance_use_disorder", + value: "assures_compliy_with_mental_healthy_and_substance_use_disorder", }, { label: @@ -296,8 +286,7 @@ export const v202401: FormSchema = { { label: "The state/territory assures, in accordance with 45 CFR 156.115(a)(4) and 45 CFR 147.130, that it will provide as essential health benefits a broad range of preventive services including: “A” and “B” services recommended by the United States Preventive Services Task Force; vaccines recommended by the Advisory Committee for Immunization Practices (ACIP); preventive care and screening for infants, children, and adults recommended by HRSA's Bright Futures program; and additional preventive services for women recommended by the Institute of Medicine (IOM).", - value: - "assures_accordance_with_CFR_it_will_provide_essential_health_benefits", + value: "assures_accordance_with_CFR_it_will_provide_essential_health_benefits", }, ], }, diff --git a/lib/libs/webforms/ABP8/sections/v202401.ts b/lib/libs/webforms/ABP8/sections/v202401.ts index 6785b253b6..573aed3ebb 100644 --- a/lib/libs/webforms/ABP8/sections/v202401.ts +++ b/lib/libs/webforms/ABP8/sections/v202401.ts @@ -52,11 +52,7 @@ export function generateDependency({ // Section generators --------------------------------------------------------- -export function managedCare({ - conditionalInfo, - programLabel, - title, -}: SectionParams): Section { +export function managedCare({ conditionalInfo, programLabel, title }: SectionParams): Section { return { title: title || `${programLabel}`, sectionId: createSectionId(programLabel), @@ -149,8 +145,7 @@ export function managedCare({ ], }, { - label: - "Section 1932(a) mandatory managed care state plan amendment", + label: "Section 1932(a) mandatory managed care state plan amendment", value: "1932a", slots: [ { @@ -205,8 +200,7 @@ export function managedCare({ }, { label: `${ - programLabel === SectionName.HIO || - programLabel === SectionName.MCO + programLabel === SectionName.HIO || programLabel === SectionName.MCO ? "An" : "A" } ${programLabel} consistent with applicable managed care requirements (42 CFR Part 438, 42 CFR Part 440, and Sections 1903(m), 1932, and 1937 of the Social Security Act)`, @@ -222,10 +216,7 @@ export function managedCare({ } // "[Program] procurement or selection" -export function procurementOrSelection({ - conditionalInfo, - programLabel, -}: SectionParams): Section { +export function procurementOrSelection({ conditionalInfo, programLabel }: SectionParams): Section { return { title: `${programLabel} procurement or selection`, sectionId: `${createSectionId(programLabel)}-procurement`, @@ -301,8 +292,7 @@ export function deliverySystemCharactaristics({ rhf: "WrappedGroup", name: "benefit-service-group", props: { - wrapperClassName: - "ml-[0.6rem] pl-4 border-l-4 border-l-primary my-2 space-y-6", + wrapperClassName: "ml-[0.6rem] pl-4 border-l-4 border-l-primary my-2 space-y-6", }, fields: [ { @@ -326,8 +316,7 @@ export function deliverySystemCharactaristics({ required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, props: { @@ -370,13 +359,11 @@ export function deliverySystemCharactaristics({ value: "ffs-provider-contracts", }, { - label: - "Provision of payments to FFS providers on behalf of the state", + label: "Provision of payments to FFS providers on behalf of the state", value: "ffs-provider-payments", }, { - label: - "Provision of enrollee outreach and education activities", + label: "Provision of enrollee outreach and education activities", value: "enrollee-outreach", }, { @@ -394,13 +381,11 @@ export function deliverySystemCharactaristics({ value: "quality-improvement", }, { - label: - "Coordination with behavioral health systems/providers", + label: "Coordination with behavioral health systems/providers", value: "behavioral-health-coordination", }, { - label: - "Coordination with long-term services and support systems/providers", + label: "Coordination with long-term services and support systems/providers", value: "ltss-coordination", }, { @@ -416,8 +401,7 @@ export function deliverySystemCharactaristics({ required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -523,8 +507,7 @@ export function deliverySystemCharactaristics({ ], }, { - label: - "In some other geographic area (must not be smaller than a zip code)", + label: "In some other geographic area (must not be smaller than a zip code)", value: "other-geographic-area", slots: [ { @@ -551,10 +534,7 @@ export function deliverySystemCharactaristics({ } // "[Program] participation exclusions" -export function participationExclusions({ - conditionalInfo, - programLabel, -}: SectionParams): Section { +export function participationExclusions({ conditionalInfo, programLabel }: SectionParams): Section { const sectionId = `${createSectionId(programLabel)}_participation-exclusions`; return { @@ -603,8 +583,7 @@ export function participationExclusions({ value: "less-than-three-months", }, { - label: - "Individuals in a retroactive period of Medicaid eligibility", + label: "Individuals in a retroactive period of Medicaid eligibility", value: "retroactive-period", }, { @@ -620,8 +599,7 @@ export function participationExclusions({ required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, props: { @@ -678,8 +656,7 @@ export function participationRequirements({ required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, props: { @@ -689,8 +666,7 @@ export function participationRequirements({ ], }, { - label: - "Voluntary, using the below method for effectuating enrollment", + label: "Voluntary, using the below method for effectuating enrollment", value: "voluntary", slots: [ { @@ -740,10 +716,7 @@ export function participationRequirements({ } // "Disenrollment" -export function disenrollment({ - conditionalInfo, - programLabel, -}: SectionParams): Section { +export function disenrollment({ conditionalInfo, programLabel }: SectionParams): Section { const sectionId = `${createSectionId(programLabel)}_disenrollment`; return { title: "Disenrollment", @@ -777,8 +750,7 @@ export function disenrollment({ }, { rhf: "Input", - label: - "Length of time the disenrollment limitation will apply (up to 12 months)", + label: "Length of time the disenrollment limitation will apply (up to 12 months)", labelClassName: "font-bold", name: "disenrollment-limit-length", props: { @@ -827,8 +799,7 @@ export function disenrollment({ }, { rhf: "Textarea", - label: - "Additional circumstances of cause for disenrollment (optional)", + label: "Additional circumstances of cause for disenrollment (optional)", labelClassName: "font-bold", name: "additional-disenrollment-cause", props: { @@ -879,8 +850,7 @@ export function disenrollment({ ], }, { - label: - "Enrollees submit disenrollment requests to the state or its agent.", + label: "Enrollees submit disenrollment requests to the state or its agent.", value: "submit-requests", }, { @@ -893,8 +863,7 @@ export function disenrollment({ "The MCO/HIO/PIHP/PAHP/PCCM/PCCM entity may not approve or disapprove requests and must refer all disenrollment requests received to the state.", value: `${createSectionId(programLabel)}-refers-requests`, }, - ...(programLabel === SectionName.PCCM || - programLabel === SectionName.PCCMEntity + ...(programLabel === SectionName.PCCM || programLabel === SectionName.PCCMEntity ? [] : [ { @@ -982,8 +951,7 @@ export function disenrollment({ required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -1019,10 +987,7 @@ export function disenrollment({ } // "Additional information: [program]" -export function additionalInfo({ - conditionalInfo, - programLabel, -}: SectionParams): Section { +export function additionalInfo({ conditionalInfo, programLabel }: SectionParams): Section { return { title: `Additional information: ${programLabel}`, sectionId: `additional-info-${createSectionId(programLabel)}`, @@ -1036,8 +1001,7 @@ export function additionalInfo({ slots: [ { rhf: "Textarea", - label: - "Additional details about this service delivery system (optional)", + label: "Additional details about this service delivery system (optional)", labelClassName: "font-bold", name: "additional-details", props: { @@ -1057,10 +1021,7 @@ export function additionalInfo({ } // "[Program] payments" -export function payments({ - conditionalInfo, - programLabel, -}: SectionParams): Section { +export function payments({ conditionalInfo, programLabel }: SectionParams): Section { const pccmEntityPayment: RHFOption[] = programLabel === SectionName.PCCMEntity ? [ @@ -1111,8 +1072,7 @@ export function payments({ required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, diff --git a/lib/libs/webforms/ABP8/v202401.ts b/lib/libs/webforms/ABP8/v202401.ts index aac203103e..246a272ed1 100644 --- a/lib/libs/webforms/ABP8/v202401.ts +++ b/lib/libs/webforms/ABP8/v202401.ts @@ -78,8 +78,7 @@ export const v202401: FormSchema = { value: "mco", }, { - label: - "Health insuring organization (HIO) (California only)", + label: "Health insuring organization (HIO) (California only)", value: "hio", }, { @@ -206,8 +205,7 @@ export const v202401: FormSchema = { }, { rhf: "Checkbox", - label: - "Which of the following will apply to the managed care program?", + label: "Which of the following will apply to the managed care program?", labelClassName: "font-bold", name: "voluntary-enrollment-options", rules: { @@ -249,8 +247,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, props: { @@ -340,8 +337,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, props: { @@ -365,8 +361,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, props: { diff --git a/lib/libs/webforms/ABP9/v202401.ts b/lib/libs/webforms/ABP9/v202401.ts index 11bfa0f060..fbd93057f1 100644 --- a/lib/libs/webforms/ABP9/v202401.ts +++ b/lib/libs/webforms/ABP9/v202401.ts @@ -36,8 +36,7 @@ export const v202401: FormSchema = { message: "Must not have leading or trailing whitespace.", }, }, - formItemClassName: - "ml-[0.6rem] px-4 my-2 border-l-4 border-l-primary", + formItemClassName: "ml-[0.6rem] px-4 my-2 border-l-4 border-l-primary", label: "Describe the employer-sponsored insurance, including the population covered, amount of premium assistance by population, and employer-sponsored insurance activities, including required contribution, cost-effectiveness test requirements, and benefit information.", labelClassName: "font-bold", @@ -59,8 +58,7 @@ export const v202401: FormSchema = { { rhf: "Select", name: "does-provide-pay-of-premiums", - label: - "Does the state/territory otherwise provide for payment of premiums?", + label: "Does the state/territory otherwise provide for payment of premiums?", labelClassName: "font-bold", rules: { required: "* Required" }, props: { @@ -81,8 +79,7 @@ export const v202401: FormSchema = { message: "Must not have leading or trailing whitespace.", }, }, - formItemClassName: - "ml-[0.6rem] px-4 my-2 border-l-4 border-l-primary", + formItemClassName: "ml-[0.6rem] px-4 my-2 border-l-4 border-l-primary", label: "Describe, including the population covered, amount of premium assistance by population, required contributions, cost-effectiveness test requirements, and benefit information.", labelClassName: "font-bold", diff --git a/lib/libs/webforms/CS11/v202401.ts b/lib/libs/webforms/CS11/v202401.ts index ed16a46d6e..cb8405b041 100644 --- a/lib/libs/webforms/CS11/v202401.ts +++ b/lib/libs/webforms/CS11/v202401.ts @@ -4,8 +4,7 @@ import { noLeadingTrailingWhitespace } from "shared-utils"; export const v202401: FormSchema = { header: "CS 11: Separate CHIP eligibility—Pregnant women who have access to public employee coverage", - subheader: - "Sections 2110(b)(2)(B) and (b)(6) of the Social Security Act (SSA)", + subheader: "Sections 2110(b)(2)(B) and (b)(6) of the Social Security Act (SSA)", formId: "cs11", sections: [ { @@ -103,8 +102,7 @@ export const v202401: FormSchema = { ], }, { - label: - "Hardship criteria as provided in Section 2110(b)(6)(C)", + label: "Hardship criteria as provided in Section 2110(b)(6)(C)", value: "hardship-criteria", slots: [ { @@ -167,8 +165,7 @@ export const v202401: FormSchema = { value: "same", }, { - label: - "Lower than the income standards for targeted low-income pregnant women", + label: "Lower than the income standards for targeted low-income pregnant women", value: "lower", }, ], @@ -307,8 +304,7 @@ export const v202401: FormSchema = { props: { className: "w-[696px]", }, - formItemClassName: - "ml-[0.6rem] px-4 border-l-4 border-l-primary mb-4", + formItemClassName: "ml-[0.6rem] px-4 border-l-4 border-l-primary mb-4", dependency: { conditions: [ { @@ -364,8 +360,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, label: "County", @@ -450,8 +445,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, label: "City", @@ -544,8 +538,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, label: "Geographic Area", @@ -561,8 +554,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, label: "Describe", @@ -584,8 +576,7 @@ export const v202401: FormSchema = { rules: { pattern: { value: /^[0-9]\d*$/, - message: - "Must be a positive integer value", + message: "Must be a positive integer value", }, required: "* Required", }, @@ -603,8 +594,7 @@ export const v202401: FormSchema = { rules: { pattern: { value: /^[0-9]\d*$/, - message: - "Must be a positive integer value", + message: "Must be a positive integer value", }, required: "* Required", }, @@ -651,13 +641,11 @@ export const v202401: FormSchema = { props: { options: [ { - label: - "All pregnant women who have access to public employee coverage", + label: "All pregnant women who have access to public employee coverage", value: "all-pregnant-women", }, { - label: - "Certain pregnant women who have access to public employee coverage", + label: "Certain pregnant women who have access to public employee coverage", value: "certain-pregnant-women", slots: [ { @@ -689,8 +677,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -719,8 +706,7 @@ export const v202401: FormSchema = { rules: { pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, required: "* Required", }, @@ -759,8 +745,7 @@ export const v202401: FormSchema = { props: { options: [ { - label: - "Same as the age criteria used for targeted low-income pregnant women", + label: "Same as the age criteria used for targeted low-income pregnant women", value: "same-as-targeted", }, { @@ -791,8 +776,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: /^(2[0-9]|[3-9]\d|\d{3,})$/, - message: - "Must be a positive integer value greater than 19", + message: "Must be a positive integer value greater than 19", }, }, props: { @@ -814,8 +798,7 @@ export const v202401: FormSchema = { rules: { pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, required: "* Required", }, @@ -843,14 +826,12 @@ export const v202401: FormSchema = { rules: { pattern: { value: /^[0-9]\d*$/, - message: - "Must be a positive integer value", + message: "Must be a positive integer value", }, required: "* Required", }, label: "Start of age range", - labelClassName: - "font-bold text-black", + labelClassName: "font-bold text-black", props: { className: "w-[125px]", }, @@ -861,8 +842,7 @@ export const v202401: FormSchema = { rules: { pattern: { value: /^[0-9]\d*$/, - message: - "Must be a positive integer value", + message: "Must be a positive integer value", }, required: "* Required", }, @@ -870,15 +850,12 @@ export const v202401: FormSchema = { { type: "greaterThanField", strictGreater: true, - fieldName: - "cs11_age-standard_start-age-range", - message: - "Must be greater than start of age range", + fieldName: "cs11_age-standard_start-age-range", + message: "Must be greater than start of age range", }, ], label: "End of age range", - labelClassName: - "font-bold text-black", + labelClassName: "font-bold text-black", props: { className: "w-[125px]", }, @@ -889,8 +866,7 @@ export const v202401: FormSchema = { rhf: "Select", label: "Does the age range for targeted low-income pregnant women overlap with the age range for targeted low-income children?", - labelClassName: - "font-bold text-black mt-4", + labelClassName: "font-bold text-black mt-4", name: "age-range-overlap", rules: { required: "* Required", @@ -920,8 +896,7 @@ export const v202401: FormSchema = { rules: { pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, required: "* Required", }, diff --git a/lib/libs/webforms/CS12/v202401.ts b/lib/libs/webforms/CS12/v202401.ts index 17e777d0ba..f68c861c26 100644 --- a/lib/libs/webforms/CS12/v202401.ts +++ b/lib/libs/webforms/CS12/v202401.ts @@ -26,11 +26,7 @@ const ageOptions = [ const childStyle = " ml-[0.6rem] px-4 my-2 border-l-4 border-l-primary "; -const ageRangeGroup = ( - nameMod: string, - fullMod: string, - wrapperDep = true, -): RHFSlotProps[] => [ +const ageRangeGroup = (nameMod: string, fullMod: string, wrapperDep = true): RHFSlotProps[] => [ { name: nameMod + "inc-age-standard", descriptionAbove: true, @@ -372,16 +368,11 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, - ...ageRangeGroup( - "county", - "cs12_inc-exception", - false, - ), + ...ageRangeGroup("county", "cs12_inc-exception", false), ], }, ], @@ -412,8 +403,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -429,8 +419,7 @@ export const v202401: FormSchema = { { name: "geo-group", rhf: "FieldArray", - description: - "Enter each geographic area with a unique income standard.", + description: "Enter each geographic area with a unique income standard.", descriptionAbove: true, props: { ...DefaultFieldGroupProps, @@ -448,8 +437,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -462,8 +450,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, props: { diff --git a/lib/libs/webforms/CS15/v202401.ts b/lib/libs/webforms/CS15/v202401.ts index ef54b2fb3b..558bae7c67 100644 --- a/lib/libs/webforms/CS15/v202401.ts +++ b/lib/libs/webforms/CS15/v202401.ts @@ -3,8 +3,7 @@ import { FormSchema } from "shared-types"; export const v202401: FormSchema = { formId: "cs15", header: "CS 15: Separate CHIP MAGI-based income methodologies", - subheader: - "2102(b)(1)(B)(v) of the Social Security Act (SSA) and 42 CFR 457.315", + subheader: "2102(b)(1)(B)(v) of the Social Security Act (SSA) and 42 CFR 457.315", sections: [ { title: "Overview", @@ -212,8 +211,7 @@ export const v202401: FormSchema = { { rhf: "Upload", name: "upload-approval-documentation", - label: - "Upload approval documentation of converted MAGI-equivalent income standards.", + label: "Upload approval documentation of converted MAGI-equivalent income standards.", labelClassName: "text-black font-bold", rules: { required: "* Required" }, formItemClassName: "pb-16", diff --git a/lib/libs/webforms/CS3/v202401.ts b/lib/libs/webforms/CS3/v202401.ts index 11af7fba31..b6d8226dfe 100644 --- a/lib/libs/webforms/CS3/v202401.ts +++ b/lib/libs/webforms/CS3/v202401.ts @@ -41,8 +41,7 @@ export const v202401: FormSchema = { name: "inc-standards", rhf: "WrappedGroup", label: "Age and household income ranges", - description: - "There should be no overlaps in or gaps between ages.", + description: "There should be no overlaps in or gaps between ages.", descriptionAbove: true, labelClassName: "font-bold", fields: [ @@ -50,8 +49,7 @@ export const v202401: FormSchema = { rhf: "FieldArray", name: "age-and-house-inc-range", descriptionClassName: "age-and-house-inc-range", - formItemClassName: - "age-and-house-inc-range [&_select~.slot-form-message]:w-max", + formItemClassName: "age-and-house-inc-range [&_select~.slot-form-message]:w-max", props: { appendText: "Add range", }, diff --git a/lib/libs/webforms/CS7/index.ts b/lib/libs/webforms/CS7/index.ts index 9f925953c2..e5cf77f4fe 100644 --- a/lib/libs/webforms/CS7/index.ts +++ b/lib/libs/webforms/CS7/index.ts @@ -1 +1 @@ -export * from "./v202401"; \ No newline at end of file +export * from "./v202401"; diff --git a/lib/libs/webforms/CS8/v202401.ts b/lib/libs/webforms/CS8/v202401.ts index 8f910b0a40..37e2d2ff0a 100644 --- a/lib/libs/webforms/CS8/v202401.ts +++ b/lib/libs/webforms/CS8/v202401.ts @@ -50,8 +50,7 @@ export const v202401: FormSchema = { subsection: true, form: [ { - description: - "The state provides coverage to pregnant women in the following age ranges:", + description: "The state provides coverage to pregnant women in the following age ranges:", descriptionClassName: "text-base", slots: [ { @@ -103,8 +102,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, label: @@ -158,8 +156,7 @@ export const v202401: FormSchema = { type: "greaterThanField", strictGreater: true, fieldName: "cs8_age_start-age-range", - message: - "Must be greater than start of age range", + message: "Must be greater than start of age range", }, ], label: "End of age range", @@ -196,8 +193,7 @@ export const v202401: FormSchema = { rhf: "WrappedGroup", name: "wrapped", props: { - wrapperClassName: - "ml-[0.6rem] px-4 border-l-4 border-l-primary mb-4", + wrapperClassName: "ml-[0.6rem] px-4 border-l-4 border-l-primary mb-4", }, fields: [ { @@ -207,15 +203,13 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, label: "Describe how it’s determined whether the applicant will be provided coverage as a child or as a pregnant woman.", labelClassName: "font-bold", - formItemClassName: - "ml-[0.6rem] px-4 border-l-4 border-l-primary my-4", + formItemClassName: "ml-[0.6rem] px-4 border-l-4 border-l-primary my-4", props: { className: "w-[658px]", }, @@ -368,8 +362,7 @@ export const v202401: FormSchema = { props: { className: "w-[696px]", }, - formItemClassName: - "ml-[0.6rem] px-4 border-l-4 border-l-primary mb-4", + formItemClassName: "ml-[0.6rem] px-4 border-l-4 border-l-primary mb-4", dependency: { conditions: [ { @@ -428,8 +421,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, label: "County", @@ -518,8 +510,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, label: "City", @@ -615,8 +606,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, label: "Geographic Area", @@ -632,8 +622,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, label: "Describe", @@ -655,8 +644,7 @@ export const v202401: FormSchema = { rules: { pattern: { value: /^[0-9]\d*$/, - message: - "Must be a positive integer value", + message: "Must be a positive integer value", }, required: "* Required", }, @@ -674,8 +662,7 @@ export const v202401: FormSchema = { rules: { pattern: { value: /^[0-9]\d*$/, - message: - "Must be a positive integer value", + message: "Must be a positive integer value", }, required: "* Required", }, diff --git a/lib/libs/webforms/CS9/v202401.ts b/lib/libs/webforms/CS9/v202401.ts index f19e4ea09f..690ccecf5b 100644 --- a/lib/libs/webforms/CS9/v202401.ts +++ b/lib/libs/webforms/CS9/v202401.ts @@ -2,8 +2,7 @@ import { FormSchema } from "shared-types"; import { noLeadingTrailingWhitespace } from "shared-utils"; export const v202401: FormSchema = { - header: - "CS 9: Separate CHIP eligibility—Coverage from conception to end of pregnancy", + header: "CS 9: Separate CHIP eligibility—Coverage from conception to end of pregnancy", subheader: "Section 2112 of the Social Security Act and 42 CFR 457.10", formId: "cs9", sections: [ @@ -86,8 +85,7 @@ export const v202401: FormSchema = { label: "Describe", labelClassName: "text-black font-bold", name: "age-standard-description", - formItemClassName: - "ml-[0.6rem] px-4 my-2 border-l-4 border-l-primary", + formItemClassName: "ml-[0.6rem] px-4 my-2 border-l-4 border-l-primary", rules: { pattern: { value: noLeadingTrailingWhitespace, @@ -200,8 +198,7 @@ export const v202401: FormSchema = { "Explain, including a description of the overlapping geographic area and the reason for having different income standards.", labelClassName: "text-black font-bold", name: "income-standard-exceptions-description", - formItemClassName: - "ml-[0.6rem] px-4 my-2 border-l-4 border-l-primary", + formItemClassName: "ml-[0.6rem] px-4 my-2 border-l-4 border-l-primary", rules: { pattern: { value: noLeadingTrailingWhitespace, @@ -266,8 +263,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: /^\S(.*\S)?$/, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, props: { @@ -282,8 +278,7 @@ export const v202401: FormSchema = { rules: { pattern: { value: /^[0-9]\d*$/, - message: - "Must be a positive integer value", + message: "Must be a positive integer value", }, required: "* Required", }, @@ -334,8 +329,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: /^\S(.*\S)?$/, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, props: { @@ -350,8 +344,7 @@ export const v202401: FormSchema = { rules: { pattern: { value: /^[0-9]\d*$/, - message: - "Must be a positive integer value", + message: "Must be a positive integer value", }, required: "* Required", }, @@ -403,8 +396,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: /^\S(.*\S)?$/, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, props: { @@ -419,8 +411,7 @@ export const v202401: FormSchema = { rules: { pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, required: "* Required", }, @@ -448,8 +439,7 @@ export const v202401: FormSchema = { rules: { pattern: { value: /^[0-9]\d*$/, - message: - "Must be a positive integer value", + message: "Must be a positive integer value", }, required: "* Required", }, @@ -467,8 +457,7 @@ export const v202401: FormSchema = { rules: { pattern: { value: /^[0-9]\d*$/, - message: - "Must be a positive integer value", + message: "Must be a positive integer value", }, required: "* Required", }, @@ -528,8 +517,7 @@ export const v202401: FormSchema = { props: { options: [ { - label: - "Exempt from requirement of verifying citizenship status", + label: "Exempt from requirement of verifying citizenship status", value: "exempt-from-citizenship-status", }, ], diff --git a/lib/libs/webforms/ER/v202401.ts b/lib/libs/webforms/ER/v202401.ts index b76d3f3a13..beac76d17c 100644 --- a/lib/libs/webforms/ER/v202401.ts +++ b/lib/libs/webforms/ER/v202401.ts @@ -22,8 +22,7 @@ const a1DropdownOptions = [ }, { value: "cfr-435-226", - label: - "Independent foster care adolescents (1902(a)(10)(A)(ii)(XVII)/42 CFR §435.226)", + label: "Independent foster care adolescents (1902(a)(10)(A)(ii)(XVII)/42 CFR §435.226)", }, { value: "cfr-435-229", @@ -47,8 +46,7 @@ const a1DropdownOptions = [ }, { value: "cfr-435-215", - label: - "Individuals with tuberculosis (1902(a)(10)(A)(ii)(XII) and 1902(z)/42 CFR §435.215)", + label: "Individuals with tuberculosis (1902(a)(10)(A)(ii)(XII) and 1902(z)/42 CFR §435.215)", }, { value: "cobra-1902", @@ -77,18 +75,15 @@ const a1DropdownOptions = [ }, { value: "hospice-1905", - label: - "Individuals receiving hospice (1902(a)(10)(A)(ii)(VII) and 1905(o))", + label: "Individuals receiving hospice (1902(a)(10)(A)(ii)(VII) and 1905(o))", }, { value: "cfr-435-225", - label: - "Children under age 19 with a disability (1902(e)(3)/42 CFR §435.225)", + label: "Children under age 19 with a disability (1902(e)(3)/42 CFR §435.225)", }, { value: "age-disability-1902", - label: - "Age and disability-related poverty level (1902(a)(10)(A)(ii)(X) and 1902(m)(1)) ", + label: "Age and disability-related poverty level (1902(a)(10)(A)(ii)(X) and 1902(m)(1)) ", }, { value: "work-1902", label: "Work incentives (1902(a)(10)(A)(ii)(XIII))" }, { @@ -119,8 +114,7 @@ const a1DropdownOptions = [ const a2DroppdownOptionsIncome = [ { value: "65-plus-blind-disability", - label: - "Individuals who are age 65 or older or who have blindness or a disability", + label: "Individuals who are age 65 or older or who have blindness or a disability", }, { value: "qual-med-ben", label: "Qualified medicare beneficiaries " }, { @@ -164,8 +158,7 @@ const a2DroppdownOptionsIncome = [ }, { value: "med-needy-under-21", - label: - "Medically needy reasonable classifications of individuals under age 21", + label: "Medically needy reasonable classifications of individuals under age 21", }, { value: "med-needy-parents", @@ -179,8 +172,7 @@ const a2DroppdownOptionsIncome = [ const a2DroppdownOptionsResource = [ { value: "65-plus-blind-disability", - label: - "Individuals who are age 65 or older or who have blindness or a disability", + label: "Individuals who are age 65 or older or who have blindness or a disability", }, { value: "qual-med-ben", label: "Qualified medicare beneficiaries " }, { @@ -228,8 +220,7 @@ const a2DroppdownOptionsResource = [ }, { value: "med-needy-under-21", - label: - "Medically needy reasonable classifications of individuals under age 21", + label: "Medically needy reasonable classifications of individuals under age 21", }, { value: "med-needy-parents", @@ -294,8 +285,7 @@ const b1DropdownOptions = [ }, { value: "med-needy-under-21", - label: - "Medically needy reasonable classifications of individuals under age 21", + label: "Medically needy reasonable classifications of individuals under age 21", }, { value: "med-needy-parents", @@ -318,13 +308,11 @@ const b2DropdownOptions = [ }, { value: "family-planning", - label: - "Individuals eligible for family planning services (if covered by state)", + label: "Individuals eligible for family planning services (if covered by state)", }, { value: "breat-cervical-cancer", - label: - "Individuals needing treatment for breast or cervical cancer (if covered by state)", + label: "Individuals needing treatment for breast or cervical cancer (if covered by state)", }, ]; @@ -437,8 +425,7 @@ const effectivePeriodSectionChildren = (letter: string): FormGroup[] => { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -483,8 +470,7 @@ export const v202401: FormSchema = { { name: "add-prev-spa", rhf: "Radio", - label: - "Does this SPA add to a previously approved emergency relief SPA in effect?", + label: "Does this SPA add to a previously approved emergency relief SPA in effect?", labelClassName: "font-bold text-black", rules: { required: "* Required", @@ -505,8 +491,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -519,8 +504,7 @@ export const v202401: FormSchema = { { name: "supersede-prev-spa", rhf: "Radio", - label: - "Does this SPA supersede a previously approved emergency relief SPA?", + label: "Does this SPA supersede a previously approved emergency relief SPA?", labelClassName: "font-bold text-black", rules: { required: "* Required", @@ -541,8 +525,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -622,8 +605,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -635,8 +617,7 @@ export const v202401: FormSchema = { { name: "sections-modified", rhf: "Checkbox", - label: - "Sections modified during the period of the public health emergency", + label: "Sections modified during the period of the public health emergency", labelClassName: "font-bold text-black", rules: { required: "* Required", @@ -731,9 +712,7 @@ export const v202401: FormSchema = { subsection: true, title: "A - Eligibility options elected", dependency: { - conditions: [ - { type: "valueExists", name: "ers_a-eligible_options-elected" }, - ], + conditions: [{ type: "valueExists", name: "ers_a-eligible_options-elected" }], effect: { type: "show" }, }, form: [ @@ -847,8 +826,7 @@ export const v202401: FormSchema = { }, { value: "parents-caretakers", - label: - "Medically needy parents and other caretaker relatives", + label: "Medically needy parents and other caretaker relatives", }, { value: "age-blind-disability", @@ -909,8 +887,7 @@ export const v202401: FormSchema = { }, { value: "parents-caretakers", - label: - "Medically needy parents and other caretaker relatives", + label: "Medically needy parents and other caretaker relatives", }, { value: "age-blind-disability", @@ -1130,8 +1107,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, labelClassName: "text-black font-bold", @@ -1178,8 +1154,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, labelClassName: "text-black font-bold", @@ -1355,8 +1330,7 @@ export const v202401: FormSchema = { }, form: [ { - description: - "1. Modify the agency’s approved hospital presumptive eligibility program.", + description: "1. Modify the agency’s approved hospital presumptive eligibility program.", dependency: { conditions: [ { @@ -1426,8 +1400,7 @@ export const v202401: FormSchema = { }, { value: "performance-standards", - label: - "Modify the performance standards for participating hospitals.", + label: "Modify the performance standards for participating hospitals.", slots: [ { rhf: "Textarea", @@ -1488,8 +1461,7 @@ export const v202401: FormSchema = { rhf: "Multiselect", name: "b2-magi-groups", rules: { required: "* Required" }, - label: - "State plan MAGI groups to which presumptive eligibility may be applied", + label: "State plan MAGI groups to which presumptive eligibility may be applied", labelClassName: "font-bold text-black", props: { options: b2DropdownOptions, @@ -1560,8 +1532,7 @@ export const v202401: FormSchema = { ], }, { - description: - "3. Designate additional qualified entities for presumptive eligibility.", + description: "3. Designate additional qualified entities for presumptive eligibility.", dependency: { conditions: [ { @@ -1593,8 +1564,7 @@ export const v202401: FormSchema = { rhf: "Multiselect", name: "b3-magi-groups", rules: { required: "* Required" }, - label: - "State plan MAGI groups to which presumptive eligibility may be applied", + label: "State plan MAGI groups to which presumptive eligibility may be applied", labelClassName: "font-bold text-black", props: { options: b2DropdownOptions, @@ -1714,13 +1684,11 @@ export const v202401: FormSchema = { }, { value: "3-suspend_enrollment_fees", - label: - "3. Suspend enrollment fees, premiums, and similar charges.", + label: "3. Suspend enrollment fees, premiums, and similar charges.", }, { value: "4-reduce_enrollment_fees", - label: - "4. Reduce enrollment fees, premiums, and similar charges.", + label: "4. Reduce enrollment fees, premiums, and similar charges.", }, { value: "5-hardship_waiver", @@ -1739,9 +1707,7 @@ export const v202401: FormSchema = { subsection: true, title: "C - Cost sharing and premiums options elected", dependency: { - conditions: [ - { type: "valueExists", name: "ers_c-costshare_options-elected" }, - ], + conditions: [{ type: "valueExists", name: "ers_c-costshare_options-elected" }], effect: { type: "show" }, }, form: [ @@ -1819,8 +1785,7 @@ export const v202401: FormSchema = { ], }, { - description: - "3. Suspend enrollment fees, premiums, and similar charges.", + description: "3. Suspend enrollment fees, premiums, and similar charges.", dependency: { conditions: [ { @@ -1835,8 +1800,7 @@ export const v202401: FormSchema = { { rhf: "Radio", name: "suspension-beneficiaries", - label: - "The agency suspends enrollment fees, premiums, and similar charges for:", + label: "The agency suspends enrollment fees, premiums, and similar charges for:", labelClassName: "font-bold text-black", rules: { required: "* Required" }, props: { @@ -1867,8 +1831,7 @@ export const v202401: FormSchema = { ], }, { - description: - "4. Reduce enrollment fees, premiums, and similar charges. ", + description: "4. Reduce enrollment fees, premiums, and similar charges. ", dependency: { conditions: [ { @@ -1884,8 +1847,7 @@ export const v202401: FormSchema = { rhf: "Textarea", rules: { required: "* Required" }, name: "how-reduce-fess-premiums-sc", - label: - "How does the agency reduce enrollment fees, premiums, and similar charges?", + label: "How does the agency reduce enrollment fees, premiums, and similar charges?", labelClassName: "text-black font-bold", props: { className: "h-[76px]", @@ -1916,8 +1878,7 @@ export const v202401: FormSchema = { rhf: "Textarea", rules: { required: "* Required" }, name: "unique-hardship-standards", - label: - "What are the standards and/or criteria for determining undue hardship?", + label: "What are the standards and/or criteria for determining undue hardship?", labelClassName: "text-black font-bold", props: { className: "h-[76px]", @@ -1986,8 +1947,7 @@ export const v202401: FormSchema = { }, { value: "3-temp_adj_1915", - label: - "3. Benefits - temporarily adjust the 1915(i) benefit", + label: "3. Benefits - temporarily adjust the 1915(i) benefit", }, { value: "4-compliance_reqs", @@ -2018,8 +1978,7 @@ export const v202401: FormSchema = { }, { value: "7-pharm_adj_supplies", - label: - "7. Pharmacy - adjust days’ supply or quantity limits", + label: "7. Pharmacy - adjust days’ supply or quantity limits", }, { value: "8-pharm_mod_auth", @@ -2027,13 +1986,11 @@ export const v202401: FormSchema = { }, { value: "9-pharm_add_payment", - label: - "9. Pharmacy - add supplement payment to professional dispensing fee", + label: "9. Pharmacy - add supplement payment to professional dispensing fee", }, { value: "10-pharm_establish", - label: - "10. Pharmacy - establish preferred drug list (PDL) exceptions", + label: "10. Pharmacy - establish preferred drug list (PDL) exceptions", }, { value: "11-pharm_waive_sig", @@ -2083,8 +2040,7 @@ export const v202401: FormSchema = { title: "D - Benefits options elected", form: [ { - description: - "1. Benefits—temporarily add optional 1905(a) benefit(s)", + description: "1. Benefits—temporarily add optional 1905(a) benefit(s)", dependency: { conditions: [ { @@ -2239,8 +2195,7 @@ export const v202401: FormSchema = { { rhf: "Textarea", name: "service-scope", - label: - "Service description and/or amount, duration, and scope changes", + label: "Service description and/or amount, duration, and scope changes", labelClassName: "text-black font-bold", props: { className: "h-[76px]" }, rules: { @@ -2268,8 +2223,7 @@ export const v202401: FormSchema = { { rhf: "Textarea", name: "assessment-consent-plan-policies", - label: - "Changes to assessment, consent, and service plan policies", + label: "Changes to assessment, consent, and service plan policies", labelClassName: "text-black font-bold", props: { className: "h-[76px]" }, rules: { @@ -2308,13 +2262,11 @@ export const v202401: FormSchema = { options: [ { value: "suspend-all-services", - label: - "Suspend prior authorization for all covered services.", + label: "Suspend prior authorization for all covered services.", }, { value: "suspend-some-services", - label: - "Suspend prior authorization for certain covered services.", + label: "Suspend prior authorization for certain covered services.", slots: [ { rhf: "Textarea", @@ -2326,8 +2278,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -2353,8 +2304,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -2463,16 +2413,12 @@ export const v202401: FormSchema = { { value: "limits-cat-needy", label: "Limits for categorically needy recipients", - slots: [ - { rhf: "Textarea", name: "limits-cat-needy-desc" }, - ], + slots: [{ rhf: "Textarea", name: "limits-cat-needy-desc" }], }, { value: "limits-med-needy", label: "Limits for medically needy recipients", - slots: [ - { rhf: "Textarea", name: "limits-med-needy-desc" }, - ], + slots: [{ rhf: "Textarea", name: "limits-med-needy-desc" }], }, ], }, @@ -2499,8 +2445,7 @@ export const v202401: FormSchema = { appendText: "Add provider type", divider: true, appendVariant: "default", - fieldArrayClassName: - DefaultFieldGroupProps.fieldArrayClassName, + fieldArrayClassName: DefaultFieldGroupProps.fieldArrayClassName, }, formItemClassName: childStyle, fields: [ @@ -2513,8 +2458,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -2535,8 +2479,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -2550,8 +2493,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -2584,8 +2526,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -2599,8 +2540,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -2701,8 +2641,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, props: { className: "h-[76px]" }, @@ -2711,8 +2650,7 @@ export const v202401: FormSchema = { }, { value: "service-scope", - label: - "Changes to limits on amount, duration, and scope of service", + label: "Changes to limits on amount, duration, and scope of service", slots: [ { rhf: "Textarea", @@ -2723,8 +2661,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, props: { className: "h-[76px]" }, @@ -2744,8 +2681,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, props: { className: "h-[76px]" }, @@ -2765,8 +2701,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, props: { className: "h-[76px]" }, @@ -2837,8 +2772,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, props: { className: "h-[76px]" }, @@ -2872,8 +2806,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, props: { className: "h-[76px]" }, @@ -2906,8 +2839,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, props: { className: "h-[76px]" }, @@ -2940,8 +2872,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, props: { className: "h-[76px]" }, @@ -2974,8 +2905,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, props: { className: "h-[76px]" }, @@ -2996,8 +2926,7 @@ export const v202401: FormSchema = { options: [ { value: "assured", - label: - "The telehealth will ensure the health and safety of an individual.", + label: "The telehealth will ensure the health and safety of an individual.", slots: [ { rhf: "Textarea", @@ -3008,8 +2937,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, props: { className: "h-[76px]" }, @@ -3024,8 +2952,7 @@ export const v202401: FormSchema = { { rhf: "Textarea", name: "changes-made-to-1915-elig-proc", - label: - "Changes made to the 1915(i) eligibility evaluation process", + label: "Changes made to the 1915(i) eligibility evaluation process", labelClassName: "font-bold text-black", rules: { required: "* Required", @@ -3138,8 +3065,7 @@ export const v202401: FormSchema = { }, { value: "not-applicable", - label: - "Not applicable: The state does not currently have an approved ABP.", + label: "Not applicable: The state does not currently have an approved ABP.", }, ], }, @@ -3164,8 +3090,7 @@ export const v202401: FormSchema = { title: "D - Benefits options elected - telehealth", form: [ { - description: - "6. Telehealth - extend coverage of services provided via telehealth", + description: "6. Telehealth - extend coverage of services provided via telehealth", dependency: { conditions: [ { @@ -3281,8 +3206,7 @@ export const v202401: FormSchema = { ], }, { - description: - "9. Pharmacy - add supplement payment to professional dispensing fee", + description: "9. Pharmacy - add supplement payment to professional dispensing fee", dependency: { conditions: [ { @@ -3301,15 +3225,13 @@ export const v202401: FormSchema = { label: "Payment adjustments made to professional dispensing fee", labelClassName: "font-bold text-black", descriptionAbove: true, - description: - "Agencies must supply documentation to justify the additional fees.", + description: "Agencies must supply documentation to justify the additional fees.", props: { className: "h-[76px]" }, }, ], }, { - description: - "10. Pharmacy - establish preferred drug list (PDL) exceptions", + description: "10. Pharmacy - establish preferred drug list (PDL) exceptions", dependency: { conditions: [ { @@ -3423,8 +3345,7 @@ export const v202401: FormSchema = { }, { value: "5-bed_hold_nf", - label: - "5. Changes to bed hold policies for nursing facilities (NFs)", + label: "5. Changes to bed hold policies for nursing facilities (NFs)", }, { value: "6-bed_hols_icf_iid", @@ -3451,9 +3372,7 @@ export const v202401: FormSchema = { sectionId: "e-options-elected", subsection: true, dependency: { - conditions: [ - { type: "valueExists", name: "ers_e-payments_options-elected" }, - ], + conditions: [{ type: "valueExists", name: "ers_e-payments_options-elected" }], effect: { type: "show" }, }, title: "E - Payments options elected", @@ -3562,8 +3481,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -3723,8 +3641,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -3771,8 +3688,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -3863,8 +3779,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -3899,8 +3814,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -3908,8 +3822,7 @@ export const v202401: FormSchema = { }, { value: "differ-face-to-face", - label: - "Differ from payments for the same services when provided face to face", + label: "Differ from payments for the same services when provided face to face", slots: [ { name: "e3-face-desc", @@ -3923,8 +3836,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -3947,8 +3859,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -4064,8 +3975,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -4093,8 +4003,7 @@ export const v202401: FormSchema = { ], }, { - description: - "5. Changes to bed hold policies for nursing facilities (NFs)", + description: "5. Changes to bed hold policies for nursing facilities (NFs)", dependency: { conditions: [ { @@ -4162,8 +4071,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -4253,8 +4161,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -4345,8 +4252,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -4437,8 +4343,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -4481,8 +4386,7 @@ export const v202401: FormSchema = { }, { value: "2-elect_variance", - label: - "2. Elect a variance to the basic personal needs allowance.", + label: "2. Elect a variance to the basic personal needs allowance.", }, ], }, @@ -4602,8 +4506,7 @@ export const v202401: FormSchema = { ], }, { - description: - "2. Elect a variance to the basic personal needs allowance.", + description: "2. Elect a variance to the basic personal needs allowance.", dependency: { conditions: [ { @@ -4635,20 +4538,17 @@ export const v202401: FormSchema = { }, { sectionId: "g-other-policies", - title: - "G - Other policies and procedures differing from approved Medicaid state plan", + title: "G - Other policies and procedures differing from approved Medicaid state plan", form: [ { slots: [ { rhf: "Textarea", name: "pol-and-procedures", - label: - "Other policies and procedures differing from approved Medicaid state plan", + label: "Other policies and procedures differing from approved Medicaid state plan", labelClassName: "text-black font-bold", descriptionAbove: true, - description: - "This includes legal reference for provision being temporarily amended.", + description: "This includes legal reference for provision being temporarily amended.", }, ], }, diff --git a/lib/libs/webforms/G1/v202401.ts b/lib/libs/webforms/G1/v202401.ts index ae48189fec..b0c745eebd 100644 --- a/lib/libs/webforms/G1/v202401.ts +++ b/lib/libs/webforms/G1/v202401.ts @@ -150,8 +150,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -165,8 +164,7 @@ export const v202401: FormSchema = { ], }, { - title: - "Cost sharing for non-emergency services provided in a hospital emergency department", + title: "Cost sharing for non-emergency services provided in a hospital emergency department", sectionId: "cost-shar-for-non-emergency", form: [ { @@ -337,8 +335,7 @@ export const v202401: FormSchema = { options: [ { value: "true", - label: - "The state identifies which drugs are considered non-preferred.", + label: "The state identifies which drugs are considered non-preferred.", }, ], }, @@ -348,8 +345,7 @@ export const v202401: FormSchema = { name: "assures-timely-process-limit-cost-shar-imposed", rhf: "Checkbox", rules: { required: "* Required" }, - formItemClassName: - "ml-[0.6rem] px-4 border-l-4 border-l-primary", + formItemClassName: "ml-[0.6rem] px-4 border-l-4 border-l-primary", dependency: { conditions: [ { @@ -375,8 +371,7 @@ export const v202401: FormSchema = { name: "all-drugs-consider-preferred-drugs", rhf: "Checkbox", rules: { required: "* Required" }, - formItemClassName: - "ml-[0.6rem] px-4 my-2 border-l-4 border-l-primary", + formItemClassName: "ml-[0.6rem] px-4 my-2 border-l-4 border-l-primary", dependency: { conditions: [ { diff --git a/lib/libs/webforms/G2A/v202401.ts b/lib/libs/webforms/G2A/v202401.ts index 823a68b4eb..6b422cc7e0 100644 --- a/lib/libs/webforms/G2A/v202401.ts +++ b/lib/libs/webforms/G2A/v202401.ts @@ -2,8 +2,7 @@ import { FormSchema, DefaultFieldGroupProps } from "shared-types"; import { noLeadingTrailingWhitespace } from "shared-utils/regex"; export const v202401: FormSchema = { - header: - "Premiums and cost sharing G2a: Cost-sharing amounts—Categorically needy individuals", + header: "Premiums and cost sharing G2a: Cost-sharing amounts—Categorically needy individuals", subheader: "1916 | 1916A | 42 CFR 447.52 through 447.54", formId: "g2a", sections: [ @@ -39,8 +38,7 @@ export const v202401: FormSchema = { ], }, { - title: - "Services or items with the same cost-sharing amounts for all incomes", + title: "Services or items with the same cost-sharing amounts for all incomes", subsection: true, sectionId: "services-same-all-income", form: [ @@ -53,8 +51,7 @@ export const v202401: FormSchema = { ...DefaultFieldGroupProps, appendText: "Add service or item", removeText: "Remove", - fieldArrayClassName: - DefaultFieldGroupProps.fieldArrayClassName + "space-y-6", + fieldArrayClassName: DefaultFieldGroupProps.fieldArrayClassName + "space-y-6", }, fields: [ { @@ -167,8 +164,7 @@ export const v202401: FormSchema = { ...DefaultFieldGroupProps, appendText: "Add service or item", removeText: "Remove", - fieldArrayClassName: - DefaultFieldGroupProps.fieldArrayClassName + "space-y-6", + fieldArrayClassName: DefaultFieldGroupProps.fieldArrayClassName + "space-y-6", }, fields: [ { @@ -201,8 +197,7 @@ export const v202401: FormSchema = { rhf: "WrappedGroup", name: "wrapped", props: { - wrapperClassName: - "space-between flex-row flex w-full gap-5", + wrapperClassName: "space-between flex-row flex w-full gap-5", }, fields: [ { @@ -240,8 +235,7 @@ export const v202401: FormSchema = { rhf: "WrappedGroup", name: "wrapped", props: { - wrapperClassName: - "space-between flex-row flex w-full gap-5", + wrapperClassName: "space-between flex-row flex w-full gap-5", }, fields: [ { @@ -315,8 +309,7 @@ export const v202401: FormSchema = { rules: { pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -329,8 +322,7 @@ export const v202401: FormSchema = { ], }, { - title: - "Cost sharing for non-preferred drugs charged to otherwise exempt individuals", + title: "Cost sharing for non-preferred drugs charged to otherwise exempt individuals", subsection: true, sectionId: "cost-share-charge-otherwise-exempt", form: [ @@ -402,8 +394,7 @@ export const v202401: FormSchema = { rhf: "WrappedGroup", name: "rateWrapper", props: { - wrapperClassName: - "space-between flex-row flex w-full gap-5", + wrapperClassName: "space-between flex-row flex w-full gap-5", }, fields: [ { @@ -562,8 +553,7 @@ export const v202401: FormSchema = { rhf: "WrappedGroup", name: "rateWrapper", props: { - wrapperClassName: - "space-between flex-row flex w-full gap-5", + wrapperClassName: "space-between flex-row flex w-full gap-5", }, fields: [ { diff --git a/lib/libs/webforms/G2B/v202401.ts b/lib/libs/webforms/G2B/v202401.ts index f86b5665a3..5795ea2956 100644 --- a/lib/libs/webforms/G2B/v202401.ts +++ b/lib/libs/webforms/G2B/v202401.ts @@ -2,8 +2,7 @@ import { FormSchema, DefaultFieldGroupProps } from "shared-types"; import { noLeadingTrailingWhitespace } from "shared-utils/regex"; export const v202401: FormSchema = { - header: - "Premiums and cost sharing G2b: Cost-sharing amounts—Medically needy individuals", + header: "Premiums and cost sharing G2b: Cost-sharing amounts—Medically needy individuals", subheader: "1916 | 1916A | 42 CFR 447.52 through 447.54", formId: "g2b", sections: [ @@ -17,8 +16,7 @@ export const v202401: FormSchema = { name: "state-charge-cost-sharing", rhf: "Select", rules: { required: "* Required" }, - label: - "Does the state charge cost sharing to all medically needy individuals?", + label: "Does the state charge cost sharing to all medically needy individuals?", labelClassName: "font-bold text-[#212121]", props: { className: "w-[125px]", @@ -61,8 +59,7 @@ export const v202401: FormSchema = { }, { - title: - "Services or items with the same cost-sharing amount for all incomes", + title: "Services or items with the same cost-sharing amount for all incomes", sectionId: "services-same-all-incomes", subsection: true, form: [ @@ -220,8 +217,7 @@ export const v202401: FormSchema = { rhf: "WrappedGroup", name: "wrapped", props: { - wrapperClassName: - "space-between flex-row flex w-full gap-5", + wrapperClassName: "space-between flex-row flex w-full gap-5", }, fields: [ { @@ -259,8 +255,7 @@ export const v202401: FormSchema = { rhf: "WrappedGroup", name: "wrapped", props: { - wrapperClassName: - "space-between flex-row flex w-full gap-5", + wrapperClassName: "space-between flex-row flex w-full gap-5", }, fields: [ { @@ -334,8 +329,7 @@ export const v202401: FormSchema = { rules: { pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -349,8 +343,7 @@ export const v202401: FormSchema = { }, { - title: - "Cost sharing for non-preferred drugs charged to otherwise exempt individuals", + title: "Cost sharing for non-preferred drugs charged to otherwise exempt individuals", sectionId: "cost-share-charge-otherwise-exempt", subsection: true, form: [ @@ -422,8 +415,7 @@ export const v202401: FormSchema = { rhf: "WrappedGroup", name: "rateWrapper", props: { - wrapperClassName: - "space-between flex-row flex w-full gap-5", + wrapperClassName: "space-between flex-row flex w-full gap-5", }, fields: [ { @@ -583,8 +575,7 @@ export const v202401: FormSchema = { rhf: "WrappedGroup", name: "rateWrapper", props: { - wrapperClassName: - "space-between flex-row flex w-full gap-5", + wrapperClassName: "space-between flex-row flex w-full gap-5", }, fields: [ { diff --git a/lib/libs/webforms/G2C/v202401.ts b/lib/libs/webforms/G2C/v202401.ts index 81ac3e3888..45c6398342 100644 --- a/lib/libs/webforms/G2C/v202401.ts +++ b/lib/libs/webforms/G2C/v202401.ts @@ -133,8 +133,7 @@ export const v202401: FormSchema = { props: { appendText: "Add service", fieldArrayClassName: - DefaultFieldGroupProps.fieldArrayClassName + - "divider-parent-element", + DefaultFieldGroupProps.fieldArrayClassName + "divider-parent-element", }, fields: [ { @@ -236,8 +235,7 @@ export const v202401: FormSchema = { rules: { pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, diff --git a/lib/libs/webforms/G3/v202401.ts b/lib/libs/webforms/G3/v202401.ts index 2d72cb477b..4725520cad 100644 --- a/lib/libs/webforms/G3/v202401.ts +++ b/lib/libs/webforms/G3/v202401.ts @@ -149,8 +149,7 @@ export const v202401: FormSchema = { subsection: true, form: [ { - description: - "The state may choose to exempt certain groups from cost sharing.", + description: "The state may choose to exempt certain groups from cost sharing.", descriptionClassName: "text-base", slots: [ { @@ -203,8 +202,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -348,8 +346,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -378,8 +375,7 @@ export const v202401: FormSchema = { name: "identify-exempt-from-cost-share", labelClassName: "font-bold text-black", formItemClassName: "border-slate-300 border-t-2 mt-2", - label: - "To identify all other individuals exempt from cost sharing, the state uses:", + label: "To identify all other individuals exempt from cost sharing, the state uses:", rules: { required: "* Required", }, @@ -391,13 +387,11 @@ export const v202401: FormSchema = { }, { value: "eligibility_and_enroll_sys", - label: - "The Eligibility and Enrollment system to flag exempt recipients", + label: "The Eligibility and Enrollment system to flag exempt recipients", }, { value: "medicaid_card_to_indicate", - label: - "The Medicaid card to indicate if a beneficiary is exempt", + label: "The Medicaid card to indicate if a beneficiary is exempt", }, { value: "use_eligi_verif_system", @@ -419,8 +413,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -543,8 +536,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: /^(?:[0-4](?:\.[0-9])?|5(?:\.0)?|\.[0-9])$/, - message: - "Must be between 0% and 5% with max one decimal place", + message: "Must be between 0% and 5% with max one decimal place", }, }, props: { @@ -594,11 +586,9 @@ export const v202401: FormSchema = { { rhf: "Checkbox", name: "how-does-state-track-incurred-prems-and-cost", - label: - "How does the state track each family’s incurred premiums and cost sharing?", + label: "How does the state track each family’s incurred premiums and cost sharing?", labelClassName: "font-bold text-black", - formItemClassName: - "ml-[0.6rem] px-4 mt-2 border-l-4 border-l-primary", + formItemClassName: "ml-[0.6rem] px-4 mt-2 border-l-4 border-l-primary", dependency: { conditions: [ { @@ -634,8 +624,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -658,8 +647,7 @@ export const v202401: FormSchema = { required: "* Required", pattern: { value: noLeadingTrailingWhitespace, - message: - "Must not have leading or trailing whitespace.", + message: "Must not have leading or trailing whitespace.", }, }, }, @@ -675,8 +663,7 @@ export const v202401: FormSchema = { label: "How does the state inform beneficiaries and providers of the beneficiaries' aggregate family limit? How does the state notify beneficiaries and providers when a beneficiary has incurred premiums and cost sharing up to the aggregate family limit and that individual family members are no longer subject to premiums or cost sharing for the remainder of the family's current monthly or quarterly cap period?", labelClassName: "font-bold text-black", - formItemClassName: - "ml-[0.6rem] px-4 mb-2 border-l-4 border-l-primary", + formItemClassName: "ml-[0.6rem] px-4 mb-2 border-l-4 border-l-primary", name: "how-state-bene-agg-fam-limit", dependency: { conditions: [ @@ -703,8 +690,7 @@ export const v202401: FormSchema = { label: "Explain how the state's premium and cost sharing rules do not place beneficiaries at risk of reaching the aggregate family limit.", labelClassName: "font-bold text-black", - formItemClassName: - "ml-[0.6rem] px-4 my-2 border-l-4 border-l-primary", + formItemClassName: "ml-[0.6rem] px-4 my-2 border-l-4 border-l-primary", name: "explain-state-prem-cost-share-dont-place-risk", dependency: { conditions: [ @@ -745,8 +731,7 @@ export const v202401: FormSchema = { rhf: "Textarea", label: "Describe", labelClassName: "font-bold text-black", - formItemClassName: - "ml-[0.6rem] px-4 my-2 border-l-4 border-l-primary", + formItemClassName: "ml-[0.6rem] px-4 my-2 border-l-4 border-l-primary", dependency: { conditions: [ { @@ -817,8 +802,7 @@ export const v202401: FormSchema = { rhf: "Textarea", label: "Describe", labelClassName: "font-bold text-black", - formItemClassName: - "ml-[0.6rem] px-4 my-2 border-l-4 border-l-primary", + formItemClassName: "ml-[0.6rem] px-4 my-2 border-l-4 border-l-primary", dependency: { conditions: [ { diff --git a/lib/local-aspects/iam-permissions-boundary/index.ts b/lib/local-aspects/iam-permissions-boundary/index.ts index cc47d0c61e..20fc544d9d 100644 --- a/lib/local-aspects/iam-permissions-boundary/index.ts +++ b/lib/local-aspects/iam-permissions-boundary/index.ts @@ -14,27 +14,18 @@ export class IamPermissionsBoundaryAspect implements IAspect { // Check if the node is an instance of the higher-level iam.Role construct if (node instanceof iam.Role) { const roleResource = node.node.defaultChild as iam.CfnRole; - roleResource.addPropertyOverride( - "PermissionsBoundary", - this.permissionsBoundaryArn, - ); + roleResource.addPropertyOverride("PermissionsBoundary", this.permissionsBoundaryArn); } // Check if the node is an instance of a low-level CloudFormation resource (CfnRole) else if (node instanceof iam.CfnRole) { - node.addPropertyOverride( - "PermissionsBoundary", - this.permissionsBoundaryArn, - ); + node.addPropertyOverride("PermissionsBoundary", this.permissionsBoundaryArn); } // For roles created by other constructs such as AutoDeleteObjects which may not be of iam.Role or iam.CfnRole else if ( CfnResource.isCfnResource(node) && (node as CfnResource).cfnResourceType === "AWS::IAM::Role" ) { - (node as iam.CfnRole).addPropertyOverride( - "PermissionsBoundary", - this.permissionsBoundaryArn, - ); + (node as iam.CfnRole).addPropertyOverride("PermissionsBoundary", this.permissionsBoundaryArn); } } } diff --git a/lib/local-constructs/clamav-scanning/index.ts b/lib/local-constructs/clamav-scanning/index.ts index 56e7d60028..b712184087 100644 --- a/lib/local-constructs/clamav-scanning/index.ts +++ b/lib/local-constructs/clamav-scanning/index.ts @@ -10,12 +10,7 @@ import * as kms from "aws-cdk-lib/aws-kms"; import * as lambdaEventSources from "aws-cdk-lib/aws-lambda-event-sources"; import * as destinations from "aws-cdk-lib/aws-lambda-destinations"; import * as cr from "aws-cdk-lib/custom-resources"; -import { - ManagedPolicy, - PolicyDocument, - Role, - ServicePrincipal, -} from "aws-cdk-lib/aws-iam"; +import { ManagedPolicy, PolicyDocument, Role, ServicePrincipal } from "aws-cdk-lib/aws-iam"; import { LambdaFunction } from "aws-cdk-lib/aws-events-targets"; import { Rule, RuleTargetInput, Schedule } from "aws-cdk-lib/aws-events"; @@ -113,9 +108,7 @@ export class ClamScanScanner extends Construct { this.lambdaRole = new Role(this, "LambdaExecutionRole", { assumedBy: new ServicePrincipal("lambda.amazonaws.com"), managedPolicies: [ - ManagedPolicy.fromAwsManagedPolicyName( - "service-role/AWSLambdaBasicExecutionRole", - ), + ManagedPolicy.fromAwsManagedPolicyName("service-role/AWSLambdaBasicExecutionRole"), ], inlinePolicies: { LambdaPolicy: new PolicyDocument({ @@ -149,11 +142,7 @@ export class ClamScanScanner extends Construct { resources: ["*"], }), new iam.PolicyStatement({ - actions: [ - "sqs:ReceiveMessage", - "sqs:DeleteMessage", - "sqs:GetQueueAttributes", - ], + actions: ["sqs:ReceiveMessage", "sqs:DeleteMessage", "sqs:GetQueueAttributes"], resources: [notificationQueue.queueArn], }), ], @@ -161,13 +150,9 @@ export class ClamScanScanner extends Construct { }, }); - const clamscanDefsLogGroup = new logs.LogGroup( - this, - `${id}ClamDefsLogGroup`, - { - removalPolicy: cdk.RemovalPolicy.DESTROY, - }, - ); + const clamscanDefsLogGroup = new logs.LogGroup(this, `${id}ClamDefsLogGroup`, { + removalPolicy: cdk.RemovalPolicy.DESTROY, + }); const clamDefsLambda = new DockerImageFunction(this, "ServerlessClamDefs", { code: DockerImageCode.fromImageAsset(__dirname, { @@ -185,13 +170,9 @@ export class ClamScanScanner extends Construct { }, }); - const clamscanLambdaLogGroup = new logs.LogGroup( - this, - `${id}ClamscanLambdaLogGroup`, - { - removalPolicy: cdk.RemovalPolicy.DESTROY, - }, - ); + const clamscanLambdaLogGroup = new logs.LogGroup(this, `${id}ClamscanLambdaLogGroup`, { + removalPolicy: cdk.RemovalPolicy.DESTROY, + }); const clamscanLambda = new DockerImageFunction(this, "ServerlessClamscan", { code: DockerImageCode.fromImageAsset(__dirname), @@ -209,9 +190,7 @@ export class ClamScanScanner extends Construct { }); // Add the SQS queue as an event source to the Lambda function - clamscanLambda.addEventSource( - new lambdaEventSources.SqsEventSource(notificationQueue), - ); + clamscanLambda.addEventSource(new lambdaEventSources.SqsEventSource(notificationQueue)); const rule = new Rule(this, "ClamscanScheduleRule", { schedule: Schedule.expression("cron(0/2 0-6,8-23 * * ? *)"), @@ -263,9 +242,7 @@ export class ClamScanScanner extends Construct { ]), }, ); - const policy = invokeClamDefsCustomResource.node.findChild( - "CustomResourcePolicy", - ); + const policy = invokeClamDefsCustomResource.node.findChild("CustomResourcePolicy"); invokeClamDefsCustomResource.node.addDependency(policy); invokeClamDefsCustomResourceLogGroup.node.addDependency(policy); } diff --git a/lib/local-constructs/clamav-scanning/src/handlers/scan.test.ts b/lib/local-constructs/clamav-scanning/src/handlers/scan.test.ts index 2545393095..5989f5b630 100644 --- a/lib/local-constructs/clamav-scanning/src/handlers/scan.test.ts +++ b/lib/local-constructs/clamav-scanning/src/handlers/scan.test.ts @@ -85,11 +85,7 @@ test("should handle event and return scan results", async () => { expect(downloadFileFromS3).toHaveBeenCalledWith("test-key", "test-bucket"); expect(checkFileExt).toHaveBeenCalledWith("file-location"); expect(scanLocalFile).toHaveBeenCalledWith("file-location"); - expect(tagWithScanStatus).toHaveBeenCalledWith( - "test-bucket", - "test-key", - STATUS_CLEAN_FILE, - ); + expect(tagWithScanStatus).toHaveBeenCalledWith("test-bucket", "test-key", STATUS_CLEAN_FILE); expect(result).toEqual([STATUS_CLEAN_FILE, STATUS_CLEAN_FILE]); }); diff --git a/lib/local-constructs/clamav-scanning/src/handlers/scan.ts b/lib/local-constructs/clamav-scanning/src/handlers/scan.ts index ba736abadc..6cf0138803 100644 --- a/lib/local-constructs/clamav-scanning/src/handlers/scan.ts +++ b/lib/local-constructs/clamav-scanning/src/handlers/scan.ts @@ -37,13 +37,7 @@ export async function handler(event: any): Promise { s3ObjectKey = extractKeyFromS3Event(sqsMessageBody); s3ObjectBucket = extractBucketFromS3Event(sqsMessageBody); } catch (error) { - logger.error( - `Error extracting data from record: ${JSON.stringify( - record, - null, - 2, - )}` + error, - ); + logger.error(`Error extracting data from record: ${JSON.stringify(record, null, 2)}` + error); results.push(STATUS_ERROR_PROCESSING_FILE); continue; } @@ -57,10 +51,7 @@ export async function handler(event: any): Promise { results.push(virusScanStatus); continue; } - const fileLoc: string = await downloadFileFromS3( - s3ObjectKey, - s3ObjectBucket, - ); + const fileLoc: string = await downloadFileFromS3(s3ObjectKey, s3ObjectBucket); virusScanStatus = await checkFileExt(fileLoc); if (virusScanStatus !== STATUS_CLEAN_FILE) { await tagWithScanStatus(s3ObjectBucket, s3ObjectKey, virusScanStatus); diff --git a/lib/local-constructs/clamav-scanning/src/lib/clamav.ts b/lib/local-constructs/clamav-scanning/src/lib/clamav.ts index bed0f133e5..ab54ca8b15 100644 --- a/lib/local-constructs/clamav-scanning/src/lib/clamav.ts +++ b/lib/local-constructs/clamav-scanning/src/lib/clamav.ts @@ -20,10 +20,7 @@ export const updateAVDefinitonsWithFreshclam = (): boolean => { try { const { stdout, stderr }: SpawnSyncReturns = spawnSync( `${constants.PATH_TO_FRESHCLAM}`, - [ - `--config-file=${constants.FRESHCLAM_CONFIG}`, - `--datadir=${constants.FRESHCLAM_WORK_DIR}`, - ], + [`--config-file=${constants.FRESHCLAM_CONFIG}`, `--datadir=${constants.FRESHCLAM_WORK_DIR}`], ); logger.info("Update message"); logger.info(stdout.toString()); @@ -52,54 +49,41 @@ export const downloadAVDefinitions = async (): Promise => { // List all the files in the bucket logger.info("Downloading Definitions"); - const allFileKeys: string[] = await listBucketFiles( - constants.CLAMAV_BUCKET_NAME, - ); + const allFileKeys: string[] = await listBucketFiles(constants.CLAMAV_BUCKET_NAME); const definitionFileKeys: string[] = allFileKeys .filter((key) => key.startsWith(constants.PATH_TO_AV_DEFINITIONS)) .map((fullPath) => path.basename(fullPath)); // Download each file in the bucket - const downloadPromises: Promise[] = definitionFileKeys.map( - (filenameToDownload) => { - return new Promise((resolve, reject) => { - const destinationFile: string = path.join( - constants.FRESHCLAM_WORK_DIR, - filenameToDownload, - ); - - logger.info( - `Downloading ${filenameToDownload} from S3 to ${destinationFile}`, - ); - - const options = { - Bucket: constants.CLAMAV_BUCKET_NAME, - Key: `${constants.PATH_TO_AV_DEFINITIONS}/${filenameToDownload}`, - }; - - try { - s3Client - .send(new GetObjectCommand(options)) - .then(async ({ Body }) => { - if (!Body || !(Body instanceof Readable)) { - throw new Error("Invalid Body type received from S3"); - } - - await asyncfs.writeFile(destinationFile, Body); - resolve(); - logger.info(`Finished download ${filenameToDownload}`); - }); - } catch (err) { - logger.info( - `Error downloading definition file ${filenameToDownload}`, - ); - logger.error(err); - reject(); - } - }); - }, - ); + const downloadPromises: Promise[] = definitionFileKeys.map((filenameToDownload) => { + return new Promise((resolve, reject) => { + const destinationFile: string = path.join(constants.FRESHCLAM_WORK_DIR, filenameToDownload); + + logger.info(`Downloading ${filenameToDownload} from S3 to ${destinationFile}`); + + const options = { + Bucket: constants.CLAMAV_BUCKET_NAME, + Key: `${constants.PATH_TO_AV_DEFINITIONS}/${filenameToDownload}`, + }; + + try { + s3Client.send(new GetObjectCommand(options)).then(async ({ Body }) => { + if (!Body || !(Body instanceof Readable)) { + throw new Error("Invalid Body type received from S3"); + } + + await asyncfs.writeFile(destinationFile, Body); + resolve(); + logger.info(`Finished download ${filenameToDownload}`); + }); + } catch (err) { + logger.info(`Error downloading definition file ${filenameToDownload}`); + logger.error(err); + reject(); + } + }); + }); return await Promise.all(downloadPromises); }; @@ -111,9 +95,7 @@ export const uploadAVDefinitions = async (): Promise => { // delete all the definitions currently in the bucket. // first list them. logger.info("Uploading Definitions"); - const s3AllFullKeys: string[] = await listBucketFiles( - constants.CLAMAV_BUCKET_NAME, - ); + const s3AllFullKeys: string[] = await listBucketFiles(constants.CLAMAV_BUCKET_NAME); const s3DefinitionFileFullKeys: string[] = s3AllFullKeys.filter((key) => key.startsWith(constants.PATH_TO_AV_DEFINITIONS), ); @@ -134,47 +116,37 @@ export const uploadAVDefinitions = async (): Promise => { logger.info(`Deleted extant definitions: ${s3DefinitionFileFullKeys}`); } catch (err) { - logger.info( - `Error deleting current definition files: ${s3DefinitionFileFullKeys}`, - ); + logger.info(`Error deleting current definition files: ${s3DefinitionFileFullKeys}`); logger.info(err); throw err; } } // list all the files in the work dir for upload - const definitionFiles: string[] = fs.readdirSync( - constants.FRESHCLAM_WORK_DIR, - ); - - const uploadPromises: Promise[] = definitionFiles.map( - (filenameToUpload) => { - return new Promise((resolve, reject) => { - logger.info( - `Uploading updated definitions for file ${filenameToUpload} ---`, - ); - - const options = { - Bucket: constants.CLAMAV_BUCKET_NAME, - Key: `${constants.PATH_TO_AV_DEFINITIONS}/${filenameToUpload}`, - Body: fs.readFileSync( - path.join(constants.FRESHCLAM_WORK_DIR, filenameToUpload), - ), - }; - - try { - s3Client.send(new PutObjectCommand(options)).then(() => { - logger.info(`--- Finished uploading ${filenameToUpload} ---`); - resolve(); - }); - } catch (err) { - logger.info(`--- Error uploading ${filenameToUpload} ---`); - logger.info(err); - reject(); - } - }); - }, - ); + const definitionFiles: string[] = fs.readdirSync(constants.FRESHCLAM_WORK_DIR); + + const uploadPromises: Promise[] = definitionFiles.map((filenameToUpload) => { + return new Promise((resolve, reject) => { + logger.info(`Uploading updated definitions for file ${filenameToUpload} ---`); + + const options = { + Bucket: constants.CLAMAV_BUCKET_NAME, + Key: `${constants.PATH_TO_AV_DEFINITIONS}/${filenameToUpload}`, + Body: fs.readFileSync(path.join(constants.FRESHCLAM_WORK_DIR, filenameToUpload)), + }; + + try { + s3Client.send(new PutObjectCommand(options)).then(() => { + logger.info(`--- Finished uploading ${filenameToUpload} ---`); + resolve(); + }); + } catch (err) { + logger.info(`--- Error uploading ${filenameToUpload} ---`); + logger.info(err); + reject(); + } + }); + }); return await Promise.all(uploadPromises); }; @@ -190,9 +162,7 @@ export const uploadAVDefinitions = async (): Promise => { * * @param pathToFile Path in the filesystem where the file is stored. */ -export const scanLocalFile = async ( - pathToFile: string, -): Promise => { +export const scanLocalFile = async (pathToFile: string): Promise => { try { const avResult: SpawnSyncReturns = spawnSync( "clamdscan", diff --git a/lib/local-constructs/clamav-scanning/src/lib/clamd.ts b/lib/local-constructs/clamav-scanning/src/lib/clamd.ts index ff71aab150..f67c2a1e05 100644 --- a/lib/local-constructs/clamav-scanning/src/lib/clamd.ts +++ b/lib/local-constructs/clamav-scanning/src/lib/clamd.ts @@ -61,11 +61,7 @@ export async function startClamd() { if (timePassed >= MAX_WAIT_TIME) { clearInterval(checkClamdReady); - reject( - new Error( - "clamd did not become fully operational within 30 seconds.", - ), - ); + reject(new Error("clamd did not become fully operational within 30 seconds.")); } }, SLEEP_INTERVAL); }); diff --git a/lib/local-constructs/clamav-scanning/src/lib/constants.ts b/lib/local-constructs/clamav-scanning/src/lib/constants.ts index c51cf7619e..c9ba371179 100644 --- a/lib/local-constructs/clamav-scanning/src/lib/constants.ts +++ b/lib/local-constructs/clamav-scanning/src/lib/constants.ts @@ -20,8 +20,7 @@ import process from "process"; // Various paths and application names on S3 export const ATTACHMENTS_BUCKET: string = process.env.ATTACHMENTS_BUCKET!; export const CLAMAV_BUCKET_NAME: string = process.env.CLAMAV_BUCKET_NAME!; -export const PATH_TO_AV_DEFINITIONS: string = - process.env.PATH_TO_AV_DEFINITIONS!; +export const PATH_TO_AV_DEFINITIONS: string = process.env.PATH_TO_AV_DEFINITIONS!; export const PATH_TO_FRESHCLAM: string = "/bin/freshclam"; export const PATH_TO_CLAMAV: string = "/bin/clamscan"; export const FRESHCLAM_CONFIG: string = "/bin/freshclam.conf"; @@ -29,21 +28,16 @@ export const FRESHCLAM_WORK_DIR: string = "/tmp/"; export const TMP_DOWNLOAD_PATH: string = "/tmp/download/"; // Constants for tagging file after a virus scan. -export const STATUS_CLEAN_FILE: string = - process.env.STATUS_CLEAN_FILE || "CLEAN"; -export const STATUS_INFECTED_FILE: string = - process.env.STATUS_INFECTED_FILE || "INFECTED"; +export const STATUS_CLEAN_FILE: string = process.env.STATUS_CLEAN_FILE || "CLEAN"; +export const STATUS_INFECTED_FILE: string = process.env.STATUS_INFECTED_FILE || "INFECTED"; export const STATUS_ERROR_PROCESSING_FILE: string = process.env.STATUS_ERROR_PROCESSING_FILE || "ERROR"; -export const STATUS_SKIPPED_FILE: string = - process.env.STATUS_SKIPPED_FILE || "SKIPPED"; +export const STATUS_SKIPPED_FILE: string = process.env.STATUS_SKIPPED_FILE || "SKIPPED"; export const STATUS_EXTENSION_MISMATCH_FILE: string = process.env.STATUS_EXTENSION_MISMATCH_FILE || "EXTMISMATCH"; -export const STATUS_UNKNOWN_EXTENSION: string = - process.env.STATUS_UNKNOWN_EXTENSION || "UKNOWNEXT"; +export const STATUS_UNKNOWN_EXTENSION: string = process.env.STATUS_UNKNOWN_EXTENSION || "UKNOWNEXT"; export const STATUS_TOO_BIG: string = process.env.STATUS_TOO_BIG || "TOOBIG"; -export const VIRUS_SCAN_STATUS_KEY: string = - process.env.VIRUS_SCAN_STATUS_KEY || "virusScanStatus"; +export const VIRUS_SCAN_STATUS_KEY: string = process.env.VIRUS_SCAN_STATUS_KEY || "virusScanStatus"; export const VIRUS_SCAN_TIMESTAMP_KEY: string = process.env.VIRUS_SCAN_TIMESTAMP_KEY || "virusScanTimestamp"; export const MAX_FILE_SIZE: string = process.env.MAX_FILE_SIZE || "314572800"; diff --git a/lib/local-constructs/clamav-scanning/src/lib/file-ext.ts b/lib/local-constructs/clamav-scanning/src/lib/file-ext.ts index f86b629e99..22a238fb80 100644 --- a/lib/local-constructs/clamav-scanning/src/lib/file-ext.ts +++ b/lib/local-constructs/clamav-scanning/src/lib/file-ext.ts @@ -37,10 +37,7 @@ export async function checkFileExt(pathToFile: string): Promise { logger.info(`File mimetype from contents: ${mimeTypeFromContents}`); // Check if the mimes are equivalent - const same = areMimeTypesEquivalent( - mimeTypeFromExtension, - mimeTypeFromContents, - ); + const same = areMimeTypesEquivalent(mimeTypeFromExtension, mimeTypeFromContents); // Error out if we can't determine equivalence if (!same) { logger.info( @@ -61,9 +58,7 @@ function isAllowedMime(mime: string): boolean { return FILE_TYPES.some((fileType) => fileType.mime === mime); } -async function getFileTypeFromContents( - filePath: string, -): Promise { +async function getFileTypeFromContents(filePath: string): Promise { try { const fileBuffer = await fs.promises.readFile(filePath); @@ -90,9 +85,7 @@ async function getFileTypeFromContents( } } if (!type?.mime) { - logger.info( - `getFileTypeFromContents: File determined to be mime:${type?.mime}`, - ); + logger.info(`getFileTypeFromContents: File determined to be mime:${type?.mime}`); return false; } logger.info( diff --git a/lib/local-constructs/clamav-scanning/src/lib/s3.ts b/lib/local-constructs/clamav-scanning/src/lib/s3.ts index 2e0addb3db..40d24b8cc1 100644 --- a/lib/local-constructs/clamav-scanning/src/lib/s3.ts +++ b/lib/local-constructs/clamav-scanning/src/lib/s3.ts @@ -16,10 +16,7 @@ import { Readable } from "stream"; const s3Client: S3Client = new S3Client(); -export async function checkFileSize( - key: string, - bucket: string, -): Promise { +export async function checkFileSize(key: string, bucket: string): Promise { try { const res: HeadObjectCommandOutput = await s3Client.send( new HeadObjectCommand({ Key: key, Bucket: bucket }), @@ -29,9 +26,7 @@ export async function checkFileSize( res.ContentLength === null || typeof res.ContentLength !== "number" ) { - logger.info( - `ContentLength is invalid for S3 Object: s3://${bucket}/${key}`, - ); + logger.info(`ContentLength is invalid for S3 Object: s3://${bucket}/${key}`); return constants.STATUS_ERROR_PROCESSING_FILE; } return res.ContentLength > parseInt(constants.MAX_FILE_SIZE) @@ -51,9 +46,7 @@ export async function downloadFileFromS3( fs.mkdirSync(constants.TMP_DOWNLOAD_PATH); } - const localPath: string = `${ - constants.TMP_DOWNLOAD_PATH - }${randomUUID()}--${s3ObjectKey}`; + const localPath: string = `${constants.TMP_DOWNLOAD_PATH}${randomUUID()}--${s3ObjectKey}`; fs.createWriteStream(localPath); logger.info(`Downloading file s3://${s3ObjectBucket}/${s3ObjectKey}`); @@ -109,9 +102,7 @@ export async function tagWithScanStatus( export async function listBucketFiles(bucketName: string): Promise { try { - const listFilesResult = await s3Client.send( - new ListObjectsV2Command({ Bucket: bucketName }), - ); + const listFilesResult = await s3Client.send(new ListObjectsV2Command({ Bucket: bucketName })); if (listFilesResult.Contents) { const keys = listFilesResult.Contents.map((c) => c.Key) as string[]; return keys; diff --git a/lib/local-constructs/cleanup-kafka/index.test.ts b/lib/local-constructs/cleanup-kafka/index.test.ts index 795533d4fa..6441ec326c 100644 --- a/lib/local-constructs/cleanup-kafka/index.test.ts +++ b/lib/local-constructs/cleanup-kafka/index.test.ts @@ -19,9 +19,7 @@ describe("CleanupKafka", () => { availabilityZone: "us-west-2a", }), ]; - const securityGroups = [ - new ec2.SecurityGroup(stack, "SecurityGroup", { vpc }), - ]; + const securityGroups = [new ec2.SecurityGroup(stack, "SecurityGroup", { vpc })]; const brokerString = "mockBrokerString"; const topicPatternsToDelete = ["mockTopicPattern"]; @@ -34,9 +32,7 @@ describe("CleanupKafka", () => { }); it("should create a log group for the Lambda function", () => { - const logGroup = cleanupKafka.node.findChild( - "cleanupKafkaLogGroup", - ) as logs.LogGroup; + const logGroup = cleanupKafka.node.findChild("cleanupKafkaLogGroup") as logs.LogGroup; expect(logGroup).toBeInstanceOf(logs.LogGroup); }); diff --git a/lib/local-constructs/cleanup-kafka/index.ts b/lib/local-constructs/cleanup-kafka/index.ts index 749a68166e..155ef13255 100644 --- a/lib/local-constructs/cleanup-kafka/index.ts +++ b/lib/local-constructs/cleanup-kafka/index.ts @@ -32,13 +32,7 @@ export class CleanupKafka extends Construct { constructor(scope: Construct, id: string, props: CleanupKafkaProps) { super(scope, id); - const { - vpc, - privateSubnets, - securityGroups, - brokerString, - topicPatternsToDelete, - } = props; + const { vpc, privateSubnets, securityGroups, brokerString, topicPatternsToDelete } = props; const logGroup = new LogGroup(this, `cleanupKafkaLogGroup`, { removalPolicy: RemovalPolicy.DESTROY, @@ -53,12 +47,8 @@ export class CleanupKafka extends Construct { role: new Role(this, "CleanupKafkaLambdaExecutionRole", { assumedBy: new ServicePrincipal("lambda.amazonaws.com"), managedPolicies: [ - ManagedPolicy.fromAwsManagedPolicyName( - "service-role/AWSLambdaBasicExecutionRole", - ), - ManagedPolicy.fromAwsManagedPolicyName( - "service-role/AWSLambdaVPCAccessExecutionRole", - ), + ManagedPolicy.fromAwsManagedPolicyName("service-role/AWSLambdaBasicExecutionRole"), + ManagedPolicy.fromAwsManagedPolicyName("service-role/AWSLambdaVPCAccessExecutionRole"), ], inlinePolicies: { InvokeLambdaPolicy: new PolicyDocument({ @@ -81,47 +71,39 @@ export class CleanupKafka extends Construct { bundling: commonBundlingOptions, }); - const customResourceLogGroup = new LogGroup( - this, - `cleanupKafkaCustomResourceLogGroup`, - { - removalPolicy: RemovalPolicy.DESTROY, - }, - ); + const customResourceLogGroup = new LogGroup(this, `cleanupKafkaCustomResourceLogGroup`, { + removalPolicy: RemovalPolicy.DESTROY, + }); - const customResource = new AwsCustomResource( - this, - "CleanupKafkaCustomResource", - { - onDelete: { - service: "Lambda", - action: "invoke", - parameters: { - FunctionName: lambda.functionName, - Payload: JSON.stringify({ - RequestType: "Delete", - ResourceProperties: { - brokerString, - topicPatternsToDelete, - }, - }), - }, - physicalResourceId: PhysicalResourceId.of("cleanup-kafka"), - }, - logGroup: customResourceLogGroup, - policy: AwsCustomResourcePolicy.fromStatements([ - new PolicyStatement({ - actions: ["lambda:InvokeFunction"], - resources: [lambda.functionArn], - }), - new PolicyStatement({ - effect: Effect.DENY, - actions: ["logs:CreateLogGroup"], - resources: ["*"], + const customResource = new AwsCustomResource(this, "CleanupKafkaCustomResource", { + onDelete: { + service: "Lambda", + action: "invoke", + parameters: { + FunctionName: lambda.functionName, + Payload: JSON.stringify({ + RequestType: "Delete", + ResourceProperties: { + brokerString, + topicPatternsToDelete, + }, }), - ]), + }, + physicalResourceId: PhysicalResourceId.of("cleanup-kafka"), }, - ); + logGroup: customResourceLogGroup, + policy: AwsCustomResourcePolicy.fromStatements([ + new PolicyStatement({ + actions: ["lambda:InvokeFunction"], + resources: [lambda.functionArn], + }), + new PolicyStatement({ + effect: Effect.DENY, + actions: ["logs:CreateLogGroup"], + resources: ["*"], + }), + ]), + }); const policy = customResource.node.findChild("CustomResourcePolicy"); customResource.node.addDependency(policy); customResourceLogGroup.node.addDependency(policy); diff --git a/lib/local-constructs/cleanup-kafka/src/cleanupKafka.test.ts b/lib/local-constructs/cleanup-kafka/src/cleanupKafka.test.ts index e04425d2f7..cf0b5f9dd5 100644 --- a/lib/local-constructs/cleanup-kafka/src/cleanupKafka.test.ts +++ b/lib/local-constructs/cleanup-kafka/src/cleanupKafka.test.ts @@ -30,10 +30,7 @@ describe("handler", () => { await handler(event, context); - expect(topics.deleteTopics).toHaveBeenCalledWith( - BrokerString, - TopicPatternsToDelete, - ); + expect(topics.deleteTopics).toHaveBeenCalledWith(BrokerString, TopicPatternsToDelete); expect(topics.deleteTopics).toHaveBeenCalledTimes(1); }); diff --git a/lib/local-constructs/cleanup-kafka/src/cleanupKafka.ts b/lib/local-constructs/cleanup-kafka/src/cleanupKafka.ts index 90a3cd72f4..8c21e516aa 100644 --- a/lib/local-constructs/cleanup-kafka/src/cleanupKafka.ts +++ b/lib/local-constructs/cleanup-kafka/src/cleanupKafka.ts @@ -1,14 +1,11 @@ import { CloudFormationCustomResourceEvent } from "aws-lambda"; import * as topics from "../../../libs/topics-lib"; -export const handler = async function ( - event: CloudFormationCustomResourceEvent, -): Promise { +export const handler = async function (event: CloudFormationCustomResourceEvent): Promise { console.log("Request:", JSON.stringify(event, undefined, 2)); const BrokerString: string = event.ResourceProperties.brokerString; - const TopicPatternsToDelete: string[] = - event.ResourceProperties.topicPatternsToDelete; + const TopicPatternsToDelete: string[] = event.ResourceProperties.topicPatternsToDelete; const requiredPattern = /^--.*--.*--/; // Regular expression to match the required format TopicPatternsToDelete.forEach((pattern) => { @@ -17,9 +14,7 @@ export const handler = async function ( } }); - console.log( - `Attempting a delete for each of the following patterns: ${TopicPatternsToDelete}`, - ); + console.log(`Attempting a delete for each of the following patterns: ${TopicPatternsToDelete}`); const maxRetries = 10; const retryDelay = 10000; //10s @@ -30,15 +25,9 @@ export const handler = async function ( await topics.deleteTopics(BrokerString, TopicPatternsToDelete); success = true; } catch (error) { - console.error( - `Error in deleteTopics operation: ${JSON.stringify(error)}`, - ); + console.error(`Error in deleteTopics operation: ${JSON.stringify(error)}`); retries++; - console.log( - `Retrying in ${ - retryDelay / 1000 - } seconds (Retry ${retries}/${maxRetries})`, - ); + console.log(`Retrying in ${retryDelay / 1000} seconds (Retry ${retries}/${maxRetries})`); await new Promise((resolve) => setTimeout(resolve, retryDelay)); } } diff --git a/lib/local-constructs/cloudwatch-logs-resource-policy/index.ts b/lib/local-constructs/cloudwatch-logs-resource-policy/index.ts index 974e996670..0fd54ae7b3 100644 --- a/lib/local-constructs/cloudwatch-logs-resource-policy/index.ts +++ b/lib/local-constructs/cloudwatch-logs-resource-policy/index.ts @@ -9,40 +9,32 @@ interface CloudWatchLogsResourcePolicyProps { export class CloudWatchLogsResourcePolicy extends Construct { public readonly policy: CfnResourcePolicy; - constructor( - scope: Construct, - id: string, - props: CloudWatchLogsResourcePolicyProps, - ) { + constructor(scope: Construct, id: string, props: CloudWatchLogsResourcePolicyProps) { super(scope, id); const stack = Stack.of(this); - this.policy = new CfnResourcePolicy( - this, - `CentralizedCloudWatchLogsResourcePolicy`, - { - policyName: `${props.project}-centralized-logs-policy-${id}`, - policyDocument: JSON.stringify({ - Version: "2012-10-17", - Statement: [ - { - Effect: "Allow", - Principal: { Service: "delivery.logs.amazonaws.com" }, - Action: ["logs:CreateLogStream", "logs:PutLogEvents"], - Resource: [ - `arn:aws:logs:*:${stack.account}:log-group:aws-waf-logs-*`, - `arn:aws:logs:*:${stack.account}:log-group:/aws/http-api/*`, - `arn:aws:logs:*:${stack.account}:log-group:/aws/vendedlogs/*`, - ], - Condition: { - StringEquals: { "aws:SourceAccount": stack.account }, - ArnLike: { - "aws:SourceArn": `arn:aws:logs:${stack.region}:${stack.account}:*`, - }, + this.policy = new CfnResourcePolicy(this, `CentralizedCloudWatchLogsResourcePolicy`, { + policyName: `${props.project}-centralized-logs-policy-${id}`, + policyDocument: JSON.stringify({ + Version: "2012-10-17", + Statement: [ + { + Effect: "Allow", + Principal: { Service: "delivery.logs.amazonaws.com" }, + Action: ["logs:CreateLogStream", "logs:PutLogEvents"], + Resource: [ + `arn:aws:logs:*:${stack.account}:log-group:aws-waf-logs-*`, + `arn:aws:logs:*:${stack.account}:log-group:/aws/http-api/*`, + `arn:aws:logs:*:${stack.account}:log-group:/aws/vendedlogs/*`, + ], + Condition: { + StringEquals: { "aws:SourceAccount": stack.account }, + ArnLike: { + "aws:SourceArn": `arn:aws:logs:${stack.region}:${stack.account}:*`, }, }, - ], - }), - }, - ); + }, + ], + }), + }); } } diff --git a/lib/local-constructs/cloudwatch-to-s3/index.test.ts b/lib/local-constructs/cloudwatch-to-s3/index.test.ts index 736bce440c..256f0244b8 100644 --- a/lib/local-constructs/cloudwatch-to-s3/index.test.ts +++ b/lib/local-constructs/cloudwatch-to-s3/index.test.ts @@ -31,22 +31,15 @@ describe("CloudWatchToS3", () => { }); it("should create IAM roles with appropriate policies", () => { - const firehoseRole = cloudWatchToS3.node.findChild( - "FirehoseRole", - ) as iam.Role; + const firehoseRole = cloudWatchToS3.node.findChild("FirehoseRole") as iam.Role; expect(firehoseRole).toBeInstanceOf(iam.Role); - const policyDocument = - firehoseRole.assumeRolePolicy?.toJSON() as iam.PolicyDocumentProps; - const statement = policyDocument.Statement.find( - (s) => s.Principal && s.Principal.Service, - ); + const policyDocument = firehoseRole.assumeRolePolicy?.toJSON() as iam.PolicyDocumentProps; + const statement = policyDocument.Statement.find((s) => s.Principal && s.Principal.Service); expect(statement).toBeDefined(); expect(statement.Principal.Service).toContain("firehose.amazonaws.com"); - const policy = firehoseRole.node.tryFindChild( - "DefaultPolicy", - ) as iam.Policy; + const policy = firehoseRole.node.tryFindChild("DefaultPolicy") as iam.Policy; const statements = policy.document.statements; expect(statements).toEqual( expect.arrayContaining([ diff --git a/lib/local-constructs/cloudwatch-to-s3/index.ts b/lib/local-constructs/cloudwatch-to-s3/index.ts index 584e0562f9..a66fcf02f1 100644 --- a/lib/local-constructs/cloudwatch-to-s3/index.ts +++ b/lib/local-constructs/cloudwatch-to-s3/index.ts @@ -2,12 +2,7 @@ import * as cdk from "aws-cdk-lib"; import { Construct } from "constructs"; import { Bucket } from "aws-cdk-lib/aws-s3"; import { CfnDeliveryStream } from "aws-cdk-lib/aws-kinesisfirehose"; -import { - Role, - ServicePrincipal, - PolicyStatement, - PolicyDocument, -} from "aws-cdk-lib/aws-iam"; +import { Role, ServicePrincipal, PolicyStatement, PolicyDocument } from "aws-cdk-lib/aws-iam"; import { LogGroup, CfnSubscriptionFilter } from "aws-cdk-lib/aws-logs"; interface CloudWatchToS3Props { @@ -76,9 +71,7 @@ export class CloudWatchToS3 extends Construct { statements: [ new PolicyStatement({ actions: ["firehose:PutRecord", "firehose:PutRecordBatch"], - resources: [ - cdk.Fn.getAtt(this.deliveryStream.logicalId, "Arn").toString(), - ], + resources: [cdk.Fn.getAtt(this.deliveryStream.logicalId, "Arn").toString()], }), ], }), @@ -89,10 +82,7 @@ export class CloudWatchToS3 extends Construct { new CfnSubscriptionFilter(this, "SubscriptionFilter", { logGroupName: logGroup.logGroupName, filterPattern: filterPattern, - destinationArn: cdk.Fn.getAtt( - this.deliveryStream.logicalId, - "Arn", - ).toString(), + destinationArn: cdk.Fn.getAtt(this.deliveryStream.logicalId, "Arn").toString(), roleArn: subscriptionFilterRole.roleArn, }); } diff --git a/lib/local-constructs/create-topics/index.test.ts b/lib/local-constructs/create-topics/index.test.ts index 6d13b06e78..c72f5e01f7 100644 --- a/lib/local-constructs/create-topics/index.test.ts +++ b/lib/local-constructs/create-topics/index.test.ts @@ -19,9 +19,7 @@ describe("CreateTopics", () => { availabilityZone: "us-west-2a", }), ]; - const securityGroups = [ - new ec2.SecurityGroup(stack, "SecurityGroup", { vpc }), - ]; + const securityGroups = [new ec2.SecurityGroup(stack, "SecurityGroup", { vpc })]; const brokerString = "mockBrokerString"; const topics = [{ topic: "mockTopic1" }, { topic: "mockTopic2" }]; @@ -34,16 +32,12 @@ describe("CreateTopics", () => { }); it("should create a log group for the Lambda function", () => { - const lambdaLogGroup = createTopics.node.findChild( - "CreateTopicsLogGroup", - ) as logs.LogGroup; + const lambdaLogGroup = createTopics.node.findChild("CreateTopicsLogGroup") as logs.LogGroup; expect(lambdaLogGroup).toBeInstanceOf(logs.LogGroup); }); it("should create a Lambda function with appropriate properties", () => { - const lambdaFunction = createTopics.node.findChild( - "CreateTopicsLambda", - ) as lambda.Function; + const lambdaFunction = createTopics.node.findChild("CreateTopicsLambda") as lambda.Function; expect(lambdaFunction).toBeInstanceOf(lambda.Function); expect(lambdaFunction.runtime).toBe(lambda.Runtime.NODEJS_18_X); expect(lambdaFunction.timeout?.toMinutes()).toBe(5); @@ -64,9 +58,7 @@ describe("CreateTopics", () => { }); it("should create a custom resource to invoke the Lambda function", () => { - const customResource = createTopics.node.findChild( - "CustomResource", - ) as cr.AwsCustomResource; + const customResource = createTopics.node.findChild("CustomResource") as cr.AwsCustomResource; expect(customResource).toBeInstanceOf(cr.AwsCustomResource); const customResourceLogGroup = createTopics.node.findChild( diff --git a/lib/local-constructs/create-topics/index.ts b/lib/local-constructs/create-topics/index.ts index e56ac8b273..9b7da9d576 100644 --- a/lib/local-constructs/create-topics/index.ts +++ b/lib/local-constructs/create-topics/index.ts @@ -47,12 +47,8 @@ export class CreateTopics extends Construct { role: new Role(this, "CreateTopicsLambdaExecutionRole", { assumedBy: new ServicePrincipal("lambda.amazonaws.com"), managedPolicies: [ - ManagedPolicy.fromAwsManagedPolicyName( - "service-role/AWSLambdaBasicExecutionRole", - ), - ManagedPolicy.fromAwsManagedPolicyName( - "service-role/AWSLambdaVPCAccessExecutionRole", - ), + ManagedPolicy.fromAwsManagedPolicyName("service-role/AWSLambdaBasicExecutionRole"), + ManagedPolicy.fromAwsManagedPolicyName("service-role/AWSLambdaVPCAccessExecutionRole"), ], inlinePolicies: { InvokeLambdaPolicy: new PolicyDocument({ @@ -75,13 +71,9 @@ export class CreateTopics extends Construct { bundling: commonBundlingOptions, }); - const customResourceLogGroup = new LogGroup( - this, - `createTopicsCustomResourceLogGroup`, - { - removalPolicy: RemovalPolicy.DESTROY, - }, - ); + const customResourceLogGroup = new LogGroup(this, `createTopicsCustomResourceLogGroup`, { + removalPolicy: RemovalPolicy.DESTROY, + }); const customResource = new AwsCustomResource(this, "CustomResource", { onCreate: { diff --git a/lib/local-constructs/create-topics/src/createTopics.test.ts b/lib/local-constructs/create-topics/src/createTopics.test.ts index afbd65f816..adc29dcdf7 100644 --- a/lib/local-constructs/create-topics/src/createTopics.test.ts +++ b/lib/local-constructs/create-topics/src/createTopics.test.ts @@ -11,9 +11,7 @@ describe("handler", () => { { topic: "validTopic", numPartitions: 3, replicationFactor: 3 }, { topic: "anotherValidTopic", numPartitions: 1, replicationFactor: 3 }, ]; - const invalidTopicsToCreateNoName = [ - { topic: "", numPartitions: 3, replicationFactor: 3 }, - ]; + const invalidTopicsToCreateNoName = [{ topic: "", numPartitions: 3, replicationFactor: 3 }]; const invalidTopicsToCreateLowReplication = [ { topic: "validTopic", numPartitions: 3, replicationFactor: 2 }, ]; @@ -41,10 +39,7 @@ describe("handler", () => { await handler(event, context); - expect(topics.createTopics).toHaveBeenCalledWith( - brokerString, - validTopicsToCreate, - ); + expect(topics.createTopics).toHaveBeenCalledWith(brokerString, validTopicsToCreate); expect(topics.createTopics).toHaveBeenCalledTimes(1); }); diff --git a/lib/local-constructs/create-topics/src/createTopics.ts b/lib/local-constructs/create-topics/src/createTopics.ts index 967d2c88b9..19fa0fbb6f 100644 --- a/lib/local-constructs/create-topics/src/createTopics.ts +++ b/lib/local-constructs/create-topics/src/createTopics.ts @@ -7,16 +7,12 @@ interface TopicConfig { replicationFactor: number; } -export const handler = async function ( - event: CloudFormationCustomResourceEvent, -) { +export const handler = async function (event: CloudFormationCustomResourceEvent) { console.log("Request:", JSON.stringify(event, undefined, 2)); const resourceProperties = event.ResourceProperties; const topicsToCreate: TopicConfig[] = resourceProperties.topicsToCreate; const brokerString: string = resourceProperties.brokerString; - const topicConfig: TopicConfig[] = topicsToCreate.map(function ( - element: TopicConfig, - ) { + const topicConfig: TopicConfig[] = topicsToCreate.map(function (element: TopicConfig) { const topic: string = element.topic; const replicationFactor: number = element.replicationFactor || 3; const numPartitions: number = element.numPartitions ?? 1; diff --git a/lib/local-constructs/empty-buckets/index.test.ts b/lib/local-constructs/empty-buckets/index.test.ts index d4940cc4fa..ee7a53e76d 100644 --- a/lib/local-constructs/empty-buckets/index.test.ts +++ b/lib/local-constructs/empty-buckets/index.test.ts @@ -21,16 +21,12 @@ describe("EmptyBuckets", () => { }); it("should create a log group for the Lambda function", () => { - const lambdaLogGroup = emptyBuckets.node.findChild( - "LambdaLogGroup", - ) as logs.LogGroup; + const lambdaLogGroup = emptyBuckets.node.findChild("LambdaLogGroup") as logs.LogGroup; expect(lambdaLogGroup).toBeInstanceOf(logs.LogGroup); }); it("should create a Lambda function with appropriate properties", () => { - const lambdaFunction = emptyBuckets.node.findChild( - "Lambda", - ) as lambda.Function; + const lambdaFunction = emptyBuckets.node.findChild("Lambda") as lambda.Function; expect(lambdaFunction).toBeInstanceOf(lambda.Function); expect(lambdaFunction.runtime).toBe(lambda.Runtime.NODEJS_18_X); expect(lambdaFunction.timeout?.toMinutes()).toBe(15); @@ -69,9 +65,7 @@ describe("EmptyBuckets", () => { }); it("should create a custom resource to invoke the Lambda function", () => { - const customResource = emptyBuckets.node.findChild( - "CustomResource", - ) as cr.AwsCustomResource; + const customResource = emptyBuckets.node.findChild("CustomResource") as cr.AwsCustomResource; expect(customResource).toBeInstanceOf(cr.AwsCustomResource); const customResourceLogGroup = emptyBuckets.node.findChild( diff --git a/lib/local-constructs/empty-buckets/index.ts b/lib/local-constructs/empty-buckets/index.ts index ad14f41a62..4082f29f32 100644 --- a/lib/local-constructs/empty-buckets/index.ts +++ b/lib/local-constructs/empty-buckets/index.ts @@ -66,9 +66,7 @@ export class EmptyBuckets extends Construct { const lambdaRole = new Role(this, "LambdaRole", { assumedBy: new ServicePrincipal("lambda.amazonaws.com"), managedPolicies: [ - ManagedPolicy.fromAwsManagedPolicyName( - "service-role/AWSLambdaBasicExecutionRole", - ), + ManagedPolicy.fromAwsManagedPolicyName("service-role/AWSLambdaBasicExecutionRole"), ], inlinePolicies: { LambdaPolicy: new PolicyDocument({ diff --git a/lib/local-constructs/manage-users/index.test.ts b/lib/local-constructs/manage-users/index.test.ts index b6c8b9779a..c95500255c 100644 --- a/lib/local-constructs/manage-users/index.test.ts +++ b/lib/local-constructs/manage-users/index.test.ts @@ -16,25 +16,15 @@ describe("ManageUsers", () => { const users = [{ username: "user1" }, { username: "user2" }]; const passwordSecretArn = "mockPasswordSecretArn"; // pragma: allowlist secret - const manageUsers = new ManageUsers( - stack, - "ManageUsers", - userPool, - users, - passwordSecretArn, - ); + const manageUsers = new ManageUsers(stack, "ManageUsers", userPool, users, passwordSecretArn); it("should create a log group for the Lambda function", () => { - const lambdaLogGroup = manageUsers.node.findChild( - "LambdaLogGroup", - ) as logs.LogGroup; + const lambdaLogGroup = manageUsers.node.findChild("LambdaLogGroup") as logs.LogGroup; expect(lambdaLogGroup).toBeInstanceOf(logs.LogGroup); }); it("should create a Lambda function with appropriate properties", () => { - const lambdaFunction = manageUsers.node.findChild( - "LambdaFunction", - ) as lambda.Function; + const lambdaFunction = manageUsers.node.findChild("LambdaFunction") as lambda.Function; expect(lambdaFunction).toBeInstanceOf(lambda.Function); expect(lambdaFunction.runtime).toBe(lambda.Runtime.NODEJS_18_X); expect(lambdaFunction.timeout?.toMinutes()).toBe(5); diff --git a/lib/local-constructs/manage-users/index.ts b/lib/local-constructs/manage-users/index.ts index ffe997b27e..043cc98f93 100644 --- a/lib/local-constructs/manage-users/index.ts +++ b/lib/local-constructs/manage-users/index.ts @@ -44,9 +44,7 @@ export class ManageUsers extends Construct { role: new Role(this, "LambdaExecutionRole", { assumedBy: new ServicePrincipal("lambda.amazonaws.com"), managedPolicies: [ - ManagedPolicy.fromAwsManagedPolicyName( - "service-role/AWSLambdaBasicExecutionRole", - ), + ManagedPolicy.fromAwsManagedPolicyName("service-role/AWSLambdaBasicExecutionRole"), ], inlinePolicies: { LambdaAssumeRolePolicy: new PolicyDocument({ @@ -68,10 +66,7 @@ export class ManageUsers extends Construct { }), new PolicyStatement({ effect: Effect.ALLOW, - actions: [ - "secretsmanager:GetSecretValue", - "secretsmanager:DescribeSecret", - ], + actions: ["secretsmanager:GetSecretValue", "secretsmanager:DescribeSecret"], resources: ["*"], }), ], @@ -81,64 +76,56 @@ export class ManageUsers extends Construct { bundling: commonBundlingOptions, }); - const customResourceLogGroup = new LogGroup( - this, - `CustomResourceLogGroup`, - { - removalPolicy: RemovalPolicy.DESTROY, - }, - ); + const customResourceLogGroup = new LogGroup(this, `CustomResourceLogGroup`, { + removalPolicy: RemovalPolicy.DESTROY, + }); - const customResource = new AwsCustomResource( - this, - "CleanupKafkaCustomResource", - { - onCreate: { - service: "Lambda", - action: "invoke", - parameters: { - FunctionName: manageUsers.functionName, - Payload: JSON.stringify({ - RequestType: "Create", - ResourceProperties: { - userPoolId: userPool.userPoolId, - users, - passwordSecretArn: passwordSecretArn, - }, - }), - }, - physicalResourceId: PhysicalResourceId.of("manage-users"), - }, - onUpdate: { - service: "Lambda", - action: "invoke", - parameters: { - FunctionName: manageUsers.functionName, - Payload: JSON.stringify({ - RequestType: "Update", - ResourceProperties: { - userPoolId: userPool.userPoolId, - users, - passwordSecretArn: passwordSecretArn, - }, - }), - }, - physicalResourceId: PhysicalResourceId.of("manage-users"), - }, - logGroup: customResourceLogGroup, - policy: AwsCustomResourcePolicy.fromStatements([ - new PolicyStatement({ - actions: ["lambda:InvokeFunction"], - resources: [manageUsers.functionArn], + const customResource = new AwsCustomResource(this, "CleanupKafkaCustomResource", { + onCreate: { + service: "Lambda", + action: "invoke", + parameters: { + FunctionName: manageUsers.functionName, + Payload: JSON.stringify({ + RequestType: "Create", + ResourceProperties: { + userPoolId: userPool.userPoolId, + users, + passwordSecretArn: passwordSecretArn, + }, }), - new PolicyStatement({ - effect: Effect.DENY, - actions: ["logs:CreateLogGroup"], - resources: ["*"], + }, + physicalResourceId: PhysicalResourceId.of("manage-users"), + }, + onUpdate: { + service: "Lambda", + action: "invoke", + parameters: { + FunctionName: manageUsers.functionName, + Payload: JSON.stringify({ + RequestType: "Update", + ResourceProperties: { + userPoolId: userPool.userPoolId, + users, + passwordSecretArn: passwordSecretArn, + }, }), - ]), + }, + physicalResourceId: PhysicalResourceId.of("manage-users"), }, - ); + logGroup: customResourceLogGroup, + policy: AwsCustomResourcePolicy.fromStatements([ + new PolicyStatement({ + actions: ["lambda:InvokeFunction"], + resources: [manageUsers.functionArn], + }), + new PolicyStatement({ + effect: Effect.DENY, + actions: ["logs:CreateLogGroup"], + resources: ["*"], + }), + ]), + }); const policy = customResource.node.findChild("CustomResourcePolicy"); customResource.node.addDependency(policy); customResourceLogGroup.node.addDependency(policy); diff --git a/lib/local-constructs/waf/index.test.ts b/lib/local-constructs/waf/index.test.ts index b1da08b32e..7ab2767d2c 100644 --- a/lib/local-constructs/waf/index.test.ts +++ b/lib/local-constructs/waf/index.test.ts @@ -17,12 +17,7 @@ describe("WafConstruct", () => { awsBadInputsExcludeRules: ["BadInputsRule1"], }; - const wafConstruct = new WafConstruct( - stack, - "WafConstruct", - props, - "REGIONAL", - ); + const wafConstruct = new WafConstruct(stack, "WafConstruct", props, "REGIONAL"); it("should create a log group with appropriate properties", () => { const logGroup = wafConstruct.logGroup; @@ -46,9 +41,7 @@ describe("WafConstruct", () => { .node.findChild("LoggingConfiguration") as wafv2.CfnLoggingConfiguration; expect(loggingConfiguration).toBeInstanceOf(wafv2.CfnLoggingConfiguration); expect(loggingConfiguration.resourceArn).toBe(wafConstruct.webAcl.attrArn); - expect(loggingConfiguration.logDestinationConfigs).toContain( - wafConstruct.logGroup.logGroupArn, - ); + expect(loggingConfiguration.logDestinationConfigs).toContain(wafConstruct.logGroup.logGroupArn); }); }); @@ -103,9 +96,7 @@ describe("RegionalWaf", () => { .findChild("RegionalWaf") .node.findChild("WebACLAssociation") as wafv2.CfnWebACLAssociation; expect(webAclAssociation).toBeInstanceOf(wafv2.CfnWebACLAssociation); - expect(webAclAssociation.resourceArn).toBe( - apiGateway.deploymentStage.stageArn, - ); + expect(webAclAssociation.resourceArn).toBe(apiGateway.deploymentStage.stageArn); expect(webAclAssociation.webAclArn).toBe(regionalWaf.webAcl.attrArn); }); }); diff --git a/lib/local-constructs/waf/index.ts b/lib/local-constructs/waf/index.ts index 1d4d905a62..2008c60691 100644 --- a/lib/local-constructs/waf/index.ts +++ b/lib/local-constructs/waf/index.ts @@ -1,10 +1,6 @@ import * as cdk from "aws-cdk-lib"; import { Construct } from "constructs"; -import { - CfnWebACL, - CfnLoggingConfiguration, - CfnWebACLAssociation, -} from "aws-cdk-lib/aws-wafv2"; +import { CfnWebACL, CfnLoggingConfiguration, CfnWebACLAssociation } from "aws-cdk-lib/aws-wafv2"; import { LogGroup } from "aws-cdk-lib/aws-logs"; import { RestApi } from "aws-cdk-lib/aws-apigateway"; @@ -20,12 +16,7 @@ export class WafConstruct extends Construct { public readonly webAcl: CfnWebACL; public readonly logGroup: LogGroup; - constructor( - scope: Construct, - id: string, - props: WafProps, - scopeType: string, - ) { + constructor(scope: Construct, id: string, props: WafProps, scopeType: string) { super(scope, id); const { @@ -150,18 +141,7 @@ export class WafConstruct extends Construct { action: { allow: {} }, statement: { geoMatchStatement: { - countryCodes: [ - "AS", - "FM", - "GU", - "MH", - "MP", - "PR", - "PW", - "UM", - "US", - "VI", - ], + countryCodes: ["AS", "FM", "GU", "MH", "MP", "PR", "PW", "UM", "US", "VI"], }, }, visibilityConfig: { diff --git a/lib/packages/shared-types/attachments.ts b/lib/packages/shared-types/attachments.ts index df13de4038..6c3c375417 100644 --- a/lib/packages/shared-types/attachments.ts +++ b/lib/packages/shared-types/attachments.ts @@ -28,9 +28,12 @@ export const attachmentTitleMap = { supportingDocumentation: "Supporting Documentation", bCapWaiverApplication: "1915(b) Comprehensive (Capitated) Waiver Application Pre-print", bCapCostSpreadsheets: "1915(b) Comprehensive (Capitated) Waiver Cost Effectiveness Spreadsheets", - bCapIndependentAssessment: "1915(b) Comprehensive (Capitated) Waiver Independent Assessment (first two renewals only)", - b4WaiverApplication: "1915(b)(4) FFS Selective Contracting (Streamlined) Waiver Application Pre-print", - b4IndependentAssessment: "1915(b)(4) FFS Selective Contracting (Streamlined) Independent Assessment (first two renewals only)", + bCapIndependentAssessment: + "1915(b) Comprehensive (Capitated) Waiver Independent Assessment (first two renewals only)", + b4WaiverApplication: + "1915(b)(4) FFS Selective Contracting (Streamlined) Waiver Application Pre-print", + b4IndependentAssessment: + "1915(b)(4) FFS Selective Contracting (Streamlined) Independent Assessment (first two renewals only)", appk: "1915(c) Appendix K Amendment Waiver Template", waiverExtensionRequest: "Waiver Extension Request", }; diff --git a/lib/packages/shared-types/authority.ts b/lib/packages/shared-types/authority.ts index 4c5aff79e6..31d749ff8f 100644 --- a/lib/packages/shared-types/authority.ts +++ b/lib/packages/shared-types/authority.ts @@ -6,8 +6,4 @@ export enum Authority { "1915c" = "1915(c)", } -export type AuthorityUnion = - | "Medicaid SPA" - | "CHIP SPA" - | "1915(b)" - | "1915(c)"; +export type AuthorityUnion = "Medicaid SPA" | "CHIP SPA" | "1915(b)" | "1915(c)"; diff --git a/lib/packages/shared-types/events/capitated-amendment.ts b/lib/packages/shared-types/events/capitated-amendment.ts index cf46921d19..2d91bf30d2 100644 --- a/lib/packages/shared-types/events/capitated-amendment.ts +++ b/lib/packages/shared-types/events/capitated-amendment.ts @@ -32,12 +32,7 @@ export const baseSchema = z.object({ files: attachmentArraySchemaOptional(), }), }), - additionalInformation: z - .string() - .max(4000) - .nullable() - .default(null) - .optional(), + additionalInformation: z.string().max(4000).nullable().default(null).optional(), waiverNumber: z .string() .min(1, { message: "Required" }) diff --git a/lib/packages/shared-types/events/contracting-amendment.ts b/lib/packages/shared-types/events/contracting-amendment.ts index 402d38bb07..ef42b89a5a 100644 --- a/lib/packages/shared-types/events/contracting-amendment.ts +++ b/lib/packages/shared-types/events/contracting-amendment.ts @@ -1,8 +1,5 @@ import { z } from "zod"; -import { - attachmentArraySchema, - attachmentArraySchemaOptional, -} from "../attachments"; +import { attachmentArraySchema, attachmentArraySchemaOptional } from "../attachments"; export const baseSchema = z.object({ event: z.literal("contracting-amendment").default("contracting-amendment"), @@ -19,9 +16,7 @@ export const baseSchema = z.object({ b4WaiverApplication: z.object({ label: z .string() - .default( - "1915(b)(4) FFS Selective Contracting (Streamlined) Waiver Application Pre-print", - ), + .default("1915(b)(4) FFS Selective Contracting (Streamlined) Waiver Application Pre-print"), files: attachmentArraySchema(), }), tribalConsultation: z.object({ @@ -33,12 +28,7 @@ export const baseSchema = z.object({ files: attachmentArraySchemaOptional(), }), }), - additionalInformation: z - .string() - .max(4000) - .nullable() - .default(null) - .optional(), + additionalInformation: z.string().max(4000).nullable().default(null).optional(), waiverNumber: z .string() .min(1, { message: "Required" }) diff --git a/lib/packages/shared-types/events/new-chip-submission.ts b/lib/packages/shared-types/events/new-chip-submission.ts index 0b5fd004df..942ea0e7b2 100644 --- a/lib/packages/shared-types/events/new-chip-submission.ts +++ b/lib/packages/shared-types/events/new-chip-submission.ts @@ -1,18 +1,10 @@ import { z } from "zod"; -import { - attachmentArraySchema, - attachmentArraySchemaOptional, -} from "../attachments"; +import { attachmentArraySchema, attachmentArraySchemaOptional } from "../attachments"; export const baseSchema = z.object({ event: z.literal("new-chip-submission").default("new-chip-submission"), - additionalInformation: z - .string() - .max(4000) - .nullable() - .default(null) - .optional(), + additionalInformation: z.string().max(4000).nullable().default(null).optional(), attachments: z.object({ currentStatePlan: z.object({ files: attachmentArraySchema(), diff --git a/lib/packages/shared-types/events/new-medicaid-submission.ts b/lib/packages/shared-types/events/new-medicaid-submission.ts index 5cac80daad..c27e5417ee 100644 --- a/lib/packages/shared-types/events/new-medicaid-submission.ts +++ b/lib/packages/shared-types/events/new-medicaid-submission.ts @@ -1,19 +1,9 @@ import { z } from "zod"; -import { - attachmentArraySchema, - attachmentArraySchemaOptional, -} from "../attachments"; +import { attachmentArraySchema, attachmentArraySchemaOptional } from "../attachments"; export const baseSchema = z.object({ - event: z - .literal("new-medicaid-submission") - .default("new-medicaid-submission"), - additionalInformation: z - .string() - .max(4000) - .nullable() - .default(null) - .optional(), + event: z.literal("new-medicaid-submission").default("new-medicaid-submission"), + additionalInformation: z.string().max(4000).nullable().default(null).optional(), attachments: z.object({ cmsForm179: z.object({ files: attachmentArraySchema({ @@ -32,9 +22,7 @@ export const baseSchema = z.object({ }), tribalEngagement: z.object({ files: attachmentArraySchemaOptional(), - label: z - .string() - .default("Document Demonstrating Good-Faith Tribal Engagement"), + label: z.string().default("Document Demonstrating Good-Faith Tribal Engagement"), }), existingStatePlanPages: z.object({ files: attachmentArraySchemaOptional(), diff --git a/lib/packages/shared-types/events/temporary-extension.ts b/lib/packages/shared-types/events/temporary-extension.ts index 13b3473174..1d5f7eb858 100644 --- a/lib/packages/shared-types/events/temporary-extension.ts +++ b/lib/packages/shared-types/events/temporary-extension.ts @@ -1,8 +1,5 @@ import { z } from "zod"; -import { - attachmentArraySchema, - attachmentArraySchemaOptional, -} from "../attachments"; +import { attachmentArraySchema, attachmentArraySchemaOptional } from "../attachments"; export const baseSchema = z.object({ event: z.literal("temporary-extension").default("temporary-extension"), @@ -21,12 +18,7 @@ export const baseSchema = z.object({ "The Approved Initial or Renewal Waiver Number must be in the format of SS-####.R##.00 or SS-#####.R##.00.", }), authority: z.string(), // z.enum? - additionalInformation: z - .string() - .max(4000) - .nullable() - .default(null) - .optional(), + additionalInformation: z.string().max(4000).nullable().default(null).optional(), attachments: z.object({ waiverExtensionRequest: z.object({ label: z.string().default("Waiver Extension Request"), diff --git a/lib/packages/shared-types/events/toggle-withdraw-rai.ts b/lib/packages/shared-types/events/toggle-withdraw-rai.ts index 7e3c81ca47..c8e4ddd301 100644 --- a/lib/packages/shared-types/events/toggle-withdraw-rai.ts +++ b/lib/packages/shared-types/events/toggle-withdraw-rai.ts @@ -1,6 +1,5 @@ import { z } from "zod"; - export const baseSchema = z.object({ event: z.literal("toggle-withdraw-rai").default("toggle-withdraw-rai"), id: z.string(), diff --git a/lib/packages/shared-types/forms.ts b/lib/packages/shared-types/forms.ts index c0e2e48332..80b6e3a7e7 100644 --- a/lib/packages/shared-types/forms.ts +++ b/lib/packages/shared-types/forms.ts @@ -1,9 +1,4 @@ -import { - Control, - FieldArrayPath, - FieldValues, - RegisterOptions, -} from "react-hook-form"; +import { Control, FieldArrayPath, FieldValues, RegisterOptions } from "react-hook-form"; import { CalendarProps, InputProps, diff --git a/lib/packages/shared-types/inputs.ts b/lib/packages/shared-types/inputs.ts index 0cceeb4c46..0778bdf5ab 100644 --- a/lib/packages/shared-types/inputs.ts +++ b/lib/packages/shared-types/inputs.ts @@ -16,21 +16,16 @@ export type DatePickerProps = { dataTestId?: string; }; -export interface InputProps - extends React.InputHTMLAttributes { +export interface InputProps extends React.InputHTMLAttributes { icon?: string; iconRight?: boolean; } -export type RadioProps = React.ComponentPropsWithoutRef< - typeof RadioGroupPrimitive.Root -> & { +export type RadioProps = React.ComponentPropsWithoutRef & { className?: string; }; -export type SelectProps = React.ComponentPropsWithoutRef< - typeof SelectPrimitive.Root -> & { +export type SelectProps = React.ComponentPropsWithoutRef & { options: { label: string; value: any }[]; className?: string; apiCall?: string; @@ -51,14 +46,11 @@ export type MultiselectProps = { onChange?: (selectedValues: string[]) => void; }; -export type SwitchProps = React.ComponentPropsWithoutRef< - typeof SwitchPrimitives.Root -> & { +export type SwitchProps = React.ComponentPropsWithoutRef & { className?: string; }; -export interface TextareaProps - extends React.TextareaHTMLAttributes { +export interface TextareaProps extends React.TextareaHTMLAttributes { charCount?: "simple" | "limited"; charCountClassName?: string; } diff --git a/lib/packages/shared-types/opensearch/cpocs/index.ts b/lib/packages/shared-types/opensearch/cpocs/index.ts index 2d5f7bc856..a6d1585f16 100644 --- a/lib/packages/shared-types/opensearch/cpocs/index.ts +++ b/lib/packages/shared-types/opensearch/cpocs/index.ts @@ -1,10 +1,4 @@ -import { - Response as Res, - Hit, - Filterable as FIL, - QueryState, - AggQuery, -} from "./../_"; +import { Response as Res, Hit, Filterable as FIL, QueryState, AggQuery } from "./../_"; import { z } from "zod"; import { Officers } from "./transforms"; diff --git a/lib/packages/shared-types/opensearch/main/transforms/app-k.ts b/lib/packages/shared-types/opensearch/main/transforms/app-k.ts index b5863849f7..05df9ed197 100644 --- a/lib/packages/shared-types/opensearch/main/transforms/app-k.ts +++ b/lib/packages/shared-types/opensearch/main/transforms/app-k.ts @@ -3,7 +3,7 @@ import { seaToolFriendlyTimestamp } from "../../../../shared-utils/seatool-date- export const transform = () => { return events["app-k"].schema.transform((data) => { - const { stateStatus, cmsStatus } = getStatus(SEATOOL_STATUS.PENDING); + const { stateStatus, cmsStatus } = getStatus(SEATOOL_STATUS.SUBMITTED); const timestampDate = new Date(data.timestamp); const todayEpoch = seaToolFriendlyTimestamp(timestampDate); @@ -18,7 +18,7 @@ export const transform = () => { makoChangedDate: timestampDate.toISOString(), origin: "OneMAC", raiWithdrawEnabled: false, // Set to false for new submissions - seatoolStatus: SEATOOL_STATUS.PENDING, + seatoolStatus: SEATOOL_STATUS.SUBMITTED, state: data.id?.split("-")?.[0], stateStatus, statusDate: new Date(todayEpoch).toISOString(), diff --git a/lib/packages/shared-types/opensearch/main/transforms/capitated-amendment.ts b/lib/packages/shared-types/opensearch/main/transforms/capitated-amendment.ts index 8b42a5adbd..d9e1598ec1 100644 --- a/lib/packages/shared-types/opensearch/main/transforms/capitated-amendment.ts +++ b/lib/packages/shared-types/opensearch/main/transforms/capitated-amendment.ts @@ -3,7 +3,7 @@ import { seaToolFriendlyTimestamp } from "../../../../shared-utils/seatool-date- export const transform = () => { return events["capitated-amendment"].schema.transform((data) => { - const { stateStatus, cmsStatus } = getStatus(SEATOOL_STATUS.PENDING); + const { stateStatus, cmsStatus } = getStatus(SEATOOL_STATUS.SUBMITTED); const timestampDate = new Date(data.timestamp); const todayEpoch = seaToolFriendlyTimestamp(timestampDate); @@ -17,7 +17,7 @@ export const transform = () => { makoChangedDate: timestampDate.toISOString(), origin: "OneMAC", raiWithdrawEnabled: false, // Set to false for new submissions - seatoolStatus: SEATOOL_STATUS.PENDING, + seatoolStatus: SEATOOL_STATUS.SUBMITTED, state: data.id?.split("-")?.[0], stateStatus, statusDate: new Date(todayEpoch).toISOString(), diff --git a/lib/packages/shared-types/opensearch/main/transforms/capitated-initial.ts b/lib/packages/shared-types/opensearch/main/transforms/capitated-initial.ts index 38b66e7737..82b873f290 100644 --- a/lib/packages/shared-types/opensearch/main/transforms/capitated-initial.ts +++ b/lib/packages/shared-types/opensearch/main/transforms/capitated-initial.ts @@ -3,7 +3,7 @@ import { seaToolFriendlyTimestamp } from "../../../../shared-utils/seatool-date- export const transform = () => { return events["capitated-initial"].schema.transform((data) => { - const { stateStatus, cmsStatus } = getStatus(SEATOOL_STATUS.PENDING); + const { stateStatus, cmsStatus } = getStatus(SEATOOL_STATUS.SUBMITTED); const timestampDate = new Date(data.timestamp); const todayEpoch = seaToolFriendlyTimestamp(timestampDate); @@ -17,7 +17,7 @@ export const transform = () => { makoChangedDate: timestampDate.toISOString(), origin: "OneMAC", raiWithdrawEnabled: false, // Set to false for new submissions - seatoolStatus: SEATOOL_STATUS.PENDING, + seatoolStatus: SEATOOL_STATUS.SUBMITTED, state: data.id?.split("-")?.[0], stateStatus, statusDate: new Date(todayEpoch).toISOString(), diff --git a/lib/packages/shared-types/opensearch/main/transforms/capitated-renewal.ts b/lib/packages/shared-types/opensearch/main/transforms/capitated-renewal.ts index 4a9b4d7fdb..9144bd2dea 100644 --- a/lib/packages/shared-types/opensearch/main/transforms/capitated-renewal.ts +++ b/lib/packages/shared-types/opensearch/main/transforms/capitated-renewal.ts @@ -3,7 +3,7 @@ import { seaToolFriendlyTimestamp } from "../../../../shared-utils/seatool-date- export const transform = () => { return events["capitated-renewal"].schema.transform((data) => { - const { stateStatus, cmsStatus } = getStatus(SEATOOL_STATUS.PENDING); + const { stateStatus, cmsStatus } = getStatus(SEATOOL_STATUS.SUBMITTED); const timestampDate = new Date(data.timestamp); const todayEpoch = seaToolFriendlyTimestamp(timestampDate); @@ -17,7 +17,7 @@ export const transform = () => { makoChangedDate: timestampDate.toISOString(), origin: "OneMAC", raiWithdrawEnabled: false, // Set to false for new submissions - seatoolStatus: SEATOOL_STATUS.PENDING, + seatoolStatus: SEATOOL_STATUS.SUBMITTED, state: data.id?.split("-")?.[0], stateStatus, statusDate: new Date(todayEpoch).toISOString(), diff --git a/lib/packages/shared-types/opensearch/main/transforms/contracting-amendment.ts b/lib/packages/shared-types/opensearch/main/transforms/contracting-amendment.ts index 577f91da6a..e0dd1bdc9f 100644 --- a/lib/packages/shared-types/opensearch/main/transforms/contracting-amendment.ts +++ b/lib/packages/shared-types/opensearch/main/transforms/contracting-amendment.ts @@ -3,7 +3,7 @@ import { seaToolFriendlyTimestamp } from "../../../../shared-utils/seatool-date- export const transform = () => { return events["contracting-amendment"].schema.transform((data) => { - const { stateStatus, cmsStatus } = getStatus(SEATOOL_STATUS.PENDING); + const { stateStatus, cmsStatus } = getStatus(SEATOOL_STATUS.SUBMITTED); const timestampDate = new Date(data.timestamp); const todayEpoch = seaToolFriendlyTimestamp(timestampDate); @@ -17,7 +17,7 @@ export const transform = () => { makoChangedDate: timestampDate.toISOString(), origin: "OneMAC", raiWithdrawEnabled: false, // Set to false for new submissions - seatoolStatus: SEATOOL_STATUS.PENDING, + seatoolStatus: SEATOOL_STATUS.SUBMITTED, state: data.id?.split("-")?.[0], stateStatus, statusDate: new Date(todayEpoch).toISOString(), diff --git a/lib/packages/shared-types/opensearch/main/transforms/contracting-initial.ts b/lib/packages/shared-types/opensearch/main/transforms/contracting-initial.ts index 6448c395dd..16e5060491 100644 --- a/lib/packages/shared-types/opensearch/main/transforms/contracting-initial.ts +++ b/lib/packages/shared-types/opensearch/main/transforms/contracting-initial.ts @@ -3,7 +3,7 @@ import { seaToolFriendlyTimestamp } from "../../../../shared-utils/seatool-date- export const transform = () => { return events["contracting-initial"].schema.transform((data) => { - const { stateStatus, cmsStatus } = getStatus(SEATOOL_STATUS.PENDING); + const { stateStatus, cmsStatus } = getStatus(SEATOOL_STATUS.SUBMITTED); const timestampDate = new Date(data.timestamp); const todayEpoch = seaToolFriendlyTimestamp(timestampDate); @@ -17,7 +17,7 @@ export const transform = () => { makoChangedDate: timestampDate.toISOString(), origin: "OneMAC", raiWithdrawEnabled: false, // Set to false for new submissions - seatoolStatus: SEATOOL_STATUS.PENDING, + seatoolStatus: SEATOOL_STATUS.SUBMITTED, state: data.id?.split("-")?.[0], stateStatus, statusDate: new Date(todayEpoch).toISOString(), diff --git a/lib/packages/shared-types/opensearch/main/transforms/contracting-renewal.ts b/lib/packages/shared-types/opensearch/main/transforms/contracting-renewal.ts index 05fb371dcc..69ec2dffa3 100644 --- a/lib/packages/shared-types/opensearch/main/transforms/contracting-renewal.ts +++ b/lib/packages/shared-types/opensearch/main/transforms/contracting-renewal.ts @@ -3,7 +3,7 @@ import { seaToolFriendlyTimestamp } from "../../../../shared-utils/seatool-date- export const transform = () => { return events["contracting-renewal"].schema.transform((data) => { - const { stateStatus, cmsStatus } = getStatus(SEATOOL_STATUS.PENDING); + const { stateStatus, cmsStatus } = getStatus(SEATOOL_STATUS.SUBMITTED); const timestampDate = new Date(data.timestamp); const todayEpoch = seaToolFriendlyTimestamp(timestampDate); @@ -17,7 +17,7 @@ export const transform = () => { makoChangedDate: timestampDate?.toISOString(), origin: "OneMAC", raiWithdrawEnabled: false, // Set to false for new submissions - seatoolStatus: SEATOOL_STATUS.PENDING, + seatoolStatus: SEATOOL_STATUS.SUBMITTED, state: data.id?.split("-")?.[0], stateStatus, statusDate: new Date(todayEpoch).toISOString(), diff --git a/lib/packages/shared-types/opensearch/main/transforms/new-chip-submission.ts b/lib/packages/shared-types/opensearch/main/transforms/new-chip-submission.ts index 0c3255b92d..677e0fcc70 100644 --- a/lib/packages/shared-types/opensearch/main/transforms/new-chip-submission.ts +++ b/lib/packages/shared-types/opensearch/main/transforms/new-chip-submission.ts @@ -3,7 +3,7 @@ import { seaToolFriendlyTimestamp } from "../../../../shared-utils/seatool-date- export const transform = () => { return events["new-chip-submission"].schema.transform((data) => { - const { stateStatus, cmsStatus } = getStatus(SEATOOL_STATUS.PENDING); + const { stateStatus, cmsStatus } = getStatus(SEATOOL_STATUS.SUBMITTED); const timestampDate = new Date(data.timestamp); const todayEpoch = seaToolFriendlyTimestamp(timestampDate); @@ -17,7 +17,7 @@ export const transform = () => { makoChangedDate: timestampDate.toISOString(), origin: "OneMAC", raiWithdrawEnabled: false, // Set to false for new submissions - seatoolStatus: SEATOOL_STATUS.PENDING, + seatoolStatus: SEATOOL_STATUS.SUBMITTED, state: data.id?.split("-")?.[0], stateStatus, statusDate: new Date(todayEpoch).toISOString(), diff --git a/lib/packages/shared-types/opensearch/main/transforms/new-medicaid-submission.ts b/lib/packages/shared-types/opensearch/main/transforms/new-medicaid-submission.ts index d75fcd61d1..c824485967 100644 --- a/lib/packages/shared-types/opensearch/main/transforms/new-medicaid-submission.ts +++ b/lib/packages/shared-types/opensearch/main/transforms/new-medicaid-submission.ts @@ -3,7 +3,7 @@ import { seaToolFriendlyTimestamp } from "../../../../shared-utils/seatool-date- export const transform = () => { return events["new-medicaid-submission"].schema.transform((data) => { - const { stateStatus, cmsStatus } = getStatus(SEATOOL_STATUS.PENDING); + const { stateStatus, cmsStatus } = getStatus(SEATOOL_STATUS.SUBMITTED); const timestampDate = new Date(data.timestamp); const todayEpoch = seaToolFriendlyTimestamp(timestampDate); @@ -17,7 +17,7 @@ export const transform = () => { makoChangedDate: timestampDate.toISOString(), origin: "OneMAC", raiWithdrawEnabled: false, // Set to false for new submissions - seatoolStatus: SEATOOL_STATUS.PENDING, + seatoolStatus: SEATOOL_STATUS.SUBMITTED, state: data.id?.split("-")?.[0], stateStatus, statusDate: new Date(todayEpoch).toISOString(), diff --git a/lib/packages/shared-types/opensearch/main/transforms/respond-to-rai.ts b/lib/packages/shared-types/opensearch/main/transforms/respond-to-rai.ts index 674fb5aaa8..b34a2db759 100644 --- a/lib/packages/shared-types/opensearch/main/transforms/respond-to-rai.ts +++ b/lib/packages/shared-types/opensearch/main/transforms/respond-to-rai.ts @@ -1,7 +1,7 @@ import { events, getStatus, SEATOOL_STATUS } from "shared-types"; export const transform = () => { return events["respond-to-rai"].schema.transform((data) => { - const { stateStatus, cmsStatus } = getStatus(SEATOOL_STATUS.PENDING_RAI); + const { stateStatus, cmsStatus } = getStatus(SEATOOL_STATUS.SUBMITTED); return { id: data.id, raiWithdrawEnabled: false, @@ -9,7 +9,8 @@ export const transform = () => { cmsStatus, stateStatus, raiReceivedDate: data.timestamp ? new Date(data.timestamp).toISOString() : null, - seatoolStatus: SEATOOL_STATUS.PENDING_RAI, + seatoolStatus: SEATOOL_STATUS.SUBMITTED, + initialIntakeNeeded: true, locked: true, }; }); diff --git a/lib/packages/shared-types/opensearch/main/transforms/seatool.ts b/lib/packages/shared-types/opensearch/main/transforms/seatool.ts index bada36dfcd..6056309305 100644 --- a/lib/packages/shared-types/opensearch/main/transforms/seatool.ts +++ b/lib/packages/shared-types/opensearch/main/transforms/seatool.ts @@ -8,7 +8,7 @@ import { seatoolSchema, } from "../../.."; -import { Authority, SEATOOL_AUTHORITIES } from "shared-types"; +import { SEATOOL_AUTHORITIES } from "shared-types"; function getLeadAnalyst(eventData: SeaTool) { let leadAnalystOfficerId: null | number = null; @@ -74,15 +74,15 @@ const getRaiDate = (data: SeaTool) => { const getDateStringOrNullFromEpoc = (epocDate: number | null | undefined) => epocDate !== null && epocDate !== undefined ? new Date(epocDate).toISOString() : null; - const compileSrtList = ( - officers: SeatoolOfficer[] | null | undefined, - ): { name: string; email: string }[] => - officers?.length - ? officers.map((o) => ({ - name: `${o.FIRST_NAME || ""} ${o.LAST_NAME || ""}`, - email: o.EMAIL || "", - })) - : []; +const compileSrtList = ( + officers: SeatoolOfficer[] | null | undefined, +): { name: string; email: string }[] => + officers?.length + ? officers.map((o) => ({ + name: `${o.FIRST_NAME || ""} ${o.LAST_NAME || ""}`, + email: o.EMAIL || "", + })) + : []; const getFinalDispositionDate = (status: string, record: SeaTool) => { return status && finalDispositionStatuses.includes(status) @@ -97,7 +97,7 @@ const isInSecondClock = ( authority: any, ) => { if ( - authority != Authority.CHIP_SPA && // if it's not a chip + authority !== "CHIP SPA" && // if it's not a chip [ SEATOOL_STATUS.PENDING, SEATOOL_STATUS.PENDING_CONCURRENCE, @@ -129,8 +129,7 @@ export const transform = (id: string) => { id: id.toUpperCase(), actionType: data.ACTIONTYPES?.[0].ACTION_NAME, approvedEffectiveDate: getDateStringOrNullFromEpoc( - data.STATE_PLAN.APPROVED_EFFECTIVE_DATE || - data.STATE_PLAN.ACTUAL_EFFECTIVE_DATE, + data.STATE_PLAN.APPROVED_EFFECTIVE_DATE || data.STATE_PLAN.ACTUAL_EFFECTIVE_DATE, ), changed_date: data.STATE_PLAN.CHANGED_DATE, description: data.STATE_PLAN.SUMMARY_MEMO, @@ -148,7 +147,7 @@ export const transform = (id: string) => { SPA_TYPE_ID: type.SPA_TYPE_ID, SPA_TYPE_NAME: type.SPA_TYPE_NAME.replace(/–|—/g, "-"), }; - }) || null, + }) || [], subTypes: data.STATE_PLAN_SERVICE_SUBTYPES?.filter( (subType): subType is NonNullable => subType != null, @@ -157,7 +156,7 @@ export const transform = (id: string) => { TYPE_ID: subType.TYPE_ID, TYPE_NAME: subType.TYPE_NAME.replace(/–|—/g, "-"), }; - }) || null, + }) || [], proposedDate: getDateStringOrNullFromEpoc(data.STATE_PLAN.PROPOSED_DATE), raiReceivedDate, raiRequestedDate, diff --git a/lib/packages/shared-types/opensearch/main/transforms/withdraw-package.ts b/lib/packages/shared-types/opensearch/main/transforms/withdraw-package.ts index 6d6ec1d0cf..f9951182cd 100644 --- a/lib/packages/shared-types/opensearch/main/transforms/withdraw-package.ts +++ b/lib/packages/shared-types/opensearch/main/transforms/withdraw-package.ts @@ -2,16 +2,16 @@ import { events, getStatus, SEATOOL_STATUS } from "shared-types"; export const transform = () => { return events["withdraw-package"].schema.transform((data) => { - const { stateStatus, cmsStatus } = getStatus(SEATOOL_STATUS.WITHDRAWN); + const { stateStatus, cmsStatus } = getStatus(SEATOOL_STATUS.WITHDRAW_REQUESTED); return { id: data.id, raiWithdrawEnabled: false, makoChangedDate: data.timestamp ? new Date(data.timestamp).toISOString() : null, cmsStatus, stateStatus, - finalDispositionDate: data.timestamp ? new Date(data.timestamp).toISOString() : null, - seatoolStatus: SEATOOL_STATUS.WITHDRAWN, - initialIntakeNeeded: false, + secondClock: false, + seatoolStatus: SEATOOL_STATUS.WITHDRAW_REQUESTED, + initialIntakeNeeded: true, locked: true, }; }); diff --git a/lib/packages/shared-types/opensearch/main/transforms/withdraw-rai-response.ts b/lib/packages/shared-types/opensearch/main/transforms/withdraw-rai-response.ts index 938fd5ebd2..380931ba74 100644 --- a/lib/packages/shared-types/opensearch/main/transforms/withdraw-rai-response.ts +++ b/lib/packages/shared-types/opensearch/main/transforms/withdraw-rai-response.ts @@ -2,14 +2,15 @@ import { events, getStatus, SEATOOL_STATUS } from "shared-types"; export const transform = () => { return events["withdraw-rai"].schema.transform((data) => { - const { stateStatus, cmsStatus } = getStatus(SEATOOL_STATUS.PENDING_RAI); + const { stateStatus, cmsStatus } = getStatus(SEATOOL_STATUS.RAI_RESPONSE_WITHDRAW_REQUESTED); return { id: data.id, raiWithdrawEnabled: false, makoChangedDate: data.timestamp ? new Date(data.timestamp).toISOString() : null, cmsStatus, stateStatus, - seatoolStatus: SEATOOL_STATUS.PENDING_RAI, + seatoolStatus: SEATOOL_STATUS.RAI_RESPONSE_WITHDRAW_REQUESTED, + secondClock: false, locked: true, }; }); diff --git a/lib/packages/shared-types/opensearch/subtypes/index.ts b/lib/packages/shared-types/opensearch/subtypes/index.ts index 9457fb9668..a9acfbbb67 100644 --- a/lib/packages/shared-types/opensearch/subtypes/index.ts +++ b/lib/packages/shared-types/opensearch/subtypes/index.ts @@ -1,10 +1,4 @@ -import { - Response as Res, - Hit, - Filterable as FIL, - QueryState, - AggQuery, -} from "./../_"; +import { Response as Res, Hit, Filterable as FIL, QueryState, AggQuery } from "./../_"; import { z } from "zod"; import { Type } from "./transforms"; diff --git a/lib/packages/shared-types/opensearch/types/index.ts b/lib/packages/shared-types/opensearch/types/index.ts index 75ed5dbd00..9727514e42 100644 --- a/lib/packages/shared-types/opensearch/types/index.ts +++ b/lib/packages/shared-types/opensearch/types/index.ts @@ -1,10 +1,4 @@ -import { - Response as Res, - Hit, - Filterable as FIL, - QueryState, - AggQuery, -} from "./../_"; +import { Response as Res, Hit, Filterable as FIL, QueryState, AggQuery } from "./../_"; import { z } from "zod"; import { SPA_Type } from "./transforms"; diff --git a/lib/packages/shared-types/seatool-tables/index.ts b/lib/packages/shared-types/seatool-tables/index.ts index 142785c0de..6a07f7fa7e 100644 --- a/lib/packages/shared-types/seatool-tables/index.ts +++ b/lib/packages/shared-types/seatool-tables/index.ts @@ -1,4 +1,4 @@ export * from "./Type"; export * from "./SPA_Type"; export * from "./State_Plan"; -export * from "./Officers"; \ No newline at end of file +export * from "./Officers"; diff --git a/lib/packages/shared-types/statusHelper.ts b/lib/packages/shared-types/statusHelper.ts index e79de3bf4f..609ad3b6cb 100644 --- a/lib/packages/shared-types/statusHelper.ts +++ b/lib/packages/shared-types/statusHelper.ts @@ -10,6 +10,9 @@ export const SEATOOL_STATUS = { PENDING_APPROVAL: "Pending-Approval", UNKNOWN: "Unknown", PENDING_OFF_THE_CLOCK: "Pending-Off the Clock", + SUBMITTED: "Submitted", + RAI_RESPONSE_WITHDRAW_REQUESTED: "Formal RAI Response - Withdrawal Requested", + WITHDRAW_REQUESTED: "Withdrawal Requested", }; export const statusToDisplayToStateUser = { @@ -23,6 +26,9 @@ export const statusToDisplayToStateUser = { [SEATOOL_STATUS.UNSUBMITTED]: "Unsubmitted", [SEATOOL_STATUS.PENDING_APPROVAL]: "Under Review", [SEATOOL_STATUS.PENDING_OFF_THE_CLOCK]: "Pending - Off the Clock", + [SEATOOL_STATUS.SUBMITTED]: "Submitted", + [SEATOOL_STATUS.RAI_RESPONSE_WITHDRAW_REQUESTED]: "Formal RAI Response - Withdrawal Requested", + [SEATOOL_STATUS.WITHDRAW_REQUESTED]: "Withdrawal Requested", }; export const statusToDisplayToCmsUser = { @@ -36,6 +42,9 @@ export const statusToDisplayToCmsUser = { [SEATOOL_STATUS.UNSUBMITTED]: "Unsubmitted", [SEATOOL_STATUS.PENDING_APPROVAL]: "Pending - Approval", [SEATOOL_STATUS.PENDING_OFF_THE_CLOCK]: "Pending - Off the Clock", + [SEATOOL_STATUS.SUBMITTED]: "Submitted - Intake Needed", + [SEATOOL_STATUS.RAI_RESPONSE_WITHDRAW_REQUESTED]: "Formal RAI Response - Withdrawal Requested", + [SEATOOL_STATUS.WITHDRAW_REQUESTED]: "Submitted - Intake Needed", }; export const finalDispositionStatuses = [ diff --git a/lib/packages/shared-utils/cloudformation.ts b/lib/packages/shared-utils/cloudformation.ts index dccd63ce6b..236553a83b 100644 --- a/lib/packages/shared-utils/cloudformation.ts +++ b/lib/packages/shared-utils/cloudformation.ts @@ -1,12 +1,6 @@ -import { - CloudFormationClient, - ListExportsCommand, -} from "@aws-sdk/client-cloudformation"; +import { CloudFormationClient, ListExportsCommand } from "@aws-sdk/client-cloudformation"; -export async function getExport( - exportName: string, - region: string = "us-east-1", -): Promise { +export async function getExport(exportName: string, region: string = "us-east-1"): Promise { const client = new CloudFormationClient({ region }); const command = new ListExportsCommand({}); diff --git a/lib/packages/shared-utils/package-actions/rules.ts b/lib/packages/shared-utils/package-actions/rules.ts index efb60e1373..d2df782cf9 100644 --- a/lib/packages/shared-utils/package-actions/rules.ts +++ b/lib/packages/shared-utils/package-actions/rules.ts @@ -47,7 +47,9 @@ const arEnableWithdrawRaiResponse: ActionRule = { checker.hasRaiResponse && !checker.hasEnabledRaiWithdraw && isCmsWriteUser(user) && - !checker.hasStatus(finalDispositionStatuses) + !checker.hasStatus(finalDispositionStatuses) && + !checker.hasStatus([SEATOOL_STATUS.PENDING_CONCURRENCE, SEATOOL_STATUS.PENDING_APPROVAL]) && + !checker.isPlaceholderStatus ); } @@ -58,7 +60,8 @@ const arEnableWithdrawRaiResponse: ActionRule = { !checker.hasEnabledRaiWithdraw && checker.isInSecondClock && isCmsWriteUser(user) && - !checker.hasStatus(finalDispositionStatuses) + !checker.hasStatus(finalDispositionStatuses) && + !checker.hasStatus([SEATOOL_STATUS.PENDING_CONCURRENCE, SEATOOL_STATUS.PENDING_APPROVAL]) ); }, }; @@ -71,7 +74,8 @@ const arDisableWithdrawRaiResponse: ActionRule = { checker.hasRaiResponse && checker.hasEnabledRaiWithdraw && isCmsWriteUser(user) && - !checker.hasStatus(finalDispositionStatuses), + !checker.hasStatus(finalDispositionStatuses) && + !checker.hasStatus([SEATOOL_STATUS.PENDING_CONCURRENCE, SEATOOL_STATUS.PENDING_APPROVAL]), }; const arWithdrawRaiResponse: ActionRule = { @@ -82,6 +86,7 @@ const arWithdrawRaiResponse: ActionRule = { checker.hasRaiResponse && // safety; prevent bad status from causing overwrite !checker.hasRaiWithdrawal && + !checker.hasStatus([SEATOOL_STATUS.PENDING_CONCURRENCE, SEATOOL_STATUS.PENDING_APPROVAL]) && checker.hasEnabledRaiWithdraw && isStateUser(user) && !checker.isLocked, @@ -90,7 +95,10 @@ const arWithdrawRaiResponse: ActionRule = { const arWithdrawPackage: ActionRule = { action: Action.WITHDRAW_PACKAGE, check: (checker, user) => - !checker.isTempExtension && !checker.hasStatus(finalDispositionStatuses) && isStateUser(user), + !checker.isTempExtension && + !checker.hasStatus(finalDispositionStatuses) && + isStateUser(user) && + !checker.isPlaceholderStatus, }; const arUpdateId: ActionRule = { @@ -119,7 +127,11 @@ const arUploadSubsequentDocuments: ActionRule = { return false; } - if (checker.hasStatus([SEATOOL_STATUS.PENDING, SEATOOL_STATUS.PENDING_RAI])) { + if (checker.hasStatus([SEATOOL_STATUS.PENDING_RAI])) { + return false; + } + + if (checker.hasStatus([SEATOOL_STATUS.PENDING])) { if (checker.hasRequestedRai) { return false; } diff --git a/lib/packages/shared-utils/package-check.ts b/lib/packages/shared-utils/package-check.ts index c03b4afb33..d28368304b 100644 --- a/lib/packages/shared-utils/package-check.ts +++ b/lib/packages/shared-utils/package-check.ts @@ -66,6 +66,12 @@ export const PackageCheck = ({ * object attributes! **/ hasStatus: (authorizedStatuses: string | string[]) => checkStatus(seatoolStatus, authorizedStatuses), + /** Is Placeholder Status is a check that is used to determine if the record is in one of the in between status while waiting on seatool intake */ + isPlaceholderStatus: [ + SEATOOL_STATUS.RAI_RESPONSE_WITHDRAW_REQUESTED, + SEATOOL_STATUS.SUBMITTED, + SEATOOL_STATUS.WITHDRAW_REQUESTED, + ].includes(seatoolStatus), /** If submission date exists */ hasSubmissionDate: submissionDate !== undefined, isLocked: locked, diff --git a/lib/packages/shared-utils/regex.ts b/lib/packages/shared-utils/regex.ts index 6b07a7e3aa..a8e04751d5 100644 --- a/lib/packages/shared-utils/regex.ts +++ b/lib/packages/shared-utils/regex.ts @@ -34,10 +34,7 @@ export const reInsertRegex = (obj: any) => { obj[key].pattern.hasOwnProperty("value") ) { // if its a pattern.value replace the value's value with a regex from the weird array thing - obj[key].pattern.value = new RegExp( - obj[key].pattern.value[1], - obj[key].pattern.value[2], - ); + obj[key].pattern.value = new RegExp(obj[key].pattern.value[1], obj[key].pattern.value[2]); } } } diff --git a/lib/packages/shared-utils/seatool-date-helper.test.ts b/lib/packages/shared-utils/seatool-date-helper.test.ts index 4051e7db59..502475fe20 100644 --- a/lib/packages/shared-utils/seatool-date-helper.test.ts +++ b/lib/packages/shared-utils/seatool-date-helper.test.ts @@ -12,12 +12,7 @@ describe("offsetToUtc", () => { const originalDate = new Date("January 1, 2000 12:00:00"); const timezoneOffset = originalDate.getTimezoneOffset() * 60000; // in milliseconds const expectedDate = new Date(originalDate.getTime() - timezoneOffset); - console.debug( - "originalDate: ", - originalDate, - "expectedDate: ", - expectedDate, - ); + console.debug("originalDate: ", originalDate, "expectedDate: ", expectedDate); expect(offsetToUtc(originalDate)).toEqual(expectedDate); }); }); @@ -27,12 +22,7 @@ describe("offsetFromUtc", () => { const originalDate = new Date("2000-01-01T12:00:00.000Z"); const timezoneOffset = originalDate.getTimezoneOffset() * 60000; // in milliseconds const expectedDate = new Date(originalDate.getTime() + timezoneOffset); - console.debug( - "originalDate: ", - originalDate, - "expectedDate: ", - expectedDate, - ); + console.debug("originalDate: ", originalDate, "expectedDate: ", expectedDate); expect(offsetFromUtc(originalDate)).toEqual(expectedDate); }); }); @@ -42,9 +32,7 @@ describe("seaToolFriendlyTimestamp", () => { const originalDate = new Date("January 1, 2000 12:00:00"); const timezoneOffset = originalDate.getTimezoneOffset() * 60000; // in milliseconds const expectedDate = new Date(originalDate.getTime() - timezoneOffset); - expect(seaToolFriendlyTimestamp(originalDate)).toEqual( - expectedDate.getTime(), - ); + expect(seaToolFriendlyTimestamp(originalDate)).toEqual(expectedDate.getTime()); }); }); diff --git a/lib/packages/shared-utils/seatool-date-helper.ts b/lib/packages/shared-utils/seatool-date-helper.ts index 03423c914e..7bab4356e6 100644 --- a/lib/packages/shared-utils/seatool-date-helper.ts +++ b/lib/packages/shared-utils/seatool-date-helper.ts @@ -26,9 +26,7 @@ export const formatSeatoolDate = (date: string): string => { return moment(date).tz("UTC").format("MM/DD/yyyy"); }; -export const getNextBusinessDayTimestamp = ( - date: Date = new Date(), -): number => { +export const getNextBusinessDayTimestamp = (date: Date = new Date()): number => { const localeStringDate = date.toLocaleString("en-US", { timeZone: "America/New_York", dateStyle: "short", diff --git a/lib/packages/shared-utils/secrets-manager.ts b/lib/packages/shared-utils/secrets-manager.ts index 9dad32b3ae..762e53f441 100644 --- a/lib/packages/shared-utils/secrets-manager.ts +++ b/lib/packages/shared-utils/secrets-manager.ts @@ -4,10 +4,7 @@ import { DescribeSecretCommand, } from "@aws-sdk/client-secrets-manager"; -export async function getSecret( - secretId: string, - region: string = "us-east-1", -): Promise { +export async function getSecret(secretId: string, region: string = "us-east-1"): Promise { const client = new SecretsManagerClient({ region }); try { // Check if the secret is marked for deletion @@ -15,9 +12,7 @@ export async function getSecret( const secretMetadata = await client.send(describeCommand); if (secretMetadata.DeletedDate) { - throw new Error( - `Secret ${secretId} is marked for deletion and will not be used.`, - ); + throw new Error(`Secret ${secretId} is marked for deletion and will not be used.`); } const command = new GetSecretValueCommand({ SecretId: secretId }); diff --git a/lib/stacks/alerts.ts b/lib/stacks/alerts.ts index a520e7eeb6..b51e36ba59 100644 --- a/lib/stacks/alerts.ts +++ b/lib/stacks/alerts.ts @@ -22,11 +22,7 @@ export class Alerts extends cdk.NestedStack { // Create Alerts Topic with AWS-managed KMS Key const alertsTopic = new cdk.aws_sns.Topic(this, "AlertsTopic", { topicName: `Alerts-${project}-${stage}`, - masterKey: cdk.aws_kms.Alias.fromAliasName( - this, - "KmsAlias", - "alias/aws/sns", - ), + masterKey: cdk.aws_kms.Alias.fromAliasName(this, "KmsAlias", "alias/aws/sns"), }); // Output the Alerts Topic ARN diff --git a/lib/stacks/api.ts b/lib/stacks/api.ts index f8cee59b1b..bd1a91cb72 100644 --- a/lib/stacks/api.ts +++ b/lib/stacks/api.ts @@ -4,11 +4,7 @@ import { Construct } from "constructs"; import { join } from "path"; import { DeploymentConfigProperties } from "../config/deployment-config"; import * as LC from "local-constructs"; -import { - BlockPublicAccess, - Bucket, - BucketEncryption, -} from "aws-cdk-lib/aws-s3"; +import { BlockPublicAccess, Bucket, BucketEncryption } from "aws-cdk-lib/aws-s3"; import { AnyPrincipal, Effect, PolicyStatement } from "aws-cdk-lib/aws-iam"; import { commonBundlingOptions } from "../config/bundling-config"; @@ -73,9 +69,7 @@ export class Api extends cdk.NestedStack { cdk.aws_iam.ManagedPolicy.fromAwsManagedPolicyName( "service-role/AWSLambdaVPCAccessExecutionRole", ), - cdk.aws_iam.ManagedPolicy.fromAwsManagedPolicyName( - "CloudWatchLogsFullAccess", - ), + cdk.aws_iam.ManagedPolicy.fromAwsManagedPolicyName("CloudWatchLogsFullAccess"), ], inlinePolicies: { LambdaPolicy: new cdk.aws_iam.PolicyDocument({ @@ -114,10 +108,7 @@ export class Api extends cdk.NestedStack { }), new cdk.aws_iam.PolicyStatement({ effect: cdk.aws_iam.Effect.ALLOW, - actions: [ - "secretsmanager:DescribeSecret", - "secretsmanager:GetSecretValue", - ], + actions: ["secretsmanager:DescribeSecret", "secretsmanager:GetSecretValue"], resources: [ `arn:aws:secretsmanager:${this.region}:${this.account}:secret:${dbInfoSecretName}-*`, ], @@ -293,18 +284,21 @@ export class Api extends cdk.NestedStack { }, ]; - const lambdas = lambdaDefinitions.reduce((acc, lambdaDef) => { - acc[lambdaDef.id] = createNodeJsLambda( - lambdaDef.id, - lambdaDef.entry, - lambdaDef.environment, - vpc, - lambdaSecurityGroup, - privateSubnets, - !props.isDev ? lambdaDef.provisionedConcurrency : 0, - ); - return acc; - }, {} as { [key: string]: NodejsFunction }); + const lambdas = lambdaDefinitions.reduce( + (acc, lambdaDef) => { + acc[lambdaDef.id] = createNodeJsLambda( + lambdaDef.id, + lambdaDef.entry, + lambdaDef.environment, + vpc, + lambdaSecurityGroup, + privateSubnets, + !props.isDev ? lambdaDef.provisionedConcurrency : 0, + ); + return acc; + }, + {} as { [key: string]: NodejsFunction }, + ); // Create IAM role for API Gateway to invoke Lambda functions const apiGatewayRole = new cdk.aws_iam.Role(this, "ApiGatewayRole", { @@ -455,13 +449,10 @@ export class Api extends cdk.NestedStack { const resource = api.root.resourceForPath(path); // Define the integration for the Lambda function - const integration = new cdk.aws_apigateway.LambdaIntegration( - lambdaFunction, - { - proxy: true, - credentialsRole: apiGatewayRole, - }, - ); + const integration = new cdk.aws_apigateway.LambdaIntegration(lambdaFunction, { + proxy: true, + credentialsRole: apiGatewayRole, + }); // Add method for specified HTTP method resource.addMethod(method, integration, { @@ -485,10 +476,7 @@ export class Api extends cdk.NestedStack { }); // Define CloudWatch Alarms - const createCloudWatchAlarm = ( - id: string, - lambdaFunction: cdk.aws_lambda.Function, - ) => { + const createCloudWatchAlarm = (id: string, lambdaFunction: cdk.aws_lambda.Function) => { const alarm = new cdk.aws_cloudwatch.Alarm(this, id, { alarmName: `${project}-${stage}-${id}Alarm`, metric: new cdk.aws_cloudwatch.Metric({ @@ -503,8 +491,7 @@ export class Api extends cdk.NestedStack { threshold: 1, evaluationPeriods: 1, comparisonOperator: - cdk.aws_cloudwatch.ComparisonOperator - .GREATER_THAN_OR_EQUAL_TO_THRESHOLD, + cdk.aws_cloudwatch.ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD, treatMissingData: cdk.aws_cloudwatch.TreatMissingData.NOT_BREACHING, }); diff --git a/lib/stacks/data.ts b/lib/stacks/data.ts index fd8f03307b..d82c408a2b 100644 --- a/lib/stacks/data.ts +++ b/lib/stacks/data.ts @@ -469,19 +469,22 @@ export class Data extends cdk.NestedStack { sinkTypes: { provisionedConcurrency: 0 }, }; - const lambdaFunctions = Object.entries(functionConfigs).reduce((acc, [name, config]) => { - acc[name] = createLambda({ - id: name, - role: sharedLambdaRole, - useVpc: true, - environment: { - osDomain: `https://${openSearchDomainEndpoint}`, - indexNamespace, - }, - provisionedConcurrency: !props.isDev ? config.provisionedConcurrency : 0, - }); - return acc; - }, {} as { [key: string]: NodejsFunction }); + const lambdaFunctions = Object.entries(functionConfigs).reduce( + (acc, [name, config]) => { + acc[name] = createLambda({ + id: name, + role: sharedLambdaRole, + useVpc: true, + environment: { + osDomain: `https://${openSearchDomainEndpoint}`, + indexNamespace, + }, + provisionedConcurrency: !props.isDev ? config.provisionedConcurrency : 0, + }); + return acc; + }, + {} as { [key: string]: NodejsFunction }, + ); const stateMachineRole = new cdk.aws_iam.Role(this, "StateMachineRole", { assumedBy: new cdk.aws_iam.ServicePrincipal("states.amazonaws.com"), diff --git a/lib/stacks/ui-infra.ts b/lib/stacks/ui-infra.ts index 4e784b880a..b5fb8c073d 100644 --- a/lib/stacks/ui-infra.ts +++ b/lib/stacks/ui-infra.ts @@ -1,10 +1,6 @@ import * as cdk from "aws-cdk-lib"; import { AnyPrincipal, Effect, PolicyStatement } from "aws-cdk-lib/aws-iam"; -import { - BlockPublicAccess, - Bucket, - BucketEncryption, -} from "aws-cdk-lib/aws-s3"; +import { BlockPublicAccess, Bucket, BucketEncryption } from "aws-cdk-lib/aws-s3"; import { Construct } from "constructs"; import * as LC from "local-constructs"; @@ -49,8 +45,7 @@ export class UiInfra extends cdk.NestedStack { ) : null; - const sanitizedDomainName = - domainName && domainName.trim() ? domainName.trim() : null; + const sanitizedDomainName = domainName && domainName.trim() ? domainName.trim() : null; // S3 Bucket for hosting static website const bucket = new cdk.aws_s3.Bucket(this, "S3Bucket", { @@ -105,22 +100,16 @@ export class UiInfra extends cdk.NestedStack { loggingBucket.addToResourcePolicy( new cdk.aws_iam.PolicyStatement({ effect: cdk.aws_iam.Effect.ALLOW, - principals: [ - new cdk.aws_iam.ServicePrincipal("cloudfront.amazonaws.com"), - ], + principals: [new cdk.aws_iam.ServicePrincipal("cloudfront.amazonaws.com")], actions: ["s3:PutObject"], resources: [`${loggingBucket.bucketArn}/*`], }), ); // CloudFront Origin Access Identity - const cloudFrontOAI = new cdk.aws_cloudfront.OriginAccessIdentity( - this, - "CloudFrontOAI", - { - comment: "OAI to prevent direct public access to the bucket", - }, - ); + const cloudFrontOAI = new cdk.aws_cloudfront.OriginAccessIdentity(this, "CloudFrontOAI", { + comment: "OAI to prevent direct public access to the bucket", + }); // HSTS Function const hstsFunction = new cdk.aws_cloudfront.Function(this, "HstsFunction", { @@ -141,15 +130,11 @@ export class UiInfra extends cdk.NestedStack { // CloudFront Distribution const viewerCertificate = domainCertificate - ? cdk.aws_cloudfront.ViewerCertificate.fromAcmCertificate( - domainCertificate, - { - aliases: sanitizedDomainName ? [sanitizedDomainName] : [], - securityPolicy: - cdk.aws_cloudfront.SecurityPolicyProtocol.TLS_V1_2_2021, - sslMethod: cdk.aws_cloudfront.SSLMethod.SNI, - }, - ) + ? cdk.aws_cloudfront.ViewerCertificate.fromAcmCertificate(domainCertificate, { + aliases: sanitizedDomainName ? [sanitizedDomainName] : [], + securityPolicy: cdk.aws_cloudfront.SecurityPolicyProtocol.TLS_V1_2_2021, + sslMethod: cdk.aws_cloudfront.SSLMethod.SNI, + }) : cdk.aws_cloudfront.ViewerCertificate.fromCloudFrontDefaultCertificate(); const distribution = new cdk.aws_cloudfront.CloudFrontWebDistribution( @@ -165,15 +150,12 @@ export class UiInfra extends cdk.NestedStack { behaviors: [ { isDefaultBehavior: true, - allowedMethods: - cdk.aws_cloudfront.CloudFrontAllowedMethods.GET_HEAD, - viewerProtocolPolicy: - cdk.aws_cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS, + allowedMethods: cdk.aws_cloudfront.CloudFrontAllowedMethods.GET_HEAD, + viewerProtocolPolicy: cdk.aws_cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS, functionAssociations: [ { function: hstsFunction, - eventType: - cdk.aws_cloudfront.FunctionEventType.VIEWER_RESPONSE, + eventType: cdk.aws_cloudfront.FunctionEventType.VIEWER_RESPONSE, }, ], }, diff --git a/lib/stacks/uploads.ts b/lib/stacks/uploads.ts index 1f754d7fce..fedd0c3725 100644 --- a/lib/stacks/uploads.ts +++ b/lib/stacks/uploads.ts @@ -43,9 +43,7 @@ export class Uploads extends cdk.NestedStack { maxAge: 3000, }, ], - removalPolicy: isDev - ? cdk.RemovalPolicy.DESTROY - : cdk.RemovalPolicy.RETAIN, + removalPolicy: isDev ? cdk.RemovalPolicy.DESTROY : cdk.RemovalPolicy.RETAIN, autoDeleteObjects: isDev, }); @@ -54,10 +52,7 @@ export class Uploads extends cdk.NestedStack { effect: cdk.aws_iam.Effect.DENY, principals: [new cdk.aws_iam.AnyPrincipal()], actions: ["s3:*"], - resources: [ - attachmentsBucket.bucketArn, - `${attachmentsBucket.bucketArn}/*`, - ], + resources: [attachmentsBucket.bucketArn, `${attachmentsBucket.bucketArn}/*`], conditions: { Bool: { "aws:SecureTransport": "false" }, }, diff --git a/lib/vitest.setup.ts b/lib/vitest.setup.ts index 573631b2b1..61012f372a 100644 --- a/lib/vitest.setup.ts +++ b/lib/vitest.setup.ts @@ -69,6 +69,8 @@ beforeEach(() => { process.env.DLQ_URL = "https://sqs.us-east-1.amazonaws.com/123/test"; process.env.configurationSetName = "SES"; process.env.brokerString = KAFKA_BROKERS; + process.env.idmAuthzApiKeyArn = "test-secret"; // pragma: allowlist secret + process.env.idmAuthzApiEndpoint = "https://dimAuthzEndpoint.com"; }); afterEach(() => { diff --git a/mocks/data/cpocs.ts b/mocks/data/cpocs.ts index bb240840a1..22c4935211 100644 --- a/mocks/data/cpocs.ts +++ b/mocks/data/cpocs.ts @@ -1,101 +1,109 @@ -export const MUHAMMAD_BASHAR_ID = ""; -export const ELTON_BEATTY_ID = ""; -export const JEDIDIAH_HAYES_ID = ""; -export const MARSHALL_HENDERSON_ID = ""; -export const BRIDGET_HERMANN_ID = ""; -export const MAGGIE_LOWENSTEIN_ID = ""; -export const THOMAS_MANN_ID = ""; -export const DESIREE_MAYER_ID = ""; -export const WINSTON_OCONNOR_ID = ""; -export const MACY_TREMBLAY_ID = ""; +import { TestCpocsItemResult } from "../index.d"; -export const cpocs = [ - { - _id: MUHAMMAD_BASHAR_ID, +export const MUHAMMAD_BASHAR_ID = 100; +export const ELTON_BEATTY_ID = 101; +export const JEDIDIAH_HAYES_ID = 102; +export const MARSHALL_HENDERSON_ID = 103; +export const BRIDGET_HERMANN_ID = 104; +export const MAGGIE_LOWENSTEIN_ID = 105; +export const THOMAS_MANN_ID = 106; +export const DESIREE_MAYER_ID = 107; +export const WINSTON_OCONNOR_ID = 108; +export const MACY_TREMBLAY_ID = 109; + +const cpocs: Record = { + [MUHAMMAD_BASHAR_ID]: { + _id: `${MUHAMMAD_BASHAR_ID}`, _source: { id: MUHAMMAD_BASHAR_ID, firstName: "Muhammad", lastName: "Bashar", - email: "muhammad.bashar@example.com" - } + email: "muhammad.bashar@example.com", + }, }, - { - _id: ELTON_BEATTY_ID, + [ELTON_BEATTY_ID]: { + _id: `${ELTON_BEATTY_ID}`, _source: { id: ELTON_BEATTY_ID, firstName: "Elton", lastName: "Beatty", - email: "elton.beatty@example.com" - } + email: "elton.beatty@example.com", + }, }, - { - _id: JEDIDIAH_HAYES_ID, + [JEDIDIAH_HAYES_ID]: { + _id: `${JEDIDIAH_HAYES_ID}`, _source: { id: JEDIDIAH_HAYES_ID, firstName: "Jedidiah", lastName: "Hayes", - email: "jedidiah.hayes@example.com" - } + email: "jedidiah.hayes@example.com", + }, }, - { - _id: MARSHALL_HENDERSON_ID, + [MARSHALL_HENDERSON_ID]: { + _id: `${MARSHALL_HENDERSON_ID}`, _source: { id: MARSHALL_HENDERSON_ID, firstName: "Marshall", lastName: "Henderson", - email: "marshall.henderson@example.com" - } + email: "marshall.henderson@example.com", + }, }, - { - _id: BRIDGET_HERMANN_ID, + [BRIDGET_HERMANN_ID]: { + _id: `${BRIDGET_HERMANN_ID}`, _source: { id: BRIDGET_HERMANN_ID, firstName: "Bridget", lastName: "Hermann", - email: "bridget.hermann@example.com" - } - },{ - _id: MAGGIE_LOWENSTEIN_ID, + email: "bridget.hermann@example.com", + }, + }, + [MAGGIE_LOWENSTEIN_ID]: { + _id: `${MAGGIE_LOWENSTEIN_ID}`, _source: { id: MAGGIE_LOWENSTEIN_ID, firstName: "Maggie", lastName: "Lowenstein", - email: "maggie.lowenstein@example.com" - } + email: "maggie.lowenstein@example.com", + }, }, - { - _id: THOMAS_MANN_ID, + [THOMAS_MANN_ID]: { + _id: `${THOMAS_MANN_ID}`, _source: { id: THOMAS_MANN_ID, firstName: "Thomas", lastName: "Mann", - email: "thomas.mann@example.com" - } + email: "thomas.mann@example.com", + }, }, - { - _id: DESIREE_MAYER_ID, + [DESIREE_MAYER_ID]: { + _id: `${DESIREE_MAYER_ID}`, _source: { id: DESIREE_MAYER_ID, firstName: "Desiree", lastName: "Mayer", - email: "desiree.mayer@example.com" - } - },{ - _id: WINSTON_OCONNOR_ID, + email: "desiree.mayer@example.com", + }, + }, + [WINSTON_OCONNOR_ID]: { + _id: `${WINSTON_OCONNOR_ID}`, _source: { id: WINSTON_OCONNOR_ID, firstName: "Winston", lastName: "O'Connor", - email: "winston.oconnor@example.com" - } + email: "winston.oconnor@example.com", + }, }, - { - _id: MACY_TREMBLAY_ID, + [MACY_TREMBLAY_ID]: { + _id: `${MACY_TREMBLAY_ID}`, _source: { id: MACY_TREMBLAY_ID, firstName: "Macy", lastName: "Tremblay", - email: "macy.tremblay@example.com" - } + email: "macy.tremblay@example.com", + }, }, -] +}; + +export default cpocs; + +export const cpocsList = Object.values(cpocs); diff --git a/mocks/data/types.ts b/mocks/data/types.ts index 17df65441a..95bd65202b 100644 --- a/mocks/data/types.ts +++ b/mocks/data/types.ts @@ -1,68 +1,75 @@ -export const CHIP_SPA_AUTHORITY_ID = "124"; -export const MEDICAID_SPA_AUTHORITY_ID = "125"; -export const NOT_FOUND_AUTHORITY_ID = "10"; +export const CHIP_SPA_AUTHORITY_ID = 124; +export const MEDICAID_SPA_AUTHORITY_ID = 125; +export const NOT_FOUND_AUTHORITY_ID = 10; export const ERROR_AUTHORITY_ID = "throw error"; -export const TYPE_ONE_ID = "1"; -export const TYPE_TWO_ID = "2"; -export const TYPE_THREE_ID = "3"; -export const DO_NOT_USE_TYPE_ID = "4"; +export const TYPE_ONE_ID = 1; +export const TYPE_TWO_ID = 2; +export const TYPE_THREE_ID = 3; +export const DO_NOT_USE_TYPE_ID = 4; -export const medicaidTypes = [{ - _source: { - id: TYPE_ONE_ID, - authorityId: MEDICAID_SPA_AUTHORITY_ID, - name: "Type One" +export const medicaidTypes = [ + { + _source: { + id: TYPE_ONE_ID, + authorityId: MEDICAID_SPA_AUTHORITY_ID, + name: "Type One", }, }, { - _source: { - id: TYPE_TWO_ID, - authorityId: MEDICAID_SPA_AUTHORITY_ID, - name: "Type Two" + _source: { + id: TYPE_TWO_ID, + authorityId: MEDICAID_SPA_AUTHORITY_ID, + name: "Type Two", }, - }]; + }, +]; -export const chipTypes = [{ - _source: { - id: TYPE_THREE_ID, - authorityId: CHIP_SPA_AUTHORITY_ID, - name: "Type Three" +export const chipTypes = [ + { + _source: { + id: TYPE_THREE_ID, + authorityId: CHIP_SPA_AUTHORITY_ID, + name: "Type Three", }, - }] + }, +]; export const types = [ ...medicaidTypes, ...chipTypes, { - _source: { - id: DO_NOT_USE_TYPE_ID, - authorityId: CHIP_SPA_AUTHORITY_ID, - name: "Do Not Use Type Four" + _source: { + id: DO_NOT_USE_TYPE_ID, + authorityId: CHIP_SPA_AUTHORITY_ID, + name: "Do Not Use Type Four", }, }, ]; -export const medicaidSubtypes = [{ - _source: { - id: "4", - authorityId: MEDICAID_SPA_AUTHORITY_ID, - name: "Sub Type Four", - typeId: TYPE_ONE_ID +export const medicaidSubtypes = [ + { + _source: { + id: 4, + authorityId: MEDICAID_SPA_AUTHORITY_ID, + name: "Sub Type Four", + typeId: TYPE_ONE_ID, }, }, { - _source: { - id: "5", - authorityId: MEDICAID_SPA_AUTHORITY_ID, - name: "Sub Type Five", - typeId: TYPE_TWO_ID + _source: { + id: 5, + authorityId: MEDICAID_SPA_AUTHORITY_ID, + name: "Sub Type Five", + typeId: TYPE_TWO_ID, }, - }] + }, +]; -export const chipSubtypes = [{ +export const chipSubtypes = [ + { _source: { - id: "6", + id: 6, authorityId: CHIP_SPA_AUTHORITY_ID, name: "Sub Type Six", typeId: TYPE_THREE_ID, @@ -70,19 +77,20 @@ export const chipSubtypes = [{ }, { _source: { - id: "7", + id: 7, authorityId: CHIP_SPA_AUTHORITY_ID, name: "Sub Type Seven", typeId: TYPE_THREE_ID, }, - }] + }, +]; export const subtypes = [ ...medicaidSubtypes, ...chipSubtypes, { _source: { - id: "8", + id: 8, authorityId: CHIP_SPA_AUTHORITY_ID, name: "Do Not Use Sub Type Eight", typeId: DO_NOT_USE_TYPE_ID, diff --git a/mocks/data/users/idmUsers.ts b/mocks/data/users/idmUsers.ts new file mode 100644 index 0000000000..e324958b12 --- /dev/null +++ b/mocks/data/users/idmUsers.ts @@ -0,0 +1,40 @@ +export const testStateIDMUserMissingIdentity = { + sub: "0000aaaa-0000-00aa-0a0a-aaaaaa000000", + "custom:cms-roles": "onemac-micro-statesubmitter", + "custom:state": "VA,OH,SC,CO,GA,MD", + email_verified: true, + given_name: "State", + family_name: "Person", + username: "abcd", + email: "stateperson@example.com", +}; + +export const testStateIDMUser = { + sub: "0000aaaa-0000-00aa-0a0a-aaaaaa000000", + "custom:cms-roles": "onemac-micro-statesubmitter", + "custom:state": "VA,OH,SC,CO,GA,MD", + email_verified: true, + given_name: "State", + family_name: "Person", + "custom:username": "fail", + email: "stateperson@example.com", + identities: + '[{"dateCreated":"1709308952587","userId":"abc123","providerName":"IDM","providerType":"OIDC","issuer":null,"primary":"true"}]', +}; +export const testStateIDMUserGood = { + sub: "0000aaaa-0000-00aa-0a0a-aaaaaa000000", + "custom:cms-roles": "onemac-micro-super", + "custom:state": "VA,OH,SC,CO,GA,MD", + email_verified: true, + given_name: "State", + family_name: "Person", + "custom:username": "abcd", + email: "stateperson@example.com", + identities: + '[{"dateCreated":"1709308952587","userId":"abc123","providerName":"IDM","providerType":"OIDC","issuer":null,"primary":"true"}]', +}; +export const TEST_IDM_USERS = { + testStateIDMUser, + testStateIDMUserGood, + testStateIDMUserMissingIdentity, +}; diff --git a/mocks/data/users/index.ts b/mocks/data/users/index.ts index b84c402249..953555aca0 100644 --- a/mocks/data/users/index.ts +++ b/mocks/data/users/index.ts @@ -47,3 +47,4 @@ export * from "./helpDeskUsers"; export * from "./mockStorage"; export * from "./readOnlyCMSUsers"; export * from "./stateSubmitters"; +export * from "./idmUsers"; diff --git a/mocks/data/users/stateSubmitters.ts b/mocks/data/users/stateSubmitters.ts index b2e5bb67db..ceb2470c42 100644 --- a/mocks/data/users/stateSubmitters.ts +++ b/mocks/data/users/stateSubmitters.ts @@ -34,6 +34,39 @@ export const makoStateSubmitter: TestUserData = { ], Username: "cd400c39-9e7c-4341-b62f-234e2ecb339d", }; +export const superUser: TestUserData = { + UserAttributes: [ + { + Name: "email", + Value: "mako.stateuser@gmail.com", + }, + { + Name: "email_verified", + Value: "true", + }, + { + Name: "given_name", + Value: "Stateuser", + }, + { + Name: "family_name", + Value: "Tester", + }, + { + Name: "custom:state", + Value: "ZZ", + }, + { + Name: "custom:cms-roles", + Value: "onemac-micro-super", + }, + { + Name: "sub", + Value: "cd400c39-9e7c-4341-b62f-234e2ecb339e", + }, + ], + Username: "cd400c39-9e7c-4341-b62f-234e2ecb339e", +}; export const stateSubmitter: TestUserData = { UserAttributes: [ @@ -275,6 +308,7 @@ export const testNewStateSubmitter: TestUserData = { export const stateSubmitters: TestUserData[] = [ makoStateSubmitter, + superUser, stateSubmitter, noDataStateSubmitter, coStateSubmitter, diff --git a/mocks/handlers/api/index.ts b/mocks/handlers/api/index.ts index dade0e5f72..abce82fd4e 100644 --- a/mocks/handlers/api/index.ts +++ b/mocks/handlers/api/index.ts @@ -2,14 +2,8 @@ import { itemHandlers } from "./items"; import { submissionHandlers } from "./submissions"; import { typeHandlers } from "./types"; -export const apiHandlers = [ - ...itemHandlers, - ...submissionHandlers, - ...typeHandlers -]; +export const apiHandlers = [...itemHandlers, ...submissionHandlers, ...typeHandlers]; -export { - mockCurrentAuthenticatedUser, - mockUseGetUser, - mockUserAttributes, -} from "./user"; +export { mockCurrentAuthenticatedUser, mockUseGetUser, mockUserAttributes } from "./user"; + +export { errorSubTypesHandler, errorTypeHandler } from "./types"; diff --git a/mocks/handlers/api/types.ts b/mocks/handlers/api/types.ts index abb15ad130..fda5255468 100644 --- a/mocks/handlers/api/types.ts +++ b/mocks/handlers/api/types.ts @@ -1,17 +1,17 @@ import { http, HttpResponse } from "msw"; -import { types, subtypes, ERROR_AUTHORITY_ID } from "../../data/types"; +import { types, subtypes } from "../../data/types"; -type GetTypesBody = { authorityId: string }; -type GetSubTypesBody = { authorityId: string; typeIds: string[] }; +type GetTypesBody = { authorityId: number }; +type GetSubTypesBody = { authorityId: number; typeIds: number[] }; const defaultTypeHandler = http.post(/\/getTypes$/, async ({ request }) => { const { authorityId } = await request.json(); - if (authorityId === ERROR_AUTHORITY_ID) { - throw Error("useGetTypes > mockFetch: Expected error thrown by test."); - } - - const hits = types.filter(type => type?._source?.authorityId == authorityId && !type?._source?.name.match(/Do Not Use/)) || [] + const hits = + types.filter( + (type) => + type?._source?.authorityId == authorityId && !type?._source?.name.match(/Do Not Use/), + ) || []; return HttpResponse.json({ hits: { @@ -20,20 +20,23 @@ const defaultTypeHandler = http.post(/\/getTypes$/, async ({ }); }); +export const errorTypeHandler = http.post( + /\/getTypes$/, + async () => new HttpResponse("Internal server error", { status: 500 }), +); + const defaultSubTypesHandler = http.post( /\/getSubTypes$/, async ({ request }) => { const { authorityId, typeIds } = await request.json(); - if (authorityId === ERROR_AUTHORITY_ID) { - throw Error("useGetSubTypes > mockFetch: Expected error thrown by test."); - } - - const hits = subtypes.filter(type => - type?._source?.authorityId == authorityId - && typeIds.includes(type?._source?.typeId) - && !type?._source?.name.match(/Do Not Use/) - ) || [] + const hits = + subtypes.filter( + (type) => + type?._source?.authorityId == authorityId && + typeIds.includes(type?._source?.typeId) && + !type?._source?.name.match(/Do Not Use/), + ) || []; return HttpResponse.json({ hits: { @@ -43,4 +46,9 @@ const defaultSubTypesHandler = http.post( }, ); +export const errorSubTypesHandler = http.post( + /\/getSubTypes$/, + () => new HttpResponse("Internal server error", { status: 500 }), +); + export const typeHandlers = [defaultTypeHandler, defaultSubTypesHandler]; diff --git a/mocks/handlers/api/user.ts b/mocks/handlers/api/user.ts index 148d725e6f..7047e4f3b1 100644 --- a/mocks/handlers/api/user.ts +++ b/mocks/handlers/api/user.ts @@ -1,9 +1,7 @@ import { CognitoUserAttribute } from "amazon-cognito-identity-js"; import { isCmsUser } from "shared-utils"; import { findUserByUsername, convertUserAttributes } from "../authUtils"; -import type { - TestUserData, -} from "../.."; +import type { TestUserData } from "../.."; // using `any` type here because the function that this is mocking uses any export const mockCurrentAuthenticatedUser = (): TestUserData | any => { diff --git a/mocks/handlers/authUtils.ts b/mocks/handlers/authUtils.ts index 97046d775e..419d2cbf0f 100644 --- a/mocks/handlers/authUtils.ts +++ b/mocks/handlers/authUtils.ts @@ -1,7 +1,5 @@ import { makoReviewer, makoStateSubmitter, userResponses } from "../data/users"; -import type { - TestUserData, -} from "../index.d"; +import type { TestUserData } from "../index.d"; import { CognitoUserAttributes } from "shared-types"; export const setMockUsername = (user?: TestUserData | string | null): void => { diff --git a/mocks/handlers/aws/cognito.ts b/mocks/handlers/aws/cognito.ts index 84a58d7ddd..969cafea99 100644 --- a/mocks/handlers/aws/cognito.ts +++ b/mocks/handlers/aws/cognito.ts @@ -286,7 +286,9 @@ export const identityProviderServiceHandler = http.post< ); return passthrough(); } - + if (target == "AWSCognitoIdentityProviderService.AdminUpdateUserAttributes") { + return new HttpResponse(null, { status: 200 }); + } if (target == "AWSCognitoIdentityProviderService.GetUser") { const { AccessToken } = (await request.json()) as IdpRequestSessionBody; const username = getUsernameFromAccessToken(AccessToken) || process.env.MOCK_USER_USERNAME; diff --git a/mocks/handlers/aws/idm.ts b/mocks/handlers/aws/idm.ts new file mode 100644 index 0000000000..2875fa9d8a --- /dev/null +++ b/mocks/handlers/aws/idm.ts @@ -0,0 +1,30 @@ +import { http, HttpResponse } from "msw"; + +const defaultIDMHandler = http.get( + "https://dimauthzendpoint.com/api/v1/authz/id/all", + async ({ request }) => { + const url = new URL(request.url); + const id = url.searchParams.get("userId"); + + if (id === "fail") { + return HttpResponse.json({ text: "Failed to retrieve user" }, { status: 401 }); + } else if (id === "abcd") { + return HttpResponse.json( + { + userProfileAppRoles: { + userRolesInfoList: [ + { + roleName: "onemac-micro-statesubmitter", + roleAttributes: [{ name: "State/Territory", value: "VA" }], + }, + ], + }, + }, + { status: 200 }, + ); + } + return HttpResponse.json({ text: "Failed to retrieve user" }, { status: 200 }); + }, +); + +export const idmHandlers = [defaultIDMHandler]; diff --git a/mocks/handlers/aws/index.ts b/mocks/handlers/aws/index.ts index 9b4f5cfb7c..f1faae9d5e 100644 --- a/mocks/handlers/aws/index.ts +++ b/mocks/handlers/aws/index.ts @@ -5,6 +5,7 @@ import { lambdaHandlers } from "./lambda"; import { secretsManagerHandlers } from "./secretsManager"; import { stepFunctionHandlers } from "./stepFunctions"; import { emailHandlers } from "./email"; +import { idmHandlers } from "./idm"; export const awsHandlers = [ ...cloudFormationHandlers, ...cognitoHandlers, @@ -13,6 +14,7 @@ export const awsHandlers = [ ...secretsManagerHandlers, ...stepFunctionHandlers, ...emailHandlers, + ...idmHandlers, ]; export { errorCloudFormationHandler } from "./cloudFormation"; diff --git a/mocks/handlers/opensearch/changelog.ts b/mocks/handlers/opensearch/changelog.ts index bdaa09f03d..456c3a71b3 100644 --- a/mocks/handlers/opensearch/changelog.ts +++ b/mocks/handlers/opensearch/changelog.ts @@ -11,7 +11,8 @@ const defaultChangelogSearchHandler = http.post( const must = query?.bool?.must; const mustTerms = must ? getTermKeys(must) : []; - const packageIdValue = getTermValues(must, "packageId.keyword") || getTermValues(must, "packageId"); + const packageIdValue = + getTermValues(must, "packageId.keyword") || getTermValues(must, "packageId"); if (!packageIdValue) { return new HttpResponse("No packageId provided", { status: 400 }); @@ -39,7 +40,11 @@ const defaultChangelogSearchHandler = http.post( "", ) as keyof TestChangelogDocument; if (filterValue) { - changelog = filterItemsByTerm(changelog, filterTerm, filterValue); + changelog = filterItemsByTerm( + changelog, + filterTerm, + filterValue, + ); } }); } diff --git a/mocks/handlers/opensearch/cpocs.ts b/mocks/handlers/opensearch/cpocs.ts index 7a1ec302e9..8e603ca865 100644 --- a/mocks/handlers/opensearch/cpocs.ts +++ b/mocks/handlers/opensearch/cpocs.ts @@ -1,36 +1,37 @@ import { http, HttpResponse } from "msw"; -import { cpocs } from "../../data/cpocs"; +import { cpocsList } from "../../data/cpocs"; const defaultCpocSearchHandler = http.post( - "https://vpc-opensearchdomain-mock-domain.us-east-1.es.amazonaws.com/test-namespace-cpocs/_search", - () => HttpResponse.json({ - "took": 3, - "timed_out": false, - "_shards": { - "total": 5, - "successful": 5, - "skipped": 0, - "failed": 0 - }, - "hits": { - "total": { - "value": 654, - "relation": "eq" + "https://vpc-opensearchdomain-mock-domain.us-east-1.es.amazonaws.com/test-namespace-cpocs/_search", + () => + HttpResponse.json({ + took: 3, + timed_out: false, + _shards: { + total: 5, + successful: 5, + skipped: 0, + failed: 0, }, - "max_score": 1, - "hits": cpocs - } - }) -) + hits: { + total: { + value: 654, + relation: "eq", + }, + max_score: 1, + hits: cpocsList, + }, + }), +); export const emptyCpocSearchHandler = http.post( - "https://vpc-opensearchdomain-mock-domain.us-east-1.es.amazonaws.com/test-namespace-cpocs/_search", - () => new HttpResponse() + "https://vpc-opensearchdomain-mock-domain.us-east-1.es.amazonaws.com/test-namespace-cpocs/_search", + () => new HttpResponse(), ); export const errorCpocSearchHandler = http.post( - "https://vpc-opensearchdomain-mock-domain.us-east-1.es.amazonaws.com/test-namespace-cpocs/_search", - () => new HttpResponse("Internal server error", { status: 500 }) + "https://vpc-opensearchdomain-mock-domain.us-east-1.es.amazonaws.com/test-namespace-cpocs/_search", + () => new HttpResponse("Internal server error", { status: 500 }), ); export const cpocSearchHandlers = [defaultCpocSearchHandler]; diff --git a/mocks/handlers/opensearch/index.ts b/mocks/handlers/opensearch/index.ts index bf9cf4fff8..5d0c78199b 100644 --- a/mocks/handlers/opensearch/index.ts +++ b/mocks/handlers/opensearch/index.ts @@ -24,3 +24,5 @@ export { errorDeleteIndexHandler, } from "./indices"; export { errorSecurityRolesMappingHandler } from "./security"; +export { errorSubtypeSearchHandler } from "./subtypes"; +export { errorTypeSearchHandler } from "./types"; diff --git a/mocks/handlers/opensearch/subtypes.ts b/mocks/handlers/opensearch/subtypes.ts index d6b3a5058f..94151831d3 100644 --- a/mocks/handlers/opensearch/subtypes.ts +++ b/mocks/handlers/opensearch/subtypes.ts @@ -1,28 +1,28 @@ import { http, HttpResponse, PathParams } from "msw"; -import { subtypes, ERROR_AUTHORITY_ID } from "../../data/types" -import { - SearchQueryBody, -} from "../../index.d"; -import { getFilterValue } from "./util"; +import { subtypes } from "../../data/types"; +import { SearchQueryBody } from "../../index.d"; +import { getFilterValueAsNumber, getFilterValueAsNumberArray } from "./util"; const defaultSubtypeSearchHandler = http.post( "https://vpc-opensearchdomain-mock-domain.us-east-1.es.amazonaws.com/test-namespace-subtypes/_search", async ({ request }) => { const { query } = await request.json(); const must = query?.bool?.must; - - const authorityId = getFilterValue(must, 'match', 'authorityId'); - const typeIds = getFilterValue(must, 'terms', 'typeId') || []; - if (authorityId === ERROR_AUTHORITY_ID) { - return new HttpResponse("Internal server error", { status: 500 }); + const authorityId = getFilterValueAsNumber(must, "match", "authorityId"); + const typeIds = getFilterValueAsNumberArray(must, "terms", "typeId"); + + if (authorityId === undefined) { + return new HttpResponse("Invalid authority Id", { status: 400 }); } - const hits = subtypes.filter(type => - type?._source?.authorityId == authorityId - && typeIds.includes(type?._source?.typeId) - && !type?._source?.name.match(/Do Not Use/) - ) || [] + const hits = + subtypes.filter( + (type) => + type?._source?.authorityId == authorityId && + typeIds.includes(type?._source?.typeId) && + !type?._source?.name.match(/Do Not Use/), + ) || []; return HttpResponse.json({ took: 5, @@ -45,4 +45,9 @@ const defaultSubtypeSearchHandler = http.post( }, ); +export const errorSubtypeSearchHandler = http.post( + "https://vpc-opensearchdomain-mock-domain.us-east-1.es.amazonaws.com/test-namespace-subtypes/_search", + () => new HttpResponse("Internal server error", { status: 500 }), +); + export const subtypeSearchHandlers = [defaultSubtypeSearchHandler]; diff --git a/mocks/handlers/opensearch/types.ts b/mocks/handlers/opensearch/types.ts index f81f9abff4..5c298ecd94 100644 --- a/mocks/handlers/opensearch/types.ts +++ b/mocks/handlers/opensearch/types.ts @@ -1,21 +1,25 @@ import { http, HttpResponse, PathParams } from "msw"; -import { types, ERROR_AUTHORITY_ID } from "../../data/types" +import { types } from "../../data/types"; import { SearchQueryBody } from "../../index.d"; -import { getFilterValue } from "./util"; +import { getFilterValueAsNumber } from "./util"; const defaultTypeSearchHandler = http.post( "https://vpc-opensearchdomain-mock-domain.us-east-1.es.amazonaws.com/test-namespace-types/_search", async ({ request }) => { const { query } = await request.json(); const must = query?.bool?.must; - - const authorityId = getFilterValue(must, 'match', 'authorityId'); - if (authorityId === ERROR_AUTHORITY_ID) { - return new HttpResponse("Internal server error", { status: 500 }); + const authorityId = getFilterValueAsNumber(must, "match", "authorityId"); + + if (authorityId === undefined) { + return new HttpResponse("Invalid authority Id", { status: 400 }); } - const hits = types.filter(type => type?._source?.authorityId == authorityId && !type?._source?.name.match(/Do Not Use/)) || [] + const hits = + types.filter( + (type) => + type?._source?.authorityId == authorityId && !type?._source?.name.match(/Do Not Use/), + ) || []; return HttpResponse.json({ took: 5, @@ -38,4 +42,9 @@ const defaultTypeSearchHandler = http.post( }, ); +export const errorTypeSearchHandler = http.post( + "https://vpc-opensearchdomain-mock-domain.us-east-1.es.amazonaws.com/test-namespace-types/_search", + () => new HttpResponse("Internal server error", { status: 500 }), +); + export const typeSearchHandlers = [defaultTypeSearchHandler]; diff --git a/mocks/handlers/opensearch/util.ts b/mocks/handlers/opensearch/util.ts index 9f26b4011a..53ffd55d8e 100644 --- a/mocks/handlers/opensearch/util.ts +++ b/mocks/handlers/opensearch/util.ts @@ -6,46 +6,125 @@ export const getFilterValue = ( filterName: string, ): string | string[] | undefined => { if (query) { - const rules: QueryContainer[] = (Array.isArray(query)) ? query : [query]; + const rules: QueryContainer[] = Array.isArray(query) ? query : [query]; const values: string[] = []; - rules.forEach(rule => { + rules.forEach((rule) => { if (rule?.[queryKey]?.[filterName] !== undefined) { if (Array.isArray(rule[queryKey][filterName])) { - rule[queryKey][filterName].forEach(value => { + rule[queryKey][filterName].forEach((value) => { if (value !== undefined) { - values.push(value.toString()) + values.push(value.toString()); } - }) + }); } else { values.push(rule[queryKey][filterName].toString()); } } - }) + }); if (values.length === 0) return undefined; if (values.length === 1) return values[0].toString(); - return values.map(value => value.toString()); + return values.map((value) => value.toString()); } return undefined; }; +export const getFilterValueAsBoolean = ( + query: QueryContainer | QueryContainer[] | undefined, + queryKey: keyof QueryContainer, + filterName: string, +): boolean | undefined => { + const value = getFilterValue(query, queryKey, filterName); + + if (value === undefined) { + return undefined; + } + + const parseSingleStringBoolean = (value: string | undefined): boolean | undefined => { + if (typeof value === "string") { + if (value.toLowerCase() === "true" || value.toLowerCase() === "yes") { + return true; + } + if (value.toLowerCase() === "false" || value.toLowerCase() === "no") { + return false; + } + } + return undefined; + }; + + if (typeof value === "string") { + return parseSingleStringBoolean(value); + } + + if (Array.isArray(value) && value.length > 0) { + const boolValues = value + .map((val) => parseSingleStringBoolean(val)) + .filter((val) => val !== undefined); + if (boolValues.length > 0) { + return boolValues.every((val) => val === true); + } + } + + return undefined; +}; + +export const getFilterValueAsNumber = ( + query: QueryContainer | QueryContainer[] | undefined, + queryKey: keyof QueryContainer, + filterName: string, +): number | undefined => { + const value = getFilterValue(query, queryKey, filterName); + + const intValues = parseValueAsNumberArray(value); + + if (intValues.length > 0) { + return intValues[0]; + } + + return undefined; +}; + +export const getFilterValueAsNumberArray = ( + query: QueryContainer | QueryContainer[] | undefined, + queryKey: keyof QueryContainer, + filterName: string, +): number[] => { + const value = getFilterValue(query, queryKey, filterName); + + return parseValueAsNumberArray(value); +}; + +const parseValueAsNumberArray = (value: string | string[] | undefined): number[] => { + if (value == undefined) { + return []; + } + + if (typeof value === "string") { + return [Number.parseInt(value)]; + } + + return ( + value.filter((val) => val && typeof val === "string").map((val) => Number.parseInt(val)) || [] + ); +}; + export const getTermValues = ( query: QueryContainer | QueryContainer[] | undefined, filterName: string, ): string | string[] | undefined => { - const term = getFilterValue(query, 'term', filterName); - const terms = getFilterValue(query, 'terms', filterName); + const term = getFilterValue(query, "term", filterName); + const terms = getFilterValue(query, "terms", filterName); if (term && terms) { const values: string[] = []; - values.concat(Array.isArray(term) ? term : [term]) + values.concat(Array.isArray(term) ? term : [term]); values.concat(Array.isArray(terms) ? terms : [terms]); return values; } - + return term || terms; -} +}; export const getTermKeys = (query: QueryContainer[] | QueryContainer | undefined): string[] => { const filterKeys: string[] = []; @@ -61,10 +140,10 @@ export const getTermKeys = (query: QueryContainer[] | QueryContainer | undefined }); } else { if ((query as QueryContainer)?.term !== undefined) { - filterKeys.push(...Object.keys((query.term as Record))); + filterKeys.push(...Object.keys(query.term as Record)); } if ((query as QueryContainer)?.terms !== undefined) { - filterKeys.push(...Object.keys((query.terms as TermsQuery))); + filterKeys.push(...Object.keys(query.terms as TermsQuery)); } } } @@ -75,7 +154,7 @@ export const matchFilter = ( item: T | null | undefined, filterTerm: keyof T | null | undefined, filterValue: string | string[] | null | undefined, -): boolean => { +): boolean => { if (!item || !filterTerm || !filterValue) { return false; } @@ -87,14 +166,15 @@ export const matchFilter = ( } return filterValue?.toString()?.toLocaleLowerCase() == itemValue; -} +}; export const filterItemsByTerm = ( hits: TestHit[], filterTerm: keyof D, - filterValue: string | string[] + filterValue: string | string[], ): TestHit[] => { return hits.filter( - (hit) => (hit as TestHit)?._source && matchFilter((hit._source as D), filterTerm, filterValue) - ) -} + (hit) => + (hit as TestHit)?._source && matchFilter(hit._source as D, filterTerm, filterValue), + ); +}; diff --git a/mocks/index.d.ts b/mocks/index.d.ts index 2def0c55ee..4b8d79e68d 100644 --- a/mocks/index.d.ts +++ b/mocks/index.d.ts @@ -32,6 +32,10 @@ export type TestSubtypeItemResult = DeepPartial; export type TestSubtypeDocument = TestSubtypeItemResult["_source"]; +export type TestCpocsItemResult = DeepPartial; + +export type TestCpocsDocument = TestCpocsItemResult["_source"]; + export type TestSecretData = Partial> & { CreatedDate: number; DeletedDate?: number; diff --git a/package.json b/package.json index afd11c9eb4..fba63df11b 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,8 @@ "cdk": "cdk", "build:cli": "turbo build:cli", "lint": "eslint", + "format:check": "prettier --check .", + "format:write": "prettier --write .", "e2e": "turbo e2e", "e2e:ui": "turbo e2e:ui", "test-tsc": "tsc --skipLibCheck --noEmit", @@ -64,12 +66,15 @@ "@vitest/ui": "^2.0.5", "aws-cdk": "^2.157.0", "eslint": "^9.10.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-prettier": "^5.2.1", "eslint-plugin-react": "^7.35.2", "eslint-plugin-react-hooks": "^4.6.2", "globals": "^15.9.0", "happy-dom": "^15.7.4", "jest": "^29.7.0", "npm-run-all": "^4.1.5", + "prettier": "3.4.2", "semantic-release": "^21.1.2", "ts-jest": "^29.2.5", "ts-node": "^10.9.2", diff --git a/react-app/components.json b/react-app/components.json deleted file mode 100644 index 2907b0c163..0000000000 --- a/react-app/components.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "https://ui.shadcn.com/schema.json", - "style": "new-york", - "rsc": false, - "tsx": true, - "tailwind": { - "config": "tailwind.config.js", - "css": "src/index.css", - "baseColor": "slate", - "cssVariables": true - }, - "aliases": { - "components": "@/components", - "utils": "@/utils" - } -} \ No newline at end of file diff --git a/react-app/index.html b/react-app/index.html index 4e26ef1ec6..3aa7ce9100 100644 --- a/react-app/index.html +++ b/react-app/index.html @@ -1,4 +1,4 @@ - + diff --git a/react-app/src/api/getAttachmentUrl.ts b/react-app/src/api/getAttachmentUrl.ts index daa79283b8..80ed6f1747 100644 --- a/react-app/src/api/getAttachmentUrl.ts +++ b/react-app/src/api/getAttachmentUrl.ts @@ -4,7 +4,7 @@ export const getAttachmentUrl = async ( id: string, bucket: string, key: string, - filename: string + filename: string, ) => { const response = await API.post("os", "/getAttachmentUrl", { body: { diff --git a/react-app/src/api/useGetCPOCs.ts b/react-app/src/api/useGetCPOCs.ts index e654a2a30e..c157a5f69b 100644 --- a/react-app/src/api/useGetCPOCs.ts +++ b/react-app/src/api/useGetCPOCs.ts @@ -15,12 +15,6 @@ export async function fetchCpocData() { } } -export function useGetCPOCs( - queryOptions?: UseQueryOptions, -) { - return useQuery( - ["package-cpocs"], - () => fetchCpocData(), - queryOptions, - ); +export function useGetCPOCs(queryOptions?: UseQueryOptions) { + return useQuery(["package-cpocs"], () => fetchCpocData(), queryOptions); } diff --git a/react-app/src/api/useGetCounties.ts b/react-app/src/api/useGetCounties.ts index b8736005ad..536a271c30 100644 --- a/react-app/src/api/useGetCounties.ts +++ b/react-app/src/api/useGetCounties.ts @@ -24,26 +24,18 @@ const usePopulationData = (stateString: string) => { export const useGetCounties = (): { label: string; value: string }[] => { const { data: userData } = useGetUser(); - const stateCodes = useMemo( - () => getUserStateCodes(userData?.user), - [userData], - ); + const stateCodes = useMemo(() => getUserStateCodes(userData?.user), [userData]); const stateNumericCodesString = useMemo( () => stateCodes - .map( - (code) => - FULL_CENSUS_STATES.find((state) => state.value === code)?.code, - ) + .map((code) => FULL_CENSUS_STATES.find((state) => state.value === code)?.code) .filter((code): code is string => code !== undefined && code !== "00") .join(","), [stateCodes], ); - const { data: populationData = [] } = usePopulationData( - stateNumericCodesString, - ); + const { data: populationData = [] } = usePopulationData(stateNumericCodesString); return ( populationData.map((county) => { diff --git a/react-app/src/api/useGetForm.ts b/react-app/src/api/useGetForm.ts index c8b1bce817..5996638314 100644 --- a/react-app/src/api/useGetForm.ts +++ b/react-app/src/api/useGetForm.ts @@ -3,10 +3,7 @@ import { API } from "aws-amplify"; import { ReactQueryApiError, FormSchema } from "shared-types"; import { reInsertRegex } from "shared-utils"; -export const getForm = async ( - formId: string, - formVersion?: string, -): Promise => { +export const getForm = async (formId: string, formVersion?: string): Promise => { const form = await API.post("os", "/forms", { body: { formId, formVersion }, }); @@ -30,7 +27,5 @@ export const getAllForms = async () => { }; export const useGetAllForms = () => { - return useQuery(["All Webforms"], () => - getAllForms(), - ); + return useQuery(["All Webforms"], () => getAllForms()); }; diff --git a/react-app/src/api/useGetItem.ts b/react-app/src/api/useGetItem.ts index 5b3ee43840..9d8b9f4cc2 100644 --- a/react-app/src/api/useGetItem.ts +++ b/react-app/src/api/useGetItem.ts @@ -1,14 +1,8 @@ -import { - useQuery, - useQueryClient, - UseQueryOptions, -} from "@tanstack/react-query"; +import { useQuery, useQueryClient, UseQueryOptions } from "@tanstack/react-query"; import { API } from "aws-amplify"; import { opensearch, ReactQueryApiError, SEATOOL_STATUS } from "shared-types"; -export const getItem = async ( - id: string, -): Promise => +export const getItem = async (id: string): Promise => await API.post("os", "/item", { body: { id } }); export const idIsApproved = async (id: string) => { diff --git a/react-app/src/api/useGetPackageActions.ts b/react-app/src/api/useGetPackageActions.ts index 389c59e2d9..8349c9ef52 100644 --- a/react-app/src/api/useGetPackageActions.ts +++ b/react-app/src/api/useGetPackageActions.ts @@ -9,11 +9,11 @@ const getPackageActions = async (id: string): Promise => export const useGetPackageActions = ( id: string, - options?: UseQueryOptions + options?: UseQueryOptions, ) => { return useQuery( ["actions", id], () => getPackageActions(id), - options + options, ); }; diff --git a/react-app/src/api/useGetTypes.test.ts b/react-app/src/api/useGetTypes.test.ts index 37bcb75cd4..dacf6a638a 100644 --- a/react-app/src/api/useGetTypes.test.ts +++ b/react-app/src/api/useGetTypes.test.ts @@ -1,30 +1,32 @@ import { describe, expect, it } from "vitest"; import { fetchData } from "./useGetTypes"; -import { - MEDICAID_SPA_AUTHORITY_ID, - CHIP_SPA_AUTHORITY_ID, - NOT_FOUND_AUTHORITY_ID, - ERROR_AUTHORITY_ID, +import { + MEDICAID_SPA_AUTHORITY_ID, + CHIP_SPA_AUTHORITY_ID, + NOT_FOUND_AUTHORITY_ID, + ERROR_AUTHORITY_ID, TYPE_ONE_ID, TYPE_TWO_ID, TYPE_THREE_ID, DO_NOT_USE_TYPE_ID, - medicaidTypes, + medicaidTypes, medicaidSubtypes, chipTypes, - chipSubtypes -} from "mocks/data/types" + chipSubtypes, +} from "mocks/data/types"; +import { errorSubTypesHandler, errorTypeHandler } from "mocks"; +import { mockedApiServer as mockedServer } from "mocks/server"; describe("fetchData", () => { describe("fetchTypes", () => { it("makes an AWS Amplify post request for types", async () => { const types = await fetchData({ authorityId: MEDICAID_SPA_AUTHORITY_ID }); - expect(types).toEqual(medicaidTypes.map(type => type?._source)); + expect(types).toEqual(medicaidTypes.map((type) => type?._source)); }); it("successfully fetches types for a given authorityId", async () => { const types = await fetchData({ authorityId: CHIP_SPA_AUTHORITY_ID }); - expect(types).toEqual(chipTypes.map(type => type?._source)); + expect(types).toEqual(chipTypes.map((type) => type?._source)); }); it("returns an empty array when there are no types", async () => { @@ -33,27 +35,42 @@ describe("fetchData", () => { }); it("throws an error when fetch fails", async () => { - await expect(fetchData({ authorityId: ERROR_AUTHORITY_ID })).rejects.toThrow("Failed to fetch types"); + mockedServer.use(errorTypeHandler); + + await expect(fetchData({ authorityId: ERROR_AUTHORITY_ID })).rejects.toThrow( + "Failed to fetch types", + ); }); }); describe("fetchSubTypes", () => { it("makes an AWS Amplify post request for subtypes", async () => { - const subtypes = await fetchData({ authorityId: MEDICAID_SPA_AUTHORITY_ID, typeIds: [TYPE_ONE_ID, TYPE_TWO_ID] }); - expect(subtypes).toEqual(medicaidSubtypes.map(subtype => subtype?._source)); + const subtypes = await fetchData({ + authorityId: MEDICAID_SPA_AUTHORITY_ID, + typeIds: [TYPE_ONE_ID, TYPE_TWO_ID], + }); + expect(subtypes).toEqual(medicaidSubtypes.map((subtype) => subtype?._source)); }); it("successfully fetches subtypes for a given authorityId and typeIds", async () => { - const subtypes = await fetchData({ authorityId: CHIP_SPA_AUTHORITY_ID, typeIds: [TYPE_THREE_ID, DO_NOT_USE_TYPE_ID] }); - expect(subtypes).toEqual(chipSubtypes.map(subtype => subtype?._source)); + const subtypes = await fetchData({ + authorityId: CHIP_SPA_AUTHORITY_ID, + typeIds: [TYPE_THREE_ID, DO_NOT_USE_TYPE_ID], + }); + expect(subtypes).toEqual(chipSubtypes.map((subtype) => subtype?._source)); }); it("returns an empty array when there are no subtypes", async () => { - const subtypes = await fetchData({ authorityId: CHIP_SPA_AUTHORITY_ID, typeIds: [DO_NOT_USE_TYPE_ID] }); + const subtypes = await fetchData({ + authorityId: CHIP_SPA_AUTHORITY_ID, + typeIds: [DO_NOT_USE_TYPE_ID], + }); expect(subtypes).toEqual([]); }); it("throws an error when fetch fails", async () => { + mockedServer.use(errorSubTypesHandler); + await expect(fetchData({ authorityId: ERROR_AUTHORITY_ID, typeIds: [] })).rejects.toThrow( "Failed to fetch subtypes", ); diff --git a/react-app/src/api/useGetTypes.ts b/react-app/src/api/useGetTypes.ts index 89a86be05c..a1dbccecec 100644 --- a/react-app/src/api/useGetTypes.ts +++ b/react-app/src/api/useGetTypes.ts @@ -8,10 +8,7 @@ type FetchOptions = { typeIds?: number[] | string[]; }; -export async function fetchData({ - authorityId, - typeIds, -}: FetchOptions): Promise { +export async function fetchData({ authorityId, typeIds }: FetchOptions): Promise { const endpoint = typeIds ? "/getSubTypes" : "/getTypes"; const body = typeIds ? { authorityId, typeIds } : { authorityId }; @@ -39,11 +36,7 @@ export function useGetData( ? ["package-subtypes", authorityId, typeIds] : ["package-types", authorityId]; - return useQuery( - queryKey, - () => fetchData(options), - queryOptions, - ); + return useQuery(queryKey, () => fetchData(options), queryOptions); } export function useGetTypes( @@ -55,11 +48,8 @@ export function useGetTypes( export function useGetSubTypes( authorityId: number | string, - typeIds: number[] | string [], + typeIds: number[] | string[], options?: UseQueryOptions, ) { - return useGetData( - { authorityId, typeIds }, - options, - ); + return useGetData({ authorityId, typeIds }, options); } diff --git a/react-app/src/api/useGetUser.test.ts b/react-app/src/api/useGetUser.test.ts index 81d6392d24..c226d87a6a 100644 --- a/react-app/src/api/useGetUser.test.ts +++ b/react-app/src/api/useGetUser.test.ts @@ -13,9 +13,7 @@ const mockCurrentAuthenticatedUser = vi.fn((options = {}) => { // If you want to simulate an error, you could set a flag on `options` and check it here. if (options.error) { reject( - new Error( - "useGetUser > mockCurrentAuthenticatedUser: Expected error thrown by test.", - ), + new Error("useGetUser > mockCurrentAuthenticatedUser: Expected error thrown by test."), ); } else { resolve({ username: "0000aaaa-0000-00aa-0a0a-aaaaaa000000" }); @@ -31,34 +29,29 @@ const mockUserAttr = ({ options?: { error?: boolean; noRoles?: boolean }; }) => vi.fn(async () => { - return await new Promise>( - (resolve) => { - if (options?.error) - throw Error( - "useGetUser > mockUserAttr: Expected error thrown by test.", - ); - /* This array of attributes is where we make changes to our test - * user for test-related assertions. */ - return resolve([ - { Name: "sub", Value: "0000aaaa-0000-00aa-0a0a-aaaaaa000000" }, - { Name: "email_verified", Value: "true" }, - { Name: "given_name", Value: "George" }, - { Name: "family_name", Value: "Harrison" }, - { - Name: "custom:state", - Value: "VA,OH,SC,CO,GA,MD", - }, - { - Name: "email", - Value: "george@example.com", - }, - !options?.noRoles && { - Name: "custom:cms-roles", - Value: isCms ? "onemac-micro-reviewer" : "onemac-micro-cmsreview", - }, - ] as Array<{ Name: string; Value: string }>); - }, - ); + return await new Promise>((resolve) => { + if (options?.error) throw Error("useGetUser > mockUserAttr: Expected error thrown by test."); + /* This array of attributes is where we make changes to our test + * user for test-related assertions. */ + return resolve([ + { Name: "sub", Value: "0000aaaa-0000-00aa-0a0a-aaaaaa000000" }, + { Name: "email_verified", Value: "true" }, + { Name: "given_name", Value: "George" }, + { Name: "family_name", Value: "Harrison" }, + { + Name: "custom:state", + Value: "VA,OH,SC,CO,GA,MD", + }, + { + Name: "email", + Value: "george@example.com", + }, + !options?.noRoles && { + Name: "custom:cms-roles", + Value: isCms ? "onemac-micro-reviewer" : "onemac-micro-cmsreview", + }, + ] as Array<{ Name: string; Value: string }>); + }); }); describe("getUser", () => { diff --git a/react-app/src/api/useSearch.ts b/react-app/src/api/useSearch.ts index a1140b2a64..a37d451640 100644 --- a/react-app/src/api/useSearch.ts +++ b/react-app/src/api/useSearch.ts @@ -16,10 +16,7 @@ type QueryProps = { aggs?: opensearch.AggQuery[]; }; -export const getOsData = async < - TProps, - TResponse extends opensearch.Response, ->( +export const getOsData = async >( props: QueryProps, ): Promise => { const searchData = await API.post("os", `/search/${props.index}`, { @@ -35,14 +32,10 @@ export const getOsData = async < return searchData; }; -export const getMainExportData = async ( - filters?: opensearch.main.Filterable[], -) => { +export const getMainExportData = async (filters?: opensearch.main.Filterable[]) => { if (!filters) return []; - const recursiveSearch = async ( - startPage: number, - ): Promise => { + const recursiveSearch = async (startPage: number): Promise => { if (startPage * 1000 >= 10000) { return []; } @@ -69,11 +62,7 @@ export const getMainExportData = async ( }; export const useOsSearch = ( - options?: UseMutationOptions< - TResponse, - ReactQueryApiError, - QueryProps - >, + options?: UseMutationOptions>, ) => { //@ts-expect-error return useMutation>( diff --git a/react-app/src/components/Alert/index.tsx b/react-app/src/components/Alert/index.tsx index 5914465426..66f46ef49a 100644 --- a/react-app/src/components/Alert/index.tsx +++ b/react-app/src/components/Alert/index.tsx @@ -9,12 +9,10 @@ const alertVariants = cva( variants: { variant: { default: "bg-background text-foreground", - destructive: - "border-destructive/50 text-destructive [&>svg]:text-destructive", + destructive: "border-destructive/50 text-destructive [&>svg]:text-destructive", infoBlock: "border-l-[6px] border-y-0 border-r-0 border-cyan-500 bg-cyan-300/10 rounded-none", - success: - "border-l-[6px] border-[#2E8540] border-y-0 border-r-0 bg-[#E7F4E4]", + success: "border-l-[6px] border-[#2E8540] border-y-0 border-r-0 bg-[#E7F4E4]", }, }, defaultVariants: { @@ -28,12 +26,7 @@ const Alert = React.forwardRef< HTMLDivElement, React.HTMLAttributes & VariantProps >(({ className, variant, ...props }, ref) => ( -

+
)); Alert.displayName = "Alert"; @@ -51,14 +44,9 @@ AlertTitle.displayName = "AlertTitle"; const AlertDescription = React.forwardRef< HTMLParagraphElement, - React.HTMLAttributes & - VariantProps + React.HTMLAttributes & VariantProps >(({ className, ...props }, ref) => ( -
+
)); AlertDescription.displayName = "AlertDescription"; diff --git a/react-app/src/components/BreadCrumb/BreadCrumb.tsx b/react-app/src/components/BreadCrumb/BreadCrumb.tsx index 89a5fdf8c6..ee1f9d4d2a 100644 --- a/react-app/src/components/BreadCrumb/BreadCrumb.tsx +++ b/react-app/src/components/BreadCrumb/BreadCrumb.tsx @@ -74,11 +74,7 @@ export const BreadCrumbSeperator = () => ; export const BreadCrumbBar = ({ children }: React.PropsWithChildren) => { return ( -
); }; diff --git a/react-app/src/components/Cards/SectionCard.tsx b/react-app/src/components/Cards/SectionCard.tsx index bed04ceaff..80dc138a60 100644 --- a/react-app/src/components/Cards/SectionCard.tsx +++ b/react-app/src/components/Cards/SectionCard.tsx @@ -8,13 +8,7 @@ interface SectionCardProps { id?: string; testId?: string; } -export const SectionCard = ({ - title, - children, - className, - id, - testId, -}: SectionCardProps) => { +export const SectionCard = ({ title, children, className, id, testId }: SectionCardProps) => { return (
{title && ( <> -

{title}

+

+ {title} +


)} -
{children}
+
+ {children} +
); }; diff --git a/react-app/src/components/Chip/Chip.test.tsx b/react-app/src/components/Chip/Chip.test.tsx index 0e1a155325..b1a160ce8c 100644 --- a/react-app/src/components/Chip/Chip.test.tsx +++ b/react-app/src/components/Chip/Chip.test.tsx @@ -9,9 +9,7 @@ describe("Chip", () => { const { container } = render(); - const chipButton = container.getElementsByClassName( - "h-8 py-2 cursor-pointer", - )[0]; + const chipButton = container.getElementsByClassName("h-8 py-2 cursor-pointer")[0]; await userEvent.click(chipButton); diff --git a/react-app/src/components/Chip/index.tsx b/react-app/src/components/Chip/index.tsx index 139053b718..e1729b065f 100644 --- a/react-app/src/components/Chip/index.tsx +++ b/react-app/src/components/Chip/index.tsx @@ -18,7 +18,7 @@ const chipVariants = cva( defaultVariants: { variant: "default", }, - } + }, ); export interface ChipProps extends VariantProps { @@ -37,10 +37,7 @@ const Chip = ({ const noIcon = variant === "noIcon" || variant === "destructive"; return (
diff --git a/react-app/src/components/ConfirmationDialog/ConfirmationDialog.tsx b/react-app/src/components/ConfirmationDialog/ConfirmationDialog.tsx index e2b97d0c6c..d9ca68c30c 100644 --- a/react-app/src/components/ConfirmationDialog/ConfirmationDialog.tsx +++ b/react-app/src/components/ConfirmationDialog/ConfirmationDialog.tsx @@ -56,11 +56,7 @@ export function ConfirmationDialog({ data-testid="dialog-footer" > {acceptButtonVisible && ( - )} diff --git a/react-app/src/components/ConfirmationDialog/userPrompt.tsx b/react-app/src/components/ConfirmationDialog/userPrompt.tsx index 09f1f1d888..45112c3560 100644 --- a/react-app/src/components/ConfirmationDialog/userPrompt.tsx +++ b/react-app/src/components/ConfirmationDialog/userPrompt.tsx @@ -31,9 +31,7 @@ export const userPrompt = (newUserPrompt: UserPrompt) => { }; export const UserPrompt = () => { - const [activeUserPrompt, setActiveUserPrompt] = useState( - null, - ); + const [activeUserPrompt, setActiveUserPrompt] = useState(null); const [isOpen, setIsOpen] = useState(false); useEffect(() => { diff --git a/react-app/src/components/Container/Accordion/index.tsx b/react-app/src/components/Container/Accordion/index.tsx index 9c8074dc64..c7d9a4b440 100644 --- a/react-app/src/components/Container/Accordion/index.tsx +++ b/react-app/src/components/Container/Accordion/index.tsx @@ -11,11 +11,7 @@ const AccordionItem = React.forwardRef< React.ElementRef, AccordionItemProps >(({ className, ...props }, ref) => ( - + )); AccordionItem.displayName = "AccordionItem"; @@ -32,7 +28,7 @@ const AccordionTrigger = React.forwardRef< ref={ref} className={cn( "flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180", - className + className, )} {...props} > diff --git a/react-app/src/components/DetailsSection/DetailsSection.test.tsx b/react-app/src/components/DetailsSection/DetailsSection.test.tsx index a23c06f080..612633385a 100644 --- a/react-app/src/components/DetailsSection/DetailsSection.test.tsx +++ b/react-app/src/components/DetailsSection/DetailsSection.test.tsx @@ -6,11 +6,7 @@ import { DetailsSection } from "./index"; describe("DetailsSection", () => { it("renders with description", () => { render( - +

test child

, ); diff --git a/react-app/src/components/Dialog/index.tsx b/react-app/src/components/Dialog/index.tsx index 9951a5a19c..9a38456eed 100644 --- a/react-app/src/components/Dialog/index.tsx +++ b/react-app/src/components/Dialog/index.tsx @@ -61,13 +61,7 @@ const DialogHeader = ({ }: React.HTMLAttributes & { className?: string; }) => ( -
+
); DialogHeader.displayName = "DialogHeader"; @@ -78,10 +72,7 @@ const DialogFooter = ({ className?: string; }) => (
); @@ -95,10 +86,7 @@ const DialogTitle = React.forwardRef< >(({ className, ...props }, ref) => ( )); diff --git a/react-app/src/components/Form/content/ContentWrappers.tsx b/react-app/src/components/Form/content/ContentWrappers.tsx index b4f0743cb3..2ff96bb15f 100644 --- a/react-app/src/components/Form/content/ContentWrappers.tsx +++ b/react-app/src/components/Form/content/ContentWrappers.tsx @@ -57,7 +57,11 @@ export const ActionFormDescription = ({ }; export const ActionFormHeading = ({ title }: { title: string }) => { - return

{title}

; + return ( +

+ {title} +

+ ); }; export const PreSubmitNotice = ({ diff --git a/react-app/src/components/Inputs/button.test.tsx b/react-app/src/components/Inputs/button.test.tsx index 8dfb4d8db5..67f9caa522 100644 --- a/react-app/src/components/Inputs/button.test.tsx +++ b/react-app/src/components/Inputs/button.test.tsx @@ -1,36 +1,39 @@ -import { render, screen } from '@testing-library/react'; -import { describe, it, expect } from 'vitest'; -import { Button } from './button'; +import { render, screen } from "@testing-library/react"; +import { describe, it, expect } from "vitest"; +import { Button } from "./button"; -describe('Button Component', () => { - it('renders children correctly', () => { +describe("Button Component", () => { + it("renders children correctly", () => { render(); - expect(screen.getByText('Click Me')).toBeInTheDocument(); + expect(screen.getByText("Click Me")).toBeInTheDocument(); }); - it('applies default variant and size classes', () => { + it("applies default variant and size classes", () => { render(); - const button = screen.getByText('Click Me'); - expect(button).toHaveClass('bg-primary text-slate-50'); + const button = screen.getByText("Click Me"); + expect(button).toHaveClass("bg-primary text-slate-50"); }); - it('applies the correct variant and size classes when props are set', () => { - render(); - const button = screen.getByText('Delete'); - expect(button).toHaveClass('bg-destructive'); - expect(button).toHaveClass('h-11 px-8'); + it("applies the correct variant and size classes when props are set", () => { + render( + , + ); + const button = screen.getByText("Delete"); + expect(button).toHaveClass("bg-destructive"); + expect(button).toHaveClass("h-11 px-8"); }); - it('shows a loading spinner when loading prop is true', () => { + it("shows a loading spinner when loading prop is true", () => { const { container } = render(); - const spinner = container.querySelector('.animate-spin'); + const spinner = container.querySelector(".animate-spin"); expect(spinner).toBeInTheDocument(); }); - it('disables the button when the disabled prop is true', () => { + it("disables the button when the disabled prop is true", () => { render(); - const button = screen.getByText('Disabled'); + const button = screen.getByText("Disabled"); expect(button).toBeDisabled(); }); }); - diff --git a/react-app/src/components/Inputs/button.tsx b/react-app/src/components/Inputs/button.tsx index c86960409b..d05bfc4b1a 100644 --- a/react-app/src/components/Inputs/button.tsx +++ b/react-app/src/components/Inputs/button.tsx @@ -11,12 +11,9 @@ const buttonVariants = cva( variants: { variant: { default: "bg-primary text-slate-50 hover:bg-primary-dark", - destructive: - "bg-destructive text-destructive-foreground hover:bg-destructive/90", - outline: - "border border-primary text-primary font-bold hover:bg-primary/10", - secondary: - "bg-secondary text-secondary-foreground hover:bg-secondary/80", + destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90", + outline: "border border-primary text-primary font-bold hover:bg-primary/10", + secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80", ghost: "hover:bg-accent hover:text-accent-foreground", link: "text-primary underline-offset-4 hover:underline", }, @@ -42,17 +39,10 @@ export interface ButtonProps } const Button = React.forwardRef( - ( - { className, variant, size, loading, children, asChild = false, ...props }, - ref, - ) => { + ({ className, variant, size, loading, children, asChild = false, ...props }, ref) => { const Comp = asChild ? Slot : "button"; return ( - + <> {loading && } {children} diff --git a/react-app/src/components/Inputs/calendar.tsx b/react-app/src/components/Inputs/calendar.tsx index a0b3de5a48..c71e36b971 100644 --- a/react-app/src/components/Inputs/calendar.tsx +++ b/react-app/src/components/Inputs/calendar.tsx @@ -3,12 +3,7 @@ import { DayPicker } from "react-day-picker"; import { cn } from "@/utils"; import { buttonVariants } from "./button"; -function Calendar({ - className, - classNames, - showOutsideDays = true, - ...props -}: CalendarProps) { +function Calendar({ className, classNames, showOutsideDays = true, ...props }: CalendarProps) { return ( {caption} - props.onPageChange(Number(v.currentTarget.value) - 1) - } + onChange={(v) => props.onPageChange(Number(v.currentTarget.value) - 1)} className="absolute w-auto h-auto opacity-0 cursor-pointer" aria-labelledby="morePagesButton" data-testid="morePagesButton" diff --git a/react-app/src/components/Popover/index.tsx b/react-app/src/components/Popover/index.tsx index 31497ebe24..6354fbd54c 100644 --- a/react-app/src/components/Popover/index.tsx +++ b/react-app/src/components/Popover/index.tsx @@ -24,7 +24,7 @@ const PopoverContent = React.forwardRef< sideOffset={sideOffset} className={cn( "z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2", - className + className, )} {...props} /> diff --git a/react-app/src/components/RHF/Field.tsx b/react-app/src/components/RHF/Field.tsx index a89cc1f828..4cc16153f4 100644 --- a/react-app/src/components/RHF/Field.tsx +++ b/react-app/src/components/RHF/Field.tsx @@ -32,22 +32,13 @@ export const Field = ({
{(SLOT.label || SLOT.styledLabel) && ( - + )} -
+
{SLOT.fields?.map((F) => { return ( - + ); })}
@@ -61,9 +52,7 @@ export const Field = ({ key={adjustedSlotName} // @ts-expect-error control={control} - rules={ - ruleGenerator(SLOT.rules, SLOT.addtnlRules) as CustomRegisterOptions - } + rules={ruleGenerator(SLOT.rules, SLOT.addtnlRules) as CustomRegisterOptions} name={adjustedSlotName as never} render={RHFSlot({ ...SLOT, diff --git a/react-app/src/components/RHF/FieldArray.tsx b/react-app/src/components/RHF/FieldArray.tsx index 07bc75aa8d..67fb5e77c5 100644 --- a/react-app/src/components/RHF/FieldArray.tsx +++ b/react-app/src/components/RHF/FieldArray.tsx @@ -7,9 +7,7 @@ import { slotInitializer } from "./utils"; import { Field } from "./Field"; import { cn } from "@/utils"; -export const RHFFieldArray = ( - props: FieldArrayProps, -) => { +export const RHFFieldArray = (props: FieldArrayProps) => { const fieldArr = useFieldArray({ control: props.control, name: props.name, @@ -31,19 +29,9 @@ export const RHFFieldArray = (
{fieldArr.fields.map((FLD, index) => { return ( -
+
{props.fields.map((SLOT, i) => { - return ( - - ); + return ; })} {/* FieldArray Removal */} {index >= 1 && !props.removeText && ( @@ -66,19 +54,12 @@ export const RHFFieldArray = ( {props.removeText ?? "Remove Group"} )} - {props.divider && ( -
- )} + {props.divider &&
}
); })} {props.lastDivider && ( -
+
)}
+
)); Table.displayName = "Table"; @@ -34,11 +30,7 @@ const TableBody = React.forwardRef< className?: string; } >(({ className, ...props }, ref) => ( - + )); TableBody.displayName = "TableBody"; @@ -98,16 +90,8 @@ const TableHead = React.forwardRef< icon ) : ( <> - {desc && ( - - )} - {!desc && ( - - )} + {desc && } + {!desc && } )} @@ -138,21 +122,8 @@ const TableCaption = React.forwardRef< className?: string; } >(({ className, ...props }, ref) => ( -
+ )); TableCaption.displayName = "TableCaption"; -export { - Table, - TableHeader, - TableBody, - TableFooter, - TableHead, - TableRow, - TableCell, - TableCaption, -}; +export { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption }; diff --git a/react-app/src/components/Tooltip/index.tsx b/react-app/src/components/Tooltip/index.tsx index b9c51859b9..01475bd6ab 100644 --- a/react-app/src/components/Tooltip/index.tsx +++ b/react-app/src/components/Tooltip/index.tsx @@ -1,12 +1,12 @@ import * as React from "react"; import * as TooltipPrimitive from "@radix-ui/react-tooltip"; import { cn } from "@/utils"; -const TooltipProvider = TooltipPrimitive.Provider - -const Tooltip = TooltipPrimitive.Root - -const TooltipTrigger = TooltipPrimitive.Trigger - +const TooltipProvider = TooltipPrimitive.Provider; + +const Tooltip = TooltipPrimitive.Root; + +const TooltipTrigger = TooltipPrimitive.Trigger; + const TooltipContent = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef @@ -16,11 +16,11 @@ const TooltipContent = React.forwardRef< sideOffset={sideOffset} className={cn( "z-50 overflow-hidden rounded-md bg-primary px-3 py-1.5 text-xs text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2", - className + className, )} {...props} /> -)) -TooltipContent.displayName = TooltipPrimitive.Content.displayName - -export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } \ No newline at end of file +)); +TooltipContent.displayName = TooltipPrimitive.Content.displayName; + +export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }; diff --git a/react-app/src/features/dashboard/Lists/spas/consts.tsx b/react-app/src/features/dashboard/Lists/spas/consts.tsx index 5e6f2fa7b1..7061542575 100644 --- a/react-app/src/features/dashboard/Lists/spas/consts.tsx +++ b/react-app/src/features/dashboard/Lists/spas/consts.tsx @@ -1,14 +1,10 @@ -import { removeUnderscoresAndCapitalize } from "@/utils"; -import { OsTableColumn } from "@/components"; -import { CMS_READ_ONLY_ROLES, UserRoles } from "shared-types"; import { useGetUser } from "@/api"; -import { - CellDetailsLink, - renderCellActions, - renderCellDate, -} from "../renderCells"; +import { OsTableColumn } from "@/components"; import { BLANK_VALUE } from "@/consts"; +import { removeUnderscoresAndCapitalize } from "@/utils"; +import { CMS_READ_ONLY_ROLES, SEATOOL_STATUS, UserRoles } from "shared-types"; import { formatSeatoolDate } from "shared-utils"; +import { CellDetailsLink, renderCellActions, renderCellDate } from "../renderCells"; export const useSpaTableColumns = (): OsTableColumn[] => { const { data: props } = useGetUser(); @@ -17,9 +13,7 @@ export const useSpaTableColumns = (): OsTableColumn[] => { return [ // hide actions column for: readonly,help desk - ...(!CMS_READ_ONLY_ROLES.some((UR) => - props.user?.["custom:cms-roles"].includes(UR), - ) + ...(!CMS_READ_ONLY_ROLES.some((UR) => props.user?.["custom:cms-roles"].includes(UR)) ? [ { locked: true, @@ -35,9 +29,7 @@ export const useSpaTableColumns = (): OsTableColumn[] => { label: "SPA ID", locked: true, transform: (data) => data.id, - cell: ({ id, authority }) => ( - - ), + cell: ({ id, authority }) => , }, { field: "state.keyword", @@ -50,9 +42,7 @@ export const useSpaTableColumns = (): OsTableColumn[] => { label: "Authority", transform: (data) => data.authority ?? BLANK_VALUE, cell: (data) => - data?.authority - ? removeUnderscoresAndCapitalize(data.authority) - : BLANK_VALUE, + data?.authority ? removeUnderscoresAndCapitalize(data.authority) : BLANK_VALUE, }, { field: props?.isCms ? "cmsStatus.keyword" : "stateStatus.keyword", @@ -66,17 +56,14 @@ export const useSpaTableColumns = (): OsTableColumn[] => { return data.cmsStatus; })(); - const subStatusRAI = data.raiWithdrawEnabled - ? " (Withdraw Formal RAI Response - Enabled)" - : ""; - - const subStatusInitialIntake = (() => { - if (!props?.isCms) return ""; - if (!data.initialIntakeNeeded) return ""; - return " (Initial Intake Needed)"; - })(); + const subStatusRAI = + data.raiWithdrawEnabled && + data.seatoolStatus !== SEATOOL_STATUS.PENDING_APPROVAL && + data.seatoolStatus !== SEATOOL_STATUS.PENDING_CONCURRENCE + ? " (Withdraw Formal RAI Response - Enabled)" + : ""; - return `${status}${subStatusRAI}${subStatusInitialIntake}`; + return `${status}${subStatusRAI}`; }, cell: (data) => { const status = (() => { @@ -89,14 +76,11 @@ export const useSpaTableColumns = (): OsTableColumn[] => { return ( <>

{status}

- {data.raiWithdrawEnabled && ( -

- · Withdraw Formal RAI Response - Enabled -

- )} - {props?.isCms && data.initialIntakeNeeded && ( -

· Initial Intake Needed

- )} + {data.raiWithdrawEnabled && + data.seatoolStatus !== SEATOOL_STATUS.PENDING_APPROVAL && + data.seatoolStatus !== SEATOOL_STATUS.PENDING_CONCURRENCE && ( +

· Withdraw Formal RAI Response - Enabled

+ )} ); }, @@ -105,9 +89,7 @@ export const useSpaTableColumns = (): OsTableColumn[] => { field: "submissionDate", label: "Initial Submission", transform: (data) => - data?.submissionDate - ? formatSeatoolDate(data.submissionDate) - : BLANK_VALUE, + data?.submissionDate ? formatSeatoolDate(data.submissionDate) : BLANK_VALUE, cell: renderCellDate("submissionDate"), }, { @@ -115,9 +97,7 @@ export const useSpaTableColumns = (): OsTableColumn[] => { label: "Final Disposition", hidden: true, transform: (data) => - data?.finalDispositionDate - ? formatSeatoolDate(data.finalDispositionDate) - : BLANK_VALUE, + data?.finalDispositionDate ? formatSeatoolDate(data.finalDispositionDate) : BLANK_VALUE, cell: renderCellDate("finalDispositionDate"), }, { @@ -131,9 +111,7 @@ export const useSpaTableColumns = (): OsTableColumn[] => { field: "makoChangedDate", label: "Latest Package Activity", transform: (data) => - data.makoChangedDate - ? formatSeatoolDate(data.makoChangedDate) - : BLANK_VALUE, + data.makoChangedDate ? formatSeatoolDate(data.makoChangedDate) : BLANK_VALUE, cell: renderCellDate("makoChangedDate"), }, { @@ -141,9 +119,7 @@ export const useSpaTableColumns = (): OsTableColumn[] => { label: "Formal RAI Requested", hidden: true, transform: (data) => { - return data.raiRequestedDate - ? formatSeatoolDate(data.raiRequestedDate) - : BLANK_VALUE; + return data.raiRequestedDate ? formatSeatoolDate(data.raiRequestedDate) : BLANK_VALUE; }, cell: renderCellDate("raiRequestedDate"), }, @@ -151,9 +127,7 @@ export const useSpaTableColumns = (): OsTableColumn[] => { field: "raiReceivedDate", label: "Formal RAI Response", transform: (data) => { - return data.raiReceivedDate - ? formatSeatoolDate(data.raiReceivedDate) - : BLANK_VALUE; + return data.raiReceivedDate ? formatSeatoolDate(data.raiReceivedDate) : BLANK_VALUE; }, cell: renderCellDate("raiReceivedDate"), }, diff --git a/react-app/src/features/dashboard/Lists/waivers/consts.tsx b/react-app/src/features/dashboard/Lists/waivers/consts.tsx index bca7d3042c..7b7aa604dd 100644 --- a/react-app/src/features/dashboard/Lists/waivers/consts.tsx +++ b/react-app/src/features/dashboard/Lists/waivers/consts.tsx @@ -1,14 +1,10 @@ -import { removeUnderscoresAndCapitalize, LABELS } from "@/utils"; +import { useGetUser } from "@/api"; import { OsTableColumn } from "@/components"; import { BLANK_VALUE } from "@/consts"; -import { CMS_READ_ONLY_ROLES, UserRoles } from "shared-types"; -import { useGetUser } from "@/api"; -import { - CellDetailsLink, - renderCellActions, - renderCellDate, -} from "../renderCells"; +import { LABELS, removeUnderscoresAndCapitalize } from "@/utils"; +import { CMS_READ_ONLY_ROLES, SEATOOL_STATUS, UserRoles } from "shared-types"; import { formatSeatoolDate } from "shared-utils"; +import { CellDetailsLink, renderCellActions, renderCellDate } from "../renderCells"; export const useWaiverTableColumns = (): OsTableColumn[] => { const { data: props } = useGetUser(); @@ -17,9 +13,7 @@ export const useWaiverTableColumns = (): OsTableColumn[] => { return [ // hide actions column for: readonly,help desk - ...(!CMS_READ_ONLY_ROLES.some((UR) => - props.user?.["custom:cms-roles"].includes(UR), - ) + ...(!CMS_READ_ONLY_ROLES.some((UR) => props.user?.["custom:cms-roles"].includes(UR)) ? [ { locked: true, @@ -35,9 +29,7 @@ export const useWaiverTableColumns = (): OsTableColumn[] => { label: "Waiver Number", locked: true, transform: (data) => data.id, - cell: ({ id, authority }) => ( - - ), + cell: ({ id, authority }) => , }, { field: "state.keyword", @@ -50,18 +42,14 @@ export const useWaiverTableColumns = (): OsTableColumn[] => { label: "Authority", transform: (data) => data.authority ?? BLANK_VALUE, cell: (data) => - data?.authority - ? removeUnderscoresAndCapitalize(data.authority) - : BLANK_VALUE, + data?.authority ? removeUnderscoresAndCapitalize(data.authority) : BLANK_VALUE, }, { field: "actionType.keyword", label: "Action Type", transform: (data) => { if (data.actionType === undefined) return BLANK_VALUE; - return ( - LABELS[data.actionType as keyof typeof LABELS] || data.actionType - ); + return LABELS[data.actionType as keyof typeof LABELS] || data.actionType; }, cell: (data) => data.actionType @@ -84,13 +72,7 @@ export const useWaiverTableColumns = (): OsTableColumn[] => { ? " (Withdraw Formal RAI Response - Enabled)" : ""; - const subStatusInitialIntake = (() => { - if (!props?.isCms) return ""; - if (!data.initialIntakeNeeded) return ""; - return " (Initial Intake Needed)"; - })(); - - return `${status}${subStatusRAI}${subStatusInitialIntake}`; + return `${status}${subStatusRAI}`; }, cell: (data) => { const status = (() => { @@ -103,14 +85,11 @@ export const useWaiverTableColumns = (): OsTableColumn[] => { return ( <>

{status}

- {data.raiWithdrawEnabled && ( -

- · Withdraw Formal RAI Response - Enabled -

- )} - {props?.isCms && data.initialIntakeNeeded && ( -

· Initial Intake Needed

- )} + {data.raiWithdrawEnabled && + data.seatoolStatus !== SEATOOL_STATUS.PENDING_APPROVAL && + data.seatoolStatus !== SEATOOL_STATUS.PENDING_CONCURRENCE && ( +

· Withdraw Formal RAI Response - Enabled

+ )} ); }, @@ -119,9 +98,7 @@ export const useWaiverTableColumns = (): OsTableColumn[] => { field: "submissionDate", label: "Initial Submission", transform: (data) => - data?.submissionDate - ? formatSeatoolDate(data.submissionDate) - : BLANK_VALUE, + data?.submissionDate ? formatSeatoolDate(data.submissionDate) : BLANK_VALUE, cell: renderCellDate("submissionDate"), }, { @@ -129,9 +106,7 @@ export const useWaiverTableColumns = (): OsTableColumn[] => { label: "Final Disposition", hidden: true, transform: (data) => - data?.finalDispositionDate - ? formatSeatoolDate(data.finalDispositionDate) - : BLANK_VALUE, + data?.finalDispositionDate ? formatSeatoolDate(data.finalDispositionDate) : BLANK_VALUE, cell: renderCellDate("finalDispositionDate"), }, { @@ -147,9 +122,7 @@ export const useWaiverTableColumns = (): OsTableColumn[] => { field: "makoChangedDate", label: "Latest Package Activity", transform: (data) => - data.makoChangedDate - ? formatSeatoolDate(data.makoChangedDate) - : BLANK_VALUE, + data.makoChangedDate ? formatSeatoolDate(data.makoChangedDate) : BLANK_VALUE, cell: renderCellDate("makoChangedDate"), }, { @@ -157,9 +130,7 @@ export const useWaiverTableColumns = (): OsTableColumn[] => { label: "Formal RAI Requested", hidden: true, transform: (data) => { - return data.raiRequestedDate - ? formatSeatoolDate(data.raiRequestedDate) - : BLANK_VALUE; + return data.raiRequestedDate ? formatSeatoolDate(data.raiRequestedDate) : BLANK_VALUE; }, cell: renderCellDate("raiRequestedDate"), }, @@ -167,9 +138,7 @@ export const useWaiverTableColumns = (): OsTableColumn[] => { field: "raiReceivedDate", label: "Formal RAI Response", transform: (data) => { - return data.raiReceivedDate - ? formatSeatoolDate(data.raiReceivedDate) - : BLANK_VALUE; + return data.raiReceivedDate ? formatSeatoolDate(data.raiReceivedDate) : BLANK_VALUE; }, cell: renderCellDate("raiReceivedDate"), }, diff --git a/react-app/src/features/forms/index.ts b/react-app/src/features/forms/index.ts index b3ae65ecb8..06b660f945 100644 --- a/react-app/src/features/forms/index.ts +++ b/react-app/src/features/forms/index.ts @@ -3,4 +3,4 @@ export * as CapitatedWaivers from "./waiver/capitated"; export * as ContractingWaivers from "./waiver/contracting"; export * from "./waiver/app-k"; export * from "./waiver/temporary-extension"; -export * from "./post-submission/withdraw-rai"; \ No newline at end of file +export * from "./post-submission/withdraw-rai"; diff --git a/react-app/src/features/forms/post-submission/respond-to-rai/index.tsx b/react-app/src/features/forms/post-submission/respond-to-rai/index.tsx index a1f6bd9798..60170d9ec0 100644 --- a/react-app/src/features/forms/post-submission/respond-to-rai/index.tsx +++ b/react-app/src/features/forms/post-submission/respond-to-rai/index.tsx @@ -13,6 +13,11 @@ export const RespondToRaiMedicaid = () => { attachments={{ faqLink: "/faq/medicaid-spa-rai-attachments", }} + promptPreSubmission={{ + acceptButtonText: "Yes, Submit", + header: "Do you want to submit your official formal RAI response?", + body: "By clicking Yes, Submit, you are submitting your official formal RAI Response to start the 90 day clock review process.", + }} documentPollerArgs={{ property: "id", documentChecker: (check) => check.recordExists, @@ -43,6 +48,11 @@ export const RespondToRaiWaiver = () => { attachments={{ faqLink: "/faq/waiverb-rai-attachments", }} + promptPreSubmission={{ + acceptButtonText: "Yes, Submit", + header: "Do you want to submit your official formal RAI response?", + body: "By clicking Yes, Submit, you are submitting your official formal RAI Response to start the 90 day clock review process.", + }} documentPollerArgs={{ property: "id", documentChecker: (check) => check.recordExists, @@ -71,6 +81,11 @@ export const RespondToRaiChip = () => { attachments={{ faqLink: "/faq/chip-spa-rai-attachments", }} + promptPreSubmission={{ + acceptButtonText: "Yes, Submit", + header: "Do you want to submit your official formal RAI response?", + body: "By clicking Yes, Submit, you are submitting your official formal RAI Response to restart the SPA review process and a new 90th day will be identified.", + }} documentPollerArgs={{ property: "id", documentChecker: (check) => check.recordExists, diff --git a/react-app/src/features/forms/post-submission/withdraw-package/index.tsx b/react-app/src/features/forms/post-submission/withdraw-package/index.tsx index e0585abcc7..6fef0a3528 100644 --- a/react-app/src/features/forms/post-submission/withdraw-package/index.tsx +++ b/react-app/src/features/forms/post-submission/withdraw-package/index.tsx @@ -2,7 +2,6 @@ import { useGetItem } from "@/api"; import { ActionForm, LoadingSpinner, PackageSection } from "@/components"; import { formSchemas } from "@/formSchemas"; import { useParams } from "react-router"; -import { SEATOOL_STATUS } from "shared-types"; export const WithdrawPackageActionWaiver = () => { const { authority, id } = useParams(); @@ -44,12 +43,14 @@ export const WithdrawPackageActionWaiver = () => { documentChecker: (check) => check.recordExists, }} bannerPostSubmission={{ - header: "Package withdrawn", - body: `The package ${id} has been withdrawn.`, + header: "Withdraw package request has been submitted", + body: "If CMS needs any additional information, they will follow up by email.", variant: "success", }} breadcrumbText="Withdraw Package" - formDescription={`Complete this form to withdraw ${authority === "1915(c)" ? "this 1915(c) Appendix K" : "a"} package. Once complete, you will not be able to resubmit this package. CMS will be notified and will use this content to review your request. If CMS needs any additional information, they will follow up by email.`} + formDescription={`Complete this form to withdraw ${ + authority === "1915(c)" ? "this 1915(c) Appendix K" : "a" + } package. Once complete, you will not be able to resubmit this package. CMS will be notified and will use this content to review your request. If CMS needs any additional information, they will follow up by email.`} preSubmissionMessage="Once complete, you will not be able to resubmit this package. CMS will be notified and will use this content to review your request. If CMS needs any additional information, they will follow up by email." additionalInformation={{ required: false, @@ -96,8 +97,8 @@ export const WithdrawPackageAction = () => { documentChecker: (check) => check.recordExists, }} bannerPostSubmission={{ - header: "Package withdrawn", - body: `The package ${id} has been withdrawn.`, + header: "Withdraw package request has been submitted", + body: "If CMS needs any additional information, they will follow up by email.", variant: "success", }} breadcrumbText="Withdraw Package" @@ -135,13 +136,13 @@ export const WithdrawPackageActionChip = () => { "Official withdrawal letters are required and must be on state letterhead signed by the State Medicaid Director or CHIP Director.", }} bannerPostSubmission={{ - header: "Package withdrawn", - body: `The package ${id} has been withdrawn.`, + header: "Withdraw package request has been submitted", + body: "If CMS needs any additional information, they will follow up by email.", variant: "success", }} documentPollerArgs={{ property: "id", - documentChecker: (check) => check.hasStatus(SEATOOL_STATUS.WITHDRAWN), + documentChecker: (check) => check.recordExists, }} breadcrumbText="Withdraw Package" additionalInformation={{ diff --git a/react-app/src/features/forms/post-submission/withdraw-rai/index.tsx b/react-app/src/features/forms/post-submission/withdraw-rai/index.tsx index eea6bf0bab..8d66a83d9f 100644 --- a/react-app/src/features/forms/post-submission/withdraw-rai/index.tsx +++ b/react-app/src/features/forms/post-submission/withdraw-rai/index.tsx @@ -34,8 +34,8 @@ export const WithdrawRaiForm = () => { you and CMS will receive an email confirmation." preSubmissionMessage="Once complete, you and CMS will receive an email confirmation." bannerPostSubmission={{ - header: "RAI response withdrawn", - body: `The RAI response for ${id} has been withdrawn. CMS may follow up if additional information is needed.`, + header: "Withdraw Formal RAI Response request has been submitted.", + body: "Your Formal RAI Response has been withdrawn successfully. If CMS needs any additional information, they will follow up by email.", variant: "success", }} additionalInformation={{ @@ -44,8 +44,8 @@ export const WithdrawRaiForm = () => { label: "Explain your need for withdrawal.", }} promptPreSubmission={{ - header: "Withdraw RAI response?", - body: `The RAI response for ${id} will be withdrawn, and CMS will be notified.`, + header: "Withdraw Formal RAI response?", + body: `You are about to withdraw the Formal RAI Response for ${id}. CMS will be notified.`, acceptButtonText: "Yes, withdraw response", cancelButtonText: "Cancel", }} diff --git a/react-app/src/features/guides/index.tsx b/react-app/src/features/guides/index.tsx index 38bddaf858..2236a01336 100644 --- a/react-app/src/features/guides/index.tsx +++ b/react-app/src/features/guides/index.tsx @@ -122,8 +122,7 @@ const abp_forms: Guide[] = [ }, { title: "Alternative Benefit Plan State Training Webinar", - linkTitle: - "Alternative Benefit Plan State Training Webinar (2013-08-13 .wmv)", + linkTitle: "Alternative Benefit Plan State Training Webinar (2013-08-13 .wmv)", href: "https://www.medicaid.gov/media/162926", targetBlank: true, }, diff --git a/react-app/src/features/package/admin-changes/index.tsx b/react-app/src/features/package/admin-changes/index.tsx index 403827f0ca..798ae11832 100644 --- a/react-app/src/features/package/admin-changes/index.tsx +++ b/react-app/src/features/package/admin-changes/index.tsx @@ -55,9 +55,9 @@ export const AdminChange: FC = (props) => { switch (props.event) { case "toggle-withdraw-rai": { if (props.raiWithdrawEnabled) { - return ["Enable formal RAI response withdraw", AC_WithdrawEnabled]; + return ["Enable Formal RAI Response Withdraw", AC_WithdrawEnabled]; } - return ["Disable formal RAI response withdraw", AC_WithdrawDisabled]; + return ["Disable Formal RAI Response Withdraw", AC_WithdrawDisabled]; } case "legacy-admin-change": return [props.changeType || "Manual Update", AC_LegacyAdminChange]; diff --git a/react-app/src/features/package/hooks.tsx b/react-app/src/features/package/hooks.tsx index 9039853522..764f6821fe 100644 --- a/react-app/src/features/package/hooks.tsx +++ b/react-app/src/features/package/hooks.tsx @@ -7,9 +7,7 @@ export type DetailsSidebarLink = { displayName: string; }; -export const useDetailsSidebarLinks = ( - dataId: string, -): DetailsSidebarLink[] => { +export const useDetailsSidebarLinks = (dataId: string): DetailsSidebarLink[] => { const { data } = useGetItem(dataId); const [sideBarLinks, setSideBarLinks] = useState([]); diff --git a/react-app/src/features/package/index.tsx b/react-app/src/features/package/index.tsx index b90747133f..a4e30538f5 100644 --- a/react-app/src/features/package/index.tsx +++ b/react-app/src/features/package/index.tsx @@ -56,7 +56,9 @@ type LoaderData = { authority: Authority; }; -export const packageDetailsLoader = async ({ params }: LoaderFunctionArgs): Promise => { +export const packageDetailsLoader = async ({ + params, +}: LoaderFunctionArgs): Promise => { const { id, authority } = params; if (id === undefined || authority === undefined) { return redirect("/dashboard"); diff --git a/react-app/src/features/package/package-activity/index.test.tsx b/react-app/src/features/package/package-activity/index.test.tsx index d30fe430f2..9474bf2bd9 100644 --- a/react-app/src/features/package/package-activity/index.test.tsx +++ b/react-app/src/features/package/package-activity/index.test.tsx @@ -37,7 +37,7 @@ describe("Package Activity", () => { await renderFormWithPackageSectionAsync(, WITHDRAWN_CHANGELOG_ITEM_ID); expect(screen.getByText("Package Activity (7)")); - expect(screen.getByText("Initial package submitted")); + expect(screen.getByText("Initial Package Submitted")); expect(screen.getByText("Download all documents")); expect(screen.getByText("Contract Amendment")); }); diff --git a/react-app/src/features/package/package-activity/index.tsx b/react-app/src/features/package/package-activity/index.tsx index 29479345cf..9621b7e608 100644 --- a/react-app/src/features/package/package-activity/index.tsx +++ b/react-app/src/features/package/package-activity/index.tsx @@ -106,18 +106,18 @@ const PackageActivity = ({ packageActivity }: PackageActivityProps) => { case "new-medicaid-submission": case "temporary-extension": case "app-k": - return "Initial package submitted"; + return "Initial Package Submitted"; case "withdraw-package": - return "Package withdrawn"; + return "Package - Withdrawal Requested"; case "withdraw-rai": - return "RAI response withdrawn"; + return "Formal RAI Response - Withdrawal Requested"; case "respond-to-rai": - return "RAI response submitted"; + return "RAI Response Submitted"; case "upload-subsequent-documents": - return "Subsequent documentation uploaded"; + return "Subsequent Documentation Uploaded"; default: return BLANK_VALUE; diff --git a/react-app/src/features/package/package-status/index.tsx b/react-app/src/features/package/package-status/index.tsx index 00c19fba7e..10033f8b60 100644 --- a/react-app/src/features/package/package-status/index.tsx +++ b/react-app/src/features/package/package-status/index.tsx @@ -1,5 +1,5 @@ import { useGetItem, useGetUser } from "@/api"; -import { UserRoles } from "shared-types"; +import { SEATOOL_STATUS, UserRoles } from "shared-types"; import { DetailCardWrapper } from ".."; import { FC } from "react"; @@ -9,38 +9,46 @@ export const PackageStatusCard: FC<{ id: string }> = ({ id }) => { if (!data) return null; + // This really a check to determine if we should show the status of an RAI Withdraw being enabled + // We have a flag that we monitor but there are certain things that can be done outside of onemac, + // specifically in seatool that will invalidate the raiWithdrawEnabled flag such as the two statuses + // below (Pending Approval, and Pending Concurrence). In the future we should build logic into the + // seatool sink that allows us to simply clear these flags + const isInRAIWithdrawEnabledSubStatus = + data._source.raiWithdrawEnabled && + data._source.seatoolStatus !== SEATOOL_STATUS.PENDING_APPROVAL && + data._source.seatoolStatus !== SEATOOL_STATUS.PENDING_CONCURRENCE; + + // Similar to the above check their are certain things that occur in seatool that invalidate the secondClock + // flag. Additionally second clock sub status only displays for CMS users + const isInActiveSecondClockStatus = + user?.isCms && + data._source.secondClock && + data._source.seatoolStatus !== SEATOOL_STATUS.PENDING_APPROVAL && + data._source.seatoolStatus !== SEATOOL_STATUS.PENDING_CONCURRENCE; + return (
- {user?.isCms && - !user.user?.["custom:cms-roles"].includes(UserRoles.HELPDESK) + {user?.isCms && !user.user?.["custom:cms-roles"].includes(UserRoles.HELPDESK) ? data?._source.cmsStatus : data?._source.stateStatus}
- {data._source.raiWithdrawEnabled && ( + {isInRAIWithdrawEnabledSubStatus && (

·

-

- Withdraw Formal RAI Response - Enabled -

+

Withdraw Formal RAI Response - Enabled

)} - {user?.isCms && data._source.secondClock && ( + {isInActiveSecondClockStatus && (

·

2nd Clock

)} - - {user?.isCms && data._source.initialIntakeNeeded && ( -
-

·

-

Initial Intake Needed

-
- )}
diff --git a/react-app/src/features/selection-flow/options.tsx b/react-app/src/features/selection-flow/options.tsx index 3d37b7ee9f..1096958c33 100644 --- a/react-app/src/features/selection-flow/options.tsx +++ b/react-app/src/features/selection-flow/options.tsx @@ -1,9 +1,5 @@ import { OptionData } from "@/features/selection-flow/plan-types"; -import { - ORIGIN, - SPA_SUBMISSION_ORIGIN, - WAIVER_SUBMISSION_ORIGIN, -} from "@/utils"; +import { ORIGIN, SPA_SUBMISSION_ORIGIN, WAIVER_SUBMISSION_ORIGIN } from "@/utils"; export const AUTHORITY_OPTIONS: OptionData[] = [ { @@ -13,8 +9,7 @@ export const AUTHORITY_OPTIONS: OptionData[] = [ }, { title: "Waiver Action", - description: - "Submit Waivers, Amendments, Renewals, and Temporary Extensions", + description: "Submit Waivers, Amendments, Renewals, and Temporary Extensions", to: "/new-submission/waiver", }, ]; @@ -94,21 +89,16 @@ export const WAIVER_OPTIONS: OptionData[] = [ export const B_WAIVER_OPTIONS: OptionData[] = [ { title: "1915(b)(4) FFS Selective Contracting Waivers", - description: - "Submit 1915(b)(4) FFS Selective Contracting Waivers, Amendments, and Renewals", + description: "Submit 1915(b)(4) FFS Selective Contracting Waivers, Amendments, and Renewals", to: "/new-submission/waiver/b/b4", }, { title: "1915(b) Comprehensive (Capitated) Waiver Authority", description: ( <> - Submit 1915(b) Comprehensive (Capitated) Waivers, Amendments and - Renewals
+ Submit 1915(b) Comprehensive (Capitated) Waivers, Amendments and Renewals
- - Not applicable for 1915(b)(4) FFS Selective Contracting Waiver - actions - + Not applicable for 1915(b)(4) FFS Selective Contracting Waiver actions ), @@ -119,8 +109,7 @@ export const B_WAIVER_OPTIONS: OptionData[] = [ export const B4_WAIVER_OPTIONS: OptionData[] = [ { title: "1915(b)(4) FFS Selective Contracting New Initial Waiver", - description: - "Create a new 1915(b)(4) FFS Selective Contracting Initial Waiver", + description: "Create a new 1915(b)(4) FFS Selective Contracting Initial Waiver", to: { pathname: "/new-submission/waiver/b/b4/initial/create", search: new URLSearchParams({ @@ -130,8 +119,7 @@ export const B4_WAIVER_OPTIONS: OptionData[] = [ }, { title: "1915(b)(4) FFS Selective Contracting Renewal Waiver", - description: - "Renew an existing 1915(b)(4) FFS Selective Contracting Waiver", + description: "Renew an existing 1915(b)(4) FFS Selective Contracting Waiver", to: { pathname: "/new-submission/waiver/b/b4/renewal/create", search: new URLSearchParams({ @@ -141,8 +129,7 @@ export const B4_WAIVER_OPTIONS: OptionData[] = [ }, { title: "1915(b)(4) FFS Selective Contracting Waiver Amendment", - description: - "Amend an existing 1915(b)(4) FFS Selective Contracting Waiver", + description: "Amend an existing 1915(b)(4) FFS Selective Contracting Waiver", to: { pathname: "/new-submission/waiver/b/b4/amendment/create", search: new URLSearchParams({ @@ -154,8 +141,7 @@ export const B4_WAIVER_OPTIONS: OptionData[] = [ export const BCAP_WAIVER_OPTIONS: OptionData[] = [ { title: "1915(b) Comprehensive (Capitated) New Initial Waiver", - description: - "Create a new 1915(b) Comprehensive (Capitated) Initial Waiver", + description: "Create a new 1915(b) Comprehensive (Capitated) Initial Waiver", to: { pathname: "/new-submission/waiver/b/capitated/initial/create", search: new URLSearchParams({ diff --git a/react-app/src/formSchemas/temporary-extension.ts b/react-app/src/formSchemas/temporary-extension.ts index 85fbc1787a..e129f90c8e 100644 --- a/react-app/src/formSchemas/temporary-extension.ts +++ b/react-app/src/formSchemas/temporary-extension.ts @@ -15,9 +15,7 @@ export const formSchema = events["temporary-extension"].baseSchema .object({ validAuthority: z .object({ - waiverNumber: events[ - "temporary-extension" - ].baseSchema.shape.waiverNumber + waiverNumber: events["temporary-extension"].baseSchema.shape.waiverNumber .refine(async (value) => await itemExists(value), { message: "According to our records, this Approved Initial or Renewal Waiver Number does not yet exist. Please check the Approved Initial or Renewal Waiver Number and try entering it again.", @@ -33,9 +31,7 @@ export const formSchema = events["temporary-extension"].baseSchema try { const originalWaiverData = await getItem(data.waiverNumber); - return !( - originalWaiverData._source.authority !== data.authority - ); + return !(originalWaiverData._source.authority !== data.authority); } catch { return z.never; } diff --git a/react-app/src/formSchemas/withdraw-package.ts b/react-app/src/formSchemas/withdraw-package.ts index dbf32c1501..bc13fe5644 100644 --- a/react-app/src/formSchemas/withdraw-package.ts +++ b/react-app/src/formSchemas/withdraw-package.ts @@ -8,8 +8,7 @@ export const formSchema = events["withdraw-package"].baseSchema .superRefine((data, ctx) => { if ( !data.attachments.supportingDocumentation?.files.length && - (data.additionalInformation === undefined || - data.additionalInformation === "") + (data.additionalInformation === undefined || data.additionalInformation === "") ) { ctx.addIssue({ message: "An Attachment or Additional Information is required.", diff --git a/react-app/src/hooks/UseDebounce.test.tsx b/react-app/src/hooks/UseDebounce.test.tsx index 9f53858fa8..74910eb276 100644 --- a/react-app/src/hooks/UseDebounce.test.tsx +++ b/react-app/src/hooks/UseDebounce.test.tsx @@ -16,10 +16,9 @@ describe("UseDebounce", () => { }); it("returns updated value after the specified delay", () => { - const { result, rerender } = renderHook( - ({ value, delay }) => useDebounce(value, delay), - { initialProps: { value: "start value", delay: 500 } }, - ); + const { result, rerender } = renderHook(({ value, delay }) => useDebounce(value, delay), { + initialProps: { value: "start value", delay: 500 }, + }); expect(result.current).toBe("start value"); rerender({ value: "new value", delay: 500 }); diff --git a/react-app/src/hooks/useCountdown/index.test.ts b/react-app/src/hooks/useCountdown/index.test.ts index eeed6eb828..d657889dd0 100644 --- a/react-app/src/hooks/useCountdown/index.test.ts +++ b/react-app/src/hooks/useCountdown/index.test.ts @@ -1,13 +1,5 @@ import { act, renderHook } from "@testing-library/react"; -import { - beforeEach, - describe, - test, - vi, - expect, - beforeAll, - afterAll, -} from "vitest"; +import { beforeEach, describe, test, vi, expect, beforeAll, afterAll } from "vitest"; import { useCountdown } from "."; import { cleanup } from "@testing-library/react"; diff --git a/react-app/src/hooks/useCountdown/index.ts b/react-app/src/hooks/useCountdown/index.ts index bdb02f6e7c..26fce65a67 100644 --- a/react-app/src/hooks/useCountdown/index.ts +++ b/react-app/src/hooks/useCountdown/index.ts @@ -8,9 +8,7 @@ type CountdownControllers = { resetCountdown: () => void; }; -export const useCountdown = ( - minutesToCountDown: number, -): [number, CountdownControllers] => { +export const useCountdown = (minutesToCountDown: number): [number, CountdownControllers] => { const [count, setCount] = useState(minutesToCountDown); const [isCountdownRunning, setIsCountdownRunning] = useState(false); diff --git a/react-app/src/hooks/useIdle/index.test.ts b/react-app/src/hooks/useIdle/index.test.ts index b175ccab62..57f275e8df 100644 --- a/react-app/src/hooks/useIdle/index.test.ts +++ b/react-app/src/hooks/useIdle/index.test.ts @@ -66,17 +66,13 @@ describe("useIdle", () => { }); test("Returns correct initial value from initialState argument", () => { - const { result } = renderHook(() => - useIdle(IDLE_TIME, { initialState: false }), - ); + const { result } = renderHook(() => useIdle(IDLE_TIME, { initialState: false })); expect(result.current).toBe(false); }); test("Returns correct value when timeout has elapsed", () => { - const { result } = renderHook(() => - useIdle(IDLE_TIME, { initialState: false }), - ); + const { result } = renderHook(() => useIdle(IDLE_TIME, { initialState: false })); act(() => { vi.advanceTimersByTime(IDLE_TIME); diff --git a/react-app/src/hooks/useIdle/index.ts b/react-app/src/hooks/useIdle/index.ts index 5831ea3003..903aa73aa0 100644 --- a/react-app/src/hooks/useIdle/index.ts +++ b/react-app/src/hooks/useIdle/index.ts @@ -48,9 +48,7 @@ export function useIdle( events.forEach((event) => document.addEventListener(event, handleEvents)); return () => { - events.forEach((event) => - document.removeEventListener(event, handleEvents), - ); + events.forEach((event) => document.removeEventListener(event, handleEvents)); }; }, [timeout]); diff --git a/react-app/src/index.css b/react-app/src/index.css index 1793e8ba32..2690fa3582 100644 --- a/react-app/src/index.css +++ b/react-app/src/index.css @@ -81,7 +81,9 @@ body { @apply bg-background text-foreground; font-family: "Open Sans", system-ui, sans-serif; - font-feature-settings: "rlig" 1, "calt" 1; + font-feature-settings: + "rlig" 1, + "calt" 1; } } diff --git a/react-app/src/utils/Poller/DataPoller.ts b/react-app/src/utils/Poller/DataPoller.ts index 3622cde367..e2d01638f9 100644 --- a/react-app/src/utils/Poller/DataPoller.ts +++ b/react-app/src/utils/Poller/DataPoller.ts @@ -39,8 +39,7 @@ export class DataPoller { } } } catch (error) { - const message = - error instanceof Error ? (error as Error).message : error; + const message = error instanceof Error ? (error as Error).message : error; errorMessage = `Error fetching data: ${message}`; } } else { diff --git a/react-app/src/utils/Poller/documentPoller.ts b/react-app/src/utils/Poller/documentPoller.ts index f86af71971..0d236eed19 100644 --- a/react-app/src/utils/Poller/documentPoller.ts +++ b/react-app/src/utils/Poller/documentPoller.ts @@ -6,10 +6,7 @@ export type CheckDocumentFunction = ( check: ReturnType & { recordExists: boolean }, ) => boolean; -export const documentPoller = ( - id: string, - documentChecker: CheckDocumentFunction, -) => +export const documentPoller = (id: string, documentChecker: CheckDocumentFunction) => new DataPoller({ interval: 1000, pollAttempts: 20, diff --git a/react-app/src/utils/createContextProvider.ts b/react-app/src/utils/createContextProvider.ts index 23f44e9577..00619ff078 100644 --- a/react-app/src/utils/createContextProvider.ts +++ b/react-app/src/utils/createContextProvider.ts @@ -24,7 +24,7 @@ type CreateContextReturn = [React.Provider, () => T, React.Context]; * @param options create context options */ export function createContextProvider( - options: CreateContextOptions + options: CreateContextOptions, ): CreateContextReturn { const { errorMessage = "useContext: `context` is undefined. Seems you forgot to wrap component within the Provider", @@ -48,9 +48,5 @@ export function createContextProvider( return context as T; } - return [ - Context.Provider, - useContext, - Context, - ] as CreateContextReturn; + return [Context.Provider, useContext, Context] as CreateContextReturn; } diff --git a/react-app/src/utils/crumbs.test.ts b/react-app/src/utils/crumbs.test.ts index 8c1de3ed7b..63649ddccc 100644 --- a/react-app/src/utils/crumbs.test.ts +++ b/react-app/src/utils/crumbs.test.ts @@ -1,15 +1,15 @@ -import { describe, it, expect} from 'vitest'; +import { describe, it, expect } from "vitest"; import { getDashboardTabForAuthority, detailsAndActionsCrumbs, dashboardCrumb, detailsCrumb, actionCrumb, -} from './crumbs'; -import { Action } from 'shared-types/actions'; +} from "./crumbs"; +import { Action } from "shared-types/actions"; -describe('getDashboardTabForAuthority', () => { - //test for authority +describe("getDashboardTabForAuthority", () => { + //test for authority it('should return "spas" for "CHIP SPA"', () => { const result = getDashboardTabForAuthority("CHIP SPA" as any); expect(result).toBe("spas"); @@ -30,25 +30,24 @@ describe('getDashboardTabForAuthority', () => { expect(result).toBe("waivers"); }); - it('should throw an error for an invalid authority', () => { - expect(() => getDashboardTabForAuthority("Invalid Authority" as any)).toThrow("Invalid authority"); + it("should throw an error for an invalid authority", () => { + expect(() => getDashboardTabForAuthority("Invalid Authority" as any)).toThrow( + "Invalid authority", + ); }); }); -describe('detailsAndActionsCrumbs', () => { +describe("detailsAndActionsCrumbs", () => { const id = "12345"; const authority = "CHIP SPA" as any; - it('should return default breadcrumbs without actionType', () => { - const expectedBreadcrumbs = [ - dashboardCrumb(authority), - detailsCrumb(id, authority), - ]; + it("should return default breadcrumbs without actionType", () => { + const expectedBreadcrumbs = [dashboardCrumb(authority), detailsCrumb(id, authority)]; const result = detailsAndActionsCrumbs({ id, authority }); expect(result).toEqual(expectedBreadcrumbs); }); - it('should return breadcrumbs including action crumb when actionType is provided', () => { + it("should return breadcrumbs including action crumb when actionType is provided", () => { const actionType = Action.RESPOND_TO_RAI; const expectedBreadcrumbs = [ dashboardCrumb(authority), @@ -60,8 +59,8 @@ describe('detailsAndActionsCrumbs', () => { }); }); -describe('dashboardCrumb', () => { - it('should return correct breadcrumb with authority', () => { +describe("dashboardCrumb", () => { + it("should return correct breadcrumb with authority", () => { const result = dashboardCrumb("CHIP SPA" as any); const expected = { displayText: "Dashboard", @@ -72,7 +71,7 @@ describe('dashboardCrumb', () => { expect(result).toEqual(expected); }); - it('should return correct breadcrumb without authority', () => { + it("should return correct breadcrumb without authority", () => { const result = dashboardCrumb(); const expected = { displayText: "Dashboard", @@ -84,8 +83,8 @@ describe('dashboardCrumb', () => { }); }); -describe('detailsCrumb', () => { - it('should return the correct details breadcrumb', () => { +describe("detailsCrumb", () => { + it("should return the correct details breadcrumb", () => { const id = "12345"; const authority = "CHIP SPA" as any; const result = detailsCrumb(id, authority); @@ -98,8 +97,8 @@ describe('detailsCrumb', () => { }); }); -describe('actionCrumb', () => { - it('should return the correct action breadcrumb', () => { +describe("actionCrumb", () => { + it("should return the correct action breadcrumb", () => { const actionType = Action.RESPOND_TO_RAI; const id = "12345"; const result = actionCrumb(actionType, id); diff --git a/react-app/src/utils/crumbs.ts b/react-app/src/utils/crumbs.ts index de778650a0..bdbb8aa328 100644 --- a/react-app/src/utils/crumbs.ts +++ b/react-app/src/utils/crumbs.ts @@ -9,9 +9,7 @@ type DetailsAndActionsBreadCrumbsArgs = { actionType?: Action; }; -export const getDashboardTabForAuthority = ( - authority: Authority, -): "spas" | "waivers" => { +export const getDashboardTabForAuthority = (authority: Authority): "spas" | "waivers" => { switch (authority) { case "CHIP SPA" as Authority: case "Medicaid SPA" as Authority: @@ -29,29 +27,19 @@ export const detailsAndActionsCrumbs = ({ authority, actionType, }: DetailsAndActionsBreadCrumbsArgs): BreadCrumbConfig[] => { - const defaultBreadCrumbs = [ - dashboardCrumb(authority), - detailsCrumb(id, authority), - ]; + const defaultBreadCrumbs = [dashboardCrumb(authority), detailsCrumb(id, authority)]; - return actionType - ? [...defaultBreadCrumbs, actionCrumb(actionType, id)] - : defaultBreadCrumbs; + return actionType ? [...defaultBreadCrumbs, actionCrumb(actionType, id)] : defaultBreadCrumbs; }; export const dashboardCrumb = (authority?: Authority): BreadCrumbConfig => ({ displayText: "Dashboard", order: 1, default: true, - to: authority - ? `/dashboard?tab=${getDashboardTabForAuthority(authority)}` - : "/dashboard", + to: authority ? `/dashboard?tab=${getDashboardTabForAuthority(authority)}` : "/dashboard", }); -export const detailsCrumb = ( - id: string, - authority: Authority, -): BreadCrumbConfig => ({ +export const detailsCrumb = (id: string, authority: Authority): BreadCrumbConfig => ({ displayText: id, order: 2, to: `/details/${authority}/${id}`, diff --git a/react-app/src/utils/formOrigin.test.ts b/react-app/src/utils/formOrigin.test.ts index 59d6f8f7dd..aca52a300d 100644 --- a/react-app/src/utils/formOrigin.test.ts +++ b/react-app/src/utils/formOrigin.test.ts @@ -1,12 +1,12 @@ -import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; -import { getFormOrigin } from './formOrigin'; -import { Authority } from 'shared-types/authority'; +import { describe, it, expect, beforeEach, afterEach, vi } from "vitest"; +import { getFormOrigin } from "./formOrigin"; +import { Authority } from "shared-types/authority"; -vi.mock('./crumbs', () => ({ - getDashboardTabForAuthority: vi.fn(() => 'spas'), // Mock return value +vi.mock("./crumbs", () => ({ + getDashboardTabForAuthority: vi.fn(() => "spas"), // Mock return value })); -describe('getFormOrigin', () => { +describe("getFormOrigin", () => { let originalLocation: Location; beforeEach(() => { @@ -14,27 +14,27 @@ describe('getFormOrigin', () => { const mockLocation = { ...originalLocation, - search: '', + search: "", assign: vi.fn(), reload: vi.fn(), replace: vi.fn(), }; - Object.defineProperty(window, 'location', { + Object.defineProperty(window, "location", { value: mockLocation, writable: true, }); }); afterEach(() => { - Object.defineProperty(window, 'location', { + Object.defineProperty(window, "location", { value: originalLocation, writable: true, }); vi.clearAllMocks(); // Clear mocks after each test }); - it('should return the correct pathname and search for dashboard origin', () => { + it("should return the correct pathname and search for dashboard origin", () => { window.location.search = `?origin=dashboard`; const authority = "chip spa" as Authority; // Use string assertion @@ -43,34 +43,34 @@ describe('getFormOrigin', () => { expect(result).toEqual({ pathname: `/dashboard`, - search: new URLSearchParams({ tab: 'spas' }).toString(), + search: new URLSearchParams({ tab: "spas" }).toString(), }); - // Other tests remain unchanged -}); - it('should return the correct pathname for spa submission origin', () => { + // Other tests remain unchanged + }); + it("should return the correct pathname for spa submission origin", () => { window.location.search = `?origin=spas`; const result = getFormOrigin(); expect(result).toEqual({ pathname: `/dashboard`, - search: new URLSearchParams({ tab: 'spas' }).toString(), + search: new URLSearchParams({ tab: "spas" }).toString(), }); }); - it('should return the correct pathname for waiver submission origin', () => { + it("should return the correct pathname for waiver submission origin", () => { window.location.search = `?origin=waivers`; const result = getFormOrigin(); expect(result).toEqual({ pathname: `/dashboard`, - search: new URLSearchParams({ tab: 'waivers' }).toString(), + search: new URLSearchParams({ tab: "waivers" }).toString(), }); }); - it('should return the default pathname for unknown origin', () => { - window.location.search = ''; + it("should return the default pathname for unknown origin", () => { + window.location.search = ""; const result = getFormOrigin(); @@ -78,4 +78,4 @@ describe('getFormOrigin', () => { pathname: `/dashboard`, }); }); -}); \ No newline at end of file +}); diff --git a/react-app/src/utils/formOrigin.ts b/react-app/src/utils/formOrigin.ts index cac985fa25..a3cf69de40 100644 --- a/react-app/src/utils/formOrigin.ts +++ b/react-app/src/utils/formOrigin.ts @@ -28,14 +28,11 @@ type GetFormOrigin = (args?: GetFormOriginArgs) => { * Instead, call within functions */ export const getFormOrigin: GetFormOrigin = ({ id, authority } = {}) => { - const origin = - new URLSearchParams(window.location.search).get(ORIGIN) ?? DASHBOARD_ORIGIN; + const origin = new URLSearchParams(window.location.search).get(ORIGIN) ?? DASHBOARD_ORIGIN; if (origin === DETAILS_ORIGIN && id && authority) { return { - pathname: `/${origin}/${encodeURIComponent( - authority, - )}/${encodeURIComponent(id)}`, + pathname: `/${origin}/${encodeURIComponent(authority)}/${encodeURIComponent(id)}`, }; } diff --git a/react-app/src/utils/location.ts b/react-app/src/utils/location.ts index bc7d7f578f..eaff8b9aab 100644 --- a/react-app/src/utils/location.ts +++ b/react-app/src/utils/location.ts @@ -1,5 +1,4 @@ export const isProd = - window.location.hostname === "mako.cms.gov" || - window.location.hostname === "onemac.cms.gov"; + window.location.hostname === "mako.cms.gov" || window.location.hostname === "onemac.cms.gov"; export const isFaqPage = window.location.pathname.startsWith("/faq"); diff --git a/react-app/src/utils/stateName.test.ts b/react-app/src/utils/stateName.test.ts index 63774431a2..d98db50bba 100644 --- a/react-app/src/utils/stateName.test.ts +++ b/react-app/src/utils/stateName.test.ts @@ -1,5 +1,5 @@ -import { describe, it, expect} from "vitest"; -import { convertStateAbbrToFullName } from "./stateNames"; +import { describe, it, expect } from "vitest"; +import { convertStateAbbrToFullName } from "./stateNames"; describe("convertStateAbbrToFullName", () => { it("should return the full state name for a valid abbreviation", () => { @@ -16,4 +16,4 @@ describe("convertStateAbbrToFullName", () => { it("should handle empty input gracefully", () => { expect(convertStateAbbrToFullName("")).toBe(""); }); -}); \ No newline at end of file +}); diff --git a/react-app/src/utils/stateNames.ts b/react-app/src/utils/stateNames.ts index 16662b68ca..255348864d 100644 --- a/react-app/src/utils/stateNames.ts +++ b/react-app/src/utils/stateNames.ts @@ -1,8 +1,7 @@ import { STATES } from "@/hooks"; type State = keyof typeof STATES; -const isStringAState = (supposedState: string): supposedState is State => - supposedState in STATES; +const isStringAState = (supposedState: string): supposedState is State => supposedState in STATES; export const convertStateAbbrToFullName = (input: string): string => { if (isStringAState(input)) { diff --git a/react-app/src/utils/test-helpers/uploadFiles.ts b/react-app/src/utils/test-helpers/uploadFiles.ts index c82d8930d6..fe6ee5da3f 100644 --- a/react-app/src/utils/test-helpers/uploadFiles.ts +++ b/react-app/src/utils/test-helpers/uploadFiles.ts @@ -11,10 +11,10 @@ type ExtractAttachmentKeys = : never : never : TSchema extends z.ZodObject // Handle direct ZodObject case - ? Shape["attachments"] extends z.ZodObject // Ensure attachments is a ZodObject - ? keyof AttachmentsShape // Extract the keys from attachments' shape - : never - : never; + ? Shape["attachments"] extends z.ZodObject // Ensure attachments is a ZodObject + ? keyof AttachmentsShape // Extract the keys from attachments' shape + : never + : never; export const uploadFiles = () => { type AttachmentKey = ExtractAttachmentKeys; @@ -24,10 +24,7 @@ export const uploadFiles = () => { type: "image/png", }); - await userEvent.upload( - screen.getByTestId(`${attachmentKey}-upload`), - EXAMPLE_FILE, - ); + await userEvent.upload(screen.getByTestId(`${attachmentKey}-upload`), EXAMPLE_FILE); return screen.getByTestId(`${attachmentKey}-label`); }; diff --git a/react-app/src/utils/textHelpers.test.ts b/react-app/src/utils/textHelpers.test.ts index a2f15efb6d..838790f3b9 100644 --- a/react-app/src/utils/textHelpers.test.ts +++ b/react-app/src/utils/textHelpers.test.ts @@ -1,8 +1,8 @@ -import { describe, it, expect } from 'vitest'; -import { removeUnderscoresAndCapitalize, convertCamelCaseToWords } from './textHelpers'; +import { describe, it, expect } from "vitest"; +import { removeUnderscoresAndCapitalize, convertCamelCaseToWords } from "./textHelpers"; -describe('removeUnderscoresAndCapitalize', () => { - it('should replace underscores with spaces and capitalize each word', () => { +describe("removeUnderscoresAndCapitalize", () => { + it("should replace underscores with spaces and capitalize each word", () => { expect(removeUnderscoresAndCapitalize("hello_world")).toBe("Hello World"); expect(removeUnderscoresAndCapitalize("remove_this_string")).toBe("Remove This String"); }); @@ -12,28 +12,28 @@ describe('removeUnderscoresAndCapitalize', () => { expect(removeUnderscoresAndCapitalize("cat_and_dogs")).toBe("Cat And Dog"); }); - it('should handle empty strings', () => { + it("should handle empty strings", () => { expect(removeUnderscoresAndCapitalize("")).toBe(""); }); - it('should handle strings without underscores', () => { + it("should handle strings without underscores", () => { expect(removeUnderscoresAndCapitalize("hello")).toBe("Hello"); expect(removeUnderscoresAndCapitalize("test")).toBe("Test"); }); }); -describe('convertCamelCaseToWords', () => { - it('should convert camel case to words', () => { +describe("convertCamelCaseToWords", () => { + it("should convert camel case to words", () => { expect(convertCamelCaseToWords("helloWorld")).toBe("Hello World"); expect(convertCamelCaseToWords("convertCamelCaseToWords")).toBe("Convert Camel Case To Words"); }); - it('should handle leading uppercase letters', () => { + it("should handle leading uppercase letters", () => { expect(convertCamelCaseToWords("CamelCase")).toBe("Camel Case"); expect(convertCamelCaseToWords("HelloWorld")).toBe("Hello World"); }); - it('should handle no camel case', () => { + it("should handle no camel case", () => { expect(convertCamelCaseToWords("justwords")).toBe("Justwords"); }); }); diff --git a/react-app/src/utils/textHelpers.ts b/react-app/src/utils/textHelpers.ts index dd42e0c953..920248ccd7 100644 --- a/react-app/src/utils/textHelpers.ts +++ b/react-app/src/utils/textHelpers.ts @@ -1,8 +1,6 @@ import { Authority } from "shared-types/authority"; -export function removeUnderscoresAndCapitalize( - str: Authority | string, -): string { +export function removeUnderscoresAndCapitalize(str: Authority | string): string { // Replace underscores with spaces const withoutUnderscores = str.replace(/_/g, " "); diff --git a/react-app/src/utils/user.test.ts b/react-app/src/utils/user.test.ts index 5dafd8867c..321951146d 100644 --- a/react-app/src/utils/user.test.ts +++ b/react-app/src/utils/user.test.ts @@ -60,9 +60,7 @@ describe("getUserStateCodes", () => { it("should return the state codes for a state user", () => { vi.mocked(isCmsUser).mockReturnValue(false); vi.mocked(isStateUser).mockReturnValue(true); - const result = getUserStateCodes( - stateSubmitterUser as CognitoUserAttributes, - ); + const result = getUserStateCodes(stateSubmitterUser as CognitoUserAttributes); expect(result).toEqual(["CA"]); }); }); @@ -84,17 +82,13 @@ describe("isAuthorizedState", () => { }); it("should throw an error if no cognito attributes are found", async () => { - const consoleErrorSpy = vi - .spyOn(console, "error") - .mockImplementation(() => {}); + const consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {}); vi.mocked(getUser).mockResolvedValue({ user: null }); const result = await isAuthorizedState("CA-1234.R00.00"); expect(result).toBe(false); - expect(consoleErrorSpy).toHaveBeenCalledWith( - new Error("No cognito attributes found."), - ); + expect(consoleErrorSpy).toHaveBeenCalledWith(new Error("No cognito attributes found.")); consoleErrorSpy.mockRestore(); }); }); diff --git a/react-app/src/utils/user.ts b/react-app/src/utils/user.ts index 82e205cb4f..185c7f9d65 100644 --- a/react-app/src/utils/user.ts +++ b/react-app/src/utils/user.ts @@ -3,23 +3,16 @@ import { type CognitoUserAttributes } from "shared-types/user"; import { isCmsUser, isStateUser } from "shared-utils"; import { getUser } from "@/api"; -export const getUserStateCodes = ( - user: CognitoUserAttributes | null | undefined, -): StateCode[] => { +export const getUserStateCodes = (user: CognitoUserAttributes | null | undefined): StateCode[] => { // We always need a user, and state users always need a custom:state value - if (!user || (isStateUser(user) && user["custom:state"] === undefined)) - return []; - return isCmsUser(user) - ? [...STATE_CODES] - : (user["custom:state"]!.split(",") as StateCode[]); + if (!user || (isStateUser(user) && user["custom:state"] === undefined)) return []; + return isCmsUser(user) ? [...STATE_CODES] : (user["custom:state"]!.split(",") as StateCode[]); }; export const isAuthorizedState = async (id: string) => { try { const user = await getUser(); if (!user.user) throw Error("No cognito attributes found."); - return getUserStateCodes(user.user).includes( - id.substring(0, 2) as StateCode, - ); + return getUserStateCodes(user.user).includes(id.substring(0, 2) as StateCode); } catch (e) { console.error(e); return false; diff --git a/react-app/src/utils/zod.test.ts b/react-app/src/utils/zod.test.ts index c74b2b58c0..0c26371510 100644 --- a/react-app/src/utils/zod.test.ts +++ b/react-app/src/utils/zod.test.ts @@ -325,9 +325,8 @@ describe("zAmendmentOriginalWaiverNumberSchema", () => { }); it("fails if the waiver number is not approved", async () => { - const result = await zAmendmentOriginalWaiverNumberSchema.safeParseAsync( - EXISTING_ITEM_PENDING_ID, - ); + const result = + await zAmendmentOriginalWaiverNumberSchema.safeParseAsync(EXISTING_ITEM_PENDING_ID); expect(result.success).toBe(false); expect(result.error.errors[0].message).toBe( "According to our records, this 1915(b) Waiver Number is not approved. You must supply an approved 1915(b) Initial or Renewal Waiver Number.", @@ -378,9 +377,8 @@ describe("zRenewalOriginalWaiverNumberSchema", () => { }); it("fails if the waiver number is not approved", async () => { - const result = await zRenewalOriginalWaiverNumberSchema.safeParseAsync( - EXISTING_ITEM_PENDING_ID, - ); + const result = + await zRenewalOriginalWaiverNumberSchema.safeParseAsync(EXISTING_ITEM_PENDING_ID); expect(result.success).toBe(false); expect(result.error.errors[0].message).toBe( "According to our records, this 1915(b) Waiver Number is not approved. You must supply an approved 1915(b) Initial or Renewal Waiver Number.", @@ -475,9 +473,8 @@ describe("zExtensionOriginalWaiverNumberSchema", () => { }); it("fails if the waiver number is not approved", async () => { - const result = await zExtensionOriginalWaiverNumberSchema.safeParseAsync( - EXISTING_ITEM_PENDING_ID, - ); + const result = + await zExtensionOriginalWaiverNumberSchema.safeParseAsync(EXISTING_ITEM_PENDING_ID); expect(result.success).toBe(false); expect(result.error.errors[0].message).toBe( "According to our records, this Approved Initial or Renewal Waiver Number is not approved. You must supply an approved Initial or Renewal Waiver Number.", diff --git a/react-app/src/utils/zod.ts b/react-app/src/utils/zod.ts index b3eee5d8c3..d27bee56e8 100644 --- a/react-app/src/utils/zod.ts +++ b/react-app/src/utils/zod.ts @@ -32,11 +32,9 @@ export const zAttachmentRequired = ({ max?: number; message?: string; }) => - z - .array(z.instanceof(File)) - .refine((value) => value.length >= min && value.length <= max, { - message: message, - }); + z.array(z.instanceof(File)).refine((value) => value.length >= min && value.length <= max, { + message: message, + }); export const zAdditionalInfoOptional = z .string() diff --git a/react-app/src/zodIdValidator.ts b/react-app/src/zodIdValidator.ts index 51334fb3bd..9a83577a7b 100644 --- a/react-app/src/zodIdValidator.ts +++ b/react-app/src/zodIdValidator.ts @@ -1,9 +1,6 @@ import { z, SuperRefinement } from "zod"; -export const validId = ( - idRegex: RegExp, - message: string, -): SuperRefinement => { +export const validId = (idRegex: RegExp, message: string): SuperRefinement => { const correctFormatSchema = z.string().regex(idRegex, { message, }); diff --git a/test/e2e/pages/faq.page.ts b/test/e2e/pages/faq.page.ts index d37862647d..2e9eac87f5 100644 --- a/test/e2e/pages/faq.page.ts +++ b/test/e2e/pages/faq.page.ts @@ -46,7 +46,7 @@ export class FAQPage { readonly withdrawWaiverRai: Locator; readonly withdrawPackageWaiver: Locator; - constructor(page:Page) { + constructor(page: Page) { this.page = page; this.header = page.getByTestId("sub-nav-header"); @@ -94,6 +94,6 @@ export class FAQPage { // HREFs of PDFs this.pdfs = { statePlans: page.locator('a[href*="state-plan-macpro"]'), - } + }; } -} \ No newline at end of file +} diff --git a/test/e2e/pages/home.page.ts b/test/e2e/pages/home.page.ts index 6df99930bb..34da5ffce3 100644 --- a/test/e2e/pages/home.page.ts +++ b/test/e2e/pages/home.page.ts @@ -1,4 +1,4 @@ -import { type Locator, type Page } from '@playwright/test'; +import { type Locator, type Page } from "@playwright/test"; export class HomePage { readonly page: Page; @@ -11,16 +11,16 @@ export class HomePage { // the desktop object is used to group like selectors this.desktop = { - usaBanner: page.getByTestId('usa-statement-d'), - usaBannerBtn: page.getByTestId('usa-expand-btn-d'), - homeLink: page.getByTestId('Home-d'), - faqLink: page.getByTestId('FAQ-d'), - signInBtn: page.getByTestId('sign-in-button-d'), - registerBtn: page.getByTestId('register-button-d'), - newBetterBtn: page.getByTestId('new-better-btn') + usaBanner: page.getByTestId("usa-statement-d"), + usaBannerBtn: page.getByTestId("usa-expand-btn-d"), + homeLink: page.getByTestId("Home-d"), + faqLink: page.getByTestId("FAQ-d"), + signInBtn: page.getByTestId("sign-in-button-d"), + registerBtn: page.getByTestId("register-button-d"), + newBetterBtn: page.getByTestId("new-better-btn"), }; - this.officialUsage = page.getByTestId('official-usage'); - this.secureUsage = page.getByTestId('secure-usage'); + this.officialUsage = page.getByTestId("official-usage"); + this.secureUsage = page.getByTestId("secure-usage"); } -} \ No newline at end of file +} diff --git a/test/e2e/pages/index.ts b/test/e2e/pages/index.ts index 5f5e4f0396..856b77b399 100644 --- a/test/e2e/pages/index.ts +++ b/test/e2e/pages/index.ts @@ -1,2 +1,2 @@ export * from "./loginPage"; -export * from "./home.page"; \ No newline at end of file +export * from "./home.page"; diff --git a/test/e2e/playwright.config.ts b/test/e2e/playwright.config.ts index e92a94de57..e0c389d382 100644 --- a/test/e2e/playwright.config.ts +++ b/test/e2e/playwright.config.ts @@ -9,9 +9,7 @@ const baseURL = process.env.STAGE_NAME ( await new SSMClient({ region: "us-east-1" }).send( new GetParameterCommand({ - Name: `/${process.env.PROJECT}/${ - process.env.STAGE_NAME || "main" - }/deployment-output`, + Name: `/${process.env.PROJECT}/${process.env.STAGE_NAME || "main"}/deployment-output`, }), ) ).Parameter!.Value!, diff --git a/test/e2e/selectors/components/AddIssueForm/index.ts b/test/e2e/selectors/components/AddIssueForm/index.ts index e7feba41f7..de3960d992 100644 --- a/test/e2e/selectors/components/AddIssueForm/index.ts +++ b/test/e2e/selectors/components/AddIssueForm/index.ts @@ -8,11 +8,11 @@ export class AddIssueFormSelectors { } get addButton() { - return this.page.locator("_react=Button[buttonText=\"Add\"]"); + return this.page.locator('_react=Button[buttonText="Add"]'); } get submitButton() { - return this.page.locator("_react=Button[buttonText=\"Submit\"]"); + return this.page.locator('_react=Button[buttonText="Submit"]'); } get titleInput() { diff --git a/test/e2e/selectors/navigation/index.ts b/test/e2e/selectors/navigation/index.ts index cb98c48358..2cfe8b193a 100644 --- a/test/e2e/selectors/navigation/index.ts +++ b/test/e2e/selectors/navigation/index.ts @@ -8,12 +8,10 @@ export class NavSelectors { } get issuesDropDown() { - return this.page.locator( - "_react=NavSection[section.buttonText = \"Issues\"]" - ); + return this.page.locator('_react=NavSection[section.buttonText = "Issues"]'); } get allIssuesLink() { - return this.page.locator("_react=Link[text = \"All Issues\"]"); + return this.page.locator('_react=Link[text = "All Issues"]'); } } diff --git a/test/e2e/tests/FAQs/faq.spec.ts b/test/e2e/tests/FAQs/faq.spec.ts index 73cf597de9..b50877a83d 100644 --- a/test/e2e/tests/FAQs/faq.spec.ts +++ b/test/e2e/tests/FAQs/faq.spec.ts @@ -1,66 +1,74 @@ -import { test, expect } from '@playwright/test'; +import { test, expect } from "@playwright/test"; -import { FAQPage } from 'pages/faq.page'; +import { FAQPage } from "pages/faq.page"; let faqPage: FAQPage; -test.describe('FAQ page', {tag: ["@e2e", "@smoke", "@faq"]}, () => { +test.describe("FAQ page", { tag: ["@e2e", "@smoke", "@faq"] }, () => { test.beforeEach(async ({ page }) => { faqPage = new FAQPage(page); - await page.goto('/faq'); + await page.goto("/faq"); }); - test.describe("UI validation", {tag: ["@CI"]}, () => { + test.describe("UI validation", { tag: ["@CI"] }, () => { test.describe("header", () => { - test("displays header", async() => { + test("displays header", async () => { await expect(faqPage.header).toBeVisible(); await expect(faqPage.header).toHaveText("Frequently Asked Questions"); }); }); - + test.describe("General section", () => { - test("displays system for state submission FAQ", async() => { + test("displays system for state submission FAQ", async () => { await expect(faqPage.crossWalk).toBeVisible(); - await expect(faqPage.crossWalk).toHaveText("Which system should I use for my state’s submission?"); - + await expect(faqPage.crossWalk).toHaveText( + "Which system should I use for my state’s submission?", + ); + await expect(faqPage.pdfs.statePlans).not.toBeVisible(); }); - test("displays browser type FAQ", async() => { + test("displays browser type FAQ", async () => { await expect(faqPage.browsers).toBeVisible(); await expect(faqPage.browsers).toHaveText("What browsers can I use to access the system?"); - + await expect(faqPage.browsers.locator("div:nth-child(1)")).not.toBeVisible(); }); - test("displays confirmation email FAQ", async() => { + test("displays confirmation email FAQ", async () => { await expect(faqPage.confirmEmail).toBeVisible(); - await expect(faqPage.confirmEmail).toHaveText("What should we do if we don’t receive a confirmation email?"); - - await expect(faqPage.confirmEmail.locator("div:nth-child(1)")).not.toBeVisible() + await expect(faqPage.confirmEmail).toHaveText( + "What should we do if we don’t receive a confirmation email?", + ); + + await expect(faqPage.confirmEmail.locator("div:nth-child(1)")).not.toBeVisible(); }); - test("displays official submission FAQ", async() => { + test("displays official submission FAQ", async () => { await expect(faqPage.official).toBeVisible(); - await expect(faqPage.official).toHaveText("Is this considered the official state submission?"); + await expect(faqPage.official).toHaveText( + "Is this considered the official state submission?", + ); await expect(faqPage.official.locator("div:nth-child(1)")).not.toBeVisible(); }); - test("displays OneMac user roles FAQ", async() => { + test("displays OneMac user roles FAQ", async () => { await expect(faqPage.onemacRoles).toBeVisible(); await expect(faqPage.onemacRoles).toHaveText("What are the OneMAC user roles?"); await expect(faqPage.onemacRoles.locator("div:nth-child(1)")).not.toBeVisible(); }); - test("displays file format FAQ", async() => { + test("displays file format FAQ", async () => { await expect(faqPage.fileFormats).toBeVisible(); - await expect(faqPage.fileFormats).toHaveText("What are the kinds of file formats I can upload into OneMAC"); + await expect(faqPage.fileFormats).toHaveText( + "What are the kinds of file formats I can upload into OneMAC", + ); await expect(faqPage.fileFormats.locator("div:nth-child(1)")).not.toBeVisible(); }); - test("displays onboarding materials FAQ", async() => { + test("displays onboarding materials FAQ", async () => { await expect(faqPage.onboardingMaterials).toBeVisible(); await expect(faqPage.onboardingMaterials).toHaveText("Onboarding Materials"); @@ -69,223 +77,285 @@ test.describe('FAQ page', {tag: ["@e2e", "@smoke", "@faq"]}, () => { }); test.describe("State Plan Amendments (SPAs)", () => { - test("displays format used to enter a SPA ID FAQ", async() => { + test("displays format used to enter a SPA ID FAQ", async () => { await expect(faqPage.spaIdFormat).toBeVisible(); await expect(faqPage.spaIdFormat).toHaveText("What format is used to enter a SPA ID?"); - + await expect(faqPage.spaIdFormat.locator("div:nth-child(1)")).not.toBeVisible(); }); - test("displays Medicaid SPA attachments FAQ", async() => { + test("displays Medicaid SPA attachments FAQ", async () => { await expect(faqPage.medicaidSpaAttachments).toBeVisible(); - await expect(faqPage.medicaidSpaAttachments).toHaveText("What are the attachments for a Medicaid SPA?"); - + await expect(faqPage.medicaidSpaAttachments).toHaveText( + "What are the attachments for a Medicaid SPA?", + ); + await expect(faqPage.medicaidSpaAttachments.locator("div:nth-child(1)")).not.toBeVisible(); }); - test("displays attachments response to Medicaid RAI FAQ", async() => { + test("displays attachments response to Medicaid RAI FAQ", async () => { await expect(faqPage.medicaidSpaRai).toBeVisible(); - await expect(faqPage.medicaidSpaRai).toHaveText("What are the attachments for a Medicaid response to Request for Additional Information (RAI)?"); - + await expect(faqPage.medicaidSpaRai).toHaveText( + "What are the attachments for a Medicaid response to Request for Additional Information (RAI)?", + ); + await expect(faqPage.medicaidSpaRai.locator("div:nth-child(1)")).not.toBeVisible(); }); - test("displays CHIP SPA attachments FAQ", async() => { + test("displays CHIP SPA attachments FAQ", async () => { await expect(faqPage.chipSpaAttachments).toBeVisible(); - await expect(faqPage.chipSpaAttachments).toHaveText("What are the attachments for a CHIP SPA?"); - + await expect(faqPage.chipSpaAttachments).toHaveText( + "What are the attachments for a CHIP SPA?", + ); + await expect(faqPage.chipSpaAttachments.locator("div:nth-child(1)")).not.toBeVisible(); }); - test("displays attachments response to CHIP RAI FAQ", async() => { + test("displays attachments response to CHIP RAI FAQ", async () => { await expect(faqPage.chipSpaRai).toBeVisible(); - await expect(faqPage.chipSpaRai).toHaveText("What are the attachments for a CHIP SPA response to Request for Additional Information (RAI)?"); - + await expect(faqPage.chipSpaRai).toHaveText( + "What are the attachments for a CHIP SPA response to Request for Additional Information (RAI)?", + ); + await expect(faqPage.chipSpaRai.locator("div:nth-child(1)")).not.toBeVisible(); }); - test("displays PHE FAQ", async() => { + test("displays PHE FAQ", async () => { await expect(faqPage.publicHealthEmergency).toBeVisible(); - await expect(faqPage.publicHealthEmergency).toHaveText("Can I submit SPAs relating to the Public Health Emergency (PHE) in OneMAC?"); - + await expect(faqPage.publicHealthEmergency).toHaveText( + "Can I submit SPAs relating to the Public Health Emergency (PHE) in OneMAC?", + ); + await expect(faqPage.publicHealthEmergency.locator("div:nth-child(1)")).not.toBeVisible(); }); - test("displays withdraw formal RAI for Medicaid SPA FAQ", async() => { + test("displays withdraw formal RAI for Medicaid SPA FAQ", async () => { await expect(faqPage.withdrawSpaRai).toBeVisible(); - await expect(faqPage.withdrawSpaRai).toHaveText("How do I Withdraw a Formal RAI Response for a Medicaid SPA?"); - + await expect(faqPage.withdrawSpaRai).toHaveText( + "How do I Withdraw a Formal RAI Response for a Medicaid SPA?", + ); + await expect(faqPage.withdrawSpaRai.locator("div:nth-child(1)")).not.toBeVisible(); }); - test("displays withdraw package for Medicaid SPA FAQ", async() => { + test("displays withdraw package for Medicaid SPA FAQ", async () => { await expect(faqPage.withdrawPackageSpa).toBeVisible(); - await expect(faqPage.withdrawPackageSpa).toHaveText("How do I Withdraw a Package for a Medicaid SPA?"); - + await expect(faqPage.withdrawPackageSpa).toHaveText( + "How do I Withdraw a Package for a Medicaid SPA?", + ); + await expect(faqPage.withdrawPackageSpa.locator("div:nth-child(1)")).not.toBeVisible(); }); - test("displays withdraw formal RAI for CHIP SPA FAQ", async() => { + test("displays withdraw formal RAI for CHIP SPA FAQ", async () => { await expect(faqPage.withdrawChipSpaRai).toBeVisible(); - await expect(faqPage.withdrawChipSpaRai).toHaveText("How do I Withdraw a Formal RAI Response for a CHIP SPA?"); - + await expect(faqPage.withdrawChipSpaRai).toHaveText( + "How do I Withdraw a Formal RAI Response for a CHIP SPA?", + ); + await expect(faqPage.withdrawChipSpaRai.locator("div:nth-child(1)")).not.toBeVisible(); }); - test("displays withdraw package for CHIP SPA FAQ", async() => { + test("displays withdraw package for CHIP SPA FAQ", async () => { await expect(faqPage.withdrawPackageChipSpa).toBeVisible(); - await expect(faqPage.withdrawPackageChipSpa).toHaveText("How do I Withdraw a Package for a CHIP SPA?"); - + await expect(faqPage.withdrawPackageChipSpa).toHaveText( + "How do I Withdraw a Package for a CHIP SPA?", + ); + await expect(faqPage.withdrawPackageChipSpa.locator("div:nth-child(1)")).not.toBeVisible(); }); - test("displays download ABP SPA templates FAQ", async() => { + test("displays download ABP SPA templates FAQ", async () => { await expect(faqPage.abpSpaTemplates).toBeVisible(); - await expect(faqPage.abpSpaTemplates).toHaveText("Where can I download Medicaid Alternative Benefit Plan (ABP) SPA templates?"); - + await expect(faqPage.abpSpaTemplates).toHaveText( + "Where can I download Medicaid Alternative Benefit Plan (ABP) SPA templates?", + ); + await expect(faqPage.abpSpaTemplates.locator("div:nth-child(1)")).not.toBeVisible(); }); - test("displays download ABP SPA implementation guides FAQ", async() => { + test("displays download ABP SPA implementation guides FAQ", async () => { await expect(faqPage.abpSpaGuides).toBeVisible(); - await expect(faqPage.abpSpaGuides).toHaveText("Where can I download Medicaid Alternative Benefit Plan (ABP) SPA implementation guides?"); - + await expect(faqPage.abpSpaGuides).toHaveText( + "Where can I download Medicaid Alternative Benefit Plan (ABP) SPA implementation guides?", + ); + await expect(faqPage.abpSpaGuides.locator("div:nth-child(1)")).not.toBeVisible(); }); - test("displays download MPC SPA templates FAQ", async() => { + test("displays download MPC SPA templates FAQ", async () => { await expect(faqPage.mpcSpaTemplates).toBeVisible(); - await expect(faqPage.mpcSpaTemplates).toHaveText("Where can I download Medicaid Premiums and Cost Sharing (MPC) SPA templates?"); - + await expect(faqPage.mpcSpaTemplates).toHaveText( + "Where can I download Medicaid Premiums and Cost Sharing (MPC) SPA templates?", + ); + await expect(faqPage.mpcSpaTemplates.locator("div:nth-child(1)")).not.toBeVisible(); }); - test("displays download MPC SPA implementation guides FAQ", async() => { + test("displays download MPC SPA implementation guides FAQ", async () => { await expect(faqPage.mpcSpaGuides).toBeVisible(); - await expect(faqPage.mpcSpaGuides).toHaveText("Where can I download Medicaid Premiums and Cost Sharing (MPC) SPA implementation guides?"); - + await expect(faqPage.mpcSpaGuides).toHaveText( + "Where can I download Medicaid Premiums and Cost Sharing (MPC) SPA implementation guides?", + ); + await expect(faqPage.mpcSpaGuides.locator("div:nth-child(1)")).not.toBeVisible(); }); - test("displays download CHIP eligibility SPA templates FAQ", async() => { + test("displays download CHIP eligibility SPA templates FAQ", async () => { await expect(faqPage.chipSpaTemplates).toBeVisible(); - await expect(faqPage.chipSpaTemplates).toHaveText("Where can I download CHIP eligibility SPA templates?"); - + await expect(faqPage.chipSpaTemplates).toHaveText( + "Where can I download CHIP eligibility SPA templates?", + ); + await expect(faqPage.chipSpaTemplates.locator("div:nth-child(1)")).not.toBeVisible(); }); - test("displays download CHIP eligibility SPA implementation guides FAQ", async() => { + test("displays download CHIP eligibility SPA implementation guides FAQ", async () => { await expect(faqPage.chipSpaGuides).toBeVisible(); - await expect(faqPage.chipSpaGuides).toHaveText("Where can I download CHIP eligibility SPA implementation guides?"); - + await expect(faqPage.chipSpaGuides).toHaveText( + "Where can I download CHIP eligibility SPA implementation guides?", + ); + await expect(faqPage.chipSpaGuides.locator("div:nth-child(1)")).not.toBeVisible(); }); }); test.describe("Waivers Section", () => { - test("displays 1915(b) initial waiver number FAQ", async() => { + test("displays 1915(b) initial waiver number FAQ", async () => { await expect(faqPage.waiverIdFormat).toBeVisible(); - await expect(faqPage.waiverIdFormat).toHaveText("What format is used to enter a 1915(b) Initial Waiver number?"); - + await expect(faqPage.waiverIdFormat).toHaveText( + "What format is used to enter a 1915(b) Initial Waiver number?", + ); + await expect(faqPage.waiverIdFormat.locator("div:nth-child(1)")).not.toBeVisible(); }); - test("displays 1915(b) waiver renewal number FAQ", async() => { + test("displays 1915(b) waiver renewal number FAQ", async () => { await expect(faqPage.waiverRenewalIdFormat).toBeVisible(); - await expect(faqPage.waiverRenewalIdFormat).toHaveText("What format is used to enter a 1915(b) Waiver Renewal number?"); + await expect(faqPage.waiverRenewalIdFormat).toHaveText( + "What format is used to enter a 1915(b) Waiver Renewal number?", + ); await expect(faqPage.waiverRenewalIdFormat.locator("div:nth-child(1)")).not.toBeVisible(); }); - test("displays 1915(b) waiver amendment number FAQ", async() => { + test("displays 1915(b) waiver amendment number FAQ", async () => { await expect(faqPage.waiverAmendmentIdFormat).toBeVisible(); - await expect(faqPage.waiverAmendmentIdFormat).toHaveText("What format is used to enter a 1915(b) Waiver Amendment number?"); + await expect(faqPage.waiverAmendmentIdFormat).toHaveText( + "What format is used to enter a 1915(b) Waiver Amendment number?", + ); await expect(faqPage.waiverAmendmentIdFormat.locator("div:nth-child(1)")).not.toBeVisible(); }); - test("displays contact help for 1915(b) waiver FAQ", async() => { + test("displays contact help for 1915(b) waiver FAQ", async () => { await expect(faqPage.waiverIdHelp).toBeVisible(); - await expect(faqPage.waiverIdHelp).toHaveText("Who can I contact to help me figure out the correct 1915(b) Waiver Number?"); + await expect(faqPage.waiverIdHelp).toHaveText( + "Who can I contact to help me figure out the correct 1915(b) Waiver Number?", + ); await expect(faqPage.waiverIdHelp.locator("div:nth-child(1)")).not.toBeVisible(); }); - test("displays format 1915(c) waiver number FAQ", async() => { + test("displays format 1915(c) waiver number FAQ", async () => { await expect(faqPage.waiverCId).toBeVisible(); - await expect(faqPage.waiverCId).toHaveText("What format is used to enter a 1915(c) waiver number?"); + await expect(faqPage.waiverCId).toHaveText( + "What format is used to enter a 1915(c) waiver number?", + ); await expect(faqPage.waiverCId.locator("div:nth-child(1)")).not.toBeVisible(); }); - test("displays attachments are needed for 1915(b) waiver action FAQ", async() => { + test("displays attachments are needed for 1915(b) waiver action FAQ", async () => { await expect(faqPage.waiverBAttachments).toBeVisible(); - await expect(faqPage.waiverBAttachments).toHaveText("What attachments are needed to submit a 1915(b) waiver action?"); + await expect(faqPage.waiverBAttachments).toHaveText( + "What attachments are needed to submit a 1915(b) waiver action?", + ); await expect(faqPage.waiverBAttachments.locator("div:nth-child(1)")).not.toBeVisible(); }); - test("displays attachments 1915b and c App K RAI response FAQ", async() => { + test("displays attachments 1915b and c App K RAI response FAQ", async () => { await expect(faqPage.waiverBRaiAttachments).toBeVisible(); - await expect(faqPage.waiverBRaiAttachments).toHaveText("What are the attachments for a 1915(b) Waiver and 1915(c) Appendix K response to Request for Additional Information (RAI)?"); + await expect(faqPage.waiverBRaiAttachments).toHaveText( + "What are the attachments for a 1915(b) Waiver and 1915(c) Appendix K response to Request for Additional Information (RAI)?", + ); await expect(faqPage.waiverBRaiAttachments.locator("div:nth-child(1)")).not.toBeVisible(); }); - test("displays temporary extension format FAQ", async() => { + test("displays temporary extension format FAQ", async () => { await expect(faqPage.waiverExtensionIdFormat).toBeVisible(); - await expect(faqPage.waiverExtensionIdFormat).toHaveText("What format is used to enter a 1915(b) or 1915(c) Temporary Extension number?"); + await expect(faqPage.waiverExtensionIdFormat).toHaveText( + "What format is used to enter a 1915(b) or 1915(c) Temporary Extension number?", + ); await expect(faqPage.waiverExtensionIdFormat.locator("div:nth-child(1)")).not.toBeVisible(); }); - test("displays status of my temporary extension FAQ", async() => { + test("displays status of my temporary extension FAQ", async () => { await expect(faqPage.waiverExtensionStatus).toBeVisible(); - await expect(faqPage.waiverExtensionStatus).toHaveText("Why does the status of my Temporary Extension Request continue to show as 'Submitted'?"); + await expect(faqPage.waiverExtensionStatus).toHaveText( + "Why does the status of my Temporary Extension Request continue to show as 'Submitted'?", + ); await expect(faqPage.waiverExtensionStatus.locator("div:nth-child(1)")).not.toBeVisible(); }); // remove skip when selector is updated in application - test.skip("displays attachments for 1915(b) waiver FAQ", async() => { + test.skip("displays attachments for 1915(b) waiver FAQ", async () => { await expect(faqPage.tempExtensionBAttachments).toBeVisible(); - await expect(faqPage.tempExtensionBAttachments).toHaveText("What are the attachments for a 1915(b) Waiver - Request for Temporary Extension?"); + await expect(faqPage.tempExtensionBAttachments).toHaveText( + "What are the attachments for a 1915(b) Waiver - Request for Temporary Extension?", + ); - await expect(faqPage.tempExtensionBAttachments.locator("div:nth-child(1)")).not.toBeVisible(); + await expect( + faqPage.tempExtensionBAttachments.locator("div:nth-child(1)"), + ).not.toBeVisible(); }); // remove skip when selector is updated in application - test.skip("displays attachments for 1915(c) waiver FAQ", async() => { + test.skip("displays attachments for 1915(c) waiver FAQ", async () => { await expect(faqPage.tempExtensionCAttachments).toBeVisible(); - await expect(faqPage.tempExtensionCAttachments).toHaveText("What are the attachments for a 1915(c) Waiver - Request for Temporary Extension?"); + await expect(faqPage.tempExtensionCAttachments).toHaveText( + "What are the attachments for a 1915(c) Waiver - Request for Temporary Extension?", + ); - await expect(faqPage.tempExtensionCAttachments.locator("div:nth-child(1)")).not.toBeVisible(); + await expect( + faqPage.tempExtensionCAttachments.locator("div:nth-child(1)"), + ).not.toBeVisible(); }); - test("displays submit App K attachments FAQ", async() => { + test("displays submit App K attachments FAQ", async () => { await expect(faqPage.appK).toBeVisible(); await expect(faqPage.appK).toHaveText("Can I submit Appendix K amendments in OneMAC?"); await expect(faqPage.appK.locator("div:nth-child(1)")).not.toBeVisible(); }); - test("displays attachments for 1915(c) Appendix K waiver FAQ", async() => { + test("displays attachments for 1915(c) Appendix K waiver FAQ", async () => { await expect(faqPage.appKAttachments).toBeVisible(); - await expect(faqPage.appKAttachments).toHaveText("What are the attachments for a 1915(c) Appendix K Waiver?"); + await expect(faqPage.appKAttachments).toHaveText( + "What are the attachments for a 1915(c) Appendix K Waiver?", + ); await expect(faqPage.appKAttachments.locator("div:nth-child(1)")).not.toBeVisible(); }); - test("displays withdraw Formal RAI Response for Medicaid Waiver FAQ", async() => { + test("displays withdraw Formal RAI Response for Medicaid Waiver FAQ", async () => { await expect(faqPage.withdrawWaiverRai).toBeVisible(); - await expect(faqPage.withdrawWaiverRai).toHaveText("How do I Withdraw a Formal RAI Response for a Medicaid Waiver?"); + await expect(faqPage.withdrawWaiverRai).toHaveText( + "How do I Withdraw a Formal RAI Response for a Medicaid Waiver?", + ); await expect(faqPage.withdrawWaiverRai.locator("div:nth-child(1)")).not.toBeVisible(); }); - test("displays withdraw Package for Waiver FAQ", async() => { + test("displays withdraw Package for Waiver FAQ", async () => { await expect(faqPage.withdrawPackageWaiver).toBeVisible(); - await expect(faqPage.withdrawPackageWaiver).toHaveText("How do I Withdraw a Package for a Waiver?"); + await expect(faqPage.withdrawPackageWaiver).toHaveText( + "How do I Withdraw a Package for a Waiver?", + ); await expect(faqPage.withdrawPackageWaiver.locator("div:nth-child(1)")).not.toBeVisible(); }); @@ -294,42 +364,42 @@ test.describe('FAQ page', {tag: ["@e2e", "@smoke", "@faq"]}, () => { test.describe("Interaction validation", () => { test.describe("General Section", () => { - test("should display crosswalk system FAQ response", async() => { + test("should display crosswalk system FAQ response", async () => { await faqPage.crossWalk.click(); await expect(faqPage.pdfs.statePlans).toBeVisible(); }); - - test("should display browser FAQ response", async() => { + + test("should display browser FAQ response", async () => { await faqPage.browsers.click(); await expect(faqPage.browsers.locator("div:nth-child(1)")).toBeVisible(); - // await expect(faqPage.browsers.locator("div:nth-child(1)")).toHaveText(""); Something TODO + // await expect(faqPage.browsers.locator("div:nth-child(1)")).toHaveText(""); Something TODO }); - - test("should display confirmation email FAQ response", async() => { + + test("should display confirmation email FAQ response", async () => { await faqPage.confirmEmail.click(); await expect(faqPage.confirmEmail.locator("div:nth-child(1)")).toBeVisible(); - // await expect(faqPage.confirmEmail.locator("div:nth-child(1)")).toHaveText(""); // Something TODO + // await expect(faqPage.confirmEmail.locator("div:nth-child(1)")).toHaveText(""); // Something TODO }); - - test("should display official submission FAQ response", async() => { + + test("should display official submission FAQ response", async () => { await faqPage.official.click(); await expect(faqPage.official.locator("div:nth-child(1)")).toBeVisible(); // await expect(faqPage.official.locator("div:nth-child(1)")).toHaveText(""); TODO }); - - test("should diplay OneMac User role FAQ response", async() => { + + test("should diplay OneMac User role FAQ response", async () => { await faqPage.onemacRoles.click(); await expect(faqPage.onemacRoles.locator("div:nth-child(1)")).toBeVisible(); // await expect(faqPage.onemacRoles.locator("div:nth-child(1)")).toHaveText(""); TODO }); - - test("should display file formats FAQ response", async() => { + + test("should display file formats FAQ response", async () => { await faqPage.fileFormats.click(); await expect(faqPage.fileFormats.locator("div:nth-child(1)")).toBeVisible(); // await expect(faqPage.fileFormats.locator("div:nth-child(1)")).toHaveText(""); TODO }); - - test("should display the list on onboarding materials FAQ response", async() => { + + test("should display the list on onboarding materials FAQ response", async () => { await faqPage.onboardingMaterials.click(); await expect(faqPage.onboardingMaterials.locator("div:nth-child(1)")).toBeVisible(); // await expect(faqPage.onboardingMaterials.locator("div:nth-child(1)")).toHaveText(""); TODO @@ -338,178 +408,180 @@ test.describe('FAQ page', {tag: ["@e2e", "@smoke", "@faq"]}, () => { }); test.describe("State Plan Amendments (SPAs) Section", () => { - test("should display format used to enter a SPA ID FAQ response", async() => { + test("should display format used to enter a SPA ID FAQ response", async () => { await faqPage.spaIdFormat.click(); await expect(faqPage.spaIdFormat.locator("div:nth-child(1)")).toBeVisible(); }); - test("should display Medicaid SPA attachments FAQ response", async() => { + test("should display Medicaid SPA attachments FAQ response", async () => { await faqPage.medicaidSpaAttachments.click(); await expect(faqPage.medicaidSpaAttachments.locator("div:nth-child(1)")).toBeVisible(); }); - test("should display attachments response to Medicaid RAI FAQ response", async() => { + test("should display attachments response to Medicaid RAI FAQ response", async () => { await faqPage.medicaidSpaRai.click(); await expect(faqPage.medicaidSpaRai.locator("div:nth-child(1)")).toBeVisible(); }); - test("should display CHIP SPA attachments FAQ response", async() => { + test("should display CHIP SPA attachments FAQ response", async () => { await faqPage.chipSpaAttachments.click(); await expect(faqPage.chipSpaAttachments.locator("div:nth-child(1)")).toBeVisible(); }); - test("should display attachments response to CHIP RAI FAQ response", async() => { + test("should display attachments response to CHIP RAI FAQ response", async () => { await faqPage.chipSpaRai.click(); await expect(faqPage.chipSpaRai.locator("div:nth-child(1)")).toBeVisible(); }); - test("should display PHE FAQ response", async() => { + test("should display PHE FAQ response", async () => { await faqPage.publicHealthEmergency.click(); await expect(faqPage.publicHealthEmergency.locator("div:nth-child(1)")).toBeVisible(); }); - test("should display withdraw formal RAI for Medicaid SPA FAQ response", async() => { + test("should display withdraw formal RAI for Medicaid SPA FAQ response", async () => { await faqPage.withdrawSpaRai.click(); await expect(faqPage.withdrawSpaRai.locator('div[data-state="open"]')).toBeVisible(); }); - test("should display withdraw package for Medicaid SPA FAQ response", async() => { + test("should display withdraw package for Medicaid SPA FAQ response", async () => { await faqPage.withdrawPackageSpa.click(); await expect(faqPage.withdrawPackageSpa.locator('div[data-state="open"]')).toBeVisible(); }); - test("should display withdraw formal RAI for CHIP SPA FAQ response", async() => { + test("should display withdraw formal RAI for CHIP SPA FAQ response", async () => { await faqPage.withdrawChipSpaRai.click(); await expect(faqPage.withdrawChipSpaRai.locator('div[data-state="open"]')).toBeVisible(); }); - test("should display withdraw package for CHIP SPA FAQ response", async() => { + test("should display withdraw package for CHIP SPA FAQ response", async () => { await faqPage.withdrawPackageChipSpa.click(); - await expect(faqPage.withdrawPackageChipSpa.locator('div[data-state="open"]')).toBeVisible(); + await expect( + faqPage.withdrawPackageChipSpa.locator('div[data-state="open"]'), + ).toBeVisible(); }); - test("should display download ABP SPA templates FAQ response", async() => { + test("should display download ABP SPA templates FAQ response", async () => { await faqPage.abpSpaTemplates.click(); await expect(faqPage.abpSpaTemplates.locator("div:nth-child(1)")).toBeVisible(); }); - test("should display download ABP SPA implementation guides FAQ response", async() => { + test("should display download ABP SPA implementation guides FAQ response", async () => { await faqPage.abpSpaGuides.click(); await expect(faqPage.abpSpaGuides.locator("div:nth-child(1)")).toBeVisible(); }); - test("should display download MPC SPA templates FAQ response", async() => { + test("should display download MPC SPA templates FAQ response", async () => { await faqPage.mpcSpaTemplates.click(); await expect(faqPage.mpcSpaTemplates.locator("div:nth-child(1)")).toBeVisible(); }); - test("should display download MPC SPA implementation guides FAQ response", async() => { + test("should display download MPC SPA implementation guides FAQ response", async () => { await faqPage.mpcSpaGuides.click(); await expect(faqPage.mpcSpaGuides.locator("div:nth-child(1)")).toBeVisible(); }); - test("should display download CHIP eligibility SPA templates FAQ response", async() => { + test("should display download CHIP eligibility SPA templates FAQ response", async () => { await faqPage.chipSpaTemplates.click(); await expect(faqPage.chipSpaTemplates.locator("div:nth-child(1)")).toBeVisible(); }); - test("should display download CHIP eligibility SPA implementation guides FAQ response", async() => { + test("should display download CHIP eligibility SPA implementation guides FAQ response", async () => { await faqPage.chipSpaGuides.click(); await expect(faqPage.chipSpaGuides.locator("div:nth-child(1)")).toBeVisible(); }); }); test.describe("Waivers Section", () => { - test("displays 1915(b) initial waiver number FAQ response", async() => { + test("displays 1915(b) initial waiver number FAQ response", async () => { await faqPage.waiverIdFormat.click(); await expect(faqPage.waiverIdFormat.locator("div:nth-child(1)")).toBeVisible(); // await expect(faqPage.waiverIdFormat.locator("div:nth-child(1)")).toHaveText(""); TODO }); - test("displays 1915(b) waiver renewal number FAQ response", async() => { + test("displays 1915(b) waiver renewal number FAQ response", async () => { await faqPage.waiverRenewalIdFormat.click(); await expect(faqPage.waiverRenewalIdFormat.locator("div:nth-child(1)")).toBeVisible(); // await expect(faqPage.waiverRenewalIdFormat.locator("div:nth-child(1)")).toHaveText(""); TODO }); - test("displays 1915(b) waiver amendment number FAQ response", async() => { + test("displays 1915(b) waiver amendment number FAQ response", async () => { await faqPage.waiverAmendmentIdFormat.click(); await expect(faqPage.waiverAmendmentIdFormat.locator("div:nth-child(1)")).toBeVisible(); // await expect(faqPage.waiverAmendmentIdFormat.locator("div:nth-child(1)")).toHaveText(""); TODO }); - test("displays contact help for 1915(b) waiver FAQ response", async() => { + test("displays contact help for 1915(b) waiver FAQ response", async () => { await faqPage.waiverIdHelp.click(); await expect(faqPage.waiverIdHelp.locator("div:nth-child(1)")).toBeVisible(); // await expect(faqPage.waiverIdHelp.locator("div:nth-child(1)")).toHaveText(""); TODO }); - test("displays format 1915(c) waiver number FAQ response", async() => { + test("displays format 1915(c) waiver number FAQ response", async () => { await faqPage.waiverCId.click(); await expect(faqPage.waiverCId.locator("div:nth-child(1)")).toBeVisible(); // await expect(faqPage.waiverCId.locator("div:nth-child(1)")).toHaveText(""); TODO }); - test("displays attachments are needed for 1915(b) waiver action FAQ response", async() => { + test("displays attachments are needed for 1915(b) waiver action FAQ response", async () => { await faqPage.waiverBAttachments.click(); await expect(faqPage.waiverBAttachments.locator("div:nth-child(1)")).toBeVisible(); // await expect(faqPage.waiverBAttachments.locator("div:nth-child(1)")).toHaveText(""); TODO }); - test("displays attachments 1915b and c App K RAI response FAQ response", async() => { + test("displays attachments 1915b and c App K RAI response FAQ response", async () => { await faqPage.waiverBRaiAttachments.click(); await expect(faqPage.waiverBRaiAttachments.locator("div:nth-child(1)")).toBeVisible(); // await expect(faqPage.waiverBRaiAttachments.locator("div:nth-child(1)")).toHaveText(""); TODO }); - test("displays temporary extension format FAQ response", async() => { + test("displays temporary extension format FAQ response", async () => { await faqPage.waiverExtensionIdFormat.click(); await expect(faqPage.waiverExtensionIdFormat.locator("div:nth-child(1)")).toBeVisible(); // await expect(faqPage.waiverExtensionIdFormat.locator("div:nth-child(1)")).toHaveText(""); TODO }); - test("displays status of my temporary extension FAQ response", async() => { + test("displays status of my temporary extension FAQ response", async () => { await faqPage.waiverExtensionStatus.click(); await expect(faqPage.waiverExtensionStatus.locator("div:nth-child(1)")).toBeVisible(); }); // remove skip when selector is updated in application - test.skip("displays attachments for 1915(b) waiver FAQ response", async() => { + test.skip("displays attachments for 1915(b) waiver FAQ response", async () => { await faqPage.tempExtensionBAttachments.click(); await expect(faqPage.tempExtensionBAttachments.locator("div:nth-child(1)")).toBeVisible(); // await expect(faqPage.tempExtensionBAttachments.locator("div:nth-child(1)")).toHaveText(""); TODO }); // remove skip when selector us updated in application - test.skip("displays attachments for 1915(c) waiver FAQ response", async() => { + test.skip("displays attachments for 1915(c) waiver FAQ response", async () => { await faqPage.tempExtensionCAttachments.click(); await expect(faqPage.tempExtensionCAttachments.locator("div:nth-child(1)")).toBeVisible(); // await expect(faqPage.tempExtensionCAttachments.locator("div:nth-child(1)")).toHaveText(""); TODO }); - test("displays submit App K attachments FAQ response", async() => { + test("displays submit App K attachments FAQ response", async () => { await faqPage.appK.click(); await expect(faqPage.appK.locator("div:nth-child(1)")).toBeVisible(); // await expect(faqPage.appK.locator("div:nth-child(1)")).toHaveText(""); TODO }); - test("displays attachments for 1915(c) Appendix K waiver FAQ response", async() => { + test("displays attachments for 1915(c) Appendix K waiver FAQ response", async () => { await faqPage.appKAttachments.click(); await expect(faqPage.appKAttachments.locator("div:nth-child(1)")).toBeVisible(); // await expect(faqPage.appKAttachments.locator("div:nth-child(1)")).toHaveText(""); TODO }); - test("displays withdraw Formal RAI Response for Medicaid Waiver FAQ response", async() => { + test("displays withdraw Formal RAI Response for Medicaid Waiver FAQ response", async () => { await faqPage.withdrawWaiverRai.click(); await expect(faqPage.withdrawWaiverRai.locator('div[data-state="open"]')).toBeVisible(); // await expect(faqPage.withdrawWaiverRai.locator("div:nth-child(1)")).toHaveText(""); TODO }); - test("displays withdraw Package for Waiver FAQ response", async() => { + test("displays withdraw Package for Waiver FAQ response", async () => { await faqPage.withdrawPackageWaiver.click(); await expect(faqPage.withdrawPackageWaiver.locator('div[data-state="open"]')).toBeVisible(); // await expect(faqPage.withdrawPackageWaiver.locator("div:nth-child(1)")).toHaveText(""); TODO }); }); }); -}); \ No newline at end of file +}); diff --git a/test/e2e/tests/a11y/index.spec.ts b/test/e2e/tests/a11y/index.spec.ts index d61044fe01..ef0139f634 100644 --- a/test/e2e/tests/a11y/index.spec.ts +++ b/test/e2e/tests/a11y/index.spec.ts @@ -4,7 +4,7 @@ import * as routes from "../fixtures/routes"; const STATIC_ROUTES = routes.STATIC; -test.describe("test a11y on static routes", {tag: ["@CI", "@a11y"] }, () => { +test.describe("test a11y on static routes", { tag: ["@CI", "@a11y"] }, () => { for (const route of STATIC_ROUTES) { test(`${route} should not have any automatically detectable accessibility issues`, async ({ page, @@ -12,10 +12,7 @@ test.describe("test a11y on static routes", {tag: ["@CI", "@a11y"] }, () => { await page.goto(route); await page.waitForTimeout(500); const accessibilityScanResults = await new AxeBuilder({ page }).analyze(); - console.log( - `${route} violations: `, - accessibilityScanResults.violations.length, - ); + console.log(`${route} violations: `, accessibilityScanResults.violations.length); expect(accessibilityScanResults.violations).toEqual([]); }); } @@ -24,7 +21,7 @@ test.describe("test a11y on static routes", {tag: ["@CI", "@a11y"] }, () => { const WEBFORM_ROUTES = routes.WEBFORM; // Add to CI when prior to going to Prod -test.describe("test a11y on webform routes", {tag: ["@CI", "@a11y"] }, () => { +test.describe("test a11y on webform routes", { tag: ["@CI", "@a11y"] }, () => { for (const route of WEBFORM_ROUTES) { test(`${route} should not have any automatically detectable accessibility issues`, async ({ page, @@ -32,10 +29,7 @@ test.describe("test a11y on webform routes", {tag: ["@CI", "@a11y"] }, () => { await page.goto(route); await page.waitForTimeout(2000); const accessibilityScanResults = await new AxeBuilder({ page }).analyze(); - console.log( - `${route} violations: `, - accessibilityScanResults.violations.length, - ); + console.log(`${route} violations: `, accessibilityScanResults.violations.length); expect(accessibilityScanResults.violations).toEqual([]); }); } diff --git a/test/e2e/tests/fixtures/routes.ts b/test/e2e/tests/fixtures/routes.ts index a88d3a2f56..517e66a248 100644 --- a/test/e2e/tests/fixtures/routes.ts +++ b/test/e2e/tests/fixtures/routes.ts @@ -47,4 +47,4 @@ export const WEBFORM = [ "/webform/abp2a/202401", "/webform/abp1/202401", "/webform/abp1/202402", -]; \ No newline at end of file +]; diff --git a/test/e2e/tests/home/disableRAIresponsewithdraw.spec.ts b/test/e2e/tests/home/disableRAIresponsewithdraw.spec.ts index 89b1944aaa..56f6dbd7d1 100644 --- a/test/e2e/tests/home/disableRAIresponsewithdraw.spec.ts +++ b/test/e2e/tests/home/disableRAIresponsewithdraw.spec.ts @@ -4,4 +4,4 @@ test.describe.skip("Disable RAI Response withdraw", async () => { // comment this out until we need it // test.beforeAll(); test("Perform disable RAI response withdraw for a Medicaid SPA", () => {}); -}); \ No newline at end of file +}); diff --git a/test/e2e/tests/home/enableRAIresponsewithdraw.spec.ts b/test/e2e/tests/home/enableRAIresponsewithdraw.spec.ts index 3df570e27e..7c0dbe8c7b 100644 --- a/test/e2e/tests/home/enableRAIresponsewithdraw.spec.ts +++ b/test/e2e/tests/home/enableRAIresponsewithdraw.spec.ts @@ -4,4 +4,4 @@ test.describe.skip("Enable RAI Response withdraw", async () => { // comment this out until we need it // test.beforeAll(); test("Perform enable RAI response withdraw for a Medicaid SPA", () => {}); -}); \ No newline at end of file +}); diff --git a/test/e2e/tests/home/index.spec.ts b/test/e2e/tests/home/index.spec.ts index 88da67ac00..a81fb8075c 100644 --- a/test/e2e/tests/home/index.spec.ts +++ b/test/e2e/tests/home/index.spec.ts @@ -1,35 +1,30 @@ import { test, expect } from "@playwright/test"; -test.describe('home page', {tag: '@e2e'}, () => { +test.describe("home page", { tag: "@e2e" }, () => { test.beforeEach(async ({ page }) => { await page.goto("/"); }); - test("has title", async ({ page }) => { + test("has title", async ({ page }) => { await expect(page).toHaveTitle("OneMAC"); }); - test('should display a menu', async({ page }) => { - await expect(page.getByTestId('sign-in-button-d')).not.toBeVisible(); + test("should display a menu", async ({ page }) => { + await expect(page.getByTestId("sign-in-button-d")).not.toBeVisible(); }); - + test("see frequently asked questions header when in faq page", async ({ page }) => { const popup = page.waitForEvent("popup"); await page.getByRole("link", { name: "FAQ", exact: true }).click(); const foundFaqHeading = await popup; - await foundFaqHeading - .getByRole("heading", { name: "Frequently Asked Questions" }) - .isVisible(); + await foundFaqHeading.getByRole("heading", { name: "Frequently Asked Questions" }).isVisible(); expect(foundFaqHeading).toBeTruthy(); }); - + test("see dashboard link when log in", async ({ page }) => { await page.getByRole("link", { name: "Dashboard" }).click(); - - const dashboardLinkVisible = await page - .getByRole("link", { name: "Dashboard" }) - .isVisible(); + + const dashboardLinkVisible = await page.getByRole("link", { name: "Dashboard" }).isVisible(); expect(dashboardLinkVisible).toBeTruthy(); - }); + }); }); - diff --git a/test/e2e/tests/home/noauth.spec.ts b/test/e2e/tests/home/noauth.spec.ts index f36877494b..8c498674b1 100644 --- a/test/e2e/tests/home/noauth.spec.ts +++ b/test/e2e/tests/home/noauth.spec.ts @@ -1,20 +1,22 @@ -import { test, expect } from '@playwright/test'; +import { test, expect } from "@playwright/test"; -import { HomePage } from 'pages/home.page'; +import { HomePage } from "pages/home.page"; let homePage; -test.describe('home page - no auth', {tag: ['@e2e', '@smoke']}, () => { +test.describe("home page - no auth", { tag: ["@e2e", "@smoke"] }, () => { test.use({ storageState: { cookies: [], origins: [] } }); test.beforeEach(async ({ page }) => { homePage = new HomePage(page); - await page.goto('/'); + await page.goto("/"); }); - test.describe('UI validations', () => { - test('should have a USA banner', async () => { + test.describe("UI validations", () => { + test("should have a USA banner", async () => { await expect(homePage.desktop.usaBanner).toBeVisible(); - await expect(homePage.desktop.usaBanner).toHaveText('An official website of the United States government'); + await expect(homePage.desktop.usaBanner).toHaveText( + "An official website of the United States government", + ); await expect(homePage.desktop.usaBannerBtn).toBeVisible(); await expect(homePage.desktop.usaBannerBtn).toHaveText("Here's how you know"); @@ -22,37 +24,41 @@ test.describe('home page - no auth', {tag: ['@e2e', '@smoke']}, () => { await expect(homePage.officialUsage).not.toBeVisible(); await expect(homePage.secureUsage).not.toBeVisible(); }); - - test('should have a navigation banner', async () => { + + test("should have a navigation banner", async () => { await expect(homePage.desktop.homeLink).toBeVisible(); - await expect(homePage.desktop.homeLink).toHaveText('Home'); - + await expect(homePage.desktop.homeLink).toHaveText("Home"); + await expect(homePage.desktop.faqLink).toBeVisible(); - await expect(homePage.desktop.faqLink).toHaveText('FAQ'); - + await expect(homePage.desktop.faqLink).toHaveText("FAQ"); + await expect(homePage.desktop.signInBtn).toBeVisible(); - await expect(homePage.desktop.signInBtn).toHaveText('Sign In'); - + await expect(homePage.desktop.signInBtn).toHaveText("Sign In"); + await expect(homePage.desktop.registerBtn).toBeVisible(); - await expect(homePage.desktop.registerBtn).toHaveText('Register'); + await expect(homePage.desktop.registerBtn).toHaveText("Register"); }); }); - test.describe('Workflow validations', () => { - test.describe('USA Banner Interactions', () => { + test.describe("Workflow validations", () => { + test.describe("USA Banner Interactions", () => { test.beforeEach(async () => { await homePage.desktop.usaBannerBtn.click(); }); - test('should display USA statement', async() => { + test("should display USA statement", async () => { await expect(homePage.officialUsage).toBeVisible(); - await expect(homePage.officialUsage).toHaveText('Official websites use .govA.gov website belongs to an official government organization in the United States.'); - + await expect(homePage.officialUsage).toHaveText( + "Official websites use .govA.gov website belongs to an official government organization in the United States.", + ); + await expect(homePage.secureUsage).toBeVisible(); - await expect(homePage.secureUsage).toHaveText("Secure .gov websites use HTTPSA lock (LockA locked padlock) or https:// means you've safely connected to the .gov website. Share sensitive information only on official, secure websites."); + await expect(homePage.secureUsage).toHaveText( + "Secure .gov websites use HTTPSA lock (LockA locked padlock) or https:// means you've safely connected to the .gov website. Share sensitive information only on official, secure websites.", + ); }); - - test('should collapse the USA statement', async() => { + + test("should collapse the USA statement", async () => { await homePage.desktop.usaBannerBtn.click(); await expect(homePage.officialUsage).not.toBeVisible(); @@ -60,16 +66,16 @@ test.describe('home page - no auth', {tag: ['@e2e', '@smoke']}, () => { }); }); - test.describe('FAQs', () => { - test('navigastes to the FAQ page', async({ page }) => { + test.describe("FAQs", () => { + test("navigastes to the FAQ page", async ({ page }) => { await homePage.desktop.faqLink.click(); - const pagePromise = page.waitForEvent('popup'); + const pagePromise = page.waitForEvent("popup"); const newTab = await pagePromise; await newTab.waitForLoadState(); - await expect(newTab.locator('#crosswalk-system')).toBeVisible(); + await expect(newTab.locator("#crosswalk-system")).toBeVisible(); }); }); }); -}); \ No newline at end of file +}); diff --git a/test/e2e/tests/home/respondtorai.spec.ts b/test/e2e/tests/home/respondtorai.spec.ts index 8276a23d28..a76db92317 100644 --- a/test/e2e/tests/home/respondtorai.spec.ts +++ b/test/e2e/tests/home/respondtorai.spec.ts @@ -4,4 +4,4 @@ test.describe.skip("Respond to RAI", async () => { // comment this out until we need it // test.beforeAll(); test("Submit a Respond to RAI for a Medicaid SPA", () => {}); -}); \ No newline at end of file +}); diff --git a/test/e2e/tests/home/subsequentdocuments.spec.ts b/test/e2e/tests/home/subsequentdocuments.spec.ts index 636120734b..c1b2512675 100644 --- a/test/e2e/tests/home/subsequentdocuments.spec.ts +++ b/test/e2e/tests/home/subsequentdocuments.spec.ts @@ -4,4 +4,4 @@ test.describe.skip("Subsequent Documents", async () => { // comment this out until we need it // test.beforeAll(); test("Submit a subsequent documents for a Medicaid SPA", () => {}); -}); \ No newline at end of file +}); diff --git a/test/e2e/tests/home/withdrawRAIresponse.spec.ts b/test/e2e/tests/home/withdrawRAIresponse.spec.ts index a5d4efedb9..6f900ee26c 100644 --- a/test/e2e/tests/home/withdrawRAIresponse.spec.ts +++ b/test/e2e/tests/home/withdrawRAIresponse.spec.ts @@ -4,4 +4,4 @@ test.describe.skip("Withdraw RAI Response", async () => { // comment this out until we need it // test.beforeAll(); test("Perform withdraw RAI response for a Medicaid SPA", () => {}); -}); \ No newline at end of file +}); diff --git a/test/e2e/tests/home/withdrawpackage.spec.ts b/test/e2e/tests/home/withdrawpackage.spec.ts index ac5aba7deb..39eb0f5323 100644 --- a/test/e2e/tests/home/withdrawpackage.spec.ts +++ b/test/e2e/tests/home/withdrawpackage.spec.ts @@ -4,4 +4,4 @@ test.describe.skip("Withdraw package", async () => { // comment this out until we need it // test.beforeAll(); test("Perform withdraw package action for a Medicaid SPA", () => {}); -}); \ No newline at end of file +}); diff --git a/test/e2e/tests/perf/index.spec.ts b/test/e2e/tests/perf/index.spec.ts index 51071f7115..bbe08d6db5 100644 --- a/test/e2e/tests/perf/index.spec.ts +++ b/test/e2e/tests/perf/index.spec.ts @@ -5,9 +5,11 @@ const STATIC_ROUTES = routes.STATIC; test.describe("test performance on static routes", { tag: ["@perf"] }, () => { for (const route of STATIC_ROUTES) { - test(`Time to First Byte for ${route}`, { tag: ["@ttfb"] }, async({ page }) => { + test(`Time to First Byte for ${route}`, { tag: ["@ttfb"] }, async ({ page }) => { await page.goto(route); - const ttfb = await page.evaluate(() => performance.timing.responseStart - performance.timing.requestStart) + const ttfb = await page.evaluate( + () => performance.timing.responseStart - performance.timing.requestStart, + ); console.log(`TTFB for ${route}: ${ttfb} ms`); }); @@ -18,7 +20,7 @@ test.describe("test performance on static routes", { tag: ["@perf"] }, () => { new PerformanceObserver((entryList) => { const entries = entryList.getEntries(); resolve(entries[entries.length - 1]); - }).observe({ type: 'largest-contentful-paint', buffered: true }); + }).observe({ type: "largest-contentful-paint", buffered: true }); }); }); @@ -32,11 +34,11 @@ test.describe("test performance on static routes", { tag: ["@perf"] }, () => { new PerformanceObserver((entryList) => { const entries = entryList.getEntries(); resolve(entries[0]); - }).observe({ type: 'paint', buffered: true }); + }).observe({ type: "paint", buffered: true }); }); }); console.log(`First Contentful Paint for ${route} is: ${fcp.startTime} ms`); }); } -}); \ No newline at end of file +}); diff --git a/test/e2e/tests/sub-doc/medicaidSPADetail.spec.ts b/test/e2e/tests/sub-doc/medicaidSPADetail.spec.ts index 59ac0caba2..ad5b258968 100644 --- a/test/e2e/tests/sub-doc/medicaidSPADetail.spec.ts +++ b/test/e2e/tests/sub-doc/medicaidSPADetail.spec.ts @@ -3,7 +3,7 @@ import { test, expect } from "@playwright/test"; test.describe("Medicaid SPA - Sub Doc", () => { test.beforeEach(async ({ page }) => { await page.goto("/"); - await page.getByTestId('Dashboard-d').click(); + await page.getByTestId("Dashboard-d").click(); await page.locator('a[href*="details/Medicaid%20SPA/CO-22-2020"]').click(); }); @@ -14,10 +14,18 @@ test.describe("Medicaid SPA - Sub Doc", () => { test.describe("form actions", () => { test("should display the details page", async ({ page }) => { // elements before to be validated - - await expect(page.locator('a[href*="upload-subsequent-documents/Medicaid SPA/CO-22-2020?origin=details"]')).toBeVisible(); - await expect(page.locator('a[href*="upload-subsequent-documents/Medicaid SPA/CO-22-2020?origin=details"]')).toContainText('Upload Subsequent Document'); - + + await expect( + page.locator( + 'a[href*="upload-subsequent-documents/Medicaid SPA/CO-22-2020?origin=details"]', + ), + ).toBeVisible(); + await expect( + page.locator( + 'a[href*="upload-subsequent-documents/Medicaid SPA/CO-22-2020?origin=details"]', + ), + ).toContainText("Upload Subsequent Document"); + // elements after to be validated }); }); @@ -25,15 +33,19 @@ test.describe("Medicaid SPA - Sub Doc", () => { test.describe.skip("package activity", () => {}); }); - test.describe('Naviation - Validation', () => { - test('navigate to withdraw package page', () => { + test.describe("Naviation - Validation", () => { + test("navigate to withdraw package page", () => { // see below }); - test('navigate to sub doc page', async ({ page }) => { - await page.locator('a[href*="/actions/upload-subsequent-documents/Medicaid SPA/CO-22-2020?origin=details"]').click(); + test("navigate to sub doc page", async ({ page }) => { + await page + .locator( + 'a[href*="/actions/upload-subsequent-documents/Medicaid SPA/CO-22-2020?origin=details"]', + ) + .click(); await expect(page.getByTestId("detail-section")).toBeVisible(); }); }); -}); \ No newline at end of file +}); diff --git a/test/e2e/tests/sub-doc/medicaidSubDocDetail.spec.ts b/test/e2e/tests/sub-doc/medicaidSubDocDetail.spec.ts index 621e83cb60..710767a0de 100644 --- a/test/e2e/tests/sub-doc/medicaidSubDocDetail.spec.ts +++ b/test/e2e/tests/sub-doc/medicaidSubDocDetail.spec.ts @@ -1,44 +1,57 @@ -import {test, expect} from "@playwright/test"; - +import { test, expect } from "@playwright/test"; test.beforeEach(async ({ page }) => { await page.goto("/"); await page.getByTestId("Dashboard-d").click(); await page.locator('a[href*="details/Medicaid%20SPA/CO-22-2020"]').click(); - await page.locator('a[href*="/actions/upload-subsequent-documents/Medicaid SPA/CO-22-2020?origin=details"]').click(); + await page + .locator( + 'a[href*="/actions/upload-subsequent-documents/Medicaid SPA/CO-22-2020?origin=details"]', + ) + .click(); }); test.describe("UI - Validation", () => { test.describe("Breadcrumbs", () => { - test("should displays breadcrumb elements", async({ page }) => { + test("should displays breadcrumb elements", async ({ page }) => { // need a better selector await expect(page.locator("#root > div > main > div:nth-child(2) > nav")).toBeVisible(); - await expect(page.locator("#root > div > main > div:nth-child(2) > nav")).toHaveText("DashboardCO-22-2020New Subsequent Documentation"); + await expect(page.locator("#root > div > main > div:nth-child(2) > nav")).toHaveText( + "DashboardCO-22-2020New Subsequent Documentation", + ); }); }); test.describe("Form Elements", () => { - test("Detail Section", async({ page }) => { + test("Detail Section", async ({ page }) => { await expect(page.getByTestId("detail-section")).toBeVisible(); await expect(page.getByTestId("detail-section-title")).toBeVisible(); - await expect(page.getByTestId("detail-section-title")).toHaveText("Medicaid SPA Subsequent Documents Details"); + await expect(page.getByTestId("detail-section-title")).toHaveText( + "Medicaid SPA Subsequent Documents Details", + ); await expect(page.getByTestId("detail-section-child")).toBeVisible(); // await expect(page.getByTestId("detail-section-child")).toHaveText(); needs more detailed selectors to validate text }); - test("Document Section", async({ page }) => { + test("Document Section", async ({ page }) => { await expect(page.getByTestId("attachment-section")).toBeVisible(); await expect(page.getByTestId("attachment-section-title")).toBeVisible(); - await expect(page.getByTestId("attachment-section-title")).toHaveText("Subsequent Medicaid SPA Documents *"); + await expect(page.getByTestId("attachment-section-title")).toHaveText( + "Subsequent Medicaid SPA Documents *", + ); await expect(page.getByTestId("attachment-section-child")).toBeVisible(); await expect(page.getByTestId("attachments-instructions")).toBeVisible(); - await expect(page.getByTestId("attachments-instructions")).toHaveText("Maximum file size of 80 MB per attachment. You can add multiple files per attachment type. Read the description for each of the attachment types on the FAQ Page."); + await expect(page.getByTestId("attachments-instructions")).toHaveText( + "Maximum file size of 80 MB per attachment. You can add multiple files per attachment type. Read the description for each of the attachment types on the FAQ Page.", + ); await expect(page.getByTestId("accepted-files")).toBeVisible(); - await expect(page.getByTestId("accepted-files")).toHaveText("We accept the following file formats: .doc, .docx, .pdf, .jpg, .xlsx, and more. See the full list."); + await expect(page.getByTestId("accepted-files")).toHaveText( + "We accept the following file formats: .doc, .docx, .pdf, .jpg, .xlsx, and more. See the full list.", + ); await expect(page.getByTestId("cmsForm179-label")).toBeVisible(); await expect(page.getByTestId("cmsForm179-label")).toHaveText("CMS Form 179"); @@ -46,15 +59,17 @@ test.describe("UI - Validation", () => { // TODO: Extend to all labels }); - test("Reason Section", async({ page }) => { + test("Reason Section", async ({ page }) => { await expect(page.getByTestId("additional-info")).toBeVisible(); await expect(page.getByTestId("additional-info-title")).toBeVisible(); - await expect(page.getByTestId("additional-info-title")).toHaveText("Reason for subsequent documents *"); + await expect(page.getByTestId("additional-info-title")).toHaveText( + "Reason for subsequent documents *", + ); await expect(page.getByTestId("additional-info-child")).toBeVisible(); }); }); }); -test.describe.skip("Navigation", () => {}); \ No newline at end of file +test.describe.skip("Navigation", () => {}); diff --git a/test/e2e/utils/auth.setup.ts b/test/e2e/utils/auth.setup.ts index ee653f28e8..f6fe93c653 100644 --- a/test/e2e/utils/auth.setup.ts +++ b/test/e2e/utils/auth.setup.ts @@ -2,10 +2,7 @@ import { test as setup } from "@playwright/test"; import { testUsers } from "./users"; import { LoginPage } from "../pages"; import { GetParameterCommand, SSMClient } from "@aws-sdk/client-ssm"; -import { - SecretsManagerClient, - GetSecretValueCommand, -} from "@aws-sdk/client-secrets-manager"; +import { SecretsManagerClient, GetSecretValueCommand } from "@aws-sdk/client-secrets-manager"; const stage = process.env.STAGE_NAME || "main"; const deploymentConfig = JSON.parse( diff --git a/test/e2e/utils/setup.ts b/test/e2e/utils/setup.ts index 6d87ffec84..769341bf11 100644 --- a/test/e2e/utils/setup.ts +++ b/test/e2e/utils/setup.ts @@ -3,10 +3,7 @@ import { test as setup } from "@playwright/test"; import { testUsers } from "./users"; import { LoginPage } from "../pages"; import { GetParameterCommand, SSMClient } from "@aws-sdk/client-ssm"; -import { - SecretsManagerClient, - GetSecretValueCommand, -} from "@aws-sdk/client-secrets-manager"; +import { SecretsManagerClient, GetSecretValueCommand } from "@aws-sdk/client-secrets-manager"; import { fromEnv } from "@aws-sdk/credential-providers"; const stage = process.env.STAGE_NAME || "brain"; diff --git a/vitest.config.ts b/vitest.config.ts index 3a81640c05..b1518d5c67 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -17,6 +17,7 @@ export default defineConfig({ ".cdk", "docs/**", "lib/libs/webforms/**", + "lib/libs/email/mock-data/**", "react-app/src/features/webforms/**", "TestWrapper.tsx", "lib/stacks/**",