Download __tests__/api/cloud/organization-service.test.ts from SaylorTwift/openhands: direct link, hf CLI and curl.
- Browser
- Download file 4.14 kB
-
https://huggingface.co/SaylorTwift/openhands/resolve/main/__tests__/api/cloud/organization-service.test.ts
- Command line
-
hf download hf://SaylorTwift/openhands/__tests__/api/cloud/organization-service.test.ts
-
curl -L -o organization-service.test.ts https://huggingface.co/SaylorTwift/openhands/resolve/main/__tests__/api/cloud/organization-service.test.ts
4.14 kB
| import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; | |
| import { HttpError } from "@openhands/typescript-client"; | |
| import { | |
| __resetActiveStoreForTests, | |
| setRegisteredBackends, | |
| } from "#/api/backend-registry/active-store"; | |
| import { | |
| getCloudOrganizationMember, | |
| getCloudOrganizations, | |
| getCurrentCloudApiKey, | |
| } from "#/api/cloud/organization-service.api"; | |
| import type { Backend } from "#/api/backend-registry/types"; | |
| const cloudBackend: Backend = { | |
| id: "prod", | |
| name: "Production", | |
| host: "https://app.all-hands.dev", | |
| apiKey: "bearer-token", | |
| kind: "cloud", | |
| }; | |
| const originalFetch = global.fetch; | |
| const fetchMock = vi.fn(); | |
| function mockJsonResponse(data: unknown, status = 200): Response { | |
| return new Response(JSON.stringify(data), { | |
| status, | |
| statusText: status === 200 ? "OK" : "Error", | |
| headers: { "content-type": "application/json" }, | |
| }); | |
| } | |
| beforeEach(() => { | |
| window.localStorage.clear(); | |
| __resetActiveStoreForTests(); | |
| setRegisteredBackends([]); | |
| fetchMock.mockReset(); | |
| global.fetch = fetchMock as typeof fetch; | |
| }); | |
| afterEach(() => { | |
| window.localStorage.clear(); | |
| __resetActiveStoreForTests(); | |
| fetchMock.mockReset(); | |
| global.fetch = originalFetch; | |
| }); | |
| describe("cloud organization-service", () => { | |
| it("getCloudOrganizations calls the cloud API directly and returns normalized data", async () => { | |
| fetchMock.mockResolvedValueOnce( | |
| mockJsonResponse({ | |
| items: [{ id: "org-1", name: "Personal" }], | |
| current_org_id: "org-1", | |
| }), | |
| ); | |
| const result = await getCloudOrganizations(cloudBackend); | |
| expect(fetchMock).toHaveBeenCalledOnce(); | |
| const [url, init] = fetchMock.mock.calls[0]!; | |
| expect(url).toBe(`${cloudBackend.host}/api/organizations`); | |
| expect(init).toMatchObject({ | |
| method: "GET", | |
| headers: { Authorization: "Bearer bearer-token" }, | |
| }); | |
| expect(result).toEqual({ | |
| items: [{ id: "org-1", name: "Personal" }], | |
| currentOrgId: "org-1", | |
| }); | |
| }); | |
| it("getCurrentCloudApiKey hits /api/keys/current and returns the bound orgId", async () => { | |
| fetchMock.mockResolvedValueOnce( | |
| mockJsonResponse({ | |
| id: "key-1", | |
| name: "k", | |
| org_id: "org-bound", | |
| user_id: "user-1", | |
| auth_type: "bearer", | |
| }), | |
| ); | |
| const result = await getCurrentCloudApiKey(cloudBackend); | |
| const [url, init] = fetchMock.mock.calls[0]!; | |
| expect(url).toBe(`${cloudBackend.host}/api/keys/current`); | |
| expect(init).toMatchObject({ | |
| method: "GET", | |
| headers: { Authorization: "Bearer bearer-token" }, | |
| }); | |
| expect(result).toEqual({ orgId: "org-bound", isLegacyKey: false }); | |
| }); | |
| it("getCurrentCloudApiKey treats an upstream 400 as a legacy key (no binding)", async () => { | |
| fetchMock.mockResolvedValueOnce(mockJsonResponse({ detail: "bad" }, 400)); | |
| const result = await getCurrentCloudApiKey(cloudBackend); | |
| expect(result).toEqual({ orgId: null, isLegacyKey: true }); | |
| }); | |
| it("getCurrentCloudApiKey rethrows non-400 upstream errors (e.g. revoked key)", async () => { | |
| fetchMock.mockResolvedValueOnce( | |
| mockJsonResponse({ detail: "unauthorized" }, 401), | |
| ); | |
| await expect(getCurrentCloudApiKey(cloudBackend)).rejects.toBeInstanceOf( | |
| HttpError, | |
| ); | |
| }); | |
| it("getCloudOrganizationMember hits /api/organizations/{orgId}/members/{userId} and returns the member", async () => { | |
| // Arrange | |
| const member = { | |
| org_id: "org-1", | |
| user_id: "user-1", | |
| email: "jdoe@acme.com", | |
| role: "member", | |
| status: "active", | |
| }; | |
| fetchMock.mockResolvedValueOnce(mockJsonResponse(member)); | |
| // Act | |
| const result = await getCloudOrganizationMember( | |
| "org-1", | |
| "user-1", | |
| cloudBackend, | |
| ); | |
| // Assert | |
| expect(fetchMock).toHaveBeenCalledOnce(); | |
| const [url, init] = fetchMock.mock.calls[0]!; | |
| expect(url).toBe( | |
| `${cloudBackend.host}/api/organizations/org-1/members/user-1`, | |
| ); | |
| expect(init).toMatchObject({ | |
| method: "GET", | |
| headers: { Authorization: "Bearer bearer-token" }, | |
| }); | |
| expect(result).toEqual(member); | |
| }); | |
| }); | |