Skip to content
Open
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
17 changes: 17 additions & 0 deletions docs/testing/TRUST_BADGE_TESTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# TrustBadge Test Coverage

`src/components/__tests__/TrustBadge.test.tsx` covers the TrustBadge component with React Testing Library and Vitest.

Covered behavior:

- Every supported `TrustLevel` value renders its visible label and icon.
- Tooltip-enabled badges expose the tooltip text through `aria-describedby`.
- `showTooltip={false}` removes the tooltip and accessible description.
- Custom `className` values are merged without dropping trust-level styling.
- Unknown trust levels fall back to the unverified badge copy.

Run the focused test locally with:

```bash
pnpm test -- --run src/components/__tests__/TrustBadge.test.tsx
```
18 changes: 15 additions & 3 deletions src/components/TrustBadge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ export const TrustBadge: React.FC<TrustBadgeProps> = ({
className = '',
showTooltip = true
}) => {
const tooltipId = React.useId();
const tooltipDescriptionId = `${tooltipId}-description`;

const getBadgeConfig = () => {
switch (level) {
case 'verified':
Expand Down Expand Up @@ -46,13 +49,22 @@ export const TrustBadge: React.FC<TrustBadgeProps> = ({
const config = getBadgeConfig();

return (
<div className={`group relative inline-flex items-center gap-1.5 px-2 py-0.5 rounded-full border text-[10px] font-bold uppercase tracking-wider ${config.colorClass} ${className}`}>
<div
aria-describedby={showTooltip ? tooltipDescriptionId : undefined}
aria-label={config.label}
role="status"
className={`group relative inline-flex items-center gap-1.5 px-2 py-0.5 rounded-full border text-[10px] font-bold uppercase tracking-wider ${config.colorClass} ${className}`}
>
{config.icon}
{config.label}

{showTooltip && (
<div className="absolute bottom-full left-1/2 -translate-x-1/2 mb-2 w-48 p-2 rounded-lg bg-[#1A1A1A] border border-white/10 shadow-2xl opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none z-50 text-[11px] normal-case tracking-normal font-medium leading-relaxed text-white/70">
<p>{config.description}</p>
<div
id={tooltipId}
role="tooltip"
className="absolute bottom-full left-1/2 -translate-x-1/2 mb-2 w-48 p-2 rounded-lg bg-[#1A1A1A] border border-white/10 shadow-2xl opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none z-50 text-[11px] normal-case tracking-normal font-medium leading-relaxed text-white/70"
>
<p id={tooltipDescriptionId}>{config.description}</p>
<div className="mt-1 flex items-center gap-1 text-[9px] text-[#0FF0FC]">
<Info className="w-2.5 h-2.5" />
Learn about trust levels
Expand Down
91 changes: 91 additions & 0 deletions src/components/__tests__/TrustBadge.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// @vitest-environment happy-dom

import { render, screen } from "@testing-library/react";
import { describe, expect, it } from "vitest";

import { TrustBadge, type TrustLevel } from "../TrustBadge";

const trustLevels: Array<{
level: TrustLevel;
label: string;
description: string;
}> = [
{
level: "verified",
label: "Verified Seller",
description:
"Identity and historical performance have been verified by Commitlabs.",
},
{
level: "reputable",
label: "Top Reputation",
description:
"Seller has a high successful commitment rate and positive community feedback.",
},
{
level: "unverified",
label: "Self-Reported",
description:
"This seller has not yet completed the verification process. Exercise caution.",
},
];

describe("TrustBadge", () => {
it.each(trustLevels)(
"renders a visible and accessible label for the $level trust level",
({ level, label }) => {
render(<TrustBadge level={level} showTooltip={false} />);

const badge = screen.getByRole("status", { name: label });

expect(badge).toHaveTextContent(label);
expect(badge.querySelector("svg")).toBeInTheDocument();
},
);

it.each(trustLevels)(
"links the $level tooltip to the badge when tooltips are enabled",
({ level, label, description }) => {
render(<TrustBadge level={level} showTooltip />);

const badge = screen.getByRole("status", { name: label });
const tooltip = screen.getByRole("tooltip");

expect(tooltip).toHaveTextContent(description);
expect(tooltip).toHaveTextContent("Learn about trust levels");
expect(badge).toHaveAccessibleDescription(description);
},
);

it("does not render or describe a tooltip when showTooltip is false", () => {
render(<TrustBadge level="verified" showTooltip={false} />);

expect(screen.queryByRole("tooltip")).not.toBeInTheDocument();
expect(
screen.getByRole("status", { name: "Verified Seller" }),
).not.toHaveAccessibleDescription();
});

it("merges custom className values without removing the trust level styling", () => {
render(
<TrustBadge
level="reputable"
className="marketplace-row-badge"
showTooltip={false}
/>,
);

const badge = screen.getByRole("status", { name: "Top Reputation" });

expect(badge).toHaveClass("marketplace-row-badge");
expect(badge.className).toContain("text-[#51A2FF]");
});

it("falls back to the unverified badge for unknown trust levels", () => {
render(<TrustBadge level={"unknown" as TrustLevel} showTooltip={false} />);

expect(
screen.getByRole("status", { name: "Self-Reported" }),
).toHaveTextContent("Self-Reported");
});
});