From 8057abacdb0c55a76cd563eb4e556768328fedf9 Mon Sep 17 00:00:00 2001 From: ajay-sentry <159853603+ajay-sentry@users.noreply.github.com> Date: Wed, 18 Sep 2024 09:53:09 -0700 Subject: [PATCH] fix: Guard when calling match() on undefined (#3207) --- .../DefaultOrgSelector/DefaultOrgSelector.jsx | 2 +- .../DefaultOrgSelector.spec.jsx | 20 +++++++++---------- src/ui/A/A.jsx | 5 ++++- src/ui/A/A.spec.jsx | 13 +++++++++++- .../CodeRendererProgressHeader.jsx | 2 +- 5 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/pages/DefaultOrgSelector/DefaultOrgSelector.jsx b/src/pages/DefaultOrgSelector/DefaultOrgSelector.jsx index 779f170443..87e530152a 100644 --- a/src/pages/DefaultOrgSelector/DefaultOrgSelector.jsx +++ b/src/pages/DefaultOrgSelector/DefaultOrgSelector.jsx @@ -47,7 +47,7 @@ const renderItem = ({ item }) => { if (item?.isProvider) { return (
- + Install Codecov GitHub app diff --git a/src/pages/DefaultOrgSelector/DefaultOrgSelector.spec.jsx b/src/pages/DefaultOrgSelector/DefaultOrgSelector.spec.jsx index 469240b794..c7ece2209f 100644 --- a/src/pages/DefaultOrgSelector/DefaultOrgSelector.spec.jsx +++ b/src/pages/DefaultOrgSelector/DefaultOrgSelector.spec.jsx @@ -330,8 +330,8 @@ describe('DefaultOrgSelector', () => { const selfOrg = screen.getByRole('option', { name: 'Rula' }) expect(selfOrg).toBeInTheDocument() - const addNewOrg = screen.getByRole('option', { - name: 'plus-circle.svg Install Codecov GitHub app', + const addNewOrg = screen.getByRole('link', { + name: 'plus-circle.svg Install Codecov GitHub app external-link.svg', }) expect(addNewOrg).toBeInTheDocument() }) @@ -378,8 +378,8 @@ describe('DefaultOrgSelector', () => { const selfOrg = screen.queryByRole('option', { name: 'janedoe' }) expect(selfOrg).not.toBeInTheDocument() - const addNewOrg = screen.getByRole('option', { - name: 'plus-circle.svg Install Codecov GitHub app', + const addNewOrg = screen.getByRole('link', { + name: 'plus-circle.svg Install Codecov GitHub app external-link.svg', }) expect(addNewOrg).toBeInTheDocument() }) @@ -417,8 +417,8 @@ describe('DefaultOrgSelector', () => { const noOrgsFound = screen.getByText(/No organizations found/) expect(noOrgsFound).toBeInTheDocument() - const addNewOrg = screen.getByRole('option', { - name: 'plus-circle.svg Install Codecov GitHub app', + const addNewOrg = screen.getByRole('link', { + name: 'plus-circle.svg Install Codecov GitHub app external-link.svg', }) expect(addNewOrg).toBeInTheDocument() }) @@ -458,8 +458,8 @@ describe('DefaultOrgSelector', () => { const orgInList = screen.getByRole('option', { name: 'criticalRole' }) expect(orgInList).toBeInTheDocument() - const addNewOrg = screen.queryByRole('option', { - name: 'plus-circle.svg Install Codecov GitHub app', + const addNewOrg = screen.queryByRole('link', { + name: 'plus-circle.svg Install Codecov GitHub app external-link.svg', }) expect(addNewOrg).not.toBeInTheDocument() }) @@ -496,8 +496,8 @@ describe('DefaultOrgSelector', () => { await user.click(selectOrg) - const addNewOrg = screen.getByRole('option', { - name: 'plus-circle.svg Install Codecov GitHub app', + const addNewOrg = screen.getByRole('link', { + name: 'plus-circle.svg Install Codecov GitHub app external-link.svg', }) await user.click(addNewOrg) diff --git a/src/ui/A/A.jsx b/src/ui/A/A.jsx index 601083b65c..058eca5c08 100644 --- a/src/ui/A/A.jsx +++ b/src/ui/A/A.jsx @@ -30,7 +30,10 @@ const variantClasses = { configure: `rounded bg-ds-blue-default px-4 py-1 font-semibold text-ds-gray-primary dark:text-white dark:bg-ds-blue-nonary`, } -const getHostnameFromRegex = (url) => { +export const getHostnameFromRegex = (url) => { + if (!url) { + return 'app.codecov.io' + } // run against regex const matches = url.match(/^https?:\/\/([^/?#]+)(?:[/?#]|$)/i) // extract hostname (will be null if no match is found) diff --git a/src/ui/A/A.spec.jsx b/src/ui/A/A.spec.jsx index bb618d4893..57ee13164e 100644 --- a/src/ui/A/A.spec.jsx +++ b/src/ui/A/A.spec.jsx @@ -1,7 +1,7 @@ import { render, screen } from '@testing-library/react' import { MemoryRouter } from 'react-router-dom' -import A from '.' +import A, { getHostnameFromRegex } from './A' describe('A', () => { function setup(props = {}) { @@ -10,6 +10,17 @@ describe('A', () => { }) } + describe('hostnameWithoutRegex', () => { + it('returns to home if no url passed', () => { + expect(getHostnameFromRegex(undefined)).toBe('app.codecov.io') + }) + it('scrubs URL if one exists', () => { + expect(getHostnameFromRegex('https://app.codecov.io')).toBe( + 'app.codecov.io' + ) + }) + }) + describe('when rendered with the prop `to`', () => { beforeEach(() => { setup({ diff --git a/src/ui/CodeRenderer/CodeRendererProgressHeader/CodeRendererProgressHeader.jsx b/src/ui/CodeRenderer/CodeRendererProgressHeader/CodeRendererProgressHeader.jsx index c68be21885..6fba3bf725 100644 --- a/src/ui/CodeRenderer/CodeRendererProgressHeader/CodeRendererProgressHeader.jsx +++ b/src/ui/CodeRenderer/CodeRendererProgressHeader/CodeRendererProgressHeader.jsx @@ -12,7 +12,7 @@ function CodeRendererProgressHeader({ path, fileCoverage, change }) { * Header component that shows progress bar for the Code Renderer component. * @param {[String]} treePaths path of file from root directory. Only used in standalone file viewer * @param {Float} fileCoverage total coverage of current file - * @param {Float} change difference between head and base coverage. Only used in commmit based file viewer + * @param {Float} change difference between head and base coverage. Only used in commit based file viewer */ const isUnsupportedFileType = unsupportedExtensionsMapper({ path })