From e84c8a15455eafdc0e9496f6a2dad4de46402113 Mon Sep 17 00:00:00 2001 From: SeSo Date: Fri, 9 Jun 2023 16:58:39 -0700 Subject: [PATCH 01/22] fix: add null and undefined values to optional fields in json schemas --- app/data/jsonSchemaForm/contactSchema.ts | 12 ++++--- app/data/jsonSchemaForm/projectSchema.ts | 25 +++++++++------ schema/data/prod/json_schema/contact.json | 28 +++++++++------- .../emission_intensity_report.json | 4 +-- schema/data/prod/json_schema/milestone.json | 32 +++++++++++-------- schema/data/prod/json_schema/operator.json | 10 +++--- schema/data/prod/json_schema/project.json | 25 +++++++++------ .../prod/json_schema/project_contact.json | 3 +- .../prod/json_schema/project_manager.json | 5 +-- .../json_schema/project_summary_report.json | 19 +++++++---- 10 files changed, 100 insertions(+), 63 deletions(-) diff --git a/app/data/jsonSchemaForm/contactSchema.ts b/app/data/jsonSchemaForm/contactSchema.ts index 69b3eb4e1d..35cbc25df1 100644 --- a/app/data/jsonSchemaForm/contactSchema.ts +++ b/app/data/jsonSchemaForm/contactSchema.ts @@ -23,20 +23,24 @@ const contactSchema = { "^(\\+?\\d{1,2}[\\s,-]?)?\\(?\\d{3}\\)?[\\s.-]?\\d{3}[\\s.-]?\\d{4}$", }, phoneExt: { - type: "string", + type: [null, "string"], title: "Phone Extension", + default: undefined, }, companyName: { - type: "string", + type: [null, "string"], title: "Company Name", + default: undefined, }, contactPosition: { - type: "string", + type: [null, "string"], title: "Position", + default: undefined, }, comments: { - type: "string", + type: [null, "string"], title: "Comments", + default: undefined, }, }, }; diff --git a/app/data/jsonSchemaForm/projectSchema.ts b/app/data/jsonSchemaForm/projectSchema.ts index df8ef9c9a0..d01a9491c4 100644 --- a/app/data/jsonSchemaForm/projectSchema.ts +++ b/app/data/jsonSchemaForm/projectSchema.ts @@ -23,14 +23,15 @@ const projectSchema = { default: undefined, }, summary: { type: "string", title: "Project Description" }, - projectType: { type: "string", title: "Project Type" }, + projectType: { + type: [null, "string"], + title: "Project Type", + default: undefined, + }, score: { - type: "number", + type: [null, "number"], title: "Score", - }, - rank: { - type: "number", - title: "Rank", + default: undefined, }, operatorId: { type: "number", @@ -56,14 +57,20 @@ const projectSchema = { anyOf: undefined, }, additionalSectorInformation: { - type: "string", + type: [null, "string"], title: "Additional Sector Information", + default: undefined, }, contractNumber: { - type: "string", + type: [null, "string"], title: "Contract Number", + default: undefined, + }, + comments: { + type: [null, "string"], + title: "General Comments", + default: undefined, }, - comments: { type: "string", title: "General Comments" }, }, }; diff --git a/schema/data/prod/json_schema/contact.json b/schema/data/prod/json_schema/contact.json index fdd47f64c7..ef93b6ebdb 100644 --- a/schema/data/prod/json_schema/contact.json +++ b/schema/data/prod/json_schema/contact.json @@ -2,7 +2,7 @@ "schema": { "$schema": "http://json-schema.org/draft-07/schema", "type": "object", - "required": ["givenName", "familyName", "email", "phone"], + "required": ["givenName", "familyName", "email"], "properties": { "givenName": { "type": "string", @@ -14,27 +14,33 @@ }, "email": { "type": "string", - "title": "Email" + "title": "Email", + "pattern": "^[\\.\\w-]+@([\\w-]+\\.)+[\\w-]{2,4}$" }, "phone": { "type": "string", - "title": "Phone" + "title": "Phone", + "pattern": "^(\\+?\\d{1,2}[\\s,-]?)?\\(?\\d{3}\\)?[\\s.-]?\\d{3}[\\s.-]?\\d{4}$" }, "phoneExt": { - "type": "string", - "title": "Phone Extension" + "type": ["null", "string"], + "title": "Phone Extension", + "default": "undefined" }, "companyName": { - "type": "string", - "title": "Company Name" + "type": ["null", "string"], + "title": "Company Name", + "default": "undefined" }, "contactPosition": { - "type": "string", - "title": "Position" + "type": ["null", "string"], + "title": "Position", + "default": "undefined" }, "comments": { - "type": "string", - "title": "Comments" + "type": ["null", "string"], + "title": "Comments", + "default": "undefined" } } } diff --git a/schema/data/prod/json_schema/emission_intensity_report.json b/schema/data/prod/json_schema/emission_intensity_report.json index 613a5d29f3..3538e60991 100644 --- a/schema/data/prod/json_schema/emission_intensity_report.json +++ b/schema/data/prod/json_schema/emission_intensity_report.json @@ -23,7 +23,7 @@ "comments": { "type": ["null", "string"], "title": "General Comments", - "default": "null" + "default": null }, "measurementPeriodStartDate": { "title": "TEIMP Start Date", @@ -40,7 +40,7 @@ "productionFunctionalUnit": { "title": "Production Functional Unit", "type": ["null", "string"], - "default": "null" + "default": null }, "baselineEmissionIntensity": { "title": "Baseline Emission Intensity (BEI)", diff --git a/schema/data/prod/json_schema/milestone.json b/schema/data/prod/json_schema/milestone.json index 32eb2823e5..0431eab37f 100644 --- a/schema/data/prod/json_schema/milestone.json +++ b/schema/data/prod/json_schema/milestone.json @@ -26,19 +26,21 @@ "title": "Report Due Date" }, "submittedDate": { - "type": "string", - "title": "Report Received Date" + "type": ["null", "string"], + "title": "Report Received Date", + "default": "undefined" }, "substantialCompletionDate": { "type": "string", "title": "Substantial Completion Date" }, "certifiedBy": { - "type": "string", - "title": "Certifier" + "type": ["null", "string"], + "title": "Certifier", + "default": "undefined" }, "certifierProfessionalDesignation": { - "type": "string", + "type": ["null", "string"], "title": "Professional Designation", "default": "Professional Engineer", "anyOf": [ @@ -80,20 +82,23 @@ "title": "Maximum Amount This Milestone" }, "adjustedGrossAmount": { - "type": "number", - "title": "Gross Payment Amount This Milestone" + "type": ["null", "number"], + "title": "Gross Payment Amount This Milestone", + "default": "undefined" }, "adjustedHoldbackAmount": { "type": "number", "title": "Holdback Amount This Milestone" }, "adjustedNetAmount": { - "type": "number", - "title": "Net Payment Amount This Milestone" + "type": ["null", "number"], + "title": "Net Payment Amount This Milestone", + "default": "undefined" }, "dateSentToCsnr": { - "type": "string", - "title": "Date Invoice Sent to CSNR" + "type": ["null", "string"], + "title": "Date Invoice Sent to CSNR", + "default": "undefined" } }, "required": ["maximumAmount"] @@ -117,8 +122,9 @@ "title": "Milestone Type" }, "totalEligibleExpenses": { - "type": "number", - "title": "Total Eligible Expenses" + "type": ["null", "number"], + "title": "Total Eligible Expenses", + "default": "undefined" } } } diff --git a/schema/data/prod/json_schema/operator.json b/schema/data/prod/json_schema/operator.json index 34c3eb22d1..5026951e54 100644 --- a/schema/data/prod/json_schema/operator.json +++ b/schema/data/prod/json_schema/operator.json @@ -14,14 +14,16 @@ "title": "Trade Name" }, "bcRegistryId": { - "type": "string", + "type": ["null", "string"], "title": "BC Registry ID", - "pattern": "^[a-zA-Z]{1,3}[0-9]{7}$" + "pattern": "^[a-zA-Z]{1,3}[0-9]{7}$", + "default": "undefined" }, "operatorCode": { - "type": "string", + "type": ["null", "string"], "title": "Operator Code", - "pattern": "^[A-Z]{4}$" + "pattern": "^[A-Z]{4}$", + "default": "undefined" } } } diff --git a/schema/data/prod/json_schema/project.json b/schema/data/prod/json_schema/project.json index 21a3d68dba..75755cf476 100644 --- a/schema/data/prod/json_schema/project.json +++ b/schema/data/prod/json_schema/project.json @@ -31,12 +31,14 @@ "title": "Project Description" }, "projectType": { - "type": "string", - "title": "Project Type" + "type": ["null", "string"], + "title": "Project Type", + "default": "undefined" }, "score": { - "type": "number", - "title": "Score" + "type": ["null", "number"], + "title": "Score", + "default": "undefined" }, "operatorId": { "type": "number", @@ -62,16 +64,19 @@ "anyOf": "undefined" }, "additionalSectorInformation": { - "type": "string", - "title": "Additional Sector Information" + "type": ["null", "string"], + "title": "Additional Sector Information", + "default": "undefined" }, "contractNumber": { - "type": "string", - "title": "Contract Number" + "type": ["null", "string"], + "title": "Contract Number", + "default": "undefined" }, "comments": { - "type": "string", - "title": "General Comments" + "type": ["null", "string"], + "title": "General Comments", + "default": "undefined" } } } diff --git a/schema/data/prod/json_schema/project_contact.json b/schema/data/prod/json_schema/project_contact.json index d952a07af9..f06101a8c5 100644 --- a/schema/data/prod/json_schema/project_contact.json +++ b/schema/data/prod/json_schema/project_contact.json @@ -6,7 +6,8 @@ "properties": { "contactId": { "title": "Contact", - "type": "number" + "type": ["null", "number"], + "default": "undefined" } } } diff --git a/schema/data/prod/json_schema/project_manager.json b/schema/data/prod/json_schema/project_manager.json index 9b4ef52638..7cad5a9067 100644 --- a/schema/data/prod/json_schema/project_manager.json +++ b/schema/data/prod/json_schema/project_manager.json @@ -5,8 +5,9 @@ "title": "Project Manager", "properties": { "cifUserId": { - "type": "number", - "title": "Project Manager" + "type": ["null", "number"], + "title": "Project Manager", + "default": "undefined" } } } diff --git a/schema/data/prod/json_schema/project_summary_report.json b/schema/data/prod/json_schema/project_summary_report.json index c97d056f2a..77a6181a96 100644 --- a/schema/data/prod/json_schema/project_summary_report.json +++ b/schema/data/prod/json_schema/project_summary_report.json @@ -10,24 +10,29 @@ "title": "Report Due Date" }, "submittedDate": { - "type": "string", - "title": "Received Date" + "type": ["null", "string"], + "title": "Received Date", + "default": "undefined" }, "comments": { - "type": "string", - "title": "General Comments" + "type": ["null", "string"], + "title": "General Comments", + "default": "undefined" }, "projectSummaryReportPayment": { "title": "Project Summary Report Payment", - "type": "number" + "type": ["null", "number"], + "default": "undefined" }, "paymentNotes": { "title": "Notes for the Payment", - "type": "string" + "type": ["null", "string"], + "default": "undefined" }, "dateSentToCsnr": { "title": "Date Invoice Sent to CSNR", - "type": "string" + "type": ["null", "string"], + "default": "undefined" } } } From afc82f37c9bf988e914069855ecd0f07ea97a530 Mon Sep 17 00:00:00 2001 From: SeSo Date: Mon, 19 Jun 2023 10:58:13 -0700 Subject: [PATCH 02/22] chore: fix json compatibility issue with null values --- app/data/jsonSchemaForm/contactSchema.ts | 8 ++++---- app/data/jsonSchemaForm/projectSchema.ts | 15 ++++++++++----- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/app/data/jsonSchemaForm/contactSchema.ts b/app/data/jsonSchemaForm/contactSchema.ts index 35cbc25df1..c715a0b58a 100644 --- a/app/data/jsonSchemaForm/contactSchema.ts +++ b/app/data/jsonSchemaForm/contactSchema.ts @@ -23,22 +23,22 @@ const contactSchema = { "^(\\+?\\d{1,2}[\\s,-]?)?\\(?\\d{3}\\)?[\\s.-]?\\d{3}[\\s.-]?\\d{4}$", }, phoneExt: { - type: [null, "string"], + type: ["null", "string"], title: "Phone Extension", default: undefined, }, companyName: { - type: [null, "string"], + type: ["null", "string"], title: "Company Name", default: undefined, }, contactPosition: { - type: [null, "string"], + type: ["null", "string"], title: "Position", default: undefined, }, comments: { - type: [null, "string"], + type: ["null", "string"], title: "Comments", default: undefined, }, diff --git a/app/data/jsonSchemaForm/projectSchema.ts b/app/data/jsonSchemaForm/projectSchema.ts index d01a9491c4..acf59726c8 100644 --- a/app/data/jsonSchemaForm/projectSchema.ts +++ b/app/data/jsonSchemaForm/projectSchema.ts @@ -24,15 +24,20 @@ const projectSchema = { }, summary: { type: "string", title: "Project Description" }, projectType: { - type: [null, "string"], + type: ["null", "string"], title: "Project Type", default: undefined, }, score: { - type: [null, "number"], + type: ["null", "number"], title: "Score", default: undefined, }, + rank: { + type: ["null", "number"], + title: "Rank", + default: undefined, + }, operatorId: { type: "number", title: "Legal Operator Name and BC Registry ID", @@ -57,17 +62,17 @@ const projectSchema = { anyOf: undefined, }, additionalSectorInformation: { - type: [null, "string"], + type: ["null", "string"], title: "Additional Sector Information", default: undefined, }, contractNumber: { - type: [null, "string"], + type: ["null", "string"], title: "Contract Number", default: undefined, }, comments: { - type: [null, "string"], + type: ["null", "string"], title: "General Comments", default: undefined, }, From 0b583ae2b782d005f99cdcfe753a5b7e5e4f291b Mon Sep 17 00:00:00 2001 From: SeSo Date: Tue, 4 Jul 2023 16:59:29 -0700 Subject: [PATCH 03/22] chore: remove redundant widget --- .../Form/SelectProjectTypeWidget.tsx | 72 ------------------- 1 file changed, 72 deletions(-) delete mode 100644 app/components/Form/SelectProjectTypeWidget.tsx diff --git a/app/components/Form/SelectProjectTypeWidget.tsx b/app/components/Form/SelectProjectTypeWidget.tsx deleted file mode 100644 index a2e5546ccb..0000000000 --- a/app/components/Form/SelectProjectTypeWidget.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import { WidgetProps } from "@rjsf/core"; -import { useMemo } from "react"; -import { graphql, useFragment } from "react-relay"; -import Dropdown from "@button-inc/bcgov-theme/Dropdown"; - -const SelectProjectType: React.FunctionComponent = (props) => { - const { id, onChange, placeholder, required, uiSchema, value, formContext } = - props; - - const { allProjectTypes } = useFragment( - graphql` - fragment SelectProjectTypeWidget_query on Query { - allProjectTypes { - edges { - node { - name - } - } - } - } - `, - formContext.query - ); - - const { projectType } = formContext.form || {}; - - const projectTypeList = useMemo(() => { - return allProjectTypes.edges - .filter((edge) => { - return edge.node.name == projectType; - }) - .map((edge) => edge.node.projectStatusByProjectStatusId); - }, [allProjectTypes, projectType]); - - return ( -
- onChange(e.target.value || undefined)} - placeholder={placeholder} - size={(uiSchema && uiSchema["bcgov:size"]) || "large"} - required={required} - value={value} - > - - {projectTypeList.map((type) => { - return ( - - ); - })} - - -
- ); -}; - -export default SelectProjectType; From 2ff68b3ead603b91e114fcfc791812029e058ee5 Mon Sep 17 00:00:00 2001 From: SeSo Date: Thu, 6 Jul 2023 11:16:34 -0700 Subject: [PATCH 04/22] chore: rework computed column to use double arrow to return null if jsob value is null --- ...cipated_funding_amount_per_fiscal_year.sql | 2 +- ...d_funding_amount_per_fiscal_year@1.9.0.sql | 42 +++++++++++++++++++ ...cipated_funding_amount_per_fiscal_year.sql | 39 ++++++++++++++++- ...d_funding_amount_per_fiscal_year@1.9.0.sql | 7 ++++ schema/sqitch.plan | 1 + ...d_funding_amount_per_fiscal_year@1.9.0.sql | 7 ++++ 6 files changed, 95 insertions(+), 3 deletions(-) create mode 100644 schema/deploy/computed_columns/form_change_anticipated_funding_amount_per_fiscal_year@1.9.0.sql create mode 100644 schema/revert/computed_columns/form_change_anticipated_funding_amount_per_fiscal_year@1.9.0.sql create mode 100644 schema/verify/computed_columns/form_change_anticipated_funding_amount_per_fiscal_year@1.9.0.sql diff --git a/schema/deploy/computed_columns/form_change_anticipated_funding_amount_per_fiscal_year.sql b/schema/deploy/computed_columns/form_change_anticipated_funding_amount_per_fiscal_year.sql index 6f2a1ffd3a..05025ad442 100644 --- a/schema/deploy/computed_columns/form_change_anticipated_funding_amount_per_fiscal_year.sql +++ b/schema/deploy/computed_columns/form_change_anticipated_funding_amount_per_fiscal_year.sql @@ -22,7 +22,7 @@ anticipated_funding as ( coalesce((new_form_data->>'dateSentToCsnr')::timestamptz, (new_form_data->>'submittedDate')::timestamptz, (new_form_data->>'reportDueDate')::timestamptz))) as year, sum( coalesce( - (select new_form_data->'adjustedGrossAmount')::numeric, + (select new_form_data->>'adjustedGrossAmount')::numeric, (select cif.form_change_calculated_gross_amount_this_milestone(row(form_changes.*))), (new_form_data->>'maximumAmount')::numeric ) diff --git a/schema/deploy/computed_columns/form_change_anticipated_funding_amount_per_fiscal_year@1.9.0.sql b/schema/deploy/computed_columns/form_change_anticipated_funding_amount_per_fiscal_year@1.9.0.sql new file mode 100644 index 0000000000..6f2a1ffd3a --- /dev/null +++ b/schema/deploy/computed_columns/form_change_anticipated_funding_amount_per_fiscal_year@1.9.0.sql @@ -0,0 +1,42 @@ +-- Deploy cif:computed_columns/form_change_anticipated_funding_amount_per_fiscal_year to pg + +begin; + +create or replace function cif.form_change_anticipated_funding_amount_per_fiscal_year(cif.form_change) +returns setof cif.sum_by_fiscal_year +as +$computed_column$ + +with form_changes as ( + select * from cif.form_change + where project_revision_id = $1.project_revision_id + and form_data_schema_name='cif' + and form_data_table_name='reporting_requirement' + and (new_form_data->>'reportType') in (select name from cif.report_type where has_expenses=true) + and operation != 'archive' +), + +anticipated_funding as ( + select + cif.get_fiscal_year_from_timestamp((select + coalesce((new_form_data->>'dateSentToCsnr')::timestamptz, (new_form_data->>'submittedDate')::timestamptz, (new_form_data->>'reportDueDate')::timestamptz))) as year, + sum( + coalesce( + (select new_form_data->'adjustedGrossAmount')::numeric, + (select cif.form_change_calculated_gross_amount_this_milestone(row(form_changes.*))), + (new_form_data->>'maximumAmount')::numeric + ) + ) as anticipatedFundingAmount + from form_changes + group by year +) + +select year, anticipatedFundingAmount from anticipated_funding; + +$computed_column$ language sql stable; + +grant execute on function cif.form_change_anticipated_funding_amount_per_fiscal_year to cif_internal, cif_external, cif_admin; + +comment on function cif.form_change_anticipated_funding_amount_per_fiscal_year is 'Computed column to calculate the anticipated amount of funding for a project by fiscal year'; + +commit; diff --git a/schema/revert/computed_columns/form_change_anticipated_funding_amount_per_fiscal_year.sql b/schema/revert/computed_columns/form_change_anticipated_funding_amount_per_fiscal_year.sql index 19fcc3d27b..6f2a1ffd3a 100644 --- a/schema/revert/computed_columns/form_change_anticipated_funding_amount_per_fiscal_year.sql +++ b/schema/revert/computed_columns/form_change_anticipated_funding_amount_per_fiscal_year.sql @@ -1,7 +1,42 @@ --- Revert cif:computed_columns/form_change_anticipated_funding_amount_per_fiscal_year from pg +-- Deploy cif:computed_columns/form_change_anticipated_funding_amount_per_fiscal_year to pg begin; -drop function cif.form_change_anticipated_funding_amount_per_fiscal_year; +create or replace function cif.form_change_anticipated_funding_amount_per_fiscal_year(cif.form_change) +returns setof cif.sum_by_fiscal_year +as +$computed_column$ + +with form_changes as ( + select * from cif.form_change + where project_revision_id = $1.project_revision_id + and form_data_schema_name='cif' + and form_data_table_name='reporting_requirement' + and (new_form_data->>'reportType') in (select name from cif.report_type where has_expenses=true) + and operation != 'archive' +), + +anticipated_funding as ( + select + cif.get_fiscal_year_from_timestamp((select + coalesce((new_form_data->>'dateSentToCsnr')::timestamptz, (new_form_data->>'submittedDate')::timestamptz, (new_form_data->>'reportDueDate')::timestamptz))) as year, + sum( + coalesce( + (select new_form_data->'adjustedGrossAmount')::numeric, + (select cif.form_change_calculated_gross_amount_this_milestone(row(form_changes.*))), + (new_form_data->>'maximumAmount')::numeric + ) + ) as anticipatedFundingAmount + from form_changes + group by year +) + +select year, anticipatedFundingAmount from anticipated_funding; + +$computed_column$ language sql stable; + +grant execute on function cif.form_change_anticipated_funding_amount_per_fiscal_year to cif_internal, cif_external, cif_admin; + +comment on function cif.form_change_anticipated_funding_amount_per_fiscal_year is 'Computed column to calculate the anticipated amount of funding for a project by fiscal year'; commit; diff --git a/schema/revert/computed_columns/form_change_anticipated_funding_amount_per_fiscal_year@1.9.0.sql b/schema/revert/computed_columns/form_change_anticipated_funding_amount_per_fiscal_year@1.9.0.sql new file mode 100644 index 0000000000..19fcc3d27b --- /dev/null +++ b/schema/revert/computed_columns/form_change_anticipated_funding_amount_per_fiscal_year@1.9.0.sql @@ -0,0 +1,7 @@ +-- Revert cif:computed_columns/form_change_anticipated_funding_amount_per_fiscal_year from pg + +begin; + +drop function cif.form_change_anticipated_funding_amount_per_fiscal_year; + +commit; diff --git a/schema/sqitch.plan b/schema/sqitch.plan index f188f93c52..ee990d0b7a 100644 --- a/schema/sqitch.plan +++ b/schema/sqitch.plan @@ -341,3 +341,4 @@ data/012_fix_milestone_schema_capitalization 2023-07-11T23:15:08Z Dylan Leard # Migration: replace bad capitalization of adjustedHoldbackAmount in form_change data data/013_insert_json_schema_form_data_anticipated_funding_per_year_to_array_type 2023-06-23T19:53:12Z Brianna Cerkiewicz # Change anticipated funding per fiscal year to an array type in funding schemas @1.10.0 2023-07-13T22:53:40Z Dylan Leard # release v1.10.0 +computed_columns/form_change_anticipated_funding_amount_per_fiscal_year [computed_columns/form_change_anticipated_funding_amount_per_fiscal_year@1.9.0] 2023-07-05T23:20:07Z Sepehr Sobhani # Using double arrow to return null if new form data prop value is null diff --git a/schema/verify/computed_columns/form_change_anticipated_funding_amount_per_fiscal_year@1.9.0.sql b/schema/verify/computed_columns/form_change_anticipated_funding_amount_per_fiscal_year@1.9.0.sql new file mode 100644 index 0000000000..22af1a579d --- /dev/null +++ b/schema/verify/computed_columns/form_change_anticipated_funding_amount_per_fiscal_year@1.9.0.sql @@ -0,0 +1,7 @@ +-- Verify cif:computed_columns/form_change_anticipated_funding_amount_per_fiscal_year on pg + +begin; + +select pg_get_functiondef('cif.form_change_anticipated_funding_amount_per_fiscal_year(cif.form_change)'::regprocedure); + +rollback; From 34601f34b8b1f1b14383c065d9020f56b06f2f74 Mon Sep 17 00:00:00 2001 From: SeSo Date: Thu, 6 Jul 2023 15:02:32 -0700 Subject: [PATCH 05/22] chore: add null value as default for optional fields --- app/data/jsonSchemaForm/contactSchema.ts | 11 ++++---- .../projectEmissionIntensitySchema.ts | 28 +++++++++++-------- app/data/jsonSchemaForm/projectSchema.ts | 11 ++++---- schema/data/prod/json_schema/contact.json | 13 +++++---- ...ssion_intensity_reporting_requirement.json | 15 +++++----- schema/data/prod/json_schema/milestone.json | 14 ++++------ schema/data/prod/json_schema/operator.json | 4 +-- schema/data/prod/json_schema/project.json | 14 ++++++---- .../prod/json_schema/project_contact.json | 3 +- .../json_schema/reporting_requirement.json | 16 ++++++----- 10 files changed, 68 insertions(+), 61 deletions(-) diff --git a/app/data/jsonSchemaForm/contactSchema.ts b/app/data/jsonSchemaForm/contactSchema.ts index c715a0b58a..2188d2a3c3 100644 --- a/app/data/jsonSchemaForm/contactSchema.ts +++ b/app/data/jsonSchemaForm/contactSchema.ts @@ -17,30 +17,31 @@ const contactSchema = { pattern: "^[\\.\\w-]+@([\\w-]+\\.)+[\\w-]{2,4}$", }, phone: { - type: "string", + type: ["null", "string"], title: "Phone", pattern: "^(\\+?\\d{1,2}[\\s,-]?)?\\(?\\d{3}\\)?[\\s.-]?\\d{3}[\\s.-]?\\d{4}$", + default: null, }, phoneExt: { type: ["null", "string"], title: "Phone Extension", - default: undefined, + default: null, }, companyName: { type: ["null", "string"], title: "Company Name", - default: undefined, + default: null, }, contactPosition: { type: ["null", "string"], title: "Position", - default: undefined, + default: null, }, comments: { type: ["null", "string"], title: "Comments", - default: undefined, + default: null, }, }, }; diff --git a/app/data/jsonSchemaForm/projectEmissionIntensitySchema.ts b/app/data/jsonSchemaForm/projectEmissionIntensitySchema.ts index 17de7838d8..c262806441 100644 --- a/app/data/jsonSchemaForm/projectEmissionIntensitySchema.ts +++ b/app/data/jsonSchemaForm/projectEmissionIntensitySchema.ts @@ -30,7 +30,8 @@ export const emissionIntensityReportSchema = { }, productionFunctionalUnit: { title: "Production Functional Unit", - type: "string", + type: ["null", "string"], + default: null, }, baselineEmissionIntensity: { title: "Baseline Emission Intensity (BEI)", @@ -42,11 +43,13 @@ export const emissionIntensityReportSchema = { }, postProjectEmissionIntensity: { title: "Post-Project Emission Intensity (PEI)", - type: "number", + type: ["null", "number"], + default: null, }, totalLifetimeEmissionReduction: { title: "Total Project Lifetime Emissions Reductions", - type: "number", + type: ["null", "number"], + default: null, }, }, }, @@ -56,17 +59,17 @@ export const emissionIntensityReportSchema = { properties: { adjustedEmissionsIntensityPerformance: { title: "GHG Emission Intensity Performance", - type: "number", + type: ["null", "number"], + default: null, }, dateSentToCsnr: { - type: "string", + type: ["null", "string"], title: "Date Invoice Sent to CSNR", - default: undefined, + default: null, }, paymentPercentage: { type: "number", title: "Payment Percentage of Performance Milestone Amount (%)", - default: undefined, }, holdbackAmountToDate: { type: "number", @@ -90,18 +93,19 @@ export const emissionIntensityReportingRequirementSchema = { required: [], properties: { reportDueDate: { - type: "string", + type: ["null", "string"], title: "Report Due Date", - default: undefined, + default: null, }, submittedDate: { - type: "string", + type: ["null", "string"], title: "Report Received Date", - default: undefined, + default: null, }, comments: { - type: "string", + type: ["null", "string"], title: "General Comments", + default: null, }, }, }; diff --git a/app/data/jsonSchemaForm/projectSchema.ts b/app/data/jsonSchemaForm/projectSchema.ts index acf59726c8..c07df32b74 100644 --- a/app/data/jsonSchemaForm/projectSchema.ts +++ b/app/data/jsonSchemaForm/projectSchema.ts @@ -31,12 +31,11 @@ const projectSchema = { score: { type: ["null", "number"], title: "Score", - default: undefined, + default: null, }, rank: { - type: ["null", "number"], + type: "number", title: "Rank", - default: undefined, }, operatorId: { type: "number", @@ -64,17 +63,17 @@ const projectSchema = { additionalSectorInformation: { type: ["null", "string"], title: "Additional Sector Information", - default: undefined, + default: null, }, contractNumber: { type: ["null", "string"], title: "Contract Number", - default: undefined, + default: null, }, comments: { type: ["null", "string"], title: "General Comments", - default: undefined, + default: null, }, }, }; diff --git a/schema/data/prod/json_schema/contact.json b/schema/data/prod/json_schema/contact.json index ef93b6ebdb..92e2adb107 100644 --- a/schema/data/prod/json_schema/contact.json +++ b/schema/data/prod/json_schema/contact.json @@ -18,29 +18,30 @@ "pattern": "^[\\.\\w-]+@([\\w-]+\\.)+[\\w-]{2,4}$" }, "phone": { - "type": "string", + "type": ["null", "string"], "title": "Phone", - "pattern": "^(\\+?\\d{1,2}[\\s,-]?)?\\(?\\d{3}\\)?[\\s.-]?\\d{3}[\\s.-]?\\d{4}$" + "pattern": "^(\\+?\\d{1,2}[\\s,-]?)?\\(?\\d{3}\\)?[\\s.-]?\\d{3}[\\s.-]?\\d{4}$", + "default": null }, "phoneExt": { "type": ["null", "string"], "title": "Phone Extension", - "default": "undefined" + "default": null }, "companyName": { "type": ["null", "string"], "title": "Company Name", - "default": "undefined" + "default": null }, "contactPosition": { "type": ["null", "string"], "title": "Position", - "default": "undefined" + "default": null }, "comments": { "type": ["null", "string"], "title": "Comments", - "default": "undefined" + "default": null } } } diff --git a/schema/data/prod/json_schema/emission_intensity_reporting_requirement.json b/schema/data/prod/json_schema/emission_intensity_reporting_requirement.json index d550a9e997..468c9f2fd7 100644 --- a/schema/data/prod/json_schema/emission_intensity_reporting_requirement.json +++ b/schema/data/prod/json_schema/emission_intensity_reporting_requirement.json @@ -6,18 +6,17 @@ "required": [], "properties": { "reportDueDate": { - "type": "string", - "title": "Report Due Date", - "default": "undefined" + "type": ["null", "string"], + "title": "Report Due Date" }, "submittedDate": { - "type": "string", - "title": "Received Date", - "default": "undefined" + "type": ["null", "string"], + "title": "Report Received Date" }, "comments": { - "type": "string", - "title": "General Comments" + "type": ["null", "string"], + "title": "General Comments", + "default": null } } } diff --git a/schema/data/prod/json_schema/milestone.json b/schema/data/prod/json_schema/milestone.json index 0431eab37f..d33aedcc33 100644 --- a/schema/data/prod/json_schema/milestone.json +++ b/schema/data/prod/json_schema/milestone.json @@ -27,8 +27,7 @@ }, "submittedDate": { "type": ["null", "string"], - "title": "Report Received Date", - "default": "undefined" + "title": "Report Received Date" }, "substantialCompletionDate": { "type": "string", @@ -37,7 +36,7 @@ "certifiedBy": { "type": ["null", "string"], "title": "Certifier", - "default": "undefined" + "default": null }, "certifierProfessionalDesignation": { "type": ["null", "string"], @@ -84,7 +83,7 @@ "adjustedGrossAmount": { "type": ["null", "number"], "title": "Gross Payment Amount This Milestone", - "default": "undefined" + "default": null }, "adjustedHoldbackAmount": { "type": "number", @@ -93,12 +92,11 @@ "adjustedNetAmount": { "type": ["null", "number"], "title": "Net Payment Amount This Milestone", - "default": "undefined" + "default": null }, "dateSentToCsnr": { "type": ["null", "string"], - "title": "Date Invoice Sent to CSNR", - "default": "undefined" + "title": "Date Invoice Sent to CSNR" } }, "required": ["maximumAmount"] @@ -124,7 +122,7 @@ "totalEligibleExpenses": { "type": ["null", "number"], "title": "Total Eligible Expenses", - "default": "undefined" + "default": null } } } diff --git a/schema/data/prod/json_schema/operator.json b/schema/data/prod/json_schema/operator.json index 5026951e54..4b63eba841 100644 --- a/schema/data/prod/json_schema/operator.json +++ b/schema/data/prod/json_schema/operator.json @@ -17,13 +17,13 @@ "type": ["null", "string"], "title": "BC Registry ID", "pattern": "^[a-zA-Z]{1,3}[0-9]{7}$", - "default": "undefined" + "default": null }, "operatorCode": { "type": ["null", "string"], "title": "Operator Code", "pattern": "^[A-Z]{4}$", - "default": "undefined" + "default": null } } } diff --git a/schema/data/prod/json_schema/project.json b/schema/data/prod/json_schema/project.json index 75755cf476..bc7a3eb41b 100644 --- a/schema/data/prod/json_schema/project.json +++ b/schema/data/prod/json_schema/project.json @@ -33,12 +33,16 @@ "projectType": { "type": ["null", "string"], "title": "Project Type", - "default": "undefined" + "default": null }, "score": { "type": ["null", "number"], "title": "Score", - "default": "undefined" + "default": null + }, + "rank": { + "type": "number", + "title": "Rank" }, "operatorId": { "type": "number", @@ -66,17 +70,17 @@ "additionalSectorInformation": { "type": ["null", "string"], "title": "Additional Sector Information", - "default": "undefined" + "default": null }, "contractNumber": { "type": ["null", "string"], "title": "Contract Number", - "default": "undefined" + "default": null }, "comments": { "type": ["null", "string"], "title": "General Comments", - "default": "undefined" + "default": null } } } diff --git a/schema/data/prod/json_schema/project_contact.json b/schema/data/prod/json_schema/project_contact.json index f06101a8c5..d952a07af9 100644 --- a/schema/data/prod/json_schema/project_contact.json +++ b/schema/data/prod/json_schema/project_contact.json @@ -6,8 +6,7 @@ "properties": { "contactId": { "title": "Contact", - "type": ["null", "number"], - "default": "undefined" + "type": "number" } } } diff --git a/schema/data/prod/json_schema/reporting_requirement.json b/schema/data/prod/json_schema/reporting_requirement.json index 52e18c6269..7fdd57d51a 100644 --- a/schema/data/prod/json_schema/reporting_requirement.json +++ b/schema/data/prod/json_schema/reporting_requirement.json @@ -3,19 +3,21 @@ "$schema": "http://json-schema.org/draft-07/schema", "type": "object", "title": "Reporting Requirement", - "required": ["reportDueDate"], "properties": { "reportDueDate": { - "type": "string", - "title": "Report Due Date" + "type": ["null", "string"], + "title": "Report Due Date", + "default": null }, "submittedDate": { - "type": "string", - "title": "Report Received Date" + "type": ["null", "string"], + "title": "Report Received Date", + "default": null }, "comments": { - "type": "string", - "title": "General Comments" + "type": ["null", "string"], + "title": "General Comments", + "default": null } } } From e7d3338158adba08eeee13ca91ab01341143cbbc Mon Sep 17 00:00:00 2001 From: SeSo Date: Thu, 6 Jul 2023 15:04:07 -0700 Subject: [PATCH 06/22] chore: cover cases when `reportTypeRecord` is null --- app/components/Form/ProjectMilestoneReportForm.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/components/Form/ProjectMilestoneReportForm.tsx b/app/components/Form/ProjectMilestoneReportForm.tsx index 30fe70e0f9..586916d5a1 100644 --- a/app/components/Form/ProjectMilestoneReportForm.tsx +++ b/app/components/Form/ProjectMilestoneReportForm.tsx @@ -221,7 +221,7 @@ const ProjectMilestoneReportForm: React.FC = (props) => { formChangePatch: { newFormData: { ...formData, - hasExpenses: reportTypeRecord.node.hasExpenses, + hasExpenses: reportTypeRecord?.node.hasExpenses, }, }, }, @@ -233,7 +233,7 @@ const ProjectMilestoneReportForm: React.FC = (props) => { id: milestoneNode.id, newFormData: { ...milestoneChangeData, - hasExpenses: reportTypeRecord.node.hasExpenses, + hasExpenses: reportTypeRecord?.node.hasExpenses, }, changeStatus: "pending", }, From 8d20828341a6a748ce2677c035e94d7291e88d97 Mon Sep 17 00:00:00 2001 From: SeSo Date: Thu, 6 Jul 2023 15:05:10 -0700 Subject: [PATCH 07/22] chore: remove redundant properties from `emission_intensity_report` schema --- schema/data/prod/json_schema/emission_intensity_report.json | 1 - 1 file changed, 1 deletion(-) diff --git a/schema/data/prod/json_schema/emission_intensity_report.json b/schema/data/prod/json_schema/emission_intensity_report.json index 3538e60991..55d659c1c7 100644 --- a/schema/data/prod/json_schema/emission_intensity_report.json +++ b/schema/data/prod/json_schema/emission_intensity_report.json @@ -4,7 +4,6 @@ "type": "object", "title": "Emissions Intensity Report", "required": [ - "reportDueDate", "measurementPeriodStartDate", "measurementPeriodEndDate", "emissionFunctionalUnit", From e440e119b5cdebe6bfb225824df36d2996f2bbdc Mon Sep 17 00:00:00 2001 From: SeSo Date: Thu, 6 Jul 2023 15:05:42 -0700 Subject: [PATCH 08/22] chore: remove redundant field from milestone ui schema --- app/data/jsonSchemaForm/projectMilestoneUiSchema.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/app/data/jsonSchemaForm/projectMilestoneUiSchema.ts b/app/data/jsonSchemaForm/projectMilestoneUiSchema.ts index 34b1a014da..f8a127cd58 100644 --- a/app/data/jsonSchemaForm/projectMilestoneUiSchema.ts +++ b/app/data/jsonSchemaForm/projectMilestoneUiSchema.ts @@ -12,7 +12,6 @@ const projectMilestoneUiSchema = { "certifierProfessionalDesignation", "submittedDate", "totalEligibleExpenses", - "grossPaymentAmount", "calculatedGrossAmount", "adjustedGrossAmount", "calculatedNetAmount", From fb3441df966bfc7c38ebe6abe96f329c13c9be8f Mon Sep 17 00:00:00 2001 From: SeSo Date: Thu, 6 Jul 2023 15:06:20 -0700 Subject: [PATCH 09/22] refactor: refactor `getBadgeForOverallReportStatus` util to handle null values --- app/lib/helpers/reportStatusHelpers.tsx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/app/lib/helpers/reportStatusHelpers.tsx b/app/lib/helpers/reportStatusHelpers.tsx index ec7436d4e8..7f3f68786e 100644 --- a/app/lib/helpers/reportStatusHelpers.tsx +++ b/app/lib/helpers/reportStatusHelpers.tsx @@ -83,9 +83,10 @@ export const getBadgeForOverallReportStatus = ( const reportsExist = reportSubmittedDates?.length !== 0; if (!reportsExist) { return ; - } else if (reportsExist && !reportSubmittedDates.includes(undefined)) { - return ; - } else { + } + + const hasNullValues = reportSubmittedDates.some((date) => date == null); //this comparison covers both null and undefined + if (hasNullValues) { const dueIn = getDaysUntilDue(parsedDueDate); return dueIn < 0 ? ( @@ -93,6 +94,8 @@ export const getBadgeForOverallReportStatus = ( ); } + + return ; }; export const getBadgeForIndividualReportStatus = ( From 99df4df36fe5868ac1e15bfceec6d0ba484df0ed Mon Sep 17 00:00:00 2001 From: SeSo Date: Thu, 6 Jul 2023 15:09:31 -0700 Subject: [PATCH 10/22] test: update some of unit tests --- .../components/Contact/ContactForm.test.tsx | 7 +++ .../Form/ProjectAnnualReportForm.test.tsx | 14 ++++- .../ProjectAnnualReportFormSummary.test.tsx | 2 +- ...rojectEmissionIntensityReportForm.test.tsx | 14 ++++- .../unit/components/Form/ProjectForm.test.tsx | 17 +++++- .../Form/ProjectMilestoneReportForm.test.tsx | 55 +++++++++++-------- .../Form/ProjectQuarterlyReportForm.test.tsx | 12 ++++ 7 files changed, 93 insertions(+), 28 deletions(-) diff --git a/app/tests/unit/components/Contact/ContactForm.test.tsx b/app/tests/unit/components/Contact/ContactForm.test.tsx index b794b80a19..98e6d30eb3 100644 --- a/app/tests/unit/components/Contact/ContactForm.test.tsx +++ b/app/tests/unit/components/Contact/ContactForm.test.tsx @@ -89,6 +89,8 @@ describe("The Contact Form component", () => { familyName: "Doo", givenName: "Scooby", phone: "+14155552671", + phoneExt: null, + companyName: null, }, }, }, @@ -126,6 +128,11 @@ describe("The Contact Form component", () => { email: "foo@example.com", familyName: "Doo", givenName: "Scooby", + phone: null, + phoneExt: null, + companyName: null, + contactPosition: null, + comments: null, }, }, }, diff --git a/app/tests/unit/components/Form/ProjectAnnualReportForm.test.tsx b/app/tests/unit/components/Form/ProjectAnnualReportForm.test.tsx index 306a8b567f..fd5783baa8 100644 --- a/app/tests/unit/components/Form/ProjectAnnualReportForm.test.tsx +++ b/app/tests/unit/components/Form/ProjectAnnualReportForm.test.tsx @@ -7,6 +7,8 @@ import compiledFormIndexPageQuery, { FormIndexPageQuery, } from "__generated__/FormIndexPageQuery.graphql"; import reportingRequirementProdSchema from "../../../../../schema/data/prod/json_schema/reporting_requirement.json"; +import { mocked } from "jest-mock"; +import { useUpdateReportingRequirementFormChange } from "mutations/ProjectReportingRequirement/updateReportingRequirementFormChange"; const testQuery = graphql` query ProjectAnnualReportFormQuery @relay_test_operation { @@ -85,6 +87,16 @@ const defaultComponentProps = { onSubmit: jest.fn(), }; +jest.mock( + "mutations/ProjectReportingRequirement/updateReportingRequirementFormChange" +); +const updateFormChange = jest.fn(); +let isUpdating = false; +mocked(useUpdateReportingRequirementFormChange).mockImplementation(() => [ + updateFormChange, + isUpdating, +]); + const componentTestingHelper = new ComponentTestingHelper({ component: ProjectAnnualReportForm, testQuery: testQuery, @@ -197,7 +209,7 @@ describe("The ProjectAnnualReportForm", () => { ); }); - it("Validates all contact forms when the submit button is clicked", () => { + it("Validates all forms when the submit button is clicked", () => { componentTestingHelper.loadQuery(); componentTestingHelper.renderComponent(); diff --git a/app/tests/unit/components/Form/ProjectAnnualReportFormSummary.test.tsx b/app/tests/unit/components/Form/ProjectAnnualReportFormSummary.test.tsx index 52844005ca..4ff6adadad 100644 --- a/app/tests/unit/components/Form/ProjectAnnualReportFormSummary.test.tsx +++ b/app/tests/unit/components/Form/ProjectAnnualReportFormSummary.test.tsx @@ -175,7 +175,7 @@ describe("The Project Annual Report Form Summary", () => { componentTestingHelper.loadQuery(); componentTestingHelper.renderComponent(); - expect(screen.getAllByText("Report Due Date")).toHaveLength(2); + expect(screen.getAllByText(/Report Due Date/i)).toHaveLength(2); expect(screen.getAllByText("Report Received Date (optional)")).toHaveLength( 2 ); diff --git a/app/tests/unit/components/Form/ProjectEmissionIntensityReportForm.test.tsx b/app/tests/unit/components/Form/ProjectEmissionIntensityReportForm.test.tsx index 8b68170550..001c9791c0 100644 --- a/app/tests/unit/components/Form/ProjectEmissionIntensityReportForm.test.tsx +++ b/app/tests/unit/components/Form/ProjectEmissionIntensityReportForm.test.tsx @@ -7,6 +7,8 @@ import compiledFormIndexPageQuery, { FormIndexPageQuery, } from "__generated__/FormIndexPageQuery.graphql"; import emissionsIntensityProdSchema from "/schema/data/prod/json_schema/emission_intensity.json"; +import { useUpdateEmissionIntensityReportFormChange } from "mutations/ProjectEmissionIntensity/updateEmissionIntensityReportFormChange"; +import { mocked } from "jest-mock"; const testQuery = graphql` query ProjectEmissionIntensityReportFormQuery @relay_test_operation { @@ -88,6 +90,16 @@ const defaultComponentProps = { onSubmit: jest.fn(), }; +jest.mock( + "mutations/ProjectEmissionIntensity/updateEmissionIntensityReportFormChange" +); +const updateFormChange = jest.fn(); +let isUpdating = false; +mocked(useUpdateEmissionIntensityReportFormChange).mockImplementation(() => [ + updateFormChange, + isUpdating, +]); + const componentTestingHelper = new ComponentTestingHelper({ component: ProjectEmissionIntensityReportForm, testQuery: testQuery, @@ -342,7 +354,7 @@ describe("the emission intensity report form component", () => { it("calls the updateformchange mutation when the user types in data", () => { componentTestingHelper.loadQuery(); componentTestingHelper.renderComponent(); - userEvent.click(screen.getByText(/submit.*/i)); + userEvent.clear(screen.getAllByLabelText(/comments/i)[0]); userEvent.type(screen.getAllByLabelText(/comments/i)[0], " edited"); componentTestingHelper.expectMutationToBeCalled( "updateEmissionIntensityReportFormChangeMutation", diff --git a/app/tests/unit/components/Form/ProjectForm.test.tsx b/app/tests/unit/components/Form/ProjectForm.test.tsx index 9ebf918697..72b2be2d9b 100644 --- a/app/tests/unit/components/Form/ProjectForm.test.tsx +++ b/app/tests/unit/components/Form/ProjectForm.test.tsx @@ -150,6 +150,8 @@ describe("The Project Form", () => { comments: "some amendment comment", contractNumber: "654321", projectType: "project type 1", + score: null, + additionalSectorInformation: null, }, }, }, @@ -174,6 +176,8 @@ describe("The Project Form", () => { comments: "some amendment comment", contractNumber: "654321", projectType: "project type 1", + score: null, + additionalSectorInformation: null, }, }, }, @@ -418,6 +422,10 @@ describe("The Project Form", () => { fundingStreamRfpId: 1, projectName: "test project name2", totalFundingRequest: 12345, + score: null, + additionalSectorInformation: null, + contractNumber: null, + comments: null, }, }, }, @@ -460,6 +468,8 @@ describe("The Project Form", () => { contractNumber: "654321", projectType: "project type 1", sectorName: "test sector 1", + score: null, + additionalSectorInformation: null, }, }, }, @@ -501,6 +511,8 @@ describe("The Project Form", () => { comments: "some amendment comment", contractNumber: "654321", projectType: "project type 2", + score: null, + additionalSectorInformation: null, }, }, }, @@ -514,12 +526,13 @@ describe("The Project Form", () => { userEvent.click(screen.getByText(/Undo Changes/i)); + // we get one extra operation (update mutation) because of default null values expect( componentTestingHelper.environment.mock.getAllOperations() - ).toHaveLength(2); + ).toHaveLength(3); const mutationUnderTest = - componentTestingHelper.environment.mock.getAllOperations()[1]; + componentTestingHelper.environment.mock.getAllOperations()[2]; expect(mutationUnderTest.fragment.node.name).toBe( "undoFormChangesMutation" diff --git a/app/tests/unit/components/Form/ProjectMilestoneReportForm.test.tsx b/app/tests/unit/components/Form/ProjectMilestoneReportForm.test.tsx index d4ec943cec..e98b2ab034 100644 --- a/app/tests/unit/components/Form/ProjectMilestoneReportForm.test.tsx +++ b/app/tests/unit/components/Form/ProjectMilestoneReportForm.test.tsx @@ -7,6 +7,8 @@ import compiledFormIndexPageQuery, { FormIndexPageQuery, } from "__generated__/FormIndexPageQuery.graphql"; import milestoneProdSchema from "../../../../../schema/data/prod/json_schema/milestone.json"; +import { useUpdateMilestone } from "mutations/MilestoneReport/updateMilestone"; +import { mocked } from "jest-mock"; const testQuery = graphql` query ProjectMilestoneReportFormQuery @relay_test_operation { @@ -187,6 +189,14 @@ const defaultComponentProps = { onSubmit: jest.fn(), }; +jest.mock("mutations/MilestoneReport/updateMilestone"); +const updateFormChange = jest.fn(); +let isUpdating = false; +mocked(useUpdateMilestone).mockImplementation(() => [ + updateFormChange, + isUpdating, +]); + const componentTestingHelper = new ComponentTestingHelper({ component: ProjectMilestoneReportForm, testQuery: testQuery, @@ -303,39 +313,38 @@ describe("The ProjectMilestoneReportForm", () => { }); }); - it("Calls updateMilestoneFormChangeMutation when changing the milestone form", async () => { + it("Calls updateMilestoneFormChangeMutation when changing the milestone form", () => { componentTestingHelper.loadQuery(); componentTestingHelper.renderComponent(); - await act(async () => { + act(() => { userEvent.click(screen.getAllByLabelText(/milestone type/i)[1]); }); - await userEvent.click( + userEvent.click( within(screen.getByRole("presentation")).getByText("General") ); - await act(async () => { - const updateMutationUnderTest = - await componentTestingHelper.environment.mock.getMostRecentOperation(); - await expect(updateMutationUnderTest.fragment.node.name).toBe( - "updateMilestoneFormChangeMutation" - ); - expect(updateMutationUnderTest.request.variables).toMatchObject({ - reportType: "Milestone", - input: { - rowId: 2, - formChangePatch: { - newFormData: { - reportType: "General Milestone", - reportDueDate: "2022-10-28", - projectId: 51, - submittedDate: "2022-05-02", - description: "i am the second description", - reportingRequirementIndex: 2, - }, + const updateMutationUnderTest = + componentTestingHelper.environment.mock.getMostRecentOperation(); + + expect(updateMutationUnderTest.fragment.node.name).toBe( + "updateMilestoneFormChangeMutation" + ); + expect(updateMutationUnderTest.request.variables).toMatchObject({ + reportType: "Milestone", + input: { + rowId: 2, + formChangePatch: { + newFormData: { + reportType: "General Milestone", + reportDueDate: "2022-10-28", + projectId: 51, + submittedDate: "2022-05-02", + description: "i am the second description", + reportingRequirementIndex: 2, }, }, - }); + }, }); }); diff --git a/app/tests/unit/components/Form/ProjectQuarterlyReportForm.test.tsx b/app/tests/unit/components/Form/ProjectQuarterlyReportForm.test.tsx index 0d462bc2b6..6a33c6160f 100644 --- a/app/tests/unit/components/Form/ProjectQuarterlyReportForm.test.tsx +++ b/app/tests/unit/components/Form/ProjectQuarterlyReportForm.test.tsx @@ -7,6 +7,8 @@ import compiledFormIndexPageQuery, { FormIndexPageQuery, } from "__generated__/FormIndexPageQuery.graphql"; import reportingRequirementProdSchema from "../../../../../schema/data/prod/json_schema/reporting_requirement.json"; +import { useUpdateReportingRequirementFormChange } from "mutations/ProjectReportingRequirement/updateReportingRequirementFormChange"; +import { mocked } from "jest-mock"; const testQuery = graphql` query ProjectQuarterlyReportFormQuery @relay_test_operation { @@ -84,6 +86,16 @@ const defaultComponentProps = { onSubmit: jest.fn(), }; +jest.mock( + "mutations/ProjectReportingRequirement/updateReportingRequirementFormChange" +); +const updateFormChange = jest.fn(); +let isUpdating = false; +mocked(useUpdateReportingRequirementFormChange).mockImplementation(() => [ + updateFormChange, + isUpdating, +]); + const componentTestingHelper = new ComponentTestingHelper({ component: ProjectQuarterlyReportForm, testQuery: testQuery, From a2ded24abc3e1c88048b109ca47fa018b699eeb4 Mon Sep 17 00:00:00 2001 From: SeSo Date: Thu, 6 Jul 2023 15:11:01 -0700 Subject: [PATCH 11/22] chore: passing actual value rather than hardcoded true to fix the unit test --- app/components/Contact/ContactForm.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/components/Contact/ContactForm.tsx b/app/components/Contact/ContactForm.tsx index 50be0f3c29..523b3572df 100644 --- a/app/components/Contact/ContactForm.tsx +++ b/app/components/Contact/ContactForm.tsx @@ -140,7 +140,7 @@ const ContactForm: React.FC = (props) => { id: formChange.id, formDataRecordId: formChange.formDataRecordId, newFormData: formData, - isUniqueValue: true, + isUniqueValue: isUniqueValue, changeStatus: "pending", }, }, From b4f6af0c3d64f03a11ca52e6668659c722961f2d Mon Sep 17 00:00:00 2001 From: SeSo Date: Mon, 10 Jul 2023 16:31:44 -0700 Subject: [PATCH 12/22] chore: add migration to update schemas --- ..._add_default_value_for_optional_fields.sql | 50 +++++++++++++++++++ ..._add_default_value_for_optional_fields.sql | 7 +++ schema/sqitch.plan | 1 + ..._add_default_value_for_optional_fields.sql | 13 +++++ 4 files changed, 71 insertions(+) create mode 100644 schema/deploy/data/0011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql create mode 100644 schema/revert/data/0011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql create mode 100644 schema/verify/data/0011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql diff --git a/schema/deploy/data/0011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql b/schema/deploy/data/0011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql new file mode 100644 index 0000000000..55b26f8e63 --- /dev/null +++ b/schema/deploy/data/0011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql @@ -0,0 +1,50 @@ +-- Deploy cif:data/0011_insert_json_schema_form_data_add_default_value_for_optional_fields to pg +-- requires: tables/form + +begin; + +--project +create temporary table project (json_data jsonb); +\copy project(json_data) from program 'sed ''s/\\/\\\\/g'' < data/prod/json_schema/project.json | tr -d ''\n'''; +-- project_contact +create temporary table project_contact (json_data jsonb); +\copy project_contact(json_data) from program 'sed ''s/\\/\\\\/g'' < data/prod/json_schema/project_contact.json | tr -d ''\n'''; +-- project_manager +create temporary table project_manager (json_data jsonb); +\copy project_manager(json_data) from program 'sed ''s/\\/\\\\/g'' < data/prod/json_schema/project_manager.json | tr -d ''\n'''; +-- reporting_requirement (quarterly / annual report) +create temporary table reporting_requirement (json_data jsonb); +\copy reporting_requirement(json_data) from program 'sed ''s/\\/\\\\/g'' < data/prod/json_schema/reporting_requirement.json | tr -d ''\n'''; +-- contact +create temporary table contact (json_data jsonb); +\copy contact(json_data) from program 'sed ''s/\\/\\\\/g'' < data/prod/json_schema/contact.json | tr -d ''\n'''; +-- operator +create temporary table operator (json_data jsonb); +\copy operator(json_data) from program 'sed ''s/\\/\\\\/g'' < data/prod/json_schema/operator.json | tr -d ''\n'''; +-- milestone +create temporary table milestone (json_data jsonb); +\copy milestone(json_data) from program 'sed ''s/\\/\\\\/g'' < data/prod/json_schema/milestone.json | tr -d ''\n'''; +--- project_summary_report +create temporary table project_summary_report (json_data jsonb); +\copy project_summary_report(json_data) from program 'sed ''s/\\/\\\\/g'' < data/prod/json_schema/project_summary_report.json | tr -d ''\n'''; + +with rows as ( +insert into cif.form(slug, form_change_commit_handler, json_schema, description) +values +('project', default, (select json_data from project), 'schema data relating to the project_overview form and the project table'), +('project_contact', default, (select json_data from project_contact), 'schema data relating to the project_contact form and the project_contact table'), +('project_manager', default, (select json_data from project_manager), 'schema data relating to the project_manager form and the project_manager table'), +('reporting_requirement', default, (select json_data from reporting_requirement), 'schema data relating to the quarterly report and annual report forms and the reporting_requirement table'), +('contact', default, (select json_data from contact), 'schema data relating to the contact form and the contact table'), +('operator', default, (select json_data from operator), 'schema data relating to the operator form and the operator table'), +('milestone', 'handle_milestone_form_change_commit', (select json_data from milestone), 'schema data relating to the milestone form and the reporting_requirement, milestone_report and payment tables'), +('project_summary_report', 'handle_project_summary_report_form_change_commit', (select json_data from project_summary_report), 'schema data relating to the project summary report') +on conflict(slug) do update +set json_schema=excluded.json_schema, + description=excluded.description, + json_schema_generator=excluded.json_schema_generator, + form_change_commit_handler=excluded.form_change_commit_handler +returning 1 +) select 'Inserted ' || count(*) || ' rows into cif.form' from rows; + +commit; diff --git a/schema/revert/data/0011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql b/schema/revert/data/0011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql new file mode 100644 index 0000000000..0469da34a9 --- /dev/null +++ b/schema/revert/data/0011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql @@ -0,0 +1,7 @@ +-- Revert cif:data/0011_insert_json_schema_form_data_add_default_value_for_optional_fields from pg + +begin; + +-- no revert needed + +commit; diff --git a/schema/sqitch.plan b/schema/sqitch.plan index ee990d0b7a..c1349a9d07 100644 --- a/schema/sqitch.plan +++ b/schema/sqitch.plan @@ -342,3 +342,4 @@ migrations/008_replace_bad_field_capitalization 2023-07-11T23:22:40Z Dylan Leard data/013_insert_json_schema_form_data_anticipated_funding_per_year_to_array_type 2023-06-23T19:53:12Z Brianna Cerkiewicz # Change anticipated funding per fiscal year to an array type in funding schemas @1.10.0 2023-07-13T22:53:40Z Dylan Leard # release v1.10.0 computed_columns/form_change_anticipated_funding_amount_per_fiscal_year [computed_columns/form_change_anticipated_funding_amount_per_fiscal_year@1.9.0] 2023-07-05T23:20:07Z Sepehr Sobhani # Using double arrow to return null if new form data prop value is null +data/0011_insert_json_schema_form_data_add_default_value_for_optional_fields 2023-07-10T17:50:36Z Sepehr Sobhani # Update json schema form data to have default value for optional fields diff --git a/schema/verify/data/0011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql b/schema/verify/data/0011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql new file mode 100644 index 0000000000..cd0b85d1e4 --- /dev/null +++ b/schema/verify/data/0011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql @@ -0,0 +1,13 @@ +-- Verify cif:data/0011_insert_json_schema_form_data_add_default_value_for_optional_fields on pg + +begin; + +do $$ + begin + assert ( + (select count(*) from cif.form) = 13 + ), 'The proper number of values were inserted in the cif.form table'; + end; +$$; + +rollback; From caf3085e2db9c50c629f8964867c06a37bf6fd7c Mon Sep 17 00:00:00 2001 From: SeSo Date: Tue, 11 Jul 2023 09:32:36 -0700 Subject: [PATCH 13/22] chore: fix file naming and verify file after rebase --- ..._data_add_default_value_for_optional_fields.sql} | 2 +- ...m_data_add_default_value_for_optional_fields.sql | 7 ------- ...m_data_add_default_value_for_optional_fields.sql | 7 +++++++ schema/sqitch.plan | 2 +- ...m_data_add_default_value_for_optional_fields.sql | 13 ------------- ...m_data_add_default_value_for_optional_fields.sql | 13 +++++++++++++ 6 files changed, 22 insertions(+), 22 deletions(-) rename schema/deploy/data/{0011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql => 011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql} (97%) delete mode 100644 schema/revert/data/0011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql create mode 100644 schema/revert/data/011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql delete mode 100644 schema/verify/data/0011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql create mode 100644 schema/verify/data/011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql diff --git a/schema/deploy/data/0011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql b/schema/deploy/data/011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql similarity index 97% rename from schema/deploy/data/0011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql rename to schema/deploy/data/011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql index 55b26f8e63..26044dcabe 100644 --- a/schema/deploy/data/0011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql +++ b/schema/deploy/data/011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql @@ -1,4 +1,4 @@ --- Deploy cif:data/0011_insert_json_schema_form_data_add_default_value_for_optional_fields to pg +-- Deploy cif:data/011_insert_json_schema_form_data_add_default_value_for_optional_fields to pg -- requires: tables/form begin; diff --git a/schema/revert/data/0011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql b/schema/revert/data/0011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql deleted file mode 100644 index 0469da34a9..0000000000 --- a/schema/revert/data/0011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql +++ /dev/null @@ -1,7 +0,0 @@ --- Revert cif:data/0011_insert_json_schema_form_data_add_default_value_for_optional_fields from pg - -begin; - --- no revert needed - -commit; diff --git a/schema/revert/data/011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql b/schema/revert/data/011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql new file mode 100644 index 0000000000..c75c2262f3 --- /dev/null +++ b/schema/revert/data/011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql @@ -0,0 +1,7 @@ +-- Revert cif:data/011_insert_json_schema_form_data_add_default_value_for_optional_fields from pg + +begin; + +-- no revert needed + +commit; diff --git a/schema/sqitch.plan b/schema/sqitch.plan index c1349a9d07..c5bc6f8e7a 100644 --- a/schema/sqitch.plan +++ b/schema/sqitch.plan @@ -342,4 +342,4 @@ migrations/008_replace_bad_field_capitalization 2023-07-11T23:22:40Z Dylan Leard data/013_insert_json_schema_form_data_anticipated_funding_per_year_to_array_type 2023-06-23T19:53:12Z Brianna Cerkiewicz # Change anticipated funding per fiscal year to an array type in funding schemas @1.10.0 2023-07-13T22:53:40Z Dylan Leard # release v1.10.0 computed_columns/form_change_anticipated_funding_amount_per_fiscal_year [computed_columns/form_change_anticipated_funding_amount_per_fiscal_year@1.9.0] 2023-07-05T23:20:07Z Sepehr Sobhani # Using double arrow to return null if new form data prop value is null -data/0011_insert_json_schema_form_data_add_default_value_for_optional_fields 2023-07-10T17:50:36Z Sepehr Sobhani # Update json schema form data to have default value for optional fields +data/011_insert_json_schema_form_data_add_default_value_for_optional_fields 2023-07-10T17:50:36Z Sepehr Sobhani # Update json schema form data to have default value for optional fields diff --git a/schema/verify/data/0011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql b/schema/verify/data/0011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql deleted file mode 100644 index cd0b85d1e4..0000000000 --- a/schema/verify/data/0011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql +++ /dev/null @@ -1,13 +0,0 @@ --- Verify cif:data/0011_insert_json_schema_form_data_add_default_value_for_optional_fields on pg - -begin; - -do $$ - begin - assert ( - (select count(*) from cif.form) = 13 - ), 'The proper number of values were inserted in the cif.form table'; - end; -$$; - -rollback; diff --git a/schema/verify/data/011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql b/schema/verify/data/011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql new file mode 100644 index 0000000000..9992d8dabc --- /dev/null +++ b/schema/verify/data/011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql @@ -0,0 +1,13 @@ +-- Verify cif:data/011_insert_json_schema_form_data_add_default_value_for_optional_fields on pg + +begin; + +do $$ + begin + assert ( + (select count(*) from cif.form) = 12 + ), 'The proper number of values were inserted in the cif.form table'; + end; +$$; + +rollback; From 04c24b00e99059ae58ebaaeb711717e3626d1f7a Mon Sep 17 00:00:00 2001 From: SeSo Date: Tue, 11 Jul 2023 16:20:26 -0700 Subject: [PATCH 14/22] chore: revert changes in `project_summary_report.json` file --- .../json_schema/project_summary_report.json | 19 +++++++------------ ..._add_default_value_for_optional_fields.sql | 3 +-- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/schema/data/prod/json_schema/project_summary_report.json b/schema/data/prod/json_schema/project_summary_report.json index 77a6181a96..c97d056f2a 100644 --- a/schema/data/prod/json_schema/project_summary_report.json +++ b/schema/data/prod/json_schema/project_summary_report.json @@ -10,29 +10,24 @@ "title": "Report Due Date" }, "submittedDate": { - "type": ["null", "string"], - "title": "Received Date", - "default": "undefined" + "type": "string", + "title": "Received Date" }, "comments": { - "type": ["null", "string"], - "title": "General Comments", - "default": "undefined" + "type": "string", + "title": "General Comments" }, "projectSummaryReportPayment": { "title": "Project Summary Report Payment", - "type": ["null", "number"], - "default": "undefined" + "type": "number" }, "paymentNotes": { "title": "Notes for the Payment", - "type": ["null", "string"], - "default": "undefined" + "type": "string" }, "dateSentToCsnr": { "title": "Date Invoice Sent to CSNR", - "type": ["null", "string"], - "default": "undefined" + "type": "string" } } } diff --git a/schema/deploy/data/011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql b/schema/deploy/data/011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql index 26044dcabe..1e0960ab62 100644 --- a/schema/deploy/data/011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql +++ b/schema/deploy/data/011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql @@ -37,8 +37,7 @@ values ('reporting_requirement', default, (select json_data from reporting_requirement), 'schema data relating to the quarterly report and annual report forms and the reporting_requirement table'), ('contact', default, (select json_data from contact), 'schema data relating to the contact form and the contact table'), ('operator', default, (select json_data from operator), 'schema data relating to the operator form and the operator table'), -('milestone', 'handle_milestone_form_change_commit', (select json_data from milestone), 'schema data relating to the milestone form and the reporting_requirement, milestone_report and payment tables'), -('project_summary_report', 'handle_project_summary_report_form_change_commit', (select json_data from project_summary_report), 'schema data relating to the project summary report') +('milestone', 'handle_milestone_form_change_commit', (select json_data from milestone), 'schema data relating to the milestone form and the reporting_requirement, milestone_report and payment tables') on conflict(slug) do update set json_schema=excluded.json_schema, description=excluded.description, From 7b31e87c65660e778edc450c37495ee7ddeb89d5 Mon Sep 17 00:00:00 2001 From: SeSo Date: Tue, 11 Jul 2023 16:22:13 -0700 Subject: [PATCH 15/22] test: remove mock functions from milestone and EI tests --- ...rojectEmissionIntensityReportForm.test.tsx | 25 ++++++------------- .../Form/ProjectMilestoneReportForm.test.tsx | 17 ++++--------- 2 files changed, 12 insertions(+), 30 deletions(-) diff --git a/app/tests/unit/components/Form/ProjectEmissionIntensityReportForm.test.tsx b/app/tests/unit/components/Form/ProjectEmissionIntensityReportForm.test.tsx index 001c9791c0..d1d272b1ff 100644 --- a/app/tests/unit/components/Form/ProjectEmissionIntensityReportForm.test.tsx +++ b/app/tests/unit/components/Form/ProjectEmissionIntensityReportForm.test.tsx @@ -7,8 +7,6 @@ import compiledFormIndexPageQuery, { FormIndexPageQuery, } from "__generated__/FormIndexPageQuery.graphql"; import emissionsIntensityProdSchema from "/schema/data/prod/json_schema/emission_intensity.json"; -import { useUpdateEmissionIntensityReportFormChange } from "mutations/ProjectEmissionIntensity/updateEmissionIntensityReportFormChange"; -import { mocked } from "jest-mock"; const testQuery = graphql` query ProjectEmissionIntensityReportFormQuery @relay_test_operation { @@ -90,16 +88,6 @@ const defaultComponentProps = { onSubmit: jest.fn(), }; -jest.mock( - "mutations/ProjectEmissionIntensity/updateEmissionIntensityReportFormChange" -); -const updateFormChange = jest.fn(); -let isUpdating = false; -mocked(useUpdateEmissionIntensityReportFormChange).mockImplementation(() => [ - updateFormChange, - isUpdating, -]); - const componentTestingHelper = new ComponentTestingHelper({ component: ProjectEmissionIntensityReportForm, testQuery: testQuery, @@ -366,7 +354,7 @@ describe("the emission intensity report form component", () => { } ); }); - it("shows the correct emission functional unit and production functional unit", () => { + it("shows the correct emission functional unit and production functional unit", async () => { componentTestingHelper.loadQuery(); componentTestingHelper.renderComponent(); @@ -382,11 +370,12 @@ describe("the emission intensity report form component", () => { expect(emissionFunctionalUnitInput).toHaveValue("tCO2e"); expect(productionFunctionalUnitInput).toHaveValue("GJ"); - userEvent.clear(emissionFunctionalUnitInput); - userEvent.type(emissionFunctionalUnitInput, "tCO2"); - userEvent.clear(productionFunctionalUnitInput); - userEvent.type(productionFunctionalUnitInput, "G"); - + act(() => { + userEvent.clear(emissionFunctionalUnitInput); + userEvent.type(emissionFunctionalUnitInput, "tCO2"); + userEvent.clear(productionFunctionalUnitInput); + userEvent.type(productionFunctionalUnitInput, "G"); + }); expect(screen.getAllByText(/tco2\/g/i)).toHaveLength(3); }); it("can call updateEmissionIntensityReportFormChangeMutation with zero values and decimal points on BEI/TEI/PEI and Total Lifetime Emission Reduction", () => { diff --git a/app/tests/unit/components/Form/ProjectMilestoneReportForm.test.tsx b/app/tests/unit/components/Form/ProjectMilestoneReportForm.test.tsx index e98b2ab034..7aeb000dc8 100644 --- a/app/tests/unit/components/Form/ProjectMilestoneReportForm.test.tsx +++ b/app/tests/unit/components/Form/ProjectMilestoneReportForm.test.tsx @@ -7,8 +7,6 @@ import compiledFormIndexPageQuery, { FormIndexPageQuery, } from "__generated__/FormIndexPageQuery.graphql"; import milestoneProdSchema from "../../../../../schema/data/prod/json_schema/milestone.json"; -import { useUpdateMilestone } from "mutations/MilestoneReport/updateMilestone"; -import { mocked } from "jest-mock"; const testQuery = graphql` query ProjectMilestoneReportFormQuery @relay_test_operation { @@ -189,14 +187,6 @@ const defaultComponentProps = { onSubmit: jest.fn(), }; -jest.mock("mutations/MilestoneReport/updateMilestone"); -const updateFormChange = jest.fn(); -let isUpdating = false; -mocked(useUpdateMilestone).mockImplementation(() => [ - updateFormChange, - isUpdating, -]); - const componentTestingHelper = new ComponentTestingHelper({ component: ProjectMilestoneReportForm, testQuery: testQuery, @@ -320,8 +310,11 @@ describe("The ProjectMilestoneReportForm", () => { act(() => { userEvent.click(screen.getAllByLabelText(/milestone type/i)[1]); }); - userEvent.click( - within(screen.getByRole("presentation")).getByText("General") + + act(() => + userEvent.click( + within(screen.getByRole("presentation")).getByText("General") + ) ); const updateMutationUnderTest = From 8c88155afaf19ea81eb78290a98cfc506678563d Mon Sep 17 00:00:00 2001 From: SeSo Date: Tue, 11 Jul 2023 16:31:27 -0700 Subject: [PATCH 16/22] chore: revert changes in milestone and project_manager schema --- schema/data/prod/json_schema/milestone.json | 28 ++++++++----------- .../prod/json_schema/project_manager.json | 5 ++-- 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/schema/data/prod/json_schema/milestone.json b/schema/data/prod/json_schema/milestone.json index d33aedcc33..7b59625977 100644 --- a/schema/data/prod/json_schema/milestone.json +++ b/schema/data/prod/json_schema/milestone.json @@ -26,7 +26,7 @@ "title": "Report Due Date" }, "submittedDate": { - "type": ["null", "string"], + "type": "string", "title": "Report Received Date" }, "substantialCompletionDate": { @@ -34,12 +34,11 @@ "title": "Substantial Completion Date" }, "certifiedBy": { - "type": ["null", "string"], - "title": "Certifier", - "default": null + "type": "string", + "title": "Certifier" }, "certifierProfessionalDesignation": { - "type": ["null", "string"], + "type": "string", "title": "Professional Designation", "default": "Professional Engineer", "anyOf": [ @@ -56,7 +55,7 @@ { "type": "string", "title": "N/A", - "enum": [""] + "enum": [null] } ] } @@ -81,21 +80,19 @@ "title": "Maximum Amount This Milestone" }, "adjustedGrossAmount": { - "type": ["null", "number"], - "title": "Gross Payment Amount This Milestone", - "default": null + "type": "number", + "title": "Gross Payment Amount This Milestone" }, "adjustedHoldbackAmount": { "type": "number", "title": "Holdback Amount This Milestone" }, "adjustedNetAmount": { - "type": ["null", "number"], - "title": "Net Payment Amount This Milestone", - "default": null + "type": "number", + "title": "Net Payment Amount This Milestone" }, "dateSentToCsnr": { - "type": ["null", "string"], + "type": "string", "title": "Date Invoice Sent to CSNR" } }, @@ -120,9 +117,8 @@ "title": "Milestone Type" }, "totalEligibleExpenses": { - "type": ["null", "number"], - "title": "Total Eligible Expenses", - "default": null + "type": "number", + "title": "Total Eligible Expenses" } } } diff --git a/schema/data/prod/json_schema/project_manager.json b/schema/data/prod/json_schema/project_manager.json index 7cad5a9067..9b4ef52638 100644 --- a/schema/data/prod/json_schema/project_manager.json +++ b/schema/data/prod/json_schema/project_manager.json @@ -5,9 +5,8 @@ "title": "Project Manager", "properties": { "cifUserId": { - "type": ["null", "number"], - "title": "Project Manager", - "default": "undefined" + "type": "number", + "title": "Project Manager" } } } From 95c57fa9347313da60a653f232c9b9f8c6e555c2 Mon Sep 17 00:00:00 2001 From: SeSo Date: Tue, 11 Jul 2023 16:33:02 -0700 Subject: [PATCH 17/22] chore: remove default from project schema and add new null value to project type --- app/components/Form/ProjectForm.tsx | 21 ++++++++++++++------- app/data/jsonSchemaForm/projectSchema.ts | 1 - schema/data/prod/json_schema/project.json | 3 +-- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/app/components/Form/ProjectForm.tsx b/app/components/Form/ProjectForm.tsx index 5dcaad6851..80cd1a7ea3 100644 --- a/app/components/Form/ProjectForm.tsx +++ b/app/components/Form/ProjectForm.tsx @@ -314,20 +314,27 @@ const ProjectForm: React.FC = (props) => { }, projectType: { ...projectSchema.properties.projectType, - anyOf: query.allProjectTypes.edges - .map(({ node }) => { + anyOf: [ + ...query.allProjectTypes.edges.map(({ node }) => { return { type: "string", title: node.name, enum: [node.name], value: node.name, }; - }) - .sort((a, b) => { - if (b.value === "Other") { - return -1; - } else return 0; }), + // Add null as an option + { + type: "null", + value: null, + enum: [null], + title: "N/A", + }, + ].sort((a, b) => { + if (b.value === "Other") { + return -1; + } else return 0; + }), }, projectStatusId: { ...projectSchema.properties.projectStatusId, diff --git a/app/data/jsonSchemaForm/projectSchema.ts b/app/data/jsonSchemaForm/projectSchema.ts index c07df32b74..1363f65cd1 100644 --- a/app/data/jsonSchemaForm/projectSchema.ts +++ b/app/data/jsonSchemaForm/projectSchema.ts @@ -26,7 +26,6 @@ const projectSchema = { projectType: { type: ["null", "string"], title: "Project Type", - default: undefined, }, score: { type: ["null", "number"], diff --git a/schema/data/prod/json_schema/project.json b/schema/data/prod/json_schema/project.json index bc7a3eb41b..5e2a29599a 100644 --- a/schema/data/prod/json_schema/project.json +++ b/schema/data/prod/json_schema/project.json @@ -32,8 +32,7 @@ }, "projectType": { "type": ["null", "string"], - "title": "Project Type", - "default": null + "title": "Project Type" }, "score": { "type": ["null", "number"], From 093b4d99c4db58638d1e26b45c47422dc990abc1 Mon Sep 17 00:00:00 2001 From: SeSo Date: Tue, 11 Jul 2023 17:04:59 -0700 Subject: [PATCH 18/22] chore: remove redundant file after rebase --- .../projectEmissionIntensitySchema.ts | 211 ------------------ 1 file changed, 211 deletions(-) delete mode 100644 app/data/jsonSchemaForm/projectEmissionIntensitySchema.ts diff --git a/app/data/jsonSchemaForm/projectEmissionIntensitySchema.ts b/app/data/jsonSchemaForm/projectEmissionIntensitySchema.ts deleted file mode 100644 index c262806441..0000000000 --- a/app/data/jsonSchemaForm/projectEmissionIntensitySchema.ts +++ /dev/null @@ -1,211 +0,0 @@ -import { emissionsIntentityTooltips } from "./tooltipText"; - -export const emissionIntensityReportSchema = { - $schema: "http://json-schema.org/draft-07/schema", - type: "object", - title: "Emissions Intensity Report", - properties: { - teimpReporting: { - type: "object", - title: "TEIMP Reporting", - required: [ - "measurementPeriodStartDate", - "measurementPeriodEndDate", - "emissionFunctionalUnit", - "baselineEmissionIntensity", - "targetEmissionIntensity", - ], - properties: { - measurementPeriodStartDate: { - title: "TEIMP Start Date", - type: "string", - }, - measurementPeriodEndDate: { - title: "TEIMP End Date", - type: "string", - }, - emissionFunctionalUnit: { - title: "Functional Unit", - type: "string", - }, - productionFunctionalUnit: { - title: "Production Functional Unit", - type: ["null", "string"], - default: null, - }, - baselineEmissionIntensity: { - title: "Baseline Emission Intensity (BEI)", - type: "number", - }, - targetEmissionIntensity: { - title: "Target Emission Intensity (TEI)", - type: "number", - }, - postProjectEmissionIntensity: { - title: "Post-Project Emission Intensity (PEI)", - type: ["null", "number"], - default: null, - }, - totalLifetimeEmissionReduction: { - title: "Total Project Lifetime Emissions Reductions", - type: ["null", "number"], - default: null, - }, - }, - }, - uponCompletion: { - type: "object", - title: "Upon Completion", - properties: { - adjustedEmissionsIntensityPerformance: { - title: "GHG Emission Intensity Performance", - type: ["null", "number"], - default: null, - }, - dateSentToCsnr: { - type: ["null", "string"], - title: "Date Invoice Sent to CSNR", - default: null, - }, - paymentPercentage: { - type: "number", - title: "Payment Percentage of Performance Milestone Amount (%)", - }, - holdbackAmountToDate: { - type: "number", - title: "Maximum Performance Milestone Amount", - default: undefined, - }, - actualPerformanceMilestoneAmount: { - type: "number", - title: "Actual Performance Milestone Amount", - default: undefined, - }, - }, - }, - }, -}; - -export const emissionIntensityReportingRequirementSchema = { - $schema: "http://json-schema.org/draft-07/schema", - type: "object", - title: "Reporting Requirement", - required: [], - properties: { - reportDueDate: { - type: ["null", "string"], - title: "Report Due Date", - default: null, - }, - submittedDate: { - type: ["null", "string"], - title: "Report Received Date", - default: null, - }, - comments: { - type: ["null", "string"], - title: "General Comments", - default: null, - }, - }, -}; - -export const emissionIntensityReportUiSchema = { - teimpReporting: { - emissionFunctionalUnit: { - "ui:widget": "TextWidget", - classNames: "functional-unit", - }, - productionFunctionalUnit: { - "ui:widget": "TextWidget", - classNames: "functional-unit", - }, - measurementPeriodStartDate: { - "ui:widget": "DateWidget", - }, - measurementPeriodEndDate: { - "ui:widget": "DateWidget", - }, - baselineEmissionIntensity: { - "ui:widget": "NumberWidget", - numberOfDecimalPlaces: 8, - }, - targetEmissionIntensity: { - "ui:widget": "NumberWidget", - numberOfDecimalPlaces: 8, - }, - postProjectEmissionIntensity: { - "ui:widget": "NumberWidget", - numberOfDecimalPlaces: 8, - }, - totalLifetimeEmissionReduction: { - "ui:widget": "NumberWidget", - numberOfDecimalPlaces: 8, - }, - }, - uponCompletion: { - adjustedEmissionsIntensityPerformance: { - "ui:widget": "AdjustableCalculatedValueWidget", - "ui:tooltip": { - text: emissionsIntentityTooltips.adjustedEmissionsIntensityPerformance, - }, - calculatedValueFormContextProperty: "calculatedEiPerformance", - isPercentage: true, - numberOfDecimalPlaces: 2, - hideOptional: true, - }, - calculatedPaymentPercentage: { - "ui:widget": "CalculatedValueWidget", - isPercentage: true, - numberOfDecimalPlaces: 2, - hideOptional: true, - calculatedValueFormContextProperty: "teimpPaymentPercentage", - }, - paymentPercentage: { - "ui:widget": "CalculatedValueWidget", - "ui:tooltip": { - text: emissionsIntentityTooltips.paymentPercentage, - }, - calculatedValueFormContextProperty: - "paymentPercentageOfPerformanceMilestoneAmount", - isPercentage: true, - hideOptional: true, - numberOfDecimalPlaces: 2, - }, - actualPerformanceMilestoneAmount: { - "ui:widget": "CalculatedValueWidget", - "ui:tooltip": { - text: emissionsIntentityTooltips.actualPerformanceMilestoneAmount, - }, - calculatedValueFormContextProperty: "actualPerformanceMilestoneAmount", - isMoney: true, - hideOptional: true, - }, - holdbackAmountToDate: { - "ui:widget": "CalculatedValueWidget", - "ui:tooltip": { - text: emissionsIntentityTooltips.holdbackAmountToDate, - }, - calculatedValueFormContextProperty: "holdbackAmountToDate", - isMoney: true, - hideOptional: true, - }, - dateSentToCsnr: { - "ui:widget": "DateWidget", - }, - }, -}; - -export const emissionIntensityReportingRequirementUiSchema = { - reportDueDate: { - "ui:widget": "DateWidget", - isDueDate: true, - }, - submittedDate: { - "ui:widget": "DateWidget", - isReceivedDate: true, - }, - comments: { - "ui:widget": "TextAreaWidget", - }, -}; From e23e14761c1a0668d00505f9e33f53eed9770258 Mon Sep 17 00:00:00 2001 From: SeSo Date: Thu, 13 Jul 2023 09:18:12 -0700 Subject: [PATCH 19/22] chore: make reporting requirement `reportDueDate` prop required --- schema/data/prod/json_schema/reporting_requirement.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/schema/data/prod/json_schema/reporting_requirement.json b/schema/data/prod/json_schema/reporting_requirement.json index 7fdd57d51a..3d513956fe 100644 --- a/schema/data/prod/json_schema/reporting_requirement.json +++ b/schema/data/prod/json_schema/reporting_requirement.json @@ -3,11 +3,11 @@ "$schema": "http://json-schema.org/draft-07/schema", "type": "object", "title": "Reporting Requirement", + "required": ["reportDueDate"], "properties": { "reportDueDate": { - "type": ["null", "string"], - "title": "Report Due Date", - "default": null + "type": "string", + "title": "Report Due Date" }, "submittedDate": { "type": ["null", "string"], From f627d9deac86b8cef877372b85582e904cbcb960 Mon Sep 17 00:00:00 2001 From: SeSo Date: Thu, 13 Jul 2023 10:04:07 -0700 Subject: [PATCH 20/22] chore: add a check to avoid happo flaky screenshots --- .../cif/project-revision/create-first-project-revision.cy.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/cypress/e2e/cif/project-revision/create-first-project-revision.cy.js b/app/cypress/e2e/cif/project-revision/create-first-project-revision.cy.js index b112159f22..03b042ece8 100644 --- a/app/cypress/e2e/cif/project-revision/create-first-project-revision.cy.js +++ b/app/cypress/e2e/cif/project-revision/create-first-project-revision.cy.js @@ -485,6 +485,7 @@ describe("when creating a project, the project page", () => { cy.findByText(/TEIMP End Date/i) .next() .contains(/Jan(\.)? 1, 2022/); + cy.contains("Changes saved").should("be.visible"); // a check to make sure happo is taking the right screenshot cy.happoAndAxe("Auto-generate quarterly reports", "generated", "main"); //generate annual reports @@ -509,6 +510,7 @@ describe("when creating a project, the project page", () => { .next() .contains(/Feb(\.)? 2, 2024/); cy.findAllByText(/^on track$/i).should("have.length", 5); + cy.contains("Changes saved").should("be.visible"); // a check to make sure happo is taking the right screenshot cy.happoAndAxe("Auto-generate annual reports", "generated", "main"); }); From 241430765a29b00dbc4139849e6a2a36ae62fb75 Mon Sep 17 00:00:00 2001 From: SeSo Date: Thu, 20 Jul 2023 13:42:03 -0700 Subject: [PATCH 21/22] chore: update files name after rebase --- ..._schema_form_data_add_default_value_for_optional_fields.sql} | 2 +- ..._schema_form_data_add_default_value_for_optional_fields.sql} | 2 +- schema/sqitch.plan | 2 +- ..._schema_form_data_add_default_value_for_optional_fields.sql} | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename schema/deploy/data/{011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql => 014_insert_json_schema_form_data_add_default_value_for_optional_fields.sql} (98%) rename schema/revert/data/{011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql => 014_insert_json_schema_form_data_add_default_value_for_optional_fields.sql} (52%) rename schema/verify/data/{011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql => 014_insert_json_schema_form_data_add_default_value_for_optional_fields.sql} (76%) diff --git a/schema/deploy/data/011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql b/schema/deploy/data/014_insert_json_schema_form_data_add_default_value_for_optional_fields.sql similarity index 98% rename from schema/deploy/data/011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql rename to schema/deploy/data/014_insert_json_schema_form_data_add_default_value_for_optional_fields.sql index 1e0960ab62..6c5621abf9 100644 --- a/schema/deploy/data/011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql +++ b/schema/deploy/data/014_insert_json_schema_form_data_add_default_value_for_optional_fields.sql @@ -1,4 +1,4 @@ --- Deploy cif:data/011_insert_json_schema_form_data_add_default_value_for_optional_fields to pg +-- Deploy cif:data/014_insert_json_schema_form_data_add_default_value_for_optional_fields to pg -- requires: tables/form begin; diff --git a/schema/revert/data/011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql b/schema/revert/data/014_insert_json_schema_form_data_add_default_value_for_optional_fields.sql similarity index 52% rename from schema/revert/data/011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql rename to schema/revert/data/014_insert_json_schema_form_data_add_default_value_for_optional_fields.sql index c75c2262f3..a262ca149e 100644 --- a/schema/revert/data/011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql +++ b/schema/revert/data/014_insert_json_schema_form_data_add_default_value_for_optional_fields.sql @@ -1,4 +1,4 @@ --- Revert cif:data/011_insert_json_schema_form_data_add_default_value_for_optional_fields from pg +-- Revert cif:data/014_insert_json_schema_form_data_add_default_value_for_optional_fields from pg begin; diff --git a/schema/sqitch.plan b/schema/sqitch.plan index c5bc6f8e7a..3c95e24be1 100644 --- a/schema/sqitch.plan +++ b/schema/sqitch.plan @@ -342,4 +342,4 @@ migrations/008_replace_bad_field_capitalization 2023-07-11T23:22:40Z Dylan Leard data/013_insert_json_schema_form_data_anticipated_funding_per_year_to_array_type 2023-06-23T19:53:12Z Brianna Cerkiewicz # Change anticipated funding per fiscal year to an array type in funding schemas @1.10.0 2023-07-13T22:53:40Z Dylan Leard # release v1.10.0 computed_columns/form_change_anticipated_funding_amount_per_fiscal_year [computed_columns/form_change_anticipated_funding_amount_per_fiscal_year@1.9.0] 2023-07-05T23:20:07Z Sepehr Sobhani # Using double arrow to return null if new form data prop value is null -data/011_insert_json_schema_form_data_add_default_value_for_optional_fields 2023-07-10T17:50:36Z Sepehr Sobhani # Update json schema form data to have default value for optional fields +data/014_insert_json_schema_form_data_add_default_value_for_optional_fields 2023-07-10T17:50:36Z Sepehr Sobhani # Update json schema form data to have default value for optional fields diff --git a/schema/verify/data/011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql b/schema/verify/data/014_insert_json_schema_form_data_add_default_value_for_optional_fields.sql similarity index 76% rename from schema/verify/data/011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql rename to schema/verify/data/014_insert_json_schema_form_data_add_default_value_for_optional_fields.sql index 9992d8dabc..506c7b4bc1 100644 --- a/schema/verify/data/011_insert_json_schema_form_data_add_default_value_for_optional_fields.sql +++ b/schema/verify/data/014_insert_json_schema_form_data_add_default_value_for_optional_fields.sql @@ -1,4 +1,4 @@ --- Verify cif:data/011_insert_json_schema_form_data_add_default_value_for_optional_fields on pg +-- Verify cif:data/014_insert_json_schema_form_data_add_default_value_for_optional_fields on pg begin; From 4ba0cae7a3346161008a66128022e86b8412f565 Mon Sep 17 00:00:00 2001 From: SeSo Date: Thu, 20 Jul 2023 15:32:55 -0700 Subject: [PATCH 22/22] fix: set milestone `certifierProfessionalDesignation` field to null when user selects N/A --- app/data/jsonSchemaForm/projectMilestoneUiSchema.ts | 1 + schema/data/prod/json_schema/milestone.json | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/data/jsonSchemaForm/projectMilestoneUiSchema.ts b/app/data/jsonSchemaForm/projectMilestoneUiSchema.ts index f8a127cd58..ed94332ec6 100644 --- a/app/data/jsonSchemaForm/projectMilestoneUiSchema.ts +++ b/app/data/jsonSchemaForm/projectMilestoneUiSchema.ts @@ -80,6 +80,7 @@ const projectMilestoneUiSchema = { "ui:col-md": 12, "bcgov:size": "small", "ui:widget": "SearchWidget", + "ui:placeholder": "Select a Professional Designation", }, adjustedGrossAmount: { "ui:widget": "AdjustableCalculatedValueWidget", diff --git a/schema/data/prod/json_schema/milestone.json b/schema/data/prod/json_schema/milestone.json index 7b59625977..edf16fbeec 100644 --- a/schema/data/prod/json_schema/milestone.json +++ b/schema/data/prod/json_schema/milestone.json @@ -38,7 +38,7 @@ "title": "Certifier" }, "certifierProfessionalDesignation": { - "type": "string", + "type": ["null", "string"], "title": "Professional Designation", "default": "Professional Engineer", "anyOf": [ @@ -53,9 +53,9 @@ "enum": ["Certified Professional Accountant"] }, { - "type": "string", - "title": "N/A", - "enum": [null] + "type": "null", + "enum": [null], + "title": "N/A" } ] }