Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a checks provider filter for catalog_new view #1136

Merged
merged 8 commits into from
Jan 24, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 55 additions & 40 deletions assets/js/components/ChecksCatalog/ChecksCatalogNew.jsx
Original file line number Diff line number Diff line change
@@ -1,66 +1,81 @@
/* eslint-disable react/no-array-index-key */
import React, { useEffect } from 'react';
import React, { useState, useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';

import { groupBy } from '@lib/lists';

import { getCatalog } from '@state/selectors/catalog';
import { updateCatalog } from '@state/actions/catalog';
import { providersList } from '../ProviderLabel/ProviderLabel';
import CatalogContainer from './CatalogContainer';
import CheckItem from './CheckItem';
import ProviderSelection from './ProviderSelection';

const providers = ['default'].concat(providersList.slice());
EMaksy marked this conversation as resolved.
Show resolved Hide resolved
EMaksy marked this conversation as resolved.
Show resolved Hide resolved
// eslint-disable-next-line import/prefer-default-export
export function ChecksCatalogNew() {
const dispatch = useDispatch();

const [selected, setSelected] = useState(providers[0]);
EMaksy marked this conversation as resolved.
Show resolved Hide resolved
const provider = selected;
const {
data: catalogData,
error: catalogError,
loading,
} = useSelector(getCatalog());
} = useSelector(getCatalog(provider));
EMaksy marked this conversation as resolved.
Show resolved Hide resolved

useEffect(() => {
dispatch(updateCatalog());
}, [dispatch]);
setSelected(providers[0]);
}, [providers[0]]);

useEffect(() => {
getCatalog();
}, []);
if (provider === 'default') {
dispatch(updateCatalog());
EMaksy marked this conversation as resolved.
Show resolved Hide resolved
} else {
dispatch(updateCatalog({ provider }));
}
}, [dispatch, provider]);

return (
<CatalogContainer
onRefresh={() => dispatch(updateCatalog())}
isCatalogEmpty={catalogData.length === 0}
catalogError={catalogError}
loading={loading}
>
<div>
{Object.entries(groupBy(catalogData, 'group')).map(
([group, checks], idx) => (
<div
key={idx}
className="check-group bg-white shadow overflow-hidden sm:rounded-md mb-8"
>
<div className="bg-white px-4 py-5 border-b border-gray-200 sm:px-6">
<h3 className="text-lg leading-6 font-medium text-gray-900">
{group}
</h3>
<div>
EMaksy marked this conversation as resolved.
Show resolved Hide resolved
<ProviderSelection
EMaksy marked this conversation as resolved.
Show resolved Hide resolved
providers={providers}
selected={selected}
onChange={setSelected}
/>
<CatalogContainer
onRefresh={() => dispatch(updateCatalog({ provider }))}
isCatalogEmpty={catalogData.length === 0}
catalogError={catalogError}
loading={loading}
>
<div>
{Object.entries(groupBy(catalogData, 'group')).map(
([group, checks], idx) => (
<div
key={idx}
className="check-group bg-white shadow overflow-hidden sm:rounded-md mb-8"
>
<div className="bg-white px-4 py-5 border-b border-gray-200 sm:px-6">
<h3 className="text-lg leading-6 font-medium text-gray-900">
{group}
</h3>
</div>
<ul className="divide-y divide-gray-200">
{checks.map((check) => (
<CheckItem
key={check.id}
checkID={check.id}
premium={check.premium}
description={check.description}
remediation={check.remediation}
/>
))}
</ul>
</div>
<ul className="divide-y divide-gray-200">
{checks.map((check) => (
<CheckItem
key={check.id}
checkID={check.id}
premium={check.premium}
description={check.description}
remediation={check.remediation}
/>
))}
</ul>
</div>
)
)}
</div>
</CatalogContainer>
)
)}
</div>
</CatalogContainer>
</div>
);
}
65 changes: 60 additions & 5 deletions assets/js/components/ChecksCatalog/ChecksCatalogNew.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,43 @@ import { catalogCheckFactory } from '@lib/test-utils/factories';

import { ChecksCatalogNew } from './ChecksCatalogNew';




describe('ChecksCatalog ChecksCatalogNew component', () => {
it('should render the checks catalog with fetched data', async () => {

const stateCatalog =() => {
const groupName1 = faker.animal.cat();
const groupName2 = faker.animal.cat();
const group1 = catalogCheckFactory.buildList(5, { group: groupName1 });
const group2 = catalogCheckFactory.buildList(5, { group: groupName2 });
const catalog = group1.concat(group2);
const groupName3 = faker.animal.cat();
const groupName4 = faker.animal.cat();
const groupName5 = faker.animal.cat();
const group1 = catalogCheckFactory.buildList(5, { group: groupName1, provider: "aws" });
const group2 = catalogCheckFactory.buildList(5, { group: groupName2, provider: "azure" });
const group3 = catalogCheckFactory.buildList(5, { group: groupName3, provider: "gcp" });
const group4 = catalogCheckFactory.buildList(5, { group: groupName4, provider: "nutanix" });
const group5 = catalogCheckFactory.buildList(5, { group: groupName5, provider: "kvm" });
const catalog = group1.concat(group2, group3, group4, group5)


const initialState = {
catalogNew: { loading: false, data: catalog, error: null },
};
const [statefulCatalog, store] = withState(
<ChecksCatalogNew />,
initialState
);
return {statefulCatalog,store}
}


it('should render the checks catalog with fetched data', async () => {

const { statefulCatalog, store } = stateCatalog();
await act(async () => renderWithRouter(statefulCatalog));

const groups = await waitFor(() => screen.getAllByRole('list'));
expect(groups.length).toBe(2);
expect(groups.length).toBe(5);

groups.forEach((group) => {
const { getAllByRole } = within(group);
Expand All @@ -45,4 +62,42 @@ describe('ChecksCatalog ChecksCatalogNew component', () => {
];
expect(actions).toEqual(expectedActions);
});



it("should render the catalog only for aws", async () => {



}
)


it("should render the catalog only for azure", async () => {



}
)

it("should render the catalog only for gcp", async () => {



}
)

it("should render the catalog only for nutanix", async () => {



}
)

it("should render the catalog only for kvm", async () => {



}
)
});
10 changes: 10 additions & 0 deletions assets/js/components/ProviderLabel/ProviderLabel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,14 @@ function ProviderLabel({ provider }) {
);
}

const getLabels = (labelValue) => {
EMaksy marked this conversation as resolved.
Show resolved Hide resolved
const labels = [];
Object.keys(labelValue).forEach((key) => {
labels.push(labelValue[key].label);
});
return labels;
};

export const providersList = getLabels(providerData);

export default ProviderLabel;
9 changes: 8 additions & 1 deletion assets/js/components/ProviderLabel/ProviderLabel.test.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom';
import ProviderLabel from './ProviderLabel';
import ProviderLabel, { providersList } from './ProviderLabel';

describe('Provider Label', () => {
it('should display an icon and label with AWS as the provider', () => {
Expand Down Expand Up @@ -41,4 +41,11 @@ describe('Provider Label', () => {
'Provider not recognized'
);
});

describe('providersList', () => {
test('returns an array of all Provider labels', () => {
const expectedProviderLabels = ['AWS', 'Azure', 'GCP', 'Nutanix', 'KVM'];
expect(providersList).toEqual(expectedProviderLabels);
});
});
});