diff --git a/src/components/__tests__/ActionButtons.test.tsx b/src/components/__tests__/ActionButtons.test.tsx
new file mode 100644
index 0000000..544ac94
--- /dev/null
+++ b/src/components/__tests__/ActionButtons.test.tsx
@@ -0,0 +1,65 @@
+import { render, screen, fireEvent } from "@testing-library/react";
+import { describe, it, expect, vi, beforeEach } from "vitest";
+import { ActionButtons } from "../ActionButtons";
+
+describe("ActionButtons", () => {
+ const defaultProps = {
+ handleCopy: vi.fn(),
+ handleDownload: vi.fn(),
+ previewUrl: "https://example.com/image.png",
+ copyStatus: "idle" as const,
+ };
+
+ beforeEach(() => {
+ vi.clearAllMocks();
+ });
+
+ it("renders both buttons", () => {
+ render();
+
+ expect(screen.getByRole("button", { name: /Copy Image/i })).toBeInTheDocument();
+ expect(screen.getByRole("button", { name: /Download PNG/i })).toBeInTheDocument();
+ });
+
+ it("calls handleCopy when Copy Image button is clicked", () => {
+ render();
+
+ const copyButton = screen.getByRole("button", { name: /Copy Image/i });
+ fireEvent.click(copyButton);
+
+ expect(defaultProps.handleCopy).toHaveBeenCalledTimes(1);
+ });
+
+ it("calls handleDownload when Download PNG button is clicked", () => {
+ render();
+
+ const downloadButton = screen.getByRole("button", { name: /Download PNG/i });
+ fireEvent.click(downloadButton);
+
+ expect(defaultProps.handleDownload).toHaveBeenCalledTimes(1);
+ });
+
+ it("disables both buttons when previewUrl is null", () => {
+ render();
+
+ const copyButton = screen.getByRole("button", { name: /Copy Image/i });
+ const downloadButton = screen.getByRole("button", { name: /Download PNG/i });
+
+ expect(copyButton).toBeDisabled();
+ expect(downloadButton).toBeDisabled();
+ });
+
+ it("shows 'Copied!' text when copyStatus is 'copied'", () => {
+ render();
+
+ expect(screen.getByRole("button", { name: /Copied!/i })).toBeInTheDocument();
+ expect(screen.queryByRole("button", { name: /Copy Image/i })).not.toBeInTheDocument();
+ });
+
+ it("shows 'Copy Image' text when copyStatus is 'error'", () => {
+ render();
+
+ expect(screen.getByRole("button", { name: /Copy Image/i })).toBeInTheDocument();
+ expect(screen.queryByRole("button", { name: /Copied!/i })).not.toBeInTheDocument();
+ });
+});
diff --git a/vitest.config.ts b/vitest.config.ts
index 9404856..12c2102 100644
--- a/vitest.config.ts
+++ b/vitest.config.ts
@@ -21,6 +21,7 @@ export default defineConfig({
"src/components/LanguageChart.tsx",
"src/components/SkillsCard.tsx",
"src/components/LayoutEditor.tsx",
+ "src/components/ActionButtons.tsx",
"src/lib/rateLimit.ts",
"src/app/api/og/[username]/route.tsx"
],