Skip to content

Commit

Permalink
Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
Claudio Benedetti committed Jan 15, 2024
1 parent 750203b commit 033e4a0
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 56 deletions.
70 changes: 35 additions & 35 deletions src/utils/__tests__/http-client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1075,38 +1075,6 @@ describe('Rerouting', () => {

})

it('should fetch a get method', async () => {
const customSupport = {
...support,
reroutingRules: [
{from: '^/$', to: '/reroute'},
{from: '^/orig$', to: '/reroute-1'},
{from: {method: 'GET', url: '^/orig-2$'}, to: '/path/reroute-2'}
]
}
const client = createFetchHttpClient.bind<() => HttpClientInstance>(customSupport)()

const {origin} = window.location

// @ts-expect-error Testing URL class
await client.fetch(new URL('/', origin))
// @ts-expect-error Testing URL class
await client.get(new URL('/orig', origin))
// @ts-expect-error Testing URL class
await client.get(new URL('/orig-2?_id=1', origin))
// @ts-expect-error Testing URL class
await client.get(new URL('/orig-3', origin))
// @ts-expect-error Testing URL class
await client.get(new URL('/orig-3?_id=1', origin))

expect(fetchMock).toBeCalledTimes(5)
expect(fetchMock).toHaveBeenNthCalledWith(1, `${origin}/reroute`, expect.any(Object))
expect(fetchMock).toHaveBeenNthCalledWith(2, `${origin}/reroute-1`, expect.any(Object))
expect(fetchMock).toHaveBeenNthCalledWith(3, `${origin}/path/reroute-2?_id=1`, expect.any(Object))
expect(fetchMock).toHaveBeenNthCalledWith(4, `${origin}/orig-3`, expect.any(Object))
expect(fetchMock).toHaveBeenNthCalledWith(5, `${origin}/orig-3?_id=1`, expect.any(Object))
})

it('should be robust to incorrect rerouting rules', async () => {
const empty = {...support, reroutingRules: []}
const incomplete = {...support, reroutingRules: [{}]}
Expand All @@ -1125,11 +1093,11 @@ describe('Rerouting', () => {
await clientEmpty.get('/')
await clientIncomplete.get('/')
await clientIncomplete2.get('/')
// @ts-expect-error invalid config
// @ts-expect-error force invalid config
await clientUnkMethod.fetch('/', {method: 'unk'})
// @ts-expect-error invalid config
// @ts-expect-error force invalid config
await clientValid.fetch('/', {method: false})
// @ts-expect-error invalid config
// @ts-expect-error force invalid config
await clientValid.fetch('/', {method: 'unk'})

expect(fetchMock).toBeCalledTimes(6)
Expand All @@ -1140,4 +1108,36 @@ describe('Rerouting', () => {
expect(fetchMock).toHaveBeenNthCalledWith(5, `${origin}/`, expect.any(Object))
expect(fetchMock).toHaveBeenNthCalledWith(6, `${origin}/`, expect.any(Object))
})

it('should fetch a get method', async () => {
const customSupport = {
...support,
reroutingRules: [
{from: '^/$', to: '/reroute'},
{from: '^/orig$', to: '/reroute-1'},
{from: {method: 'GET', url: '^/orig-2$'}, to: '/path/reroute-2'}
]
}
const client = createFetchHttpClient.bind<() => HttpClientInstance>(customSupport)()

const {origin} = window.location

// @ts-expect-error force URL instance input
await client.fetch(new URL('/', origin))
// @ts-expect-error force URL instance input
await client.get(new URL('/orig', origin))
// @ts-expect-error force URL instance input
await client.get(new URL('/orig-2?_id=1', origin))
// @ts-expect-error force URL instance input
await client.get(new URL('/orig-3', origin))
// @ts-expect-error force URL instance input
await client.get(new URL('/orig-3?_id=1', origin))

expect(fetchMock).toBeCalledTimes(5)
expect(fetchMock).toHaveBeenNthCalledWith(1, `${origin}/reroute`, expect.any(Object))
expect(fetchMock).toHaveBeenNthCalledWith(2, `${origin}/reroute-1`, expect.any(Object))
expect(fetchMock).toHaveBeenNthCalledWith(3, `${origin}/path/reroute-2?_id=1`, expect.any(Object))
expect(fetchMock).toHaveBeenNthCalledWith(4, `${origin}/orig-3`, expect.any(Object))
expect(fetchMock).toHaveBeenNthCalledWith(5, `${origin}/orig-3?_id=1`, expect.any(Object))
})
})
41 changes: 20 additions & 21 deletions src/utils/http-client/with-rerouting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,27 +33,26 @@ function isValidRerouteRule (input: unknown): input is ValidRerouteRule {
&& typeof to === 'string'
}

const getRegexGroups = (input: string, regex: RegExp) => {
const match = input.match(regex)
if (!match) {
return {}
}
const getRegexGroups = (match: RegExpMatchArray) => {
const namedGroups = {...match.groups}
const positionalGroups = match.slice(1)?.filter((g) => !Object.values(namedGroups).includes(g)) ?? []
return positionalGroups.reduce((acc, group, idx) => ({...acc, [`${idx+1}`]: group}), namedGroups)
}

const getRouter: (rules: ValidRerouteRule[]) => ReroutingFunction = (rules) => {
return (inputUrl, inputMethod) => {
const ruleToApply = rules.find(({from: {method, url: urlRegex}}) =>
inputMethod === method && inputUrl.match(urlRegex)
)
if (ruleToApply) {
const tagetUrl = ruleToApply.to
const groups = getRegexGroups(inputUrl, ruleToApply.from.url)
return Object
.entries(groups)
.reduce((acc, [toReplace, replaceWith]) => acc.replaceAll(`$${toReplace}`, replaceWith), tagetUrl)
let match: RegExpMatchArray | null = null
for (const {to: targetUrl, from: {method, url: urlRegex}} of rules) {
match = inputUrl.match(urlRegex)
if (inputMethod === method && match) {
const groups = getRegexGroups(match)
if (Object.keys(groups).length > 0) {
return Object
.entries(groups)
.reduce((acc, [toReplace, replaceWith]) => acc.replaceAll(`$${toReplace}`, replaceWith), targetUrl)
}
return targetUrl
}
}
return inputUrl
}
Expand Down Expand Up @@ -97,13 +96,13 @@ export function withRerouting (this: HttpClientSupport): void | (() => void) {
url.pathname = router(url.pathname, init.method)
return fetch(typeof input === 'string' ? url.toString() : url, init, ...rest)
}
// else if (input instanceof Request) {
// const {url: reqUrl, ...reqRest} = input
// const url = new URL(reqUrl)
// url.pathname = router(url.pathname, init.method)
// const reroutedReq = {url: url.toString(), ...reqRest}
// return fetch(reroutedReq, init, ...rest)
// }
else if (input instanceof Request) {
const {url: reqUrl, ...reqRest} = input
const url = new URL(reqUrl)
url.pathname = router(url.pathname, init.method)
const reroutedReq = {url: url.toString(), ...reqRest}
return fetch(reroutedReq, init, ...rest)
}
}

return fetch(input, init, ...rest)
Expand Down

0 comments on commit 033e4a0

Please sign in to comment.