Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SCC-3762 - Hold Confirmation Details #413

Merged
merged 54 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from 53 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
d9fff88
Merge branch 'main' of github.com:NYPL/research-catalog into SCC-3762…
dgcohen Dec 2, 2024
ddaa479
Merge branch 'hold-pages' of github.com:NYPL/research-catalog into SC…
dgcohen Dec 2, 2024
4a78c27
Initialize HoldPageStatusMessage component
dgcohen Dec 2, 2024
01bc099
Rename to HoldPageStatusMessage
dgcohen Dec 2, 2024
2ba3e42
Update renamed variable references
dgcohen Dec 2, 2024
584843d
More reference name changes
dgcohen Dec 2, 2024
a8121d1
Start error message refactor
dgcohen Dec 3, 2024
faac548
Add patron error messages
dgcohen Dec 3, 2024
7e77b23
Rename pageStatus to errorStatus
dgcohen Dec 3, 2024
a1cdffa
Check patron eligibility in hold request getServerSideProps
dgcohen Dec 3, 2024
dd94ac1
Rename HoldRequestBanner to HoldRequestErrorBanner
dgcohen Dec 3, 2024
bfb4769
Make patron errors a DS list component
dgcohen Dec 3, 2024
d5f09ef
Remove 404 redirect on patron eligibility fetch failure
dgcohen Dec 3, 2024
eeebb65
Remove patron error fallback from body
dgcohen Dec 3, 2024
a1d35f5
Move error copy to constants file
dgcohen Dec 3, 2024
0582787
Fix error handling on edd page
dgcohen Dec 3, 2024
9317001
Remove brackets from redirect path
dgcohen Dec 3, 2024
c186bc9
Remove check on eligibility boolean
dgcohen Dec 3, 2024
c15b8f5
Add top margin to banner body
dgcohen Dec 3, 2024
69e359b
Add switch statement to client side fetch
dgcohen Dec 3, 2024
b14187d
Add eligibility check to api route
dgcohen Dec 3, 2024
87d3528
Add variable with failed edd server responses
dgcohen Dec 4, 2024
2911eb9
Don't show reasons list when none is active
dgcohen Dec 4, 2024
3872336
Don't return reason when there isn't a specific eligibility reason
dgcohen Dec 6, 2024
cf3bda6
Add top margin to reasons box
dgcohen Dec 6, 2024
7f5e309
Render item details on confirmation page
dgcohen Dec 6, 2024
8d9b937
Remove console logs
dgcohen Dec 6, 2024
580b160
Render back to search link
dgcohen Dec 9, 2024
45b8db3
Add margin to search link
dgcohen Dec 9, 2024
50e4b4e
Add separate item table for confirmation page
dgcohen Dec 9, 2024
ff5e32d
Remove redundant item result prop
dgcohen Dec 9, 2024
3fa04f5
Remove query from mocked gerServerSideProps calls
dgcohen Dec 9, 2024
6fcc965
Fix bib item fetching call
dgcohen Dec 9, 2024
3a72e57
Merge branch 'hold-pages' of github.com:NYPL/research-catalog into SC…
dgcohen Dec 9, 2024
76d2837
Update prop names on hold item details components
dgcohen Dec 9, 2024
fdd8d6b
Remove duplicate item initialization
dgcohen Dec 9, 2024
2ed9b4c
Remove NextResponse from hold request api handler
dgcohen Dec 9, 2024
fa7dfa3
Rename fetchHoldRequestEligibility to fetchPatronEligibility
dgcohen Dec 9, 2024
5c108a7
Add tests for fetching patron eligibility status
dgcohen Dec 9, 2024
7439343
Fix patron eligibility error handling and add tests for fetchHoldDetails
dgcohen Dec 9, 2024
22d5f4e
Separate confirmation related changes
dgcohen Dec 10, 2024
06a100b
Restore config file
dgcohen Dec 10, 2024
8be9f65
Add confirmation page tests
dgcohen Dec 10, 2024
1e5a85a
Merge branch 'hold-pages' of github.com:NYPL/research-catalog into SC…
dgcohen Dec 10, 2024
c2cf8c3
Update changelog
dgcohen Dec 10, 2024
122cded
Remove ternaries from HoldConfirmationItemDetails
dgcohen Dec 10, 2024
82533e8
Comment out eligibility fetch
dgcohen Dec 10, 2024
52a1e65
Restore fragment syntax
dgcohen Dec 10, 2024
5ba879f
Pass list children as props in detail element
dgcohen Dec 11, 2024
702b3ec
Remove fragment
dgcohen Dec 11, 2024
1645a55
Restore fragments
dgcohen Dec 11, 2024
dbc84d1
Remove bib and item initialization from getServerSideProps
dgcohen Dec 11, 2024
fdf92d6
Fix comment
dgcohen Dec 11, 2024
e89a976
Remove winston line
dgcohen Dec 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Unreleased
## Prerelease

### Added

- Added and integrated hold confirmation details fetcher function (SCC-3762)
- Added server-side auth redirect to hold confirmation page (SCC-3762)

### Updated

Expand Down
226 changes: 219 additions & 7 deletions __test__/pages/hold/confirmation.test.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,141 @@
import HoldConfirmationPage from "../../../pages/hold/confirmation/[id]"
import HoldConfirmationPage, {
getServerSideProps,
} from "../../../pages/hold/confirmation/[id]"
import { render, screen } from "../../../src/utils/testUtils"
import { bibWithItems } from "../../fixtures/bibFixtures"

import initializePatronTokenAuth, {
doRedirectBasedOnNyplAccountRedirects,
} from "../../../src/server/auth"

import { fetchBib } from "../../../src/server/api/bib"
import {
fetchHoldDetails,
fetchDeliveryLocations,
} from "../../../src/server/api/hold"

jest.mock("../../../src/server/auth")
jest.mock("../../../src/server/api/bib")
jest.mock("../../../src/server/sierraClient")
jest.mock("../../../src/server/api/hold")

jest.mock("next/router", () => jest.requireActual("next-router-mock"))

const mockRes = {
setHeader: jest.fn(),
}
const id = "b15080796-i39333697"
const mockReq = {
headers: {
host: "local.nypl.org:8080",
},
url: `/hold/confirmation/${id}`,
cookies: {
nyplIdentityPatron: '{"access_token":123}',
},
}

describe("Hold Confirmation page", () => {
describe("Hold Confirmation page UI", () => {
describe("logout redirect handling", () => {
beforeEach(() => {
;(initializePatronTokenAuth as jest.Mock).mockResolvedValue({
isTokenValid: true,
errorCode: null,
decodedPatron: { sub: "123" },
})
;(fetchHoldDetails as jest.Mock).mockResolvedValue({
patronId: "123",
pickupLocation: "mal17",
status: 200,
})
;(fetchBib as jest.Mock).mockResolvedValue({
discoveryBibResult: bibWithItems.resource,
status: 200,
})
;(fetchDeliveryLocations as jest.Mock).mockResolvedValue({
eddRequestable: true,
status: 200,
})
})

it("redirects if cookie count is less than 3", async () => {
;(doRedirectBasedOnNyplAccountRedirects as jest.Mock).mockReturnValue(
true
)
;(initializePatronTokenAuth as jest.Mock).mockResolvedValue({
isTokenValid: false,
})

const responseWithZeroRedirects = await getServerSideProps({
params: { id },
req: mockReq,
res: mockRes,
query: {},
})
expect(responseWithZeroRedirects.redirect).toBeDefined()
const responseWithTwoRedirects = await getServerSideProps({
params: { id: "123-456" },
req: { ...mockReq, cookies: { nyplAccountRedirects: 2 } },
res: mockRes,
query: {},
})
expect(responseWithTwoRedirects.redirect).toBeDefined()
})
it("does not redirect if doRedirect method returns false", async () => {
;(doRedirectBasedOnNyplAccountRedirects as jest.Mock).mockReturnValue(
false
)
;(initializePatronTokenAuth as jest.Mock).mockResolvedValue({
decodedPatron: { sub: "123" },
isTokenValid: false,
})

const responseWithoutRedirect = await getServerSideProps({
params: { id },
req: mockReq,
res: mockRes,
query: {},
})
expect(responseWithoutRedirect.redirect).not.toBeDefined()
})
it("does not redirect if patron is authenticated", async () => {
const response = await getServerSideProps({
params: { id },
req: mockReq,
res: mockRes,
query: {},
})
expect(response.redirect).toBeUndefined()
})
it("updates the nyplAccountRedirectsCookie upon redirecting", async () => {
;(doRedirectBasedOnNyplAccountRedirects as jest.Mock).mockReturnValue(
true
)
;(initializePatronTokenAuth as jest.Mock).mockResolvedValue({
decodedPatron: { sub: "123" },
isTokenValid: false,
})
await getServerSideProps({
params: { id },
res: mockRes,
req: mockReq,
query: {},
})
expect(mockRes.setHeader.mock.calls[0]).toStrictEqual([
"Set-Cookie",
"nyplAccountRedirects=1; Max-Age=10; path=/; domain=.nypl.org;",
])
})
})

describe("On-site Confirmation page UI", () => {
beforeEach(() => {
render(<HoldConfirmationPage />)
render(
<HoldConfirmationPage
discoveryBibResult={bibWithItems.resource}
pickupLocationLabel="Schwarzman Building"
/>
)
})

it("renders an H2", () => {
Expand All @@ -13,14 +144,95 @@ describe("Hold Confirmation page", () => {
)
})

it("renders a success banner", () => {
it("renders a success banner with a link to the requested item's bib", () => {
expect(screen.getAllByRole("heading", { level: 2 })[1]).toHaveTextContent(
"Request successful"
)
expect(
screen.queryByText(
"You're all set! We have received your request for",
{
exact: false,
}
)
).toBeInTheDocument()

const bibLink = screen.getByText("Urban spaghetti.")
expect(bibLink).toHaveAttribute(
"href",
"/research/research-catalog/bib/b15080796"
)
})
it("renders an item details table with a pickup location for on-site holds", () => {
expect(screen.getByTestId("pickup-location")).toHaveTextContent(
"Schwarzman Building"
)
expect(screen.getByTestId("call-number")).toHaveTextContent(
"JFK 01-374 no. 4 (2001)"
)
expect(screen.getByTestId("barcode")).toHaveTextContent("33433130221975")
})
it("renders an on-site specific faq accordion", () => {
expect(screen.getByTestId("on-site-confirmation-faq")).toBeInTheDocument()
})
it("renders a back to search link", () => {
const searchLink = screen.getByText("Start a new search")
expect(searchLink).toHaveAttribute(
"href",
"/research/research-catalog/search"
)
})
})
describe("Electronic Delivery Confirmation page UI", () => {
beforeEach(() => {
render(
<HoldConfirmationPage
discoveryBibResult={bibWithItems.resource}
isEDD
/>
)
})

it("renders an H2", () => {
expect(screen.getAllByRole("heading", { level: 2 })[0]).toHaveTextContent(
"Request scan"
)
})

it("renders a success banner with a link to the requested item's bib", () => {
expect(screen.getAllByRole("heading", { level: 2 })[1]).toHaveTextContent(
"Request successful"
)
expect(
screen.queryByText(
"You're all set! We have received your scan request for",
{
exact: false,
}
)
).toBeInTheDocument()

const bibLink = screen.getByText("Urban spaghetti.")
expect(bibLink).toHaveAttribute(
"href",
"/research/research-catalog/bib/b15080796"
)
})
it("renders an item details table without a pickup location for EDD holds", () => {
expect(screen.queryByTestId("pickup-location")).not.toBeInTheDocument()
expect(screen.getByTestId("call-number")).toHaveTextContent(
"JFK 01-374 no. 4 (2001)"
)
expect(screen.getByTestId("barcode")).toHaveTextContent("33433130221975")
})
it("renders an edd-specific faq accordion", () => {
expect(screen.getByTestId("edd-confirmation-faq")).toBeInTheDocument()
})
it("renders a faq accordion", () => {
expect(screen.getByRole("heading", { level: 3 })).toHaveTextContent(
"Frequently asked questions"
it("renders a back to search link", () => {
const searchLink = screen.getByText("Start a new search")
expect(searchLink).toHaveAttribute(
"href",
"/research/research-catalog/search"
)
})
})
Expand Down
Loading
Loading