fork of hey-api/openapi-ts because I need some additional things

fix: add getSpec tests and apply same fix to openapi-python

Co-authored-by: mrlubos <12529395+mrlubos@users.noreply.github.com>

+107 -1
+4 -1
packages/openapi-python/src/createClient.ts
··· 66 66 // if in watch mode, subsequent errors won't throw to gracefully handle 67 67 // cases where server might be reloading 68 68 if (error && !_watches) { 69 - throw new Error(`Request failed with status ${response.status}: ${response.statusText}`); 69 + const text = await response.text().catch(() => ''); 70 + throw new Error( 71 + `Request failed with status ${response.status}: ${text || response.statusText}`, 72 + ); 70 73 } 71 74 72 75 return { arrayBuffer, resolvedInput };
+103
packages/shared/src/__tests__/getSpec.test.ts
··· 1 + import * as refParser from '@hey-api/json-schema-ref-parser'; 2 + 3 + import { getSpec } from '../getSpec'; 4 + 5 + vi.mock('@hey-api/json-schema-ref-parser', () => ({ 6 + getResolvedInput: vi.fn(({ pathOrUrlOrSchema }: { pathOrUrlOrSchema: string }) => ({ 7 + path: pathOrUrlOrSchema, 8 + schema: undefined, 9 + type: 'url', 10 + })), 11 + sendRequest: vi.fn(), 12 + })); 13 + 14 + const mockSendRequest = vi.mocked(refParser.sendRequest); 15 + 16 + describe('getSpec', () => { 17 + beforeEach(() => { 18 + vi.clearAllMocks(); 19 + }); 20 + 21 + describe('URL input', () => { 22 + it('returns error with status 500 and error message when GET request throws an exception', async () => { 23 + mockSendRequest.mockRejectedValueOnce(new Error('fetch failed')); 24 + 25 + const result = await getSpec({ 26 + fetchOptions: undefined, 27 + inputPath: 'http://example.com/openapi.json', 28 + timeout: undefined, 29 + watch: { headers: new Headers() }, 30 + }); 31 + 32 + expect(result.error).toBe('not-ok'); 33 + expect(result.response!.status).toBe(500); 34 + expect(await result.response!.text()).toBe('fetch failed'); 35 + }); 36 + 37 + it('returns error with status 500 and string message when non-Error is thrown during GET request', async () => { 38 + mockSendRequest.mockRejectedValueOnce('network unavailable'); 39 + 40 + const result = await getSpec({ 41 + fetchOptions: undefined, 42 + inputPath: 'http://example.com/openapi.json', 43 + timeout: undefined, 44 + watch: { headers: new Headers() }, 45 + }); 46 + 47 + expect(result.error).toBe('not-ok'); 48 + expect(result.response!.status).toBe(500); 49 + expect(await result.response!.text()).toBe('network unavailable'); 50 + }); 51 + 52 + it('returns error when GET response has status >= 300', async () => { 53 + mockSendRequest.mockResolvedValueOnce({ 54 + response: new Response(null, { status: 404, statusText: 'Not Found' }), 55 + }); 56 + 57 + const result = await getSpec({ 58 + fetchOptions: undefined, 59 + inputPath: 'http://example.com/openapi.json', 60 + timeout: undefined, 61 + watch: { headers: new Headers() }, 62 + }); 63 + 64 + expect(result.error).toBe('not-ok'); 65 + expect(result.response!.status).toBe(404); 66 + }); 67 + 68 + it('returns error with status 500 and error message when HEAD request throws an exception', async () => { 69 + mockSendRequest.mockRejectedValueOnce(new Error('connection refused')); 70 + 71 + const result = await getSpec({ 72 + fetchOptions: undefined, 73 + inputPath: 'http://example.com/openapi.json', 74 + timeout: undefined, 75 + watch: { headers: new Headers(), isHeadMethodSupported: true, lastValue: 'previous' }, 76 + }); 77 + 78 + expect(result.error).toBe('not-ok'); 79 + expect(result.response!.status).toBe(500); 80 + expect(await result.response!.text()).toBe('connection refused'); 81 + }); 82 + 83 + it('returns arrayBuffer on successful GET', async () => { 84 + const content = '{"openapi":"3.0.0"}'; 85 + const encoder = new TextEncoder(); 86 + const buffer = encoder.encode(content).buffer as ArrayBuffer; 87 + 88 + mockSendRequest.mockResolvedValueOnce({ 89 + response: new Response(buffer, { status: 200 }), 90 + }); 91 + 92 + const result = await getSpec({ 93 + fetchOptions: undefined, 94 + inputPath: 'http://example.com/openapi.json', 95 + timeout: undefined, 96 + watch: { headers: new Headers() }, 97 + }); 98 + 99 + expect(result.error).toBeUndefined(); 100 + expect(result.arrayBuffer).toBeDefined(); 101 + }); 102 + }); 103 + });