-
Notifications
You must be signed in to change notification settings - Fork 165
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into snyk-upgrade-cb9acf232477db6dd68b7234f1ceae8b
- Loading branch information
Showing
30 changed files
with
1,854 additions
and
392 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,66 @@ | ||
import React from "react"; | ||
|
||
import { render, screen } from "@testing-library/react"; | ||
import entityGroup from "~/lib/data/law-firms"; | ||
import LawFirmPage, { | ||
getStaticPaths, | ||
getStaticProps, | ||
} from "~/pages/lbh/[lawFirmSlug]"; | ||
|
||
jest.mock("~/lib/data/law-firms"); | ||
|
||
describe("LawFirmPage", () => { | ||
const [lawFirm] = entityGroup.data; | ||
|
||
it("renders the title and the breadcrumbs correctly", () => { | ||
render(<LawFirmPage lawFirm={lawFirm} />); | ||
|
||
const lawFirmListBreadcrumbs = screen.getByText(/^lembaga bantuan hukum$/i); | ||
expect(lawFirmListBreadcrumbs).toBeVisible(); | ||
expect(lawFirmListBreadcrumbs).toHaveAttribute("href", `/lbh`); | ||
|
||
const [lawFirmBreadcrumbs, title] = screen.getAllByText(lawFirm.nama_lbh); | ||
expect(lawFirmBreadcrumbs).toBeVisible(); | ||
expect(lawFirmBreadcrumbs).toHaveAttribute("href", `/lbh/${lawFirm.slug}`); | ||
|
||
expect(title).toBeVisible(); | ||
}); | ||
}); | ||
|
||
describe("getStaticPaths", () => { | ||
it("returns the correct paths", () => { | ||
const paths = entityGroup.data.map((lawFirm) => ({ | ||
params: { | ||
lawFirmSlug: lawFirm.slug, | ||
}, | ||
})); | ||
expect(getStaticPaths({})).toEqual({ | ||
fallback: false, | ||
paths, | ||
}); | ||
}); | ||
}); | ||
|
||
describe("getStaticProps", () => { | ||
const [lawFirm] = entityGroup.data; | ||
|
||
it("gets the lawFirm from the lawFirmSlug params", () => { | ||
expect( | ||
getStaticProps({ | ||
params: { lawFirmSlug: lawFirm.slug }, | ||
}), | ||
).toEqual({ | ||
props: { | ||
lawFirm, | ||
}, | ||
}); | ||
}); | ||
|
||
it("returns undefined only given an empty params", () => { | ||
expect(getStaticProps({})).toEqual({ | ||
props: { | ||
lawFirm: undefined, | ||
}, | ||
}); | ||
}); | ||
}); |
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,79 @@ | ||
import React from "react"; | ||
|
||
import { render, screen, within } from "@testing-library/react"; | ||
import userEvent from "@testing-library/user-event"; | ||
import LawFirmsPage, { getStaticProps } from "~/pages/lbh"; | ||
import { lawFirmBuilder } from "~/lib/data/__mocks__/builders/law-firms"; | ||
import entityGroup from "~/lib/data/law-firms"; | ||
|
||
jest.mock("~/lib/data/law-firms"); | ||
jest.mock("next/router", () => require("next-router-mock")); | ||
|
||
describe("LawFirmsPage", () => { | ||
const lawFirm1 = lawFirmBuilder(); | ||
const lawFirm2 = lawFirmBuilder(); | ||
const lawFirmList = [lawFirm1, lawFirm2]; | ||
|
||
it("renders the title and the breadcrumbs correctly", () => { | ||
render(<LawFirmsPage lawFirmList={lawFirmList} />); | ||
|
||
const [breadcrumbs, title] = screen.getAllByText("Lembaga Bantuan Hukum"); | ||
|
||
expect(breadcrumbs).toBeVisible(); | ||
expect(breadcrumbs).toHaveAttribute("href", "/lbh"); | ||
expect(title).toBeVisible(); | ||
}); | ||
|
||
it("renders the law firms list correctly", () => { | ||
render(<LawFirmsPage lawFirmList={lawFirmList} />); | ||
|
||
expect(screen.getByText(lawFirm1.nama_lbh)).toBeVisible(); | ||
|
||
const lbhFirmLink = screen.getByRole("link", { | ||
name: lawFirm1.nama_lbh, | ||
}); | ||
expect(lbhFirmLink).toHaveAttribute("href", `/lbh/${lawFirm1.slug}`); | ||
|
||
expect(within(lbhFirmLink).getByText(lawFirm1.nama_lbh)).toBeVisible(); | ||
}); | ||
|
||
it("performs the search functionality correctly", async () => { | ||
const aceh = lawFirmBuilder({ | ||
overrides: { | ||
nama_lbh: "LBH Aceh", | ||
}, | ||
}); | ||
const medan = lawFirmBuilder({ | ||
overrides: { | ||
nama_lbh: "LBH Medan", | ||
}, | ||
}); | ||
|
||
render(<LawFirmsPage lawFirmList={[aceh, medan]} />); | ||
|
||
expect(screen.getByText(aceh.nama_lbh)).toBeVisible(); | ||
|
||
userEvent.type( | ||
screen.getByRole("textbox", { | ||
name: /cari lembaga bantuan hukum:/i, | ||
}), | ||
medan.nama_lbh, | ||
); | ||
userEvent.click(screen.getByRole("button", { name: /cari/i })); | ||
|
||
expect(screen.queryByText(aceh.nama_lbh)).not.toBeInTheDocument(); | ||
expect(screen.getByText(medan.nama_lbh)).toBeVisible(); | ||
}); | ||
}); | ||
|
||
describe("getStaticProps", () => { | ||
it("transforms entityGroup into lawFirmList props correctly", () => { | ||
// TODO: Do a better test because this test is merely a copy of the implementation | ||
const lawFirmList = entityGroup.data; | ||
expect(getStaticProps({})).toEqual({ | ||
props: { | ||
lawFirmList, | ||
}, | ||
}); | ||
}); | ||
}); |
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,93 @@ | ||
import clsx from "clsx"; | ||
import htmr from "htmr"; | ||
import { CopyButton } from "~/components/copy-button"; | ||
import { OpenMapButton } from "~/components/open-map-button"; | ||
import { LawFirm } from "~/lib/data/law-firms"; | ||
import { htmrTransform } from "~/lib/htmr-transformers"; | ||
import { isNotEmpty, stripTags } from "~/lib/string-utils"; | ||
|
||
type LawFirmDetailsProps = { | ||
lawFirm: LawFirm; | ||
}; | ||
|
||
type DescriptionItemProps = { | ||
label: string; | ||
value?: string; | ||
withCopyButton?: boolean; | ||
withOpenMapButton?: boolean; | ||
withTruncation?: boolean; | ||
}; | ||
|
||
const DescriptionItem = (props: DescriptionItemProps) => { | ||
const value = isNotEmpty(props.value) ? (props.value as string) : ""; | ||
|
||
return ( | ||
<div className="py-4 px-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4"> | ||
<dt className="text-sm font-medium text-gray-500">{props.label}</dt> | ||
<dd className="mt-1 flex text-sm text-gray-900 sm:mt-0 sm:col-span-2"> | ||
<span | ||
className={clsx("flex-grow", props.withTruncation ? "truncate" : "")} | ||
> | ||
{htmr(value, { transform: htmrTransform })} | ||
</span> | ||
<div className="flex flex-col items-end space-y-1 flex-none ml-2"> | ||
{typeof value == "string" && | ||
value.length > 0 && | ||
props.withCopyButton && <CopyButton text={stripTags(value)} />} | ||
{typeof value == "string" && | ||
value.length > 0 && | ||
props.withOpenMapButton && ( | ||
<OpenMapButton address={stripTags(value)} /> | ||
)} | ||
</div> | ||
</dd> | ||
</div> | ||
); | ||
}; | ||
|
||
export function LawFirmDetails({ lawFirm }: LawFirmDetailsProps) { | ||
return ( | ||
<div className="bg-white shadow overflow-hidden rounded-md"> | ||
<dl className="divide-y divide-gray-200"> | ||
<DescriptionItem label="Nama LBH" value={lawFirm.nama_lbh} /> | ||
<DescriptionItem | ||
label="Alamat" | ||
value={lawFirm.alamat} | ||
withCopyButton | ||
withOpenMapButton | ||
/> | ||
<DescriptionItem | ||
label="Kontak" | ||
value={lawFirm.nomor_kontak} | ||
withCopyButton | ||
/> | ||
<DescriptionItem label="Email" value={lawFirm.email} /> | ||
<DescriptionItem | ||
label="Website" | ||
value={lawFirm.website} | ||
withTruncation | ||
/> | ||
<DescriptionItem label="Instagram" value={lawFirm.ig} withTruncation /> | ||
<DescriptionItem | ||
label="Twitter" | ||
value={lawFirm.twitter} | ||
withTruncation | ||
/> | ||
<DescriptionItem | ||
label="Facebook" | ||
value={lawFirm.facebook} | ||
withTruncation | ||
/> | ||
<DescriptionItem | ||
label="Link Donasi" | ||
value={lawFirm.link_donasi} | ||
withTruncation | ||
/> | ||
<DescriptionItem | ||
label="Status Verifikasi" | ||
value={lawFirm.verifikasi ? "Terverifikasi" : "Belum terverifikasi"} | ||
/> | ||
</dl> | ||
</div> | ||
); | ||
} |
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,105 @@ | ||
import React from "react"; | ||
|
||
import { BadgeCheckIcon as BadgeCheckIconUnverified } from "@heroicons/react/outline"; | ||
import { | ||
BadgeCheckIcon, | ||
LocationMarkerIcon, | ||
PhoneIcon, | ||
} from "@heroicons/react/solid"; | ||
import htmr from "htmr"; | ||
import Link from "next/link"; | ||
import { CopyButton } from "./copy-button"; | ||
import { Badge } from "./ui/badge"; | ||
import { OpenMapButton } from "./open-map-button"; | ||
import { isNotEmpty, stripTags } from "~/lib/string-utils"; | ||
import { htmrTransform } from "~/lib/htmr-transformers"; | ||
import { LawFirm } from "~/lib/data/law-firms"; | ||
|
||
interface LawFirmListItemProps { | ||
lawFirm: LawFirm; | ||
} | ||
|
||
function LawFirmListItem({ lawFirm }: LawFirmListItemProps) { | ||
return ( | ||
<li> | ||
<div className="px-4 py-4 sm:px-6 relative hover:bg-gray-50"> | ||
<div className="flex items-center justify-between"> | ||
<Link href={`/lbh/${lawFirm.slug}`}> | ||
<a | ||
className="text-sm font-semibold text-blue-600 truncate block helper-link-cover" | ||
title={lawFirm.nama_lbh} | ||
> | ||
{lawFirm.nama_lbh} | ||
</a> | ||
</Link> | ||
<div className="flex-shrink-0 flex space-x-2"> | ||
<Badge color="yellow">Lembaga Bantuan Hukum</Badge> | ||
</div> | ||
</div> | ||
<div className="mt-2 sm:flex sm:justify-between"> | ||
<p className="text-sm font-medium text-gray-600 truncate"> | ||
{lawFirm.email} | ||
</p> | ||
{lawFirm.verifikasi ? ( | ||
<div className="mt-2 mb-3 flex items-center text-xs text-gray-500 sm:my-0"> | ||
<BadgeCheckIcon | ||
aria-hidden="true" | ||
className="flex-shrink-0 h-4 w-4 sm:order-2 text-green-400" | ||
/> | ||
<p className="ml-2 mr-1">Terverifikasi</p> | ||
</div> | ||
) : ( | ||
<div className="mt-2 mb-3 flex items-center text-xs text-gray-400 sm:my-0"> | ||
<BadgeCheckIconUnverified | ||
aria-hidden="true" | ||
className="flex-shrink-0 h-4 w-4 sm:order-2 text-gray-400" | ||
/> | ||
<p className="ml-2 mr-1">Belum terverifkasi</p> | ||
</div> | ||
)} | ||
</div> | ||
{isNotEmpty(lawFirm.nomor_kontak) && ( | ||
<div className="mt-2 flex justify-between w-full"> | ||
<p className="flex items-center text-sm text-gray-500"> | ||
<PhoneIcon | ||
aria-hidden="true" | ||
className="flex-shrink-0 mr-2 h-4 w-4 text-gray-400" | ||
/> | ||
{htmr(lawFirm.nomor_kontak as string, { | ||
transform: htmrTransform, | ||
})} | ||
</p> | ||
{typeof lawFirm.nomor_kontak == "string" && ( | ||
<CopyButton text={stripTags(lawFirm.nomor_kontak)} /> | ||
)} | ||
</div> | ||
)} | ||
{isNotEmpty(lawFirm.alamat) && ( | ||
<div className="mt-2 flex justify-between w-full"> | ||
<p className="mt-2 flex items-start text-sm text-gray-500 sm:mt-0"> | ||
<LocationMarkerIcon | ||
aria-hidden="true" | ||
className="flex-shrink-0 mr-2 h-4 w-4 text-gray-400" | ||
/> | ||
{htmr(lawFirm.alamat, { | ||
transform: htmrTransform, | ||
})} | ||
</p> | ||
<div className="flex flex-col items-end space-y-1 flex-none ml-2"> | ||
{typeof lawFirm.alamat == "string" && ( | ||
<CopyButton text={stripTags(lawFirm.alamat)} /> | ||
)} | ||
{typeof lawFirm.alamat == "string" && ( | ||
<OpenMapButton address={stripTags(lawFirm.alamat)} /> | ||
)} | ||
</div> | ||
</div> | ||
)} | ||
</div> | ||
</li> | ||
); | ||
} | ||
|
||
const _LawFirmListItem = React.memo(LawFirmListItem); | ||
|
||
export { _LawFirmListItem as LawFirmListItem }; |
Oops, something went wrong.