From 86ce2ce3a8ed897111e8df0964a13aad5105c638 Mon Sep 17 00:00:00 2001 From: Antonio Gamez Diaz Date: Tue, 8 Aug 2023 15:50:00 +0200 Subject: [PATCH] Avoid endless spinner when no readme Signed-off-by: Antonio Gamez Diaz --- .../PackageHeader/PackageReadme.test.tsx | 89 +++++++++++++------ .../PackageHeader/PackageReadme.tsx | 17 ++-- .../components/PackageHeader/PackageView.tsx | 6 +- 3 files changed, 77 insertions(+), 35 deletions(-) diff --git a/dashboard/src/components/PackageHeader/PackageReadme.test.tsx b/dashboard/src/components/PackageHeader/PackageReadme.test.tsx index 8ac1c3410f4..49b3774195d 100644 --- a/dashboard/src/components/PackageHeader/PackageReadme.test.tsx +++ b/dashboard/src/components/PackageHeader/PackageReadme.test.tsx @@ -6,11 +6,12 @@ import LoadingWrapper from "components/LoadingWrapper/LoadingWrapper"; import ReactMarkdown from "react-markdown"; import { HashLink as Link } from "react-router-hash-link"; import { defaultStore, mountWrapper } from "shared/specs/mountWrapper"; -import PackageReadme from "./PackageReadme"; +import PackageReadme, { IPackageReadmeProps } from "./PackageReadme"; -const defaultProps = { +const defaultProps: IPackageReadmeProps = { error: undefined, readme: "", + isFetching: false, }; const kubeActions = { ...actions.kube }; @@ -24,27 +25,46 @@ afterEach(() => { actions.kube = { ...kubeActions }; }); -it("behaves as a loading component", () => { - const wrapper = mountWrapper(defaultStore, ); +it("behaves as a loading component if it's fetching with readme", () => { + const props: IPackageReadmeProps = { + ...defaultProps, + isFetching: true, + readme: "foo", + }; + const wrapper = mountWrapper(defaultStore, ); + + expect(wrapper.find(LoadingWrapper)).toExist(); +}); + +it("behaves as a loading component if it's fetching without readme", () => { + const props: IPackageReadmeProps = { + ...defaultProps, + isFetching: true, + readme: "", + }; + const wrapper = mountWrapper(defaultStore, ); + expect(wrapper.find(LoadingWrapper)).toExist(); }); it("renders the ReactMarkdown content is readme is present", () => { - const props = { + const props: IPackageReadmeProps = { ...defaultProps, readme: "# Markdown Readme", }; const wrapper = mountWrapper(defaultStore, ); + const component = wrapper.find(ReactMarkdown); expect(component.html()).toEqual('

Markdown Readme

'); }); it("renders the ReactMarkdown content with github flavored markdown (table)", () => { - const props = { + const props: IPackageReadmeProps = { ...defaultProps, readme: "|h1|h2|\n|-|-|\n|foo|bar|", }; const wrapper = mountWrapper(defaultStore, ); + const component = wrapper.find(ReactMarkdown); expect(component.props()).toMatchObject({ children: props.readme }); expect(component.find("table th").first().text()).toBe("h1"); @@ -61,42 +81,57 @@ it("renders a not found error when error is set", () => { expect(wrapper.text()).toContain("No README found"); }); +it("renders a message if no readme is fetched", () => { + const props: IPackageReadmeProps = { + ...defaultProps, + readme: "", + }; + const wrapper = mountWrapper(defaultStore, ); + + expect(wrapper.text()).toContain("This package does not contain a README file."); +}); + it("renders an alert when error is set", () => { - const wrapper = mountWrapper(defaultStore, ); + const props: IPackageReadmeProps = { + ...defaultProps, + error: "Boom!", + }; + const wrapper = mountWrapper(defaultStore, ); + expect(wrapper.text()).toContain("Unable to fetch the package's README: Boom!"); }); it("renders the ReactMarkdown content adding IDs for the titles", () => { - const wrapper = mountWrapper( - defaultStore, - , - ); + const props: IPackageReadmeProps = { + ...defaultProps, + readme: "# _Markdown_ 'Readme_or_not'!", + }; + const wrapper = mountWrapper(defaultStore, ); + const component = wrapper.find("#markdown-readme_or_not"); expect(component).toExist(); }); it("renders the ReactMarkdown ignoring comments", () => { - const wrapper = mountWrapper( - defaultStore, - - This is text`} - />, - ); + const props: IPackageReadmeProps = { + ...defaultProps, + readme: ` + This is text`, + }; + const wrapper = mountWrapper(defaultStore, ); + const html = wrapper.html(); expect(html).toContain("This is text"); expect(html).not.toContain("This is a comment"); }); it("renders the ReactMarkdown content with hash links", () => { - const wrapper = mountWrapper( - defaultStore, - , - ); + const props: IPackageReadmeProps = { + ...defaultProps, + readme: `[section 1](#section-1) + # Section 1`, + }; + const wrapper = mountWrapper(defaultStore, ); + expect(wrapper.find(Link)).toExist(); }); diff --git a/dashboard/src/components/PackageHeader/PackageReadme.tsx b/dashboard/src/components/PackageHeader/PackageReadme.tsx index 5d1279bce48..6b451051913 100644 --- a/dashboard/src/components/PackageHeader/PackageReadme.tsx +++ b/dashboard/src/components/PackageHeader/PackageReadme.tsx @@ -10,12 +10,13 @@ import HeadingRenderer from "../MarkdownRenderer/HeadingRenderer"; import LinkRenderer from "../MarkdownRenderer/LinkRenderer"; import TableRenderer from "../MarkdownRenderer/TableRenderer"; -interface IPackageReadmeProps { +export interface IPackageReadmeProps { error?: string; readme?: string; + isFetching?: boolean; } -function PackageReadme({ error, readme }: IPackageReadmeProps) { +function PackageReadme({ error, readme, isFetching }: IPackageReadmeProps) { if (error) { if (error.toLocaleLowerCase().includes("not found")) { return ( @@ -33,10 +34,10 @@ function PackageReadme({ error, readme }: IPackageReadmeProps) { - {readme && ( -
+
+ {readme ? ( {readme} -
- )} + ) : ( +

This package does not contain a README file.

+ )} +
); } diff --git a/dashboard/src/components/PackageHeader/PackageView.tsx b/dashboard/src/components/PackageHeader/PackageView.tsx index 87127a0e44a..3f9a9085823 100644 --- a/dashboard/src/components/PackageHeader/PackageView.tsx +++ b/dashboard/src/components/PackageHeader/PackageView.tsx @@ -144,7 +144,11 @@ export default function PackageView() { - +