Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
207 changes: 207 additions & 0 deletions __tests__/components/utils/input/ens-address/EnsAddressInput.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
import { render, screen, fireEvent } from "@testing-library/react";
import EnsAddressInput from "@/components/utils/input/ens-address/EnsAddressInput";

const mockHandleInputChange = jest.fn();
const mockSetInputValue = jest.fn();

jest.mock("react-bootstrap", () => ({
Form: {
Control: (props: React.InputHTMLAttributes<HTMLInputElement>) => (
<input data-testid="form-control" {...props} />
),
},
}));

jest.mock("@/hooks/useEnsResolution", () => ({
useEnsResolution: jest.fn(() => ({
inputValue: "",
address: "",
handleInputChange: mockHandleInputChange,
setInputValue: mockSetInputValue,
ensNameQuery: { isLoading: false },
ensAddressQuery: { isLoading: false, isError: false },
})),
}));

import { useEnsResolution } from "@/hooks/useEnsResolution";

const mockUseEnsResolution = useEnsResolution as jest.Mock;

describe("EnsAddressInput", () => {
const mockOnAddressChange = jest.fn();

beforeEach(() => {
jest.clearAllMocks();
mockUseEnsResolution.mockReturnValue({
inputValue: "",
address: "",
handleInputChange: mockHandleInputChange,
setInputValue: mockSetInputValue,
ensNameQuery: { isLoading: false },
ensAddressQuery: { isLoading: false, isError: false },
});
});

it("renders input with placeholder", () => {
render(<EnsAddressInput onAddressChange={mockOnAddressChange} />);

expect(
screen.getByPlaceholderText("0x... or ENS")
).toBeInTheDocument();
});

it("renders with custom placeholder", () => {
render(
<EnsAddressInput
onAddressChange={mockOnAddressChange}
placeholder="Enter wallet"
/>
);

expect(screen.getByPlaceholderText("Enter wallet")).toBeInTheDocument();
});

it("calls handleInputChange when user types", () => {
render(<EnsAddressInput onAddressChange={mockOnAddressChange} />);

const input = screen.getByPlaceholderText("0x... or ENS");
fireEvent.change(input, { target: { value: "0x123" } });

expect(mockHandleInputChange).toHaveBeenCalledWith("0x123");
});

it("calls onAddressChange when address changes", () => {
const testAddress = "0x1234567890abcdef";
mockUseEnsResolution.mockReturnValue({
inputValue: testAddress,
address: testAddress,
handleInputChange: mockHandleInputChange,
setInputValue: mockSetInputValue,
ensNameQuery: { isLoading: false },
ensAddressQuery: { isLoading: false, isError: false },
});

render(<EnsAddressInput onAddressChange={mockOnAddressChange} />);

expect(mockOnAddressChange).toHaveBeenCalledWith(testAddress);
});

it("calls onLoadingChange when loading state changes", () => {
const mockOnLoadingChange = jest.fn();
mockUseEnsResolution.mockReturnValue({
inputValue: "test.eth",
address: "",
handleInputChange: mockHandleInputChange,
setInputValue: mockSetInputValue,
ensNameQuery: { isLoading: false },
ensAddressQuery: { isLoading: true, isError: false },
});

render(
<EnsAddressInput
onAddressChange={mockOnAddressChange}
onLoadingChange={mockOnLoadingChange}
/>
);

expect(mockOnLoadingChange).toHaveBeenCalledWith(true);
});

it("calls onError when ENS resolution fails for .eth input", () => {
const mockOnError = jest.fn();
mockUseEnsResolution.mockReturnValue({
inputValue: "invalid.eth",
address: "",
handleInputChange: mockHandleInputChange,
setInputValue: mockSetInputValue,
ensNameQuery: { isLoading: false },
ensAddressQuery: { isLoading: false, isError: true },
});

render(
<EnsAddressInput
onAddressChange={mockOnAddressChange}
onError={mockOnError}
/>
);

expect(mockOnError).toHaveBeenCalledWith(true);
});

it("does not call onError for non-.eth input even if ensAddressQuery has error", () => {
const mockOnError = jest.fn();
mockUseEnsResolution.mockReturnValue({
inputValue: "0x123",
address: "0x123",
handleInputChange: mockHandleInputChange,
setInputValue: mockSetInputValue,
ensNameQuery: { isLoading: false },
ensAddressQuery: { isLoading: false, isError: true },
});

render(
<EnsAddressInput
onAddressChange={mockOnAddressChange}
onError={mockOnError}
/>
);

expect(mockOnError).toHaveBeenCalledWith(false);
});

it("disables input when disabled prop is true", () => {
render(
<EnsAddressInput onAddressChange={mockOnAddressChange} disabled />
);

expect(screen.getByPlaceholderText("0x... or ENS")).toBeDisabled();
});

it("applies custom className", () => {
render(
<EnsAddressInput
onAddressChange={mockOnAddressChange}
className="custom-class"
/>
);

expect(screen.getByPlaceholderText("0x... or ENS")).toHaveClass(
"custom-class"
);
});

it("passes value prop as initialValue to useEnsResolution", () => {
const { rerender } = render(
<EnsAddressInput onAddressChange={mockOnAddressChange} value="initial" />
);

expect(mockUseEnsResolution).toHaveBeenCalledWith({
initialValue: "initial",
chainId: 1,
});

rerender(
<EnsAddressInput onAddressChange={mockOnAddressChange} value="updated" />
);

expect(mockUseEnsResolution).toHaveBeenCalledWith({
initialValue: "updated",
chainId: 1,
});
});

it("displays resolved ENS with address format", () => {
mockUseEnsResolution.mockReturnValue({
inputValue: "vitalik.eth - 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
address: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
handleInputChange: mockHandleInputChange,
setInputValue: mockSetInputValue,
ensNameQuery: { isLoading: false },
ensAddressQuery: { isLoading: false, isError: false },
});

render(<EnsAddressInput onAddressChange={mockOnAddressChange} />);

expect(screen.getByDisplayValue(/vitalik\.eth - 0x/)).toBeInTheDocument();
});
});
28 changes: 24 additions & 4 deletions __tests__/components/walletChecker.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,30 @@ jest.mock("react-bootstrap", () => ({
Table: (p: any) => <table>{p.children}</table>,
}));

jest.mock("wagmi", () => ({
useEnsName: () => ({ data: undefined, isLoading: false }),
useEnsAddress: () => ({ data: undefined, isLoading: false }),
}));
jest.mock(
"@/components/utils/input/ens-address/EnsAddressInput",
() =>
function MockEnsAddressInput(props: {
value?: string;
placeholder?: string;
onAddressChange: (address: string) => void;
disabled?: boolean;
autoFocus?: boolean;
className?: string;
}) {
return (
<input
data-testid="ens-address-input"
placeholder={props.placeholder}
value={props.value ?? ""}
disabled={props.disabled}
autoFocus={props.autoFocus}
className={props.className}
onChange={(e) => props.onAddressChange(e.target.value)}
/>
);
}
);

jest.mock("@/services/6529api");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,17 @@ describe('MemesArtSubmissionContainer', () => {
additional_media: {
artist_profile_media: [],
artwork_commentary_media: [],
preview_image: "",
},
commentary: "",
about_artist: "",
},
setAirdropConfig: jest.fn(),
setPaymentInfo: jest.fn(),
setAllowlistBatches: jest.fn(),
setAdditionalMedia: jest.fn(),
setCommentary: jest.fn(),
setAboutArtist: jest.fn(),
handleBackToArtwork: jest.fn(),
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,39 @@ import AdditionalMediaUpload from "@/components/waves/memes/submission/component

describe("AdditionalMediaUpload", () => {
const defaultProps = {
artworkCommentaryMedia: [],
supportingMedia: [],
artworkCommentary: "",
onArtworkCommentaryMediaChange: jest.fn(),
aboutArtist: "",
previewImage: "",
requiresPreviewImage: false,
previewRequiredMediaType: null,
onSupportingMediaChange: jest.fn(),
onPreviewImageChange: jest.fn(),
onArtworkCommentaryChange: jest.fn(),
onAboutArtistChange: jest.fn(),
};

it("renders commentary media section and commentary field", () => {
it("renders supporting media section and commentary field", () => {
render(<AdditionalMediaUpload {...defaultProps} />);
expect(screen.getByText(/Artwork Commentary Media/i)).toBeInTheDocument();
expect(screen.getByText(/Supporting Media/i)).toBeInTheDocument();
expect(
screen.getByRole("textbox", { name: /^Artwork Commentary$/i })
screen.getByRole("textbox", { name: /Artwork Commentary/i })
).toBeInTheDocument();
});

it("shows preview image section when video submission", () => {
render(<AdditionalMediaUpload {...defaultProps} requiresPreviewImage previewRequiredMediaType="Video" />);
expect(screen.getByText(/Preview Image \*/i)).toBeInTheDocument();
expect(
screen.getByText(/Video submissions require a preview image/i)
).toBeInTheDocument();
});

it("does not show preview image section for regular submissions", () => {
render(<AdditionalMediaUpload {...defaultProps} requiresPreviewImage={false} />);
expect(screen.queryByText(/Preview Image \*/i)).not.toBeInTheDocument();
});

it("calls onArtworkCommentaryChange when commentary is updated", async () => {
const user = userEvent.setup();
const onArtworkCommentaryChange = jest.fn();
Expand All @@ -29,13 +48,10 @@ describe("AdditionalMediaUpload", () => {
);

const textarea = screen.getByRole("textbox", {
name: /^Artwork Commentary$/i,
name: /Artwork Commentary/i,
});
await user.type(textarea, "This is my commentary");
await user.tab();
await user.type(textarea, "T");

expect(onArtworkCommentaryChange).toHaveBeenCalledWith(
"This is my commentary"
);
expect(onArtworkCommentaryChange).toHaveBeenCalled();
});
});
Loading