diff --git a/src/frontend/js/components/CourseGlimpse/index.stories.tsx b/src/frontend/js/components/CourseGlimpse/index.stories.tsx index bcd7b0555a..2361feaf82 100644 --- a/src/frontend/js/components/CourseGlimpse/index.stories.tsx +++ b/src/frontend/js/components/CourseGlimpse/index.stories.tsx @@ -1,5 +1,5 @@ import { Meta, StoryObj } from '@storybook/react'; -import { RichieContextFactory, CourseFactory } from 'utils/test/factories/richie'; +import { RichieContextFactory, CourseLightFactory } from 'utils/test/factories/richie'; import { CourseGlimpse } from '.'; export default { @@ -11,6 +11,6 @@ type Story = StoryObj; export const RichieCourse: Story = { args: { context: RichieContextFactory().generate(), - course: CourseFactory.generate(), + course: CourseLightFactory.generate(), }, }; diff --git a/src/frontend/js/components/CourseGlimpseList/index.stories.tsx b/src/frontend/js/components/CourseGlimpseList/index.stories.tsx index 8b12f88f3d..69f83e480f 100644 --- a/src/frontend/js/components/CourseGlimpseList/index.stories.tsx +++ b/src/frontend/js/components/CourseGlimpseList/index.stories.tsx @@ -1,5 +1,5 @@ import { Meta, StoryObj } from '@storybook/react'; -import { RichieContextFactory, CourseFactory } from 'utils/test/factories/richie'; +import { RichieContextFactory, CourseLightFactory } from 'utils/test/factories/richie'; import { CourseGlimpseList } from '.'; export default { @@ -11,7 +11,7 @@ type Story = StoryObj; export const RichieCourseList: Story = { args: { context: RichieContextFactory().generate(), - courses: CourseFactory.generate(10), + courses: CourseLightFactory.generate(10), meta: { count: 10, offset: 0, diff --git a/src/frontend/js/hooks/useOrders.ts b/src/frontend/js/hooks/useOrders.ts index 57c79be0a1..abb239aaf5 100644 --- a/src/frontend/js/hooks/useOrders.ts +++ b/src/frontend/js/hooks/useOrders.ts @@ -1,11 +1,11 @@ import { defineMessages } from 'react-intl'; -import { API, Course, Order, OrderState, PaginatedResourceQuery, Product } from 'types/Joanie'; +import { API, CourseLight, Order, OrderState, PaginatedResourceQuery, Product } from 'types/Joanie'; import { useJoanieApi } from 'contexts/JoanieApiContext'; import { useSessionMutation } from 'utils/react-query/useSessionMutation'; import { QueryOptions, useResource, useResourcesCustom, UseResourcesProps } from './useResources'; export type OrderResourcesQuery = PaginatedResourceQuery & { - course?: Course['code']; + course?: CourseLight['code']; product?: Product['id']; state?: OrderState[]; }; diff --git a/src/frontend/js/types/Joanie.ts b/src/frontend/js/types/Joanie.ts index 4c10059dae..5af61cbda3 100644 --- a/src/frontend/js/types/Joanie.ts +++ b/src/frontend/js/types/Joanie.ts @@ -34,7 +34,7 @@ export interface CourseRun { text: StateText; }; title: string; - course?: Course; + course?: CourseLight; } // - Certificate @@ -106,7 +106,7 @@ export interface CourseProduct extends Product { target_courses: TargetCourse[]; } -export interface Course extends AbstractCourse { +export interface CourseLight extends AbstractCourse { products: CourseProduct[]; orders?: OrderLite[]; } @@ -136,7 +136,7 @@ export enum OrderState { export interface Order { id: string; - course?: Course['code'] | Course; + course?: CourseLight['code'] | CourseLight; created_on: string; enrollments: Enrollment[]; main_proforma_invoice: string; @@ -183,11 +183,11 @@ export interface Address { // Wishlist export interface UserWishlistCourse { id: string; - course: Course['code']; + course: CourseLight['code']; } export interface UserWishlistCreationPayload { - course: Course['code']; + course: CourseLight['code']; } // Payment @@ -217,7 +217,7 @@ export interface AddressCreationPayload extends Omit interface OrderCreationPayload { product: Product['id']; - course: Course['code']; + course: CourseLight['code']; billing_address?: Omit; credit_card_id?: CreditCard['id']; } diff --git a/src/frontend/js/utils/test/factories/joanie.ts b/src/frontend/js/utils/test/factories/joanie.ts index 2e37bda1b7..d3b9b1e7d6 100644 --- a/src/frontend/js/utils/test/factories/joanie.ts +++ b/src/frontend/js/utils/test/factories/joanie.ts @@ -99,12 +99,27 @@ export const CourseRunFactory = (scopes?: { course: Boolean }) => { text: 'closing on', }, ...(scopes?.course && { - course: CourseFactory.generate(), + course: CourseLightFactory.generate(), }), }); }; export const CourseFactory = createSpec({ + code: faker.random.alphaNumeric(5), + organization: OrganizationFactory, + title: faker.unique(faker.random.words(Math.ceil(Math.random() * 3))), + state: { + call_to_action: null, + datetime: derived(() => faker.date.past(0.25)().toISOString()), + priority: Priority.ONGOING_OPEN, + text: 'Ongoing', + }, + cover_image: { + src: '/static/course_cover_image.jpg', + }, +}); + +export const CourseLightFactory = createSpec({ code: faker.random.alphaNumeric(5), organization: OrganizationLightFactory, title: faker.unique(faker.random.words(Math.ceil(Math.random() * 3))), diff --git a/src/frontend/js/utils/test/factories/richie.ts b/src/frontend/js/utils/test/factories/richie.ts index 2de14a8938..fbef7e44b3 100644 --- a/src/frontend/js/utils/test/factories/richie.ts +++ b/src/frontend/js/utils/test/factories/richie.ts @@ -61,7 +61,7 @@ export const RichieContextFactory = (context: Partial context.web_analytics_providers || null), }); -export const CourseFactory = createSpec({ +export const CourseLightFactory = createSpec({ absolute_url: '', categories: [], code: faker.random.alphaNumeric(5), diff --git a/src/frontend/js/widgets/CourseAddToWishlist/index.tsx b/src/frontend/js/widgets/CourseAddToWishlist/index.tsx index 6003ac7b8c..27e8b56fda 100644 --- a/src/frontend/js/widgets/CourseAddToWishlist/index.tsx +++ b/src/frontend/js/widgets/CourseAddToWishlist/index.tsx @@ -37,7 +37,7 @@ enum ComponentStates { } export interface Props { - courseCode: Joanie.Course['code']; + courseCode: Joanie.CourseLight['code']; } const CourseAddToWishlist = ({ courseCode }: Props) => { diff --git a/src/frontend/js/widgets/CourseProductItem/components/CourseProductCourseRuns/index.spec.tsx b/src/frontend/js/widgets/CourseProductItem/components/CourseProductCourseRuns/index.spec.tsx index 5babda8fee..34fbbb5391 100644 --- a/src/frontend/js/widgets/CourseProductItem/components/CourseProductCourseRuns/index.spec.tsx +++ b/src/frontend/js/widgets/CourseProductItem/components/CourseProductCourseRuns/index.spec.tsx @@ -6,13 +6,13 @@ import { IntlProvider } from 'react-intl'; import { QueryClientProvider } from '@tanstack/react-query'; import { RichieContextFactory as mockRichieContextFactory } from 'utils/test/factories/richie'; import { - CourseFactory, + CourseLightFactory, CourseRunFactory, EnrollmentFactory, OrderFactory, } from 'utils/test/factories/joanie'; import JoanieApiProvider from 'contexts/JoanieApiContext'; -import type { Course, CourseRun, Enrollment, OrderLite } from 'types/Joanie'; +import type { CourseLight, CourseRun, Enrollment, OrderLite } from 'types/Joanie'; import { Deferred } from 'utils/test/deferred'; import { Priority } from 'types'; import { createTestQueryClient } from 'utils/test/createTestQueryClient'; @@ -133,7 +133,7 @@ describe('CourseProductCourseRuns', () => { }); it('renders a list of course runs with a call to action to enroll', async () => { - const course: Course = CourseFactory.generate(); + const course: CourseLight = CourseLightFactory.generate(); const courseRuns: CourseRun[] = CourseRunFactory().generate(2); const order: OrderLite = OrderFactory.generate(); @@ -233,7 +233,7 @@ describe('CourseProductCourseRuns', () => { }); it('enroll with errors', async () => { - const course: Course = CourseFactory.generate(); + const course: CourseLight = CourseLightFactory.generate(); const courseRuns: CourseRun[] = CourseRunFactory().generate(2); const order: OrderLite = OrderFactory.generate(); fetchMock.get(`https://joanie.test/api/v1.0/courses/${course.code}/`, 200); diff --git a/src/frontend/js/widgets/CourseProductItem/contexts/CourseProductContext/index.tsx b/src/frontend/js/widgets/CourseProductItem/contexts/CourseProductContext/index.tsx index 4c1ec09cd0..56aa63d2b3 100644 --- a/src/frontend/js/widgets/CourseProductItem/contexts/CourseProductContext/index.tsx +++ b/src/frontend/js/widgets/CourseProductItem/contexts/CourseProductContext/index.tsx @@ -4,13 +4,13 @@ import type * as Joanie from 'types/Joanie'; const Context = createContext< Maybe<{ - courseCode: Joanie.Course['code']; + courseCode: Joanie.CourseLight['code']; productId: Joanie.Product['id']; }> >(undefined); export interface CourseProductProviderProps { - courseCode: Joanie.Course['code']; + courseCode: Joanie.CourseLight['code']; productId: Joanie.Product['id']; } diff --git a/src/frontend/js/widgets/CourseProductItem/index.tsx b/src/frontend/js/widgets/CourseProductItem/index.tsx index d9f11fd611..cf1b340a9d 100644 --- a/src/frontend/js/widgets/CourseProductItem/index.tsx +++ b/src/frontend/js/widgets/CourseProductItem/index.tsx @@ -33,7 +33,7 @@ const messages = defineMessages({ export interface Props { productId: Joanie.Product['id']; - courseCode: Joanie.Course['code']; + courseCode: Joanie.CourseLight['code']; } const CourseProductItem = ({ productId, courseCode }: Props) => { diff --git a/src/frontend/js/widgets/Dashboard/components/DashboardItem/Certificate/index.spec.tsx b/src/frontend/js/widgets/Dashboard/components/DashboardItem/Certificate/index.spec.tsx index d7654009ac..b8ca41bca1 100644 --- a/src/frontend/js/widgets/Dashboard/components/DashboardItem/Certificate/index.spec.tsx +++ b/src/frontend/js/widgets/Dashboard/components/DashboardItem/Certificate/index.spec.tsx @@ -5,7 +5,7 @@ import { IntlProvider } from 'react-intl'; import userEvent from '@testing-library/user-event'; import fetchMock from 'fetch-mock'; import { RichieContextFactory as mockRichieContextFactory } from 'utils/test/factories/richie'; -import { Certificate, Course } from 'types/Joanie'; +import { Certificate, CourseLight } from 'types/Joanie'; import { createTestQueryClient } from 'utils/test/createTestQueryClient'; import { SessionProvider } from 'contexts/SessionContext'; import { DashboardItemCertificate } from 'widgets/Dashboard/components/DashboardItem/Certificate/index'; @@ -52,7 +52,7 @@ describe('', () => { render(, { wrapper: Wrapper }); await waitFor(() => screen.getByText(certificate.certificate_definition.title)); - screen.getByText((certificate.order.course as Course).title); + screen.getByText((certificate.order.course as CourseLight).title); screen.getByText( 'Issued on ' + new Intl.DateTimeFormat('en', DEFAULT_DATE_FORMAT).format(new Date(certificate.issued_on)), diff --git a/src/frontend/js/widgets/Dashboard/components/DashboardItem/Certificate/index.tsx b/src/frontend/js/widgets/Dashboard/components/DashboardItem/Certificate/index.tsx index b12ec3bf5b..dd4a63d00a 100644 --- a/src/frontend/js/widgets/Dashboard/components/DashboardItem/Certificate/index.tsx +++ b/src/frontend/js/widgets/Dashboard/components/DashboardItem/Certificate/index.tsx @@ -1,7 +1,7 @@ import { defineMessages, FormattedMessage } from 'react-intl'; import { Button } from 'components/Button'; import { Icon } from 'components/Icon'; -import { Certificate, CertificateDefinition, Course } from 'types/Joanie'; +import { Certificate, CertificateDefinition, CourseLight } from 'types/Joanie'; import { useDownloadCertificate } from 'hooks/useDownloadCertificate'; import { Spinner } from 'components/Spinner'; import useDateFormat from 'hooks/useDateFormat'; @@ -58,7 +58,7 @@ export const DashboardItemCertificate = ({ throw new Error('certificate or certificateDefinition is required'); } - const course = certificate?.order.course as Maybe; + const course = certificate?.order.course as Maybe; const { download, loading } = useDownloadCertificate(); const formatDate = useDateFormat(); diff --git a/src/frontend/js/widgets/Dashboard/components/DashboardItem/DashboardItemCourseEnrolling.stories.tsx b/src/frontend/js/widgets/Dashboard/components/DashboardItem/DashboardItemCourseEnrolling.stories.tsx index a52b4acfcc..0c5f2b57ce 100644 --- a/src/frontend/js/widgets/Dashboard/components/DashboardItem/DashboardItemCourseEnrolling.stories.tsx +++ b/src/frontend/js/widgets/Dashboard/components/DashboardItem/DashboardItemCourseEnrolling.stories.tsx @@ -1,7 +1,7 @@ import { Meta, StoryObj } from '@storybook/react'; import { createMemoryRouter, RouterProvider } from 'react-router-dom'; import faker from 'faker'; -import { CourseFactory } from 'utils/test/factories/joanie'; +import { CourseLightFactory } from 'utils/test/factories/joanie'; import { StorybookHelper } from 'utils/StorybookHelper'; import { Priority } from 'types'; import { enrollment } from './stories.mock'; @@ -39,7 +39,7 @@ type Story = StoryObj; export const ReadonlyEnrolledOpened: Story = { args: { - course: CourseFactory.generate(), + course: CourseLightFactory.generate(), activeEnrollment: { ...enrollment, course_run: { @@ -53,7 +53,7 @@ export const ReadonlyEnrolledOpened: Story = { export const ReadonlyEnrolledClosed: Story = { args: { - course: CourseFactory.generate(), + course: CourseLightFactory.generate(), activeEnrollment: { ...enrollment, course_run: { @@ -67,6 +67,6 @@ export const ReadonlyEnrolledClosed: Story = { export const ReadonlyNotEnrolled: Story = { args: { - course: CourseFactory.generate(), + course: CourseLightFactory.generate(), }, };