From 81e1ad3c178a572960c0178555a6bd1a5aca2afb Mon Sep 17 00:00:00 2001 From: Xavier FACQ Date: Thu, 25 Apr 2024 16:34:15 +0200 Subject: [PATCH 1/3] issue-2808 Release notes pages not operational for april releases --- .../__tests__/ReleaseNotesRender.test.tsx | 18 ++++---- src/components/ReleaseNotesRender/index.tsx | 10 +++-- .../fetchReleaseNotes.test.tsx.snap | 41 ++++++++++--------- .../__tests__/fetchReleaseNotes.test.tsx | 4 +- src/hooks/fetchReleaseNotes.tsx | 22 +++++++--- .../temurin/__tests__/release-notes.test.tsx | 4 +- 6 files changed, 59 insertions(+), 40 deletions(-) diff --git a/src/components/ReleaseNotesRender/__tests__/ReleaseNotesRender.test.tsx b/src/components/ReleaseNotesRender/__tests__/ReleaseNotesRender.test.tsx index f60c6e9c9..3e023b49b 100644 --- a/src/components/ReleaseNotesRender/__tests__/ReleaseNotesRender.test.tsx +++ b/src/components/ReleaseNotesRender/__tests__/ReleaseNotesRender.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { render } from '@testing-library/react'; import { describe, expect, it, vi } from 'vitest' import ReleaseNotesRender, { fetchTitle, sortReleaseNotesBy } from '../index'; -import { fetchReleaseNotesForVersion, ReleaseNoteAPIResponse } from '../../../hooks/fetchReleaseNotes'; +import { fetchReleaseNotesForVersion } from '../../../hooks/fetchReleaseNotes'; import { createMockReleaseNotesAPI } from '../../../__fixtures__/hooks'; import { DataGridProps } from "@mui/x-data-grid" import queryString from 'query-string'; @@ -32,7 +32,7 @@ describe('ReleaseNotesRender component', () => { queryString.parse = vi.fn().mockReturnValue({'version': 'jdk-17.0.1+12'}); // @ts-ignore - fetchReleaseNotesForVersion.mockReturnValue(createMockReleaseNotesAPI(2)); + fetchReleaseNotesForVersion.mockReturnValue({ releaseNoteAPIResponse :createMockReleaseNotesAPI(2), isValid: true }); const { container } = render( @@ -72,9 +72,9 @@ describe('ReleaseNotesRender component', () => { queryString.parse = vi.fn().mockReturnValue({'version': 'jdk-20+36'}); function mockReleaseNotes(num: number) { - let mockReleaseNotesAPI = createMockReleaseNotesAPI(num); - mockReleaseNotesAPI.release_notes[0].type = 'Enhancement'; - return mockReleaseNotesAPI; + let releaseNoteDataBag = { releaseNoteAPIResponse :createMockReleaseNotesAPI(num), isValid: true }; + releaseNoteDataBag.releaseNoteAPIResponse.release_notes[0].type = 'Enhancement'; + return releaseNoteDataBag; } // @ts-ignore @@ -91,9 +91,9 @@ describe('ReleaseNotesRender component', () => { it('should render correctly - priority not defined', () => { queryString.parse = vi.fn().mockReturnValue({'version': 'version'}); function mockReleaseNotes() { - let mockReleaseNotesAPI = createMockReleaseNotesAPI(1); - mockReleaseNotesAPI.release_notes[0].priority = undefined; - return mockReleaseNotesAPI; + let releaseNoteDataBag = { releaseNoteAPIResponse :createMockReleaseNotesAPI(1), isValid: true }; + releaseNoteDataBag.releaseNoteAPIResponse.release_notes[0].priority = undefined; + return releaseNoteDataBag; } // @ts-ignore @@ -110,7 +110,7 @@ describe('ReleaseNotesRender component', () => { queryString.parse = vi.fn().mockReturnValue({'version': 'version'}); // @ts-ignore - fetchReleaseNotesForVersion.mockReturnValue({ release_notes: null}); + fetchReleaseNotesForVersion.mockReturnValue({ releaseNoteAPIResponse :createMockReleaseNotesAPI(0), isValid: false }); const { container } = render( ); diff --git a/src/components/ReleaseNotesRender/index.tsx b/src/components/ReleaseNotesRender/index.tsx index 40f8bce54..7c1c54b47 100644 --- a/src/components/ReleaseNotesRender/index.tsx +++ b/src/components/ReleaseNotesRender/index.tsx @@ -2,7 +2,7 @@ import React, { useRef, MutableRefObject } from 'react'; import { DataGrid, GridColDef, GridToolbarContainer, GridToolbarFilterButton, gridClasses } from '@mui/x-data-grid'; import { useLocation } from '@gatsbyjs/reach-router'; import queryString from 'query-string'; -import { fetchReleaseNotesForVersion, useOnScreen, ReleaseNoteAPIResponse } from '../../hooks'; +import { fetchReleaseNotesForVersion, useOnScreen, ReleaseNoteAPIResponse, ReleaseNoteDataBag } from '../../hooks'; import './ReleaseNotesRender.scss'; export const fetchTitle = (priority) => { @@ -109,8 +109,10 @@ const ReleaseNotesRender = (): null | JSX.Element => { const ref = useRef(null); const isVisible = useOnScreen(ref as MutableRefObject, true); - const releaseNotes = fetchReleaseNotesForVersion(isVisible, version, sortReleaseNotesBy); + const releaseNoteDataBag = fetchReleaseNotesForVersion(isVisible, version, sortReleaseNotesBy); + const releaseNotes = releaseNoteDataBag ? releaseNoteDataBag.releaseNoteAPIResponse : null; + // Set all priorities set as undefined to '?' to avoid errors releaseNotes?.release_notes?.forEach((note) => { if (note.priority === undefined) { @@ -163,7 +165,7 @@ const ReleaseNotesRender = (): null | JSX.Element => {

{version}

- {!version || releaseNotes?.release_notes === null ? ( + {!version || releaseNoteDataBag?.isValid === false ? ( <>

Oops... We couldn't find those release notes

Please ensure that you have a specified a version using the version URL parameter: ?version=x.x.x @@ -175,7 +177,7 @@ const ReleaseNotesRender = (): null | JSX.Element => { returns valid JSON 1`] = ` { - "id": "id_mock", - "release_name": "release_name_mock", - "release_notes": [ - { - "component": "component_mock", - "id": "0", - "link": "https://link_mock/", - "priority": "1", - "title": "title_mock", - "type": "Bug", + "isValid": true, + "releaseNoteAPIResponse": { + "id": "id_mock", + "release_name": "release_name_mock", + "release_notes": [ + { + "component": "component_mock", + "id": "0", + "link": "https://link_mock/", + "priority": "1", + "title": "title_mock", + "type": "Bug", + }, + ], + "vendor": "vendor_mock", + "version_data": { + "build": 0, + "major": 0, + "minor": 0, + "openjdk_version": "openjdk_version_mock", + "patch": 0, + "security": 0, }, - ], - "vendor": "vendor_mock", - "version_data": { - "build": 0, - "major": 0, - "minor": 0, - "openjdk_version": "openjdk_version_mock", - "patch": 0, - "security": 0, }, } `; diff --git a/src/hooks/__tests__/fetchReleaseNotes.test.tsx b/src/hooks/__tests__/fetchReleaseNotes.test.tsx index db1d40920..c7c4603de 100644 --- a/src/hooks/__tests__/fetchReleaseNotes.test.tsx +++ b/src/hooks/__tests__/fetchReleaseNotes.test.tsx @@ -25,8 +25,10 @@ describe('fetchReleaseNotesForVersion', () => { let spy = vi.spyOn(axios, "get"); const { result } = renderHook(() => fetchReleaseNotesForVersion(true, 'sample_version', sortReleaseNotesByCallback)); + + await waitFor(() => { - expect(result.current?.release_name).toBe('release_name_mock') + expect(result.current?.releaseNoteAPIResponse?.release_name).toBe('release_name_mock') }, { interval: 1 }); expect(spy).toHaveBeenCalledTimes(1) expect(spy).toHaveBeenCalledWith( diff --git a/src/hooks/fetchReleaseNotes.tsx b/src/hooks/fetchReleaseNotes.tsx index 79bf79e7f..833dc37d4 100644 --- a/src/hooks/fetchReleaseNotes.tsx +++ b/src/hooks/fetchReleaseNotes.tsx @@ -8,12 +8,12 @@ export function fetchReleaseNotesForVersion( isVisible: boolean, version: any, sortReleaseNotesByCallback?: Function, -): ReleaseNoteAPIResponse | null { +): ReleaseNoteDataBag | null { if (!version) { return null } - const [releaseNotes, setReleaseNotes] = useState(null); + const [releaseNotes, setReleaseNotes] = useState(null); useEffect(() => { if (isVisible) { @@ -22,12 +22,19 @@ export function fetchReleaseNotesForVersion( await axios.get(url.toString()) .then(function (response) { - let result = response.data + let result = response.data; if(sortReleaseNotesByCallback) sortReleaseNotesByCallback(result); - setReleaseNotes(result) + let releaseNoteDataBag: ReleaseNoteDataBag = { + releaseNoteAPIResponse: result, + isValid: (result.release_notes !== null) + }; + setReleaseNotes(releaseNoteDataBag); }) .catch(function (error) { - setReleaseNotes(null) + let releaseNoteDataBag: ReleaseNoteDataBag = { + isValid: false + }; + setReleaseNotes(releaseNoteDataBag); }); })(); } @@ -36,6 +43,11 @@ export function fetchReleaseNotesForVersion( return releaseNotes; } +export interface ReleaseNoteDataBag { + releaseNoteAPIResponse?: ReleaseNoteAPIResponse + isValid: boolean +} + export interface ReleaseNoteAPIResponse { id: string; release_name: string; diff --git a/src/pages/temurin/__tests__/release-notes.test.tsx b/src/pages/temurin/__tests__/release-notes.test.tsx index 27d1eae85..1c4392879 100644 --- a/src/pages/temurin/__tests__/release-notes.test.tsx +++ b/src/pages/temurin/__tests__/release-notes.test.tsx @@ -25,7 +25,7 @@ describe('Temurin Release Notes page', () => { useOnScreen.mockReturnValue(true); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - fetchReleaseNotesForVersion.mockReturnValue(createMockReleaseNotesAPI(1)); + fetchReleaseNotesForVersion.mockReturnValue({ releaseNoteAPIResponse :createMockReleaseNotesAPI(1), isValid: true }); const { container } = render(); // eslint-disable-next-line const pageContent = container.querySelector('main'); @@ -47,7 +47,7 @@ describe('Temurin Release Notes page', () => { useOnScreen.mockReturnValue(true); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - fetchReleaseNotesForVersion.mockReturnValue(createMockReleaseNotesAPI(1)); + fetchReleaseNotesForVersion.mockReturnValue({ releaseNoteAPIResponse :createMockReleaseNotesAPI(1), isValid: true }); await act(async () => { const { container } = render(); const results = await axe(container); From 8a62e17ec29e8c0d0aa12c74fe438f85f6e37e94 Mon Sep 17 00:00:00 2001 From: Xavier FACQ Date: Thu, 25 Apr 2024 16:39:44 +0200 Subject: [PATCH 2/3] clean code --- src/components/ReleaseNotesRender/index.tsx | 2 +- src/hooks/__tests__/fetchReleaseNotes.test.tsx | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/ReleaseNotesRender/index.tsx b/src/components/ReleaseNotesRender/index.tsx index 7c1c54b47..3bd58511d 100644 --- a/src/components/ReleaseNotesRender/index.tsx +++ b/src/components/ReleaseNotesRender/index.tsx @@ -2,7 +2,7 @@ import React, { useRef, MutableRefObject } from 'react'; import { DataGrid, GridColDef, GridToolbarContainer, GridToolbarFilterButton, gridClasses } from '@mui/x-data-grid'; import { useLocation } from '@gatsbyjs/reach-router'; import queryString from 'query-string'; -import { fetchReleaseNotesForVersion, useOnScreen, ReleaseNoteAPIResponse, ReleaseNoteDataBag } from '../../hooks'; +import { fetchReleaseNotesForVersion, useOnScreen, ReleaseNoteAPIResponse } from '../../hooks'; import './ReleaseNotesRender.scss'; export const fetchTitle = (priority) => { diff --git a/src/hooks/__tests__/fetchReleaseNotes.test.tsx b/src/hooks/__tests__/fetchReleaseNotes.test.tsx index c7c4603de..b3eec1414 100644 --- a/src/hooks/__tests__/fetchReleaseNotes.test.tsx +++ b/src/hooks/__tests__/fetchReleaseNotes.test.tsx @@ -26,7 +26,6 @@ describe('fetchReleaseNotesForVersion', () => { const { result } = renderHook(() => fetchReleaseNotesForVersion(true, 'sample_version', sortReleaseNotesByCallback)); - await waitFor(() => { expect(result.current?.releaseNoteAPIResponse?.release_name).toBe('release_name_mock') }, { interval: 1 }); From 9fd7fe66620ce30907a0366f42877dff4255241e Mon Sep 17 00:00:00 2001 From: Xavier FACQ Date: Thu, 25 Apr 2024 17:00:30 +0200 Subject: [PATCH 3/3] Add a CircularProgress while loading --- src/components/ReleaseNotesRender/index.tsx | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/components/ReleaseNotesRender/index.tsx b/src/components/ReleaseNotesRender/index.tsx index 3bd58511d..84235a98b 100644 --- a/src/components/ReleaseNotesRender/index.tsx +++ b/src/components/ReleaseNotesRender/index.tsx @@ -4,6 +4,7 @@ import { useLocation } from '@gatsbyjs/reach-router'; import queryString from 'query-string'; import { fetchReleaseNotesForVersion, useOnScreen, ReleaseNoteAPIResponse } from '../../hooks'; import './ReleaseNotesRender.scss'; +import CircularProgress from '@mui/material/CircularProgress'; export const fetchTitle = (priority) => { let title @@ -112,13 +113,6 @@ const ReleaseNotesRender = (): null | JSX.Element => { const releaseNoteDataBag = fetchReleaseNotesForVersion(isVisible, version, sortReleaseNotesBy); const releaseNotes = releaseNoteDataBag ? releaseNoteDataBag.releaseNoteAPIResponse : null; - - // Set all priorities set as undefined to '?' to avoid errors - releaseNotes?.release_notes?.forEach((note) => { - if (note.priority === undefined) { - note.priority = '6'; - } - }); if(releaseNotes && Array.isArray(releaseNotes.release_notes)) { let priorities: string[] = []; @@ -126,6 +120,11 @@ const ReleaseNotesRender = (): null | JSX.Element => { let components: string[] = []; releaseNotes.release_notes.forEach(release_note => { + // Set all priorities set as undefined to '?' to avoid errors + if (release_note.priority === undefined) { + release_note.priority = '6'; + } + if(release_note.priority && priorities.indexOf(release_note.priority) < 0) priorities.push(release_note.priority); if(release_note.type && types.indexOf(release_note.type) < 0) types.push(release_note.type); if(release_note.component && components.indexOf(release_note.component) < 0) components.push(release_note.component); @@ -164,7 +163,8 @@ const ReleaseNotesRender = (): null | JSX.Element => {

{version}

-
+ {!releaseNoteDataBag ?
: + (
{!version || releaseNoteDataBag?.isValid === false ? ( <>

Oops... We couldn't find those release notes

@@ -211,7 +211,7 @@ const ReleaseNotesRender = (): null | JSX.Element => { /> )} -
+
)}
);