the universal sandbox runtime for agents and humans. pocketenv.io
sandbox openclaw agent claude-code vercel-sandbox deno-sandbox cloudflare-sandbox atproto sprites daytona
7
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 130 lines 3.8 kB view raw
1import { vi, describe, it, expect, beforeEach } from "vitest"; 2import consola from "consola"; 3import { Sandbox } from "@pocketenv/sdk"; 4import { listVolumes, createVolume, deleteVolume } from "./volume"; 5 6vi.mock("../lib/sdk", () => ({ configureSdk: vi.fn() })); 7vi.mock("../lib/getAccessToken", () => ({ 8 default: vi.fn().mockResolvedValue("test-access-token"), 9})); 10vi.mock("../lib/env", () => ({ 11 env: { POCKETENV_TOKEN: "", POCKETENV_API_URL: "https://api.pocketenv.io" }, 12})); 13vi.mock("../theme", () => ({ 14 c: { 15 primary: (s: string | number) => String(s), 16 secondary: (s: string | number) => String(s), 17 }, 18})); 19vi.mock("../client", () => ({ 20 client: { post: vi.fn().mockResolvedValue({ data: {} }) }, 21})); 22vi.mock("consola", () => ({ 23 default: { log: vi.fn(), success: vi.fn(), error: vi.fn() }, 24})); 25vi.mock("@pocketenv/sdk", () => ({ 26 Sandbox: { get: vi.fn(), configure: vi.fn() }, 27})); 28 29import { client } from "../client"; 30 31describe("volume commands", () => { 32 beforeEach(() => { 33 vi.clearAllMocks(); 34 }); 35 36 describe("listVolumes", () => { 37 it("lists volumes and logs a table", async () => { 38 const mockSandbox = { 39 volume: { 40 list: vi.fn().mockResolvedValue({ 41 volumes: [ 42 { 43 id: "vol-1", 44 name: "data", 45 path: "/data", 46 createdAt: new Date().toISOString(), 47 }, 48 ], 49 }), 50 }, 51 }; 52 vi.mocked(Sandbox.get).mockResolvedValue(mockSandbox as any); 53 54 await listVolumes("my-sandbox"); 55 56 expect(mockSandbox.volume.list).toHaveBeenCalledOnce(); 57 expect(consola.log).toHaveBeenCalledOnce(); 58 }); 59 60 it("logs an empty table when no volumes exist", async () => { 61 const mockSandbox = { 62 volume: { list: vi.fn().mockResolvedValue({ volumes: [] }) }, 63 }; 64 vi.mocked(Sandbox.get).mockResolvedValue(mockSandbox as any); 65 66 await listVolumes("my-sandbox"); 67 68 expect(consola.log).toHaveBeenCalledOnce(); 69 }); 70 }); 71 72 describe("createVolume", () => { 73 it("creates a volume and logs success", async () => { 74 const mockSandbox = { 75 volume: { create: vi.fn().mockResolvedValue(undefined) }, 76 }; 77 vi.mocked(Sandbox.get).mockResolvedValue(mockSandbox as any); 78 79 await createVolume("my-sandbox", "data", "/data"); 80 81 expect(mockSandbox.volume.create).toHaveBeenCalledWith("data", { 82 path: "/data", 83 }); 84 expect(consola.success).toHaveBeenCalledWith( 85 expect.stringContaining("data"), 86 ); 87 }); 88 89 it("logs error when volume creation fails", async () => { 90 const mockSandbox = { 91 volume: { 92 create: vi.fn().mockRejectedValue(new Error("Create failed")), 93 }, 94 }; 95 vi.mocked(Sandbox.get).mockResolvedValue(mockSandbox as any); 96 97 await createVolume("my-sandbox", "data", "/data"); 98 99 expect(consola.error).toHaveBeenCalledWith( 100 "Failed to create volume:", 101 expect.any(Error), 102 ); 103 }); 104 }); 105 106 describe("deleteVolume", () => { 107 it("deletes a volume via API and logs success", async () => { 108 await deleteVolume("vol-1"); 109 110 expect(client.post).toHaveBeenCalledWith( 111 "/xrpc/io.pocketenv.volume.deleteVolume", 112 undefined, 113 expect.objectContaining({ params: { id: "vol-1" } }), 114 ); 115 expect(consola.success).toHaveBeenCalledWith( 116 expect.stringContaining("vol-1"), 117 ); 118 }); 119 120 it("logs error when deletion fails", async () => { 121 vi.mocked(client.post).mockRejectedValue(new Error("API error")); 122 123 await deleteVolume("vol-1"); 124 125 expect(consola.error).toHaveBeenCalledWith( 126 expect.stringContaining("Failed to delete volume"), 127 ); 128 }); 129 }); 130});