Skip to content
Closed
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
8 changes: 7 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { ToastProvider } from "./components/Toast/ToastProvider"
import { WalletToastWatcher } from "./components/WalletToastWatcher"

const Admin = lazy(() => import("./pages/Admin"))
const AdminModeration = lazy(() => import("./pages/AdminModeration"))
const Community = lazy(() => import("./pages/Community"))
const Courses = lazy(() => import("./pages/Courses"))
const Credential = lazy(() => import("./pages/Credential"))
Expand All @@ -28,6 +29,8 @@ const ScholarshipApply = lazy(() => import("./pages/ScholarshipApply"))
const Treasury = lazy(() => import("./pages/Treasury"))
const Wiki = lazy(() => import("./pages/Wiki"))
const WikiPage = lazy(() => import("./pages/WikiPage"))
const FAQPage = lazy(() => import("./pages/FAQPage"))
const SponsorCheckoutPage = lazy(() => import("./pages/SponsorCheckoutPage"))

const renderRoute = (element: ReactNode) => (
<ErrorBoundary>
Expand Down Expand Up @@ -66,9 +69,12 @@ function App() {
path="/scholarships/apply"
element={renderRoute(<ScholarshipApply />)}
/>
<Route path="/admin" element={renderRoute(<Admin />)} />
<Route path="/admin" element={renderRoute(<Admin />)} />
<Route path="/admin/moderation" element={renderRoute(<AdminModeration />)} />
<Route path="/wiki" element={renderRoute(<Wiki />)} />
<Route path="/wiki/:slug" element={renderRoute(<WikiPage />)} />
<Route path="/faq" element={renderRoute(<FAQPage />)} />
<Route path="/sponsor/checkout" element={renderRoute(<SponsorCheckoutPage />)} />
<Route path="/treasury" element={renderRoute(<Treasury />)} />
<Route path="/donor" element={renderRoute(<Donor />)} />
<Route
Expand Down
101 changes: 101 additions & 0 deletions src/components/FAQSection.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { fireEvent, screen } from "@testing-library/react"
import { describe, expect, it } from "vitest"
import { render } from "../test/setup"
import { FAQSection } from "./FAQSection"

describe("FAQSection Component", () => {
it("renders the help center header correctly", () => {
render(<FAQSection />)

expect(screen.getByText("Help Center")).toBeInTheDocument()
expect(screen.getByText(/Got questions\? We've got/i)).toBeInTheDocument()
expect(
screen.getByPlaceholderText(/Search by keywords/i),
).toBeInTheDocument()
})

it("renders the list of FAQs", () => {
render(<FAQSection />)

// Check some of our questions exist
expect(
screen.getByText("What is Soroban and how does it integrate with LearnVault?"),
).toBeInTheDocument()
expect(
screen.getByText("Which Web3 wallets are supported on LearnVault?"),
).toBeInTheDocument()
})

it("can filter FAQ items by search keywords", () => {
render(<FAQSection />)

const searchInput = screen.getByPlaceholderText(/Search by keywords/i)

// Search for "freighter" (Web3 wallets tag/word)
fireEvent.change(searchInput, { target: { value: "freighter" } })

// The freighter question should remain
expect(
screen.getByText("Which Web3 wallets are supported on LearnVault?"),
).toBeInTheDocument()

// Soroban question should NOT be visible
expect(
screen.queryByText(
"What is Soroban and how does it integrate with LearnVault?",
),
).not.toBeInTheDocument()
})

it("can filter FAQ items by category tabs", () => {
render(<FAQSection />)

// Click on "Soroban" tab
const sorobanTab = screen.getByRole("button", { name: /Soroban/i })
fireEvent.click(sorobanTab)

// Soroban question should be there
expect(
screen.getByText("What is Soroban and how does it integrate with LearnVault?"),
).toBeInTheDocument()

// Web3 Wallets question should NOT be there
expect(
screen.queryByText("Which Web3 wallets are supported on LearnVault?"),
).not.toBeInTheDocument()
})

it("expands and collapses accordions on click", async () => {
render(<FAQSection />)

const questionText =
"What is Soroban and how does it integrate with LearnVault?"
const questionButton = screen.getByRole("button", { name: new RegExp(questionText, "i") })

// Answer shouldn't be visible initially (not rendered or height 0 inside accordion)
expect(screen.queryByText(/native, high-performance smart contract platform/i)).not.toBeInTheDocument()

// Click to expand
fireEvent.click(questionButton)

// Answer should now be visible in the DOM
expect(await screen.findByText(/native, high-performance smart contract platform/i)).toBeInTheDocument()
})

it("can submit helpful feedback on individual FAQ items", async () => {
render(<FAQSection />)

// First, expand the accordion to make the helpfulness buttons visible
const questionText =
"What is Soroban and how does it integrate with LearnVault?"
const questionButton = screen.getByRole("button", { name: new RegExp(questionText, "i") })
fireEvent.click(questionButton)

// Click Thumbs Up button
const thumbsUpButton = await screen.findByRole("button", { name: /yes/i })
fireEvent.click(thumbsUpButton)

// The thank you message should show up
expect(await screen.findByText("Thank you!")).toBeInTheDocument()
})
})
Loading
Loading