Skip to content

Commit

Permalink
Merge pull request #40 from danskernesdigitalebibliotek/DDFBRA-159-gl…
Browse files Browse the repository at this point in the history
…obal-route-helper-function

refactor: route helper function and add unit tests
  • Loading branch information
ThomasGross authored Nov 12, 2024
2 parents 121fa20 + 7305595 commit d57d410
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 19 deletions.
22 changes: 22 additions & 0 deletions __tests__/url.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { expect, test, vi } from "vitest"

import { resolveUrl } from "../lib/helpers/helper.routes"

test("That resolveUrl can return a work url", async () => {
const workUrl = resolveUrl({ type: "work", routeParams: { id: 123 } })
expect(workUrl).toBe("/work/123")
})

test("That resolveUrl can return a work url with a manifestation type", async () => {
const workUrl = resolveUrl({
type: "work",
routeParams: { id: 123 },
queryParams: { audio: "true" },
})
expect(workUrl).toBe("/work/123?audio=true")
})

test("That resolveUrl can return a search url", async () => {
const workUrl = resolveUrl({ type: "search", queryParams: { q: "test" } })
expect(workUrl).toBe("/search?q=test")
})
6 changes: 4 additions & 2 deletions components/shared/workCard/WorkCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Link from "next/link"
import React from "react"

import { WorkTeaserFragment } from "@/lib/graphql/generated/fbi/graphql"
import { resolveWorkUrl } from "@/lib/helpers/helper.routes"
import { resolveUrl } from "@/lib/helpers/helper.routes"
import { getIsbnsFromWork } from "@/lib/helpers/ids"
import { useGetCoverCollection } from "@/lib/rest/cover-service-api/generated/cover-service"
import { GetCoverCollectionSizesItem } from "@/lib/rest/cover-service-api/generated/model"
Expand Down Expand Up @@ -56,7 +56,9 @@ const WorkCard = ({ work }: WorkCardProps) => {
const lowResCover = getLowResCoverUrl(dataCovers)

return (
<Link className="block space-y-3 lg:space-y-5" href={resolveWorkUrl(work.workId)}>
<Link
className="block space-y-3 lg:space-y-5"
href={resolveUrl({ type: "work", routeParams: { id: work.workId } })}>
<div>
<div
key={work.workId}
Expand Down
56 changes: 39 additions & 17 deletions lib/helpers/helper.routes.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,56 @@
type RouteParams = { [key: string]: string | number }
type QueryParams = { [key: string]: string | number }

// Example usage:
// const userRoute = buildRoute("/users/:id", { id: 123 })
// console.log(userRoute) // Output: /users/123

// const searchRoute = buildRoute("/search", undefined, { query: "test" })
// console.log(searchRoute) // Output: /search?query=test

function buildRoute(route: string, params?: RouteParams, query?: QueryParams): string {
export function buildRoute({
route,
params,
query,
}: {
route: string
params?: RouteParams
query?: QueryParams
}): string {
if (params) {
route = Object.keys(params).reduce((acc, key) => {
const value = encodeURIComponent(params[key])
return acc.replace(`:${key}`, value)
}, route)
}

const queryParams = new URLSearchParams()
if (query) {
const queryString = Object.keys(query)
.map(key => `${encodeURIComponent(key)}=${encodeURIComponent(query[key])}`)
.join("&")
route += `?${queryString}`
Object.keys(query).forEach(key => {
queryParams.append(key, query[key].toString())
})
}

if (queryParams.toString()) {
return `${route}?${queryParams}`
}

return route
}

// Add url resolvers for each route below
const resolveWorkUrl = (id: string) => {
return buildRoute("/work/:id", { id: id })
}
type ResolveUrlOptions =
| {
type: "work"
routeParams?: { id: number | string }
queryParams?: QueryParams
}
| {
type: "search"
routeParams?: undefined
queryParams?: QueryParams
}

export { resolveWorkUrl, buildRoute }
export const resolveUrl = ({ type, routeParams, queryParams }: ResolveUrlOptions) => {
switch (type as ResolveUrlOptions["type"]) {
case "work":
if (!routeParams?.id) return ""
return buildRoute({ route: "/work/:id", params: { id: routeParams.id }, query: queryParams })
case "search":
return buildRoute({ route: "/search", query: queryParams })
default:
return ""
}
}

0 comments on commit d57d410

Please sign in to comment.