diff --git a/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainAgentPage/__tests__/auth-state.test.tsx b/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainAgentPage/__tests__/auth-state.test.tsx new file mode 100644 index 0000000000..4ca5cafd0a --- /dev/null +++ b/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainAgentPage/__tests__/auth-state.test.tsx @@ -0,0 +1,64 @@ +import { describe, expect, test, afterEach } from "vitest"; +import { render, screen, waitFor } from "@/tests/integrations/test-utils"; +import { MainAgentPage } from "../MainAgentPage"; +import { + mockAuthenticatedUser, + mockUnauthenticatedUser, + resetAuthState, +} from "@/tests/integrations/helpers/mock-supabase-auth"; + +const defaultParams = { + creator: "test-creator", + slug: "test-agent", +}; + +describe("MainAgentPage - Auth State", () => { + afterEach(() => { + resetAuthState(); + }); + + test("shows add to library button when authenticated", async () => { + mockAuthenticatedUser(); + render(); + + await waitFor(() => { + expect( + screen.getByTestId("agent-add-library-button"), + ).toBeInTheDocument(); + }); + }); + + test("hides add to library button when not authenticated", async () => { + mockUnauthenticatedUser(); + render(); + + await waitFor(() => { + expect(screen.getByTestId("agent-title")).toBeInTheDocument(); + }); + expect( + screen.queryByTestId("agent-add-library-button"), + ).not.toBeInTheDocument(); + }); + + test("renders page correctly when logged out", async () => { + mockUnauthenticatedUser(); + render(); + + await waitFor(() => { + expect(screen.getByTestId("agent-title")).toBeInTheDocument(); + }); + expect(screen.getByTestId("agent-download-button")).toBeInTheDocument(); + }); + + test("renders page correctly when logged in", async () => { + mockAuthenticatedUser(); + render(); + + await waitFor(() => { + expect(screen.getByTestId("agent-title")).toBeInTheDocument(); + }); + expect( + screen.getByTestId("agent-add-library-button"), + ).toBeInTheDocument(); + }); +}); diff --git a/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainAgentPage/__tests__/error-handling.test.tsx b/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainAgentPage/__tests__/error-handling.test.tsx new file mode 100644 index 0000000000..3def10880a --- /dev/null +++ b/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainAgentPage/__tests__/error-handling.test.tsx @@ -0,0 +1,57 @@ +import { describe, expect, test } from "vitest"; +import { render, screen, waitFor, act } from "@/tests/integrations/test-utils"; +import { MainAgentPage } from "../MainAgentPage"; +import { server } from "@/mocks/mock-server"; +import { getGetV2GetSpecificAgentMockHandler422 } from "@/app/api/__generated__/endpoints/store/store.msw"; +import { create500Handler } from "@/tests/integrations/helpers/create-500-handler"; + +const defaultParams = { + creator: "test-creator", + slug: "test-agent", +}; + +describe("MainAgentPage - Error Handling", () => { + test("displays error when agent API returns 422", async () => { + server.use(getGetV2GetSpecificAgentMockHandler422()); + + render(); + + await waitFor(() => { + expect( + screen.getByText("Failed to load agent data", { exact: false }), + ).toBeInTheDocument(); + }); + + await act(async () => {}); + }); + + test("displays error when API returns 500", async () => { + server.use( + create500Handler("get", "*/api/store/agents/test-creator/test-agent"), + ); + + render(); + + await waitFor(() => { + expect( + screen.getByText("Failed to load agent data", { exact: false }), + ).toBeInTheDocument(); + }); + + await act(async () => {}); + }); + + test("retry button is visible on error", async () => { + server.use(getGetV2GetSpecificAgentMockHandler422()); + + render(); + + await waitFor(() => { + expect( + screen.getByRole("button", { name: /try again/i }), + ).toBeInTheDocument(); + }); + + await act(async () => {}); + }); +}); diff --git a/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainAgentPage/__tests__/main.test.tsx b/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainAgentPage/__tests__/main.test.tsx deleted file mode 100644 index 2260fa6925..0000000000 --- a/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainAgentPage/__tests__/main.test.tsx +++ /dev/null @@ -1,173 +0,0 @@ -import { describe, expect, test, afterEach } from "vitest"; -import { - render, - screen, - waitFor, - act, -} from "@/tests/integrations/test-utils"; -import { MainAgentPage } from "../MainAgentPage"; -import { server } from "@/mocks/mock-server"; -import { getGetV2GetSpecificAgentMockHandler422 } from "@/app/api/__generated__/endpoints/store/store.msw"; -import { create500Handler } from "@/tests/integrations/helpers/create-500-handler"; -import { - mockAuthenticatedUser, - mockUnauthenticatedUser, - resetAuthState, -} from "@/tests/integrations/helpers/mock-supabase-auth"; - -const defaultParams = { - creator: "test-creator", - slug: "test-agent", -}; - -describe("MainAgentPage", () => { - afterEach(() => { - resetAuthState(); - }); - - describe("rendering", () => { - test("renders agent info with title", async () => { - render(); - await waitFor(() => { - expect(screen.getByTestId("agent-title")).toBeInTheDocument(); - }); - }); - - test("renders agent creator info", async () => { - render(); - - await waitFor(() => { - expect(screen.getByTestId("agent-creator")).toBeInTheDocument(); - }); - }); - - test("renders agent description", async () => { - render(); - - await waitFor(() => { - expect(screen.getByTestId("agent-description")).toBeInTheDocument(); - }); - }); - - test("renders breadcrumbs with marketplace link", async () => { - render(); - - await waitFor(() => { - expect( - screen.getByRole("link", { name: /marketplace/i }), - ).toBeInTheDocument(); - }); - }); - - test("renders download button", async () => { - render(); - - await waitFor(() => { - expect(screen.getByTestId("agent-download-button")).toBeInTheDocument(); - }); - }); - - test("renders similar agents section", async () => { - render(); - - await waitFor(() => { - expect( - screen.getByText("Similar agents", { exact: false }), - ).toBeInTheDocument(); - }); - }); - }); - - describe("auth state", () => { - test("shows add to library button when authenticated", async () => { - mockAuthenticatedUser(); - render(); - - await waitFor(() => { - expect( - screen.getByTestId("agent-add-library-button"), - ).toBeInTheDocument(); - }); - }); - - test("hides add to library button when not authenticated", async () => { - mockUnauthenticatedUser(); - render(); - - await waitFor(() => { - expect(screen.getByTestId("agent-title")).toBeInTheDocument(); - }); - expect( - screen.queryByTestId("agent-add-library-button"), - ).not.toBeInTheDocument(); - }); - - test("renders page correctly when logged out", async () => { - mockUnauthenticatedUser(); - render(); - - await waitFor(() => { - expect(screen.getByTestId("agent-title")).toBeInTheDocument(); - }); - expect(screen.getByTestId("agent-download-button")).toBeInTheDocument(); - }); - - test("renders page correctly when logged in", async () => { - mockAuthenticatedUser(); - render(); - - await waitFor(() => { - expect(screen.getByTestId("agent-title")).toBeInTheDocument(); - }); - expect( - screen.getByTestId("agent-add-library-button"), - ).toBeInTheDocument(); - }); - }); - - describe("error handling", () => { - test("displays error when agent API returns 422", async () => { - server.use(getGetV2GetSpecificAgentMockHandler422()); - - render(); - - await waitFor(() => { - expect( - screen.getByText("Failed to load agent data", { exact: false }), - ).toBeInTheDocument(); - }); - - await act(async () => {}); - }); - - test("displays error when API returns 500", async () => { - server.use( - create500Handler("get", "*/api/store/agents/test-creator/test-agent"), - ); - - render(); - - await waitFor(() => { - expect( - screen.getByText("Failed to load agent data", { exact: false }), - ).toBeInTheDocument(); - }); - - await act(async () => {}); - }); - - test("retry button is visible on error", async () => { - server.use(getGetV2GetSpecificAgentMockHandler422()); - - render(); - - await waitFor(() => { - expect( - screen.getByRole("button", { name: /try again/i }), - ).toBeInTheDocument(); - }); - - await act(async () => {}); - }); - }); -}); diff --git a/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainAgentPage/__tests__/rendering.test.tsx b/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainAgentPage/__tests__/rendering.test.tsx new file mode 100644 index 0000000000..01de89566c --- /dev/null +++ b/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainAgentPage/__tests__/rendering.test.tsx @@ -0,0 +1,61 @@ +import { describe, expect, test } from "vitest"; +import { render, screen, waitFor } from "@/tests/integrations/test-utils"; +import { MainAgentPage } from "../MainAgentPage"; + +const defaultParams = { + creator: "test-creator", + slug: "test-agent", +}; + +describe("MainAgentPage - Rendering", () => { + test("renders agent info with title", async () => { + render(); + await waitFor(() => { + expect(screen.getByTestId("agent-title")).toBeInTheDocument(); + }); + }); + + test("renders agent creator info", async () => { + render(); + + await waitFor(() => { + expect(screen.getByTestId("agent-creator")).toBeInTheDocument(); + }); + }); + + test("renders agent description", async () => { + render(); + + await waitFor(() => { + expect(screen.getByTestId("agent-description")).toBeInTheDocument(); + }); + }); + + test("renders breadcrumbs with marketplace link", async () => { + render(); + + await waitFor(() => { + expect( + screen.getByRole("link", { name: /marketplace/i }), + ).toBeInTheDocument(); + }); + }); + + test("renders download button", async () => { + render(); + + await waitFor(() => { + expect(screen.getByTestId("agent-download-button")).toBeInTheDocument(); + }); + }); + + test("renders similar agents section", async () => { + render(); + + await waitFor(() => { + expect( + screen.getByText("Similar agents", { exact: false }), + ).toBeInTheDocument(); + }); + }); +}); diff --git a/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainCreatorPage/__tests__/auth-state.test.tsx b/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainCreatorPage/__tests__/auth-state.test.tsx new file mode 100644 index 0000000000..0526a82a1e --- /dev/null +++ b/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainCreatorPage/__tests__/auth-state.test.tsx @@ -0,0 +1,36 @@ +import { describe, expect, test, afterEach } from "vitest"; +import { render, screen, waitFor } from "@/tests/integrations/test-utils"; +import { MainCreatorPage } from "../MainCreatorPage"; +import { + mockAuthenticatedUser, + mockUnauthenticatedUser, + resetAuthState, +} from "@/tests/integrations/helpers/mock-supabase-auth"; + +const defaultParams = { + creator: "test-creator", +}; + +describe("MainCreatorPage - Auth State", () => { + afterEach(() => { + resetAuthState(); + }); + + test("renders page correctly when logged out", async () => { + mockUnauthenticatedUser(); + render(); + + await waitFor(() => { + expect(screen.getByTestId("creator-description")).toBeInTheDocument(); + }); + }); + + test("renders page correctly when logged in", async () => { + mockAuthenticatedUser(); + render(); + + await waitFor(() => { + expect(screen.getByTestId("creator-description")).toBeInTheDocument(); + }); + }); +}); diff --git a/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainCreatorPage/__tests__/error-handling.test.tsx b/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainCreatorPage/__tests__/error-handling.test.tsx new file mode 100644 index 0000000000..2ae32484f0 --- /dev/null +++ b/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainCreatorPage/__tests__/error-handling.test.tsx @@ -0,0 +1,63 @@ +import { describe, expect, test } from "vitest"; +import { render, screen, waitFor } from "@/tests/integrations/test-utils"; +import { MainCreatorPage } from "../MainCreatorPage"; +import { server } from "@/mocks/mock-server"; +import { + getGetV2GetCreatorDetailsMockHandler422, + getGetV2ListStoreAgentsMockHandler422, +} from "@/app/api/__generated__/endpoints/store/store.msw"; +import { create500Handler } from "@/tests/integrations/helpers/create-500-handler"; + +const defaultParams = { + creator: "test-creator", +}; + +describe("MainCreatorPage - Error Handling", () => { + test("displays error when creator details API returns 422", async () => { + server.use(getGetV2GetCreatorDetailsMockHandler422()); + + render(); + + await waitFor(() => { + expect( + screen.getByText("Failed to load creator data", { exact: false }), + ).toBeInTheDocument(); + }); + }); + + test("displays error when creator agents API returns 422", async () => { + server.use(getGetV2ListStoreAgentsMockHandler422()); + + render(); + + await waitFor(() => { + expect( + screen.getByText("Failed to load creator data", { exact: false }), + ).toBeInTheDocument(); + }); + }); + + test("displays error when API returns 500", async () => { + server.use(create500Handler("get", "*/api/store/creator/test-creator")); + + render(); + + await waitFor(() => { + expect( + screen.getByText("Failed to load creator data", { exact: false }), + ).toBeInTheDocument(); + }); + }); + + test("retry button is visible on error", async () => { + server.use(getGetV2GetCreatorDetailsMockHandler422()); + + render(); + + await waitFor(() => { + expect( + screen.getByRole("button", { name: /try again/i }), + ).toBeInTheDocument(); + }); + }); +}); diff --git a/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainCreatorPage/__tests__/main.test.tsx b/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainCreatorPage/__tests__/main.test.tsx deleted file mode 100644 index bcc8278f4b..0000000000 --- a/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainCreatorPage/__tests__/main.test.tsx +++ /dev/null @@ -1,131 +0,0 @@ -import { describe, expect, test, afterEach } from "vitest"; -import { cleanup, render, screen, waitFor } from "@/tests/integrations/test-utils"; -import { MainCreatorPage } from "../MainCreatorPage"; -import { server } from "@/mocks/mock-server"; -import { - getGetV2GetCreatorDetailsMockHandler422, - getGetV2ListStoreAgentsMockHandler422, -} from "@/app/api/__generated__/endpoints/store/store.msw"; -import { create500Handler } from "@/tests/integrations/helpers/create-500-handler"; -import { - mockAuthenticatedUser, - mockUnauthenticatedUser, - resetAuthState, -} from "@/tests/integrations/helpers/mock-supabase-auth"; - -const defaultParams = { - creator: "test-creator", -}; - -describe("MainCreatorPage", () => { - afterEach(() => { - resetAuthState(); - }); - - describe("rendering", () => { - test("renders creator info card", async () => { - render(); - await waitFor(() => { - expect(screen.getByTestId("creator-description")).toBeInTheDocument(); - }); - }); - - test("renders breadcrumbs with marketplace link", async () => { - render(); - - await waitFor(() => { - expect( - screen.getByRole("link", { name: /marketplace/i }), - ).toBeInTheDocument(); - }); - }); - - test("renders about section", async () => { - render(); - - await waitFor(() => { - expect(screen.getByText("About")).toBeInTheDocument(); - }); - }); - - test("renders agents by creator section", async () => { - render(); - - await waitFor(() => { - expect( - screen.getByText(/Agents by/i, { exact: false }), - ).toBeInTheDocument(); - }); - }); - }); - - describe("auth state", () => { - test("renders page correctly when logged out", async () => { - mockUnauthenticatedUser(); - render(); - - await waitFor(() => { - expect(screen.getByTestId("creator-description")).toBeInTheDocument(); - }); - }); - - test("renders page correctly when logged in", async () => { - mockAuthenticatedUser(); - render(); - - await waitFor(() => { - expect(screen.getByTestId("creator-description")).toBeInTheDocument(); - }); - }); - }); - - describe("error handling", () => { - test("displays error when creator details API returns 422", async () => { - server.use(getGetV2GetCreatorDetailsMockHandler422()); - - render(); - - await waitFor(() => { - expect( - screen.getByText("Failed to load creator data", { exact: false }), - ).toBeInTheDocument(); - }); - }); - - test("displays error when creator agents API returns 422", async () => { - server.use(getGetV2ListStoreAgentsMockHandler422()); - - render(); - - await waitFor(() => { - expect( - screen.getByText("Failed to load creator data", { exact: false }), - ).toBeInTheDocument(); - }); - }); - - test("displays error when API returns 500", async () => { - server.use(create500Handler("get", "*/api/store/creator/test-creator")); - - render(); - - await waitFor(() => { - expect( - screen.getByText("Failed to load creator data", { exact: false }), - ).toBeInTheDocument(); - }); - }); - - test("retry button is visible on error", async () => { - server.use(getGetV2GetCreatorDetailsMockHandler422()); - - render(); - - await waitFor(() => { - expect( - screen.getByRole("button", { name: /try again/i }), - ).toBeInTheDocument(); - }); - }); - }); -}); diff --git a/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainCreatorPage/__tests__/rendering.test.tsx b/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainCreatorPage/__tests__/rendering.test.tsx new file mode 100644 index 0000000000..bca00f99f1 --- /dev/null +++ b/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainCreatorPage/__tests__/rendering.test.tsx @@ -0,0 +1,44 @@ +import { describe, expect, test } from "vitest"; +import { render, screen, waitFor } from "@/tests/integrations/test-utils"; +import { MainCreatorPage } from "../MainCreatorPage"; + +const defaultParams = { + creator: "test-creator", +}; + +describe("MainCreatorPage - Rendering", () => { + test("renders creator info card", async () => { + render(); + await waitFor(() => { + expect(screen.getByTestId("creator-description")).toBeInTheDocument(); + }); + }); + + test("renders breadcrumbs with marketplace link", async () => { + render(); + + await waitFor(() => { + expect( + screen.getByRole("link", { name: /marketplace/i }), + ).toBeInTheDocument(); + }); + }); + + test("renders about section", async () => { + render(); + + await waitFor(() => { + expect(screen.getByText("About")).toBeInTheDocument(); + }); + }); + + test("renders agents by creator section", async () => { + render(); + + await waitFor(() => { + expect( + screen.getByText(/Agents by/i, { exact: false }), + ).toBeInTheDocument(); + }); + }); +}); diff --git a/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainMarketplacePage/__tests__/auth-state.test.tsx b/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainMarketplacePage/__tests__/auth-state.test.tsx new file mode 100644 index 0000000000..d2ef79384a --- /dev/null +++ b/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainMarketplacePage/__tests__/auth-state.test.tsx @@ -0,0 +1,38 @@ +import { describe, expect, test, afterEach } from "vitest"; +import { render, screen } from "@/tests/integrations/test-utils"; +import { MainMarkeplacePage } from "../MainMarketplacePage"; +import { + mockAuthenticatedUser, + mockUnauthenticatedUser, + resetAuthState, +} from "@/tests/integrations/helpers/mock-supabase-auth"; + +describe("MainMarketplacePage - Auth State", () => { + afterEach(() => { + resetAuthState(); + }); + + test("renders page correctly when logged out", async () => { + mockUnauthenticatedUser(); + render(); + + expect( + await screen.findByText("Featured agents", { exact: false }), + ).toBeInTheDocument(); + expect( + screen.getByText("Top Agents", { exact: false }), + ).toBeInTheDocument(); + }); + + test("renders page correctly when logged in", async () => { + mockAuthenticatedUser(); + render(); + + expect( + await screen.findByText("Featured agents", { exact: false }), + ).toBeInTheDocument(); + expect( + screen.getByText("Top Agents", { exact: false }), + ).toBeInTheDocument(); + }); +}); diff --git a/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainMarketplacePage/__tests__/empty-state.test.tsx b/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainMarketplacePage/__tests__/empty-state.test.tsx new file mode 100644 index 0000000000..83d7fbab51 --- /dev/null +++ b/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainMarketplacePage/__tests__/empty-state.test.tsx @@ -0,0 +1,87 @@ +import { describe, expect, test } from "vitest"; +import { render, screen } from "@/tests/integrations/test-utils"; +import { MainMarkeplacePage } from "../MainMarketplacePage"; +import { server } from "@/mocks/mock-server"; +import { http, HttpResponse } from "msw"; + +describe("MainMarketplacePage - Empty State", () => { + test("handles empty featured agents gracefully", async () => { + server.use( + http.get("*/api/store/agents*", () => { + return HttpResponse.json({ + agents: [], + pagination: { + total_items: 0, + total_pages: 0, + current_page: 1, + page_size: 10, + }, + }); + }), + ); + + render(); + + // Page should still render without crashing + expect( + await screen.findByText("Featured creators", { exact: false }), + ).toBeInTheDocument(); + }); + + test("handles empty creators gracefully", async () => { + server.use( + http.get("*/api/store/creators*", () => { + return HttpResponse.json({ + creators: [], + pagination: { + total_items: 0, + total_pages: 0, + current_page: 1, + page_size: 10, + }, + }); + }), + ); + + render(); + + // Page should still render without crashing + expect( + await screen.findByText("Featured agents", { exact: false }), + ).toBeInTheDocument(); + }); + + test("handles all empty data gracefully", async () => { + server.use( + http.get("*/api/store/agents*", () => { + return HttpResponse.json({ + agents: [], + pagination: { + total_items: 0, + total_pages: 0, + current_page: 1, + page_size: 10, + }, + }); + }), + http.get("*/api/store/creators*", () => { + return HttpResponse.json({ + creators: [], + pagination: { + total_items: 0, + total_pages: 0, + current_page: 1, + page_size: 10, + }, + }); + }), + ); + + render(); + + // Page should still render the search bar + expect( + await screen.findByPlaceholderText(/search/i), + ).toBeInTheDocument(); + }); +}); diff --git a/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainMarketplacePage/__tests__/error-handling.test.tsx b/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainMarketplacePage/__tests__/error-handling.test.tsx new file mode 100644 index 0000000000..aaa1f15d63 --- /dev/null +++ b/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainMarketplacePage/__tests__/error-handling.test.tsx @@ -0,0 +1,59 @@ +import { describe, expect, test } from "vitest"; +import { render, screen, waitFor } from "@/tests/integrations/test-utils"; +import { MainMarkeplacePage } from "../MainMarketplacePage"; +import { server } from "@/mocks/mock-server"; +import { + getGetV2ListStoreAgentsMockHandler422, + getGetV2ListStoreCreatorsMockHandler422, +} from "@/app/api/__generated__/endpoints/store/store.msw"; +import { create500Handler } from "@/tests/integrations/helpers/create-500-handler"; + +describe("MainMarketplacePage - Error Handling", () => { + test("displays error when featured agents API returns 422", async () => { + server.use(getGetV2ListStoreAgentsMockHandler422()); + + render(); + + await waitFor(() => { + expect( + screen.getByText("Failed to load marketplace data", { exact: false }), + ).toBeInTheDocument(); + }); + }); + + test("displays error when creators API returns 422", async () => { + server.use(getGetV2ListStoreCreatorsMockHandler422()); + + render(); + + await waitFor(() => { + expect( + screen.getByText("Failed to load marketplace data", { exact: false }), + ).toBeInTheDocument(); + }); + }); + + test("displays error when API returns 500", async () => { + server.use(create500Handler("get", "*/api/store/agents*")); + + render(); + + await waitFor(() => { + expect( + screen.getByText("Failed to load marketplace data", { exact: false }), + ).toBeInTheDocument(); + }); + }); + + test("retry button is visible on error", async () => { + server.use(getGetV2ListStoreAgentsMockHandler422()); + + render(); + + await waitFor(() => { + expect( + screen.getByRole("button", { name: /try again/i }), + ).toBeInTheDocument(); + }); + }); +}); diff --git a/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainMarketplacePage/__tests__/loading-state.test.tsx b/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainMarketplacePage/__tests__/loading-state.test.tsx new file mode 100644 index 0000000000..e0553be5fb --- /dev/null +++ b/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainMarketplacePage/__tests__/loading-state.test.tsx @@ -0,0 +1,43 @@ +import { describe, expect, test } from "vitest"; +import { render } from "@/tests/integrations/test-utils"; +import { MainMarkeplacePage } from "../MainMarketplacePage"; +import { server } from "@/mocks/mock-server"; +import { http, HttpResponse, delay } from "msw"; + +describe("MainMarketplacePage - Loading State", () => { + test("shows loading skeleton while data is being fetched", async () => { + // Override handlers to add delay to simulate loading + server.use( + http.get("*/api/store/agents*", async () => { + await delay(500); + return HttpResponse.json({ + agents: [], + pagination: { + total_items: 0, + total_pages: 0, + current_page: 1, + page_size: 10, + }, + }); + }), + http.get("*/api/store/creators*", async () => { + await delay(500); + return HttpResponse.json({ + creators: [], + pagination: { + total_items: 0, + total_pages: 0, + current_page: 1, + page_size: 10, + }, + }); + }), + ); + + const { container } = render(); + + // Check for loading skeleton elements (animated pulse elements) + const loadingElements = container.querySelectorAll('[class*="animate-pulse"]'); + expect(loadingElements.length).toBeGreaterThan(0); + }); +}); diff --git a/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainMarketplacePage/__tests__/main.test.tsx b/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainMarketplacePage/__tests__/main.test.tsx deleted file mode 100644 index d71f5dda7c..0000000000 --- a/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainMarketplacePage/__tests__/main.test.tsx +++ /dev/null @@ -1,132 +0,0 @@ -import { describe, expect, test, afterEach } from "vitest"; -import { render, screen, waitFor } from "@/tests/integrations/test-utils"; -import { MainMarkeplacePage } from "../MainMarketplacePage"; -import { server } from "@/mocks/mock-server"; -import { - getGetV2ListStoreAgentsMockHandler422, - getGetV2ListStoreCreatorsMockHandler422, -} from "@/app/api/__generated__/endpoints/store/store.msw"; -import { create500Handler } from "@/tests/integrations/helpers/create-500-handler"; -import { - mockAuthenticatedUser, - mockUnauthenticatedUser, - resetAuthState, -} from "@/tests/integrations/helpers/mock-supabase-auth"; - -describe("MainMarketplacePage", () => { - afterEach(() => { - resetAuthState(); - }); - - describe("rendering", () => { - test("renders hero section with search bar", async () => { - render(); - - expect( - await screen.findByText("Featured agents", { exact: false }), - ).toBeInTheDocument(); - - expect(screen.getByPlaceholderText(/search/i)).toBeInTheDocument(); - }); - - test("renders featured agents section", async () => { - render(); - - expect( - await screen.findByText("Featured agents", { exact: false }), - ).toBeInTheDocument(); - }); - - test("renders top agents section", async () => { - render(); - - expect( - await screen.findByText("Top Agents", { exact: false }), - ).toBeInTheDocument(); - }); - - test("renders featured creators section", async () => { - render(); - - expect( - await screen.findByText("Featured creators", { exact: false }), - ).toBeInTheDocument(); - }); - }); - - describe("auth state", () => { - test("renders page correctly when logged out", async () => { - mockUnauthenticatedUser(); - render(); - - expect( - await screen.findByText("Featured agents", { exact: false }), - ).toBeInTheDocument(); - expect( - screen.getByText("Top Agents", { exact: false }), - ).toBeInTheDocument(); - }); - - test("renders page correctly when logged in", async () => { - mockAuthenticatedUser(); - render(); - - expect( - await screen.findByText("Featured agents", { exact: false }), - ).toBeInTheDocument(); - expect( - screen.getByText("Top Agents", { exact: false }), - ).toBeInTheDocument(); - }); - }); - - describe("error handling", () => { - test("displays error when featured agents API returns 422", async () => { - server.use(getGetV2ListStoreAgentsMockHandler422()); - - render(); - - await waitFor(() => { - expect( - screen.getByText("Failed to load marketplace data", { exact: false }), - ).toBeInTheDocument(); - }); - }); - - test("displays error when creators API returns 422", async () => { - server.use(getGetV2ListStoreCreatorsMockHandler422()); - - render(); - - await waitFor(() => { - expect( - screen.getByText("Failed to load marketplace data", { exact: false }), - ).toBeInTheDocument(); - }); - }); - - test("displays error when API returns 500", async () => { - server.use(create500Handler("get", "*/api/store/agents*")); - - render(); - - await waitFor(() => { - expect( - screen.getByText("Failed to load marketplace data", { exact: false }), - ).toBeInTheDocument(); - }); - }); - - test("retry button is visible on error", async () => { - server.use(getGetV2ListStoreAgentsMockHandler422()); - - render(); - - await waitFor(() => { - expect( - screen.getByRole("button", { name: /try again/i }), - ).toBeInTheDocument(); - }); - }); - }); -}); diff --git a/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainMarketplacePage/__tests__/rendering.test.tsx b/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainMarketplacePage/__tests__/rendering.test.tsx new file mode 100644 index 0000000000..ea87fb5cff --- /dev/null +++ b/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainMarketplacePage/__tests__/rendering.test.tsx @@ -0,0 +1,39 @@ +import { describe, expect, test } from "vitest"; +import { render, screen } from "@/tests/integrations/test-utils"; +import { MainMarkeplacePage } from "../MainMarketplacePage"; + +describe("MainMarketplacePage - Rendering", () => { + test("renders hero section with search bar", async () => { + render(); + + expect( + await screen.findByText("Featured agents", { exact: false }), + ).toBeInTheDocument(); + + expect(screen.getByPlaceholderText(/search/i)).toBeInTheDocument(); + }); + + test("renders featured agents section", async () => { + render(); + + expect( + await screen.findByText("Featured agents", { exact: false }), + ).toBeInTheDocument(); + }); + + test("renders top agents section", async () => { + render(); + + expect( + await screen.findByText("Top Agents", { exact: false }), + ).toBeInTheDocument(); + }); + + test("renders featured creators section", async () => { + render(); + + expect( + await screen.findByText("Featured creators", { exact: false }), + ).toBeInTheDocument(); + }); +}); diff --git a/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainSearchResultPage/__tests__/auth-state.test.tsx b/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainSearchResultPage/__tests__/auth-state.test.tsx new file mode 100644 index 0000000000..443feb0144 --- /dev/null +++ b/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainSearchResultPage/__tests__/auth-state.test.tsx @@ -0,0 +1,37 @@ +import { describe, expect, test, afterEach } from "vitest"; +import { render, screen, waitFor } from "@/tests/integrations/test-utils"; +import { MainSearchResultPage } from "../MainSearchResultPage"; +import { + mockAuthenticatedUser, + mockUnauthenticatedUser, + resetAuthState, +} from "@/tests/integrations/helpers/mock-supabase-auth"; + +const defaultProps = { + searchTerm: "test-search", + sort: undefined as undefined, +}; + +describe("MainSearchResultPage - Auth State", () => { + afterEach(() => { + resetAuthState(); + }); + + test("renders page correctly when logged out", async () => { + mockUnauthenticatedUser(); + render(); + + await waitFor(() => { + expect(screen.getByText("Results for:")).toBeInTheDocument(); + }); + }); + + test("renders page correctly when logged in", async () => { + mockAuthenticatedUser(); + render(); + + await waitFor(() => { + expect(screen.getByText("Results for:")).toBeInTheDocument(); + }); + }); +}); diff --git a/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainSearchResultPage/__tests__/error-handling.test.tsx b/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainSearchResultPage/__tests__/error-handling.test.tsx new file mode 100644 index 0000000000..7eee72acaa --- /dev/null +++ b/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainSearchResultPage/__tests__/error-handling.test.tsx @@ -0,0 +1,64 @@ +import { describe, expect, test } from "vitest"; +import { render, screen, waitFor } from "@/tests/integrations/test-utils"; +import { MainSearchResultPage } from "../MainSearchResultPage"; +import { server } from "@/mocks/mock-server"; +import { + getGetV2ListStoreAgentsMockHandler422, + getGetV2ListStoreCreatorsMockHandler422, +} from "@/app/api/__generated__/endpoints/store/store.msw"; +import { create500Handler } from "@/tests/integrations/helpers/create-500-handler"; + +const defaultProps = { + searchTerm: "test-search", + sort: undefined as undefined, +}; + +describe("MainSearchResultPage - Error Handling", () => { + test("displays error when agents API returns 422", async () => { + server.use(getGetV2ListStoreAgentsMockHandler422()); + + render(); + + await waitFor(() => { + expect( + screen.getByText("Failed to load marketplace data", { exact: false }), + ).toBeInTheDocument(); + }); + }); + + test("displays error when creators API returns 422", async () => { + server.use(getGetV2ListStoreCreatorsMockHandler422()); + + render(); + + await waitFor(() => { + expect( + screen.getByText("Failed to load marketplace data", { exact: false }), + ).toBeInTheDocument(); + }); + }); + + test("displays error when API returns 500", async () => { + server.use(create500Handler("get", "*/api/store/agents*")); + + render(); + + await waitFor(() => { + expect( + screen.getByText("Failed to load marketplace data", { exact: false }), + ).toBeInTheDocument(); + }); + }); + + test("retry button is visible on error", async () => { + server.use(getGetV2ListStoreAgentsMockHandler422()); + + render(); + + await waitFor(() => { + expect( + screen.getByRole("button", { name: /try again/i }), + ).toBeInTheDocument(); + }); + }); +}); diff --git a/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainSearchResultPage/__tests__/main.test.tsx b/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainSearchResultPage/__tests__/main.test.tsx deleted file mode 100644 index fe973db13d..0000000000 --- a/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainSearchResultPage/__tests__/main.test.tsx +++ /dev/null @@ -1,114 +0,0 @@ -import { describe, expect, test, afterEach } from "vitest"; -import { render, screen, waitFor } from "@/tests/integrations/test-utils"; -import { MainSearchResultPage } from "../MainSearchResultPage"; -import { server } from "@/mocks/mock-server"; -import { - getGetV2ListStoreAgentsMockHandler422, - getGetV2ListStoreCreatorsMockHandler422, -} from "@/app/api/__generated__/endpoints/store/store.msw"; -import { create500Handler } from "@/tests/integrations/helpers/create-500-handler"; -import { - mockAuthenticatedUser, - mockUnauthenticatedUser, - resetAuthState, -} from "@/tests/integrations/helpers/mock-supabase-auth"; - -const defaultProps = { - searchTerm: "test-search", - sort: undefined as undefined, -}; - -describe("MainSearchResultPage", () => { - afterEach(() => { - resetAuthState(); - }); - - describe("rendering", () => { - test("renders search results header with search term", async () => { - render(); - - await waitFor(() => { - expect(screen.getByText("Results for:")).toBeInTheDocument(); - }); - expect(screen.getByText("test-search")).toBeInTheDocument(); - }); - - test("renders search bar", async () => { - render(); - - await waitFor(() => { - expect(screen.getByPlaceholderText(/search/i)).toBeInTheDocument(); - }); - }); - }); - - describe("auth state", () => { - test("renders page correctly when logged out", async () => { - mockUnauthenticatedUser(); - render(); - - await waitFor(() => { - expect(screen.getByText("Results for:")).toBeInTheDocument(); - }); - }); - - test("renders page correctly when logged in", async () => { - mockAuthenticatedUser(); - render(); - - await waitFor(() => { - expect(screen.getByText("Results for:")).toBeInTheDocument(); - }); - }); - }); - - describe("error handling", () => { - test("displays error when agents API returns 422", async () => { - server.use(getGetV2ListStoreAgentsMockHandler422()); - - render(); - - await waitFor(() => { - expect( - screen.getByText("Failed to load marketplace data", { exact: false }), - ).toBeInTheDocument(); - }); - }); - - test("displays error when creators API returns 422", async () => { - server.use(getGetV2ListStoreCreatorsMockHandler422()); - - render(); - - await waitFor(() => { - expect( - screen.getByText("Failed to load marketplace data", { exact: false }), - ).toBeInTheDocument(); - }); - }); - - test("displays error when API returns 500", async () => { - server.use(create500Handler("get", "*/api/store/agents*")); - - render(); - - await waitFor(() => { - expect( - screen.getByText("Failed to load marketplace data", { exact: false }), - ).toBeInTheDocument(); - }); - }); - - test("retry button is visible on error", async () => { - server.use(getGetV2ListStoreAgentsMockHandler422()); - - render(); - - await waitFor(() => { - expect( - screen.getByRole("button", { name: /try again/i }), - ).toBeInTheDocument(); - }); - }); - }); -}); diff --git a/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainSearchResultPage/__tests__/no-results.test.tsx b/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainSearchResultPage/__tests__/no-results.test.tsx new file mode 100644 index 0000000000..20d6c509bf --- /dev/null +++ b/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainSearchResultPage/__tests__/no-results.test.tsx @@ -0,0 +1,92 @@ +import { describe, expect, test } from "vitest"; +import { render, screen, waitFor } from "@/tests/integrations/test-utils"; +import { MainSearchResultPage } from "../MainSearchResultPage"; +import { server } from "@/mocks/mock-server"; +import { http, HttpResponse } from "msw"; + +const defaultProps = { + searchTerm: "nonexistent-search-term-xyz", + sort: undefined as undefined, +}; + +describe("MainSearchResultPage - No Results", () => { + test("shows empty state when no agents match search", async () => { + server.use( + http.get("*/api/store/agents*", () => { + return HttpResponse.json({ + agents: [], + pagination: { + total_items: 0, + total_pages: 0, + current_page: 1, + page_size: 10, + }, + }); + }), + http.get("*/api/store/creators*", () => { + return HttpResponse.json({ + creators: [], + pagination: { + total_items: 0, + total_pages: 0, + current_page: 1, + page_size: 10, + }, + }); + }), + ); + + render(); + + await waitFor(() => { + expect(screen.getByText("Results for:")).toBeInTheDocument(); + }); + + // Verify search term is displayed + expect(screen.getByText("nonexistent-search-term-xyz")).toBeInTheDocument(); + }); + + test("displays search term even with no results", async () => { + server.use( + http.get("*/api/store/agents*", () => { + return HttpResponse.json({ + agents: [], + pagination: { + total_items: 0, + total_pages: 0, + current_page: 1, + page_size: 10, + }, + }); + }), + ); + + render(); + + await waitFor(() => { + expect(screen.getByText("nonexistent-search-term-xyz")).toBeInTheDocument(); + }); + }); + + test("search bar remains functional with no results", async () => { + server.use( + http.get("*/api/store/agents*", () => { + return HttpResponse.json({ + agents: [], + pagination: { + total_items: 0, + total_pages: 0, + current_page: 1, + page_size: 10, + }, + }); + }), + ); + + render(); + + await waitFor(() => { + expect(screen.getByPlaceholderText(/search/i)).toBeInTheDocument(); + }); + }); +}); diff --git a/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainSearchResultPage/__tests__/rendering.test.tsx b/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainSearchResultPage/__tests__/rendering.test.tsx new file mode 100644 index 0000000000..abefacbf03 --- /dev/null +++ b/autogpt_platform/frontend/src/app/(platform)/marketplace/components/MainSearchResultPage/__tests__/rendering.test.tsx @@ -0,0 +1,27 @@ +import { describe, expect, test } from "vitest"; +import { render, screen, waitFor } from "@/tests/integrations/test-utils"; +import { MainSearchResultPage } from "../MainSearchResultPage"; + +const defaultProps = { + searchTerm: "test-search", + sort: undefined as undefined, +}; + +describe("MainSearchResultPage - Rendering", () => { + test("renders search results header with search term", async () => { + render(); + + await waitFor(() => { + expect(screen.getByText("Results for:")).toBeInTheDocument(); + }); + expect(screen.getByText("test-search")).toBeInTheDocument(); + }); + + test("renders search bar", async () => { + render(); + + await waitFor(() => { + expect(screen.getByPlaceholderText(/search/i)).toBeInTheDocument(); + }); + }); +});