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
4 changes: 4 additions & 0 deletions jest.setup.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
// Extend Jest's built-in matchers with jest-dom's DOM-specific matchers
// (e.g. toBeInTheDocument, toHaveAttribute, toHaveClass)
import "@testing-library/jest-dom";

if (!process.env.NEXT_PUBLIC_STELLAR_NETWORK) {
process.env.NEXT_PUBLIC_STELLAR_NETWORK = "TESTNET";
}
51 changes: 51 additions & 0 deletions src/app/dashboard/maintainer/MaintainerDashboard.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { pipelineStages } from "./page";
import type { Bounty } from "@/types";

describe("MaintainerDashboard — pipeline stages and escrow alignment (#88)", () => {
it("includes the 'merged' status in pipelineStages with appropriate label", () => {
const mergedStage = pipelineStages.find((stage) => stage.status === "merged");
expect(mergedStage).toBeDefined();
expect(mergedStage?.label).toBe("Merged");
});

it("contains all active stages aligned with totalEscrow calculation", () => {
const stageStatuses = pipelineStages.map((s) => s.status);

// Check that open, funded, claimed, in_review, and merged are present
expect(stageStatuses).toContain("open");
expect(stageStatuses).toContain("funded");
expect(stageStatuses).toContain("claimed");
expect(stageStatuses).toContain("in_review");
expect(stageStatuses).toContain("merged");

// Finished or non-escrow statuses like paid, refunded, expired are intentionally omitted from pipeline board
expect(stageStatuses).not.toContain("paid");
expect(stageStatuses).not.toContain("refunded");
expect(stageStatuses).not.toContain("expired");
});

it("ensures a merged bounty is captured and counted under the merged pipeline column", () => {
const mockBounties: Bounty[] = [
{
id: "1",
org: "MergeFi",
repo: "frontend",
issueNumber: 88,
title: "Test merged bounty",
description: "Testing merged column",
reward: 50,
asset: "USDC",
status: "merged",
creator: "user1",
createdAt: "2026-08-16T00:00:00Z",
},
];

const mergedStage = pipelineStages.find((stage) => stage.status === "merged");
expect(mergedStage).toBeDefined();

const filtered = mockBounties.filter((b) => b.status === mergedStage?.status);
expect(filtered).toHaveLength(1);
expect(filtered[0].title).toBe("Test merged bounty");
});
});
5 changes: 3 additions & 2 deletions src/app/dashboard/maintainer/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@ import { Avatar } from "@/components/ui/Avatar";
import { formatCurrency } from "@/lib/utils";
import type { Bounty, BountyStatus } from "@/types";

const pipelineStages: { status: BountyStatus; label: string }[] = [
export const pipelineStages: { status: BountyStatus; label: string }[] = [
{ status: "open", label: "Open" },
{ status: "funded", label: "Funded" },
{ status: "claimed", label: "Claimed" },
{ status: "in_review", label: "In review" },
{ status: "merged", label: "Merged" },
];

function PipelineColumn({ label, bounties }: { label: string; bounties: Bounty[] }) {
export function PipelineColumn({ label, bounties }: { label: string; bounties: Bounty[] }) {
return (
<div className="min-w-0 flex-1">
<div className="flex items-center justify-between px-1">
Expand Down