import { jest } from '@jest/globals'; import { HttpClient } from '../../dist/index.js'; import * as fetcher from '@cloudpss/fetch'; import { fetch, Response, FormData } from '@cloudpss/fetch'; describe('restful tunnel', () => { const mockFetch = jest.fn(fetch); const client = new HttpClient({ token: 'xx.yy.zz', altTokens: ['token1.x.y', 'token2.x.y'], apiTunnel: true, fetcher: { ...fetcher, fetch: mockFetch, }, }); const headers = { 'content-type': 'application/json' }; it('GET', async () => { const expectedResponse = { test: 'TEST' }; mockFetch.mockResolvedValueOnce(Response.json(expectedResponse, { headers })); const response = await client.restful('/xx?yy=zz'); expect(response.status).toEqual(200); expect(response.data).toEqual(expectedResponse); expect(mockFetch).toHaveBeenCalledWith( 'https://cloudpss.net/api/connect?yy=zz', expect.objectContaining({ method: 'POST', headers: expect.hasHeaders({ authorization: 'Bearer xx.yy.zz', 'x-authorization': 'Bearer token1.x.y, Bearer token2.x.y', 'x-http-method': 'GET', 'x-http-path': '/xx', }), }), ); }); it('POST', async () => { const requestData = { req: 'REQ' }; const expectedResponse = { test: 'TEST' }; mockFetch.mockResolvedValueOnce(Response.json(expectedResponse, { headers })); const response = await client.restful('http://xx.xx/test', requestData); expect(response.status).toEqual(200); expect(response.data).toEqual(expectedResponse); expect(mockFetch).toHaveBeenCalledWith( 'http://xx.xx/test', expect.objectContaining({ method: 'POST', headers: expect.hasHeaders({ authorization: 'Bearer xx.yy.zz', 'x-authorization': 'Bearer token1.x.y, Bearer token2.x.y', 'Content-Type': 'application/json;charset=utf-8', }), body: JSON.stringify(requestData), }), ); }); it('POST url', async () => { const requestData = new URLSearchParams('a=1&b=2'); const expectedResponse = new FormData(); mockFetch.mockResolvedValueOnce(new Response(expectedResponse, {})); const response = await client.restful('http://xx.xx/testurl', requestData); expect(response.status).toEqual(200); expect(response.data).toEqual(expectedResponse); expect(mockFetch).toHaveBeenCalledWith('http://xx.xx/testurl', { method: 'POST', headers: expect.hasHeaders({ authorization: 'Bearer xx.yy.zz', 'x-authorization': 'Bearer token1.x.y, Bearer token2.x.y', }), body: requestData, }); }); it('POST custom header', async () => { const requestData = { req: 'REQ' }; const expectedResponse = { test: 'TEST' }; mockFetch.mockResolvedValueOnce( Response.json(expectedResponse, { headers: { 'content-type': 'application/ld+json' } }), ); const response = await client.restful('/xx/?x=1&y=2', requestData, { headers: { 'content-type': 'application/x-json', 'x-custom': 'custom header', }, }); expect(response.status).toEqual(200); expect(response.data).toEqual(expectedResponse); expect(mockFetch).toHaveBeenCalledWith( 'https://cloudpss.net/api/connect?x=1&y=2', expect.objectContaining({ method: 'POST', headers: expect.hasHeaders({ authorization: 'Bearer xx.yy.zz', 'x-authorization': 'Bearer token1.x.y, Bearer token2.x.y', 'Content-Type': 'application/x-json', 'x-custom': 'custom header', 'x-http-method': 'POST', 'x-http-path': '/xx/', }), body: JSON.stringify(requestData), }), ); }); it('PUT', async () => { const requestData = { req: 'REQ' }; const expectedResponse = ''; mockFetch.mockResolvedValueOnce(new Response('', { status: 201, headers: { 'content-length': '0' } })); const response = await client.restful('http://xx.xx/test', requestData, { method: 'PUT' }); expect(response.status).toEqual(201); expect(response.data).toEqual(expectedResponse); expect(mockFetch).toHaveBeenCalledWith( 'http://xx.xx/test', expect.objectContaining({ method: 'PUT', headers: expect.hasHeaders({ authorization: 'Bearer xx.yy.zz', 'x-authorization': 'Bearer token1.x.y, Bearer token2.x.y', 'Content-Type': 'application/json;charset=utf-8', }), body: JSON.stringify(requestData), }), ); }); it('PUT buffer', async () => { const requestData = new Uint8Array(10); const expectedResponse = new Uint8Array(10); mockFetch.mockResolvedValueOnce(new Response(expectedResponse, { status: 201 })); const response = await client.restful('http://xx.xx/test', requestData, { method: 'PUT' }); expect(response.status).toEqual(201); expect(new Uint8Array(response.data as Uint8Array)).toEqual(expectedResponse); expect(mockFetch).toHaveBeenCalledWith('http://xx.xx/test', { method: 'PUT', headers: expect.hasHeaders({ authorization: 'Bearer xx.yy.zz', 'x-authorization': 'Bearer token1.x.y, Bearer token2.x.y', 'Content-Type': 'application/octet-stream', }), body: requestData, }); }); it('DELETE', async () => { const requestData = { req: 'REQ' }; const expectedResponse = undefined; mockFetch.mockResolvedValueOnce(new Response(undefined, { status: 204 })); const response = await client.restful('http://xx.xx/test', requestData, { method: 'DELETE' }); expect(response.status).toEqual(204); expect(response.data).toEqual(expectedResponse); expect(mockFetch).toHaveBeenCalledWith( 'http://xx.xx/test', expect.objectContaining({ method: 'DELETE', headers: expect.hasHeaders({ authorization: 'Bearer xx.yy.zz', 'x-authorization': 'Bearer token1.x.y, Bearer token2.x.y', 'Content-Type': 'application/json;charset=utf-8', }), body: JSON.stringify(requestData), }), ); }); it('DELETE string', async () => { const requestData = '{}'; const expectedResponse = undefined; mockFetch.mockResolvedValueOnce(new Response(undefined, { status: 204 })); const response = await client.restful('http://xx.xx/test', requestData, { method: 'DELETE', headers }); expect(response.status).toEqual(204); expect(response.data).toEqual(expectedResponse); expect(mockFetch).toHaveBeenCalledWith( 'http://xx.xx/test', expect.objectContaining({ method: 'DELETE', headers: expect.hasHeaders({ 'content-type': 'application/json', authorization: 'Bearer xx.yy.zz', 'x-authorization': 'Bearer token1.x.y, Bearer token2.x.y', }), body: requestData, }), ); }); it('DELETE form data', async () => { const requestData = new FormData(); globalThis.FormData = FormData; const expectedResponse = undefined; mockFetch.mockResolvedValueOnce(new Response(undefined, { status: 204 })); const response = await client.restful('http://xx.xx/test', requestData, { method: 'DELETE', headers }); expect(response.status).toEqual(204); expect(response.data).toEqual(expectedResponse); expect(mockFetch).toHaveBeenCalledWith( 'http://xx.xx/test', expect.objectContaining({ method: 'DELETE', headers: expect.hasHeaders({ 'content-type': 'application/json', authorization: 'Bearer xx.yy.zz', 'x-authorization': 'Bearer token1.x.y, Bearer token2.x.y', }), body: requestData, }), ); }); it('DELETE blob', async () => { const requestData = new Blob([]); globalThis.Blob = Blob; const expectedResponse = undefined; mockFetch.mockResolvedValueOnce(new Response(undefined, { status: 204 })); const response = await client.restful('/test', requestData, { method: 'DELETE' }); expect(response.status).toEqual(204); expect(response.data).toEqual(expectedResponse); expect(mockFetch).toHaveBeenCalledWith( 'https://cloudpss.net/api/connect', expect.objectContaining({ method: 'POST', headers: expect.hasHeaders({ 'content-type': 'application/octet-stream', authorization: 'Bearer xx.yy.zz', 'x-authorization': 'Bearer token1.x.y, Bearer token2.x.y', 'x-http-method': 'DELETE', 'x-http-path': '/test', }), body: requestData, }), ); }); });