Skip to content

Commit

Permalink
Merge branch 'webforms' into oy2-26378
Browse files Browse the repository at this point in the history
  • Loading branch information
daniel-belcher committed Nov 28, 2023
2 parents de40297 + 468e0e6 commit b3400a4
Show file tree
Hide file tree
Showing 34 changed files with 259 additions and 312 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,26 @@ import {
FieldValues,
RegisterOptions,
} from "react-hook-form";
import type { ReactElement } from "react";
import {
CalendarProps,
InputProps,
RadioProps,
SelectProps,
SwitchProps,
TextareaProps,
SelectProps,
RadioProps,
CalendarProps,
} from "../Inputs";
} from "shared-types";

export interface FormSchema {
header: string;
sections: Section[];
}

export type RHFSlotProps = {
name: string;
label?: ReactElement | string;
label?: string;
labelStyling?: string;
groupNamePrefix?: string;
description?: ReactElement | string;
description?: string;
dependency?: DependencyRule;
rules?: RegisterOptions;
} & {
Expand All @@ -43,8 +47,8 @@ export type RHFOption = {

export type RHFComponentMap = {
Input: InputProps & {
label?: ReactElement | string;
description?: ReactElement | string;
label?: string;
description?: string;
};
Textarea: TextareaProps;
Switch: SwitchProps;
Expand Down
2 changes: 2 additions & 0 deletions src/packages/shared-types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ export * from "./opensearch";
export * from "./uploads";
export * from "./actions";
export * from "./action-types/withdraw-record";
export * from "./forms";
export * from "./inputs";
45 changes: 45 additions & 0 deletions src/packages/shared-types/inputs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { DayPicker } from "react-day-picker";
import * as RadioGroupPrimitive from "@radix-ui/react-radio-group";
import * as SwitchPrimitives from "@radix-ui/react-switch";
import * as SelectPrimitive from "@radix-ui/react-select";

export type CalendarProps = React.ComponentProps<typeof DayPicker> & {
className?: string;
classNames?: any;
showOutsideDays?: boolean;
};

export type DatePickerProps = {
date: Date | undefined;
onChange: (date: Date | undefined) => void;
};

export interface InputProps
extends React.InputHTMLAttributes<HTMLInputElement> {
icon?: string;
}

export type RadioProps = React.ComponentPropsWithoutRef<
typeof RadioGroupPrimitive.Root
> & {
className?: string;
};

export type SelectProps = React.ComponentPropsWithoutRef<
typeof SelectPrimitive.Root
> & {
options: { label: string; value: any }[];
className?: string;
};

export type SwitchProps = React.ComponentPropsWithoutRef<
typeof SwitchPrimitives.Root
> & {
className?: string;
};

export interface TextareaProps
extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
charcount?: "simple" | "limited";
charcountstyling?: string;
}
72 changes: 51 additions & 21 deletions src/services/api/handlers/forms.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { response } from "../libs/handler";

import * as fs from "fs";
import { APIGatewayEvent } from "aws-lambda";

export const forms = async (event: APIGatewayEvent) => {
try {
const formId = event.queryStringParameters.formId;
const formVersion = event.queryStringParameters.formVersion;
const formId = event.queryStringParameters?.formId?.toLocaleUpperCase();
let formVersion = event.queryStringParameters?.formVersion;

if (!formId) {
return response({
Expand All @@ -16,40 +15,61 @@ export const forms = async (event: APIGatewayEvent) => {
}

const filePath = getFilepathForIdAndVersion(formId, formVersion);

if (!filePath) {
return response({
statusCode: 404,
body: JSON.stringify({
error: "No file was found with provided formId and formVersion",
}),
});
}

const jsonData = await fs.promises.readFile(filePath, "utf-8");

if (!jsonData) {
return response({
statusCode: 404,
body: JSON.stringify({
error: "No file was found with provided formId and formVersion",
error: `File found for ${formId}, but it's empty`,
}),
});
}

if (!formVersion) formVersion = getMaxVersion(formId);

try {
const formObj = await import(`/opt/${formId}/v${formVersion}.js`);

if (formObj?.form) {
return response({
statusCode: 200,
body: formObj.form,
});
}
} catch (importError) {
console.error("Error importing module:", importError);
return response({
statusCode: 500,
body: JSON.stringify({
error: importError.message
? importError.message
: "Internal server error",
}),
});
}
console.log(jsonData);
return response({
statusCode: 200,
body: jsonData,
});
} catch (error) {
console.error("Error:", error);
return response({
statusCode: 500,
statusCode: 502,
body: JSON.stringify({
error: error.message ? error.message : "Internal server error",
}),
});
}
};

export function getFilepathForIdAndVersion(
formId: string,
formVersion: string | undefined
): string | undefined {
if (formId && formVersion) {
return `/opt/${formId}/v${formVersion}.json`;
}

export function getMaxVersion(formId: string) {
const files = fs.readdirSync(`/opt/${formId}`);
if (!files) return undefined;
const versionNumbers = files?.map((fileName: string) => {
Expand All @@ -59,11 +79,21 @@ export function getFilepathForIdAndVersion(
}
return 1;
});
const maxVersion = Math.max(...versionNumbers);
return Math.max(...versionNumbers).toString();
}

if (!maxVersion) return undefined;
export function getFilepathForIdAndVersion(
formId: string,
formVersion: string | undefined
): string | undefined {
if (formId && formVersion) {
return `/opt/${formId}/v${formVersion}.js`;
}

return `/opt/${formId}/v${maxVersion}.json`;
const maxVersion = getMaxVersion(formId);

if (!maxVersion) return undefined;
return `/opt/${formId}/v${maxVersion}.js`;
}

export const handler = forms;
34 changes: 17 additions & 17 deletions src/services/api/handlers/tests/forms.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ describe("Forms Lambda Tests", () => {
} as APIGatewayProxyEvent;
const result = await forms(event);

expect(result.statusCode).toBe(400);
expect(JSON.parse(result.body)).toEqual({
expect(result?.statusCode).toBe(400);
expect(JSON.parse(result?.body as string)).toEqual({
error: "File ID was not provided",
});
});
Expand All @@ -22,9 +22,9 @@ describe("Forms Lambda Tests", () => {
} as APIGatewayProxyEvent;
const result = await forms(event);

expect(result.statusCode).toBe(500);
expect(JSON.parse(result.body)).toEqual({
error: "ENOENT: no such file or directory, open '/opt/test/v1.json'",
expect(result?.statusCode).toBe(500);
expect(JSON.parse(result?.body as string)).toEqual({
error: "ENOENT: no such file or directory, open '/opt/test/v1.js'",
});
});

Expand All @@ -38,8 +38,8 @@ describe("Forms Lambda Tests", () => {
} as APIGatewayProxyEvent;
const result = await forms(event);

expect(result.statusCode).toBe(200);
expect(result.headers["Content-Type"]).toBe("application/json");
expect(result?.statusCode).toBe(200);
expect(result?.headers["Content-Type"]).toBe("application/json");
});

it("should return 500 with a custom error message for other internal errors", async () => {
Expand All @@ -53,19 +53,19 @@ describe("Forms Lambda Tests", () => {

const result = await forms(event);

expect(result.statusCode).toBe(500);
expect(JSON.parse(result.body)).toEqual({
expect(result?.statusCode).toBe(500);
expect(JSON.parse(result?.body as string)).toEqual({
error: "Internal Server Error Message",
});
});

it("should return the correct JSON data for different file versions", async () => {
vi.spyOn(fs.promises, "readFile").mockImplementation(async (filePath) => {
const filePathString = filePath.toString();
if (filePathString.includes("/opt/testform/v1.json")) {
return JSON.stringify({ version: "1", data: "v1 data" });
} else if (filePathString.includes("/opt/testform/v2.json")) {
return JSON.stringify({ version: "2", data: "v2 data" });
if (filePathString.includes("/opt/testform/v1.js")) {
return Buffer.from(JSON.stringify({ version: "1", data: "v1 data" }));
} else {
return Buffer.from(JSON.stringify({ version: "2", data: "v2 data" }));
}
});

Expand All @@ -79,14 +79,14 @@ describe("Forms Lambda Tests", () => {
const resultV1 = await forms(eventV1);
const resultV2 = await forms(eventV2);

expect(resultV1.statusCode).toBe(200);
expect(resultV2.statusCode).toBe(200);
expect(resultV1?.statusCode).toBe(200);
expect(resultV2?.statusCode).toBe(200);

expect(JSON.parse(resultV1.body)).toEqual({
expect(JSON.parse(resultV1?.body as string)).toEqual({
version: "1",
data: "v1 data",
});
expect(JSON.parse(resultV2.body)).toEqual({
expect(JSON.parse(resultV2?.body as string)).toEqual({
version: "2",
data: "v2 data",
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Document } from "@/components/RHF/types";
import { FormSchema } from "shared-types";

export const ABP1: Document = {
const ABP1: FormSchema = {
header: "ABP 1: Alternative Benefit Plan populations",
sections: [
{
Expand Down Expand Up @@ -1319,3 +1319,5 @@ export const ABP1: Document = {
// },
],
};

export const form = ABP1;
32 changes: 0 additions & 32 deletions src/services/api/layers/testform/v1.json

This file was deleted.

32 changes: 0 additions & 32 deletions src/services/api/layers/testform/v2.json

This file was deleted.

1 change: 1 addition & 0 deletions src/services/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
},
"version": "0.0.0",
"scripts": {
"build": "tsc",
"lint": "eslint '**/*.{ts,js}'"
}
}
Loading

0 comments on commit b3400a4

Please sign in to comment.