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

patch: signature display redesign #388

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all 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
85 changes: 76 additions & 9 deletions src/__tests__/Explore/Explore.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const mockImageList = {
NewestImage: {
Tag: 'latest',
Description: 'w',
IsSigned: false,
SignatureInfo: [],
Licenses: '',
Vendor: '',
Labels: '',
Expand All @@ -61,7 +61,18 @@ const mockImageList = {
NewestImage: {
Tag: 'latest',
Description: '',
IsSigned: true,
SignatureInfo: [
{
Tool: 'cosign',
IsTrusted: false,
Author: ''
},
{
Tool: 'notation',
IsTrusted: false,
Author: ''
}
],
Licenses: '',
Vendor: '',
Labels: '',
Expand All @@ -85,7 +96,18 @@ const mockImageList = {
NewestImage: {
Tag: 'latest',
Description: '',
IsSigned: true,
SignatureInfo: [
{
Tool: 'cosign',
IsTrusted: true,
Author: ''
},
{
Tool: 'notation',
IsTrusted: true,
Author: ''
}
],
Licenses: '',
Vendor: '',
Labels: '',
Expand All @@ -109,7 +131,18 @@ const mockImageList = {
NewestImage: {
Tag: 'latest',
Description: '',
IsSigned: true,
SignatureInfo: [
{
Tool: 'cosign',
IsTrusted: true,
Author: ''
},
{
Tool: 'notation',
IsTrusted: true,
Author: ''
}
],
Licenses: '',
Vendor: '',
Labels: '',
Expand All @@ -133,7 +166,18 @@ const mockImageList = {
NewestImage: {
Tag: 'latest',
Description: '',
IsSigned: true,
SignatureInfo: [
{
Tool: 'cosign',
IsTrusted: true,
Author: ''
},
{
Tool: 'notation',
IsTrusted: true,
Author: ''
}
],
Licenses: '',
Vendor: '',
Labels: '',
Expand Down Expand Up @@ -161,7 +205,18 @@ const mockImageList = {
NewestImage: {
Tag: 'latest',
Description: '',
IsSigned: true,
SignatureInfo: [
{
Tool: 'cosign',
IsTrusted: true,
Author: ''
},
{
Tool: 'notation',
IsTrusted: true,
Author: ''
}
],
Licenses: '',
Vendor: '',
Labels: '',
Expand All @@ -185,7 +240,18 @@ const mockImageList = {
NewestImage: {
Tag: 'latest',
Description: '',
IsSigned: true,
SignatureInfo: [
{
Tool: 'cosign',
IsTrusted: true,
Author: ''
},
{
Tool: 'notation',
IsTrusted: true,
Author: ''
}
],
Licenses: '',
Vendor: '',
Labels: '',
Expand Down Expand Up @@ -218,7 +284,7 @@ const filteredMockImageListWindows = () => {
};

const filteredMockImageListSigned = () => {
const filteredRepos = mockImageList.GlobalSearch.Repos.filter((r) => r.NewestImage.IsSigned);
const filteredRepos = mockImageList.GlobalSearch.Repos.filter((r) => r.NewestImage.SignatureInfo?.length > 0);
return {
GlobalSearch: {
Page: { TotalCount: 6, ItemCount: 6 },
Expand Down Expand Up @@ -266,7 +332,8 @@ describe('Explore component', () => {
jest.spyOn(api, 'get').mockResolvedValue({ status: 200, data: { data: mockImageList } });
render(<StateExploreWrapper />);
expect(await screen.findAllByTestId('unverified-icon')).toHaveLength(1);
expect(await screen.findAllByTestId('verified-icon')).toHaveLength(6);
expect(await screen.findAllByTestId('untrusted-icon')).toHaveLength(2);
expect(await screen.findAllByTestId('verified-icon')).toHaveLength(10);
});

it('renders vulnerability icons', async () => {
Expand Down
45 changes: 39 additions & 6 deletions src/__tests__/HomePage/Home.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const mockImageList = {
NewestImage: {
Tag: 'latest',
Description: 'w',
IsSigned: false,
SignatureInfo: [],
Licenses: '',
Vendor: '',
Labels: '',
Expand All @@ -49,7 +49,18 @@ const mockImageList = {
NewestImage: {
Tag: 'latest',
Description: '',
IsSigned: true,
SignatureInfo: [
{
Tool: 'cosign',
IsTrusted: true,
Author: ''
},
{
Tool: 'notation',
IsTrusted: true,
Author: ''
}
],
Licenses: '',
Vendor: '',
Labels: '',
Expand All @@ -66,7 +77,18 @@ const mockImageList = {
NewestImage: {
Tag: 'latest',
Description: '',
IsSigned: true,
SignatureInfo: [
{
Tool: 'cosign',
IsTrusted: true,
Author: ''
},
{
Tool: 'notation',
IsTrusted: true,
Author: ''
}
],
Licenses: '',
Vendor: '',
Labels: '',
Expand All @@ -91,7 +113,7 @@ const mockImageListRecent = {
NewestImage: {
Tag: 'latest',
Description: 'w',
IsSigned: false,
SignatureInfo: [],
Licenses: '',
Vendor: '',
Labels: '',
Expand All @@ -108,7 +130,18 @@ const mockImageListRecent = {
NewestImage: {
Tag: 'latest',
Description: '',
IsSigned: true,
SignatureInfo: [
{
Tool: 'cosign',
IsTrusted: true,
Author: ''
},
{
Tool: 'notation',
IsTrusted: true,
Author: ''
}
],
Licenses: '',
Vendor: '',
Labels: '',
Expand Down Expand Up @@ -188,7 +221,7 @@ describe('Home component', () => {
jest.spyOn(api, 'get').mockResolvedValue({ status: 200, data: { data: mockImageListRecent } });
render(<HomeWrapper />);
expect(await screen.findAllByTestId('unverified-icon')).toHaveLength(3);
expect(await screen.findAllByTestId('verified-icon')).toHaveLength(4);
expect(await screen.findAllByTestId('verified-icon')).toHaveLength(8);
});

it('renders vulnerability icons', async () => {
Expand Down
1 change: 0 additions & 1 deletion src/components/Explore/Explore.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,6 @@ function Explore({ searchInputValue }) {
version={item.latestVersion}
description={item.description}
downloads={item.downloads}
isSigned={item.isSigned}
signatureInfo={item.signatureInfo}
isBookmarked={item.isBookmarked}
vendor={item.vendor}
Expand Down
1 change: 0 additions & 1 deletion src/components/Home/Home.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,6 @@ function Home() {
version={item.latestVersion}
description={item.description}
downloads={item.downloads}
isSigned={item.isSigned}
signatureInfo={item.signatureInfo}
isBookmarked={item.isBookmarked}
vendor={item.vendor}
Expand Down
34 changes: 23 additions & 11 deletions src/components/Repo/RepoDetails.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,14 @@
return lastDate;
};

const getSignatureChips = () => {
if (repoDetailData.signatureInfo?.length > 0)
return repoDetailData.signatureInfo?.map((si, index) => (
<SignatureIconCheck key={`${si?.tool}${index}`} signatureInfo={[si]} />

Check warning on line 249 in src/components/Repo/RepoDetails.jsx

View check run for this annotation

Codecov / codecov/patch

src/components/Repo/RepoDetails.jsx#L248-L249

Added lines #L248 - L249 were not covered by tests
));
return <SignatureIconCheck />;
};

return (
<>
{isLoading ? (
Expand Down Expand Up @@ -271,19 +279,23 @@
</Stack>
<Stack alignItems="center" sx={{ width: { xs: '100%', md: 'auto' } }} direction="row" spacing={2}>
<VulnerabilityIconCheck vulnerabilitySeverity={repoDetailData?.vulnerabilitySeverity} />
<SignatureIconCheck
isSigned={repoDetailData.isSigned}
signatureInfo={repoDetailData.signatureInfo}
/>
{getSignatureChips()}
</Stack>
{isAuthenticated() && (
<IconButton component="span" onClick={handleBookmarkClick} data-testid="bookmark-button">
{repoDetailData?.isBookmarked ? (
<BookmarkIcon data-testid="bookmarked" />
) : (
<BookmarkBorderIcon data-testid="not-bookmarked" />
)}
</IconButton>
<Stack
alignItems="center"
sx={{ width: { xs: '100%', md: 'auto' } }}
direction="row"
spacing={2}
>
<IconButton component="span" onClick={handleBookmarkClick} data-testid="bookmark-button">
{repoDetailData?.isBookmarked ? (
<BookmarkIcon data-testid="bookmarked" />
) : (
<BookmarkBorderIcon data-testid="not-bookmarked" />
)}
</IconButton>
</Stack>
)}
</Stack>
<Typography gutterBottom className={classes.repoTitle}>
Expand Down
5 changes: 2 additions & 3 deletions src/components/Shared/PreviewCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import repocube3 from '../../assets/repocube-3.png';
import repocube4 from '../../assets/repocube-4.png';

import { isEmpty } from 'lodash';
import { VulnerabilityIconCheck, SignatureIconCheck } from 'utilities/vulnerabilityAndSignatureCheck';
import { VulnerabilityIconCheck } from 'utilities/vulnerabilityAndSignatureCheck';

// temporary utility to get image
const randomIntFromInterval = (min, max) => {
Expand Down Expand Up @@ -67,7 +67,7 @@ const useStyles = makeStyles(() => ({
function PreviewCard(props) {
const classes = useStyles();
const navigate = useNavigate();
const { name, isSigned, vulnerabilityData, logo } = props;
const { name, vulnerabilityData, logo } = props;

const goToDetails = () => {
navigate(`/image/${encodeURIComponent(name)}`);
Expand Down Expand Up @@ -108,7 +108,6 @@ function PreviewCard(props) {
</Tooltip>
<Stack direction="row" spacing={0.5} sx={{ marginLeft: 'auto', marginRight: 0 }}>
<VulnerabilityIconCheck {...vulnerabilityData} />
<SignatureIconCheck isSigned={isSigned} />
</Stack>
</Stack>
</Grid>
Expand Down
29 changes: 22 additions & 7 deletions src/components/Shared/RepoCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ import {
import makeStyles from '@mui/styles/makeStyles';
import BookmarkIcon from '@mui/icons-material/Bookmark';
import BookmarkBorderIcon from '@mui/icons-material/BookmarkBorder';
import { VulnerabilityIconCheck, SignatureIconCheck } from 'utilities/vulnerabilityAndSignatureCheck';
import { Markdown } from 'utilities/MarkdowntojsxWrapper';
import filterConstants from 'utilities/filterConstants';
import { useTheme } from '@emotion/react';

// placeholder images
Expand All @@ -36,9 +39,6 @@ import repocube2 from '../../assets/repocube-2.png';
import repocube3 from '../../assets/repocube-3.png';
import repocube4 from '../../assets/repocube-4.png';

import { VulnerabilityIconCheck, SignatureIconCheck } from 'utilities/vulnerabilityAndSignatureCheck';
import { Markdown } from 'utilities/MarkdowntojsxWrapper';

// temporary utility to get image
const randomIntFromInterval = (min, max) => {
return Math.floor(Math.random() * (max - min + 1) + min);
Expand Down Expand Up @@ -183,7 +183,6 @@ function RepoCard(props) {
platforms,
description,
downloads,
isSigned,
signatureInfo,
lastUpdated,
version,
Expand Down Expand Up @@ -260,6 +259,24 @@ function RepoCard(props) {
);
};

const getSignatureChips = () => {
const cosign = signatureInfo?.map((s) => s.tool).includes(filterConstants.signatureToolConstants.COSIGN)
? signatureInfo.filter((si) => si.tool == filterConstants.signatureToolConstants.COSIGN)
: null;
const notation = signatureInfo?.map((s) => s.tool).includes(filterConstants.signatureToolConstants.NOTATION)
? signatureInfo.filter((si) => si.tool == filterConstants.signatureToolConstants.NOTATION)
: null;
const sigArray = [];
if (cosign) sigArray.push(cosign);
if (notation) sigArray.push(notation);
if (sigArray.length === 0) return <SignatureIconCheck />;
return sigArray.map((sig, index) => (
<div className="hide-on-mobile" key={`${name}sig${index}`}>
<SignatureIconCheck signatureInfo={sig} />
</div>
));
};

return (
<Card variant="outlined" className={classes.card} data-testid="repo-card">
<CardActionArea
Expand Down Expand Up @@ -290,9 +307,7 @@ function RepoCard(props) {
<div className="hide-on-mobile">
<VulnerabilityIconCheck {...vulnerabilityData} className="hide-on-mobile" />
</div>
<div className="hide-on-mobile">
<SignatureIconCheck isSigned={isSigned} signatureInfo={signatureInfo} className="hide-on-mobile" />
</div>
{getSignatureChips()}
</Stack>
<Tooltip title={description || 'Description not available'} placement="top">
<Typography className={classes.description} pt={1} sx={{ fontSize: 12 }} gutterBottom noWrap>
Expand Down
Loading
Loading