Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion frontends/api/src/hooks/channels/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,5 @@ export {
useChannelsList,
useChannelPartialUpdate,
useChannelCounts,
channels,
channels as channelsKeyFactory,
}
2 changes: 1 addition & 1 deletion frontends/api/src/hooks/learningResources/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,5 +150,5 @@ export {
useSchoolsList,
useSimilarLearningResources,
useVectorSimilarLearningResources,
learningResources,
learningResources as learningResourcesKeyFactory,
}
2 changes: 1 addition & 1 deletion frontends/api/src/hooks/newsEvents/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@ export {
useNewsEventsList,
useNewsEventsDetail,
NewsEventsListFeedTypeEnum,
newsEvents,
newsEvents as newsEventsKeyFactory,
}
6 changes: 5 additions & 1 deletion frontends/api/src/hooks/testimonials/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,8 @@ const useTestimonialDetail = (id: number | undefined) => {
})
}

export { useTestimonialDetail, useTestimonialList, testimonials }
export {
useTestimonialDetail,
useTestimonialList,
testimonials as testimonialsKeyFactory,
}
14 changes: 4 additions & 10 deletions frontends/api/src/ssr/prefetch.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
import { QueryClient, dehydrate } from "@tanstack/react-query"
import type { Query } from "@tanstack/react-query"

/* Utility to avoid repetition in server components
* Optionally pass the queryClient returned from a previous prefetch
* where queries are dependent on previous results
*/
export const prefetch = async (
queries: (Query | unknown)[],
queryClient?: QueryClient,
) => {
queryClient = queryClient || new QueryClient()
// Utility to avoid repetition in server components
export const prefetch = async (queries: (Query | unknown)[]) => {
const queryClient = new QueryClient()

await Promise.all(
queries.map((query) => queryClient.prefetchQuery(query as Query)),
)

return { dehydratedState: dehydrate(queryClient), queryClient }
return dehydrate(queryClient)
}
12 changes: 6 additions & 6 deletions frontends/api/src/ssr/usePrefetchWarnings.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { usePrefetchWarnings } from "./usePrefetchWarnings"
import { setupReactQueryTest } from "../hooks/test-utils"
import { urls, factories, setMockResponse } from "../test-utils"
import {
learningResources,
learningResourcesKeyFactory,
useLearningResourcesDetail,
} from "../hooks/learningResources"

Expand Down Expand Up @@ -45,7 +45,7 @@ describe("SSR prefetch warnings", () => {
expect.objectContaining({
disabled: false,
initialStatus: "loading",
key: learningResources.detail(1).queryKey,
key: learningResourcesKeyFactory.detail(1).queryKey,
observerCount: 1,
}),
],
Expand All @@ -65,7 +65,7 @@ describe("SSR prefetch warnings", () => {
wrapper,
initialProps: {
queryClient,
exemptions: [learningResources.detail(1).queryKey],
exemptions: [learningResourcesKeyFactory.detail(1).queryKey],
},
})

Expand All @@ -83,7 +83,7 @@ describe("SSR prefetch warnings", () => {
const { unmount } = renderHook(
() =>
useQuery({
...learningResources.detail(1),
...learningResourcesKeyFactory.detail(1),
initialData: data,
}),
{ wrapper },
Expand All @@ -105,9 +105,9 @@ describe("SSR prefetch warnings", () => {
[
{
disabled: false,
hash: JSON.stringify(learningResources.detail(1).queryKey),
hash: JSON.stringify(learningResourcesKeyFactory.detail(1).queryKey),
initialStatus: "success",
key: learningResources.detail(1).queryKey,
key: learningResourcesKeyFactory.detail(1).queryKey,
observerCount: 0,
status: "success",
},
Expand Down
1 change: 0 additions & 1 deletion frontends/api/src/test-utils/factories/channels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,6 @@ const _channelShared = (): Partial<Omit<Channel, "channel_type">> => {
key: faker.lorem.slug(),
value: faker.lorem.slug(),
}),
channel_url: `${faker.internet.url({ appendSlash: false })}${faker.system.directoryPath()}`,
}
}

Expand Down
3 changes: 0 additions & 3 deletions frontends/api/src/test-utils/urls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import type {
NewsEventsApiNewsEventsListRequest,
TestimonialsApi,
ChannelsApi,
} from "../generated/v0"
import type {
LearningResourcesApi as LRApi,
Expand Down Expand Up @@ -187,8 +186,6 @@ const channels = {
details: (channelType: string, name: string) =>
`${API_BASE_URL}/api/v0/channels/type/${channelType}/${name}/`,
patch: (id: number) => `${API_BASE_URL}/api/v0/channels/${id}/`,
list: (params?: Paramsv0<ChannelsApi, "channelsList">) =>
`${API_BASE_URL}/api/v0/channels/${query(params)}`,
}

const widgetLists = {
Expand Down
29 changes: 16 additions & 13 deletions frontends/main/src/app-pages/UnitsListingPage/UnitCard.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from "react"
import type { OfferedByEnum } from "api"
import type { UnitChannel } from "api/v0"
import { LearningResourceOfferorDetail, OfferedByEnum } from "api"
import {
Card,
Skeleton,
Expand All @@ -9,6 +8,7 @@ import {
theme,
UnitLogo,
} from "ol-components"
import { useChannelDetail } from "api/hooks/channels"
import Link from "next/link"

const CardStyled = styled(Card)({
Expand Down Expand Up @@ -102,23 +102,25 @@ const CountsText = styled(Typography)(({ theme }) => ({
}))

interface UnitCardsProps {
channels: UnitChannel[] | undefined
units: LearningResourceOfferorDetail[] | undefined
courseCounts: Record<string, number>
programCounts: Record<string, number>
}

interface UnitCardProps {
channel: UnitChannel
unit: LearningResourceOfferorDetail
courseCount: number
programCount: number
}

const UnitCard: React.FC<UnitCardProps> = (props) => {
const { channel, courseCount, programCount } = props
const unit = channel.unit_detail.unit
const { unit, courseCount, programCount } = props
const channelDetailQuery = useChannelDetail("unit", unit.code)
const channelDetail = channelDetailQuery.data
const unitUrl = channelDetail?.channel_url

if (!channel.channel_url) return null
const href = new URL(channel.channel_url).pathname
if (!unitUrl) return null
const href = unitUrl && new URL(unitUrl).pathname

return (
<CardStyled forwardClicksToLink data-testid={`unit-card-${unit.code}`}>
Expand All @@ -132,7 +134,9 @@ const UnitCard: React.FC<UnitCardProps> = (props) => {
</LogoContainer>
<CardBottom>
<ValuePropContainer>
<HeadingText>{channel?.configuration?.heading}</HeadingText>
<HeadingText>
{channelDetail?.configuration?.heading}
</HeadingText>
</ValuePropContainer>
<CountsTextContainer>
<CountsText data-testid={`course-count-${unit.code}`}>
Expand Down Expand Up @@ -170,18 +174,17 @@ export const UnitCardLoading = () => {
}

export const UnitCards: React.FC<UnitCardsProps> = (props) => {
const { channels, courseCounts, programCounts } = props
const { units, courseCounts, programCounts } = props
return (
<>
{channels?.map((channel) => {
const unit = channel.unit_detail.unit
{units?.map((unit) => {
const courseCount = courseCounts[unit.code] || 0
const programCount = programCounts[unit.code] || 0

return unit.value_prop ? (
<UnitCard
key={unit.code}
channel={channel}
unit={unit}
courseCount={courseCount}
programCount={programCount}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,71 +2,44 @@ import React from "react"
import { renderWithProviders, screen, waitFor, within } from "@/test-utils"
import UnitsListingPage from "./UnitsListingPage"
import { factories, setMockResponse, urls } from "api/test-utils"
import { ChannelTypeEnum } from "api/v0"
import type { UnitChannel } from "api/v0"
import { assertHeadings } from "ol-test-utilities"

describe("UnitListingPage", () => {
describe("DepartmentListingPage", () => {
const setupApis = () => {
const make = factories.channels
const academicUnit1 = make.channel({
channel_type: ChannelTypeEnum.Unit,
name: "academicUnit1",
title: "Academic Unit 1",
unit_detail: {
unit: {
value_prop: "Academic Unit 1 value prop",
professional: false,
},
},
const make = factories.learningResources
const academicUnit1 = make.offeror({
code: "academicUnit1",
name: "Academic Unit 1",
value_prop: "Academic Unit 1 value prop",
professional: false,
})
const academicUnit2 = make.channel({
channel_type: ChannelTypeEnum.Unit,
name: "academicUnit2",
title: "Academic Unit 2",
unit_detail: {
unit: {
value_prop: "Academic Unit 2 value prop",
professional: false,
},
},
const academicUnit2 = make.offeror({
code: "academicUnit2",
name: "Academic Unit 2",
value_prop: "Academic Unit 2 value prop",
professional: false,
})
const academicUnit3 = make.channel({
channel_type: ChannelTypeEnum.Unit,
name: "academicUnit3",
title: "Academic Unit 3",
unit_detail: {
unit: {
value_prop: "Academic Unit 3 value prop",
professional: false,
},
},
const academicUnit3 = make.offeror({
code: "academicUnit3",
name: "Academic Unit 3",
value_prop: "Academic Unit 3 value prop",
professional: false,
})

const professionalUnit1 = make.channel({
channel_type: ChannelTypeEnum.Unit,
name: "professionalUnit1",
title: "Professional Unit 1",
unit_detail: {
unit: {
value_prop: "Professional Unit 1 value prop",
professional: true,
},
},
const professionalUnit1 = make.offeror({
code: "professionalUnit1",
name: "Professional Unit 1",
value_prop: "Professional Unit 1 value prop",
professional: true,
})
const professionalUnit2 = make.channel({
channel_type: ChannelTypeEnum.Unit,
name: "professionalUnit2",
title: "Professional Unit 2",
unit_detail: {
unit: {
value_prop: "Professional Unit 2 value prop",
professional: true,
},
},
const professionalUnit2 = make.offeror({
code: "professionalUnit2",
name: "Professional Unit 2",
value_prop: "Professional Unit 2 value prop",
professional: true,
})

const unitChannels = [
const units = [
academicUnit1,
academicUnit2,
academicUnit3,
Expand All @@ -90,23 +63,29 @@ describe("UnitListingPage", () => {

setMockResponse.get(
urls.channels.counts("unit"),
unitChannels.map((channel) => {
units.map((unit) => {
return {
name: channel.name,
name: unit.code,
counts: {
courses: courseCounts[channel.name],
programs: programCounts[channel.name],
courses: courseCounts[unit.code],
programs: programCounts[unit.code],
},
}
}),
)
setMockResponse.get(urls.channels.list({ channel_type: "unit" }), {
count: unitChannels.length,
results: unitChannels,
setMockResponse.get(urls.offerors.list(), {
count: units.length,
results: units,
})

units.forEach((unit) => {
setMockResponse.get(urls.channels.details("unit", unit.code), {
channel_url: `${window.location.origin}/units/${unit.code}`,
})
})

return {
unitChannels,
units,
courseCounts,
programCounts,
}
Expand All @@ -119,7 +98,7 @@ describe("UnitListingPage", () => {
})

it("Shows unit properties within the proper section", async () => {
const { unitChannels, courseCounts, programCounts } = setupApis()
const { units, courseCounts, programCounts } = setupApis()

renderWithProviders(<UnitsListingPage />)

Expand All @@ -137,15 +116,11 @@ describe("UnitListingPage", () => {
return links
})

unitChannels.forEach((channel) => {
const { unit } = (channel as UnitChannel).unit_detail
units.forEach((unit) => {
const section = unit.professional ? professionalSection : academicSection
const card = within(section).getByTestId(`unit-card-${unit.code}`)
const link = within(card).getByRole("link")
expect(link).toHaveAttribute(
"href",
new URL(channel.channel_url!).pathname,
)
expect(link).toHaveAttribute("href", `/units/${unit.code}`)

const courseCount = courseCounts[unit.code]
const programCount = programCounts[unit.code]
Expand Down
Loading