Skip to content

Commit

Permalink
test(designer): Add unit tests for graph container node (#6415)
Browse files Browse the repository at this point in the history
* Add snpashots and unit tests for cards

* Add test cases for graph container

* Fix typos
  • Loading branch information
ccastrotrejo authored Jan 16, 2025
1 parent 1caa3aa commit 98271a8
Show file tree
Hide file tree
Showing 4 changed files with 471 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`GraphContainer component > renders with active prop set to false 1`] = `
<div
className="msla-graph-container msla-card-inactive"
/>
`;

exports[`GraphContainer component > renders with default props 1`] = `
<div
className="msla-graph-container"
/>
`;

exports[`GraphContainer component > renders with selected and active props 1`] = `
<div
className="msla-graph-container selected msla-card-inactive"
/>
`;

exports[`GraphContainer component > renders with selected prop 1`] = `
<div
className="msla-graph-container selected"
/>
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { describe, it, expect } from 'vitest';
import renderer from 'react-test-renderer';
import { GraphContainer } from '../index';
import React from 'react';

describe('GraphContainer component', () => {
it('renders with default props', () => {
const container = renderer.create(<GraphContainer />).toJSON();
expect(container).toMatchSnapshot();
expect(container).toHaveProperty('props.className', expect.stringContaining('msla-graph-container'));
expect(container).not.toHaveProperty('props.className', expect.stringContaining('selected'));
expect(container).not.toHaveProperty('props.className', expect.stringContaining('msla-card-inactive'));
});

it('renders with selected prop', () => {
const container = renderer.create(<GraphContainer selected={true} />).toJSON();
expect(container).toMatchSnapshot();
expect(container).toHaveProperty('props.className', expect.stringContaining('msla-graph-container'));
expect(container).toHaveProperty('props.className', expect.stringContaining('selected'));
expect(container).not.toHaveProperty('props.className', expect.stringContaining('msla-card-inactive'));
});

it('renders with active prop set to false', () => {
const container = renderer.create(<GraphContainer active={false} />).toJSON();
expect(container).toMatchSnapshot();
expect(container).toHaveProperty('props.className', expect.stringContaining('msla-graph-container'));
expect(container).not.toHaveProperty('props.className', expect.stringContaining('selected'));
expect(container).toHaveProperty('props.className', expect.stringContaining('msla-card-inactive'));
});

it('renders with selected and active props', () => {
const container = renderer.create(<GraphContainer selected={true} active={false} />).toJSON();
expect(container).toMatchSnapshot();
expect(container).toHaveProperty('props.className', expect.stringContaining('msla-graph-container'));
expect(container).toHaveProperty('props.className', expect.stringContaining('selected'));
expect(container).toHaveProperty('props.className', expect.stringContaining('msla-card-inactive'));
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import React from 'react';
import renderer from 'react-test-renderer';
import GraphContainerNode from '../GraphContainerNode';
import { vi, beforeEach, describe, Mock, it, expect } from 'vitest';
import { useMonitoringView, useReadOnly } from '../../../core/state/designerOptions/designerOptionsSelectors';
import { useIsNodeSelectedInOperationPanel } from '../../../core/state/panel/panelSelectors';
import { useNodeMetadata } from '../../../core';
import { useActionMetadata, useIsLeafNode, useParentRunId, useRunData } from '../../../core/state/workflow/workflowSelectors';
import { useNodeSize, useNodeLeafIndex, SUBGRAPH_TYPES } from '@microsoft/logic-apps-shared';
import { NodeProps } from '@xyflow/react';

vi.mock('../../../core/state/designerOptions/designerOptionsSelectors', () => ({
useReadOnly: vi.fn(),
useMonitoringView: vi.fn(),
}));

vi.mock('../../../core/state/panel/panelSelectors', () => ({
useIsNodeSelectedInOperationPanel: vi.fn(),
}));

vi.mock('../../../core/state/workflow/workflowSelectors', () => ({
useActionMetadata: vi.fn(),
useNodeMetadata: vi.fn(),
useIsLeafNode: vi.fn(),
useParentRunId: vi.fn(),
useRunData: vi.fn(),
}));

vi.mock(import('@microsoft/logic-apps-shared'), async (importOriginal) => {
const actual = await importOriginal();
return {
...actual,
useNodeSize: vi.fn(),
useNodeLeafIndex: vi.fn(),
};
});

vi.mock(import('../../connections/dropzone'), async (importOriginal) => {
const actual = await importOriginal();
return {
...actual,
DropZone: (({ children, ...props }) => <div {...props}>{'DropZone'}</div>) as any,
};
});

vi.mock(import('@xyflow/react'), async (importOriginal) => {
const actual = await importOriginal();
return {
...actual,
Handle: (({ children, ...props }) => <div {...props}>{'Handle reactflow'}</div>) as any,
};
});

describe('GraphContainerNode', () => {
const defaultProps = {
id: 'mockId',
} as NodeProps;

beforeEach(() => {
(useReadOnly as Mock).mockReturnValue(false);
(useIsNodeSelectedInOperationPanel as Mock).mockReturnValue(false);
(useActionMetadata as Mock).mockReturnValue({});
(useNodeMetadata as Mock).mockReturnValue({});
(useIsLeafNode as Mock).mockReturnValue(false);
(useMonitoringView as Mock).mockReturnValue(false);
(useParentRunId as Mock).mockReturnValue(null);
(useRunData as Mock).mockReturnValue({});
(useNodeSize as Mock).mockReturnValue({ width: 100, height: 100 });
(useNodeLeafIndex as Mock).mockReturnValue(0);
});

it('should render without crashing', () => {
const tree = renderer.create(<GraphContainerNode {...defaultProps} />).toJSON();
expect(tree).toMatchSnapshot();
});

it('should render with footer and be a subgraph', () => {
(useNodeMetadata as Mock).mockReturnValue({ subgraphType: SUBGRAPH_TYPES.UNTIL_DO });
const tree = renderer.create(<GraphContainerNode {...defaultProps} />).toJSON();
expect(tree.props.className).includes('has-footer');
expect(tree.props.className).includes('is-subgraph');

expect(tree).toMatchSnapshot();
});

it('should render graph container as normal when in monitoring view', () => {
(useMonitoringView as Mock).mockReturnValue(true);
(useRunData as Mock).mockReturnValue({ status: 'Success' });

const tree = renderer.create(<GraphContainerNode {...defaultProps} />).toJSON();

expect(tree).toMatchSnapshot();
});

it('should render graph container as inactive when is monitoring view', () => {
(useMonitoringView as Mock).mockReturnValue(true);
(useRunData as Mock).mockReturnValue({});

const tree = renderer.create(<GraphContainerNode {...defaultProps} />).toJSON();

expect(tree).toMatchSnapshot();
});

it('should apply correct styles based on node size', () => {
const tree = renderer.create(<GraphContainerNode {...defaultProps} />).toJSON();
expect(tree?.props.style).toEqual({ width: 100, height: 100 });
expect(tree).toMatchSnapshot();
});

it('should render the top and bottom handles', () => {
const tree = renderer.create(<GraphContainerNode {...defaultProps} />).toJSON();
const topHandle = tree.children.find((child) => child.props.className.includes('node-handle top'));
const bottomHandle = tree.children.find((child) => child.props.className.includes('node-handle bottom'));
expect(topHandle).toBeTruthy();
expect(bottomHandle).toBeTruthy();
expect(tree).toMatchSnapshot();
});

it('should render DropZone when showLeafComponents is true', () => {
(useIsLeafNode as Mock).mockReturnValue(true);
(useActionMetadata as Mock).mockReturnValue({ type: 'someType' });

const tree = renderer.create(<GraphContainerNode {...defaultProps} />).toJSON();

expect(tree.length).toBe(2);
expect(tree[1].props.className).toBe('edge-drop-zone-container');
expect(tree).toMatchSnapshot();
});

it('should not render DropZone when showLeafComponents is false', () => {
const tree = renderer.create(<GraphContainerNode {...defaultProps} />).toJSON();
const dropZone = tree.children.find((child) => child.props.className.includes('edge-drop-zone-container'));

expect(dropZone).toBeFalsy();
expect(tree).toMatchSnapshot();
});
});
Loading

0 comments on commit 98271a8

Please sign in to comment.