App reorganization

This commit is contained in:
adilallo
2026-04-18 14:12:49 -06:00
parent f866d11ff8
commit e9dab04b34
288 changed files with 2698 additions and 5029 deletions
+1
View File
@@ -24,6 +24,7 @@ const mockPost = {
},
};
// Pure presentational; no provider context needed.
describe("ContentContainer", () => {
it("renders with default props", () => {
render(<ContentContainer post={mockPost} />);
@@ -35,6 +35,7 @@ const mockPost = {
},
};
// Pure presentational; no provider context needed.
describe("ContentThumbnailTemplate", () => {
describe("Vertical Variant", () => {
it("should render vertical variant with responsive dimensions", () => {
+37 -19
View File
@@ -1,5 +1,7 @@
import { describe, test, expect, vi } from "vitest";
import RootLayout from "../../app/layout";
import MarketingLayout from "../../app/(marketing)/layout";
import AppLayout from "../../app/(app)/layout";
// Mock the font imports since they're Next.js specific
vi.mock("next/font/google", () => ({
@@ -70,30 +72,46 @@ describe("RootLayout", () => {
expect(container).toBeTruthy();
});
test("renders main content area", () => {
const testContent = "Test content";
const tree = RootLayout({ children: <div>{testContent}</div> });
const main = findDescendant(
tree,
(n) => n.type === "main" && n.props?.className?.includes("flex-1"),
);
expect(main).toBeTruthy();
const childText = findDescendant(
main,
(n) => typeof n === "string" && n.includes(testContent),
);
expect(childText).toBeTruthy();
});
test("renders children content correctly", () => {
test("renders children directly inside the flex container (no <main> at root)", () => {
const testContent = "This is test content";
const tree = RootLayout({ children: <div>{testContent}</div> });
const main = findDescendant(tree, (n) => n.type === "main");
expect(findDescendant(tree, (n) => n?.type === "main")).toBeNull();
const childText = findDescendant(
main,
tree,
(n) => typeof n === "string" && n.includes(testContent),
);
expect(childText).toBeTruthy();
});
});
describe("Group layouts (chrome composition)", () => {
test("MarketingLayout wraps children in <main flex-1> and appends Footer", () => {
const tree = MarketingLayout({ children: <div>marketing-child</div> });
const main = findDescendant(
tree,
(n) => n?.type === "main" && n.props?.className?.includes("flex-1"),
);
expect(main).toBeTruthy();
expect(
findDescendant(main, (n) => typeof n === "string" && n.includes("marketing-child")),
).toBeTruthy();
// Footer is loaded via next/dynamic — it appears as a render prop component
// sibling to <main>. Verify the layout returns more than just <main>.
const childrenArr = Array.isArray(tree.props.children)
? tree.props.children
: [tree.props.children];
expect(childrenArr.length).toBeGreaterThan(1);
});
test("AppLayout wraps children in <main flex-1> with no footer", () => {
const tree = AppLayout({ children: <div>app-child</div> });
expect(tree.type).toBe("main");
expect(tree.props.className).toContain("flex-1");
expect(
findDescendant(tree, (n) => typeof n === "string" && n.includes("app-child")),
).toBeTruthy();
});
});
+1
View File
@@ -6,6 +6,7 @@ afterEach(() => {
cleanup();
});
// Pure presentational; no provider context needed.
describe("LogoWall Component", () => {
test("renders with default logos", () => {
render(<LogoWall />);
+5 -4
View File
@@ -2,6 +2,7 @@ import { render, screen } from "@testing-library/react";
import { describe, it, expect } from "vitest";
import NumberCard from "../../app/components/cards/NumberCard";
// Pure presentational; no provider context needed.
describe("NumberCard Component", () => {
const defaultProps = {
number: 1,
@@ -200,7 +201,7 @@ describe("NumberCard Component", () => {
});
it("applies Small size variant correctly", () => {
render(<NumberCard {...defaultProps} size="Small" />);
render(<NumberCard {...defaultProps} size="small" />);
// For Small size, text is directly in card div (no wrapper), so use closest("div")
const card = screen.getByText("Test Card Text").closest("div");
@@ -219,7 +220,7 @@ describe("NumberCard Component", () => {
});
it("applies Medium size variant correctly", () => {
render(<NumberCard {...defaultProps} size="Medium" />);
render(<NumberCard {...defaultProps} size="medium" />);
const card = screen
.getByText("Test Card Text")
@@ -237,7 +238,7 @@ describe("NumberCard Component", () => {
});
it("applies Large size variant correctly", () => {
render(<NumberCard {...defaultProps} size="Large" />);
render(<NumberCard {...defaultProps} size="large" />);
const card = screen
.getByText("Test Card Text")
@@ -257,7 +258,7 @@ describe("NumberCard Component", () => {
});
it("applies XLarge size variant correctly", () => {
render(<NumberCard {...defaultProps} size="XLarge" />);
render(<NumberCard {...defaultProps} size="xlarge" />);
const card = screen
.getByText("Test Card Text")
+1 -1
View File
@@ -159,7 +159,7 @@ describe("RuleCard Component", () => {
{
name: "Values",
chipOptions: [
{ id: "v1", label: "Consciousness", state: "Unselected" },
{ id: "v1", label: "Consciousness", state: "unselected" },
],
},
];
+3 -3
View File
@@ -4,7 +4,7 @@ import {
parseDocumentSectionsForDisplay,
parseSectionsFromCreateFlowState,
} from "../../lib/create/buildPublishPayload";
import type { CreateFlowState } from "../../app/create/types";
import type { CreateFlowState } from "../../app/(app)/create/types";
describe("buildPublishPayload", () => {
it("returns error when title missing", () => {
@@ -97,8 +97,8 @@ describe("buildPublishPayload", () => {
title: "T",
selectedCoreValueIds: ["1", "2"],
coreValuesChipsSnapshot: [
{ id: "1", label: "Alpha", state: "Selected" },
{ id: "2", label: "Beta", state: "Selected" },
{ id: "1", label: "Alpha", state: "selected" },
{ id: "2", label: "Beta", state: "selected" },
],
coreValueDetailsByChipId: {
"1": { meaning: "m1", signals: "s1" },
+1 -1
View File
@@ -3,7 +3,7 @@ import {
CREATE_FLOW_MD_UP_COLUMN_MAX_CLASS,
CREATE_FLOW_MD_UP_GRID_CELL_CLASS,
CREATE_FLOW_TWO_COLUMN_MAX_WIDTH_CLASS,
} from "../../app/create/components/createFlowLayoutTokens";
} from "../../app/(app)/create/components/createFlowLayoutTokens";
describe("createFlowLayoutTokens", () => {
it("exports create-flow column and two-column max class strings", () => {
@@ -1,5 +1,5 @@
import { describe, it, expect } from "vitest";
import { getProportionBarProgressForCreateFlowStep } from "../../app/create/utils/createFlowProportionProgress";
import { getProportionBarProgressForCreateFlowStep } from "../../app/(app)/create/utils/createFlowProportionProgress";
describe("getProportionBarProgressForCreateFlowStep", () => {
it("uses 1-2 on community-structure (third Create Community step)", () => {
+2 -2
View File
@@ -83,8 +83,8 @@ describe("createFlowStateSchema", () => {
const r = createFlowStateSchema.safeParse({
communityStructureChipSnapshots: {
organizationTypes: [
{ id: "1", label: "Co-op", state: "Selected" },
{ id: "custom-uuid", label: "My type", state: "Selected" },
{ id: "1", label: "Co-op", state: "selected" },
{ id: "custom-uuid", label: "My type", state: "selected" },
],
scale: [{ id: "1", label: "Local" }],
maturity: [],
+1 -1
View File
@@ -5,7 +5,7 @@ import {
getPreviousStep,
isValidStep,
getStepIndex,
} from "../../app/create/utils/flowSteps";
} from "../../app/(app)/create/utils/flowSteps";
describe("flowSteps", () => {
it("places confirm-stakeholders immediately before final-review", () => {
+1 -1
View File
@@ -1,5 +1,5 @@
import { describe, it, expect } from "vitest";
import { hasCreateFlowUserInput } from "../../app/create/utils/hasCreateFlowUserInput";
import { hasCreateFlowUserInput } from "../../app/(app)/create/utils/hasCreateFlowUserInput";
describe("hasCreateFlowUserInput", () => {
it("returns false for empty state", () => {
+1 -1
View File
@@ -1,6 +1,6 @@
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
import { saveDraftToServer } from "../../lib/create/api";
import type { CreateFlowState } from "../../app/create/types";
import type { CreateFlowState } from "../../app/(app)/create/types";
const minimalState: CreateFlowState = {};