diff --git a/src/components/order-item-context-popover-trigger.test.tsx b/src/components/order-item-context-popover-trigger.test.tsx
new file mode 100644
index 0000000..b09e4de
--- /dev/null
+++ b/src/components/order-item-context-popover-trigger.test.tsx
@@ -0,0 +1,36 @@
+import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
+import { cleanup, render, screen, waitFor, fireEvent } from "@testing-library/react";
+import { OrderItemContextPopoverTrigger } from "@/components/order-item-context-popover-trigger";
+
+afterEach(cleanup);
+
+describe("OrderItemContextPopoverTrigger", () => {
+ beforeEach(() => {
+ vi.restoreAllMocks();
+ });
+
+ it("renders the ⓘ button by default", () => {
+ render();
+ expect(screen.getByRole("button", { name: /View item context/ })).toBeInTheDocument();
+ });
+
+ it("fetches on first open, not on render", async () => {
+ const fetchSpy = vi.spyOn(globalThis, "fetch").mockResolvedValue({
+ ok: true,
+ status: 200,
+ json: async () => ({
+ generated_at: "2026-08-07T10:00:00Z",
+ match: { sku: "X", match_kind: "sku_exact", match_confidence: 1 },
+ last_quote: null, last_order: null, last_invoiced: null, stock: null,
+ suppliers: [], cheapest: null,
+ }),
+ } as Response);
+
+ render();
+ expect(fetchSpy).not.toHaveBeenCalled();
+
+ fireEvent.click(screen.getByRole("button", { name: /View item context/ }));
+ await waitFor(() => expect(fetchSpy).toHaveBeenCalledTimes(1));
+ expect(fetchSpy.mock.calls[0][0]).toContain("/api/v1/order-items/abc/context");
+ });
+});