Skip to content

Commit

Permalink
Merge pull request #730 from IntersectMBO/fix/712-gas-fails-validatio…
Browse files Browse the repository at this point in the history
…n-due-to-fetching-the-resource-blocked-by-csp

[#712] fix: Fix displaying Governance Actions that fails the validation test
  • Loading branch information
MSzalowski authored Apr 16, 2024
2 parents 411db90 + b55aca2 commit 0002e4d
Show file tree
Hide file tree
Showing 17 changed files with 137 additions and 86 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ changes.
- Fix displaying modals to not block signing transactions [Issue 710](https://github.com/IntersectMBO/govtool/issues/710)
- Change style of url button to trim the file name [Issue 655](https://github.com/IntersectMBO/govtool/issues/655)
- Change regex for parsing urls to match urls without protocol [Issue 655](https://github.com/IntersectMBO/govtool/issues/655)
- Integrate ga displaying metadata validation with the validation service [Issue 712](https://github.com/IntersectMBO/govtool/issues/712)

### Added

Expand Down
11 changes: 8 additions & 3 deletions govtool/frontend/src/components/molecules/Breadcrumbs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ import Divider from "@mui/material/Divider";

import { useScreenDimension } from "@hooks";
import { Typography } from "@atoms";
import { getMetadataDataMissingStatusTranslation } from "@/utils";
import { MetadataValidationStatus } from "@/models";

type BreadcrumbsProps = {
elementOne: string;
elementOnePath: To;
elementTwo: string;
isDataMissing: boolean;
isDataMissing: MetadataValidationStatus | boolean;
};

export const Breadcrumbs = ({
Expand All @@ -19,7 +21,6 @@ export const Breadcrumbs = ({
isDataMissing,
}: BreadcrumbsProps) => {
const { isMobile } = useScreenDimension();

return (
<Box
sx={{
Expand Down Expand Up @@ -54,7 +55,11 @@ export const Breadcrumbs = ({
textOverflow: "ellipsis",
}}
>
{isDataMissing || elementTwo}
{(isDataMissing !== false &&
getMetadataDataMissingStatusTranslation(
isDataMissing as MetadataValidationStatus,
)) ||
elementTwo}
</Typography>
</Box>
);
Expand Down
23 changes: 13 additions & 10 deletions govtool/frontend/src/components/molecules/DataMissingInfoBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,43 @@ import { Box, Link } from "@mui/material";

import { Typography } from "@atoms";
import { useTranslation } from "@hooks";
import { GAMetedataErrors, openInNewTab } from "@utils";
import { openInNewTab } from "@utils";
import { MetadataValidationStatus } from "@/models";

export const DataMissingInfoBox = ({
isDataMissing,
isInProgress,
isSubmitted,
}: {
isDataMissing: boolean | GAMetedataErrors;
isDataMissing: boolean | MetadataValidationStatus;
isInProgress?: boolean;
isSubmitted?: boolean;
}) => {
const { t } = useTranslation();

const gaMetadataErrorMessage = {
[GAMetedataErrors.DATA_MISSING]: t("errors.gAMetadata.message.dataMissing"),
[GAMetedataErrors.INCORRECT_FORMAT]: t(
[MetadataValidationStatus.URL_NOT_FOUND]: t(
"errors.gAMetadata.message.dataMissing",
),
[MetadataValidationStatus.INVALID_JSONLD]: t(
"errors.gAMetadata.message.incorrectFormat",
),
[GAMetedataErrors.NOT_VERIFIABLE]: t(
[MetadataValidationStatus.INVALID_HASH]: t(
"errors.gAMetadata.message.notVerifiable",
),
}[isDataMissing as GAMetedataErrors];
}[isDataMissing as MetadataValidationStatus];

const gaMetadataErrorDescription = {
[GAMetedataErrors.DATA_MISSING]: t(
[MetadataValidationStatus.URL_NOT_FOUND]: t(
"errors.gAMetadata.description.dataMissing",
),
[GAMetedataErrors.INCORRECT_FORMAT]: t(
[MetadataValidationStatus.INVALID_JSONLD]: t(
"errors.gAMetadata.description.incorrectFormat",
),
[GAMetedataErrors.NOT_VERIFIABLE]: t(
[MetadataValidationStatus.INVALID_HASH]: t(
"errors.gAMetadata.description.notVerifiable",
),
}[isDataMissing as GAMetedataErrors];
}[isDataMissing as MetadataValidationStatus];

return isDataMissing && !isSubmitted && !isInProgress ? (
<Box
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import InfoOutlinedIcon from "@mui/icons-material/InfoOutlined";

import { Tooltip, Typography } from "@atoms";
import { useTranslation } from "@hooks";
import { getMetadataDataMissingStatusTranslation } from "@/utils";
import { MetadataValidationStatus } from "@/models";

type GovernanceActionCardHeaderProps = {
title?: string;
isDataMissing: string | boolean;
isDataMissing: MetadataValidationStatus | boolean;
};

export const GovernanceActionCardHeader = ({
Expand All @@ -22,7 +24,6 @@ export const GovernanceActionCardHeader = ({
alignItems: "center",
mb: "20px",
overflow: "hidden",

}}
data-testid="governance-action-card-header"
>
Expand All @@ -38,11 +39,17 @@ export const GovernanceActionCardHeader = ({
...(isDataMissing && { color: "#9E2323" }),
}}
>
{isDataMissing || title}
{(isDataMissing !== false &&
getMetadataDataMissingStatusTranslation(
isDataMissing as MetadataValidationStatus,
)) ||
title}
</Typography>
{isDataMissing && typeof isDataMissing === "string" && (
<Tooltip
heading={isDataMissing}
heading={getMetadataDataMissingStatusTranslation(
isDataMissing as MetadataValidationStatus,
)}
paragraphOne={t("govActions.dataMissingTooltipExplanation")}
placement="bottom-end"
arrow
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ import { Box } from "@mui/material";

import { Typography } from "@atoms";
import { Share } from "@molecules";
import { GAMetedataErrors } from "@utils";
import { MetadataValidationStatus } from "@models";
import { getMetadataDataMissingStatusTranslation } from "@/utils";

type GovernanceActionDetailsCardHeaderProps = {
title?: string;
isDataMissing: boolean | GAMetedataErrors;
isDataMissing: boolean | MetadataValidationStatus;
};

export const GovernanceActionDetailsCardHeader = ({
Expand Down Expand Up @@ -47,7 +48,11 @@ export const GovernanceActionDetailsCardHeader = ({
}}
variant="title2"
>
{isDataMissing || title}
{(isDataMissing !== false &&
getMetadataDataMissingStatusTranslation(
isDataMissing as MetadataValidationStatus,
)) ||
title}
</Typography>
</Box>
<Share link={govActionLinkToShare} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
GovernanceActionDetailsCardVotes,
} from "@molecules";
import { GovernanceActionDetailsCardData } from "@organisms";
import { GAMetedataErrors } from "@utils";
import { MetadataValidationStatus } from "@models";

type GovernanceActionDetailsCardProps = {
abstainVotes: number;
Expand All @@ -25,7 +25,7 @@ type GovernanceActionDetailsCardProps = {
rationale?: string;
yesVotes: number;
govActionId: string;
isDataMissing: boolean | GAMetedataErrors;
isDataMissing: boolean | MetadataValidationStatus;
isDashboard?: boolean;
isVoter?: boolean;
voteFromEP?: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import {
GovernanceActionDetailsCardOnChainData,
} from "@molecules";
import { useScreenDimension, useTranslation } from "@hooks";
import { GAMetedataErrors, getProposalTypeNoEmptySpaces } from "@utils";
import { getProposalTypeNoEmptySpaces } from "@utils";
import { MetadataValidationStatus } from "@models";

type GovernanceActionDetailsCardDataProps = {
type: string;
Expand All @@ -25,7 +26,7 @@ type GovernanceActionDetailsCardDataProps = {
about?: string;
motivation?: string;
rationale?: string;
isDataMissing: boolean | GAMetedataErrors;
isDataMissing: boolean | MetadataValidationStatus;
isOneColumn: boolean;
isDashboard?: boolean;
isInProgress?: boolean;
Expand Down
5 changes: 5 additions & 0 deletions govtool/frontend/src/i18n/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -714,6 +714,11 @@ export const en = {
usingUnregisteredStakeKeys:
"Warning, no registered stake keys, using unregistered stake keys",
},
dataMissingErrors: {
dataMissing: "Data Missing",
notVerifiable: "Not Verifiable",
incorrectFormat: "Incorrect Format",
},
about: "About",
abstain: "Abstain",
addLink: "+ Add link",
Expand Down
8 changes: 5 additions & 3 deletions govtool/frontend/src/models/api.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { GAMetedataErrors } from "@utils";
import { MetadataValidationStatus } from "@models";

export interface VoterInfo {
isRegisteredAsDRep: boolean;
Expand All @@ -22,7 +22,7 @@ export interface DRepData {
deposit: number;
votingPower: number;
status: DRepStatus;
type: 'DRep' | 'SoleVoter';
type: "DRep" | "SoleVoter";
}

export type Vote = "yes" | "no" | "abstain";
Expand Down Expand Up @@ -70,5 +70,7 @@ export interface VotedProposal {
}
export type VotedProposalToDisplay = {
vote: ProposalVote;
proposal: ProposalData & { isDataMissing: boolean | GAMetedataErrors };
proposal: ProposalData & {
isDataMissing: boolean | MetadataValidationStatus;
};
};
5 changes: 5 additions & 0 deletions govtool/frontend/src/models/metadataValidation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@ export type ValidateMetadataResult = {
valid: boolean;
};

export enum MetadataStandard {
CIP108 = "CIP108",
}

export type MetadataValidationDTO = {
url: string;
hash: string;
standard?: MetadataStandard;
};
9 changes: 5 additions & 4 deletions govtool/frontend/src/stories/GovernanceAction.stories.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import type { Meta, StoryObj } from "@storybook/react";
import { within, userEvent, waitFor, screen } from "@storybook/testing-library";
import { expect, jest } from "@storybook/jest";
import { GAMetedataErrors, formatDisplayDate } from "@utils";
import { formatDisplayDate } from "@utils";
import { MetadataValidationStatus } from "@models";
import { GovernanceActionCard } from "@/components/molecules";

const meta = {
Expand Down Expand Up @@ -74,20 +75,20 @@ export const GovernanceActionCardIsLoading: Story = {
export const GovernanceActionCardDataMissing: Story = {
args: {
...commonArgs,
isDataMissing: GAMetedataErrors.DATA_MISSING,
isDataMissing: MetadataValidationStatus.URL_NOT_FOUND,
},
};

export const GovernanceActionCardIncorectFormat: Story = {
args: {
...commonArgs,
isDataMissing: GAMetedataErrors.INCORRECT_FORMAT,
isDataMissing: MetadataValidationStatus.INVALID_JSONLD,
},
};

export const GovernanceActionCardNotVerifiable: Story = {
args: {
...commonArgs,
isDataMissing: GAMetedataErrors.NOT_VERIFIABLE,
isDataMissing: MetadataValidationStatus.INVALID_HASH,
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { Meta, StoryObj } from "@storybook/react";
import { screen, userEvent, waitFor, within } from "@storybook/testing-library";
import { GovernanceActionDetailsCard } from "@organisms";
import { expect } from "@storybook/jest";
import { GAMetedataErrors } from "@/utils";
import { MetadataValidationStatus } from "@models";

const meta = {
title: "Example/GovernanceActionDetailsCard",
Expand Down Expand Up @@ -79,20 +79,20 @@ export const GovernanceActionDetailsDrep: Story = {
export const GovernanceActionDetailsDataMissing: Story = {
args: {
...commonArgs,
isDataMissing: GAMetedataErrors.DATA_MISSING,
isDataMissing: MetadataValidationStatus.URL_NOT_FOUND,
},
};

export const GovernanceActionDetailsIncorrectFormat: Story = {
args: {
...commonArgs,
isDataMissing: GAMetedataErrors.INCORRECT_FORMAT,
isDataMissing: MetadataValidationStatus.INVALID_JSONLD,
},
};

export const GovernanceActionDetailsNotVerifiable: Story = {
args: {
...commonArgs,
isDataMissing: GAMetedataErrors.NOT_VERIFIABLE,
isDataMissing: MetadataValidationStatus.INVALID_HASH,
},
};
4 changes: 2 additions & 2 deletions govtool/frontend/src/types/global.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { GAMetedataErrors } from "@utils";
import { MetadataValidationStatus } from "@models";

export {};

Expand Down Expand Up @@ -40,7 +40,7 @@ declare global {
};

type ActionTypeToDsiplay = ActionType & {
isDataMissing: boolean | GAMetedataErrors;
isDataMissing: boolean | MetadataValidationStatus;
};

interface ActionVotedOnType extends ActionTypeToDsiplay {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import i18n from "@/i18n";
import { MetadataValidationStatus } from "@/models";

/**
* Retrieves the translation for the given metadata validation status.
*
* @param status - The metadata validation status.
* @returns The translated string corresponding to the status.
*/
export const getMetadataDataMissingStatusTranslation = (
status: MetadataValidationStatus,
): string => {
const errorKey = {
[MetadataValidationStatus.URL_NOT_FOUND]: "dataMissing",
[MetadataValidationStatus.INVALID_JSONLD]: "incorrectFormat",
[MetadataValidationStatus.INVALID_HASH]: "notVerifiable",
}[status] as "dataMissing" | "incorrectFormat" | "notVerifiable";
return i18n.t(`dataMissingErrors.${errorKey || "dataMissing"}`);
};
1 change: 1 addition & 0 deletions govtool/frontend/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export * from "./generateJsonld";
export * from "./getDRepID";
export * from "./getGovActionId";
export * from "./getLengthInBytes";
export * from "./getMetadataDataMissingStatusTranslation";
export * from "./getProposalTypeLabel";
export * from "./isValidFormat";
export * from "./jsonUtils";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { MetadataValidationStatus } from "@models";
import { getMetadataDataMissingStatusTranslation } from "../getMetadataDataMissingStatusTranslation";

describe("getMetadataDataMissingStatusTranslation", () => {
it("should return the correct translation for URL_NOT_FOUND status", () => {
const translation = getMetadataDataMissingStatusTranslation(
MetadataValidationStatus.URL_NOT_FOUND,
);
expect(translation).toBe("Data Missing");
});

it("should return the correct translation for INVALID_JSONLD status", () => {
const translation = getMetadataDataMissingStatusTranslation(
MetadataValidationStatus.INVALID_JSONLD,
);
expect(translation).toBe("Incorrect Format");
});

it("should return the correct translation for INVALID_HASH status", () => {
const translation = getMetadataDataMissingStatusTranslation(
MetadataValidationStatus.INVALID_HASH,
);
expect(translation).toBe("Not Verifiable");
});

it("should return the default translation for unknown status", () => {
const translation = getMetadataDataMissingStatusTranslation(
"UNKNOWN_STATUS" as MetadataValidationStatus,
);
expect(translation).toBe("Data Missing");
});
});
Loading

0 comments on commit 0002e4d

Please sign in to comment.