diff --git a/mocks/data/items.ts b/mocks/data/items.ts index 78756ace8b..cd377c82f9 100644 --- a/mocks/data/items.ts +++ b/mocks/data/items.ts @@ -515,4 +515,18 @@ export const TEST_TEMP_EXT_ITEM = items[ EXISTING_ITEM_TEMPORARY_EXTENSION_ID ] as opensearch.main.ItemResult; +export const itemList = Object.values(items); + +export const getFilteredItemList = (filters: string[]) => { + return itemList.filter((item) => filters.includes(item?._source?.authority || "")); +}; + +export const docList = Object.values(items).map( + (item) => (item?._source || {}) as opensearch.main.Document, +); + +export const getFilteredDocList = (filters: string[]) => { + return docList.filter((item) => filters.includes(item?.authority || "")); +}; + export default items; diff --git a/mocks/handlers/api/search.ts b/mocks/handlers/api/search.ts index d1a51c0767..cbc80f5f72 100644 --- a/mocks/handlers/api/search.ts +++ b/mocks/handlers/api/search.ts @@ -1,12 +1,23 @@ -import { http, HttpResponse } from "msw"; -import { cpocsList } from "../../data/cpocs"; +import { http, HttpResponse, PathParams } from "msw"; +import { getFilteredItemList } from "../../data/items"; +import { getFilterValueAsStringArray } from "../search.utils"; +import { SearchQueryBody } from "../../index.d"; -const defaultApiSearchHandler = http.post( +const defaultApiSearchHandler = http.post( "https://test-domain.execute-api.us-east-1.amazonaws.com/mocked-tests/search/:index", - ({ params }) => { + async ({ params, request }) => { const { index } = params; + const { query } = await request.json(); + + const must = query?.bool?.must; + + if (index === "main") { + const authorityValues = + getFilterValueAsStringArray(must, "terms", "authority.keyword") || + getFilterValueAsStringArray(must, "terms", "authority") || + []; + const itemList = getFilteredItemList(authorityValues); - if (index === "cpocs") { return HttpResponse.json({ took: 3, timed_out: false, @@ -22,7 +33,7 @@ const defaultApiSearchHandler = http.post( relation: "eq", }, max_score: 1, - hits: cpocsList, + hits: itemList, }, }); } diff --git a/mocks/handlers/search.utils.ts b/mocks/handlers/search.utils.ts index 608a7b2e13..9290c7ea03 100644 --- a/mocks/handlers/search.utils.ts +++ b/mocks/handlers/search.utils.ts @@ -109,6 +109,38 @@ const parseValueAsNumberArray = (value: string | string[] | undefined): number[] ); }; +export const getFilterValueAsString = ( + query: QueryContainer | QueryContainer[] | undefined, + queryKey: keyof QueryContainer, + filterName: string, +): string | undefined => { + const value = getFilterValue(query, queryKey, filterName); + + return parseValueAsStringArray(value).join(","); +}; + +export const getFilterValueAsStringArray = ( + query: QueryContainer | QueryContainer[] | undefined, + queryKey: keyof QueryContainer, + filterName: string, +): string[] => { + const value = getFilterValue(query, queryKey, filterName); + + return parseValueAsStringArray(value); +}; + +const parseValueAsStringArray = (value: string | string[] | undefined): string[] => { + if (value == undefined) { + return []; + } + + if (typeof value === "string") { + return value.split(",").map((val) => val.trim()); + } + + return value.filter((val) => val && typeof val === "string").map((val) => val.trim()) || []; +}; + export const getTermValues = ( query: QueryContainer | QueryContainer[] | undefined, filterName: string, diff --git a/react-app/src/api/useSearch.test.ts b/react-app/src/api/useSearch.test.ts index c412d53ea7..fa4a2d4216 100644 --- a/react-app/src/api/useSearch.test.ts +++ b/react-app/src/api/useSearch.test.ts @@ -1,21 +1,21 @@ import { describe, expect, it } from "vitest"; -import { getOsData } from "./useSearch"; -import { cpocsList } from "mocks/data/cpocs"; +import { getMainExportData } from "./useSearch"; +import { DEFAULT_FILTERS } from "@/components/Opensearch/main/useOpensearch"; +import { getFilteredDocList } from "mocks/data/items"; -describe("getOsData tests", () => { - it("should return cpocs", async () => { - const results = await getOsData({ - index: "cpocs", - sort: { - field: "lastName", - order: "asc", - }, - pagination: { - number: 0, - size: 20, - }, - filters: [], - }); - expect(results.hits.hits).toEqual(cpocsList); +describe("getMainExportData tests", () => { + it("should return spa items", async () => { + const results = await getMainExportData(DEFAULT_FILTERS.spas.filters); + expect(results).toEqual(getFilteredDocList(["Medicaid SPA", "CHIP SPA"])); + }); + + it("should return waiver items", async () => { + const results = await getMainExportData(DEFAULT_FILTERS.waivers.filters); + expect(results).toEqual(getFilteredDocList(["1915(b)", "1915(c)"])); + }); + + it("should return an empty array if there are no filters", async () => { + const results = await getMainExportData(); + expect(results).toEqual([]); }); }); diff --git a/react-app/src/components/Opensearch/utils.test.ts b/react-app/src/components/Opensearch/utils.test.ts new file mode 100644 index 0000000000..f6b701fa68 --- /dev/null +++ b/react-app/src/components/Opensearch/utils.test.ts @@ -0,0 +1,688 @@ +import { describe, expect, it } from "vitest"; +import { + filterQueryBuilder, + paginationQueryBuilder, + sortQueryBuilder, + aggQueryBuilder, + createSearchFilterable, + checkMultiFilter, +} from "./utils"; + +describe("Opensearch utils tests", () => { + describe("filterQueryBuilder tests", () => { + it("should handle undefined filters", () => { + const results = filterQueryBuilder(undefined); + expect(results).toEqual({}); + }); + it("should handle null filters", () => { + const results = filterQueryBuilder(null); + expect(results).toEqual({}); + }); + it("should handle empty filters", () => { + const results = filterQueryBuilder([]); + expect(results).toEqual({}); + }); + it("should handle exists filter without a value", () => { + const results = filterQueryBuilder([ + // @ts-expect-error + { + type: "exists", + prefix: "must", + field: "origin", + }, + ]); + expect(results).toEqual({ + query: { + bool: { + must: [{ exists: { field: "origin" } }], + must_not: [], + should: [], + filter: [], + }, + }, + }); + }); + it("should handle an invalid prefix", () => { + const result = filterQueryBuilder([ + { + // @ts-expect-error + type: "mismatch", + prefix: "must", + field: "authority.keyword", + value: ["Medicaid SPA", "CHIP SPA"], + }, + ]); + expect(result).toEqual({ + query: { + bool: { + must: [], + must_not: [], + should: [], + filter: [], + }, + }, + }); + }); + it.each([["terms"], ["term"], ["range"], ["global_search"]])( + "should handle %s filter without a value", + (type) => { + const results = filterQueryBuilder([ + { + // @ts-expect-error + type, + prefix: "must", + field: "authority.keyword", + }, + ]); + expect(results).toEqual({ + query: { + bool: { + must: [], + must_not: [], + should: [], + filter: [], + }, + }, + }); + }, + ); + it("should handle match filter with a false value", () => { + const results = filterQueryBuilder([ + { + type: "match", + prefix: "must", + field: "authority.keyword", + value: false, + }, + ]); + expect(results).toEqual({ + query: { + bool: { + must: [{ match: { "authority.keyword": false } }], + must_not: [], + should: [], + filter: [], + }, + }, + }); + }); + it.each([ + [ + "terms", + "authority.keyword", + ["Medicaid SPA", "CHIP SPA"], + [{ terms: { "authority.keyword": ["Medicaid SPA", "CHIP SPA"] } }], + ], + ["term", "state", "MD", [{ term: { state: "MD" } }]], + ["exists", "origin", "OneMAC", [{ exists: { field: "origin" } }]], + [ + "range", + "timestamp", + ["1677715190000", "1677715210000"], + [{ range: { timestamp: ["1677715190000", "1677715210000"] } }], + ], + ])("should handle must %s filters", (type, field, value, expected) => { + const results = filterQueryBuilder([ + { + // @ts-expect-error + type, + prefix: "must", + field, + value, + }, + ]); + expect(results).toEqual({ + query: { + bool: { + must: expected, + must_not: [], + should: [], + filter: [], + }, + }, + }); + }); + it("should handle a global_search filter", () => { + const results = filterQueryBuilder([ + { + type: "global_search", + prefix: "must", + field: "authority", + value: " CHIP SPA ", + }, + ]); + expect(results).toEqual({ + query: { + bool: { + must: [ + { + dis_max: { + tie_breaker: 0.7, + boost: 1.2, + queries: [ + { + wildcard: { + "id.keyword": { + value: "*CHIP SPA*", + case_insensitive: true, + }, + }, + }, + { + wildcard: { + "submitterName.keyword": { + value: "*CHIP SPA*", + case_insensitive: true, + }, + }, + }, + { + wildcard: { + "leadAnalystName.keyword": { + value: "*CHIP SPA*", + case_insensitive: true, + }, + }, + }, + ], + }, + }, + ], + must_not: [], + should: [], + filter: [], + }, + }, + }); + }); + it("should handle multiple filters", () => { + const results = filterQueryBuilder([ + { + type: "terms", + prefix: "must", + field: "authority.keyword", + value: ["Medicaid SPA", "CHIP SPA"], + }, + { + type: "term", + prefix: "must_not", + field: "state", + value: "MD", + }, + // @ts-expect-error + { + type: "exists", + prefix: "should", + field: "origin", + }, + { + type: "range", + prefix: "filter", + field: "timestamp", + value: ["1677715190000", "1677715210000"], + }, + { + type: "global_search", + prefix: "must", + field: "authority", + value: " CHIP SPA ", + }, + ]); + expect(results).toEqual({ + query: { + bool: { + must: [ + { terms: { "authority.keyword": ["Medicaid SPA", "CHIP SPA"] } }, + { + dis_max: { + tie_breaker: 0.7, + boost: 1.2, + queries: [ + { + wildcard: { + "id.keyword": { + value: "*CHIP SPA*", + case_insensitive: true, + }, + }, + }, + { + wildcard: { + "submitterName.keyword": { + value: "*CHIP SPA*", + case_insensitive: true, + }, + }, + }, + { + wildcard: { + "leadAnalystName.keyword": { + value: "*CHIP SPA*", + case_insensitive: true, + }, + }, + }, + ], + }, + }, + ], + must_not: [{ term: { state: "MD" } }], + should: [{ exists: { field: "origin" } }], + filter: [{ range: { timestamp: ["1677715190000", "1677715210000"] } }], + }, + }, + }); + }); + }); + + describe("paginationQueryBuilder tests", () => { + it("should handle an undefined pagination", () => { + const result = paginationQueryBuilder(undefined); + expect(result).toEqual({}); + }); + it("should handle a null pagination", () => { + const result = paginationQueryBuilder(null); + expect(result).toEqual({}); + }); + it("should handle an empty pagination", () => { + // @ts-expect-error + const result = paginationQueryBuilder({}); + expect(result).toEqual({ + from: 0, + size: 25, + }); + }); + it("should handle an undefined number", () => { + // @ts-expect-error + const result = paginationQueryBuilder({ size: 20 }); + expect(result).toEqual({ + from: 0, + size: 20, + }); + }); + it("should handle 0 number", () => { + const result = paginationQueryBuilder({ number: 0, size: 20 }); + expect(result).toEqual({ + from: 0, + size: 20, + }); + }); + it("should handle a negative number", () => { + const result = paginationQueryBuilder({ number: -3, size: 20 }); + expect(result).toEqual({ + from: 0, + size: 20, + }); + }); + it("should handle an undefined size", () => { + // @ts-expect-error + const result = paginationQueryBuilder({ number: 1 }); + expect(result).toEqual({ + from: 0, + size: 25, + }); + }); + it("should handle 0 size", () => { + const result = paginationQueryBuilder({ number: 1, size: 0 }); + expect(result).toEqual({ + from: 0, + size: 25, + }); + }); + it("should handle a negative size", () => { + const result = paginationQueryBuilder({ number: 1, size: -3 }); + expect(result).toEqual({ + from: 0, + size: 25, + }); + }); + it("should handle a valid number and size", () => { + const result = paginationQueryBuilder({ number: 2, size: 20 }); + expect(result).toEqual({ + from: 40, + size: 20, + }); + }); + }); + + describe("sortQueryBuilder tests", () => { + it("should handle an undefined sort", () => { + const result = sortQueryBuilder(undefined); + expect(result).toEqual({}); + }); + it("should handle a null sort", () => { + const result = sortQueryBuilder(null); + expect(result).toEqual({}); + }); + it("should handle an empty sort", () => { + // @ts-expect-error + const result = sortQueryBuilder({}); + expect(result).toEqual({}); + }); + it("should handle an undefined field", () => { + // @ts-expect-error + const result = sortQueryBuilder({ order: "asc" }); + expect(result).toEqual({}); + }); + it("should handle a null field", () => { + const result = sortQueryBuilder({ field: null, order: "asc" }); + expect(result).toEqual({}); + }); + it("should handle an undefined order", () => { + // @ts-expect-error + const result = sortQueryBuilder({ field: "test" }); + expect(result).toEqual({ sort: [{ test: "asc" }] }); + }); + it("should handle a null field", () => { + const result = sortQueryBuilder({ field: "test", order: null }); + expect(result).toEqual({ sort: [{ test: "asc" }] }); + }); + it("should handle a valid sort", () => { + const result = sortQueryBuilder({ field: "test", order: "desc" }); + expect(result).toEqual({ sort: [{ test: "desc" }] }); + }); + }); + + describe("aggQueryBuilder tests", () => { + it("should handle an undefined aggregation", () => { + const result = aggQueryBuilder(undefined); + expect(result).toEqual({}); + }); + it("should handle a null aggregation", () => { + const result = aggQueryBuilder(null); + expect(result).toEqual({}); + }); + it("should handle an empty aggregation", () => { + const result = aggQueryBuilder([]); + expect(result).toEqual({}); + }); + it("should handle an aggregation with an undefined name", () => { + const result = aggQueryBuilder([ + // @ts-expect-error + { + type: "term", + field: "authority.keyword", + size: 25, + }, + ]); + expect(result).toEqual({ + aggs: {}, + }); + }); + it("should handle an aggregation with an undefined type", () => { + const result = aggQueryBuilder([ + // @ts-expect-error + { + name: "must", + field: "authority.keyword", + size: 25, + }, + ]); + expect(result).toEqual({ + aggs: {}, + }); + }); + it("should handle an aggregation with an undefined field", () => { + const result = aggQueryBuilder([ + // @ts-expect-error + { + name: "must", + type: "term", + size: 25, + }, + ]); + expect(result).toEqual({ + aggs: {}, + }); + }); + it("should handle an aggregation with an undefined size", () => { + const result = aggQueryBuilder([ + // @ts-expect-error + { + name: "must", + type: "term", + field: "authority.keyword", + }, + ]); + expect(result).toEqual({ + aggs: { + must: { + term: { + field: "authority.keyword", + order: { _term: "asc" }, + }, + }, + }, + }); + }); + it("should handle an aggregation with one definition", () => { + const result = aggQueryBuilder([ + { + name: "must", + type: "term", + field: "authority.keyword", + size: 50, + }, + ]); + expect(result).toEqual({ + aggs: { + must: { + term: { + field: "authority.keyword", + order: { _term: "asc" }, + size: 50, + }, + }, + }, + }); + }); + it("should handle an aggregation with multiple definitions", () => { + const result = aggQueryBuilder([ + // @ts-expect-error + { + name: "must", + type: "terms", + field: "state", + }, + { + name: "must_not", + type: "match", + field: "origin", + size: 40, + }, + ]); + expect(result).toEqual({ + aggs: { + must: { + terms: { + field: "state", + order: { _term: "asc" }, + }, + }, + must_not: { + match: { + field: "origin", + order: { _term: "asc" }, + size: 40, + }, + }, + }, + }); + }); + it("should overwrite aggregations with the same name and type", () => { + const result = aggQueryBuilder([ + // @ts-expect-error + { + name: "must", + type: "terms", + field: "state", + }, + { + name: "must", + type: "terms", + field: "origin", + size: 40, + }, + ]); + expect(result).toEqual({ + aggs: { + must: { + terms: { + field: "origin", + order: { _term: "asc" }, + size: 40, + }, + }, + }, + }); + }); + it("should over aggregations with the same name and different types", () => { + const result = aggQueryBuilder([ + // @ts-expect-error + { + name: "must", + type: "terms", + field: "state", + }, + { + name: "must", + type: "match", + field: "origin", + size: 40, + }, + ]); + expect(result).toEqual({ + aggs: { + must: { + match: { + field: "origin", + order: { _term: "asc" }, + size: 40, + }, + }, + }, + }); + }); + }); + + describe("createSearchFilterable tests", () => { + it("should handle an undefined value", () => { + const result = createSearchFilterable(undefined); + expect(result).toEqual([]); + }); + it("should handle a null value", () => { + const result = createSearchFilterable(null); + expect(result).toEqual([]); + }); + it("should handle an empty value", () => { + const result = createSearchFilterable(""); + expect(result).toEqual([]); + }); + it("should handle a value", () => { + const result = createSearchFilterable("test"); + expect(result).toEqual([ + { + type: "global_search", + field: "", + value: "test", + prefix: "must", + }, + ]); + }); + }); + + describe("checkMultiFilter tests", () => { + it("should return true undefined filters and undefined val", () => { + const result = checkMultiFilter(undefined, undefined); + expect(result).toBe(true); + }); + it("should return true for equal filters and val", () => { + const result = checkMultiFilter( + [ + { + prefix: "must", + type: "terms", + field: "authority.keyword", + value: ["Medicaid SPA", "CHIP SPA"], + }, + ], + 1, + ); + expect(result).toBe(true); + }); + it("should return true for more filters than val", () => { + const result = checkMultiFilter( + [ + { + prefix: "must", + type: "terms", + field: "authority.keyword", + value: ["Medicaid SPA", "CHIP SPA"], + }, + { + prefix: "must", + type: "exists", + field: "origin", + value: true, + }, + ], + 1, + ); + expect(result).toBe(true); + }); + it("should return true for more filter values than val", () => { + const result = checkMultiFilter( + [ + { + prefix: "must", + type: "terms", + field: "authority.keyword", + value: ["Medicaid SPA", "CHIP SPA", "1915(b)", "1915(c)"], + }, + { + prefix: "must", + type: "exists", + field: "origin", + value: true, + }, + ], + 3, + ); + expect(result).toBe(true); + }); + it("should return false for less filters than val", () => { + const result = checkMultiFilter( + [ + { + prefix: "must", + type: "terms", + field: "authority.keyword", + value: ["Medicaid SPA", "CHIP SPA"], + }, + { + prefix: "must", + type: "exists", + field: "origin", + value: true, + }, + ], + 4, + ); + expect(result).toBe(false); + }); + it("should return false for filter values less than val", () => { + const result = checkMultiFilter( + [ + { + prefix: "must", + type: "terms", + field: "authority.keyword", + value: ["Medicaid SPA"], + }, + ], + 2, + ); + expect(result).toBe(false); + }); + }); +}); diff --git a/react-app/src/components/Opensearch/utils.ts b/react-app/src/components/Opensearch/utils.ts index bc73ea90c3..d0e20443e6 100644 --- a/react-app/src/components/Opensearch/utils.ts +++ b/react-app/src/components/Opensearch/utils.ts @@ -4,6 +4,14 @@ const filterMapQueryReducer = ( state: Record["prefix"], any[]>, filter: opensearch.Filterable, ) => { + if (filter.type === "exists") { + state[filter.prefix].push({ + exists: { field: filter.field }, + }); + } + + if (filter.value === undefined || filter.value == null) return state; + // this was hoisted up since false is a valid "match" value if (filter.type === "match") { state[filter.prefix].push({ @@ -25,12 +33,6 @@ const filterMapQueryReducer = ( }); } - if (filter.type === "exists") { - state[filter.prefix].push({ - exists: { field: filter.field }, - }); - } - if (filter.type === "range") { state[filter.prefix].push({ range: { [filter.field]: filter.value }, @@ -38,7 +40,6 @@ const filterMapQueryReducer = ( } if (filter.type === "global_search") { - if (!filter.value) return state; state[filter.prefix].push({ dis_max: { tie_breaker: 0.7, @@ -74,31 +75,45 @@ export const filterQueryBuilder = (filters: opensearch.Filterable[]) => { }; export const paginationQueryBuilder = (pagination: opensearch.QueryState["pagination"]) => { + if (!pagination) return {}; + const from = (() => { - if (!pagination.number) return 0; + if ( + !pagination?.number || + !pagination?.size || + pagination?.number < 1 || + pagination?.size < 1 + ) { + return 0; + } return pagination.number * pagination.size; })(); return { - size: pagination.size, + size: pagination?.size && pagination?.size > 0 ? pagination?.size : 25, from, }; }; export const sortQueryBuilder = (sort: opensearch.QueryState["sort"]) => { - return { sort: [{ [sort.field]: sort.order }] }; + if (!sort?.field) return {}; + return { sort: [{ [sort.field]: sort.order || "asc" }] }; }; export const aggQueryBuilder = (aggs: opensearch.AggQuery[]) => { + if (!aggs?.length) return {}; + return { aggs: aggs.reduce((STATE, AGG) => { - STATE[AGG.name] = { - [AGG.type]: { - field: AGG.field, - order: { _term: "asc" }, - ...(AGG.size && { size: AGG.size }), - }, - }; + if (AGG?.name && AGG?.type && AGG?.field) { + STATE[AGG.name] = { + [AGG.type]: { + field: AGG.field, + order: { _term: "asc" }, + ...(AGG.size && { size: AGG.size }), + }, + }; + } return STATE; }, {} as any), }; @@ -116,7 +131,7 @@ export const createSearchFilterable = (value?: string) => { ]; }; -export const checkMultiFilter = (filters: opensearch.Filterable[], val: number) => { +export const checkMultiFilter = (filters: opensearch.Filterable[] = [], val: number = 0) => { return ( filters.length >= val || filters.some((filter) => Array.isArray(filter.value) && filter.value.length >= val) diff --git a/react-app/src/features/forms/post-submission/toggle-withdraw-rai/__snapshots__/index.test.tsx.snap b/react-app/src/features/forms/post-submission/toggle-withdraw-rai/__snapshots__/index.test.tsx.snap new file mode 100644 index 0000000000..914c34bc0b --- /dev/null +++ b/react-app/src/features/forms/post-submission/toggle-withdraw-rai/__snapshots__/index.test.tsx.snap @@ -0,0 +1,851 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`Toggle Withdraw Rai components > renders disable withdraw rai correctly 1`] = ` +{ + "asFragment": [Function], + "baseElement": +
+
+ +
+
+

+ Enable Formal RAI Response Withdraw Details +

+
+
+
+
+ Once you submit this form, the most recent Formal RAI Response for this package will be able to be withdrawn by the state +
+
+
+
+

+ Waiver Number +

+

+ VA-2234.R11.02 +

+
+
+

+ Authority +

+

+ 1915(b) Waiver +

+
+
+
+
+
+ + +
+
+ +
+ , +
+ , + "container":
+
+ +
+
+

+ Enable Formal RAI Response Withdraw Details +

+
+
+
+
+ Once you submit this form, the most recent Formal RAI Response for this package will be able to be withdrawn by the state +
+
+
+
+

+ Waiver Number +

+

+ VA-2234.R11.02 +

+
+
+

+ Authority +

+

+ 1915(b) Waiver +

+
+
+
+
+
+ + +
+
+ +
+ , +
, + "debug": [Function], + "findAllByAltText": [Function], + "findAllByDisplayValue": [Function], + "findAllByLabelText": [Function], + "findAllByPlaceholderText": [Function], + "findAllByRole": [Function], + "findAllByTestId": [Function], + "findAllByText": [Function], + "findAllByTitle": [Function], + "findByAltText": [Function], + "findByDisplayValue": [Function], + "findByLabelText": [Function], + "findByPlaceholderText": [Function], + "findByRole": [Function], + "findByTestId": [Function], + "findByText": [Function], + "findByTitle": [Function], + "getAllByAltText": [Function], + "getAllByDisplayValue": [Function], + "getAllByLabelText": [Function], + "getAllByPlaceholderText": [Function], + "getAllByRole": [Function], + "getAllByTestId": [Function], + "getAllByText": [Function], + "getAllByTitle": [Function], + "getByAltText": [Function], + "getByDisplayValue": [Function], + "getByLabelText": [Function], + "getByPlaceholderText": [Function], + "getByRole": [Function], + "getByTestId": [Function], + "getByText": [Function], + "getByTitle": [Function], + "queryAllByAltText": [Function], + "queryAllByDisplayValue": [Function], + "queryAllByLabelText": [Function], + "queryAllByPlaceholderText": [Function], + "queryAllByRole": [Function], + "queryAllByTestId": [Function], + "queryAllByText": [Function], + "queryAllByTitle": [Function], + "queryByAltText": [Function], + "queryByDisplayValue": [Function], + "queryByLabelText": [Function], + "queryByPlaceholderText": [Function], + "queryByRole": [Function], + "queryByTestId": [Function], + "queryByText": [Function], + "queryByTitle": [Function], + "rerender": [Function], + "unmount": [Function], +} +`; + +exports[`Toggle Withdraw Rai components > renders disable withdraw rai correctly 2`] = ` +{ + "asFragment": [Function], + "baseElement": +
+
+ +
+
+

+ Disable Formal RAI Response Withdraw Details +

+
+
+
+
+ The state will not be able to withdraw its RAI response. It may take up to a minute for this change to be applied. +
+
+
+
+

+ Waiver Number +

+

+ VA-2234.R11.02 +

+
+
+

+ Authority +

+

+ 1915(b) Waiver +

+
+
+
+
+
+ + +
+
+ +
+ , +
+ , + "container":
+
+ +
+
+

+ Disable Formal RAI Response Withdraw Details +

+
+
+
+
+ The state will not be able to withdraw its RAI response. It may take up to a minute for this change to be applied. +
+
+
+
+

+ Waiver Number +

+

+ VA-2234.R11.02 +

+
+
+

+ Authority +

+

+ 1915(b) Waiver +

+
+
+
+
+
+ + +
+
+ +
+ , +
, + "debug": [Function], + "findAllByAltText": [Function], + "findAllByDisplayValue": [Function], + "findAllByLabelText": [Function], + "findAllByPlaceholderText": [Function], + "findAllByRole": [Function], + "findAllByTestId": [Function], + "findAllByText": [Function], + "findAllByTitle": [Function], + "findByAltText": [Function], + "findByDisplayValue": [Function], + "findByLabelText": [Function], + "findByPlaceholderText": [Function], + "findByRole": [Function], + "findByTestId": [Function], + "findByText": [Function], + "findByTitle": [Function], + "getAllByAltText": [Function], + "getAllByDisplayValue": [Function], + "getAllByLabelText": [Function], + "getAllByPlaceholderText": [Function], + "getAllByRole": [Function], + "getAllByTestId": [Function], + "getAllByText": [Function], + "getAllByTitle": [Function], + "getByAltText": [Function], + "getByDisplayValue": [Function], + "getByLabelText": [Function], + "getByPlaceholderText": [Function], + "getByRole": [Function], + "getByTestId": [Function], + "getByText": [Function], + "getByTitle": [Function], + "queryAllByAltText": [Function], + "queryAllByDisplayValue": [Function], + "queryAllByLabelText": [Function], + "queryAllByPlaceholderText": [Function], + "queryAllByRole": [Function], + "queryAllByTestId": [Function], + "queryAllByText": [Function], + "queryAllByTitle": [Function], + "queryByAltText": [Function], + "queryByDisplayValue": [Function], + "queryByLabelText": [Function], + "queryByPlaceholderText": [Function], + "queryByRole": [Function], + "queryByTestId": [Function], + "queryByText": [Function], + "queryByTitle": [Function], + "rerender": [Function], + "unmount": [Function], +} +`; diff --git a/react-app/src/features/forms/post-submission/toggle-withdraw-rai/index.test.tsx b/react-app/src/features/forms/post-submission/toggle-withdraw-rai/index.test.tsx new file mode 100644 index 0000000000..552afa0845 --- /dev/null +++ b/react-app/src/features/forms/post-submission/toggle-withdraw-rai/index.test.tsx @@ -0,0 +1,30 @@ +import { describe, expect, it, vi } from "vitest"; + +import { WITHDRAW_RAI_ITEM_B } from "mocks"; +import { EnableWithdrawRaiForm, DisableWithdrawRaiForm } from "."; +import { renderFormAsync } from "@/utils/test-helpers/renderForm"; + +vi.mock("react-router", async () => ({ + ...(await vi.importActual>("react-router")), + useParams: vi.fn().mockReturnValue({ authority: "1915(b)", id: WITHDRAW_RAI_ITEM_B }), +})); +vi.mock("shared-utils", async (importOriginal) => { + const actual = await importOriginal(); + return { + ...(typeof actual === "object" && actual !== null ? actual : {}), + isCmsUser: vi.fn().mockReturnValue(true), + }; +}); + +describe("Toggle Withdraw Rai components", () => { + it("renders disable withdraw rai correctly", async () => { + const container = renderFormAsync(); + + expect(await container).toMatchSnapshot(); + }); + it("renders disable withdraw rai correctly", async () => { + const container = renderFormAsync(); + + expect(await container).toMatchSnapshot(); + }); +}); diff --git a/react-app/src/features/forms/post-submission/withdraw-package/__snapshots__/indext.test.tsx.snap b/react-app/src/features/forms/post-submission/withdraw-package/__snapshots__/indext.test.tsx.snap new file mode 100644 index 0000000000..2fc5fae390 --- /dev/null +++ b/react-app/src/features/forms/post-submission/withdraw-package/__snapshots__/indext.test.tsx.snap @@ -0,0 +1,876 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`WithdrawPackageAction components > renders WithdrawPackageActionWaiver correctly 1`] = ` +{ + "asFragment": [Function], + "baseElement": +
+
+ +
+
+

+ Withdraw 1915(c) Appendix K +

+
+
+
+ + * + + + + Indicates a required field. + +
+ Complete this form to withdraw this 1915(c) Appendix K 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. +

+ If you leave this page, you will lose your progress on this form. +

+
+
+
+
+

+ Waiver Number +

+

+ VA-2234.R11.01 +

+
+
+

+ Authority +

+

+ 1915(c) Waiver +

+
+
+
+
+
+

+ Attachments + +

+
+
+
+

+ Upload your supporting documentation for withdrawal or explain your need for withdrawal in the Additional Information section. +

+
+

+ 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 + + . +

+
+

+ We accept the following file formats: + + + .doc, .docx, .pdf, .jpg, .xlsx, and more. + + + + See the full list + + . +

+
+
+
+ + +
+
+
+
+
+

+ Additional Information + +

+
+
+
+ +