import { describe, expect, it, vi } from "@stencil/vitest";
import { Micro as Effect } from "effect";
import { FetchError, NotFoundError, ResponseTextError, httpClient, responseAsText } from "./http";
describe('Http Utils', () => {
    describe('httpClient', () => {
        it('should return response on successful fetch', async () => {
            const mockResponse = { status: 200, url: 'https://example.com' };
            globalThis.fetch = vi.fn().mockResolvedValueOnce(mockResponse);
            const result = await Effect.runPromise(httpClient('https://example.com'));
            expect(result).toEqual(mockResponse);
        });
        it('should handle fetch errors', async () => {
            const error = new Error('Network error');
            globalThis.fetch = vi.fn().mockRejectedValueOnce(error);
            const result = await Effect.runPromise(Effect.flip(httpClient('https://example.com')));
            expect(result).toBeInstanceOf(FetchError);
            expect(result.cause).toBe(error);
        });
        it('should return NotFoundError on 404 status', async () => {
            const mockResponse = { status: 404, url: 'https://example.com/notfound' };
            globalThis.fetch = vi.fn().mockResolvedValueOnce(mockResponse);
            const result = await Effect.runPromise(Effect.flip(httpClient('https://example.com/notfound')));
            expect(result).toBeInstanceOf(NotFoundError);
        });
        it('should pass RequestInit options to fetch', async () => {
            const mockResponse = { status: 200, url: 'https://example.com' };
            globalThis.fetch = vi.fn().mockResolvedValueOnce(mockResponse);
            const init = { method: 'POST', headers: { 'Content-Type': 'application/json' } };
            await Effect.runPromise(httpClient('https://example.com', init));
            expect(globalThis.fetch).toHaveBeenCalledWith('https://example.com', init);
        });
    });
    describe('responseAsText', () => {
        it('should return text from response', async () => {
            const mockResponse = { text: vi.fn().mockResolvedValueOnce('Hello World') };
            const result = await Effect.runPromise(responseAsText(mockResponse));
            expect(result).toBe('Hello World');
        });
        it('should handle text reading errors', async () => {
            const error = new Error('Read error');
            const mockResponse = { text: vi.fn().mockRejectedValueOnce(error) };
            const result = await Effect.runPromise(Effect.flip(responseAsText(mockResponse)));
            expect(result).toBeInstanceOf(ResponseTextError);
            expect(result.message).toContain('Failed to read response text');
        });
    });
});
