Skip to content

Commit

Permalink
fix(portal): fix uploading yaml file validation failed on linux (need…
Browse files Browse the repository at this point in the history
… check)
  • Loading branch information
james-tran-3005 committed Dec 13, 2024
1 parent 165fcdb commit 94b6371
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 75 deletions.
8 changes: 4 additions & 4 deletions kraken-app/kraken-app-portal/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion kraken-app/kraken-app-portal/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"js-base64": "^3.7.7",
"js-yaml": "^4.1.0",
"lodash": "^4.17.21",
"nanoid": "^5.0.7",
"nanoid": "^5.0.9",
"path": "^0.12.7",
"qs": "^6.12.1",
"react": "^18.2.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,27 @@ import { cloneDeep, get, isEmpty, set } from "lodash";
import { useEffect, useState } from "react";
import { useNavigate, useParams } from "react-router";
import SwaggerInfo from "../NewAPIServer/components/SwaggerInfo";
import { tranformSwaggerToArray } from "../NewAPIServer/components/UploadYaml";
import styles from "./index.module.scss";

const tranformSwaggerToArray = (data: any) => {
const paths = data.paths;
const pathsArray = [];

for (const path in paths) {
for (const method in paths[path]) {
const pathObject = {
key: `${path} ${method}`,
title: path,
description: method,
info: paths[path][method],
};
pathsArray.push(pathObject);
}
}

return pathsArray;
};

const APIServerEditSelection = () => {
const { currentProduct } = useAppStore();
const { componentId } = useParams();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
flex: 1;
width: 100%;
height: 100%;
max-width: calc(100vw - 620px);
overflow-y: auto;
> .center {
box-sizing: border-box;
Expand Down Expand Up @@ -129,6 +128,6 @@
flex: 1;
width: 100%;
height: 100%;
max-width: calc(100vw - 620px);
max-width: 100%;
overflow-y: auto;
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ import {
} from "lodash";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { Link } from "react-router-dom";
import { useSessionStorage } from "usehooks-ts";
import { Deployment } from "./components/Deployment";
import DeploymentInfo from "./components/DeploymentInfo";
import HeaderMapping from "./components/HeaderMapping";
Expand All @@ -52,8 +51,6 @@ enum EMainTab {
deploy = "deploy",
}

const collapsedStyle = { maxWidth: `calc(100vw - 462px)` };

const NewAPIMapping = ({
refetch,
isRequiredMapping,
Expand All @@ -62,7 +59,6 @@ const NewAPIMapping = ({
isRequiredMapping: boolean;
}) => {
const pathQuery = usePathQuery();
const [collapsed] = useSessionStorage("collapsed", false);
const { currentProduct } = useAppStore();
const { activeTab, setActiveTab } = useMappingUiStore();
const {
Expand Down Expand Up @@ -523,7 +519,6 @@ const NewAPIMapping = ({
<div
ref={ref}
className={styles.newContent}
style={collapsed ? collapsedStyle : {}}
>
{upgradingVersion && (
<Alert
Expand All @@ -544,7 +539,6 @@ const NewAPIMapping = ({
<Flex
gap={12}
className={styles.mainWrapper}
style={collapsed ? collapsedStyle : {}}
>
<div className={styles.center}>
{!isRequiredMapping && (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,57 @@
import { fireEvent, getAllByTestId, render } from "@testing-library/react";
import { QueryClientProvider } from "@tanstack/react-query";
import { queryClient } from "@/utils/helpers/reactQuery";
import { BrowserRouter } from "react-router-dom";
import { fireEvent, render, waitFor } from "@/__test__/utils";
import NewAPIServer from "..";
import SelectAPIServer from '../components/SelectAPIServer';
import { isURL } from '@/utils/helpers/url';
import { validateServerName, validateURL } from '@/utils/helpers/validators';
import { Mock } from 'vitest';
import UploadYaml from "../components/UploadYaml";
import { Form, FormInstance } from "antd";

vi.mock('@/utils/helpers/url', () => ({
isURL: vi.fn(),
}));

test("test API new", () => {
const { container } = render(
<QueryClientProvider client={queryClient}>
<BrowserRouter>
<NewAPIServer />
</BrowserRouter>
</QueryClientProvider>
const createFormMock = () => {
const formInstance: FormInstance<any> = {} as any;
const FakeComponent = () => {
const [form] = Form.useForm();
Object.assign(formInstance, form);

formInstance.getFieldError = () => ['mock error']

return null;
};
render(<FakeComponent />);

return formInstance;
};

test("test API new", async () => {
const { container, getByText } = render(
<NewAPIServer />
);

expect(container).toBeInTheDocument();

expect(getByText('API spec')).toBeInTheDocument()
});

test('uploading openapi yaml file', async () => {
vi.spyOn(Form, 'useWatch').mockReturnValue({
file: new File(['(⌐□_□)'], 'chucknorris.png', { type: 'image/png' })
})

const { container, getByText, getByTestId } = render(<UploadYaml form={createFormMock()} />)
expect(container).toBeInTheDocument()

const btnUpload = getByTestId('btnUploadReplace')
fireEvent.click(btnUpload)

await waitFor(() => expect(getByText('Upload a new file will replace the existing one')).toBeInTheDocument())
fireEvent.click(getByText('Continue'))

fireEvent.click(getByTestId('btnViewFileContent'))
})

test("test SelectApiServer", async () => {
vi.mock("@/hooks/product", async () => {
Expand All @@ -38,16 +67,12 @@ test("test SelectApiServer", async () => {
};
});

const { container } = render(
<QueryClientProvider client={queryClient}>
<BrowserRouter>
<SelectAPIServer />
</BrowserRouter>
</QueryClientProvider>
const { container, getAllByTestId } = render(
<SelectAPIServer />
);
expect(container).toBeInTheDocument();
const input = getAllByTestId(container, "api-seller-name-input")[0];
const formContainer = getAllByTestId(container, "api-seller-name-container")[0];
const input = getAllByTestId("api-seller-name-input")[0];
const formContainer = getAllByTestId("api-seller-name-container")[0];
fireEvent.change(input, { target: { value: "test" } });
expect(formContainer).toBeInTheDocument();
});
Expand All @@ -66,16 +91,12 @@ test("test SelectApiServer", async () => {
};
});

const { container } = render(
<QueryClientProvider client={queryClient}>
<BrowserRouter>
<SelectAPIServer />
</BrowserRouter>
</QueryClientProvider>
const { container, getAllByTestId } = render(
<SelectAPIServer />
);
expect(container).toBeInTheDocument();
const input = getAllByTestId(container, "api-seller-name-input")[0];
const formContainer = getAllByTestId(container, "api-seller-name-container")[0];
const input = getAllByTestId("api-seller-name-input")[0];
const formContainer = getAllByTestId("api-seller-name-container")[0];
fireEvent.change(input, { target: { value: "test" } });
expect(formContainer).toBeInTheDocument();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { Text } from "@/components/Text";
import { UploadOutlined, PaperClipOutlined } from "@ant-design/icons";
import { Upload, notification, Button, Form, FormInstance } from "antd";
import clsx from "clsx";
import { decode } from "js-base64";
import { get } from "lodash";
import { useEffect, useState } from "react";
import { useBoolean } from "usehooks-ts";
Expand All @@ -16,24 +15,28 @@ type Props = {
form: FormInstance<any>;
};

export const tranformSwaggerToArray = (data: any) => {
const paths = data.paths;
const pathsArray = [];
const uploadYamlFile = async (value: any) => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = function (evt) {
const content = evt.target?.result as string

for (const path in paths) {
for (const method in paths[path]) {
const pathObject = {
key: `${path} ${method}`,
title: path,
description: method,
info: paths[path][method],
};
pathsArray.push(pathObject);
}
}
const isOpenApi = content?.startsWith("openapi:");
const isSwagger = content?.startsWith("swagger:");
if (!isOpenApi && !isSwagger) {
reject(
new Error("Please upload valid open api spec in yaml format")
);
}

return pathsArray;
};
resolve(true);
};
reader.onerror = function (error) {
reject(error)
};
reader.readAsText(value.file, 'utf-8');
})
}

const UploadYaml = ({ form }: Props) => {
const {
Expand All @@ -42,6 +45,7 @@ const UploadYaml = ({ form }: Props) => {
setFalse: closeDrawer,
} = useBoolean(false);
const file = Form.useWatch("file", form);

const [content, setContent] = useState("");
const handleReplace = () => {
closeModal();
Expand Down Expand Up @@ -114,21 +118,8 @@ const UploadYaml = ({ form }: Props) => {
if (!file?.file) {
return Promise.resolve();
}
const swaggerData = await new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result);
reader.onerror = reject;
reader.readAsDataURL(value.file);
});
const swaggerText = decode(swaggerData as string);
const idxOpenAPI = swaggerText?.indexOf("openapi:");
const idxSwagger = swaggerText?.indexOf("swagger:");
if (idxOpenAPI === -1 && idxSwagger === -1) {
return Promise.reject(
new Error("Please upload valid open api spec in yaml format")
);
}
return Promise.resolve();

return uploadYamlFile(value)
},
}),
]}
Expand All @@ -147,7 +138,7 @@ const UploadYaml = ({ form }: Props) => {
return false;
}}
>
<Button icon={<UploadOutlined />}>Click to upload</Button>
<Button data-testid="btnUpload" icon={<UploadOutlined />}>Click to upload</Button>
</Upload>
</Form.Item>

Expand All @@ -156,7 +147,7 @@ const UploadYaml = ({ form }: Props) => {
label="Upload API Spec in yaml format :"
style={{ display: !file?.file ? "none" : "block" }}
>
<Button icon={<UploadOutlined />} onClick={openModal}>
<Button data-testid="btnUploadReplace" icon={<UploadOutlined />} onClick={openModal}>
Click to upload
</Button>
</Form.Item>
Expand All @@ -165,6 +156,7 @@ const UploadYaml = ({ form }: Props) => {
<PaperClipOutlined />
<Text.LightMedium>{get(file, "file.name", "")}</Text.LightMedium>
<Text.LightMedium
data-testid="btnViewFileContent"
color="#2962FF"
role="none"
style={{ cursor: "pointer" }}
Expand Down

0 comments on commit 94b6371

Please sign in to comment.