Dealer_Onboard_Frontend/src/features/onboarding/__tests__/ApplicationsPage.test.tsx

166 lines
6.6 KiB
TypeScript

import { render, screen, waitFor } from "@testing-library/react"
import userEvent from "@testing-library/user-event"
import { ApplicationsPage } from "../pages/ApplicationsPage"
import { renderWithProviders } from "./test-utils"
import { SHARED_APP_STATUSES } from "@/testing/constants"
import { mockOnboardingService, createGlobalMockApplication } from "@/testing/mocks"
describe("ApplicationsPage - Robust Feature Verification", () => {
beforeEach(() => {
jest.clearAllMocks()
})
const renderPage = (apps = []) => {
;(mockOnboardingService.getApplications as jest.Mock).mockResolvedValue({
success: true,
data: apps
})
return renderWithProviders(<ApplicationsPage onViewDetails={jest.fn()} />, {
preloadedState: {
auth: {
user: { id: "admin-1", role: "DD Admin" } as any,
token: "tok",
isAuthenticated: true,
loading: false,
error: null
}
}
})
}
it("should correctly filter Dealership Requests based on business rules", async () => {
// Business Rules:
// 1. Must be shortlisted (ddLeadShortlisted: true)
// 2. Must NOT be in initial Questionnaire/Submitted states
// 3. Must NOT be an excluded ID (5, 6, 7, 8)
const mockApps = [
createGlobalMockApplication({
id: "valid-1",
applicantName: "Visible Application",
overallStatus: SHARED_APP_STATUSES.FDD,
ddLeadShortlisted: true
}),
createGlobalMockApplication({
id: "invalid-status",
applicantName: "Hidden By Status",
overallStatus: SHARED_APP_STATUSES.SUBMITTED,
ddLeadShortlisted: true
}),
createGlobalMockApplication({
id: "not-shortlisted",
applicantName: "Hidden By Shortlist",
overallStatus: SHARED_APP_STATUSES.ARCH,
ddLeadShortlisted: false,
isShortlisted: false,
}),
createGlobalMockApplication({
id: "5", // Excluded ID
applicantName: "Hidden By Excluded ID",
overallStatus: SHARED_APP_STATUSES.LOI,
ddLeadShortlisted: true
})
]
renderPage(mockApps)
// Verify positive visibility
expect(await screen.findByText("Visible Application")).toBeInTheDocument()
// Verify negative visibility (proving the filter logic is actually working, not bypassed)
expect(screen.queryByText("Hidden By Status")).not.toBeInTheDocument()
expect(screen.queryByText("Hidden By Shortlist")).not.toBeInTheDocument()
expect(screen.queryByText("Hidden By Excluded ID")).not.toBeInTheDocument()
})
it("should search across name, ID, and email with case-insensitivity", async () => {
const user = userEvent.setup()
const mockApps = [
createGlobalMockApplication({
id: "app-search",
applicationId: "REG-SEARCH-001",
applicantName: "Specific Dealer Name",
overallStatus: SHARED_APP_STATUSES.LOI,
ddLeadShortlisted: true
})
]
renderPage(mockApps)
const searchInput = await screen.findByTestId("onboarding-applications-search-input")
// 1. Search by name (case-insensitive)
await user.type(searchInput, "specific")
expect(await screen.findByText("Specific Dealer Name")).toBeInTheDocument()
// 2. Search by Registration ID
await user.clear(searchInput)
await user.type(searchInput, "REG-SEARCH")
expect(await screen.findByText("Specific Dealer Name")).toBeInTheDocument()
})
it("should hide applications still in questionnaire stages (including Questionnaire Completed)", async () => {
const mockApps = [
createGlobalMockApplication({
id: "qc-1",
applicantName: "Hidden Questionnaire Completed",
overallStatus: "Questionnaire Completed",
ddLeadShortlisted: true,
}),
createGlobalMockApplication({
id: "show-1",
applicantName: "Visible Post Questionnaire",
overallStatus: SHARED_APP_STATUSES.LOI,
ddLeadShortlisted: true,
}),
]
renderPage(mockApps)
expect(await screen.findByText("Visible Post Questionnaire")).toBeInTheDocument()
expect(screen.queryByText("Hidden Questionnaire Completed")).not.toBeInTheDocument()
})
it("should filter by My Assignments when checkbox is enabled", async () => {
const user = userEvent.setup()
const mockApps = [
createGlobalMockApplication({
id: "mine-1",
applicantName: "Assigned To Me",
overallStatus: SHARED_APP_STATUSES.LOI,
ddLeadShortlisted: true,
assignedTo: "admin-1",
}),
createGlobalMockApplication({
id: "other-1",
applicantName: "Assigned To Someone Else",
overallStatus: SHARED_APP_STATUSES.LOI,
ddLeadShortlisted: true,
assignedTo: "other-user",
}),
]
renderPage(mockApps)
expect(await screen.findByText("Assigned To Me")).toBeInTheDocument()
expect(screen.getByText("Assigned To Someone Else")).toBeInTheDocument()
await user.click(screen.getByTestId("onboarding-applications-assignments-checkbox"))
expect(screen.getByText("Assigned To Me")).toBeInTheDocument()
expect(screen.queryByText("Assigned To Someone Else")).not.toBeInTheDocument()
})
it("should handle API failures gracefully without crashing the dashboard", async () => {
// Mock a 500 or Network error
;(mockOnboardingService.getApplications as jest.Mock).mockRejectedValue(new Error("Network Error"))
// Suppress console.error for this test to keep logs clean
const consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => {})
renderPage([])
// The dashboard should still render its UI shell and empty table, not crash
expect(await screen.findByTestId("onboarding-applications-search-input")).toBeInTheDocument()
expect(screen.getByTestId("onboarding-applications-count-text")).toHaveTextContent("0 applications")
consoleSpy.mockRestore()
})
})