import { describe, it, expect, vi, beforeEach } from "vitest";
import * as client from "./client";
import {
  fetchUserWorkspaces,
  fetchWorkspaceMembers,
  addWorkspaceMember,
  updateWorkspaceMemberRole,
  removeWorkspaceMember,
} from "./workspaces";

vi.mock("./client");

beforeEach((): void => {
  vi.clearAllMocks();
});

describe("fetchUserWorkspaces", (): void => {
  it("calls correct endpoint", async (): Promise<void> => {
    vi.mocked(client.apiGet).mockResolvedValueOnce([] as never);
    await fetchUserWorkspaces();
    expect(client.apiGet).toHaveBeenCalledWith("/api/workspaces");
  });
});

describe("fetchWorkspaceMembers", (): void => {
  it("calls correct endpoint with workspace id", async (): Promise<void> => {
    vi.mocked(client.apiGet).mockResolvedValueOnce([] as never);
    await fetchWorkspaceMembers("ws-1");
    expect(client.apiGet).toHaveBeenCalledWith("/api/workspaces/ws-1/members");
  });

  it("throws on error", async (): Promise<void> => {
    vi.mocked(client.apiGet).mockRejectedValueOnce(new Error("Forbidden"));
    await expect(fetchWorkspaceMembers("ws-1")).rejects.toThrow("Forbidden");
  });
});

describe("addWorkspaceMember", (): void => {
  it("posts to correct endpoint", async (): Promise<void> => {
    vi.mocked(client.apiPost).mockResolvedValueOnce({} as never);
    await addWorkspaceMember("ws-1", { userId: "u1", role: "MEMBER" as never });
    expect(client.apiPost).toHaveBeenCalledWith("/api/workspaces/ws-1/members", {
      userId: "u1",
      role: "MEMBER",
    });
  });
});

describe("updateWorkspaceMemberRole", (): void => {
  it("patches correct endpoint", async (): Promise<void> => {
    vi.mocked(client.apiPatch).mockResolvedValueOnce({} as never);
    await updateWorkspaceMemberRole("ws-1", "u1", { role: "ADMIN" as never });
    expect(client.apiPatch).toHaveBeenCalledWith("/api/workspaces/ws-1/members/u1", {
      role: "ADMIN",
    });
  });
});

describe("removeWorkspaceMember", (): void => {
  it("calls delete on correct endpoint", async (): Promise<void> => {
    vi.mocked(client.apiDelete).mockResolvedValueOnce(undefined as never);
    await removeWorkspaceMember("ws-1", "u1");
    expect(client.apiDelete).toHaveBeenCalledWith("/api/workspaces/ws-1/members/u1");
  });
});
