ENT-11639: Add testimonials to all plans - updated AcademicSelection component#180
ENT-11639: Add testimonials to all plans - updated AcademicSelection component#180gshivajibiradar wants to merge 3 commits intomainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Adds testimonials support across the checkout/essentials flows and adjusts navigation/redirect behavior to respect the Essentials flow variant.
Changes:
- Add a resilient testimonials data hook with default fallbacks, and expand PurchaseSummary to rotate testimonials by step/substep.
- Update Essentials AcademicSelection layout to include PurchaseSummary (and add tests).
- Update navigation/redirect logic (AccountDetails, BillingDetails, root loader, subscribe success) to route correctly for Essentials vs standard checkout, with corresponding test updates.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| src/components/essentials-page/AcademicSelection.tsx | Adds a two-column layout and embeds PurchaseSummary in Essentials AcademicSelection. |
| src/components/essentials-page/tests/AcademicSelection.test.tsx | New tests covering AcademicSelection rendering/layout. |
| src/components/app/data/hooks/useTestimonials.tsx | Implements testimonials fetch with authenticated/unauthenticated clients and default fallbacks. |
| src/components/app/data/hooks/tests/useTestimonials.test.tsx | Adds tests for authenticated vs unauthenticated fetching and fallback behavior. |
| src/components/PurchaseSummary/PurchaseSummary.tsx | Rotates testimonials based on current step/substep. |
| src/components/PurchaseSummary/tests/PurchaseSummary.test.tsx | Extends tests to cover testimonial display across steps. |
| src/components/PurchaseSummary/TestimonialCard.tsx | Updates testimonial card styling/structure. |
| src/components/PurchaseSummary/TestimonialCard.test.tsx | Adds tests for the new quote icon/styling. |
| src/components/account-details-page/AccountDetailsPage.tsx | Routes Back/Continue to Essentials or standard flow destinations. |
| src/components/account-details-page/tests/AccountDetailsPage.test.tsx | Expands tests to cover Essentials-vs-checkout navigation and mutation flows. |
| src/components/billing-details-pages/BillingDetailsPage.tsx | Routes Back to the correct Account Details page depending on flow. |
| src/components/billing-details-pages/tests/BillingDetailsPage.test.tsx | Adds tests for Back navigation in Essentials vs checkout flow. |
| src/components/app/routes/loaders/rootLoader.ts | Redirects successful intents to the Essentials success route when on Essentials paths. |
| src/components/app/routes/tests/rootLoader.test.ts | Adds coverage for Essentials-path redirects (success + expired intent). |
| src/components/app/routes/loaders/checkoutStepperLoader.ts | Adjusts plan-details loader signatures (but currently introduces type issues). |
| src/components/StatefulButton/StatefulSubscribeButton.tsx | Navigates to Essentials success route when Essentials flow is active. |
| src/components/StatefulButton/tests/StatefulSubscribeButton.test.tsx | Adds test coverage for Essentials success navigation. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| await waitFor(() => { | ||
| expect(mockNavigate).toHaveBeenCalledWith('/essentials/billing-details/success'); | ||
| }); |
There was a problem hiding this comment.
This expectation hardcodes the essentials success path string. Using EssentialsPageRoute.BillingDetailsSuccess (or a shared route constant) would make the test resilient to future route changes and keep it consistent with the component implementation.
| it('does not repeat a testimonial until all have been shown', async () => { | ||
| const testimonials = [ | ||
| { uuid: '1', quote_text: 'First', attribution_name: 'A', attribution_title: 'T1' }, | ||
| { uuid: '2', quote_text: 'Second', attribution_name: 'B', attribution_title: 'T2' }, | ||
| ]; | ||
| (useTestimonials as jest.Mock).mockReturnValue({ data: testimonials, isLoading: false }); | ||
|
|
||
| // Render at plan-details step; a testimonial should be shown | ||
| renderWithProviders(`/${CheckoutStepKey.PlanDetails}`); | ||
| await waitFor(() => expect(screen.getByTestId('testimonial-card')).toBeInTheDocument()); | ||
|
|
||
| const firstQuote = screen.getByTestId('testimonial-quote').textContent; | ||
| // First quote must be one of the two testimonials | ||
| expect(['First', 'Second']).toContain(firstQuote); | ||
| }); |
There was a problem hiding this comment.
This test name claims to verify non-repetition, but the assertions only check that the first quote is one of the testimonials; it doesn’t verify behavior across multiple step/substep changes. Either rename the test to match what’s asserted, or extend it to navigate through steps/substeps and assert that the testimonial changes and doesn’t repeat until the list is exhausted.
| it('renders two-column layout with Row and Col components', () => { | ||
| const { container } = render(<AcademicSelection />); | ||
| const rowElement = container.querySelector('.row'); | ||
| expect(rowElement).toBeInTheDocument(); | ||
|
|
||
| // Check for column elements | ||
| const colElements = container.querySelectorAll('[class*="col"]'); | ||
| expect(colElements.length).toBeGreaterThanOrEqual(2); | ||
| }); | ||
|
|
||
| it('renders main content in left column with responsive breakpoints', () => { | ||
| const { container } = render(<AcademicSelection />); | ||
| const columns = container.querySelectorAll('[class*="col"]'); | ||
|
|
||
| // Verify we have at least 2 columns | ||
| expect(columns.length).toBeGreaterThanOrEqual(2); | ||
|
|
||
| // First column should have md={12} lg={8} classes for responsive layout | ||
| const mainColumn = columns[0]; | ||
| expect(mainColumn?.className).toMatch(/col-md-12|col-lg-8/); | ||
| }); | ||
|
|
||
| it('renders PurchaseSummary in right sidebar with responsive breakpoints', () => { | ||
| render(<AcademicSelection />); | ||
| const purchaseSummaryWrapper = screen.getByTestId('purchase-summary').parentElement; | ||
|
|
||
| // The parent should have col classes with lg={4} | ||
| expect(purchaseSummaryWrapper?.className).toMatch(/col-lg-4|col-md-12/); | ||
| }); | ||
|
|
||
| it('renders with correct Stack styling for main content', () => { | ||
| const { container } = render(<AcademicSelection />); | ||
| const stack = container.querySelector('.text-center.my-5.py-5'); | ||
| expect(stack).toBeInTheDocument(); | ||
| }); | ||
|
|
||
| it('renders all layout elements in correct order', () => { | ||
| const { container } = render(<AcademicSelection />); | ||
|
|
||
| // Check order: Container > Row > Col (main) with Stack > Col (sidebar) with PurchaseSummary | ||
| const mainContainer = container.querySelector('[class*="container"]'); | ||
| expect(mainContainer).toBeInTheDocument(); | ||
|
|
||
| const row = mainContainer?.querySelector('[class*="row"]'); | ||
| expect(row).toBeInTheDocument(); | ||
|
|
||
| const mainCol = row?.querySelector('[class*="col-lg-8"]'); | ||
| expect(mainCol).toBeInTheDocument(); | ||
|
|
||
| const sidebarCol = row?.querySelector('[class*="col-lg-4"]'); | ||
| expect(sidebarCol).toBeInTheDocument(); | ||
| }); | ||
|
|
There was a problem hiding this comment.
This test suite heavily asserts implementation details of Paragon/Bootstrap layout (e.g., specific .row/.col-* class names, DOM order, and presence of an svg). These assertions are brittle and likely to break on harmless refactors or Paragon upgrades. Consider limiting tests to user-observable behavior (heading text, presence of PurchaseSummary) and only keep class/structure assertions that are necessary for a known regression.
8a1345f to
d0507cb
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #180 +/- ##
==========================================
+ Coverage 86.99% 88.23% +1.23%
==========================================
Files 153 155 +2
Lines 2799 2975 +176
Branches 526 586 +60
==========================================
+ Hits 2435 2625 +190
+ Misses 364 350 -14 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Summary
This PR implements ENT-11639 by adding the testimonials component across all plans in the checkout flow.
https://twou.slack.com/files/U0A9VMPQTB4/F0AV16KUV36/recording_2026-04-24_002338cc.mp4
Changes
Updated AcademicSelection component
Integrated testimonials section for all plans
Ensured consistent UI across Essentials and other plan flows
Improved layout and user experience
Dependency
Dependent on ENT-11423 (plan details implementation)
Testing
Verified testimonials display correctly across all plans
Checked UI responsiveness and alignment
Ensured no impact on existing checkout flow
Next Steps
Ready for review once dependent ticket is merged
Will proceed with final validation after integration
Recreated PR because previous PR #160 shows 0 commits / 0 files after branch history rewrites.
This PR contains the current branch state for
feature/ENT-11639-testimonials-all-plans, including AcademicSelection/testimonials updates and related navigation/test changes.