UNPKG

@follow-app/client-sdk

Version:

TypeScript client SDK for Follow RSS Server API

245 lines (204 loc) 6.78 kB
import { beforeEach, describe, expect, it, vi } from "vitest" import { defineRoute } from "../shared/define-module" import { HttpClient } from "./base" // Mock fetch const mockFetch = vi.fn() global.fetch = mockFetch describe("Content Types Support", () => { let client: HttpClient beforeEach(() => { client = new HttpClient({ baseURL: "https://api.example.com", fetch: mockFetch, }) mockFetch.mockClear() }) describe("Request Types", () => { it("should handle JSON requests by default", async () => { mockFetch.mockResolvedValueOnce({ ok: true, headers: new Map([["content-type", "application/json"]]), json: async () => ({ code: 0, data: { result: "success" } }), }) await client.request("/test", { method: "POST", body: { test: "data" }, }) expect(mockFetch).toHaveBeenCalledWith( "https://api.example.com/test", expect.objectContaining({ method: "POST", headers: expect.objectContaining({ "Content-Type": "application/json", }), body: JSON.stringify({ test: "data" }), }), ) }) it("should handle FormData requests", async () => { mockFetch.mockResolvedValueOnce({ ok: true, headers: new Map([["content-type", "application/json"]]), json: async () => ({ code: 0, data: { result: "success" } }), }) const formData = new FormData() formData.append("file", new Blob(["test"]), "test.txt") await client.request("/upload", { method: "POST", body: formData, requestType: "formData", }) expect(mockFetch).toHaveBeenCalledWith( "https://api.example.com/upload", expect.objectContaining({ method: "POST", headers: expect.not.objectContaining({ "Content-Type": expect.any(String), }), body: formData, }), ) }) it("should handle object as FormData", async () => { mockFetch.mockResolvedValueOnce({ ok: true, headers: new Map([["content-type", "application/json"]]), json: async () => ({ code: 0, data: { result: "success" } }), }) await client.request("/upload", { method: "POST", body: { name: "test", value: "123" }, requestType: "formData", }) expect(mockFetch).toHaveBeenCalledWith( "https://api.example.com/upload", expect.objectContaining({ method: "POST", headers: expect.not.objectContaining({ "Content-Type": expect.any(String), }), body: expect.any(FormData), }), ) }) it("should handle text requests", async () => { mockFetch.mockResolvedValueOnce({ ok: true, headers: new Map([["content-type", "text/plain"]]), text: async () => "success", }) await client.request("/text", { method: "POST", body: "plain text content", requestType: "text", }) expect(mockFetch).toHaveBeenCalledWith( "https://api.example.com/text", expect.objectContaining({ method: "POST", headers: expect.objectContaining({ "Content-Type": "text/plain", }), body: "plain text content", }), ) }) }) describe("Response Types", () => { it("should handle JSON responses", async () => { mockFetch.mockResolvedValueOnce({ ok: true, headers: new Map([["content-type", "application/json"]]), json: async () => ({ code: 0, data: { result: "success" } }), }) const result = await client.request("/test") expect(result).toEqual({ code: 0, data: { result: "success" } }) }) it("should handle text responses", async () => { mockFetch.mockResolvedValueOnce({ ok: true, headers: new Map([["content-type", "text/plain"]]), text: async () => "plain text response", }) const result = await client.request("/text") expect(result).toBe("plain text response") }) it("should handle blob responses", async () => { const mockBlob = new Blob(["binary data"]) mockFetch.mockResolvedValueOnce({ ok: true, headers: new Map([["content-type", "image/png"]]), blob: async () => mockBlob, }) const result = await client.request("/image") expect(result).toBe(mockBlob) }) it("should handle event stream responses", async () => { const mockResponse = { ok: true, headers: new Map([["content-type", "text/event-stream"]]), body: new ReadableStream(), } mockFetch.mockResolvedValueOnce(mockResponse) const result = await client.request("/stream") expect(result).toBe(mockResponse) }) }) describe("defineRoute with requestType", () => { it("should define route with requestType", () => { const route = defineRoute<FormData, { ok: 1 }>("POST", "/upload", { requestType: "formData", }) expect(route).toEqual({ method: "POST", path: "/upload", params: undefined, input: undefined, response: undefined, requestType: "formData", }) }) it("should define route with both requestType and responseType", () => { const route = defineRoute<string, Blob>("POST", "/convert", { requestType: "text", }) expect(route).toEqual({ method: "POST", path: "/convert", params: undefined, input: undefined, response: undefined, requestType: "text", }) }) }) describe("Convenience methods", () => { it("should use postForm for form data", async () => { mockFetch.mockResolvedValueOnce({ ok: true, headers: new Map([["content-type", "application/json"]]), json: async () => ({ code: 0, data: { result: "success" } }), }) const formData = new FormData() formData.append("file", new Blob(["test"]), "test.txt") await client.postForm("/upload", formData) expect(mockFetch).toHaveBeenCalledWith( "https://api.example.com/upload", expect.objectContaining({ method: "POST", body: formData, }), ) }) it("should use getStream for event streams", async () => { const mockResponse = { ok: true, headers: new Map([["content-type", "text/event-stream"]]), body: new ReadableStream(), } mockFetch.mockResolvedValueOnce(mockResponse) const result = await client.getStream("/events") expect(result).toBe(mockResponse) }) }) })