cloudflare/cloudflare-typescript

Public

mirrored from https://github.com/cloudflare/cloudflare-typescriptAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
generated-ffa4e09d02

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

tests/index.test.ts

351lines · modeblame

2d51afdcstainless-app[bot]2 years ago1// File generated from our OpenAPI spec by Stainless.
2
3import Cloudflare from 'cloudflare';
4import { APIUserAbortError } from 'cloudflare';
5import { Headers } from 'cloudflare/core';
6import defaultFetch, { Response, type RequestInit, type RequestInfo } from 'node-fetch';
7
8describe('instantiate client', () => {
9const env = process.env;
10
11beforeEach(() => {
12jest.resetModules();
13process.env = { ...env };
14
15console.warn = jest.fn();
16});
17
18afterEach(() => {
19process.env = env;
20});
21
22describe('defaultHeaders', () => {
23const client = new Cloudflare({
24baseURL: 'http://localhost:5000/',
25defaultHeaders: { 'X-My-Default-Header': '2' },
71186a55stainless-app[bot]2 years ago26apiKey: '144c9defac04969c7bfad8efaa8ea194',
27apiEmail: 'user@example.com',
2d51afdcstainless-app[bot]2 years ago28});
29
30test('they are used in the request', () => {
31const { req } = client.buildRequest({ path: '/foo', method: 'post' });
32expect((req.headers as Headers)['x-my-default-header']).toEqual('2');
33});
34
35test('can ignore `undefined` and leave the default', () => {
36const { req } = client.buildRequest({
37path: '/foo',
38method: 'post',
39headers: { 'X-My-Default-Header': undefined },
40});
41expect((req.headers as Headers)['x-my-default-header']).toEqual('2');
42});
43
44test('can be removed with `null`', () => {
45const { req } = client.buildRequest({
46path: '/foo',
47method: 'post',
48headers: { 'X-My-Default-Header': null },
49});
50expect(req.headers as Headers).not.toHaveProperty('x-my-default-header');
51});
52});
53
54describe('defaultQuery', () => {
55test('with null query params given', () => {
56const client = new Cloudflare({
57baseURL: 'http://localhost:5000/',
58defaultQuery: { apiVersion: 'foo' },
71186a55stainless-app[bot]2 years ago59apiKey: '144c9defac04969c7bfad8efaa8ea194',
60apiEmail: 'user@example.com',
2d51afdcstainless-app[bot]2 years ago61});
62expect(client.buildURL('/foo', null)).toEqual('http://localhost:5000/foo?apiVersion=foo');
63});
64
65test('multiple default query params', () => {
66const client = new Cloudflare({
67baseURL: 'http://localhost:5000/',
68defaultQuery: { apiVersion: 'foo', hello: 'world' },
71186a55stainless-app[bot]2 years ago69apiKey: '144c9defac04969c7bfad8efaa8ea194',
70apiEmail: 'user@example.com',
2d51afdcstainless-app[bot]2 years ago71});
72expect(client.buildURL('/foo', null)).toEqual('http://localhost:5000/foo?apiVersion=foo&hello=world');
73});
74
75test('overriding with `undefined`', () => {
71186a55stainless-app[bot]2 years ago76const client = new Cloudflare({
77baseURL: 'http://localhost:5000/',
78defaultQuery: { hello: 'world' },
79apiKey: '144c9defac04969c7bfad8efaa8ea194',
80apiEmail: 'user@example.com',
81});
2d51afdcstainless-app[bot]2 years ago82expect(client.buildURL('/foo', { hello: undefined })).toEqual('http://localhost:5000/foo');
83});
84});
85
86test('custom fetch', async () => {
87const client = new Cloudflare({
88baseURL: 'http://localhost:5000/',
71186a55stainless-app[bot]2 years ago89apiKey: '144c9defac04969c7bfad8efaa8ea194',
90apiEmail: 'user@example.com',
2d51afdcstainless-app[bot]2 years ago91fetch: (url) => {
92return Promise.resolve(
93new Response(JSON.stringify({ url, custom: true }), {
94headers: { 'Content-Type': 'application/json' },
95}),
96);
97},
98});
99
100const response = await client.get('/foo');
101expect(response).toEqual({ url: 'http://localhost:5000/foo', custom: true });
102});
103
104test('custom signal', async () => {
105const client = new Cloudflare({
106baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
71186a55stainless-app[bot]2 years ago107apiKey: '144c9defac04969c7bfad8efaa8ea194',
108apiEmail: 'user@example.com',
2d51afdcstainless-app[bot]2 years ago109fetch: (...args) => {
110return new Promise((resolve, reject) =>
111setTimeout(
112() =>
113defaultFetch(...args)
114.then(resolve)
115.catch(reject),
116300,
117),
118);
119},
120});
121
122const controller = new AbortController();
123setTimeout(() => controller.abort(), 200);
124
125const spy = jest.spyOn(client, 'request');
126
127await expect(client.get('/foo', { signal: controller.signal })).rejects.toThrowError(APIUserAbortError);
128expect(spy).toHaveBeenCalledTimes(1);
129});
130
131describe('baseUrl', () => {
132test('trailing slash', () => {
71186a55stainless-app[bot]2 years ago133const client = new Cloudflare({
134baseURL: 'http://localhost:5000/custom/path/',
135apiKey: '144c9defac04969c7bfad8efaa8ea194',
136apiEmail: 'user@example.com',
137});
2d51afdcstainless-app[bot]2 years ago138expect(client.buildURL('/foo', null)).toEqual('http://localhost:5000/custom/path/foo');
139});
140
141test('no trailing slash', () => {
71186a55stainless-app[bot]2 years ago142const client = new Cloudflare({
143baseURL: 'http://localhost:5000/custom/path',
144apiKey: '144c9defac04969c7bfad8efaa8ea194',
145apiEmail: 'user@example.com',
146});
2d51afdcstainless-app[bot]2 years ago147expect(client.buildURL('/foo', null)).toEqual('http://localhost:5000/custom/path/foo');
148});
149
150afterEach(() => {
151process.env['CLOUDFLARE_BASE_URL'] = undefined;
152});
153
154test('explicit option', () => {
71186a55stainless-app[bot]2 years ago155const client = new Cloudflare({
156baseURL: 'https://example.com',
157apiKey: '144c9defac04969c7bfad8efaa8ea194',
158apiEmail: 'user@example.com',
159});
2d51afdcstainless-app[bot]2 years ago160expect(client.baseURL).toEqual('https://example.com');
161});
162
163test('env variable', () => {
164process.env['CLOUDFLARE_BASE_URL'] = 'https://example.com/from_env';
71186a55stainless-app[bot]2 years ago165const client = new Cloudflare({
166apiKey: '144c9defac04969c7bfad8efaa8ea194',
167apiEmail: 'user@example.com',
168});
2d51afdcstainless-app[bot]2 years ago169expect(client.baseURL).toEqual('https://example.com/from_env');
170});
171
172test('empty env variable', () => {
173process.env['CLOUDFLARE_BASE_URL'] = ''; // empty
71186a55stainless-app[bot]2 years ago174const client = new Cloudflare({
175apiKey: '144c9defac04969c7bfad8efaa8ea194',
176apiEmail: 'user@example.com',
177});
2d51afdcstainless-app[bot]2 years ago178expect(client.baseURL).toEqual('https://api.cloudflare.com/client/v4');
179});
180
181test('blank env variable', () => {
182process.env['CLOUDFLARE_BASE_URL'] = ' '; // blank
71186a55stainless-app[bot]2 years ago183const client = new Cloudflare({
184apiKey: '144c9defac04969c7bfad8efaa8ea194',
185apiEmail: 'user@example.com',
186});
2d51afdcstainless-app[bot]2 years ago187expect(client.baseURL).toEqual('https://api.cloudflare.com/client/v4');
188});
189});
190
191test('maxRetries option is correctly set', () => {
71186a55stainless-app[bot]2 years ago192const client = new Cloudflare({
193maxRetries: 4,
194apiKey: '144c9defac04969c7bfad8efaa8ea194',
195apiEmail: 'user@example.com',
196});
2d51afdcstainless-app[bot]2 years ago197expect(client.maxRetries).toEqual(4);
198
199// default
71186a55stainless-app[bot]2 years ago200const client2 = new Cloudflare({
201apiKey: '144c9defac04969c7bfad8efaa8ea194',
202apiEmail: 'user@example.com',
203});
2d51afdcstainless-app[bot]2 years ago204expect(client2.maxRetries).toEqual(2);
205});
71186a55stainless-app[bot]2 years ago206
207test('with environment variable arguments', () => {
208// set options via env var
209process.env['CLOUDFLARE_API_KEY'] = '144c9defac04969c7bfad8efaa8ea194';
210process.env['CLOUDFLARE_EMAIL'] = 'user@example.com';
211const client = new Cloudflare();
212expect(client.apiKey).toBe('144c9defac04969c7bfad8efaa8ea194');
213expect(client.apiEmail).toBe('user@example.com');
214});
215
216test('with overriden environment variable arguments', () => {
217// set options via env var
218process.env['CLOUDFLARE_API_KEY'] = 'another 144c9defac04969c7bfad8efaa8ea194';
219process.env['CLOUDFLARE_EMAIL'] = 'another user@example.com';
220const client = new Cloudflare({
221apiKey: '144c9defac04969c7bfad8efaa8ea194',
222apiEmail: 'user@example.com',
223});
224expect(client.apiKey).toBe('144c9defac04969c7bfad8efaa8ea194');
225expect(client.apiEmail).toBe('user@example.com');
226});
2d51afdcstainless-app[bot]2 years ago227});
228
229describe('request building', () => {
71186a55stainless-app[bot]2 years ago230const client = new Cloudflare({ apiKey: '144c9defac04969c7bfad8efaa8ea194', apiEmail: 'user@example.com' });
2d51afdcstainless-app[bot]2 years ago231
232describe('Content-Length', () => {
233test('handles multi-byte characters', () => {
234const { req } = client.buildRequest({ path: '/foo', method: 'post', body: { value: '—' } });
235expect((req.headers as Record<string, string>)['content-length']).toEqual('20');
236});
237
238test('handles standard characters', () => {
239const { req } = client.buildRequest({ path: '/foo', method: 'post', body: { value: 'hello' } });
240expect((req.headers as Record<string, string>)['content-length']).toEqual('22');
241});
242});
243
244describe('custom headers', () => {
245test('handles undefined', () => {
246const { req } = client.buildRequest({
247path: '/foo',
248method: 'post',
249body: { value: 'hello' },
250headers: { 'X-Foo': 'baz', 'x-foo': 'bar', 'x-Foo': undefined, 'x-baz': 'bam', 'X-Baz': null },
251});
252expect((req.headers as Record<string, string>)['x-foo']).toEqual('bar');
253expect((req.headers as Record<string, string>)['x-Foo']).toEqual(undefined);
254expect((req.headers as Record<string, string>)['X-Foo']).toEqual(undefined);
255expect((req.headers as Record<string, string>)['x-baz']).toEqual(undefined);
256});
257});
258});
259
260describe('retries', () => {
261test('retry on timeout', async () => {
262let count = 0;
263const testFetch = async (url: RequestInfo, { signal }: RequestInit = {}): Promise<Response> => {
264if (count++ === 0) {
265return new Promise(
266(resolve, reject) => signal?.addEventListener('abort', () => reject(new Error('timed out'))),
267);
268}
269return new Response(JSON.stringify({ a: 1 }), { headers: { 'Content-Type': 'application/json' } });
270};
271
71186a55stainless-app[bot]2 years ago272const client = new Cloudflare({
273apiKey: '144c9defac04969c7bfad8efaa8ea194',
274apiEmail: 'user@example.com',
275timeout: 10,
276fetch: testFetch,
277});
2d51afdcstainless-app[bot]2 years ago278
279expect(await client.request({ path: '/foo', method: 'get' })).toEqual({ a: 1 });
280expect(count).toEqual(2);
281expect(
282await client
283.request({ path: '/foo', method: 'get' })
284.asResponse()
285.then((r) => r.text()),
286).toEqual(JSON.stringify({ a: 1 }));
287expect(count).toEqual(3);
288});
289
290test('retry on 429 with retry-after', async () => {
291let count = 0;
292const testFetch = async (url: RequestInfo, { signal }: RequestInit = {}): Promise<Response> => {
293if (count++ === 0) {
294return new Response(undefined, {
295status: 429,
296headers: {
297'Retry-After': '0.1',
298},
299});
300}
301return new Response(JSON.stringify({ a: 1 }), { headers: { 'Content-Type': 'application/json' } });
302};
303
71186a55stainless-app[bot]2 years ago304const client = new Cloudflare({
305apiKey: '144c9defac04969c7bfad8efaa8ea194',
306apiEmail: 'user@example.com',
307fetch: testFetch,
308});
2d51afdcstainless-app[bot]2 years ago309
310expect(await client.request({ path: '/foo', method: 'get' })).toEqual({ a: 1 });
311expect(count).toEqual(2);
312expect(
313await client
314.request({ path: '/foo', method: 'get' })
315.asResponse()
316.then((r) => r.text()),
317).toEqual(JSON.stringify({ a: 1 }));
318expect(count).toEqual(3);
319});
320
321test('retry on 429 with retry-after-ms', async () => {
322let count = 0;
323const testFetch = async (url: RequestInfo, { signal }: RequestInit = {}): Promise<Response> => {
324if (count++ === 0) {
325return new Response(undefined, {
326status: 429,
327headers: {
328'Retry-After-Ms': '10',
329},
330});
331}
332return new Response(JSON.stringify({ a: 1 }), { headers: { 'Content-Type': 'application/json' } });
333};
334
71186a55stainless-app[bot]2 years ago335const client = new Cloudflare({
336apiKey: '144c9defac04969c7bfad8efaa8ea194',
337apiEmail: 'user@example.com',
338fetch: testFetch,
339});
2d51afdcstainless-app[bot]2 years ago340
341expect(await client.request({ path: '/foo', method: 'get' })).toEqual({ a: 1 });
342expect(count).toEqual(2);
343expect(
344await client
345.request({ path: '/foo', method: 'get' })
346.asResponse()
347.then((r) => r.text()),
348).toEqual(JSON.stringify({ a: 1 }));
349expect(count).toEqual(3);
350});
351});