From 6d5bf54d701b4fcdbd6839d682e25dbf2d08f35e Mon Sep 17 00:00:00 2001 From: Volodymyr Petrov Date: Fri, 21 Oct 2022 17:00:29 +0300 Subject: [PATCH 1/3] add regex matcher for custom transformation GitHub url --- airbyte-webapp/src/locales/en.json | 3 ++- .../Connection/TransformationForm/TransformationForm.tsx | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/airbyte-webapp/src/locales/en.json b/airbyte-webapp/src/locales/en.json index 8bff60bd0e71..d03d0fbd6ddf 100644 --- a/airbyte-webapp/src/locales/en.json +++ b/airbyte-webapp/src/locales/en.json @@ -164,13 +164,14 @@ "form.transformationName": "Transformation name *", "form.transformationType": "Transformation type *", "form.dockerUrl": "Docker image URL with dbt installed *", - "form.repositoryUrl": "Git repository URL of the custom transformation project *", "form.entrypoint": "Entrypoint arguments for dbt cli to run the project *", "form.entrypoint.docs": "Learn more", "form.entrypoint.linked": "Entrypoint arguments for dbt cli to run the project. Learn more *", "form.gitBranch": "Git branch name (leave blank for default branch)", "form.selectType": "Select a type", + "form.repositoryUrl": "Git repository URL of the custom transformation project *", "form.repositoryUrl.placeholder": "https://github.com/organisation/git_repo.git", + "form.repositoryUrl.invalidUrl": "Please enter a valid Git repository URL", "form.sourceNamespace": "Source namespace", "form.sourceStreamName": "Source stream name", diff --git a/airbyte-webapp/src/views/Connection/TransformationForm/TransformationForm.tsx b/airbyte-webapp/src/views/Connection/TransformationForm/TransformationForm.tsx index 5ba2540e75fe..61005bbe3a0c 100644 --- a/airbyte-webapp/src/views/Connection/TransformationForm/TransformationForm.tsx +++ b/airbyte-webapp/src/views/Connection/TransformationForm/TransformationForm.tsx @@ -32,7 +32,10 @@ const validationSchema = yup.object({ name: yup.string().required("form.empty.error"), operatorConfiguration: yup.object({ dbt: yup.object({ - gitRepoUrl: yup.string().required("form.empty.error"), + gitRepoUrl: yup + .string() + .required("form.empty.error") + .matches(/((http(s)?)|(git@[\w.]+))(:(\/\/)?)([\w.@:/\-~]+)(\.git)$/, "form.repositoryUrl.invalidUrl"), dockerImage: yup.string().required("form.empty.error"), dbtArguments: yup.string().required("form.empty.error"), gitRepoBranch: yup.string().nullable(), From 54b4eddfb9ea78cc214c27fc06b96984068c7e73 Mon Sep 17 00:00:00 2001 From: Volodymyr Petrov Date: Tue, 25 Oct 2022 19:33:53 +0300 Subject: [PATCH 2/3] move validationSchema to separate file --- .../TransformationForm/TransformationForm.tsx | 17 +---------------- .../Connection/TransformationForm/utils.ts | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 16 deletions(-) create mode 100644 airbyte-webapp/src/views/Connection/TransformationForm/utils.ts diff --git a/airbyte-webapp/src/views/Connection/TransformationForm/TransformationForm.tsx b/airbyte-webapp/src/views/Connection/TransformationForm/TransformationForm.tsx index 61005bbe3a0c..389ecff8df23 100644 --- a/airbyte-webapp/src/views/Connection/TransformationForm/TransformationForm.tsx +++ b/airbyte-webapp/src/views/Connection/TransformationForm/TransformationForm.tsx @@ -3,7 +3,6 @@ import type { FormikErrors } from "formik/dist/types"; import { getIn, useFormik } from "formik"; import React from "react"; import { FormattedMessage, useIntl } from "react-intl"; -import * as yup from "yup"; import { FormChangeTracker } from "components/FormChangeTracker"; import { ControlLabels } from "components/LabeledControl"; @@ -20,6 +19,7 @@ import { links } from "utils/links"; import { equal } from "utils/objects"; import styles from "./TransformationForm.module.scss"; +import { validationSchema } from "./utils"; interface TransformationProps { transformation: OperationCreate; @@ -28,21 +28,6 @@ interface TransformationProps { isNewTransformation?: boolean; } -const validationSchema = yup.object({ - name: yup.string().required("form.empty.error"), - operatorConfiguration: yup.object({ - dbt: yup.object({ - gitRepoUrl: yup - .string() - .required("form.empty.error") - .matches(/((http(s)?)|(git@[\w.]+))(:(\/\/)?)([\w.@:/\-~]+)(\.git)$/, "form.repositoryUrl.invalidUrl"), - dockerImage: yup.string().required("form.empty.error"), - dbtArguments: yup.string().required("form.empty.error"), - gitRepoBranch: yup.string().nullable(), - }), - }), -}); - function prepareLabelFields( errors: FormikErrors, name: string diff --git a/airbyte-webapp/src/views/Connection/TransformationForm/utils.ts b/airbyte-webapp/src/views/Connection/TransformationForm/utils.ts new file mode 100644 index 000000000000..50fa38792737 --- /dev/null +++ b/airbyte-webapp/src/views/Connection/TransformationForm/utils.ts @@ -0,0 +1,16 @@ +import * as yup from "yup"; + +export const validationSchema = yup.object({ + name: yup.string().required("form.empty.error"), + operatorConfiguration: yup.object({ + dbt: yup.object({ + gitRepoUrl: yup + .string() + .required("form.empty.error") + .matches(/((http(s)?)|(git@[\w.]+))(:(\/\/)?)([\w.@:/\-~]+)(\.git)$/, "form.repositoryUrl.invalidUrl"), + dockerImage: yup.string().required("form.empty.error"), + dbtArguments: yup.string().required("form.empty.error"), + gitRepoBranch: yup.string().nullable(), + }), + }), +}); From f1698b18f0e188050b72f793599dafe20556514a Mon Sep 17 00:00:00 2001 From: Volodymyr Petrov Date: Tue, 25 Oct 2022 19:34:59 +0300 Subject: [PATCH 3/3] add tests for validationSchema --- .../TransformationForm/utils.test.ts | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 airbyte-webapp/src/views/Connection/TransformationForm/utils.test.ts diff --git a/airbyte-webapp/src/views/Connection/TransformationForm/utils.test.ts b/airbyte-webapp/src/views/Connection/TransformationForm/utils.test.ts new file mode 100644 index 000000000000..5640544e4cbf --- /dev/null +++ b/airbyte-webapp/src/views/Connection/TransformationForm/utils.test.ts @@ -0,0 +1,86 @@ +import { merge } from "lodash"; +import { InferType, ValidationError } from "yup"; + +import { validationSchema } from "./utils"; + +describe(" - validationSchema", () => { + const customTransformationFields: InferType = { + name: "test name", + operatorConfiguration: { + dbt: { + gitRepoUrl: "https://github.com/username/example.git", + dockerImage: "image", + dbtArguments: "arguments", + gitRepoBranch: "", + }, + }, + }; + + it("should successfully validate the schema", async () => { + const result = validationSchema.validate(customTransformationFields); + + await expect(result).resolves.toBeTruthy(); + }); + + it("should fail if 'name' is empty", async () => { + await expect(async () => { + await validationSchema.validateAt( + "name", + merge(customTransformationFields, { + name: "", + }) + ); + }).rejects.toThrow(ValidationError); + }); + + it("should fail if 'gitRepoUrl' is invalid", async () => { + await expect(async () => { + await validationSchema.validateAt( + "operatorConfiguration.dbt.gitRepoUrl", + merge(customTransformationFields, { + operatorConfiguration: { dbt: { gitRepoUrl: "" } }, + }) + ); + }).rejects.toThrow(ValidationError); + + await expect(async () => { + await validationSchema.validateAt( + "operatorConfiguration.dbt.gitRepoUrl", + merge(customTransformationFields, { + operatorConfiguration: { dbt: { gitRepoUrl: "https://github.com/username/example.git " } }, + }) + ); + }).rejects.toThrow(ValidationError); + + await expect(async () => { + await validationSchema.validateAt( + "operatorConfiguration.dbt.gitRepoUrl", + merge(customTransformationFields, { + operatorConfiguration: { dbt: { gitRepoUrl: "https://github.com/username/example.git/" } }, + }) + ); + }).rejects.toThrow(ValidationError); + }); + + it("should fail if 'dockerImage' is empty", async () => { + await expect(async () => { + await validationSchema.validateAt( + "operatorConfiguration.dbt.dockerImage", + merge(customTransformationFields, { + operatorConfiguration: { dbt: { dockerImage: "" } }, + }) + ); + }).rejects.toThrow(ValidationError); + }); + + it("should fail if 'dbtArguments' is empty", async () => { + await expect(async () => { + await validationSchema.validateAt( + "operatorConfiguration.dbt.dbtArguments", + merge(customTransformationFields, { + operatorConfiguration: { dbt: { dbtArguments: "" } }, + }) + ); + }).rejects.toThrow(ValidationError); + }); +});