Path: blob/main/src/vs/base/parts/request/test/electron-main/request.test.ts
4780 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import * as http from 'http';6import { AddressInfo } from 'net';7import assert from 'assert';8import { CancellationToken, CancellationTokenSource } from '../../../../common/cancellation.js';9import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../test/common/utils.js';10import { request } from '../../common/requestImpl.js';11import { streamToBuffer } from '../../../../common/buffer.js';12import { runWithFakedTimers } from '../../../../test/common/timeTravelScheduler.js';131415suite('Request', () => {1617let port: number;18let server: http.Server;1920setup(async () => {21port = await new Promise<number>((resolvePort, rejectPort) => {22server = http.createServer((req, res) => {23if (req.url === '/noreply') {24return; // never respond25}26res.setHeader('Content-Type', 'application/json');27if (req.headers['echo-header']) {28res.setHeader('echo-header', req.headers['echo-header']);29}30const data: Buffer[] = [];31req.on('data', chunk => data.push(chunk));32req.on('end', () => {33res.end(JSON.stringify({34method: req.method,35url: req.url,36data: Buffer.concat(data).toString()37}));38});39}).listen(0, '127.0.0.1', () => {40const address = server.address();41resolvePort((address as AddressInfo).port);42}).on('error', err => {43rejectPort(err);44});45});46});4748teardown(async () => {49await new Promise<void>((resolve, reject) => {50server.close(err => err ? reject(err) : resolve());51});52});5354test('GET', async () => {55const context = await request({56url: `http://127.0.0.1:${port}`,57headers: {58'echo-header': 'echo-value'59}60}, CancellationToken.None);61assert.strictEqual(context.res.statusCode, 200);62assert.strictEqual(context.res.headers['content-type'], 'application/json');63assert.strictEqual(context.res.headers['echo-header'], 'echo-value');64const buffer = await streamToBuffer(context.stream);65const body = JSON.parse(buffer.toString());66assert.strictEqual(body.method, 'GET');67assert.strictEqual(body.url, '/');68});6970test('POST', async () => {71const context = await request({72type: 'POST',73url: `http://127.0.0.1:${port}/postpath`,74data: 'Some data',75}, CancellationToken.None);76assert.strictEqual(context.res.statusCode, 200);77assert.strictEqual(context.res.headers['content-type'], 'application/json');78const buffer = await streamToBuffer(context.stream);79const body = JSON.parse(buffer.toString());80assert.strictEqual(body.method, 'POST');81assert.strictEqual(body.url, '/postpath');82assert.strictEqual(body.data, 'Some data');83});8485test('timeout', async () => {86return runWithFakedTimers({}, async () => {87try {88await request({89type: 'GET',90url: `http://127.0.0.1:${port}/noreply`,91timeout: 123,92}, CancellationToken.None);93assert.fail('Should fail with timeout');94} catch (err) {95assert.strictEqual(err.message, 'Fetch timeout: 123ms');96}97});98});99100test('cancel', async () => {101return runWithFakedTimers({}, async () => {102try {103const source = new CancellationTokenSource();104const res = request({105type: 'GET',106url: `http://127.0.0.1:${port}/noreply`,107}, source.token);108await new Promise(resolve => setTimeout(resolve, 100));109source.cancel();110await res;111assert.fail('Should fail with cancellation');112} catch (err) {113assert.strictEqual(err.message, 'Canceled');114}115});116});117118ensureNoDisposablesAreLeakedInTestSuite();119});120121122