Spaces:
Build error
Build error
| import { render, screen } from "@testing-library/react"; | |
| import { describe, expect, vi, beforeEach, it } from "vitest"; | |
| import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; | |
| import userEvent from "@testing-library/user-event"; | |
| import { RepositorySelectionForm } from "../../../../src/components/features/home/repo-selection-form"; | |
| import OpenHands from "#/api/open-hands"; | |
| import { GitRepository } from "#/types/git"; | |
| // Create mock functions | |
| const mockUseUserRepositories = vi.fn(); | |
| const mockUseCreateConversation = vi.fn(); | |
| const mockUseIsCreatingConversation = vi.fn(); | |
| const mockUseTranslation = vi.fn(); | |
| const mockUseAuth = vi.fn(); | |
| // Setup default mock returns | |
| mockUseUserRepositories.mockReturnValue({ | |
| data: [], | |
| isLoading: false, | |
| isError: false, | |
| }); | |
| mockUseCreateConversation.mockReturnValue({ | |
| mutate: vi.fn(), | |
| isPending: false, | |
| isSuccess: false, | |
| }); | |
| mockUseIsCreatingConversation.mockReturnValue(false); | |
| mockUseTranslation.mockReturnValue({ t: (key: string) => key }); | |
| mockUseAuth.mockReturnValue({ | |
| isAuthenticated: true, | |
| isLoading: false, | |
| providersAreSet: true, | |
| user: { | |
| id: 1, | |
| login: "testuser", | |
| avatar_url: "https://example.com/avatar.png", | |
| name: "Test User", | |
| email: "test@example.com", | |
| company: "Test Company", | |
| }, | |
| login: vi.fn(), | |
| logout: vi.fn(), | |
| }); | |
| vi.mock("#/hooks/mutation/use-create-conversation", () => ({ | |
| useCreateConversation: () => mockUseCreateConversation(), | |
| })); | |
| vi.mock("#/hooks/use-is-creating-conversation", () => ({ | |
| useIsCreatingConversation: () => mockUseIsCreatingConversation(), | |
| })); | |
| vi.mock("react-i18next", () => ({ | |
| useTranslation: () => mockUseTranslation(), | |
| })); | |
| vi.mock("#/context/auth-context", () => ({ | |
| useAuth: () => mockUseAuth(), | |
| })); | |
| vi.mock("#/hooks/use-debounce", () => ({ | |
| useDebounce: (value: string) => value, | |
| })); | |
| const mockOnRepoSelection = vi.fn(); | |
| const renderForm = () => | |
| render(<RepositorySelectionForm onRepoSelection={mockOnRepoSelection} />, { | |
| wrapper: ({ children }) => ( | |
| <QueryClientProvider | |
| client={ | |
| new QueryClient({ | |
| defaultOptions: { | |
| queries: { | |
| retry: false, | |
| }, | |
| }, | |
| }) | |
| } | |
| > | |
| {children} | |
| </QueryClientProvider> | |
| ), | |
| }); | |
| describe("RepositorySelectionForm", () => { | |
| beforeEach(() => { | |
| vi.clearAllMocks(); | |
| }); | |
| it("shows loading indicator when repositories are being fetched", () => { | |
| const MOCK_REPOS: GitRepository[] = [ | |
| { | |
| id: 1, | |
| full_name: "user/repo1", | |
| git_provider: "github", | |
| is_public: true, | |
| }, | |
| { | |
| id: 2, | |
| full_name: "user/repo2", | |
| git_provider: "github", | |
| is_public: true, | |
| }, | |
| ]; | |
| const retrieveUserGitRepositoriesSpy = vi.spyOn( | |
| OpenHands, | |
| "retrieveUserGitRepositories", | |
| ); | |
| retrieveUserGitRepositoriesSpy.mockResolvedValue(MOCK_REPOS); | |
| renderForm(); | |
| // Check if loading indicator is displayed | |
| expect(screen.getByTestId("repo-dropdown-loading")).toBeInTheDocument(); | |
| expect(screen.getByText("HOME$LOADING_REPOSITORIES")).toBeInTheDocument(); | |
| }); | |
| it("shows dropdown when repositories are loaded", async () => { | |
| const MOCK_REPOS: GitRepository[] = [ | |
| { | |
| id: 1, | |
| full_name: "user/repo1", | |
| git_provider: "github", | |
| is_public: true, | |
| }, | |
| { | |
| id: 2, | |
| full_name: "user/repo2", | |
| git_provider: "github", | |
| is_public: true, | |
| }, | |
| ]; | |
| const retrieveUserGitRepositoriesSpy = vi.spyOn( | |
| OpenHands, | |
| "retrieveUserGitRepositories", | |
| ); | |
| retrieveUserGitRepositoriesSpy.mockResolvedValue(MOCK_REPOS); | |
| renderForm(); | |
| expect(await screen.findByTestId("repo-dropdown")).toBeInTheDocument(); | |
| }); | |
| it("shows error message when repository fetch fails", async () => { | |
| const retrieveUserGitRepositoriesSpy = vi.spyOn( | |
| OpenHands, | |
| "retrieveUserGitRepositories", | |
| ); | |
| retrieveUserGitRepositoriesSpy.mockRejectedValue( | |
| new Error("Failed to load"), | |
| ); | |
| renderForm(); | |
| expect( | |
| await screen.findByTestId("repo-dropdown-error"), | |
| ).toBeInTheDocument(); | |
| expect( | |
| screen.getByText("HOME$FAILED_TO_LOAD_REPOSITORIES"), | |
| ).toBeInTheDocument(); | |
| }); | |
| it("should call the search repos API when searching a URL", async () => { | |
| const MOCK_REPOS: GitRepository[] = [ | |
| { | |
| id: 1, | |
| full_name: "user/repo1", | |
| git_provider: "github", | |
| is_public: true, | |
| }, | |
| { | |
| id: 2, | |
| full_name: "user/repo2", | |
| git_provider: "github", | |
| is_public: true, | |
| }, | |
| ]; | |
| const MOCK_SEARCH_REPOS: GitRepository[] = [ | |
| { | |
| id: 3, | |
| full_name: "kubernetes/kubernetes", | |
| git_provider: "github", | |
| is_public: true, | |
| }, | |
| ]; | |
| const searchGitReposSpy = vi.spyOn(OpenHands, "searchGitRepositories"); | |
| const retrieveUserGitRepositoriesSpy = vi.spyOn( | |
| OpenHands, | |
| "retrieveUserGitRepositories", | |
| ); | |
| searchGitReposSpy.mockResolvedValue(MOCK_SEARCH_REPOS); | |
| retrieveUserGitRepositoriesSpy.mockResolvedValue(MOCK_REPOS); | |
| renderForm(); | |
| const input = await screen.findByTestId("repo-dropdown"); | |
| await userEvent.click(input); | |
| for (const repo of MOCK_REPOS) { | |
| expect(screen.getByText(repo.full_name)).toBeInTheDocument(); | |
| } | |
| expect( | |
| screen.queryByText(MOCK_SEARCH_REPOS[0].full_name), | |
| ).not.toBeInTheDocument(); | |
| expect(searchGitReposSpy).not.toHaveBeenCalled(); | |
| await userEvent.type(input, "https://github.com/kubernetes/kubernetes"); | |
| expect(searchGitReposSpy).toHaveBeenLastCalledWith( | |
| "kubernetes/kubernetes", | |
| 3, | |
| ); | |
| expect( | |
| screen.getByText(MOCK_SEARCH_REPOS[0].full_name), | |
| ).toBeInTheDocument(); | |
| for (const repo of MOCK_REPOS) { | |
| expect(screen.queryByText(repo.full_name)).not.toBeInTheDocument(); | |
| } | |
| }); | |
| it("should call onRepoSelection when a searched repository is selected", async () => { | |
| const MOCK_SEARCH_REPOS: GitRepository[] = [ | |
| { | |
| id: 3, | |
| full_name: "kubernetes/kubernetes", | |
| git_provider: "github", | |
| is_public: true, | |
| }, | |
| ]; | |
| const searchGitReposSpy = vi.spyOn(OpenHands, "searchGitRepositories"); | |
| searchGitReposSpy.mockResolvedValue(MOCK_SEARCH_REPOS); | |
| renderForm(); | |
| const input = await screen.findByTestId("repo-dropdown"); | |
| await userEvent.type(input, "https://github.com/kubernetes/kubernetes"); | |
| expect(searchGitReposSpy).toHaveBeenLastCalledWith( | |
| "kubernetes/kubernetes", | |
| 3, | |
| ); | |
| const searchedRepo = screen.getByText(MOCK_SEARCH_REPOS[0].full_name); | |
| expect(searchedRepo).toBeInTheDocument(); | |
| await userEvent.click(searchedRepo); | |
| expect(mockOnRepoSelection).toHaveBeenCalledWith( | |
| MOCK_SEARCH_REPOS[0].full_name, | |
| ); | |
| }); | |
| }); | |