import { http, HttpResponse } from 'msw'; import { Cookie, CookieJar } from 'tough-cookie'; import { describe, expect, it, vi } from 'vitest'; import { config } from '@/config'; import got from '@/utils/got'; describe('got', () => { it('no ua headers', async () => { const { data } = await got('http://rsshub.test/headers'); expect(data['user-agent']).toBeUndefined(); }); it('retry', async () => { const requestRun = vi.fn(); const { default: server } = await import('@/setup.test'); server.use( http.get(`http://rsshub.test/retry-test`, () => { requestRun(); return HttpResponse.error(); }) ); try { await got.get('http://rsshub.test/retry-test'); } catch (error: any) { expect(error.name).toBe('FetchError'); } // retries expect(requestRun).toHaveBeenCalledTimes(config.requestRetry + 1); }); it('form-post', async () => { const response = await got.post('http://rsshub.test/form-post', { form: { test: 'rsshub', }, }); expect(response.body).toContain('"test":"rsshub"'); expect(response.data.test).toBe('rsshub'); expect(response.data.req.headers['content-type']).toBe('application/x-www-form-urlencoded'); }); it('json-post', async () => { const response = await got.post('http://rsshub.test/json-post', { json: { test: 'rsshub', }, }); expect(response.body).toBe('{"test":"rsshub"}'); expect(response.data.test).toBe('rsshub'); }); it('buffer-get', async () => { const response = await got.get('http://rsshub.test/headers', { responseType: 'buffer', }); expect(response.body instanceof Buffer).toBe(true); expect(response.data instanceof Buffer).toBe(true); }); it('cookieJar', async () => { const cookieJar = new CookieJar(); const cookie = Cookie.fromJSON({ key: 'cookie', value: 'test', domain: 'rsshub.test', path: '/', }); cookie && cookieJar.setCookie(cookie, 'http://rsshub.test'); const { data } = await got.get('http://rsshub.test/headers', { cookieJar, }); expect(data.cookie).toBe('cookie=test; Domain=rsshub.test; Path=/'); }); it('runs beforeRequest hooks', async () => { const hook = vi.fn((options) => { options.headers = { ...options.headers, 'x-before-request': '1', }; }); const { data } = await got('http://rsshub.test/headers', { hooks: { beforeRequest: [hook], }, }); expect(hook).toHaveBeenCalledTimes(1); expect(data['x-before-request']).toBe('1'); }); it('appends search params', async () => { const { default: server } = await import('@/setup.test'); server.use( http.get('http://rsshub.test/query', ({ request }) => { const url = new URL(request.url); return HttpResponse.json({ query: Object.fromEntries(url.searchParams.entries()), }); }) ); const { data } = await got('http://rsshub.test/query', { searchParams: { foo: 'bar', baz: 'qux', }, }); expect(data.query).toEqual({ foo: 'bar', baz: 'qux', }); }); it('supports additional http verbs and extend', async () => { const { default: server } = await import('@/setup.test'); server.use( http.all('http://rsshub.test/method', ({ request }) => HttpResponse.json({ method: request.method, }) ) ); const putResponse = await got.put('http://rsshub.test/method'); expect(putResponse.data.method).toBe('PUT'); const patchResponse = await got.patch('http://rsshub.test/method'); expect(patchResponse.data.method).toBe('PATCH'); const deleteResponse = await got.delete('http://rsshub.test/method'); expect(deleteResponse.data.method).toBe('DELETE'); const headResponse = await got.head('http://rsshub.test/method', { responseType: 'text', }); expect(headResponse).toBeUndefined(); const extended = got.extend({ headers: { 'x-extended': '1', }, }); const extendedResponse = await extended.get('http://rsshub.test/headers'); expect(extendedResponse.data['x-extended']).toBe('1'); }); });