Skip to content

Commit

Permalink
fix: [M3-8538] - Incorrect Commands in Linode CLI Modal (#11303)
Browse files Browse the repository at this point in the history
* fix: [M3-8538] - Fix Linode clone CLI Modal

* remove comments

* Fix cli command

* Fix typos and unit tests and add missing slash in api url

* Add changeset
  • Loading branch information
carrillo-erik authored Dec 10, 2024
1 parent ac15267 commit 81e55d5
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 14 deletions.
5 changes: 5 additions & 0 deletions packages/manager/.changeset/pr-11303-fixed-1733422977888.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Fixed
---

Incorrect Cloning Commands in Linode CLI Modal ([#11303](https://github.com/linode/manager/pull/11303))
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import { screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';

import { renderWithTheme } from 'src/utilities/testHelpers';
import { renderWithThemeAndHookFormContext } from 'src/utilities/testHelpers';

import { ApiAwarenessModal } from './ApiAwarenessModal';

import type { LinodeCreateFormValues } from '../utilities';
import type { ApiAwarenessModalProps } from './ApiAwarenessModal';

const defaultProps: ApiAwarenessModalProps = {
Expand All @@ -19,19 +20,22 @@ const renderComponent = (overrideProps?: Partial<ApiAwarenessModalProps>) => {
...defaultProps,
...overrideProps,
};
return renderWithTheme(<ApiAwarenessModal {...props} />);

return renderWithThemeAndHookFormContext<LinodeCreateFormValues>({
component: <ApiAwarenessModal {...props} />,
});
};

describe('ApiAwarenessModal', () => {
it('Should not render ApiAwarenessModal componet', () => {
it('Should not render ApiAwarenessModal component', () => {
renderComponent();
expect(screen.queryByText('Create Linode')).not.toBeInTheDocument();
});
it('Should render ApiAwarenessModal componet when enabled', () => {
it('Should render ApiAwarenessModal component when enabled', () => {
renderComponent({ isOpen: true });
screen.getByText('Create Linode');
});
it('Should invoke onClose handler upon cliking close button', async () => {
it('Should invoke onClose handler upon clicking close button', async () => {
renderComponent({ isOpen: true });
await userEvent.click(screen.getByTestId('close-button'));
expect(defaultProps.onClose).toHaveBeenCalledTimes(1);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import { Typography } from '@linode/ui';
import { useTheme } from '@mui/material/styles';
import React, { useMemo } from 'react';
import { useFormContext } from 'react-hook-form';

import { CodeBlock } from 'src/components/CodeBlock/CodeBlock';
import { Link } from 'src/components/Link';
import { SafeTabPanel } from 'src/components/Tabs/SafeTabPanel';
import { sendApiAwarenessClickEvent } from 'src/utilities/analytics/customEventAnalytics';
import { generateCurlCommand } from 'src/utilities/codesnippets/generate-cURL';

import { useLinodeCreateQueryParams } from '../utilities';

import type { LinodeCreateFormValues } from '../utilities';
import type { CreateLinodeRequest } from '@linode/api-v4/lib/linodes';

export interface CurlTabPanelProps {
Expand All @@ -19,10 +23,20 @@ export interface CurlTabPanelProps {
export const CurlTabPanel = ({ index, payLoad, title }: CurlTabPanelProps) => {
const theme = useTheme();

const curlCommand = useMemo(
() => generateCurlCommand(payLoad, '/linode/instances'),
[payLoad]
);
const { getValues } = useFormContext<LinodeCreateFormValues>();
const sourceLinodeID = getValues('linode.id');

const { params } = useLinodeCreateQueryParams();
const linodeCLIAction = params.type === 'Clone Linode' ? 'clone' : 'create';
const path =
linodeCLIAction === 'create'
? '/linode/instances'
: `/linode/instances/${sourceLinodeID}/clone`;

const curlCommand = useMemo(() => generateCurlCommand(payLoad, path), [
path,
payLoad,
]);

return (
<SafeTabPanel index={index}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import { Typography } from '@linode/ui';
import React, { useMemo } from 'react';
import { useFormContext } from 'react-hook-form';

import { CodeBlock } from 'src/components/CodeBlock/CodeBlock';
import { Link } from 'src/components/Link';
import { SafeTabPanel } from 'src/components/Tabs/SafeTabPanel';
import { sendApiAwarenessClickEvent } from 'src/utilities/analytics/customEventAnalytics';
import { generateCLICommand } from 'src/utilities/codesnippets/generate-cli';

import { useLinodeCreateQueryParams } from '../utilities';

import type { LinodeCreateFormValues } from '../utilities';
import type { CreateLinodeRequest } from '@linode/api-v4/lib/linodes';

export interface LinodeCLIPanelProps {
Expand All @@ -20,7 +24,16 @@ export const LinodeCLIPanel = ({
payLoad,
title,
}: LinodeCLIPanelProps) => {
const cliCommand = useMemo(() => generateCLICommand(payLoad), [payLoad]);
const { params } = useLinodeCreateQueryParams();
const linodeCLIAction = params.type;

const { getValues } = useFormContext<LinodeCreateFormValues>();
const sourceLinodeID = getValues('linode.id');

const cliCommand = useMemo(
() => generateCLICommand(payLoad, sourceLinodeID, linodeCLIAction),
[linodeCLIAction, payLoad, sourceLinodeID]
);

return (
<SafeTabPanel index={index}>
Expand Down
18 changes: 14 additions & 4 deletions packages/manager/src/utilities/codesnippets/generate-cli.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import {
import type { PlacementGroup } from '@linode/api-v4';
import type {
ConfigInterfaceIPv4,
UserData,
} from '@linode/api-v4/lib/linodes/types';

import type { PlacementGroup } from '@linode/api-v4';

// Credit: https://github.com/xxorax/node-shell-escape
function escapeStringForCLI(s: string): string {
if (/[^A-Za-z0-9_\/:=-]/.test(s)) {
Expand Down Expand Up @@ -111,7 +110,18 @@ const dataEntriesReduce = (acc: string[], [key, value]: JSONFieldToArray) => {
return acc;
};

export const generateCLICommand = (data: {}) => {
export const generateCLICommand = (
data: {},
sourceLinodeID?: number,
linodeCLIAction?: string
) => {
const dataForCLI = Object.entries(data).reduce(dataEntriesReduce, []);

if (linodeCLIAction === 'Clone Linode') {
return `linode-cli linodes clone ${sourceLinodeID} \\\n${dataForCLI.join(
' \\\n'
)}`;
}

return `linode-cli linodes create \\\n${dataForCLI.join(' \\\n')}`;
};

0 comments on commit 81e55d5

Please sign in to comment.