datajunction-ui
Version:
DataJunction Metrics Platform UI
211 lines (187 loc) • 6.38 kB
JSX
import React from 'react';
import { MemoryRouter, Route, Routes } from 'react-router-dom';
import { screen, waitFor } from '@testing-library/react';
import { render } from '../../../../setupTests';
import fetchMock from 'jest-fetch-mock';
import { AddEditNodePage } from '../index.jsx';
import { mocks } from '../../../../mocks/mockNodes';
import DJClientContext from '../../../providers/djclient';
fetchMock.enableMocks();
export const initializeMockDJClient = () => {
return {
DataJunctionAPI: {
namespace: _ => {
return [
{
name: 'default.contractors',
display_name: 'Default: Contractors',
version: 'v1.0',
type: 'source',
status: 'valid',
mode: 'published',
updated_at: '2023-08-21T16:48:53.246914+00:00',
},
{
name: 'default.num_repair_orders',
display_name: 'Default: Num Repair Orders',
version: 'v1.0',
type: 'metric',
status: 'valid',
mode: 'published',
updated_at: '2023-08-21T16:48:56.841704+00:00',
},
];
},
metrics: {},
getNodeForEditing: jest.fn(),
namespaces: () => {
return [
{
namespace: 'default',
num_nodes: 33,
},
{
namespace: 'default123',
num_nodes: 0,
},
];
},
createNode: jest.fn(),
patchNode: jest.fn(),
node: jest.fn(),
tagsNode: jest.fn(),
listTags: jest.fn().mockReturnValue([]),
metric: jest.fn().mockReturnValue(mocks.mockMetricNode),
nodesWithType: jest
.fn()
.mockReturnValueOnce(['a'])
.mockReturnValueOnce(['b'])
.mockReturnValueOnce(['default.repair_orders']),
listMetricMetadata: jest.fn().mockReturnValue({
directions: ['higher_is_better', 'lower_is_better', 'neutral'],
units: [
{ name: 'dollar', label: 'Dollar' },
{ name: 'second', label: 'Second' },
],
}),
},
};
};
export const testElement = djClient => {
return (
<DJClientContext.Provider value={djClient}>
<AddEditNodePage />
</DJClientContext.Provider>
);
};
export const renderCreateNode = element => {
return render(
<MemoryRouter initialEntries={['/create/dimension/default']}>
<Routes>
<Route path="create/:nodeType/:initialNamespace" element={element} />
</Routes>
</MemoryRouter>,
);
};
export const renderCreateMetric = element => {
return render(
<MemoryRouter initialEntries={['/create/metric/default']}>
<Routes>
<Route path="create/:nodeType/:initialNamespace" element={element} />
</Routes>
</MemoryRouter>,
);
};
export const renderEditNode = element => {
return render(
<MemoryRouter initialEntries={['/nodes/default.num_repair_orders/edit']}>
<Routes>
<Route path="nodes/:name/edit" element={element} />
</Routes>
</MemoryRouter>,
);
};
export const renderEditTransformNode = element => {
return render(
<MemoryRouter
initialEntries={['/nodes/default.repair_order_transform/edit']}
>
<Routes>
<Route path="nodes/:name/edit" element={element} />
</Routes>
</MemoryRouter>,
);
};
describe('AddEditNodePage', () => {
beforeEach(() => {
fetchMock.resetMocks();
jest.clearAllMocks();
window.scrollTo = jest.fn();
});
it('Create node page renders with the selected nodeType and namespace', async () => {
const mockDjClient = initializeMockDJClient();
const element = testElement(mockDjClient);
const { container } = renderCreateNode(element);
// The node type should be included in the page title
await waitFor(() => {
expect(
container.getElementsByClassName('node_type__metric'),
).toMatchSnapshot();
// The namespace should be set to the one provided in params
screen
.getAllByText('default')
.forEach(element => expect(element).toBeInTheDocument());
});
});
it('Edit node page renders with the selected node', async () => {
const mockDjClient = initializeMockDJClient();
mockDjClient.DataJunctionAPI.getNodeForEditing.mockReturnValue(
mocks.mockGetMetricNode,
);
const element = testElement(mockDjClient);
renderEditNode(element);
await waitFor(() => {
// Should be an edit node page
expect(screen.getByText('Edit')).toBeInTheDocument();
// The node name should be loaded onto the page
expect(screen.getByText('default.num_repair_orders')).toBeInTheDocument();
// The node type should be loaded onto the page
expect(screen.getByText('metric')).toBeInTheDocument();
// The description should be populated
expect(screen.getByText('Number of repair orders')).toBeInTheDocument();
// The upstream node should be populated
expect(screen.getByText('default.repair_orders')).toBeInTheDocument();
// The aggregate expression should be populated
expect(screen.getByText('count')).toBeInTheDocument();
expect(screen.getByText('(repair_order_id)')).toBeInTheDocument();
});
});
it('Verify edit page node not found', async () => {
const mockDjClient = initializeMockDJClient();
mockDjClient.DataJunctionAPI.getNodeForEditing.mockReturnValue(null);
const element = testElement(mockDjClient);
renderEditNode(element);
await waitFor(() => {
expect(mockDjClient.DataJunctionAPI.getNodeForEditing).toBeCalledTimes(1);
expect(
screen.getByText('Node default.num_repair_orders does not exist!'),
).toBeInTheDocument();
});
}, 60000);
it('Verify only transforms, metrics, and dimensions can be edited', async () => {
const mockDjClient = initializeMockDJClient();
mockDjClient.DataJunctionAPI.getNodeForEditing.mockReturnValue(
mocks.mockGetSourceNode,
);
const element = testElement(mockDjClient);
renderEditNode(element);
await waitFor(() => {
expect(mockDjClient.DataJunctionAPI.getNodeForEditing).toBeCalledTimes(1);
expect(
screen.getByText(
'Node default.num_repair_orders is of type source and cannot be edited',
),
).toBeInTheDocument();
});
}, 60000);
});