-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Logic for trimming/revising the links works Corresponding specs are failing (`Cannot read properties of null (reading 'useMemo'`) Also need to set up protocols API auth flow
- Loading branch information
1 parent
d3ad26e
commit 3ac9107
Showing
4 changed files
with
120 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
// Fetcher function that lets SWR fetch multiple urls at once | ||
export const multiFetcher = (...urls: string[]) => { | ||
const f = (url: string) => fetch(url).then((response) => response.json()); | ||
return Promise.all(urls.map((url) => f(url))); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,40 @@ | ||
import React from 'react'; | ||
import { useMemo } from 'react'; | ||
import useSWR from 'swr'; | ||
|
||
function useProtocolData(doiSuffix, lastVersion = 1) { | ||
const [protocol, setProtocol] = React.useState({}); | ||
React.useEffect(() => { | ||
async function getAndSetProtocol() { | ||
const url = `https://www.protocols.io/api/v3/protocols/${doiSuffix}?last_version=${lastVersion}`; | ||
const response = await fetch(url); | ||
if (!response.ok) { | ||
console.error('Protocol API failed:', url, response); | ||
return; | ||
} | ||
const data = await response.json(); | ||
setProtocol(data); | ||
} | ||
getAndSetProtocol(); | ||
}, [doiSuffix, lastVersion]); | ||
import { multiFetcher } from 'js/helpers/multiFetcher'; | ||
|
||
return protocol; | ||
export function useFormattedProtocolUrls(protocolUrls, lastVersion) { | ||
return useMemo(() => { | ||
// Handle case with multiple URLs provided in one string | ||
// If only one string is provided, it will be returned as an array | ||
const protocols = protocolUrls.split(','); | ||
// Strip `http://` and `https://` from the beginning of the URL if it exists | ||
// https://dx.doi.org/10.17504/protocols.io.btnfnmbn -> dx.doi.org/10.17504/protocols.io.btnfnmbn | ||
const noHttpPrefix = protocols.map((url) => url.replace(/^(?:https?:\/\/)?/i, '')); | ||
// Strip `dx.doi.org/` from the beginning of the URL if it exists | ||
// dx.doi.org/10.17504/protocols.io.btnfnmbn -> 10.17504/protocols.io.btnfnmbn | ||
const noDomainPrefix = noHttpPrefix.map((url) => url.replace(/^dx.doi.org\//i, '')); | ||
// Strip version number from end of the URL if it exists | ||
// 10.17504/protocols.io.btnfnmbn/v1 -> 10.17504/protocols.io.btnfnmbn | ||
const noVersionSuffix = noDomainPrefix.map((url) => url.replace(/\/v\d+$/, '')); | ||
// Format into the API call URL | ||
// 10.17504/protocols.io.btnfnmbn -> https://www.protocols.io/api/v3/protocols/10.17504/protocols.io.btnfnmbn?last_version=1 | ||
const formattedUrls = noVersionSuffix.map( | ||
// TODO: Update to v4 API (see HMP-254) | ||
(doi) => `https://www.protocols.io/api/v3/protocols/${doi}?last_version=${lastVersion}`, | ||
); | ||
return formattedUrls; | ||
}, [protocolUrls, lastVersion]); | ||
} | ||
|
||
function useProtocolData(protocolUrls, lastVersion = 1) { | ||
const urls = useFormattedProtocolUrls(protocolUrls, lastVersion); | ||
|
||
const protocols = useSWR(urls, multiFetcher, { | ||
revalidateOnFocus: false, | ||
}); | ||
|
||
return protocols.data ?? []; | ||
} | ||
|
||
export default useProtocolData; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import { renderHook } from '@testing-library/react-hooks'; | ||
|
||
import { useFormattedProtocolUrls } from './useProtocolData'; | ||
|
||
describe('useFormattedProtocolUrls', () => { | ||
it('should format a single URL with no version number', () => { | ||
const protocolUrls = 'https://dx.doi.org/10.17504/protocols.io.btnfnmbn'; | ||
const lastVersion = 1; | ||
const { result } = renderHook(useFormattedProtocolUrls(protocolUrls, lastVersion)); | ||
expect(result).toEqual(['https://www.protocols.io/api/v3/protocols/10.17504/protocols.io.btnfnmbn?last_version=1']); | ||
}); | ||
|
||
it('should format multiple URLs with version numbers', () => { | ||
const protocolUrls = | ||
'https://dx.doi.org/10.17504/protocols.io.btnfnmbn/v1,https://dx.doi.org/10.17504/protocols.io.7d5h6en/v2'; | ||
const lastVersion = 2; | ||
const { result } = renderHook(useFormattedProtocolUrls(protocolUrls, lastVersion)); | ||
expect(result).toEqual([ | ||
'https://www.protocols.io/api/v3/protocols/10.17504/protocols.io.btnfnmbn?last_version=2', | ||
'https://www.protocols.io/api/v3/protocols/10.17504/protocols.io.7d5h6en?last_version=2', | ||
]); | ||
}); | ||
|
||
it('should handle URLs with http:// prefix', () => { | ||
const protocolUrls = 'http://dx.doi.org/10.17504/protocols.io.btnfnmbn'; | ||
const lastVersion = 1; | ||
const { result } = renderHook(useFormattedProtocolUrls(protocolUrls, lastVersion)); | ||
expect(result).toEqual(['https://www.protocols.io/api/v3/protocols/10.17504/protocols.io.btnfnmbn?last_version=1']); | ||
}); | ||
|
||
it('should handle URLs with https:// prefix', () => { | ||
const protocolUrls = 'https://dx.doi.org/10.17504/protocols.io.btnfnmbn'; | ||
const lastVersion = 1; | ||
const { result } = renderHook(useFormattedProtocolUrls(protocolUrls, lastVersion)); | ||
expect(result).toEqual(['https://www.protocols.io/api/v3/protocols/10.17504/protocols.io.btnfnmbn?last_version=1']); | ||
}); | ||
|
||
it('should handle URLs with dx.doi.org/ prefix', () => { | ||
const protocolUrls = 'dx.doi.org/10.17504/protocols.io.btnfnmbn'; | ||
const lastVersion = 1; | ||
const { result } = renderHook(useFormattedProtocolUrls(protocolUrls, lastVersion)); | ||
expect(result).toEqual(['https://www.protocols.io/api/v3/protocols/10.17504/protocols.io.btnfnmbn?last_version=1']); | ||
}); | ||
|
||
it('should handle URLs with multiple prefixes', () => { | ||
const protocolUrls = | ||
'https://dx.doi.org/10.17504/protocols.io.btnfnmbn/v1,http://dx.doi.org/10.17504/protocols.io.7d5h6en/v2'; | ||
const lastVersion = 2; | ||
const { result } = renderHook(useFormattedProtocolUrls(protocolUrls, lastVersion)); | ||
expect(result).toEqual([ | ||
'https://www.protocols.io/api/v3/protocols/10.17504/protocols.io.btnfnmbn?last_version=2', | ||
'https://www.protocols.io/api/v3/protocols/10.17504/protocols.io.7d5h6en?last_version=2', | ||
]); | ||
}); | ||
|
||
it('should handle URLs with no http or https prefix', () => { | ||
const protocolUrls = 'dx.doi.org/10.17504/protocols.io.btnfnmbn/v1'; | ||
const lastVersion = 1; | ||
const { result } = renderHook(useFormattedProtocolUrls(protocolUrls, lastVersion)); | ||
expect(result).toEqual(['https://www.protocols.io/api/v3/protocols/10.17504/protocols.io.btnfnmbn?last_version=1']); | ||
}); | ||
|
||
it('should handle URLs with no version number', () => { | ||
const protocolUrls = 'https://dx.doi.org/10.17504/protocols.io.btnfnmbn'; | ||
const lastVersion = 2; | ||
const { result } = renderHook(useFormattedProtocolUrls(protocolUrls, lastVersion)); | ||
expect(result).toEqual(['https://www.protocols.io/api/v3/protocols/10.17504/protocols.io.btnfnmbn?last_version=2']); | ||
}); | ||
|
||
it('should handle empty input', () => { | ||
const protocolUrls = ''; | ||
const lastVersion = 1; | ||
const { result } = renderHook(useFormattedProtocolUrls(protocolUrls, lastVersion)); | ||
expect(result).toEqual([]); | ||
}); | ||
}); |