import { describe, it, expect, vi, beforeEach } from "vitest"; vi.mock("../lib/config.js", () => ({ getConfig: vi.fn(() => ({ apiUrl: "https://api.skills-hub.ai" })), getAuthHeader: vi.fn(() => ({ Authorization: "Bearer test" })), ensureAuth: vi.fn(), saveConfig: vi.fn(), })); vi.mock("../lib/api-client.js", () => ({ apiRequest: vi.fn(), })); import { orgRemoveCommand } from "./org-remove.js"; import { apiRequest } from "../lib/api-client.js"; const mockApiRequest = vi.mocked(apiRequest); beforeEach(() => { vi.clearAllMocks(); }); describe("org remove", () => { it("finds member and removes them", async () => { mockApiRequest .mockResolvedValueOnce({ data: [{ user: { id: "user-456", username: "bob" } }], }) // search members .mockResolvedValueOnce(undefined); // DELETE await orgRemoveCommand.parseAsync(["node", "remove", "acme", "bob"], { from: "node", }); expect(mockApiRequest).toHaveBeenCalledWith( expect.stringContaining("/api/v1/orgs/acme/members?q=bob"), ); expect(mockApiRequest).toHaveBeenCalledWith( "/api/v1/orgs/acme/members/user-456", expect.objectContaining({ method: "DELETE" }), ); }); it("fails when member not found", async () => { mockApiRequest.mockResolvedValue({ data: [] }); const exit = vi.spyOn(process, "exit").mockImplementation(() => { throw new Error("exit"); }); await expect( orgRemoveCommand.parseAsync(["node", "remove", "acme", "ghost"], { from: "node", }), ).rejects.toThrow("exit"); exit.mockRestore(); }); it("handles API error", async () => { mockApiRequest.mockRejectedValue(new Error("Forbidden")); const exit = vi.spyOn(process, "exit").mockImplementation(() => { throw new Error("exit"); }); await expect( orgRemoveCommand.parseAsync(["node", "remove", "acme", "bob"], { from: "node", }), ).rejects.toThrow("exit"); exit.mockRestore(); }); });