diff --git a/.all-contributorsrc b/.all-contributorsrc
index a1af349..691f526 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -41,7 +41,7 @@
],
"contributorsPerLine": 7,
"projectName": "httpie",
- "projectOwner": "MyUnisoft",
+ "projectOwner": "OpenAlly",
"repoType": "github",
"repoHost": "https://github.com",
"skipCi": true,
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index d4abe09..8b7deb1 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -4,6 +4,8 @@ updates:
directory: /
schedule:
interval: monthly
+ cooldown:
+ default-days: 5
groups:
github-actions:
patterns:
@@ -14,6 +16,8 @@ updates:
versioning-strategy: widen
schedule:
interval: weekly
+ cooldown:
+ default-days: 5
groups:
dependencies:
dependency-type: "production"
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index 3a15900..a8eef23 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -41,16 +41,16 @@ jobs:
steps:
- name: Harden Runner
- uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
+ uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
- name: Checkout repository
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
- uses: github/codeql-action/init@48ab28a6f5dbc2a99bf1e0131198dd8f1df78169 # v3.28.0
+ uses: github/codeql-action/init@3c3833e0f8c1c83d449a7478aa59c036a9165498 # v3.29.11
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -60,7 +60,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
- uses: github/codeql-action/autobuild@48ab28a6f5dbc2a99bf1e0131198dd8f1df78169 # v3.28.0
+ uses: github/codeql-action/autobuild@3c3833e0f8c1c83d449a7478aa59c036a9165498 # v3.29.11
# âšī¸ Command-line programs to run using the OS shell.
# đ See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
@@ -73,6 +73,6 @@ jobs:
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@48ab28a6f5dbc2a99bf1e0131198dd8f1df78169 # v3.28.0
+ uses: github/codeql-action/analyze@3c3833e0f8c1c83d449a7478aa59c036a9165498 # v3.29.11
with:
category: "/language:${{matrix.language}}"
diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml
index 9d5cf16..9ef83d0 100644
--- a/.github/workflows/node.js.yml
+++ b/.github/workflows/node.js.yml
@@ -19,20 +19,20 @@ jobs:
strategy:
matrix:
- node-version: [20.x]
+ node-version: [24.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- name: Harden Runner
- uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
+ uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
- - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Use Node.js ${{ matrix.node-version }}
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
+ uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: ${{ matrix.node-version }}
- - run: npm i
+ - run: npm i --ignore-scripts
- run: npm run build
- run: npm test
diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml
index 960a3b0..63444b0 100644
--- a/.github/workflows/scorecard.yml
+++ b/.github/workflows/scorecard.yml
@@ -32,17 +32,17 @@ jobs:
steps:
- name: Harden Runner
- uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
+ uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
- name: "Checkout code"
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
- name: "Run analysis"
- uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0
+ uses: ossf/scorecard-action@05b42c624433fc40578a4040d5cf5e36ddca8cde # v2.4.2
with:
results_file: results.sarif
results_format: sarif
@@ -64,7 +64,7 @@ jobs:
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
- uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: SARIF file
path: results.sarif
@@ -72,6 +72,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
- uses: github/codeql-action/upload-sarif@48ab28a6f5dbc2a99bf1e0131198dd8f1df78169 # v3.28.0
+ uses: github/codeql-action/upload-sarif@3c3833e0f8c1c83d449a7478aa59c036a9165498 # v3.29.11
with:
sarif_file: results.sarif
diff --git a/.gitignore b/.gitignore
index 0e2529b..b22eb85 100644
--- a/.gitignore
+++ b/.gitignore
@@ -120,3 +120,4 @@ dist
tmp/
test/download
+nsecure-result.json
diff --git a/.npmrc b/.npmrc
index 43c97e7..304fb65 100644
--- a/.npmrc
+++ b/.npmrc
@@ -1 +1,3 @@
package-lock=false
+ignore-scripts=true
+save-exact=true
diff --git a/README.md b/README.md
index 28e421b..1f012e7 100644
--- a/README.md
+++ b/README.md
@@ -8,20 +8,20 @@
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
@@ -36,12 +36,11 @@ The package is inspired by lukeed [httpie](https://github.com/lukeed/httpie) (Th
- Includes aliases for common HTTP verbs: `get`, `post`, `put`, `patch`, and `del`.
- Able to automatically detect domains and paths to assign the right Agent (use a LRU cache to avoid repetitive computation).
- Allows to use an accurate rate-limiter like `p-ratelimit` with the `limit` option.
-- Built-in retry mechanism with **custom policies**.
- Safe error handling with Rust-like [Result](https://github.com/OpenAlly/npm-packages/tree/main/src/result).
Thanks to undici:
-- Support [HTTP redirections](https://developer.mozilla.org/en-US/docs/Web/HTTP/Redirections) with the `maxRedirections` argument.
+- Support [redirections](https://developer.mozilla.org/en-US/docs/Web/HTTP/Redirections) or retry using interceptors.
- Implement high-level API for undici **stream** and **pipeline** method.
- High performance (see [benchmarks](https://undici.nodejs.org/#/?id=benchmarks)).
- Work well with **newest** Node.js API [AbortController](https://nodejs.org/dist/latest-v16.x/docs/api/globals.html#globals_class_abortcontroller) to cancel http request.
@@ -51,24 +50,24 @@ Light with seriously maintained dependencies:

## đ§ Requirements
-- [Node.js](https://nodejs.org/en/) version 20 or higher
+- [Node.js](https://nodejs.org/en/) version 22 or higher
## đ Getting Started
This package is available in the Node Package Repository and can be easily installed with [npm](https://docs.npmjs.com/getting-started/what-is-npm) or [yarn](https://yarnpkg.com).
```bash
-$ npm i @myunisoft/httpie
+$ npm i @openally/httpie
# or
-$ yarn add @myunisoft/httpie
+$ yarn add @openally/httpie
```
## đ Usage example
-The MyUnisoft httpie client is very similar to lukeed httpie http client.
+This client is very similar to lukeed httpie http client.
```js
-import * as httpie from "@myunisoft/httpie";
+import * as httpie from "@openally/httpie";
try {
const { data } = await httpie.get("https://jsonplaceholder.typicode.com/posts");
@@ -94,10 +93,10 @@ catch (error) {
}
```
-Since v2.0.0 you can also use the `safe` prefix API to get a `Promise>`
+You can also use the `safe` prefix API to get a `Promise>`
```ts
-import * as httpie from "@myunisoft/httpie";
+import * as httpie from "@openally/httpie";
const response = (await httpie.safePost("https://jsonplaceholder.typicode.com/posts", {
body: {
@@ -111,19 +110,18 @@ const response = (await httpie.safePost("https://jsonplaceholder.typicode.com/po
.unwrap();
```
-> đ For more examples of use please look at the root folder **examples**.
+> [!TIP]
+> More examples available in the root folder **examples**.
## đ API
- [Request API](./docs/request.md)
-- [Retry API](./docs/retry.md)
- [Work and manage Agents](./docs/agents.md)
## Error handling
Read the [error documentation](./docs/errors.md).
-
## Contributors â¨
@@ -138,9 +136,9 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
diff --git a/SECURITY.md b/SECURITY.md
index 2f34da4..91aac10 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -1,4 +1,4 @@
# Reporting Security Issues
-To report a security issue, please email `node@myunisoft.fr` with a description of the issue, the steps you took to create the issue, affected versions, and, if known, mitigations for the issue.
+To report a security issue, please [publish a private security advisory](https://github.com/OpenAlly/httpie/security/advisories) with a description of the issue, the steps you took to create the issue, affected versions, and, if known, mitigations for the issue.
Our vulnerability management team will respond within one week to your email. If the issue is confirmed as a vulnerability, we will open a Security Advisory and acknowledge your contributions as part of it. This project follows a 90 day disclosure timeline.
diff --git a/docs/agents.md b/docs/agents.md
index b9bbf4a..f428e8c 100644
--- a/docs/agents.md
+++ b/docs/agents.md
@@ -3,7 +3,7 @@
Agents are custom constructs that are used to describe internal and external services.
```js
-import { agents } from "@myunisoft/httpie";
+import { agents } from "@openally/httpie";
console.log(agents); // <- push a new agent in this Array
```
@@ -12,11 +12,8 @@ Those custom `agents` are described by the following TypeScript interface:
```ts
export interface CustomHttpAgent {
customPath: string;
- domains: Set;
+ origin: string;
agent: Agent;
- prod: string;
- preprod: string;
- dev: string;
}
```
@@ -24,15 +21,10 @@ Example with a test custom agent:
```ts
export const test: CustomHttpAgent = {
customPath: "test",
- domains: new Set([
- "test.domain.fr",
- ]),
agent: new Agent({
connections: 30
}),
- prod: "",
- preprod: "",
- dev: "https://test.domain.fr"
+ origin: "https://test.domain.fr"
};
// Note: push it to the package agents list
diff --git a/docs/errors.md b/docs/errors.md
index 1e2ebb6..a13a81e 100644
--- a/docs/errors.md
+++ b/docs/errors.md
@@ -13,14 +13,14 @@ interface HttpieError {
### isHttpieError
-The `isHttpieError` function can be used to find out weither the error is a `@myunisoft/httpie` or a `undici` error.
+The `isHttpieError` function can be used to find out weither the error is a `@openally/httpie` or a `undici` error.
```ts
function isHttpieError(error: unknown): boolean;
```
Example:
```ts
-import * as httpie from "@myunisoft/httpie";
+import * as httpie from "@openally/httpie";
try {
await httpie.request("GET", "127.0.0.1");
@@ -48,7 +48,7 @@ function isHTTPError(error: unknown): boolean;
Example:
```ts
-import * as httpie from "@myunisoft/httpie";
+import * as httpie from "@openally/httpie";
try {
await httpie.request("GET", "127.0.0.1");
diff --git a/docs/images/nodesecure.PNG b/docs/images/nodesecure.PNG
index 5f3dab5..9e31576 100644
Binary files a/docs/images/nodesecure.PNG and b/docs/images/nodesecure.PNG differ
diff --git a/docs/request.md b/docs/request.md
index 9eb30cd..31af0be 100644
--- a/docs/request.md
+++ b/docs/request.md
@@ -7,8 +7,6 @@ The method **options** and **response** are described by the following TypeScrip
type ModeOfHttpieResponseHandler = "decompress" | "parse" | "raw";
export interface RequestOptions {
- /** @default 0 */
- maxRedirections?: number;
/** @default{ "user-agent": "httpie" } */
headers?: IncomingHttpHeaders;
querystring?: string | URLSearchParams;
@@ -37,7 +35,7 @@ The first **method** argument take an [HTTP Verb](https://developer.mozilla.org/
The options allow you to quickly authenticate and add additional headers:
```js
-import { request } from "@myunisoft/httpie";
+import { request } from "@openally/httpie";
const { data } = await request("GET", "https://test.domain.fr/user/info", {
authorization: "Token here",
diff --git a/docs/retry.md b/docs/retry.md
deleted file mode 100644
index ce13f4b..0000000
--- a/docs/retry.md
+++ /dev/null
@@ -1,53 +0,0 @@
-# Retry API
-
-Allows to restart http calls according to various criteria that we will call policies. By default there is two built-in policies:
-- none (do not stop retry to append). **This is the default policy**.
-- httpcode (allow to retry or fail on some http codes).
-
-The httpcode by default retry on codes: `307`, `408`, `429`, `444`, `500`, `503`, `504`, `520`, `521`, `522`, `523`, `524`. However you can also choose to extend the list yourself:
-
-```js
-import * as httpie from "@myunisoft/httpie";
-
-const policy = httpie.policies.httpcode(new Set([501]), true);
-```
-
-## Usage example
-
-```js
-import * as httpie from "@myunisoft/httpie";
-
-const { data } = httpie.retry(async() => {
- return await httpie.get("https://jsonplaceholder.typicode.com/posts");
-}, { factor: 1, forever: true }, httpie.policies.httpcode());
-```
-
-Retry options are described by the following interface:
-```ts
-export interface RetryOptions {
- retries?: number;
- minTimeout?: number;
- maxTimeout?: number;
- unref?: boolean;
- factor?: number;
- forever?: boolean;
- signal?: AbortSignal | null;
-}
-```
-
-By default it will retry three times, with a minTimeout of `1_000` and a factor of `2`.
-
-## Creating your own policy
-
-A policy "callback" is described by the following interface
-```ts
-export type PolicyCallback = (error?: any) => boolean;
-```
-
-So it's pretty straightforward to create a new one. For example here this policy will throw if the error is an `AbortError`.
-
-```js
-export function abort(error) {
- return error.name === "AbortError";
-}
-```
diff --git a/eslint.config.mjs b/eslint.config.mjs
index 8a1e9d0..f221107 100644
--- a/eslint.config.mjs
+++ b/eslint.config.mjs
@@ -1,3 +1,5 @@
import { typescriptConfig } from "@openally/config.eslint";
-export default typescriptConfig();
+export default typescriptConfig({
+ ignores: ["./examples"]
+});
diff --git a/examples/agent.mjs b/examples/agent.mjs
index e62a9b8..e24bd57 100644
--- a/examples/agent.mjs
+++ b/examples/agent.mjs
@@ -1,19 +1,12 @@
import * as httpie from "../dist/index.js";
-// import * as httpie from "@myunisoft/httpie";
+// import * as httpie from "@openally/httpie";
const yoda = {
customPath: "yoda",
- domains: new Set([
- "yoda.myunisoft.fr"
- ]),
agent: new httpie.Agent({
connections: 500
}),
-
- // Work by reading the NODE_ENV var.
- prod: "",
- preprod: "",
- dev: "https://yoda.myunisoft.fr:1407"
+ origin: "https://yoda.myunisoft.fr:1407"
};
httpie.agents.add(yoda);
diff --git a/examples/get.mjs b/examples/get.mjs
index bf92d4a..b7379eb 100644
--- a/examples/get.mjs
+++ b/examples/get.mjs
@@ -1,5 +1,5 @@
import * as httpie from "../dist/index.js";
-// import * as httpie from "@myunisoft/httpie";
+// import * as httpie from "@openally/httpie";
const { data } = await httpie.get("https://jsonplaceholder.typicode.com/posts");
console.log(data);
diff --git a/examples/mode.ts b/examples/mode.ts
index b16bda5..76a6363 100644
--- a/examples/mode.ts
+++ b/examples/mode.ts
@@ -1,5 +1,5 @@
import * as httpie from "../dist/index.js";
-// import * as httpie from "@myunisoft/httpie";
+// import * as httpie from "@openally/httpie";
{
const { data } = await httpie.request("GET", "127.0.0.1", { mode: "raw" });
diff --git a/examples/pipeline.mjs b/examples/pipeline.mjs
index b3bf758..c77554e 100644
--- a/examples/pipeline.mjs
+++ b/examples/pipeline.mjs
@@ -6,7 +6,7 @@ import { fileURLToPath } from "url";
// Third-party Dependencies
import * as httpie from "../dist/index.js";
-// import * as httpie from "@myunisoft/httpie";
+// import * as httpie from "@openally/httpie";
// CONSTANTS
const __dirname = path.dirname(fileURLToPath(import.meta.url));
diff --git a/examples/ratelimit.mjs b/examples/ratelimit.mjs
index 69dcc63..768dc86 100644
--- a/examples/ratelimit.mjs
+++ b/examples/ratelimit.mjs
@@ -1,7 +1,7 @@
// Import Third-party Dependencies
import { pRateLimit } from "p-ratelimit";
import * as httpie from "../dist/index.js";
-// import * as httpie from "@myunisoft/httpie";
+// import * as httpie from "@openally/httpie";
// Note: limit can also be provided to an Agent!
const limit = pRateLimit({
diff --git a/examples/retry.mjs b/examples/retry.mjs
deleted file mode 100644
index cb2d6f1..0000000
--- a/examples/retry.mjs
+++ /dev/null
@@ -1,8 +0,0 @@
-// Import Third-party Dependencies
-import * as httpie from "../dist/index.js";
-// import * as httpie from "@myunisoft/httpie";
-
-const { data } = await httpie.retry(async() => {
- return await httpie.get("https://jsonplaceholder.typicode.com/posts");
-}, { forever: true }, httpie.policies.httpcode());
-console.log(data);
diff --git a/examples/stream.mjs b/examples/stream.mjs
index 6c727f6..ee83e23 100644
--- a/examples/stream.mjs
+++ b/examples/stream.mjs
@@ -5,15 +5,20 @@ import { fileURLToPath } from "url";
// Third-party Dependencies
import * as httpie from "../dist/index.js";
-// import * as httpie from "@myunisoft/httpie";
+// import * as httpie from "@openally/httpie";
// CONSTANTS
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const kGithubURL = new URL("https://github.com/");
-const cursor = httpie.stream("GET", new URL("NodeSecure/i18n/archive/main.tar.gz", kGithubURL), {
- maxRedirections: 1
-});
+const agent = new httpie.Agent(
+ httpie.interceptors.redirect({ maxRedirections: 2 })
+);
+const cursor = httpie.stream(
+ "GET",
+ new URL("NodeSecure/vulnera/archive/main.tar.gz", kGithubURL),
+ { agent }
+);
const writable = fs.createWriteStream(path.join(__dirname, "archive.tar.gz"));
@@ -26,4 +31,4 @@ await cursor(({ statusCode, headers }) => {
return writable;
});
-console.log(code, contentType);
\ No newline at end of file
+console.log(code, contentType);
diff --git a/examples/throwOnHttpieError.mjs b/examples/throwOnHttpieError.mjs
index 4c0cd4e..69277ba 100644
--- a/examples/throwOnHttpieError.mjs
+++ b/examples/throwOnHttpieError.mjs
@@ -1,5 +1,5 @@
import * as httpie from "../dist/index.js";
-// import * as httpie from "@myunisoft/httpie";
+// import * as httpie from "@openally/httpie";
// Should not throw
{
diff --git a/jest.config.js b/jest.config.js
deleted file mode 100644
index a1fadc1..0000000
--- a/jest.config.js
+++ /dev/null
@@ -1,16 +0,0 @@
-module.exports = {
- preset: "ts-jest",
- testEnvironment: "node",
- collectCoverage: true,
- collectCoverageFrom: [
- "**/src/**/**/*.ts"
- ],
- setupFilesAfterEnv: [
- "./test/jest.setup.js"
- ],
- testPathIgnorePatterns: [
- "/node_modules/",
- "/test/fixtures/"
- ],
- setupFiles: ["dotenv/config"]
-};
diff --git a/package.json b/package.json
index 39bc071..b9208fc 100644
--- a/package.json
+++ b/package.json
@@ -1,55 +1,55 @@
{
- "name": "@myunisoft/httpie",
- "version": "5.0.1",
- "description": "MyUnisoft Node.js HTTP client that use Undici client",
+ "name": "@openally/httpie",
+ "version": "1.0.0",
+ "description": "Node.js HTTP client that use Undici client",
+ "type": "module",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"build": "tsc",
"lint": "eslint src test",
- "prepublishOnly": "npm run build",
- "test": "jest"
+ "prepublishOnly": "npm run build && npm run test-types",
+ "test-only": "tsx --test ./**/*.test.ts",
+ "test-types": "attw --pack . --profile esm-only",
+ "test": "c8 -r html npm run test-only && npm run test-types"
},
"repository": {
"type": "git",
- "url": "git+https://github.com/MyUnisoft/httpie.git"
+ "url": "git+https://github.com/OpenAlly/httpie.git"
},
"engines": {
- "node": ">=20"
+ "node": ">=22"
},
"keywords": [],
"files": [
"dist"
],
- "publishConfig": {
- "@myunisoft:registry": "https://registry.npmjs.org/"
- },
"author": "GENTILHOMME Thomas ",
"license": "MIT",
"bugs": {
- "url": "https://github.com/MyUnisoft/httpie/issues"
+ "url": "https://github.com/OpenAlly/httpie/issues"
},
- "homepage": "https://github.com/MyUnisoft/httpie#readme",
+ "homepage": "https://github.com/OpenAlly/httpie#readme",
"devDependencies": {
- "@openally/config.eslint": "^1.1.0",
- "@openally/config.typescript": "^1.0.3",
- "@types/content-type": "^1.1.8",
- "@types/jest": "^29.5.11",
- "@types/lru-cache": "^7.10.10",
- "@types/node": "^22.0.0",
- "@types/statuses": "^2.0.4",
- "dotenv": "^16.3.1",
- "fastify": "^5.2.0",
- "jest": "^29.7.0",
+ "@arethetypeswrong/cli": "^0.18.2",
+ "@openally/config.eslint": "^2.2.0",
+ "@openally/config.typescript": "1.2.1",
+ "@types/content-type": "^1.1.9",
+ "@types/lru-cache": "^7.10.9",
+ "@types/node": "24.9.1",
+ "@types/statuses": "^2.0.6",
+ "c8": "^10.1.3",
+ "fastify": "5.6.1",
+ "is-html": "3.2.0",
"p-ratelimit": "^1.0.1",
- "ts-jest": "^29.1.1",
- "typescript": "^5.3.3"
+ "tsx": "4.20.6",
+ "typescript": "5.9.3"
},
"dependencies": {
"@openally/result": "^1.2.1",
"content-type": "^1.0.5",
- "lru-cache": "^11.0.0",
- "statuses": "^2.0.1",
- "undici": "^6.9.0"
+ "lru-cache": "11.2.2",
+ "statuses": "^2.0.2",
+ "undici": "7.16.0"
}
}
diff --git a/src/agents.ts b/src/agents.ts
index 2b7284f..1949215 100644
--- a/src/agents.ts
+++ b/src/agents.ts
@@ -3,21 +3,21 @@ import { Agent, ProxyAgent, MockAgent } from "undici";
import { LRUCache } from "lru-cache";
// Import Internal Dependencies
-import { InlineCallbackAction, HttpMethod, WebDavMethod } from "./request";
-import { getCurrentEnv } from "./utils";
-
-// CONSTANTS
-const kEnvName = getCurrentEnv();
+import {
+ type InlineCallbackAction,
+ type HttpMethod,
+ type WebDavMethod
+} from "./request.js";
/**
* @see https://en.wikipedia.org/wiki/Page_replacement_algorithm
*/
-export const URICache = new LRUCache({
+export const URI_CACHE = new LRUCache({
max: 100,
ttl: 1_000 * 60 * 120
});
-export interface computedUrlAndAgent {
+export interface ComputedUrlAndAgent {
url: URL;
agent: Agent | ProxyAgent | MockAgent | null;
limit?: InlineCallbackAction;
@@ -28,11 +28,8 @@ export interface computedUrlAndAgent {
*/
export interface CustomHttpAgent {
customPath: string;
- domains: Set;
+ origin: string;
agent: Agent | ProxyAgent | MockAgent;
- prod: string;
- preprod: string;
- dev: string;
limit?: InlineCallbackAction;
}
@@ -45,19 +42,22 @@ export const agents: Set = new Set();
* const URI = computeAgentPath("/windev/ws_monitoring", windev);
* assert.strictEqual(URI, "https://ws-dev.myunisoft.fr/ws_monitoring");
*/
-export function isAgentPathMatchingURI(uri: string, agent: CustomHttpAgent): URL | null {
+export function isAgentPathMatchingURI(
+ uri: string,
+ agent: CustomHttpAgent
+): URL | null {
// Note: we want to match both '/path/xxx...' and 'path/xxx...'
const localCustomPath = uri.charAt(0) === "/" ? `/${agent.customPath}` : agent.customPath;
return uri.startsWith(localCustomPath) ?
- new URL(uri.slice(localCustomPath.length), agent[kEnvName]) :
+ new URL(uri.slice(localCustomPath.length), agent.origin) :
null;
}
/**
* @description Compute a given string URI to the local list of agents.
*/
-export function computeURIOnAllAgents(uri: string): computedUrlAndAgent {
+export function computeURIOnAllAgents(uri: string): ComputedUrlAndAgent {
for (const agent of agents) {
const url = isAgentPathMatchingURI(uri, agent);
@@ -85,7 +85,7 @@ export function detectAgentFromURI(uri: URL): CustomHttpAgent | null {
const hostname = uri.hostname;
for (const agent of agents) {
- if (agent.domains.has(hostname)) {
+ if (new URL(agent.origin).hostname === hostname) {
return agent;
}
}
@@ -100,13 +100,13 @@ export function detectAgentFromURI(uri: URL): CustomHttpAgent | null {
export function computeURI(
method: HttpMethod | WebDavMethod,
uri: string | URL
-): computedUrlAndAgent {
+): ComputedUrlAndAgent {
const uriStr = method.toUpperCase() + uri.toString();
- if (URICache.has(uriStr)) {
- return URICache.get(uriStr)!;
+ if (URI_CACHE.has(uriStr)) {
+ return URI_CACHE.get(uriStr)!;
}
- let response: computedUrlAndAgent;
+ let response: ComputedUrlAndAgent;
if (typeof uri === "string") {
response = computeURIOnAllAgents(uri);
}
@@ -115,7 +115,7 @@ export function computeURI(
response = { url: uri, agent: agent?.agent ?? null, limit: agent?.limit };
}
- URICache.set(uriStr, response);
+ URI_CACHE.set(uriStr, response);
return response;
}
diff --git a/src/class/HttpieCommonError.ts b/src/class/HttpieCommonError.ts
index d80fbf4..75b54b5 100644
--- a/src/class/HttpieCommonError.ts
+++ b/src/class/HttpieCommonError.ts
@@ -1,5 +1,5 @@
-// Import Third-party Dependencies
-import { IncomingHttpHeaders } from "undici/types/header";
+// Import Node.js Dependencies
+import type { IncomingHttpHeaders } from "node:http";
type CommonResponseData = {
statusCode: number;
diff --git a/src/class/HttpieHandlerError.ts b/src/class/HttpieHandlerError.ts
index ed1253a..30ac336 100644
--- a/src/class/HttpieHandlerError.ts
+++ b/src/class/HttpieHandlerError.ts
@@ -1,8 +1,12 @@
/* eslint-disable max-classes-per-file */
-// Import Third-party Dependencies
-import { HttpieError, HttpieErrorOptions } from "./HttpieCommonError";
-import { getDecompressionError, getFetchError, getParserError } from "../common/errors";
+// Import Internal Dependencies
+import { HttpieError, type HttpieErrorOptions } from "./HttpieCommonError.js";
+import {
+ getDecompressionError,
+ getFetchError,
+ getParserError
+} from "../common/errors.js";
type MessageOfGetDecompressionError = Parameters[0]["message"];
type MessageOfGetParserError = Parameters[0]["message"];
diff --git a/src/class/HttpieOnHttpError.ts b/src/class/HttpieOnHttpError.ts
index 3eb4855..8242fcb 100644
--- a/src/class/HttpieOnHttpError.ts
+++ b/src/class/HttpieOnHttpError.ts
@@ -1,6 +1,6 @@
// Import Internal Dependencies
-import { HttpieError } from "./HttpieCommonError";
-import { RequestResponse } from "../request";
+import { HttpieError } from "./HttpieCommonError.js";
+import { type RequestResponse } from "../request.js";
/**
* @description Class to generate an Error with all the required properties from the response.
diff --git a/src/class/Operation.class.ts b/src/class/Operation.class.ts
deleted file mode 100644
index c4ddb41..0000000
--- a/src/class/Operation.class.ts
+++ /dev/null
@@ -1,108 +0,0 @@
-// Import Node.js Dependencies
-import timers from "node:timers/promises";
-
-// Import Internal Dependencies
-import { RetryOptions } from "../retry";
-
-// CONSTANTS
-const kDefaultOperationOptions: Partial = {
- retries: 3,
- minTimeout: 1_000,
- maxTimeout: Infinity,
- forever: false,
- unref: false,
- factor: 2,
- signal: null
-};
-
-export interface OperationResult {
- data: T;
- metrics: {
- attempt: number;
- executionTimestamp: number;
- elapsedTimeoutTime: number;
- };
-}
-
-export default class Operation {
- private retries: number;
- private minTimeout: number;
- private maxTimeout: number;
- private forever: boolean;
- private unref: boolean;
- private factor: number;
- private signal: AbortSignal;
- private data: T;
- private continueExecution = true;
-
- private attempt = 0;
- private startAt = Date.now();
- private executionTimestamp: number;
- private elapsedTimeoutTime = 0;
-
- constructor(options: RetryOptions) {
- Object.assign(this, {}, kDefaultOperationOptions, options);
- if (this.forever) {
- this.retries = Infinity;
- }
- }
-
- /**
- * @see http://dthain.blogspot.com/2009/02/exponential-backoff-in-distributed.html
- */
- private get backoff() {
- return Math.min(this.minTimeout * Math.pow(this.factor, this.attempt - 1), this.maxTimeout);
- }
-
- get continue() {
- return this.continueExecution;
- }
-
- ensureAbort() {
- if (this.signal === null) {
- return;
- }
-
- if (this.signal.aborted) {
- throw new Error("Aborted");
- }
- }
-
- async retry() {
- this.ensureAbort();
- this.attempt++;
-
- if (this.attempt > this.retries) {
- // TODO: add error causes ?
-
- throw new Error("Exceeded the maximum number of allowed retries!");
- }
-
- const timeout = this.backoff;
- const signal = this.signal ?? void 0;
- this.continueExecution = true;
-
- await timers.setTimeout(timeout, void 0, { ref: this.unref, signal });
- this.ensureAbort();
-
- this.elapsedTimeoutTime += timeout;
- }
-
- success(data: T) {
- this.data = data;
-
- this.continueExecution = false;
- this.executionTimestamp = Date.now() - this.startAt;
- }
-
- toJSON(): OperationResult {
- return {
- data: this.data,
- metrics: {
- attempt: this.attempt,
- executionTimestamp: this.executionTimestamp,
- elapsedTimeoutTime: this.elapsedTimeoutTime
- }
- };
- }
-}
diff --git a/src/class/undiciResponseHandler.ts b/src/class/undiciResponseHandler.ts
index f07c5a9..e8ade2e 100644
--- a/src/class/undiciResponseHandler.ts
+++ b/src/class/undiciResponseHandler.ts
@@ -8,8 +8,12 @@ import { Dispatcher } from "undici";
import * as contentType from "content-type";
// Import Internal Dependencies
-import { getEncodingCharset } from "../utils";
-import { HttpieDecompressionError, HttpieFetchBodyError, HttpieParserError } from "./HttpieHandlerError";
+import { getEncodingCharset } from "../utils.js";
+import {
+ HttpieDecompressionError,
+ HttpieFetchBodyError,
+ HttpieParserError
+} from "./HttpieHandlerError.js";
const kAsyncGunzip = promisify(gunzip);
const kDecompress = {
diff --git a/src/common/errors.ts b/src/common/errors.ts
index 5ff133b..d53db83 100644
--- a/src/common/errors.ts
+++ b/src/common/errors.ts
@@ -3,7 +3,6 @@ interface GetErrorOptions {
message: keyof T;
}
-// from myu-utils
function taggedString(chains: TemplateStringsArray, ...expectedValues: string[] | number[]) {
return function cur(...args: any[]): string {
const directory = args.at(-1) || {};
diff --git a/src/index.ts b/src/index.ts
index 646dbef..3a0013e 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -2,43 +2,43 @@
import {
Agent,
ProxyAgent,
+ interceptors,
fetch,
setGlobalDispatcher,
getGlobalDispatcher,
Headers,
- HeadersInit,
+ type HeadersInit,
FormData,
- File,
- BodyInit,
- BodyMixin,
+ type BodyInit,
MockAgent,
mockErrors,
MockPool,
- Interceptable,
+ type Interceptable,
Client
} from "undici";
-export * from "./request";
-export * from "./stream";
-export * from "./retry";
-export * as policies from "./policies";
-export { agents, computeURI, type CustomHttpAgent } from "./agents";
-export { DEFAULT_HEADER, isHTTPError, isHttpieError } from "./utils";
-export { HttpieOnHttpError } from "./class/HttpieOnHttpError";
-export * from "./class/undiciResponseHandler";
+setGlobalDispatcher(
+ new Agent().compose(interceptors.redirect())
+);
+
+export * from "./request.js";
+export * from "./stream.js";
+export { agents, computeURI, type CustomHttpAgent } from "./agents.js";
+export { DEFAULT_HEADER, isHTTPError, isHttpieError } from "./utils.js";
+export { HttpieOnHttpError } from "./class/HttpieOnHttpError.js";
+export * from "./class/undiciResponseHandler.js";
export {
Agent,
ProxyAgent,
+ interceptors,
fetch,
setGlobalDispatcher,
getGlobalDispatcher,
Headers,
type HeadersInit,
FormData,
- File,
type BodyInit,
- BodyMixin,
MockAgent,
mockErrors,
MockPool,
diff --git a/src/policies/httpcode.ts b/src/policies/httpcode.ts
deleted file mode 100644
index 8853b1e..0000000
--- a/src/policies/httpcode.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-/**
- * @see https://fr.wikipedia.org/wiki/Liste_des_codes_HTTP
- */
-const kDefaultCodes = new Set([307, 408, 429, 444, 500, 503, 504, 520, 521, 522, 523, 524]);
-
-export function httpcode(codes: Set = kDefaultCodes, useDefault = false) {
- if (useDefault) {
- [...kDefaultCodes].forEach((code) => codes.add(code));
- }
-
- return ({ statusCode }) => !codes.has(statusCode);
-}
diff --git a/src/policies/index.ts b/src/policies/index.ts
deleted file mode 100644
index 1d7bb38..0000000
--- a/src/policies/index.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export * from "./none";
-export * from "./httpcode";
-
-export type PolicyCallback = (error?: any) => boolean;
diff --git a/src/policies/none.ts b/src/policies/none.ts
deleted file mode 100644
index 7149d70..0000000
--- a/src/policies/none.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export function none() {
- return false;
-}
diff --git a/src/request.ts b/src/request.ts
index b6843f9..4ef9d8a 100644
--- a/src/request.ts
+++ b/src/request.ts
@@ -1,5 +1,5 @@
// Import Node.js Dependencies
-import { IncomingHttpHeaders } from "node:http";
+import { type IncomingHttpHeaders } from "node:http";
import { URLSearchParams } from "node:url";
// Import Third-party Dependencies
@@ -8,11 +8,20 @@ import { Result } from "@openally/result";
import status from "statuses";
// Import Internal Dependencies
-import * as Utils from "./utils";
-import { computeURI } from "./agents";
-import { HttpieResponseHandler, ModeOfHttpieResponseHandler } from "./class/undiciResponseHandler";
-import { HttpieOnHttpError } from "./class/HttpieOnHttpError";
-import { HttpieDecompressionError, HttpieFetchBodyError, HttpieParserError } from "./class/HttpieHandlerError";
+import * as Utils from "./utils.js";
+import { computeURI } from "./agents.js";
+import {
+ HttpieResponseHandler,
+ type ModeOfHttpieResponseHandler
+} from "./class/undiciResponseHandler.js";
+import {
+ HttpieOnHttpError
+} from "./class/HttpieOnHttpError.js";
+import {
+ HttpieDecompressionError,
+ HttpieFetchBodyError,
+ HttpieParserError
+} from "./class/HttpieHandlerError.js";
export type WebDavMethod = "MKCOL" | "COPY" | "MOVE" | "LOCK" | "UNLOCK" | "PROPFIND" | "PROPPATCH";
export type HttpMethod = "GET" | "HEAD" | "POST" | "PUT" | "DELETE" | "CONNECT" | "OPTIONS" | "TRACE" | "PATCH";
@@ -25,8 +34,6 @@ export type RequestError =
HttpieParserError;
export interface RequestOptions {
- /** @default 0 */
- maxRedirections?: number;
/** @default{ "user-agent": "httpie" } */
headers?: IncomingHttpHeaders;
querystring?: string | URLSearchParams;
@@ -62,8 +69,6 @@ export async function request(
uri: string | URL,
options: RequestOptions = {}
): Promise> {
- const { maxRedirections = 0 } = options;
-
const computedURI = computeURI(method, uri);
if (typeof options.querystring !== "undefined") {
const qs = typeof options.querystring === "string" ? new URLSearchParams(options.querystring) : options.querystring;
@@ -78,7 +83,7 @@ export async function request(
const headers = Utils.createHeaders({ headers: options.headers, authorization: options.authorization });
const body = Utils.createBody(options.body, headers);
- const requestOptions = { method: method as HttpMethod, headers, body, dispatcher, maxRedirections };
+ const requestOptions = { method: method as HttpMethod, headers, body, dispatcher };
const requestResponse = limit === null ?
await undici.request(computedURI.url, requestOptions) :
await limit(() => undici.request(computedURI.url, requestOptions));
@@ -86,7 +91,7 @@ export async function request(
const statusCode = requestResponse.statusCode;
const responseHandler = new HttpieResponseHandler(requestResponse);
- let data;
+ let data: any;
if (options.mode === "parse" || !options.mode) {
data = await responseHandler.getData("parse");
}
diff --git a/src/retry.ts b/src/retry.ts
deleted file mode 100644
index 3569104..0000000
--- a/src/retry.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-// Import Internal Dependencies
-import Operation, { OperationResult } from "./class/Operation.class";
-import { PolicyCallback, none } from "./policies";
-
-/**
- * Those options are inspired by the retry package
- * @see https://www.npmjs.com/package/retry
- */
-export interface RetryOptions {
- retries?: number;
- minTimeout?: number;
- maxTimeout?: number;
- unref?: boolean;
- factor?: number;
- forever?: boolean;
- signal?: AbortSignal | null;
-}
-
-export type RetryCallback = (() => Promise) | (() => T);
-
-export async function retry(
- callback: RetryCallback, options: RetryOptions = {}, policy: PolicyCallback = none
-): Promise> {
- const op = new Operation(options);
-
- do {
- try {
- const data = await callback();
- op.success(data);
- }
- catch (error: any) {
- if (policy(error)) {
- throw error;
- }
-
- await op.retry();
- }
- } while (op.continue);
-
- return op.toJSON();
-}
diff --git a/src/stream.ts b/src/stream.ts
index 451130d..030b39e 100644
--- a/src/stream.ts
+++ b/src/stream.ts
@@ -5,9 +5,13 @@ import { Duplex } from "node:stream";
import * as undici from "undici";
// Import Internal Dependencies
-import { RequestOptions, HttpMethod, WebDavMethod } from "./request";
-import { computeURI } from "./agents";
-import * as Utils from "./utils";
+import {
+ type RequestOptions,
+ type HttpMethod,
+ type WebDavMethod
+} from "./request.js";
+import { computeURI } from "./agents.js";
+import * as Utils from "./utils.js";
export type StreamOptions = Omit;
@@ -16,8 +20,6 @@ export function pipeline(
uri: string | URL,
options: StreamOptions = {}
): Duplex {
- const { maxRedirections = 0 } = options;
-
const computedURI = computeURI(method, uri);
if (typeof options.querystring !== "undefined") {
const qs = typeof options.querystring === "string" ? new URLSearchParams(options.querystring) : options.querystring;
@@ -31,7 +33,7 @@ export function pipeline(
const body = Utils.createBody(options.body, headers);
return undici.pipeline(computedURI.url, {
- method: method as HttpMethod, headers, body, dispatcher, maxRedirections
+ method: method as HttpMethod, headers, body, dispatcher
}, ({ body }) => body);
}
@@ -44,7 +46,6 @@ export function stream(
uri: string | URL,
options: StreamOptions = {}
): WritableStreamCallback {
- const { maxRedirections = 0 } = options;
const computedURI = computeURI(method, uri);
const dispatcher = options.agent ?? computedURI.agent ?? void 0;
@@ -54,7 +55,7 @@ export function stream(
return (factory) => undici
.stream(
computedURI.url,
- { method: method as HttpMethod, headers, body, dispatcher, maxRedirections },
+ { method: method as HttpMethod, headers, body, dispatcher },
factory
);
}
diff --git a/src/utils.ts b/src/utils.ts
index 56b0e45..b465a76 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -1,11 +1,11 @@
// Import Node.js Dependencies
-import { IncomingHttpHeaders } from "node:http";
+import { type IncomingHttpHeaders } from "node:http";
// Import Internal Dependencies
-import { RequestOptions, RequestResponse } from "./request";
-import { HttpieError } from "./class/HttpieCommonError";
-import { HttpieOnHttpError } from "./class/HttpieOnHttpError";
+import { type RequestOptions, type RequestResponse } from "./request.js";
+import { HttpieError } from "./class/HttpieCommonError.js";
+import { HttpieOnHttpError } from "./class/HttpieOnHttpError.js";
// CONSTANTS
const kDefaultUserAgent = "httpie";
@@ -24,7 +24,9 @@ export function isAsyncIterable(value: any): boolean {
* @description Get a valid Node.js charset from the "content-type" http header.
* @see https://nodejs.org/api/buffer.html#buffer_buffers_and_character_encodings
*/
-export function getEncodingCharset(charset = kDefaultEncodingCharset): BufferEncoding {
+export function getEncodingCharset(
+ charset = kDefaultEncodingCharset
+): BufferEncoding {
if (Buffer.isEncoding(charset)) {
return charset as BufferEncoding;
}
@@ -37,7 +39,9 @@ export function getEncodingCharset(charset = kDefaultEncodingCharset): BufferEnc
* - User-agent
* - Authorization
*/
-export function createHeaders(options: Partial>): IncomingHttpHeaders {
+export function createHeaders(
+ options: Partial>
+): IncomingHttpHeaders {
const headers = Object.assign({ ...DEFAULT_HEADER }, options.headers ?? {});
if (options.authorization) {
@@ -47,7 +51,9 @@ export function createHeaders(options: Partial {
- it("it should create an HttpieOnHttpError with the properties of RequestResponse", async() => {
- expect.assertions(2);
+ it("it should create an HttpieOnHttpError with the properties of RequestResponse", async(t) => {
+ t.plan(2);
const expectedResponseData = {
statusCode: 404,
@@ -34,8 +37,13 @@ describe("HttpieOnHttpError", () => {
await request(targetUrl.method as any, path);
}
catch (error: any) {
- expect(error.name).toStrictEqual("HttpieOnHttpError");
- expect(error).toMatchObject(expectedResponseData);
+ const { data, headers, statusCode, statusMessage } = error;
+
+ t.assert.equal(error.name, "HttpieOnHttpError");
+ t.assert.deepEqual(
+ { data, headers, statusCode, statusMessage },
+ expectedResponseData
+ );
}
});
});
diff --git a/test/__snapshots__/request.spec.ts.snap b/test/__snapshots__/request.spec.ts.snap
deleted file mode 100644
index c906e83..0000000
--- a/test/__snapshots__/request.spec.ts.snap
+++ /dev/null
@@ -1,23 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`http.get should throw a 404 Not Found error because the path is not known 1`] = `
-"
-
-404 Not Found
-
-Not Found
-The requested URL was not found on this server.
-
-"
-`;
-
-exports[`http.safeGet should throw a 404 Not Found error because the path is not known 1`] = `
-"
-
-404 Not Found
-
-Not Found
-The requested URL was not found on this server.
-
-"
-`;
diff --git a/test/agents.spec.ts b/test/agents.test.ts
similarity index 59%
rename from test/agents.spec.ts
rename to test/agents.test.ts
index b7ce8e3..45f769a 100644
--- a/test/agents.spec.ts
+++ b/test/agents.test.ts
@@ -1,3 +1,7 @@
+// Import Node.js Dependencies
+import { beforeEach, describe, it } from "node:test";
+import assert from "node:assert";
+
// Import Internal Dependencies
import { windev } from "./helpers";
import * as Agents from "../src/agents";
@@ -7,44 +11,43 @@ const kWindevMonitoringURL = "https://ws.dev.myunisoft.tech/ws_monitoring";
describe("agents", () => {
it("should be an Array of CustomHttpAgent and must remain extensible", () => {
- expect(Agents.agents instanceof Set).toStrictEqual(true);
-
- expect(Object.isExtensible(Agents.agents)).toStrictEqual(true);
+ assert.ok(Agents.agents instanceof Set);
+ assert.ok(Object.isExtensible(Agents.agents));
});
});
describe("isAgentPathMatchingURI", () => {
it("should compute the path because it start with '/windev'", () => {
const result = Agents.isAgentPathMatchingURI("/windev/ws_monitoring", windev);
- expect(result?.href).toStrictEqual(kWindevMonitoringURL);
+ assert.strictEqual(result?.href, kWindevMonitoringURL);
// Same but without '/' at the beginning
const result2 = Agents.isAgentPathMatchingURI("windev/ws_monitoring", windev);
- expect(result2?.href).toStrictEqual(kWindevMonitoringURL);
+ assert.strictEqual(result2?.href, kWindevMonitoringURL);
});
it("should not compute the path and return null instead", () => {
const result = Agents.isAgentPathMatchingURI("/xd/ws_monitoring", windev);
- expect(result).toStrictEqual(null);
+ assert.strictEqual(result, null);
});
});
describe("computeURIOnAllAgents", () => {
it("should compute with windev agent", () => {
const result = Agents.computeURIOnAllAgents("/windev/ws_monitoring");
- expect(result.url.href).toStrictEqual(kWindevMonitoringURL);
- expect(result.agent).toStrictEqual(windev.agent);
+ assert.strictEqual(result.url.href, kWindevMonitoringURL);
+ assert.strictEqual(result.agent, windev.agent);
});
it("should return the given URI with no computation", () => {
const result = Agents.computeURIOnAllAgents("https://www.google.fr/");
- expect(result.url.href).toStrictEqual("https://www.google.fr/");
- expect(result.agent).toStrictEqual(null);
+ assert.strictEqual(result.url.href, "https://www.google.fr/");
+ assert.strictEqual(result.agent, null);
});
it("should throw an Error if no computation because that's not a valid URI", () => {
- expect(() => Agents.computeURIOnAllAgents("/xdd/healthz")).toThrow();
+ assert.throws(() => Agents.computeURIOnAllAgents("/xdd/healthz"));
});
});
@@ -52,63 +55,63 @@ describe("detectAgentFromURI", () => {
it("should detect windev agent with URI hostname", () => {
const returnedAgent = Agents.detectAgentFromURI(new URL("https://ws.dev.myunisoft.tech"));
- expect(returnedAgent).toStrictEqual(windev);
+ assert.strictEqual(returnedAgent, windev);
});
it("should return null if hostname is not internaly known", () => {
const returnedAgent = Agents.detectAgentFromURI(new URL("https://www.google.fr/"));
- expect(returnedAgent).toStrictEqual(null);
+ assert.strictEqual(returnedAgent, null);
});
});
describe("computeURI", () => {
beforeEach(() => {
- Agents.URICache.clear();
+ Agents.URI_CACHE.clear();
});
it("should compute a windev URI (as string)", () => {
const result = Agents.computeURI("GET", kWindevMonitoringURL);
- expect(result.url.href).toStrictEqual(kWindevMonitoringURL);
- expect(result.agent).toStrictEqual(windev.agent);
+ assert.strictEqual(result.url.href, kWindevMonitoringURL);
+ assert.strictEqual(result.agent, windev.agent);
- expect(Agents.URICache.has("GET" + kWindevMonitoringURL)).toStrictEqual(true);
+ assert.strictEqual(Agents.URI_CACHE.has("GET" + kWindevMonitoringURL), true);
});
it("should compute a windev URI (as WHATWG URL)", () => {
const localURL = new URL(kWindevMonitoringURL);
const result = Agents.computeURI("POST", localURL);
- expect(result.url.href).toStrictEqual(kWindevMonitoringURL);
- expect(result.agent).toStrictEqual(windev.agent);
+ assert.strictEqual(result.url.href, kWindevMonitoringURL);
+ assert.strictEqual(result.agent, windev.agent);
- expect(Agents.URICache.has("POST" + localURL.toString())).toStrictEqual(true);
+ assert.strictEqual(Agents.URI_CACHE.has("POST" + localURL.toString()), true);
});
it("should return cached entry", () => {
- Agents.URICache.set("GET" + kWindevMonitoringURL, true as any);
+ Agents.URI_CACHE.set("GET" + kWindevMonitoringURL, true as any);
const result = Agents.computeURI("GET", kWindevMonitoringURL) as unknown as boolean;
- expect(result).toStrictEqual(true);
+ assert.strictEqual(result, true);
});
it("should not return cached entry because method doesn't match", () => {
- Agents.URICache.set("POST" + kWindevMonitoringURL, true as any);
+ Agents.URI_CACHE.set("POST" + kWindevMonitoringURL, true as any);
const result = Agents.computeURI("GET", kWindevMonitoringURL);
- expect(result.url.href).toStrictEqual(kWindevMonitoringURL);
- expect(result.agent).toStrictEqual(windev.agent);
+ assert.strictEqual(result.url.href, kWindevMonitoringURL);
+ assert.strictEqual(result.agent, windev.agent);
- expect(Agents.URICache.has("GET" + kWindevMonitoringURL)).toStrictEqual(true);
+ assert.strictEqual(Agents.URI_CACHE.has("GET" + kWindevMonitoringURL), true);
});
it("should compute an URL not related to any local agents", () => {
const stringURL = "https://www.linkedin.com/feed/";
const result = Agents.computeURI("GET", new URL("", stringURL));
- expect(result.url.href).toStrictEqual(stringURL);
- expect(result.agent).toStrictEqual(null);
- expect(result.limit).toStrictEqual(undefined);
+ assert.strictEqual(result.url.href, stringURL);
+ assert.strictEqual(result.agent, null);
+ assert.strictEqual(result.limit, undefined);
});
});
diff --git a/test/helpers.ts b/test/helpers.ts
index b2b287e..4479f19 100644
--- a/test/helpers.ts
+++ b/test/helpers.ts
@@ -6,15 +6,10 @@ import { CustomHttpAgent, agents } from "../src/agents";
const windev: CustomHttpAgent = {
customPath: "windev",
- domains: new Set([
- "ws.dev.myunisoft.tech"
- ]),
+ origin: "https://ws.dev.myunisoft.tech",
agent: new undici.Agent({
connections: 500
- }),
- prod: "https://ws.dev.myunisoft.tech",
- preprod: "https://ws.dev.myunisoft.tech",
- dev: "https://ws.dev.myunisoft.tech"
+ })
};
agents.add(windev);
diff --git a/test/jest.setup.js b/test/jest.setup.js
deleted file mode 100644
index 33a2fba..0000000
--- a/test/jest.setup.js
+++ /dev/null
@@ -1 +0,0 @@
-jest.setTimeout(120_000);
diff --git a/test/request.spec.ts b/test/request.test.ts
similarity index 64%
rename from test/request.spec.ts
rename to test/request.test.ts
index 7c94354..bff4592 100644
--- a/test/request.spec.ts
+++ b/test/request.test.ts
@@ -1,20 +1,26 @@
+// Import Node.js Dependencies
+import { describe, it, before, after } from "node:test";
+import assert from "node:assert";
+
// Import Third-party Dependencies
import { FastifyInstance } from "fastify";
+import isHtml from "is-html";
// Import Internal Dependencies
-import { get, post, put, patch, del, safeGet } from "../src/index";
-import { isHTTPError } from "../src/utils";
-
-// Helpers and mock
-import { createServer } from "./server/index";
-import { windev } from "./helpers";
+import {
+ get, post, put, patch, del, safeGet,
+ Agent, interceptors
+} from "../src/index.js";
+import { isHTTPError } from "../src/utils.js";
+import { createServer } from "./server/index.js";
+import { windev } from "./helpers.js";
let httpServer: FastifyInstance;
-beforeAll(async() => {
+before(async() => {
httpServer = await createServer();
});
-afterAll(async() => {
+after(async() => {
await httpServer.close();
});
@@ -22,8 +28,8 @@ describe("http.get", () => {
it("should GET uptime from local fastify server", async() => {
const { data } = await get<{ uptime: number; }>("/local/");
- expect("uptime" in data).toStrictEqual(true);
- expect(typeof data.uptime).toStrictEqual("number");
+ assert.ok("uptime" in data);
+ assert.equal(typeof data.uptime, "number");
});
it("should GET query parameters provided to fastify", async() => {
@@ -33,15 +39,19 @@ describe("http.get", () => {
})
});
- expect("name" in data).toStrictEqual(true);
- expect(data.name).toStrictEqual("foobar");
+ assert.ok("name" in data);
+ assert.equal(data.name, "foobar");
});
it("should GET uptime by following an HTTP redirection from local fastify server", async() => {
- const { data } = await get<{ uptime: number; }>("/local/redirect", { maxRedirections: 1 });
+ const agent = new Agent()
+ .compose(interceptors.redirect({ maxRedirections: 2 }));
+ const { data } = await get<{ uptime: number; }>("/local/redirect", {
+ agent
+ });
- expect("uptime" in data).toStrictEqual(true);
- expect(typeof data.uptime).toStrictEqual("number");
+ assert.ok("uptime" in data);
+ assert.equal(typeof data.uptime, "number");
});
it("should GET uptime through a limit function handler from local fastify server", async() => {
@@ -54,15 +64,15 @@ describe("http.get", () => {
};
const { data } = await get<{ uptime: number; }>("/local/", { limit });
- expect("uptime" in data).toStrictEqual(true);
- expect(typeof data.uptime).toStrictEqual("number");
- expect(executed).toStrictEqual(true);
+ assert.ok("uptime" in data);
+ assert.equal(typeof data.uptime, "number");
+ assert.equal(executed, true);
});
it("should GET response from windev ws-monitoring endpoint (without Agent)", async() => {
const { data } = await get("/windev/ws_monitoring");
- expect(data).toStrictEqual(true);
+ assert.equal(data, true);
});
it("should GET response from windev ws-monitoring endpoint (with Agent)", async() => {
@@ -70,43 +80,43 @@ describe("http.get", () => {
agent: windev.agent
});
- expect(data).toStrictEqual(true);
+ assert.equal(data, true);
});
it("should GET json response from node.js health endpoint", async() => {
const { data } = await get("https://app.dev.myunisoft.tech/api/authenticate/healthz");
- expect(Object.keys(data).sort()).toMatchObject([
+ assert.deepEqual(Object.keys(data).sort(), [
"status", "version", "description", "checks"
].sort());
});
- it("should throw a 404 Not Found error because the path is not known", async() => {
- expect.assertions(4);
+ it("should throw a 404 Not Found error because the path is not known", async(t) => {
+ t.plan(4);
try {
await get("/windev/hlkezcjcke");
}
catch (error: any) {
- expect(error.name).toStrictEqual("HttpieOnHttpError");
- expect(error.statusCode).toStrictEqual(404);
- expect(error.statusMessage).toStrictEqual("Not Found");
- expect(error.data).toMatchSnapshot();
+ t.assert.equal(error.name, "HttpieOnHttpError");
+ t.assert.equal(error.statusCode, 404);
+ t.assert.equal(error.statusMessage, "Not Found");
+ t.assert.equal(isHtml(error.data), true);
}
});
- it("should throw a 'HttpieParserError' with jsonError endpoint from local fastify server", async() => {
- expect.assertions(4);
+ it("should throw a 'HttpieParserError' with jsonError endpoint from local fastify server", async(t) => {
+ t.plan(4);
const expectedPayload = "{ 'foo': bar }";
try {
await get("/local/jsonError");
}
catch (error: any) {
- expect(error.name).toStrictEqual("ResponseParsingError");
- expect(error.reason.name).toStrictEqual("SyntaxError");
- expect(error.text).toStrictEqual(expectedPayload);
- expect(error.buffer).toStrictEqual(Buffer.from(expectedPayload));
+ t.assert.equal(error.name, "ResponseParsingError");
+ t.assert.equal(error.reason.name, "SyntaxError");
+ t.assert.equal(error.text, expectedPayload);
+ t.assert.equal(Buffer.from(expectedPayload).compare(error.buffer), 0);
}
});
});
@@ -123,8 +133,8 @@ describe("http.post", () => {
};
const { data } = await post("https://jsonplaceholder.typicode.com/posts", { body });
- expect(typeof data.userId).toStrictEqual("number");
- expect(data).toMatchObject(body);
+ assert.equal(typeof data.userId, "number");
+ assert.partialDeepStrictEqual(data, body);
});
});
@@ -138,7 +148,7 @@ describe("http.put", () => {
};
const { data } = await put("https://jsonplaceholder.typicode.com/posts/1", { body });
- expect(data).toEqual(body);
+ assert.deepEqual(data, body);
});
});
@@ -153,7 +163,7 @@ describe("http.patch", () => {
const { data } = await patch("https://jsonplaceholder.typicode.com/posts/1", {
body: { title: "foo" }
});
- expect(data).toMatchObject(body);
+ assert.partialDeepStrictEqual(data, body);
});
});
@@ -162,7 +172,7 @@ describe("http.del", () => {
const { statusCode } = await del("https://jsonplaceholder.typicode.com/posts/1", {
body: { title: "foo" }
});
- expect(statusCode).toStrictEqual(200);
+ assert.equal(statusCode, 200);
});
});
@@ -170,26 +180,26 @@ describe("http.safeGet", () => {
it("should GET uptime from local fastify server", async() => {
const result = await safeGet<{ uptime: number; }, any>("/local/");
- expect(result.ok).toStrictEqual(true);
+ assert.ok(result.ok);
const { data } = result.unwrap();
- expect("uptime" in data).toStrictEqual(true);
- expect(typeof data.uptime).toStrictEqual("number");
+ assert.ok("uptime" in data);
+ assert.equal(typeof data.uptime, "number");
});
- it("should throw a 404 Not Found error because the path is not known", async() => {
- expect.assertions(5);
+ it("should throw a 404 Not Found error because the path is not known", async(t) => {
+ t.plan(4);
const result = await safeGet("/windev/hlkezcjcke");
- expect(result.err).toStrictEqual(true);
+ assert.ok(result.err);
if (result.err) {
const error = result.val;
if (isHTTPError(error)) {
- expect(error.name).toStrictEqual("HttpieOnHttpError");
- expect(error.statusCode).toStrictEqual(404);
- expect(error.statusMessage).toStrictEqual("Not Found");
- expect(error.data).toMatchSnapshot();
+ t.assert.equal(error.name, "HttpieOnHttpError");
+ t.assert.equal(error.statusCode, 404);
+ t.assert.equal(error.statusMessage, "Not Found");
+ t.assert.equal(isHtml(error.data), true);
}
}
});
diff --git a/test/request2.spec.ts b/test/request2.spec.ts
deleted file mode 100644
index e0b7766..0000000
--- a/test/request2.spec.ts
+++ /dev/null
@@ -1,1991 +0,0 @@
-/* eslint-disable max-lines */
-// Import Third-Party Dependencies
-import { Interceptable, MockAgent, setGlobalDispatcher } from "undici";
-
-// Import Internal Dependencies
-import { request } from "../src/request";
-import { brotliCompress, deflate, gzip } from "zlib";
-import { promisify } from "util";
-import { isHTTPError, isHttpieError } from "../src";
-import { randomInt } from "crypto";
-
-// CONSTANTS
-const kUrl = "http://test.com";
-const kAsyncGzip = promisify(gzip);
-const kAsyncBrotli = promisify(brotliCompress);
-const kAsyncDeflate = promisify(deflate);
-
-// VARS
-let pool: Interceptable;
-
-describe("Httpie.safeRequest", () => {
- beforeAll(() => {
- const mockAgent = new MockAgent();
- setGlobalDispatcher(mockAgent);
- mockAgent.disableNetConnect();
-
- pool = mockAgent.get(kUrl);
- });
-
- describe("with ThrowOnHttpError", () => {
- describe("GET", () => {
- it("should throw if the response status code is higher than 400", async() => {
- expect.assertions(4);
-
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = randomInt(400, 503);
- const headers = { "content-type": "text/html" };
- const payload = Buffer.from("Body");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- await request(target.method as any, kUrl + target.path);
- }
- catch (error: any) {
- expect(isHTTPError(error)).toBeTruthy();
- expect(error.statusCode).toBe(statusCode);
- expect(error.data).toBe(payload.toString());
- expect(error.headers).toMatchObject(headers);
- }
- });
-
- it("should not throw if the response status code is lower than 400", async() => {
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = randomInt(200, 399);
- const headers = { "content-type": "text/html" };
- const payload = Buffer.from("Body");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path);
-
- expect(response.statusCode).toBe(statusCode);
- expect(response.data).toBe(payload.toString());
- expect(response.headers).toMatchObject(headers);
- });
- });
-
- describe("POST", () => {
- it("should throw if the response status code is higher than 400", async() => {
- expect.assertions(4);
-
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = randomInt(400, 503);
- const headers = { "content-type": "text/html" };
- const payload = Buffer.from("Body");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- await request(target.method as any, kUrl + target.path);
- }
- catch (error: any) {
- expect(isHTTPError(error)).toBeTruthy();
- expect(error.statusCode).toBe(statusCode);
- expect(error.data).toBe(payload.toString());
- expect(error.headers).toMatchObject(headers);
- }
- });
-
- it("should not throw if the response status code is lower than 400", async() => {
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = randomInt(200, 399);
- const headers = { "content-type": "text/html" };
- const payload = Buffer.from("Body");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path);
-
- expect(response.statusCode).toBe(statusCode);
- expect(response.data).toBe(payload.toString());
- expect(response.headers).toMatchObject(headers);
- });
- });
-
- describe("PUT", () => {
- it("should throw if the response status code is higher than 400", async() => {
- expect.assertions(4);
-
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = randomInt(400, 503);
- const headers = { "content-type": "text/html" };
- const payload = Buffer.from("Body");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- await request(target.method as any, kUrl + target.path);
- }
- catch (error: any) {
- expect(isHTTPError(error)).toBeTruthy();
- expect(error.statusCode).toBe(statusCode);
- expect(error.data).toBe(payload.toString());
- expect(error.headers).toMatchObject(headers);
- }
- });
-
- it("should not throw if the response status code is lower than 400", async() => {
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = randomInt(200, 399);
- const headers = { "content-type": "text/html" };
- const payload = Buffer.from("Body");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path);
-
- expect(response.statusCode).toBe(statusCode);
- expect(response.data).toBe(payload.toString());
- expect(response.headers).toMatchObject(headers);
- });
- });
-
- describe("DELETE", () => {
- it("should throw if the response status code is higher than 400", async() => {
- expect.assertions(4);
-
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = randomInt(400, 503);
- const headers = { "content-type": "text/html" };
- const payload = Buffer.from("Body");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- await request(target.method as any, kUrl + target.path);
- }
- catch (error: any) {
- expect(isHTTPError(error)).toBeTruthy();
- expect(error.statusCode).toBe(statusCode);
- expect(error.data).toBe(payload.toString());
- expect(error.headers).toMatchObject(headers);
- }
- });
-
- it("should not throw if the response status code is lower than 400", async() => {
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = randomInt(200, 399);
- const headers = { "content-type": "text/html" };
- const payload = Buffer.from("Body");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path);
-
- expect(response.statusCode).toBe(statusCode);
- expect(response.data).toBe(payload.toString());
- expect(response.headers).toMatchObject(headers);
- });
- });
- });
-
- describe("without ThrowOnHttpError", () => {
- describe("GET", () => {
- it("should not throw if the response status code is higher than 400", async() => {
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = randomInt(400, 503);
- const headers = { "content-type": "text/html" };
- const payload = Buffer.from("Body");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path, { throwOnHttpError: false });
-
- expect(response.statusCode).toBe(statusCode);
- expect(response.data).toBe(payload.toString());
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should not throw if the response status code is lower than 400", async() => {
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = randomInt(200, 399);
- const headers = { "content-type": "text/html" };
- const payload = Buffer.from("Body");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path, { throwOnHttpError: false });
-
- expect(response.statusCode).toBe(statusCode);
- expect(response.data).toBe(payload.toString());
- expect(response.headers).toMatchObject(headers);
- });
- });
-
- describe("POST", () => {
- it("should not throw if the response status code is higher than 400", async() => {
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = randomInt(400, 503);
- const headers = { "content-type": "text/html" };
- const payload = Buffer.from("Body");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path, { throwOnHttpError: false });
-
- expect(response.statusCode).toBe(statusCode);
- expect(response.data).toBe(payload.toString());
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should not throw if the response status code is lower than 400", async() => {
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = randomInt(200, 399);
- const headers = { "content-type": "text/html" };
- const payload = Buffer.from("Body");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path, { throwOnHttpError: false });
-
- expect(response.statusCode).toBe(statusCode);
- expect(response.data).toBe(payload.toString());
- expect(response.headers).toMatchObject(headers);
- });
- });
-
- describe("PUT", () => {
- it("should not throw if the response status code is higher than 400", async() => {
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = randomInt(400, 503);
- const headers = { "content-type": "text/html" };
- const payload = Buffer.from("Body");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path, { throwOnHttpError: false });
-
- expect(response.statusCode).toBe(statusCode);
- expect(response.data).toBe(payload.toString());
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should not throw if the response status code is lower than 400", async() => {
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = randomInt(200, 399);
- const headers = { "content-type": "text/html" };
- const payload = Buffer.from("Body");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path, { throwOnHttpError: false });
-
- expect(response.statusCode).toBe(statusCode);
- expect(response.data).toBe(payload.toString());
- expect(response.headers).toMatchObject(headers);
- });
- });
-
- describe("DELETE", () => {
- it("should not throw if the response status code is higher than 400", async() => {
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = randomInt(400, 503);
- const headers = { "content-type": "text/html" };
- const payload = Buffer.from("Body");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path, { throwOnHttpError: false });
-
- expect(response.statusCode).toBe(statusCode);
- expect(response.data).toBe(payload.toString());
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should not throw if the response status code is lower than 400", async() => {
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = randomInt(200, 399);
- const headers = { "content-type": "text/html" };
- const payload = Buffer.from("Body");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path, { throwOnHttpError: false });
-
- expect(response.statusCode).toBe(statusCode);
- expect(response.data).toBe(payload.toString());
- expect(response.headers).toMatchObject(headers);
- });
- });
- });
-
- describe("PARSE mode (default)", () => {
- describe("GET", () => {
- it("should return a parsed response as text when 'content-type' header starts with 'text/'", async() => {
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/klsmdkf" };
- const payload = "La data.";
- const buf = Buffer.from(payload);
-
- pool.intercept(target).reply(statusCode, buf, { headers });
-
- const response = await request(target.method as any, kUrl + target.path);
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(statusCode);
- });
-
- it("should return a parsed response as object when 'content-type' header is set with 'application/json'", async() => {
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "application/json" };
- const payload = { my: "object" };
- const buf = Buffer.from(JSON.stringify(payload));
-
- pool.intercept(target).reply(statusCode, buf, { headers });
-
- const response = await request(target.method as any, kUrl + target.path);
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(statusCode);
- });
-
- it("should return a buffer when 'content-type' header is set with 'application/pdf'", async() => {
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "application/pdf" };
- const payload = Buffer.from("mon pdf");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path);
-
- expect(response.data).toStrictEqual(Buffer.from(payload));
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(statusCode);
- });
-
- it("should return a buffer when 'content-type' header is set with unsupported value", async() => {
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "application/msword" };
- const payload = Buffer.from(JSON.stringify({ my: "object" }));
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path);
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should throw when 'content-type' header is set with unsupported value", async() => {
- expect.assertions(5);
-
- const target = {
- method: "GET",
- path: "/test"
- };
- const statusCode = 200;
- const headers = { "content-type": "unknown" };
- const payload = Buffer.from(JSON.stringify({ my: "object" }));
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- await request(target.method as any, kUrl + target.path);
- }
- catch (error: any) {
- expect(isHttpieError(error)).toBeTruthy();
- expect(error.message).toStrictEqual(
- "An unexpected error occurred when trying to parse the response body (reason: 'invalid media type')."
- );
- expect(error.buffer).toStrictEqual(payload);
- expect(error.headers).toMatchObject(headers);
- expect(error.statusCode).toBe(200);
- }
- });
-
- it("should throw when 'content-encoding' header is set with unsupported value", async() => {
- expect.assertions(5);
-
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const payload = await kAsyncGzip("Mon document");
- const headers = { "content-encoding": "unknown" };
- const statusCode = 200;
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- await request(target.method as any, kUrl + target.path);
- }
- catch (error: any) {
- expect(error.message).toStrictEqual("Unsupported encoding 'unknown'.");
- expect(error.buffer).toStrictEqual(payload);
- expect(error.headers).toMatchObject(headers);
- expect(error.statusCode).toBe(statusCode);
- expect(isHttpieError(error)).toBeTruthy();
- }
- });
-
- it("should decompress data when 'content-encoding' header is set with 'gzip'", async() => {
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "gzip" };
- const payload = Buffer.from("Payload");
- const compressedPayload = await kAsyncGzip(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path);
-
- expect(response.data).toStrictEqual(payload.toString());
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(statusCode);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'x-gzip'", async() => {
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "x-gzip" };
- const payload = "Payload";
- const compressedPayload = await kAsyncGzip(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path);
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'br'", async() => {
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "br" };
- const payload = "Payload";
- const compressedPayload = await kAsyncBrotli(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path);
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'deflate'", async() => {
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "deflate" };
- const payload = "Payload";
- const compressedPayload = await kAsyncDeflate(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path);
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(200);
- });
- });
-
- describe("POST", () => {
- it("should return a parsed response as text when 'content-type' header starts with 'text/'", async() => {
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/klsmdkf" };
- const payload = "La data.";
- const buf = Buffer.from(payload);
-
- pool.intercept(target).reply(statusCode, buf, { headers });
-
- const response = await request(target.method as any, kUrl + target.path);
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(statusCode);
- });
-
- it("should return a parsed response as object when 'content-type' header is set with 'application/json'", async() => {
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "application/json" };
- const payload = { my: "object" };
- const buf = Buffer.from(JSON.stringify(payload));
-
- pool.intercept(target).reply(statusCode, buf, { headers });
-
- const response = await request(target.method as any, kUrl + target.path);
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(statusCode);
- });
-
- it("should return a buffer when 'content-type' header is set with 'application/pdf'", async() => {
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "application/pdf" };
- const payload = Buffer.from("mon pdf");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path);
-
- expect(response.data).toStrictEqual(Buffer.from(payload));
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(statusCode);
- });
-
- it("should return a buffer when 'content-type' header is set with unsupported value", async() => {
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "application/msword" };
- const payload = Buffer.from(JSON.stringify({ my: "object" }));
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path);
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should throw when 'content-type' header is set with unsupported value", async() => {
- expect.assertions(5);
-
- const target = {
- method: "POST",
- path: "/test"
- };
- const statusCode = 200;
- const headers = { "content-type": "unknown" };
- const payload = Buffer.from(JSON.stringify({ my: "object" }));
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- await request(target.method as any, kUrl + target.path);
- }
- catch (error: any) {
- expect(isHttpieError(error)).toBeTruthy();
- expect(error.message).toStrictEqual(
- "An unexpected error occurred when trying to parse the response body (reason: 'invalid media type')."
- );
- expect(error.buffer).toStrictEqual(payload);
- expect(error.headers).toMatchObject(headers);
- expect(error.statusCode).toBe(200);
- }
- });
-
- it("should throw when 'content-encoding' header is set with unsupported value", async() => {
- expect.assertions(5);
-
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const payload = await kAsyncGzip("Mon document");
- const headers = { "content-encoding": "unknown" };
- const statusCode = 200;
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- await request(target.method as any, kUrl + target.path);
- }
- catch (error: any) {
- expect(error.message).toStrictEqual("Unsupported encoding 'unknown'.");
- expect(error.buffer).toStrictEqual(payload);
- expect(error.headers).toMatchObject(headers);
- expect(error.statusCode).toBe(statusCode);
- expect(isHttpieError(error)).toBeTruthy();
- }
- });
-
- it("should decompress data when 'content-encoding' header is set with 'gzip'", async() => {
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "gzip" };
- const payload = Buffer.from("Payload");
- const compressedPayload = await kAsyncGzip(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path);
-
- expect(response.data).toStrictEqual(payload.toString());
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(statusCode);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'x-gzip'", async() => {
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "x-gzip" };
- const payload = "Payload";
- const compressedPayload = await kAsyncGzip(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path);
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'br'", async() => {
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "br" };
- const payload = "Payload";
- const compressedPayload = await kAsyncBrotli(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path);
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'deflate'", async() => {
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "deflate" };
- const payload = "Payload";
- const compressedPayload = await kAsyncDeflate(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path);
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(200);
- });
- });
-
- describe("PUT", () => {
- it("should return a parsed response as text when 'content-type' header starts with 'text/'", async() => {
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/klsmdkf" };
- const payload = "La data.";
- const buf = Buffer.from(payload);
-
- pool.intercept(target).reply(statusCode, buf, { headers });
-
- const response = await request(target.method as any, kUrl + target.path);
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(statusCode);
- });
-
- it("should return a parsed response as object when 'content-type' header is set with 'application/json'", async() => {
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "application/json" };
- const payload = { my: "object" };
- const buf = Buffer.from(JSON.stringify(payload));
-
- pool.intercept(target).reply(statusCode, buf, { headers });
-
- const response = await request(target.method as any, kUrl + target.path);
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(statusCode);
- });
-
- it("should return a buffer when 'content-type' header is set with 'application/pdf'", async() => {
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "application/pdf" };
- const payload = Buffer.from("mon pdf");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path);
-
- expect(response.data).toStrictEqual(Buffer.from(payload));
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(statusCode);
- });
-
- it("should return a buffer when 'content-type' header is set with unsupported value", async() => {
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "application/msword" };
- const payload = Buffer.from(JSON.stringify({ my: "object" }));
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path);
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should throw when 'content-type' header is set with unsupported value", async() => {
- expect.assertions(5);
-
- const target = {
- method: "PUT",
- path: "/test"
- };
- const statusCode = 200;
- const headers = { "content-type": "unknown" };
- const payload = Buffer.from(JSON.stringify({ my: "object" }));
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- await request(target.method as any, kUrl + target.path);
- }
- catch (error: any) {
- expect(isHttpieError(error)).toBeTruthy();
- expect(error.message).toStrictEqual(
- "An unexpected error occurred when trying to parse the response body (reason: 'invalid media type')."
- );
- expect(error.buffer).toStrictEqual(payload);
- expect(error.headers).toMatchObject(headers);
- expect(error.statusCode).toBe(200);
- }
- });
-
- it("should throw when 'content-encoding' header is set with unsupported value", async() => {
- expect.assertions(5);
-
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const payload = await kAsyncGzip("Mon document");
- const headers = { "content-encoding": "unknown" };
- const statusCode = 200;
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- await request(target.method as any, kUrl + target.path);
- }
- catch (error: any) {
- expect(error.message).toStrictEqual("Unsupported encoding 'unknown'.");
- expect(error.buffer).toStrictEqual(payload);
- expect(error.headers).toMatchObject(headers);
- expect(error.statusCode).toBe(statusCode);
- expect(isHttpieError(error)).toBeTruthy();
- }
- });
-
- it("should decompress data when 'content-encoding' header is set with 'gzip'", async() => {
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "gzip" };
- const payload = Buffer.from("Payload");
- const compressedPayload = await kAsyncGzip(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path);
-
- expect(response.data).toStrictEqual(payload.toString());
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(statusCode);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'x-gzip'", async() => {
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "x-gzip" };
- const payload = "Payload";
- const compressedPayload = await kAsyncGzip(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path);
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'br'", async() => {
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "br" };
- const payload = "Payload";
- const compressedPayload = await kAsyncBrotli(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path);
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'deflate'", async() => {
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "deflate" };
- const payload = "Payload";
- const compressedPayload = await kAsyncDeflate(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path);
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(200);
- });
- });
-
- describe("DELETE", () => {
- it("should return a parsed response as text when 'content-type' header starts with 'text/'", async() => {
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/klsmdkf" };
- const payload = "La data.";
- const buf = Buffer.from(payload);
-
- pool.intercept(target).reply(statusCode, buf, { headers });
-
- const response = await request(target.method as any, kUrl + target.path);
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(statusCode);
- });
-
- it("should return a parsed response as object when 'content-type' header is set with 'application/json'", async() => {
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "application/json" };
- const payload = { my: "object" };
- const buf = Buffer.from(JSON.stringify(payload));
-
- pool.intercept(target).reply(statusCode, buf, { headers });
-
- const response = await request(target.method as any, kUrl + target.path);
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(statusCode);
- });
-
- it("should return a buffer when 'content-type' header is set with 'application/pdf'", async() => {
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "application/pdf" };
- const payload = Buffer.from("mon pdf");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path);
-
- expect(response.data).toStrictEqual(Buffer.from(payload));
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(statusCode);
- });
-
- it("should return a buffer when 'content-type' header is set with unsupported value", async() => {
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "application/msword" };
- const payload = Buffer.from(JSON.stringify({ my: "object" }));
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path);
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should throw when 'content-type' header is set with unsupported value", async() => {
- expect.assertions(5);
-
- const target = {
- method: "DELETE",
- path: "/test"
- };
- const statusCode = 200;
- const headers = { "content-type": "unknown" };
- const payload = Buffer.from(JSON.stringify({ my: "object" }));
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- await request(target.method as any, kUrl + target.path);
- }
- catch (error: any) {
- expect(isHttpieError(error)).toBeTruthy();
- expect(error.message).toStrictEqual(
- "An unexpected error occurred when trying to parse the response body (reason: 'invalid media type')."
- );
- expect(error.buffer).toStrictEqual(payload);
- expect(error.headers).toMatchObject(headers);
- expect(error.statusCode).toBe(200);
- }
- });
-
- it("should throw when 'content-encoding' header is set with unsupported value", async() => {
- expect.assertions(5);
-
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const payload = await kAsyncGzip("Mon document");
- const headers = { "content-encoding": "unknown" };
- const statusCode = 200;
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- await request(target.method as any, kUrl + target.path);
- }
- catch (error: any) {
- expect(error.message).toStrictEqual("Unsupported encoding 'unknown'.");
- expect(error.buffer).toStrictEqual(payload);
- expect(error.headers).toMatchObject(headers);
- expect(error.statusCode).toBe(statusCode);
- expect(isHttpieError(error)).toBeTruthy();
- }
- });
-
- it("should decompress data when 'content-encoding' header is set with 'gzip'", async() => {
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "gzip" };
- const payload = Buffer.from("Payload");
- const compressedPayload = await kAsyncGzip(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path);
-
- expect(response.data).toStrictEqual(payload.toString());
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(statusCode);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'x-gzip'", async() => {
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "x-gzip" };
- const payload = "Payload";
- const compressedPayload = await kAsyncGzip(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path);
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'br'", async() => {
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "br" };
- const payload = "Payload";
- const compressedPayload = await kAsyncBrotli(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path);
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'deflate'", async() => {
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "deflate" };
- const payload = "Payload";
- const compressedPayload = await kAsyncDeflate(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path);
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(200);
- });
- });
- });
-
- describe("DECOMPRESS mode", () => {
- describe("GET", () => {
- it("should return a buffer without parsing it even if 'content-type' header exists", async() => {
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/klsmdkf" };
- const payload = Buffer.from("La data.");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path, { mode: "decompress" });
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should throw when 'content-encoding' header is set with unsupported value", async() => {
- expect.assertions(5);
-
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-encoding": "unknown" };
- const payload = Buffer.from("Mon document");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- await request(target.method as any, kUrl + target.path, { mode: "decompress" });
- }
- catch (error: any) {
- expect(error.message).toStrictEqual("Unsupported encoding 'unknown'.");
- expect(error.buffer).toMatchObject(payload);
- expect(error.headers).toMatchObject(headers);
- expect(isHttpieError(error)).toBeTruthy();
- expect(error.statusCode).toBe(200);
- }
- });
-
- it("should throw when 'content-encoding' header is invalid", async() => {
- expect.assertions(8);
-
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-encoding": "gzip" };
- const payload = await kAsyncBrotli("Mon document");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- await request(target.method as any, kUrl + target.path, { mode: "decompress" });
- }
- catch (error: any) {
- expect(error.reason).toBeTruthy();
- expect(error.message).toStrictEqual(
- "An unexpected error occurred when trying to decompress the response body (reason: 'incorrect header check')."
- );
- expect(error.buffer).toMatchObject(payload);
- expect(error.headers).toMatchObject(headers);
- expect(error.reason).toBeTruthy();
- expect(error.reason.message).toStrictEqual("incorrect header check");
- expect(isHttpieError(error)).toBeTruthy();
- expect(error.statusCode).toBe(200);
- }
- });
-
- it("should decompress data when 'content-encoding' header is set with 'gzip'", async() => {
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "gzip" };
- const payload = Buffer.from("payload");
- const compressedPayload = await kAsyncGzip("payload");
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path, { mode: "decompress" });
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'x-gzip'", async() => {
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "x-gzip" };
- const payload = Buffer.from("Payload");
- const compressedPayload = await kAsyncGzip(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path, { mode: "decompress" });
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'br'", async() => {
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const payload = Buffer.from("Payload");
- const compressedPayload = await kAsyncBrotli(payload);
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "br" };
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
- const response = await request(target.method as any, kUrl + target.path, { mode: "decompress" });
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'deflate'", async() => {
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const payload = Buffer.from("Payload");
- const compressedPayload = await kAsyncDeflate(payload);
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "deflate" };
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
- const response = await request(target.method as any, kUrl + target.path, { mode: "decompress" });
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
- });
-
- describe("POST", () => {
- it("should return a buffer without parsing it even if 'content-type' header exists", async() => {
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/klsmdkf" };
- const payload = Buffer.from("La data.");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path, { mode: "decompress" });
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should throw when 'content-encoding' header is set with unsupported value", async() => {
- expect.assertions(5);
-
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-encoding": "unknown" };
- const payload = Buffer.from("Mon document");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- await request(target.method as any, kUrl + target.path, { mode: "decompress" });
- }
- catch (error: any) {
- expect(error.message).toStrictEqual("Unsupported encoding 'unknown'.");
- expect(error.buffer).toMatchObject(payload);
- expect(error.headers).toMatchObject(headers);
- expect(isHttpieError(error)).toBeTruthy();
- expect(error.statusCode).toBe(200);
- }
- });
-
- it("should throw when 'content-encoding' header is invalid", async() => {
- expect.assertions(8);
-
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-encoding": "gzip" };
- const payload = await kAsyncBrotli("Mon document");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- await request(target.method as any, kUrl + target.path, { mode: "decompress" });
- }
- catch (error: any) {
- expect(error.reason).toBeTruthy();
- expect(error.message).toStrictEqual(
- "An unexpected error occurred when trying to decompress the response body (reason: 'incorrect header check')."
- );
- expect(error.buffer).toMatchObject(payload);
- expect(error.headers).toMatchObject(headers);
- expect(error.reason).toBeTruthy();
- expect(error.reason.message).toStrictEqual("incorrect header check");
- expect(isHttpieError(error)).toBeTruthy();
- expect(error.statusCode).toBe(200);
- }
- });
-
- it("should decompress data when 'content-encoding' header is set with 'gzip'", async() => {
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "gzip" };
- const payload = Buffer.from("payload");
- const compressedPayload = await kAsyncGzip("payload");
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path, { mode: "decompress" });
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'x-gzip'", async() => {
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "x-gzip" };
- const payload = Buffer.from("Payload");
- const compressedPayload = await kAsyncGzip(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path, { mode: "decompress" });
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'br'", async() => {
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const payload = Buffer.from("Payload");
- const compressedPayload = await kAsyncBrotli(payload);
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "br" };
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
- const response = await request(target.method as any, kUrl + target.path, { mode: "decompress" });
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'deflate'", async() => {
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const payload = Buffer.from("Payload");
- const compressedPayload = await kAsyncDeflate(payload);
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "deflate" };
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
- const response = await request(target.method as any, kUrl + target.path, { mode: "decompress" });
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
- });
-
- describe("PUT", () => {
- it("should return a buffer without parsing it even if 'content-type' header exists", async() => {
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/klsmdkf" };
- const payload = Buffer.from("La data.");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path, { mode: "decompress" });
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should throw when 'content-encoding' header is set with unsupported value", async() => {
- expect.assertions(5);
-
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-encoding": "unknown" };
- const payload = Buffer.from("Mon document");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- await request(target.method as any, kUrl + target.path, { mode: "decompress" });
- }
- catch (error: any) {
- expect(error.message).toStrictEqual("Unsupported encoding 'unknown'.");
- expect(error.buffer).toMatchObject(payload);
- expect(error.headers).toMatchObject(headers);
- expect(isHttpieError(error)).toBeTruthy();
- expect(error.statusCode).toBe(200);
- }
- });
-
- it("should throw when 'content-encoding' header is invalid", async() => {
- expect.assertions(8);
-
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-encoding": "gzip" };
- const payload = await kAsyncBrotli("Mon document");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- await request(target.method as any, kUrl + target.path, { mode: "decompress" });
- }
- catch (error: any) {
- expect(error.reason).toBeTruthy();
- expect(error.message).toStrictEqual(
- "An unexpected error occurred when trying to decompress the response body (reason: 'incorrect header check')."
- );
- expect(error.buffer).toMatchObject(payload);
- expect(error.headers).toMatchObject(headers);
- expect(error.reason).toBeTruthy();
- expect(error.reason.message).toStrictEqual("incorrect header check");
- expect(isHttpieError(error)).toBeTruthy();
- expect(error.statusCode).toBe(200);
- }
- });
-
- it("should decompress data when 'content-encoding' header is set with 'gzip'", async() => {
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "gzip" };
- const payload = Buffer.from("payload");
- const compressedPayload = await kAsyncGzip("payload");
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path, { mode: "decompress" });
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'x-gzip'", async() => {
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "x-gzip" };
- const payload = Buffer.from("Payload");
- const compressedPayload = await kAsyncGzip(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path, { mode: "decompress" });
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'br'", async() => {
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const payload = Buffer.from("Payload");
- const compressedPayload = await kAsyncBrotli(payload);
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "br" };
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
- const response = await request(target.method as any, kUrl + target.path, { mode: "decompress" });
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'deflate'", async() => {
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const payload = Buffer.from("Payload");
- const compressedPayload = await kAsyncDeflate(payload);
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "deflate" };
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
- const response = await request(target.method as any, kUrl + target.path, { mode: "decompress" });
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
- });
-
- describe("DELETE", () => {
- it("should return a buffer without parsing it even if 'content-type' header exists", async() => {
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/klsmdkf" };
- const payload = Buffer.from("La data.");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path, { mode: "decompress" });
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should throw when 'content-encoding' header is set with unsupported value", async() => {
- expect.assertions(5);
-
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-encoding": "unknown" };
- const payload = Buffer.from("Mon document");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- await request(target.method as any, kUrl + target.path, { mode: "decompress" });
- }
- catch (error: any) {
- expect(error.message).toStrictEqual("Unsupported encoding 'unknown'.");
- expect(error.buffer).toMatchObject(payload);
- expect(error.headers).toMatchObject(headers);
- expect(isHttpieError(error)).toBeTruthy();
- expect(error.statusCode).toBe(200);
- }
- });
-
- it("should throw when 'content-encoding' header is invalid", async() => {
- expect.assertions(8);
-
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-encoding": "gzip" };
- const payload = await kAsyncBrotli("Mon document");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- await request(target.method as any, kUrl + target.path, { mode: "decompress" });
- }
- catch (error: any) {
- expect(error.reason).toBeTruthy();
- expect(error.message).toStrictEqual(
- "An unexpected error occurred when trying to decompress the response body (reason: 'incorrect header check')."
- );
- expect(error.buffer).toMatchObject(payload);
- expect(error.headers).toMatchObject(headers);
- expect(error.reason).toBeTruthy();
- expect(error.reason.message).toStrictEqual("incorrect header check");
- expect(isHttpieError(error)).toBeTruthy();
- expect(error.statusCode).toBe(200);
- }
- });
-
- it("should decompress data when 'content-encoding' header is set with 'gzip'", async() => {
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "gzip" };
- const payload = Buffer.from("payload");
- const compressedPayload = await kAsyncGzip("payload");
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path, { mode: "decompress" });
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'x-gzip'", async() => {
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "x-gzip" };
- const payload = Buffer.from("Payload");
- const compressedPayload = await kAsyncGzip(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path, { mode: "decompress" });
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'br'", async() => {
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const payload = Buffer.from("Payload");
- const compressedPayload = await kAsyncBrotli(payload);
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "br" };
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
- const response = await request(target.method as any, kUrl + target.path, { mode: "decompress" });
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'deflate'", async() => {
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const payload = Buffer.from("Payload");
- const compressedPayload = await kAsyncDeflate(payload);
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "deflate" };
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
- const response = await request(target.method as any, kUrl + target.path, { mode: "decompress" });
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
- });
- });
-
- describe("RAW mode", () => {
- describe("GET", () => {
- it("should return a buffer without parsing it even if 'content-type' header exists", async() => {
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/klsmdkf" };
- const payload = Buffer.from("payload");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path, { mode: "raw" });
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(200);
- });
-
- it("should return a buffer without decompress it even if 'content-encoding' header exists", async() => {
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-encoding": "gzip" };
- const payload = await kAsyncGzip("Doc");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path, { mode: "raw" });
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(200);
- });
- });
-
- describe("POST", () => {
- it("should return a buffer without parsing it even if 'content-type' header exists", async() => {
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/klsmdkf" };
- const payload = Buffer.from("payload");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path, { mode: "raw" });
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(200);
- });
-
- it("should return a buffer without decompress it even if 'content-encoding' header exists", async() => {
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-encoding": "gzip" };
- const payload = await kAsyncGzip("Doc");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path, { mode: "raw" });
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(200);
- });
- });
-
- describe("PUT", () => {
- it("should return a buffer without parsing it even if 'content-type' header exists", async() => {
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/klsmdkf" };
- const payload = Buffer.from("payload");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path, { mode: "raw" });
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(200);
- });
-
- it("should return a buffer without decompress it even if 'content-encoding' header exists", async() => {
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-encoding": "gzip" };
- const payload = await kAsyncGzip("Doc");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path, { mode: "raw" });
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(200);
- });
- });
-
- describe("DELETE", () => {
- it("should return a buffer without parsing it even if 'content-type' header exists", async() => {
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/klsmdkf" };
- const payload = Buffer.from("payload");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path, { mode: "raw" });
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(200);
- });
-
- it("should return a buffer without decompress it even if 'content-encoding' header exists", async() => {
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-encoding": "gzip" };
- const payload = await kAsyncGzip("Doc");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const response = await request(target.method as any, kUrl + target.path, { mode: "raw" });
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(200);
- });
- });
- });
-});
diff --git a/test/request2.test.ts b/test/request2.test.ts
new file mode 100644
index 0000000..4d0a98a
--- /dev/null
+++ b/test/request2.test.ts
@@ -0,0 +1,489 @@
+// Import Node.js Dependencies
+import { describe, it, before } from "node:test";
+import { brotliCompress, deflate, gzip } from "node:zlib";
+import { promisify } from "node:util";
+import { randomInt } from "node:crypto";
+import assert from "node:assert";
+
+// Import Third-party Dependencies
+import { Interceptable, MockAgent, setGlobalDispatcher } from "undici";
+
+// Import Internal Dependencies
+import { HttpMethod, isHTTPError, isHttpieError, request } from "../src/index.js";
+
+// CONSTANTS
+const kUrl = "http://com";
+const kAsyncGzip = promisify(gzip);
+const kAsyncBrotli = promisify(brotliCompress);
+const kAsyncDeflate = promisify(deflate);
+
+// VARS
+let pool: Interceptable;
+
+describe("Httpie.safeRequest", () => {
+ before(() => {
+ const mockAgent = new MockAgent();
+ setGlobalDispatcher(mockAgent);
+ mockAgent.disableNetConnect();
+
+ pool = mockAgent.get(kUrl);
+ });
+
+ describe("with ThrowOnHttpError", () => {
+ describe("GET", () => {
+ it("should throw if the response status code is higher than 400", async(t) => {
+ t.plan(4);
+
+ const target = {
+ method: "GET",
+ path: "/test"
+ };
+
+ const statusCode = randomInt(400, 503);
+ const headers = { "content-type": "text/html" };
+ const payload = Buffer.from("Body");
+
+ pool.intercept(target).reply(statusCode, payload, { headers });
+
+ try {
+ await request(target.method as any, kUrl + target.path);
+ }
+ catch (error: any) {
+ t.assert.equal(isHTTPError(error), true);
+ t.assert.equal(error.statusCode, statusCode);
+ t.assert.equal(error.data, payload.toString());
+ t.assert.deepEqual(error.headers, headers);
+ }
+ });
+
+ it("should not throw if the response status code is lower than 400", async() => {
+ const target = {
+ method: "GET",
+ path: "/test"
+ };
+
+ const statusCode = randomInt(200, 399);
+ const headers = { "content-type": "text/html" };
+ const payload = Buffer.from("Body");
+
+ pool.intercept(target).reply(statusCode, payload, { headers });
+
+ const response = await request(target.method as any, kUrl + target.path);
+
+ assert.strictEqual(response.statusCode, statusCode);
+ assert.strictEqual(response.data, payload.toString());
+ assert.deepStrictEqual(response.headers, headers);
+ });
+ });
+
+ for (const method of ["POST", "PUT", "DELETE"] as const) {
+ describe(method, () => {
+ it("should throw if the response status code is higher than 400", async() => {
+ const target = { method, path: "/test" };
+ const statusCode = randomInt(400, 503);
+ const headers = { "content-type": "text/html" };
+ const payload = Buffer.from("Body");
+
+ pool.intercept(target).reply(statusCode, payload, { headers });
+
+ try {
+ await request(target.method, kUrl + target.path);
+ assert.fail("Expected an error to be thrown");
+ }
+ catch (error: any) {
+ assert.ok(isHTTPError(error));
+ assert.strictEqual(error.statusCode, statusCode);
+ assert.strictEqual(error.data, payload.toString());
+ assert.deepStrictEqual(error.headers, headers);
+ }
+ });
+
+ it("should not throw if the response status code is lower than 400", async() => {
+ const target = { method, path: "/test" };
+ const statusCode = randomInt(200, 399);
+ const headers = { "content-type": "text/html" };
+ const payload = Buffer.from("Body");
+
+ pool.intercept(target).reply(statusCode, payload, { headers });
+
+ const response = await request(target.method, kUrl + target.path);
+
+ assert.strictEqual(response.statusCode, statusCode);
+ assert.strictEqual(response.data, payload.toString());
+ assert.deepStrictEqual(response.headers, headers);
+ });
+ });
+ }
+ });
+
+ describe("without ThrowOnHttpError", () => {
+ describe("GET", () => {
+ it("should not throw if the response status code is higher than 400", async() => {
+ const target = { method: "GET", path: "/test" };
+ const statusCode = randomInt(400, 503);
+ const headers = { "content-type": "text/html" };
+ const payload = Buffer.from("Body");
+
+ pool.intercept(target).reply(statusCode, payload, { headers });
+
+ const response = await request(target.method as any, kUrl + target.path, { throwOnHttpError: false });
+
+ assert.strictEqual(response.statusCode, statusCode);
+ assert.strictEqual(response.data, payload.toString());
+ assert.deepStrictEqual(response.headers, headers);
+ });
+
+ it("should not throw if the response status code is lower than 400", async() => {
+ const target = { method: "GET", path: "/test" };
+ const statusCode = randomInt(200, 399);
+ const headers = { "content-type": "text/html" };
+ const payload = Buffer.from("Body");
+
+ pool.intercept(target).reply(statusCode, payload, { headers });
+
+ const response = await request(target.method as any, kUrl + target.path, { throwOnHttpError: false });
+
+ assert.strictEqual(response.statusCode, statusCode);
+ assert.strictEqual(response.data, payload.toString());
+ assert.deepStrictEqual(response.headers, headers);
+ });
+ });
+
+ for (const method of ["POST", "PUT", "DELETE"] as const) {
+ describe(method, () => {
+ it("should not throw if the response status code is higher than 400", async() => {
+ const target = { method, path: "/test" };
+ const statusCode = randomInt(400, 503);
+ const headers = { "content-type": "text/html" };
+ const payload = Buffer.from("Body");
+
+ pool.intercept(target).reply(statusCode, payload, { headers });
+
+ const response = await request(target.method, kUrl + target.path, { throwOnHttpError: false });
+
+ assert.strictEqual(response.statusCode, statusCode);
+ assert.strictEqual(response.data, payload.toString());
+ assert.deepStrictEqual(response.headers, headers);
+ });
+
+ it("should not throw if the response status code is lower than 400", async() => {
+ const target = { method, path: "/test" };
+ const statusCode = randomInt(200, 399);
+ const headers = { "content-type": "text/html" };
+ const payload = Buffer.from("Body");
+
+ pool.intercept(target).reply(statusCode, payload, { headers });
+
+ const response = await request(target.method, kUrl + target.path, { throwOnHttpError: false });
+
+ assert.strictEqual(response.statusCode, statusCode);
+ assert.strictEqual(response.data, payload.toString());
+ assert.deepStrictEqual(response.headers, headers);
+ });
+ });
+ }
+ });
+
+ describe("RAW mode", () => {
+ describe("GET", () => {
+ it("should return a buffer without parsing it even if 'content-type' header exists", async() => {
+ const target = { method: "GET", path: "/test" };
+ const statusCode = 200;
+ const headers = { "content-type": "text/klsmdkf" };
+ const payload = Buffer.from("payload");
+
+ pool.intercept(target).reply(statusCode, payload, { headers });
+
+ const response = await request(target.method as any, kUrl + target.path, { mode: "raw" });
+
+ assert.deepStrictEqual(response.data, payload);
+ assert.deepStrictEqual(response.headers, headers);
+ assert.strictEqual(response.statusCode, 200);
+ });
+
+ it("should return a buffer without decompress it even if 'content-encoding' header exists", async() => {
+ const target = { method: "GET", path: "/test" };
+ const statusCode = 200;
+ const headers = { "content-encoding": "gzip" };
+ const payload = await kAsyncGzip("Doc");
+
+ pool.intercept(target).reply(statusCode, payload, { headers });
+
+ const response = await request(target.method as any, kUrl + target.path, { mode: "raw" });
+
+ assert.deepStrictEqual(response.data, payload);
+ assert.deepStrictEqual(response.headers, headers);
+ assert.strictEqual(response.statusCode, 200);
+ });
+ });
+
+ for (const method of ["POST", "PUT", "DELETE"] as const) {
+ describe(method, () => {
+ it("should return a buffer without parsing it even if 'content-type' header exists", async() => {
+ const target = { method, path: "/test" };
+ const statusCode = 200;
+ const headers = { "content-type": "text/klsmdkf" };
+ const payload = Buffer.from("payload");
+
+ pool.intercept(target).reply(statusCode, payload, { headers });
+
+ const response = await request(target.method, kUrl + target.path, { mode: "raw" });
+
+ assert.deepStrictEqual(response.data, payload);
+ assert.deepStrictEqual(response.headers, headers);
+ assert.strictEqual(response.statusCode, 200);
+ });
+
+ it("should return a buffer without decompress it even if 'content-encoding' header exists", async() => {
+ const target = { method, path: "/test" };
+ const statusCode = 200;
+ const headers = { "content-encoding": "gzip" };
+ const payload = await kAsyncGzip("Doc");
+
+ pool.intercept(target).reply(statusCode, payload, { headers });
+
+ const response = await request(target.method, kUrl + target.path, { mode: "raw" });
+
+ assert.deepStrictEqual(response.data, payload);
+ assert.deepStrictEqual(response.headers, headers);
+ assert.strictEqual(response.statusCode, 200);
+ });
+ });
+ }
+ });
+
+ describe("PARSE mode (default)", () => {
+ const methods: HttpMethod[] = ["GET", "POST", "PUT", "DELETE"];
+
+ for (const method of methods) {
+ describe(method, () => {
+ it("should return a parsed response as text when 'content-type' header starts with 'text/'", async() => {
+ const target = { method, path: "/test" };
+ const payload = "La data.";
+ const buf = Buffer.from(payload);
+ const headers = { "content-type": "text/klsmdkf" };
+ const statusCode = 200;
+
+ pool.intercept(target).reply(statusCode, buf, { headers });
+
+ const response = await request(target.method, kUrl + target.path);
+
+ assert.strictEqual(response.data, payload);
+ assert.deepStrictEqual(response.headers, headers);
+ assert.strictEqual(response.statusCode, statusCode);
+ });
+
+ it("should return a parsed response as object when 'content-type' is 'application/json'", async() => {
+ const target = { method, path: "/test" };
+ const payload = { my: "object" };
+ const buf = Buffer.from(JSON.stringify(payload));
+ const headers = { "content-type": "application/json" };
+ const statusCode = 200;
+
+ pool.intercept(target).reply(statusCode, buf, { headers });
+
+ const response = await request(target.method, kUrl + target.path);
+
+ assert.deepStrictEqual(response.data, payload);
+ assert.deepStrictEqual(response.headers, headers);
+ assert.strictEqual(response.statusCode, statusCode);
+ });
+
+ it("should return a buffer when 'content-type' is 'application/pdf'", async() => {
+ const target = { method, path: "/test" };
+ const payload = Buffer.from("mon pdf");
+ const headers = { "content-type": "application/pdf" };
+ const statusCode = 200;
+
+ pool.intercept(target).reply(statusCode, payload, { headers });
+
+ const response = await request(target.method, kUrl + target.path);
+
+ assert.deepStrictEqual(response.data, payload);
+ assert.deepStrictEqual(response.headers, headers);
+ assert.strictEqual(response.statusCode, statusCode);
+ });
+
+ it("should return a buffer when 'content-type' is unsupported", async() => {
+ const target = { method, path: "/test" };
+ const payload = Buffer.from(JSON.stringify({ my: "object" }));
+ const headers = { "content-type": "application/msword" };
+ const statusCode = 200;
+
+ pool.intercept(target).reply(statusCode, payload, { headers });
+
+ const response = await request(target.method, kUrl + target.path);
+
+ assert.deepStrictEqual(response.data, payload);
+ assert.deepStrictEqual(response.headers, headers);
+ });
+
+ it("should throw when 'content-type' is unknown", async() => {
+ const target = { method, path: "/test" };
+ const payload = Buffer.from(JSON.stringify({ my: "object" }));
+ const headers = { "content-type": "unknown" };
+ const statusCode = 200;
+
+ pool.intercept(target).reply(statusCode, payload, { headers });
+
+ try {
+ await request(target.method, kUrl + target.path);
+ assert.fail("Expected error not thrown");
+ }
+ catch (error: any) {
+ assert.ok(isHttpieError(error));
+ assert.strictEqual(
+ error.message,
+ "An unexpected error occurred when trying to parse the response body (reason: 'invalid media type')."
+ );
+ assert.deepStrictEqual(error.headers, headers);
+ assert.strictEqual(error.statusCode, 200);
+ }
+ });
+
+ it("should throw when 'content-encoding' is unsupported", async() => {
+ const target = { method, path: "/test" };
+ const payload = await kAsyncGzip("Mon document");
+ const headers = { "content-encoding": "unknown" };
+ const statusCode = 200;
+
+ pool.intercept(target).reply(statusCode, payload, { headers });
+
+ try {
+ await request(target.method, kUrl + target.path);
+ assert.fail("Expected error not thrown");
+ }
+ catch (error: any) {
+ assert.strictEqual(error.message, "Unsupported encoding 'unknown'.");
+ assert.deepStrictEqual(error.buffer, payload);
+ assert.deepStrictEqual(error.headers, headers);
+ assert.strictEqual(error.statusCode, statusCode);
+ assert.ok(isHttpieError(error));
+ }
+ });
+
+ const encodings = [
+ { encoding: "gzip", compress: kAsyncGzip },
+ { encoding: "x-gzip", compress: kAsyncGzip },
+ { encoding: "br", compress: kAsyncBrotli },
+ { encoding: "deflate", compress: kAsyncDeflate }
+ ];
+
+ for (const { encoding, compress } of encodings) {
+ it(`should decompress data when 'content-encoding' is '${encoding}'`, async() => {
+ const target = { method, path: "/test" };
+ const payload = "Payload";
+ const compressedPayload = await compress(Buffer.from(payload));
+ const headers = {
+ "content-type": "text/html",
+ "content-encoding": encoding
+ };
+ const statusCode = 200;
+
+ pool.intercept(target).reply(statusCode, compressedPayload, { headers });
+
+ const response = await request(target.method, kUrl + target.path);
+
+ assert.strictEqual(response.data, payload);
+ assert.deepStrictEqual(response.headers, headers);
+ assert.strictEqual(response.statusCode, statusCode);
+ });
+ }
+ });
+ }
+ });
+
+ describe("DECOMPRESS mode", () => {
+ const methods: HttpMethod[] = ["GET", "POST", "PUT", "DELETE"];
+
+ for (const method of methods) {
+ describe(method, () => {
+ it("should return a buffer without parsing it even if 'content-type' header exists", async() => {
+ const target = { method, path: "/test" };
+ const statusCode = 200;
+ const headers = { "content-type": "text/klsmdkf" };
+ const payload = Buffer.from("La data.");
+
+ pool.intercept(target).reply(statusCode, payload, { headers });
+
+ const response = await request(target.method, kUrl + target.path, { mode: "decompress" });
+
+ assert.deepStrictEqual(response.data, payload);
+ assert.deepStrictEqual(response.headers, headers);
+ });
+
+ it("should throw when 'content-encoding' header is set with unsupported value", async() => {
+ const target = { method, path: "/test" };
+ const statusCode = 200;
+ const headers = { "content-encoding": "unknown" };
+ const payload = Buffer.from("Mon document");
+
+ pool.intercept(target).reply(statusCode, payload, { headers });
+
+ try {
+ await request(target.method, kUrl + target.path, { mode: "decompress" });
+ assert.fail("Expected an error to be thrown");
+ }
+ catch (error: any) {
+ assert.strictEqual(error.message, "Unsupported encoding 'unknown'.");
+ assert.deepStrictEqual(error.buffer, payload);
+ assert.deepStrictEqual(error.headers, headers);
+ assert.ok(isHttpieError(error));
+ assert.strictEqual(error.statusCode, 200);
+ }
+ });
+
+ it("should throw when 'content-encoding' header is invalid", async() => {
+ const target = { method, path: "/test" };
+ const statusCode = 200;
+ const headers = { "content-encoding": "gzip" };
+ const payload = await kAsyncBrotli("Mon document");
+
+ pool.intercept(target).reply(statusCode, payload, { headers });
+
+ try {
+ await request(target.method, kUrl + target.path, { mode: "decompress" });
+ assert.fail("Expected an error to be thrown");
+ }
+ catch (error: any) {
+ assert.ok(error.reason);
+ assert.strictEqual(
+ error.message,
+ "An unexpected error occurred when trying to decompress the response body (reason: 'incorrect header check')."
+ );
+ assert.deepStrictEqual(error.buffer, payload);
+ assert.deepStrictEqual(error.headers, headers);
+ assert.ok(error.reason);
+ assert.strictEqual(error.reason.message, "incorrect header check");
+ assert.ok(isHttpieError(error));
+ assert.strictEqual(error.statusCode, 200);
+ }
+ });
+
+ const encodings = [
+ { encoding: "gzip", compress: kAsyncGzip },
+ { encoding: "x-gzip", compress: kAsyncGzip },
+ { encoding: "br", compress: kAsyncBrotli },
+ { encoding: "deflate", compress: kAsyncDeflate }
+ ];
+
+ for (const { encoding, compress } of encodings) {
+ it(`should decompress data when 'content-encoding' header is set with '${encoding}'`, async() => {
+ const target = { method, path: "/test" };
+ const payload = Buffer.from("Payload");
+ const compressedPayload = await compress(payload);
+ const statusCode = 200;
+ const headers = { "content-type": "text/html", "content-encoding": encoding };
+
+ pool.intercept(target).reply(statusCode, compressedPayload, { headers });
+
+ const response = await request(target.method, kUrl + target.path, { mode: "decompress" });
+
+ assert.deepStrictEqual(response.data, payload);
+ assert.deepStrictEqual(response.headers, headers);
+ });
+ }
+ });
+ }
+ });
+});
diff --git a/test/retry.spec.ts b/test/retry.spec.ts
deleted file mode 100644
index 90f4a06..0000000
--- a/test/retry.spec.ts
+++ /dev/null
@@ -1,109 +0,0 @@
-// Import Third-party Dependencies
-import { FastifyInstance } from "fastify";
-
-// Import Internal Dependencies
-import { retry, get, policies } from "../src/index";
-
-// Helpers and mock
-import { createServer } from "./server/index";
-
-let httpServer: FastifyInstance;
-beforeAll(async() => {
- httpServer = await createServer("retry", 1337);
-});
-
-afterAll(async() => {
- await httpServer.close();
-});
-
-describe("retry (with default policy)", () => {
- it("should throw an Error because the number of retries has been exceeded", async() => {
- expect.assertions(1);
-
- try {
- await retry(() => {
- throw new Error("exceed");
- }, { factor: 1 });
- }
- catch (error: any) {
- expect(error.message).toStrictEqual("Exceeded the maximum number of allowed retries!");
- }
- });
-
- it("should succeed after one try", async() => {
- let count = 0;
-
- const { data, metrics } = await retry(() => {
- count++;
- if (count === 1) {
- throw new Error("oops");
- }
-
- return "hello world!";
- });
-
- expect(data).toStrictEqual("hello world!");
- expect(metrics.attempt).toStrictEqual(1);
- expect(typeof metrics.elapsedTimeoutTime).toStrictEqual("number");
- expect(typeof metrics.executionTimestamp).toStrictEqual("number");
- });
-
- it("should be stopped with Node.js AbortController", async() => {
- expect.assertions(1);
-
- let count = 0;
- const controller = new AbortController();
-
- try {
- await retry(() => {
- count++;
- if (count <= 2) {
- throw new Error("oops");
- }
- controller.abort();
-
- throw new Error("oops");
- }, { forever: true, signal: controller.signal });
- }
- catch (error: any) {
- expect(error.message).toStrictEqual("Aborted");
- }
- });
-});
-
-describe("retry (with http policy)", () => {
- it("should throw an Error because the number of retries has been exceeded", async() => {
- expect.assertions(1);
-
- try {
- await retry(async() => get("/retry/internalerror"), { factor: 1, retries: 2 }, policies.httpcode());
- }
- catch (error: any) {
- expect(error.message).toStrictEqual("Exceeded the maximum number of allowed retries!");
- }
- });
-
- it("should return the http error because the code (501) is not supported by the policy", async() => {
- expect.assertions(1);
-
- try {
- await retry(async() => get("/retry/notimplemented"), { factor: 1, retries: 2 }, policies.httpcode());
- }
- catch (error: any) {
- expect(error.message).toStrictEqual("Not Implemented");
- }
- });
-
- it("should include code 501 and all other default port", async() => {
- expect.assertions(1);
-
- try {
- const policy = policies.httpcode(new Set([501]), true);
-
- await retry(async() => get("/retry/notimplemented"), { factor: 1, retries: 2 }, policy);
- }
- catch (error: any) {
- expect(error.message).toStrictEqual("Exceeded the maximum number of allowed retries!");
- }
- });
-});
diff --git a/test/safeRequest.spec.ts b/test/safeRequest.spec.ts
deleted file mode 100644
index a8d6a80..0000000
--- a/test/safeRequest.spec.ts
+++ /dev/null
@@ -1,2152 +0,0 @@
-/* eslint-disable max-lines */
-// Import Third-Party Dependencies
-import { Interceptable, MockAgent, setGlobalDispatcher } from "undici";
-
-// Import Internal Dependencies
-import { safeDel, safeGet, safePost, safePut } from "../src/request";
-import { brotliCompress, deflate, gzip } from "zlib";
-import { promisify } from "util";
-import { isHTTPError, isHttpieError } from "../src";
-import { randomInt } from "crypto";
-
-// CONSTANTS
-const kUrl = "http://test.com";
-const kAsyncGzip = promisify(gzip);
-const kAsyncBrotli = promisify(brotliCompress);
-const kAsyncDeflate = promisify(deflate);
-
-// VARS
-let pool: Interceptable;
-
-describe("Httpie.safeRequest", () => {
- beforeAll(() => {
- const mockAgent = new MockAgent();
- setGlobalDispatcher(mockAgent);
- mockAgent.disableNetConnect();
-
- pool = mockAgent.get(kUrl);
- });
-
- describe("with ThrowOnHttpError", () => {
- describe("GET", () => {
- it("should throw if the response status code is higher than 400", async() => {
- expect.assertions(5);
-
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = randomInt(400, 503);
- const headers = { "content-type": "text/html" };
- const payload = Buffer.from("Body");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- const result = await safeGet(kUrl + target.path);
- expect(result.ok).toBeFalsy();
- result.unwrap();
- }
- catch (error: any) {
- expect(isHTTPError(error)).toBeTruthy();
- expect(error.statusCode).toBe(statusCode);
- expect(error.data).toBe(payload.toString());
- expect(error.headers).toMatchObject(headers);
- }
- });
-
- it("should not throw if the response status code is lower than 400", async() => {
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = randomInt(200, 399);
- const headers = { "content-type": "text/html" };
- const payload = Buffer.from("Body");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const result = await safeGet(kUrl + target.path);
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.statusCode).toBe(statusCode);
- expect(response.data).toBe(payload.toString());
- expect(response.headers).toMatchObject(headers);
- });
- });
-
- describe("POST", () => {
- it("should throw if the response status code is higher than 400", async() => {
- expect.assertions(5);
-
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = randomInt(400, 503);
- const headers = { "content-type": "text/html" };
- const payload = Buffer.from("Body");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- const result = await safePost(kUrl + target.path);
- expect(result.ok).toBeFalsy();
- result.unwrap();
- }
- catch (error: any) {
- expect(isHTTPError(error)).toBeTruthy();
- expect(error.statusCode).toBe(statusCode);
- expect(error.data).toBe(payload.toString());
- expect(error.headers).toMatchObject(headers);
- }
- });
-
- it("should not throw if the response status code is lower than 400", async() => {
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = randomInt(200, 399);
- const headers = { "content-type": "text/html" };
- const payload = Buffer.from("Body");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const result = await safePost(kUrl + target.path);
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.statusCode).toBe(statusCode);
- expect(response.data).toBe(payload.toString());
- expect(response.headers).toMatchObject(headers);
- });
- });
-
- describe("PUT", () => {
- it("should throw if the response status code is higher than 400", async() => {
- expect.assertions(5);
-
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = randomInt(400, 503);
- const headers = { "content-type": "text/html" };
- const payload = Buffer.from("Body");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- const result = await safePut(kUrl + target.path);
- expect(result.ok).toBeFalsy();
- result.unwrap();
- }
- catch (error: any) {
- expect(isHTTPError(error)).toBeTruthy();
- expect(error.statusCode).toBe(statusCode);
- expect(error.data).toBe(payload.toString());
- expect(error.headers).toMatchObject(headers);
- }
- });
-
- it("should not throw if the response status code is lower than 400", async() => {
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = randomInt(200, 399);
- const headers = { "content-type": "text/html" };
- const payload = Buffer.from("Body");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const result = await safePut(kUrl + target.path);
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.statusCode).toBe(statusCode);
- expect(response.data).toBe(payload.toString());
- expect(response.headers).toMatchObject(headers);
- });
- });
-
- describe("DELETE", () => {
- it("should throw if the response status code is higher than 400", async() => {
- expect.assertions(5);
-
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = randomInt(400, 503);
- const headers = { "content-type": "text/html" };
- const payload = Buffer.from("Body");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- const result = await safeDel(kUrl + target.path);
- expect(result.ok).toBeFalsy();
- result.unwrap();
- }
- catch (error: any) {
- expect(isHTTPError(error)).toBeTruthy();
- expect(error.statusCode).toBe(statusCode);
- expect(error.data).toBe(payload.toString());
- expect(error.headers).toMatchObject(headers);
- }
- });
-
- it("should not throw if the response status code is lower than 400", async() => {
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = randomInt(200, 399);
- const headers = { "content-type": "text/html" };
- const payload = Buffer.from("Body");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const result = await safeDel(kUrl + target.path);
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.statusCode).toBe(statusCode);
- expect(response.data).toBe(payload.toString());
- expect(response.headers).toMatchObject(headers);
- });
- });
- });
-
- describe("without ThrowOnHttpError", () => {
- describe("GET", () => {
- it("should not throw if the response status code is higher than 400", async() => {
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = randomInt(400, 503);
- const headers = { "content-type": "text/html" };
- const payload = Buffer.from("Body");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const result = await safeGet(kUrl + target.path, { throwOnHttpError: false });
- const response = result.unwrap();
- expect(result.ok).toBeTruthy();
- expect(response.statusCode).toBe(statusCode);
- expect(response.data).toBe(payload.toString());
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should not throw if the response status code is lower than 400", async() => {
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = randomInt(200, 399);
- const headers = { "content-type": "text/html" };
- const payload = Buffer.from("Body");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const result = await safeGet(kUrl + target.path, { throwOnHttpError: false });
- const response = result.unwrap();
- expect(result.ok).toBeTruthy();
- expect(response.statusCode).toBe(statusCode);
- expect(response.data).toBe(payload.toString());
- expect(response.headers).toMatchObject(headers);
- });
- });
-
- describe("POST", () => {
- it("should not throw if the response status code is higher than 400", async() => {
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = randomInt(400, 503);
- const headers = { "content-type": "text/html" };
- const payload = Buffer.from("Body");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const result = await safePost(kUrl + target.path, { throwOnHttpError: false });
- const response = result.unwrap();
- expect(result.ok).toBeTruthy();
- expect(response.statusCode).toBe(statusCode);
- expect(response.data).toBe(payload.toString());
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should not throw if the response status code is lower than 400", async() => {
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = randomInt(200, 399);
- const headers = { "content-type": "text/html" };
- const payload = Buffer.from("Body");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const result = await safePost(kUrl + target.path, { throwOnHttpError: false });
- const response = result.unwrap();
- expect(result.ok).toBeTruthy();
- expect(response.statusCode).toBe(statusCode);
- expect(response.data).toBe(payload.toString());
- expect(response.headers).toMatchObject(headers);
- });
- });
-
- describe("PUT", () => {
- it("should not throw if the response status code is higher than 400", async() => {
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = randomInt(400, 503);
- const headers = { "content-type": "text/html" };
- const payload = Buffer.from("Body");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const result = await safePut(kUrl + target.path, { throwOnHttpError: false });
- const response = result.unwrap();
- expect(result.ok).toBeTruthy();
- expect(response.statusCode).toBe(statusCode);
- expect(response.data).toBe(payload.toString());
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should not throw if the response status code is lower than 400", async() => {
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = randomInt(200, 399);
- const headers = { "content-type": "text/html" };
- const payload = Buffer.from("Body");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const result = await safePut(kUrl + target.path, { throwOnHttpError: false });
- const response = result.unwrap();
- expect(result.ok).toBeTruthy();
- expect(response.statusCode).toBe(statusCode);
- expect(response.data).toBe(payload.toString());
- expect(response.headers).toMatchObject(headers);
- });
- });
-
- describe("DELETE", () => {
- it("should not throw if the response status code is higher than 400", async() => {
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = randomInt(400, 503);
- const headers = { "content-type": "text/html" };
- const payload = Buffer.from("Body");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const result = await safeDel(kUrl + target.path, { throwOnHttpError: false });
- const response = result.unwrap();
- expect(result.ok).toBeTruthy();
- expect(response.statusCode).toBe(statusCode);
- expect(response.data).toBe(payload.toString());
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should not throw if the response status code is lower than 400", async() => {
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = randomInt(200, 399);
- const headers = { "content-type": "text/html" };
- const payload = Buffer.from("Body");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const result = await safeDel(kUrl + target.path, { throwOnHttpError: false });
- const response = result.unwrap();
- expect(result.ok).toBeTruthy();
- expect(response.statusCode).toBe(statusCode);
- expect(response.data).toBe(payload.toString());
- expect(response.headers).toMatchObject(headers);
- });
- });
- });
-
- describe("PARSE mode (default)", () => {
- describe("GET", () => {
- it("should return a parsed response as text when 'content-type' header starts with 'text/'", async() => {
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/klsmdkf" };
- const payload = "La data.";
- const buf = Buffer.from(payload);
-
- pool.intercept(target).reply(statusCode, buf, { headers });
-
- const result = await safeGet(kUrl + target.path);
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(statusCode);
- });
-
- it("should return a parsed response as object when 'content-type' header is set with 'application/json'", async() => {
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "application/json" };
- const payload = { my: "object" };
- const buf = Buffer.from(JSON.stringify(payload));
-
- pool.intercept(target).reply(statusCode, buf, { headers });
-
- const result = await safeGet(kUrl + target.path);
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(statusCode);
- });
-
- it("should return a buffer when 'content-type' header is set with 'application/pdf'", async() => {
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "application/pdf" };
- const payload = Buffer.from("mon pdf");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const result = await safeGet(kUrl + target.path);
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.data).toStrictEqual(Buffer.from(payload));
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(statusCode);
- });
-
- it("should return a buffer when 'content-type' header is set with unsupported value", async() => {
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "application/msword" };
- const payload = Buffer.from(JSON.stringify({ my: "object" }));
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const result = await safeGet(kUrl + target.path);
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should throw when 'content-type' header is set with unsupported value", async() => {
- expect.assertions(6);
-
- const target = {
- method: "GET",
- path: "/test"
- };
- const statusCode = 200;
- const headers = { "content-type": "unknown" };
- const payload = Buffer.from(JSON.stringify({ my: "object" }));
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- const result = await safeGet(kUrl + target.path);
- expect(result.ok).toBeFalsy();
- result.unwrap();
- }
- catch (error: any) {
- expect(isHttpieError(error)).toBeTruthy();
- expect(error.message).toStrictEqual(
- "An unexpected error occurred when trying to parse the response body (reason: 'invalid media type')."
- );
- expect(error.buffer).toStrictEqual(payload);
- expect(error.headers).toMatchObject(headers);
- expect(error.statusCode).toBe(200);
- }
- });
-
- it("should throw when 'content-encoding' header is set with unsupported value", async() => {
- expect.assertions(6);
-
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const payload = await kAsyncGzip("Mon document");
- const headers = { "content-encoding": "unknown" };
- const statusCode = 200;
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- const result = await safeGet(kUrl + target.path);
- expect(result.ok).toBeFalsy();
- result.unwrap();
- }
- catch (error: any) {
- expect(error.message).toStrictEqual("Unsupported encoding 'unknown'.");
- expect(error.buffer).toStrictEqual(payload);
- expect(error.headers).toMatchObject(headers);
- expect(error.statusCode).toBe(statusCode);
- expect(isHttpieError(error)).toBeTruthy();
- }
- });
-
- it("should decompress data when 'content-encoding' header is set with 'gzip'", async() => {
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "gzip" };
- const payload = Buffer.from("Payload");
- const compressedPayload = await kAsyncGzip(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const result = await safeGet(kUrl + target.path);
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.data).toStrictEqual(payload.toString());
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(statusCode);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'x-gzip'", async() => {
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "x-gzip" };
- const payload = "Payload";
- const compressedPayload = await kAsyncGzip(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const result = await safeGet(kUrl + target.path);
- const response = result.unwrap();
- expect(result.ok).toBeTruthy();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'br'", async() => {
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "br" };
- const payload = "Payload";
- const compressedPayload = await kAsyncBrotli(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const result = await safeGet(kUrl + target.path);
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'deflate'", async() => {
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "deflate" };
- const payload = "Payload";
- const compressedPayload = await kAsyncDeflate(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const result = await safeGet(kUrl + target.path);
- const response = result.unwrap();
- expect(result.ok).toBeTruthy();
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(200);
- });
- });
-
- describe("POST", () => {
- it("should return a parsed response as text when 'content-type' header starts with 'text/'", async() => {
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/klsmdkf" };
- const payload = "La data.";
- const buf = Buffer.from(payload);
-
- pool.intercept(target).reply(statusCode, buf, { headers });
-
- const result = await safePost(kUrl + target.path);
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(statusCode);
- });
-
- it("should return a parsed response as object when 'content-type' header is set with 'application/json'", async() => {
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "application/json" };
- const payload = { my: "object" };
- const buf = Buffer.from(JSON.stringify(payload));
-
- pool.intercept(target).reply(statusCode, buf, { headers });
-
- const result = await safePost(kUrl + target.path);
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(statusCode);
- });
-
- it("should return a buffer when 'content-type' header is set with 'application/pdf'", async() => {
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "application/pdf" };
- const payload = Buffer.from("mon pdf");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const result = await safePost(kUrl + target.path);
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.data).toStrictEqual(Buffer.from(payload));
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(statusCode);
- });
-
- it("should return a buffer when 'content-type' header is set with unsupported value", async() => {
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "application/msword" };
- const payload = Buffer.from(JSON.stringify({ my: "object" }));
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const result = await safePost(kUrl + target.path);
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should throw when 'content-type' header is set with unsupported value", async() => {
- expect.assertions(6);
-
- const target = {
- method: "POST",
- path: "/test"
- };
- const statusCode = 200;
- const headers = { "content-type": "unknown" };
- const payload = Buffer.from(JSON.stringify({ my: "object" }));
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- const result = await safePost(kUrl + target.path);
- expect(result.ok).toBeFalsy();
- result.unwrap();
- }
- catch (error: any) {
- expect(isHttpieError(error)).toBeTruthy();
- expect(error.message).toStrictEqual(
- "An unexpected error occurred when trying to parse the response body (reason: 'invalid media type')."
- );
- expect(error.buffer).toStrictEqual(payload);
- expect(error.headers).toMatchObject(headers);
- expect(error.statusCode).toBe(200);
- }
- });
-
- it("should throw when 'content-encoding' header is set with unsupported value", async() => {
- expect.assertions(6);
-
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const payload = await kAsyncGzip("Mon document");
- const headers = { "content-encoding": "unknown" };
- const statusCode = 200;
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- const result = await safePost(kUrl + target.path);
- expect(result.ok).toBeFalsy();
- result.unwrap();
- }
- catch (error: any) {
- expect(error.message).toStrictEqual("Unsupported encoding 'unknown'.");
- expect(error.buffer).toStrictEqual(payload);
- expect(error.headers).toMatchObject(headers);
- expect(error.statusCode).toBe(statusCode);
- expect(isHttpieError(error)).toBeTruthy();
- }
- });
-
- it("should decompress data when 'content-encoding' header is set with 'gzip'", async() => {
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "gzip" };
- const payload = Buffer.from("Payload");
- const compressedPayload = await kAsyncGzip(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const result = await safePost(kUrl + target.path);
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.data).toStrictEqual(payload.toString());
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(statusCode);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'x-gzip'", async() => {
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "x-gzip" };
- const payload = "Payload";
- const compressedPayload = await kAsyncGzip(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const result = await safePost(kUrl + target.path);
- const response = result.unwrap();
- expect(result.ok).toBeTruthy();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'br'", async() => {
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "br" };
- const payload = "Payload";
- const compressedPayload = await kAsyncBrotli(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const result = await safePost(kUrl + target.path);
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'deflate'", async() => {
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "deflate" };
- const payload = "Payload";
- const compressedPayload = await kAsyncDeflate(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const result = await safePost(kUrl + target.path);
- const response = result.unwrap();
- expect(result.ok).toBeTruthy();
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(200);
- });
- });
-
- describe("PUT", () => {
- it("should return a parsed response as text when 'content-type' header starts with 'text/'", async() => {
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/klsmdkf" };
- const payload = "La data.";
- const buf = Buffer.from(payload);
-
- pool.intercept(target).reply(statusCode, buf, { headers });
-
- const result = await safePut(kUrl + target.path);
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(statusCode);
- });
-
- it("should return a parsed response as object when 'content-type' header is set with 'application/json'", async() => {
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "application/json" };
- const payload = { my: "object" };
- const buf = Buffer.from(JSON.stringify(payload));
-
- pool.intercept(target).reply(statusCode, buf, { headers });
-
- const result = await safePut(kUrl + target.path);
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(statusCode);
- });
-
- it("should return a buffer when 'content-type' header is set with 'application/pdf'", async() => {
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "application/pdf" };
- const payload = Buffer.from("mon pdf");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const result = await safePut(kUrl + target.path);
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.data).toStrictEqual(Buffer.from(payload));
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(statusCode);
- });
-
- it("should return a buffer when 'content-type' header is set with unsupported value", async() => {
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "application/msword" };
- const payload = Buffer.from(JSON.stringify({ my: "object" }));
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const result = await safePut(kUrl + target.path);
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should throw when 'content-type' header is set with unsupported value", async() => {
- expect.assertions(6);
-
- const target = {
- method: "PUT",
- path: "/test"
- };
- const statusCode = 200;
- const headers = { "content-type": "unknown" };
- const payload = Buffer.from(JSON.stringify({ my: "object" }));
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- const result = await safePut(kUrl + target.path);
- expect(result.ok).toBeFalsy();
- result.unwrap();
- }
- catch (error: any) {
- expect(isHttpieError(error)).toBeTruthy();
- expect(error.message).toStrictEqual(
- "An unexpected error occurred when trying to parse the response body (reason: 'invalid media type')."
- );
- expect(error.buffer).toStrictEqual(payload);
- expect(error.headers).toMatchObject(headers);
- expect(error.statusCode).toBe(200);
- }
- });
-
- it("should throw when 'content-encoding' header is set with unsupported value", async() => {
- expect.assertions(6);
-
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const payload = await kAsyncGzip("Mon document");
- const headers = { "content-encoding": "unknown" };
- const statusCode = 200;
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- const result = await safePut(kUrl + target.path);
- expect(result.ok).toBeFalsy();
- result.unwrap();
- }
- catch (error: any) {
- expect(error.message).toStrictEqual("Unsupported encoding 'unknown'.");
- expect(error.buffer).toStrictEqual(payload);
- expect(error.headers).toMatchObject(headers);
- expect(error.statusCode).toBe(statusCode);
- expect(isHttpieError(error)).toBeTruthy();
- }
- });
-
- it("should decompress data when 'content-encoding' header is set with 'gzip'", async() => {
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "gzip" };
- const payload = Buffer.from("Payload");
- const compressedPayload = await kAsyncGzip(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const result = await safePut(kUrl + target.path);
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.data).toStrictEqual(payload.toString());
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(statusCode);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'x-gzip'", async() => {
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "x-gzip" };
- const payload = "Payload";
- const compressedPayload = await kAsyncGzip(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const result = await safePut(kUrl + target.path);
- const response = result.unwrap();
- expect(result.ok).toBeTruthy();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'br'", async() => {
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "br" };
- const payload = "Payload";
- const compressedPayload = await kAsyncBrotli(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const result = await safePut(kUrl + target.path);
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'deflate'", async() => {
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "deflate" };
- const payload = "Payload";
- const compressedPayload = await kAsyncDeflate(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const result = await safePut(kUrl + target.path);
- const response = result.unwrap();
- expect(result.ok).toBeTruthy();
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(200);
- });
- });
-
- describe("DELETE", () => {
- it("should return a parsed response as text when 'content-type' header starts with 'text/'", async() => {
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/klsmdkf" };
- const payload = "La data.";
- const buf = Buffer.from(payload);
-
- pool.intercept(target).reply(statusCode, buf, { headers });
-
- const result = await safeDel(kUrl + target.path);
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(statusCode);
- });
-
- it("should return a parsed response as object when 'content-type' header is set with 'application/json'", async() => {
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "application/json" };
- const payload = { my: "object" };
- const buf = Buffer.from(JSON.stringify(payload));
-
- pool.intercept(target).reply(statusCode, buf, { headers });
-
- const result = await safeDel(kUrl + target.path);
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(statusCode);
- });
-
- it("should return a buffer when 'content-type' header is set with 'application/pdf'", async() => {
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "application/pdf" };
- const payload = Buffer.from("mon pdf");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const result = await safeDel(kUrl + target.path);
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.data).toStrictEqual(Buffer.from(payload));
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(statusCode);
- });
-
- it("should return a buffer when 'content-type' header is set with unsupported value", async() => {
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "application/msword" };
- const payload = Buffer.from(JSON.stringify({ my: "object" }));
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const result = await safeDel(kUrl + target.path);
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should throw when 'content-type' header is set with unsupported value", async() => {
- expect.assertions(6);
-
- const target = {
- method: "DELETE",
- path: "/test"
- };
- const statusCode = 200;
- const headers = { "content-type": "unknown" };
- const payload = Buffer.from(JSON.stringify({ my: "object" }));
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- const result = await safeDel(kUrl + target.path);
- expect(result.ok).toBeFalsy();
- result.unwrap();
- }
- catch (error: any) {
- expect(isHttpieError(error)).toBeTruthy();
- expect(error.message).toStrictEqual(
- "An unexpected error occurred when trying to parse the response body (reason: 'invalid media type')."
- );
- expect(error.buffer).toStrictEqual(payload);
- expect(error.headers).toMatchObject(headers);
- expect(error.statusCode).toBe(200);
- }
- });
-
- it("should throw when 'content-encoding' header is set with unsupported value", async() => {
- expect.assertions(6);
-
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const payload = await kAsyncGzip("Mon document");
- const headers = { "content-encoding": "unknown" };
- const statusCode = 200;
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- const result = await safeDel(kUrl + target.path);
- expect(result.ok).toBeFalsy();
- result.unwrap();
- }
- catch (error: any) {
- expect(error.message).toStrictEqual("Unsupported encoding 'unknown'.");
- expect(error.buffer).toStrictEqual(payload);
- expect(error.headers).toMatchObject(headers);
- expect(error.statusCode).toBe(statusCode);
- expect(isHttpieError(error)).toBeTruthy();
- }
- });
-
- it("should decompress data when 'content-encoding' header is set with 'gzip'", async() => {
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "gzip" };
- const payload = Buffer.from("Payload");
- const compressedPayload = await kAsyncGzip(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const result = await safeDel(kUrl + target.path);
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.data).toStrictEqual(payload.toString());
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(statusCode);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'x-gzip'", async() => {
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "x-gzip" };
- const payload = "Payload";
- const compressedPayload = await kAsyncGzip(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const result = await safeDel(kUrl + target.path);
- const response = result.unwrap();
- expect(result.ok).toBeTruthy();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'br'", async() => {
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "br" };
- const payload = "Payload";
- const compressedPayload = await kAsyncBrotli(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const result = await safeDel(kUrl + target.path);
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'deflate'", async() => {
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "deflate" };
- const payload = "Payload";
- const compressedPayload = await kAsyncDeflate(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const result = await safeDel(kUrl + target.path);
- const response = result.unwrap();
- expect(result.ok).toBeTruthy();
-
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(200);
- });
- });
- });
-
- describe("DECOMPRESS mode", () => {
- describe("GET", () => {
- it("should return a buffer without parsing it even if 'content-type' header exists", async() => {
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/klsmdkf" };
- const payload = Buffer.from("La data.");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const result = await safeGet(kUrl + target.path, { mode: "decompress" });
- const response = result.unwrap();
- expect(result.ok).toBeTruthy();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should throw when 'content-encoding' header is set with unsupported value", async() => {
- expect.assertions(6);
-
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-encoding": "unknown" };
- const payload = Buffer.from("Mon document");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- const result = await safeGet(kUrl + target.path, { mode: "decompress" });
- expect(result.ok).toBeFalsy();
- result.unwrap();
- }
- catch (error: any) {
- expect(error.message).toStrictEqual("Unsupported encoding 'unknown'.");
- expect(error.buffer).toMatchObject(payload);
- expect(error.headers).toMatchObject(headers);
- expect(isHttpieError(error)).toBeTruthy();
- expect(error.statusCode).toBe(200);
- }
- });
-
- it("should throw when 'content-encoding' header is invalid", async() => {
- expect.assertions(10);
-
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-encoding": "gzip" };
- const payload = await kAsyncBrotli("Mon document");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- const result = await safeGet(kUrl + target.path, { mode: "decompress" });
- expect(result.ok).toBeFalsy();
- result.unwrap();
- }
- catch (error: any) {
- expect(error).toBeTruthy();
- expect(error.reason).toBeTruthy();
- expect(error.message).toStrictEqual(
- "An unexpected error occurred when trying to decompress the response body (reason: 'incorrect header check')."
- );
- expect(error.buffer).toMatchObject(payload);
- expect(error.headers).toMatchObject(headers);
- expect(error.reason).toBeTruthy();
- expect(error.reason.message).toStrictEqual("incorrect header check");
- expect(isHttpieError(error)).toBeTruthy();
- expect(error.statusCode).toBe(200);
- }
- });
-
- it("should decompress data when 'content-encoding' header is set with 'gzip'", async() => {
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "gzip" };
- const payload = Buffer.from("payload");
- const compressedPayload = await kAsyncGzip("payload");
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const result = await safeGet(kUrl + target.path, { mode: "decompress" });
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'x-gzip'", async() => {
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "x-gzip" };
- const payload = Buffer.from("Payload");
- const compressedPayload = await kAsyncGzip(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const result = await safeGet(kUrl + target.path, { mode: "decompress" });
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'br'", async() => {
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const payload = Buffer.from("Payload");
- const compressedPayload = await kAsyncBrotli(payload);
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "br" };
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
- const result = await safeGet(kUrl + target.path, { mode: "decompress" });
- const response = result.unwrap();
- expect(result.ok).toBeTruthy();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'deflate'", async() => {
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const payload = Buffer.from("Payload");
- const compressedPayload = await kAsyncDeflate(payload);
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "deflate" };
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
- const result = await safeGet(kUrl + target.path, { mode: "decompress" });
- const response = result.unwrap();
- expect(result.ok).toBeTruthy();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
- });
-
- describe("POST", () => {
- it("should return a buffer without parsing it even if 'content-type' header exists", async() => {
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/klsmdkf" };
- const payload = Buffer.from("La data.");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const result = await safePost(kUrl + target.path, { mode: "decompress" });
- const response = result.unwrap();
- expect(result.ok).toBeTruthy();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should throw when 'content-encoding' header is set with unsupported value", async() => {
- expect.assertions(6);
-
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-encoding": "unknown" };
- const payload = Buffer.from("Mon document");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- const result = await safePost(kUrl + target.path, { mode: "decompress" });
- expect(result.ok).toBeFalsy();
- result.unwrap();
- }
- catch (error: any) {
- expect(error.message).toStrictEqual("Unsupported encoding 'unknown'.");
- expect(error.buffer).toMatchObject(payload);
- expect(error.headers).toMatchObject(headers);
- expect(isHttpieError(error)).toBeTruthy();
- expect(error.statusCode).toBe(200);
- }
- });
-
- it("should throw when 'content-encoding' header is invalid", async() => {
- expect.assertions(10);
-
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-encoding": "gzip" };
- const payload = await kAsyncBrotli("Mon document");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- const result = await safePost(kUrl + target.path, { mode: "decompress" });
- expect(result.ok).toBeFalsy();
- result.unwrap();
- }
- catch (error: any) {
- expect(error).toBeTruthy();
- expect(error.reason).toBeTruthy();
- expect(error.message).toStrictEqual(
- "An unexpected error occurred when trying to decompress the response body (reason: 'incorrect header check')."
- );
- expect(error.buffer).toMatchObject(payload);
- expect(error.headers).toMatchObject(headers);
- expect(error.reason).toBeTruthy();
- expect(error.reason.message).toStrictEqual("incorrect header check");
- expect(isHttpieError(error)).toBeTruthy();
- expect(error.statusCode).toBe(200);
- }
- });
-
- it("should decompress data when 'content-encoding' header is set with 'gzip'", async() => {
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "gzip" };
- const payload = Buffer.from("payload");
- const compressedPayload = await kAsyncGzip("payload");
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const result = await safePost(kUrl + target.path, { mode: "decompress" });
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'x-gzip'", async() => {
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "x-gzip" };
- const payload = Buffer.from("Payload");
- const compressedPayload = await kAsyncGzip(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const result = await safePost(kUrl + target.path, { mode: "decompress" });
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'br'", async() => {
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const payload = Buffer.from("Payload");
- const compressedPayload = await kAsyncBrotli(payload);
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "br" };
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
- const result = await safePost(kUrl + target.path, { mode: "decompress" });
- const response = result.unwrap();
- expect(result.ok).toBeTruthy();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'deflate'", async() => {
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const payload = Buffer.from("Payload");
- const compressedPayload = await kAsyncDeflate(payload);
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "deflate" };
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
- const result = await safePost(kUrl + target.path, { mode: "decompress" });
- const response = result.unwrap();
- expect(result.ok).toBeTruthy();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
- });
-
- describe("PUT", () => {
- it("should return a buffer without parsing it even if 'content-type' header exists", async() => {
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/klsmdkf" };
- const payload = Buffer.from("La data.");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const result = await safePut(kUrl + target.path, { mode: "decompress" });
- const response = result.unwrap();
- expect(result.ok).toBeTruthy();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should throw when 'content-encoding' header is set with unsupported value", async() => {
- expect.assertions(6);
-
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-encoding": "unknown" };
- const payload = Buffer.from("Mon document");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- const result = await safePut(kUrl + target.path, { mode: "decompress" });
- expect(result.ok).toBeFalsy();
- result.unwrap();
- }
- catch (error: any) {
- expect(error.message).toStrictEqual("Unsupported encoding 'unknown'.");
- expect(error.buffer).toMatchObject(payload);
- expect(error.headers).toMatchObject(headers);
- expect(isHttpieError(error)).toBeTruthy();
- expect(error.statusCode).toBe(200);
- }
- });
-
- it("should throw when 'content-encoding' header is invalid", async() => {
- expect.assertions(10);
-
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-encoding": "gzip" };
- const payload = await kAsyncBrotli("Mon document");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- const result = await safePut(kUrl + target.path, { mode: "decompress" });
- expect(result.ok).toBeFalsy();
- result.unwrap();
- }
- catch (error: any) {
- expect(error).toBeTruthy();
- expect(error.reason).toBeTruthy();
- expect(error.message).toStrictEqual(
- "An unexpected error occurred when trying to decompress the response body (reason: 'incorrect header check')."
- );
- expect(error.buffer).toMatchObject(payload);
- expect(error.headers).toMatchObject(headers);
- expect(error.reason).toBeTruthy();
- expect(error.reason.message).toStrictEqual("incorrect header check");
- expect(isHttpieError(error)).toBeTruthy();
- expect(error.statusCode).toBe(200);
- }
- });
-
- it("should decompress data when 'content-encoding' header is set with 'gzip'", async() => {
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "gzip" };
- const payload = Buffer.from("payload");
- const compressedPayload = await kAsyncGzip("payload");
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const result = await safePut(kUrl + target.path, { mode: "decompress" });
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'x-gzip'", async() => {
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "x-gzip" };
- const payload = Buffer.from("Payload");
- const compressedPayload = await kAsyncGzip(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const result = await safePut(kUrl + target.path, { mode: "decompress" });
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'br'", async() => {
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const payload = Buffer.from("Payload");
- const compressedPayload = await kAsyncBrotli(payload);
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "br" };
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
- const result = await safePut(kUrl + target.path, { mode: "decompress" });
- const response = result.unwrap();
- expect(result.ok).toBeTruthy();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'deflate'", async() => {
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const payload = Buffer.from("Payload");
- const compressedPayload = await kAsyncDeflate(payload);
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "deflate" };
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
- const result = await safePut(kUrl + target.path, { mode: "decompress" });
- const response = result.unwrap();
- expect(result.ok).toBeTruthy();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
- });
-
- describe("DELETE", () => {
- it("should return a buffer without parsing it even if 'content-type' header exists", async() => {
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/klsmdkf" };
- const payload = Buffer.from("La data.");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const result = await safeDel(kUrl + target.path, { mode: "decompress" });
- const response = result.unwrap();
- expect(result.ok).toBeTruthy();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should throw when 'content-encoding' header is set with unsupported value", async() => {
- expect.assertions(6);
-
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-encoding": "unknown" };
- const payload = Buffer.from("Mon document");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- const result = await safeDel(kUrl + target.path, { mode: "decompress" });
- expect(result.ok).toBeFalsy();
- result.unwrap();
- }
- catch (error: any) {
- expect(error.message).toStrictEqual("Unsupported encoding 'unknown'.");
- expect(error.buffer).toMatchObject(payload);
- expect(error.headers).toMatchObject(headers);
- expect(isHttpieError(error)).toBeTruthy();
- expect(error.statusCode).toBe(200);
- }
- });
-
- it("should throw when 'content-encoding' header is invalid", async() => {
- expect.assertions(10);
-
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-encoding": "gzip" };
- const payload = await kAsyncBrotli("Mon document");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- try {
- const result = await safeDel(kUrl + target.path, { mode: "decompress" });
- expect(result.ok).toBeFalsy();
- result.unwrap();
- }
- catch (error: any) {
- expect(error).toBeTruthy();
- expect(error.reason).toBeTruthy();
- expect(error.message).toStrictEqual(
- "An unexpected error occurred when trying to decompress the response body (reason: 'incorrect header check')."
- );
- expect(error.buffer).toMatchObject(payload);
- expect(error.headers).toMatchObject(headers);
- expect(error.reason).toBeTruthy();
- expect(error.reason.message).toStrictEqual("incorrect header check");
- expect(isHttpieError(error)).toBeTruthy();
- expect(error.statusCode).toBe(200);
- }
- });
-
- it("should decompress data when 'content-encoding' header is set with 'gzip'", async() => {
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "gzip" };
- const payload = Buffer.from("payload");
- const compressedPayload = await kAsyncGzip("payload");
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const result = await safeDel(kUrl + target.path, { mode: "decompress" });
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'x-gzip'", async() => {
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "x-gzip" };
- const payload = Buffer.from("Payload");
- const compressedPayload = await kAsyncGzip(payload);
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
-
- const result = await safeDel(kUrl + target.path, { mode: "decompress" });
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'br'", async() => {
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const payload = Buffer.from("Payload");
- const compressedPayload = await kAsyncBrotli(payload);
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "br" };
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
- const result = await safeDel(kUrl + target.path, { mode: "decompress" });
- const response = result.unwrap();
- expect(result.ok).toBeTruthy();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
-
- it("should decompress data when 'content-encoding' header is set with 'deflate'", async() => {
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const payload = Buffer.from("Payload");
- const compressedPayload = await kAsyncDeflate(payload);
-
- const statusCode = 200;
- const headers = { "content-type": "text/html", "content-encoding": "deflate" };
-
- pool.intercept(target).reply(statusCode, compressedPayload, { headers });
- const result = await safeDel(kUrl + target.path, { mode: "decompress" });
- const response = result.unwrap();
- expect(result.ok).toBeTruthy();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- });
- });
- });
-
- describe("RAW mode", () => {
- describe("GET", () => {
- it("should return a buffer without parsing it even if 'content-type' header exists", async() => {
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/klsmdkf" };
- const payload = Buffer.from("payload");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const result = await safeGet(kUrl + target.path, { mode: "raw" });
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(200);
- });
-
- it("should return a buffer without decompress it even if 'content-encoding' header exists", async() => {
- const target = {
- method: "GET",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-encoding": "gzip" };
- const payload = await kAsyncGzip("Doc");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const result = await safeGet(kUrl + target.path, { mode: "raw" });
- const response = result.unwrap();
- expect(result.ok).toBeTruthy();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(200);
- });
- });
-
- describe("POST", () => {
- it("should return a buffer without parsing it even if 'content-type' header exists", async() => {
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/klsmdkf" };
- const payload = Buffer.from("payload");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const result = await safePost(kUrl + target.path, { mode: "raw" });
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(200);
- });
-
- it("should return a buffer without decompress it even if 'content-encoding' header exists", async() => {
- const target = {
- method: "POST",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-encoding": "gzip" };
- const payload = await kAsyncGzip("Doc");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const result = await safePost(kUrl + target.path, { mode: "raw" });
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(200);
- });
- });
-
- describe("PUT", () => {
- it("should return a buffer without parsing it even if 'content-type' header exists", async() => {
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/klsmdkf" };
- const payload = Buffer.from("payload");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const result = await safePut(kUrl + target.path, { mode: "raw" });
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(200);
- });
-
- it("should return a buffer without decompress it even if 'content-encoding' header exists", async() => {
- const target = {
- method: "PUT",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-encoding": "gzip" };
- const payload = await kAsyncGzip("Doc");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const result = await safePut(kUrl + target.path, { mode: "raw" });
- const response = result.unwrap();
- expect(result.ok).toBeTruthy();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(200);
- });
- });
-
- describe("DELETE", () => {
- it("should return a buffer without parsing it even if 'content-type' header exists", async() => {
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-type": "text/klsmdkf" };
- const payload = Buffer.from("payload");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const result = await safeDel(kUrl + target.path, { mode: "raw" });
- expect(result.ok).toBeTruthy();
-
- const response = result.unwrap();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(200);
- });
-
- it("should return a buffer without decompress it even if 'content-encoding' header exists", async() => {
- const target = {
- method: "DELETE",
- path: "/test"
- };
-
- const statusCode = 200;
- const headers = { "content-encoding": "gzip" };
- const payload = await kAsyncGzip("Doc");
-
- pool.intercept(target).reply(statusCode, payload, { headers });
-
- const result = await safeDel(kUrl + target.path, { mode: "raw" });
- const response = result.unwrap();
- expect(result.ok).toBeTruthy();
- expect(response.data).toStrictEqual(payload);
- expect(response.headers).toMatchObject(headers);
- expect(response.statusCode).toBe(200);
- });
- });
- });
-});
diff --git a/test/server/index.ts b/test/server/index.ts
index d820aeb..832b29b 100644
--- a/test/server/index.ts
+++ b/test/server/index.ts
@@ -11,10 +11,11 @@ import * as undici from "undici";
import { CustomHttpAgent, agents } from "../../src/agents";
// CONSTANTS
+const __dirname = import.meta.dirname;
const kFixturesPath = path.join(__dirname, "..", "fixtures");
const toUpperCase = new Transform({
- transform(chunk, enc, next) {
+ transform(chunk, _enc, next) {
for (let id = 0; id < chunk.length; id++) {
const char = chunk[id];
chunk[id] = char < 97 || char > 122 ? char : char - 32;
@@ -29,15 +30,10 @@ export async function createServer(customPath = "local", port = 3000) {
const server = fastify({ logger: false });
const serverAgent: CustomHttpAgent = {
customPath,
- domains: new Set([
- `localhost:${port}`
- ]),
agent: new undici.Agent({
connections: 10
- }),
- prod: `http://localhost:${port}/`,
- preprod: `http://localhost:${port}/`,
- dev: `http://localhost:${port}/`
+ }).compose(undici.interceptors.redirect()),
+ origin: `http://localhost:${port}/`
};
agents.add(serverAgent);
@@ -49,7 +45,7 @@ export async function createServer(customPath = "local", port = 3000) {
server.get("/qs", async(request) => request.query);
- server.get("/home", (request, reply) => {
+ server.get("/home", (_request, reply) => {
reply.send(
fs.createReadStream(path.join(kFixturesPath, "home.html"))
);
@@ -61,36 +57,36 @@ export async function createServer(customPath = "local", port = 3000) {
);
});
- server.get("/redirect", (request, reply) => {
+ server.get("/redirect", (_request, reply) => {
reply.redirect("/");
});
- server.get("/jsonError", (request, reply) => {
+ server.get("/jsonError", (_request, reply) => {
reply.type("application/json");
reply.send("{ 'foo': bar }");
});
- server.get("/notimplemented", (request, reply) => {
+ server.get("/notimplemented", (_request, reply) => {
reply.code(501);
reply.send();
});
- server.get("/internalerror", (request, reply) => {
+ server.get("/internalerror", (_request, reply) => {
reply.code(500);
reply.send();
});
- server.get("/badEncoding", (request, reply) => {
+ server.get("/badEncoding", (_request, reply) => {
reply.header("content-encoding", "oui");
reply.send("{ 'foo': bar }");
});
- server.get("/pdf", (request, reply) => {
+ server.get("/pdf", (_request, reply) => {
reply.header("content-type", "application/pdf");
reply.send("{ 'foo': bar }");
});
- server.get("/text", (request, reply) => {
+ server.get("/text", (_request, reply) => {
reply.header("content-type", "text/anything");
reply.send("text");
});
diff --git a/test/stream.spec.ts b/test/stream.test.ts
similarity index 70%
rename from test/stream.spec.ts
rename to test/stream.test.ts
index d1e093f..617705e 100644
--- a/test/stream.spec.ts
+++ b/test/stream.test.ts
@@ -1,7 +1,9 @@
// Import Node.js Dependencies
+import { describe, it, before, after } from "node:test";
import { createWriteStream, createReadStream, existsSync, promises as fs } from "node:fs";
import path from "node:path";
import { pipeline } from "node:stream/promises";
+import assert from "node:assert";
// Import Third-party Dependencies
import { FastifyInstance } from "fastify";
@@ -11,32 +13,36 @@ import * as httpie from "../src/index";
import { createServer } from "./server/index";
// CONSTANTS
+const __dirname = import.meta.dirname;
+
const kGithubURL = new URL("https://github.com/");
const kFixturesPath = path.join(__dirname, "fixtures");
const kDownloadPath = path.join(__dirname, "download");
let httpServer: FastifyInstance;
-beforeAll(async() => {
+before(async() => {
httpServer = await createServer("stream", 1338);
await fs.mkdir(kDownloadPath, { recursive: true });
});
-afterAll(async() => {
+after(async() => {
await httpServer.close();
await fs.rm(kDownloadPath, { force: true, recursive: true });
});
describe("stream", () => {
it("should use callback dispatcher to init headers/statusCode etc.", async() => {
- const fileDestination = path.join(kDownloadPath, "i18n-main.tar.gz");
- const repositoryURL = new URL("NodeSecure/i18n/archive/main.tar.gz", kGithubURL);
+ const fileDestination = path.join(kDownloadPath, "fs-walk-main.tar.gz");
+ const repositoryURL = new URL("NodeSecure/vulnera/archive/main.tar.gz", kGithubURL);
+ const agent = new httpie.Agent()
+ .compose(httpie.interceptors.redirect({ maxRedirections: 1 }));
const cursor = httpie.stream("GET", repositoryURL, {
headers: {
"User-Agent": "httpie",
"Accept-Encoding": "gzip, deflate"
},
- maxRedirections: 1
+ agent
});
let contentType = "";
@@ -48,24 +54,26 @@ describe("stream", () => {
return createWriteStream(fileDestination);
});
- expect(existsSync(fileDestination)).toStrictEqual(true);
- expect(contentType).toBe("application/x-gzip");
- expect(code).toBe(200);
+ assert.ok(existsSync(fileDestination));
+ assert.equal(contentType, "application/x-gzip");
+ assert.equal(code, 200);
});
it("should fetch a .tar.gz of a given github repository", async() => {
- const fileDestination = path.join(kDownloadPath, "i18n-main.tar.gz");
- const repositoryURL = new URL("NodeSecure/i18n/archive/main.tar.gz", kGithubURL);
+ const fileDestination = path.join(kDownloadPath, "vulnera-main.tar.gz");
+ const repositoryURL = new URL("NodeSecure/vulnera/archive/main.tar.gz", kGithubURL);
+ const agent = new httpie.Agent()
+ .compose(httpie.interceptors.redirect());
await httpie.stream("GET", repositoryURL, {
headers: {
"User-Agent": "httpie",
"Accept-Encoding": "gzip, deflate"
},
- maxRedirections: 1
+ agent
})(() => createWriteStream(fileDestination));
- expect(existsSync(fileDestination)).toStrictEqual(true);
+ assert.ok(existsSync(fileDestination));
});
it("should fetch the HTML home from the local fastify server", async() => {
@@ -73,13 +81,13 @@ describe("stream", () => {
await httpie.stream("GET", "/stream/home")(() => createWriteStream(fileDestination));
- expect(existsSync(fileDestination)).toStrictEqual(true);
+ assert.ok(existsSync(fileDestination));
const [contentA, contentB] = await Promise.all([
fs.readFile(path.join(kFixturesPath, "home.html"), "utf-8"),
fs.readFile(path.join(kDownloadPath, "home.html"), "utf-8")
]);
- expect(contentA).toStrictEqual(contentB);
+ assert.equal(contentA, contentB);
});
});
@@ -94,12 +102,12 @@ describe("pipeline", () => {
createWriteStream(fileDestination)
);
- expect(existsSync(fileDestination)).toStrictEqual(true);
+ assert.ok(existsSync(fileDestination));
const [contentA, contentB] = await Promise.all([
fs.readFile(fixtureLocation, "utf-8"),
fs.readFile(fileDestination, "utf-8")
]);
- expect(contentA.toUpperCase()).toStrictEqual(contentB);
+ assert.equal(contentA.toUpperCase(), contentB);
});
});
diff --git a/test/undiciResponseHandler.spec.ts b/test/undiciResponseHandler.test.ts
similarity index 79%
rename from test/undiciResponseHandler.spec.ts
rename to test/undiciResponseHandler.test.ts
index 651cdfe..c2e7179 100644
--- a/test/undiciResponseHandler.spec.ts
+++ b/test/undiciResponseHandler.test.ts
@@ -1,9 +1,11 @@
// Import Node.js Dependencies
import { randomBytes } from "node:crypto";
+import { describe, it } from "node:test";
+import assert from "node:assert";
// Import Third-party Dependencies
-import { brotliCompressSync, deflateSync, gzipSync } from "zlib";
+import { brotliCompressSync, deflateSync, gzipSync } from "node:zlib";
// Import Internal Dependencies
import { HttpieResponseHandler } from "../src/class/undiciResponseHandler";
@@ -24,7 +26,7 @@ describe("HttpieResponseHandler.getData", () => {
const handler = new HttpieResponseHandler(mockResponse as any);
const data = await handler.getData();
- expect(data).toMatchObject(payload);
+ assert.deepEqual(data, payload);
});
});
@@ -38,11 +40,11 @@ describe("HttpieResponseHandler.getData (mode: 'raw')", () => {
const handler = new HttpieResponseHandler(mockResponse as any);
const data = await handler.getData("raw");
- expect(data).toMatchObject(payload);
+ assert.deepEqual(data, payload);
});
- it("should throw HttpieFetchBodyError", async() => {
- expect.assertions(4);
+ it("should throw HttpieFetchBodyError", async(t) => {
+ t.plan(4);
const errMsg = "unexpected error";
const mockResponse = {
@@ -59,11 +61,13 @@ describe("HttpieResponseHandler.getData (mode: 'raw')", () => {
await handler.getData();
}
catch (error: any) {
- expect(error.name).toStrictEqual("ResponseFetchError");
- expect(error.message)
- .toStrictEqual(`An unexpected error occurred while trying to retrieve the response body (reason: '${errMsg}').`);
- expect(error.statusCode).toStrictEqual(mockResponse.statusCode);
- expect(error.headers).toStrictEqual(mockResponse.headers);
+ t.assert.equal(error.name, "ResponseFetchError");
+ t.assert.equal(
+ error.message,
+ `An unexpected error occurred while trying to retrieve the response body (reason: '${errMsg}').`
+ );
+ t.assert.equal(error.statusCode, mockResponse.statusCode);
+ t.assert.deepEqual(error.headers, mockResponse.headers);
}
});
});
@@ -79,11 +83,11 @@ describe("HttpieResponseHandler.getData (mode: 'decompress')", () => {
const handler = new HttpieResponseHandler(mockResponse as any);
const data = await handler.getData("decompress");
- expect(data).toStrictEqual(buf);
+ assert.deepEqual(data, buf);
});
- it("must throw when the 'content-encoding' header is set with an unknown value", async() => {
- expect.assertions(6);
+ it("must throw when the 'content-encoding' header is set with an unknown value", async(t) => {
+ t.plan(6);
const buf = Buffer.from("hello world!");
const encoding = randomBytes(4).toString("hex");
@@ -98,17 +102,17 @@ describe("HttpieResponseHandler.getData (mode: 'decompress')", () => {
await handler.getData("decompress");
}
catch (error: any) {
- expect(error.message).toStrictEqual(`Unsupported encoding '${encoding}'.`);
- expect(error.buffer).toStrictEqual(buf);
- expect(error.encodings).toStrictEqual([encoding]);
- expect(error.name).toStrictEqual("DecompressionNotSupported");
- expect(error.statusCode).toStrictEqual(mockResponse.statusCode);
- expect(error.headers).toStrictEqual(mockResponse.headers);
+ t.assert.equal(error.message, `Unsupported encoding '${encoding}'.`);
+ t.assert.deepEqual(error.buffer, buf);
+ t.assert.deepEqual(error.encodings, [encoding]);
+ t.assert.equal(error.name, "DecompressionNotSupported");
+ t.assert.equal(error.statusCode, mockResponse.statusCode);
+ t.assert.deepEqual(error.headers, mockResponse.headers);
}
});
- it("must throw when the 'content-encoding' header is a list that includes an unknown value", async() => {
- expect.assertions(6);
+ it("must throw when the 'content-encoding' header is a list that includes an unknown value", async(t) => {
+ t.plan(6);
const buf = Buffer.from("hello world!");
const encoding = randomBytes(4).toString("hex");
@@ -123,12 +127,12 @@ describe("HttpieResponseHandler.getData (mode: 'decompress')", () => {
await handler.getData("decompress");
}
catch (error: any) {
- expect(error.message).toStrictEqual(`Unsupported encoding '${encoding}'.`);
- expect(error.buffer).toStrictEqual(buf);
- expect(error.encodings).toStrictEqual([encoding]);
- expect(error.name).toStrictEqual("DecompressionNotSupported");
- expect(error.statusCode).toStrictEqual(mockResponse.statusCode);
- expect(error.headers).toStrictEqual(mockResponse.headers);
+ t.assert.equal(error.message, `Unsupported encoding '${encoding}'.`);
+ t.assert.deepEqual(error.buffer, buf);
+ t.assert.deepEqual(error.encodings, [encoding]);
+ t.assert.equal(error.name, "DecompressionNotSupported");
+ t.assert.equal(error.statusCode, mockResponse.statusCode);
+ t.assert.deepEqual(error.headers, mockResponse.headers);
}
});
@@ -142,7 +146,7 @@ describe("HttpieResponseHandler.getData (mode: 'decompress')", () => {
const handler = new HttpieResponseHandler(mockResponse as any);
const data = await handler.getData("decompress");
- expect(data).toStrictEqual(buf);
+ assert.deepEqual(data, buf);
});
it(`must use 'gunzip' before to returning an uncompressed buffer
@@ -155,7 +159,7 @@ describe("HttpieResponseHandler.getData (mode: 'decompress')", () => {
const handler = new HttpieResponseHandler(mockResponse as any);
const data = await handler.getData("decompress");
- expect(data).toStrictEqual(buf);
+ assert.deepEqual(data, buf);
});
it(`must use 'brotliDecompress' before to returning an uncompressed buffer
@@ -168,7 +172,7 @@ describe("HttpieResponseHandler.getData (mode: 'decompress')", () => {
const handler = new HttpieResponseHandler(mockResponse as any);
const data = await handler.getData("decompress");
- expect(data).toStrictEqual(buf);
+ assert.deepEqual(data, buf);
});
it(`must use 'inflate' before to returning an uncompressed buffer
@@ -181,7 +185,7 @@ describe("HttpieResponseHandler.getData (mode: 'decompress')", () => {
const handler = new HttpieResponseHandler(mockResponse as any);
const data = await handler.getData("decompress");
- expect(data).toStrictEqual(buf);
+ assert.deepEqual(data, buf);
});
it("must decompress in reverse order of the given encodings list when there are multiple compression types", async() => {
@@ -194,7 +198,7 @@ describe("HttpieResponseHandler.getData (mode: 'decompress')", () => {
const handler = new HttpieResponseHandler(mockResponse as any);
const data = await handler.getData("decompress");
- expect(data).toStrictEqual(buf);
+ assert.deepEqual(data, buf);
});
it("must decompress in reverse order of the given encodings string when there are multiple compression types", async() => {
@@ -207,7 +211,7 @@ describe("HttpieResponseHandler.getData (mode: 'decompress')", () => {
const handler = new HttpieResponseHandler(mockResponse as any);
const data = await handler.getData("decompress");
- expect(data).toStrictEqual(buf);
+ assert.deepEqual(data, buf);
});
});
@@ -221,11 +225,11 @@ describe("HttpieResponseHandler.getData (mode: 'parse')", () => {
const handler = new HttpieResponseHandler(mockResponse as any);
const data = await handler.getData("parse");
- expect(data).toMatchObject(payload);
+ assert.deepEqual(data, payload);
});
- it("should parse an invalid JSON response but still keep the request data in the Error", async() => {
- expect.assertions(5);
+ it("should parse an invalid JSON response but still keep the request data in the Error", async(t) => {
+ t.plan(5);
const payload = "{\"foo\": bar}";
const buf = Buffer.from("{\"foo\": bar}");
@@ -240,11 +244,11 @@ describe("HttpieResponseHandler.getData (mode: 'parse')", () => {
await handler.getData("parse");
}
catch (error: any) {
- expect(error.text).toStrictEqual(payload);
- expect(error.buffer).toStrictEqual(buf);
- expect(error.name).toStrictEqual("ResponseParsingError");
- expect(error.statusCode).toStrictEqual(mockResponse.statusCode);
- expect(error.headers).toMatchObject(mockResponse.headers);
+ t.assert.equal(error.text, payload);
+ t.assert.deepEqual(error.buffer, buf);
+ t.assert.equal(error.name, "ResponseParsingError");
+ t.assert.equal(error.statusCode, mockResponse.statusCode);
+ t.assert.deepEqual(error.headers, mockResponse.headers);
}
});
@@ -259,7 +263,7 @@ describe("HttpieResponseHandler.getData (mode: 'parse')", () => {
const handler = new HttpieResponseHandler(mockResponse as any);
const data = await handler.getData("parse");
- expect(data).toStrictEqual(payload);
+ assert.deepEqual(data, payload);
});
it("must converting it to a string when the 'content-type' header starts with 'text/'", async() => {
@@ -271,7 +275,7 @@ describe("HttpieResponseHandler.getData (mode: 'parse')", () => {
const handler = new HttpieResponseHandler(mockResponse as any);
const data = await handler.getData("parse");
- expect(data).toStrictEqual(payload);
+ assert.deepEqual(data, payload);
});
it("must converting body to JSON when the 'content-type' header is set with 'application/json'", async() => {
@@ -284,7 +288,7 @@ describe("HttpieResponseHandler.getData (mode: 'parse')", () => {
const handler = new HttpieResponseHandler(mockResponse as any);
const data = await handler.getData("parse");
- expect(data).toStrictEqual(payload);
+ assert.deepEqual(data, payload);
});
it("must return the original buffer when 'content-type' header is set with 'application/pdf'", async() => {
@@ -297,6 +301,6 @@ describe("HttpieResponseHandler.getData (mode: 'parse')", () => {
const handler = new HttpieResponseHandler(mockResponse as any);
const data = await handler.getData("parse");
- expect(data).toStrictEqual(buf);
+ assert.deepEqual(data, buf);
});
});
diff --git a/test/utils.spec.ts b/test/utils.spec.ts
deleted file mode 100644
index e7f26a0..0000000
--- a/test/utils.spec.ts
+++ /dev/null
@@ -1,212 +0,0 @@
-// Import Node.js Dependencies
-import { IncomingHttpHeaders } from "node:http2";
-import stream from "node:stream";
-
-// Import Internal Dependencies
-import * as Utils from "../src/utils";
-import { HttpieOnHttpError } from "../src/class/HttpieOnHttpError";
-import { HttpieDecompressionError, HttpieFetchBodyError, HttpieParserError } from "../src/class/HttpieHandlerError";
-
-describe("isAsyncIterable", () => {
- it("should return false for synchronous iterable like an Array", () => {
- expect(Utils.isAsyncIterable([])).toStrictEqual(false);
- });
-
- it("should return false for synchronous iterable like a primitive string", () => {
- expect(Utils.isAsyncIterable("foobar")).toStrictEqual(false);
- });
-
- it("should return true for a Async Generator Function", () => {
- async function* foo() {
- yield "bar";
- }
- expect(Utils.isAsyncIterable(foo())).toStrictEqual(true);
- });
-});
-
-describe("getEncodingCharset", () => {
- it("should return 'utf-8' if no value is provided", () => {
- expect(Utils.getEncodingCharset()).toStrictEqual("utf-8");
- });
-
- it("should return 'utf-8' if the provided charset is not known", () => {
- expect(Utils.getEncodingCharset("bolekeole")).toStrictEqual("utf-8");
- });
-
- it("should return 'latin1' if the charset is equal to 'ISO-8859-1'", () => {
- expect(Utils.getEncodingCharset("ISO-8859-1")).toStrictEqual("latin1");
- });
-
- it("should return the charset unchanged (only if the charset is a valid BufferEncoding)", () => {
- expect(Utils.getEncodingCharset("ascii")).toStrictEqual("ascii");
- });
-});
-
-describe("createHeaders", () => {
- it("should return a plain object with 'user-agent' equal to 'httpie'", () => {
- const result = Utils.createHeaders({});
-
- expect(result).toEqual({ "user-agent": "httpie" });
- });
-
- it("should re-use provided headers plain object", () => {
- const result = Utils.createHeaders({
- headers: { foo: "bar" }
- });
-
- expect(result).toEqual({ foo: "bar", "user-agent": "httpie" });
- });
-
- it("should overwrite the 'user-agent' header", () => {
- const result = Utils.createHeaders({
- headers: { "user-agent": "myUserAgent" }
- });
-
- expect(result).toEqual({ "user-agent": "myUserAgent" });
- });
-
- it("should add authorization header (and override original property)", () => {
- const result = Utils.createHeaders({
- headers: {
- Authorization: "bar"
- },
- authorization: "foo"
- });
-
- expect(result).toEqual({ Authorization: "Bearer foo", "user-agent": "httpie" });
- });
-});
-
-describe("createBody", () => {
- it("should return 'undefined' when undefined is provided as body argument", () => {
- expect(Utils.createBody(undefined)).toStrictEqual(undefined);
- });
-
- it("should be able to prepare and stringify a JSON body", () => {
- const body = {
- foo: "bar"
- };
- const bodyStr = JSON.stringify(body);
- const headerRef: IncomingHttpHeaders = {};
-
- const result = Utils.createBody(body, headerRef);
-
- expect(result).toStrictEqual(bodyStr);
- expect(Object.keys(headerRef).length).toStrictEqual(2);
- expect(headerRef["content-type"]).toStrictEqual("application/json");
- expect(headerRef["content-length"]).toStrictEqual(String(Buffer.byteLength(bodyStr)));
- });
-
- it("should be able to prepare a FORM (URLEncoded) body", () => {
- const body = new URLSearchParams({
- foo: "bar"
- });
- const bodyStr = body.toString();
- const headerRef: IncomingHttpHeaders = {};
-
- const result = Utils.createBody(body, headerRef);
-
- expect(result).toStrictEqual(bodyStr);
- expect(Object.keys(headerRef).length).toStrictEqual(2);
- expect(headerRef["content-type"]).toStrictEqual("application/x-www-form-urlencoded");
- expect(headerRef["content-length"]).toStrictEqual(String(Buffer.byteLength(bodyStr)));
- });
-
- it("should be able to prepare a Buffer body", () => {
- const body = Buffer.from("hello world!");
- const headerRef: IncomingHttpHeaders = {};
-
- const result = Utils.createBody(body, headerRef);
-
- expect(result).toStrictEqual(body);
- expect(Object.keys(headerRef).length).toStrictEqual(1);
- expect(headerRef["content-length"]).toStrictEqual(String(Buffer.byteLength(body)));
- });
-
- it("should return the ReadableStream without any transformation", () => {
- const headerRef: IncomingHttpHeaders = {};
- const readStream = new stream.Readable();
-
- const result = Utils.createBody(readStream, headerRef);
-
- expect(result).toStrictEqual(readStream);
- expect(Object.keys(headerRef)).toHaveLength(0);
- });
-});
-
-describe("createAuthorizationHeader", () => {
- it("it should start with 'Bearer ' if the token is Bearer or empty string", () => {
- expect(Utils.createAuthorizationHeader("")).toStrictEqual("Bearer ");
- expect(Utils.createAuthorizationHeader("lol")).toStrictEqual("Bearer lol");
- });
-
- it("it should start with 'Basic ' for a Basic Authentication", () => {
- const result = Utils.createAuthorizationHeader("toto:lolo");
- const base64 = result.split(" ")[1];
-
- expect(result.startsWith("Basic ")).toBe(true);
- expect(Buffer.from(base64, "base64").toString("ascii")).toStrictEqual("toto:lolo");
- });
-});
-
-describe("isHttpieError", () => {
- it("it should be true", () => {
- expect(Utils.isHttpieError(new HttpieOnHttpError({} as any))).toBeTruthy();
- expect(Utils.isHttpieError(new HttpieFetchBodyError({ message: "ResponseFetchError", response: {} } as any))).toBeTruthy();
- expect(
- Utils.isHttpieError(new HttpieDecompressionError({ message: "UnexpectedDecompressionError", response: {} } as any))
- ).toBeTruthy();
- expect(Utils.isHttpieError(new HttpieParserError({ message: "ResponseParsingError", response: {} } as any))).toBeTruthy();
- });
-
- it("it should be false", () => {
- expect(Utils.isHttpieError(new Error())).toBeFalsy();
- });
-});
-
-describe("isHTTPError", () => {
- it("it should be true", () => {
- expect(Utils.isHTTPError(new HttpieOnHttpError({} as any))).toBeTruthy();
- });
-
- it("it should be false", () => {
- expect(Utils.isHTTPError(new Error())).toBeFalsy();
- expect(Utils.isHTTPError(new HttpieFetchBodyError({ message: "ResponseFetchError", response: {} } as any))).toBeFalsy();
- expect(
- Utils.isHTTPError(new HttpieDecompressionError({ message: "UnexpectedDecompressionError", response: {} } as any))
- ).toBeFalsy();
- expect(Utils.isHTTPError(new HttpieParserError({ message: "ResponseParsingError", response: {} } as any))).toBeFalsy();
- });
-});
-
-describe("getCurrentEnv", () => {
- afterAll(() => {
- Utils.env.NODE_ENV = "dev";
- });
-
- it("should return 'prod'", () => {
- Utils.env.NODE_ENV = "prod";
- expect(Utils.getCurrentEnv()).toStrictEqual("prod");
- });
-
- it("should return 'preprod'", () => {
- Utils.env.NODE_ENV = "staging";
- expect(Utils.getCurrentEnv()).toStrictEqual("preprod");
-
- Utils.env.NODE_ENV = "preprod";
- expect(Utils.getCurrentEnv()).toStrictEqual("preprod");
- });
-
- it("should return 'dev'", () => {
- Utils.env.NODE_ENV = "dev";
- expect(Utils.getCurrentEnv()).toStrictEqual("dev");
-
- Utils.env.NODE_ENV = "test";
- expect(Utils.getCurrentEnv()).toStrictEqual("dev");
- });
-
- it("should return 'dev' as default value", () => {
- delete Utils.env.NODE_ENV;
- expect(Utils.getCurrentEnv()).toStrictEqual("dev");
- });
-});
diff --git a/test/utils.test.ts b/test/utils.test.ts
new file mode 100644
index 0000000..56c0c99
--- /dev/null
+++ b/test/utils.test.ts
@@ -0,0 +1,199 @@
+// Import Node.js Dependencies
+import { describe, it } from "node:test";
+import { IncomingHttpHeaders } from "node:http2";
+import assert from "node:assert";
+import stream from "node:stream";
+
+// Import Internal Dependencies
+import * as Utils from "../src/utils";
+import { HttpieOnHttpError } from "../src/class/HttpieOnHttpError";
+import { HttpieDecompressionError, HttpieFetchBodyError, HttpieParserError } from "../src/class/HttpieHandlerError";
+
+describe("isAsyncIterable", () => {
+ it("should return false for synchronous iterable like an Array", () => {
+ assert.strictEqual(Utils.isAsyncIterable([]), false);
+ });
+
+ it("should return false for synchronous iterable like a primitive string", () => {
+ assert.strictEqual(Utils.isAsyncIterable("foobar"), false);
+ });
+
+ it("should return true for a Async Generator Function", () => {
+ async function* foo() {
+ yield "bar";
+ }
+ assert.strictEqual(Utils.isAsyncIterable(foo()), true);
+ });
+});
+
+describe("getEncodingCharset", () => {
+ it("should return 'utf-8' if no value is provided", () => {
+ assert.strictEqual(Utils.getEncodingCharset(), "utf-8");
+ });
+
+ it("should return 'utf-8' if the provided charset is not known", () => {
+ assert.strictEqual(Utils.getEncodingCharset("bolekeole"), "utf-8");
+ });
+
+ it("should return 'latin1' if the charset is equal to 'ISO-8859-1'", () => {
+ assert.strictEqual(Utils.getEncodingCharset("ISO-8859-1"), "latin1");
+ });
+
+ it("should return the charset unchanged (only if the charset is a valid BufferEncoding)", () => {
+ assert.strictEqual(Utils.getEncodingCharset("ascii"), "ascii");
+ });
+});
+
+describe("createHeaders", () => {
+ it("should return a plain object with 'user-agent' equal to 'httpie'", () => {
+ const result = Utils.createHeaders({});
+
+ assert.deepStrictEqual(result, { "user-agent": "httpie" });
+ });
+
+ it("should re-use provided headers plain object", () => {
+ const result = Utils.createHeaders({
+ headers: { foo: "bar" }
+ });
+
+ assert.deepStrictEqual(result, { foo: "bar", "user-agent": "httpie" });
+ });
+
+ it("should overwrite the 'user-agent' header", () => {
+ const result = Utils.createHeaders({
+ headers: { "user-agent": "myUserAgent" }
+ });
+
+ assert.deepStrictEqual(result, { "user-agent": "myUserAgent" });
+ });
+
+ it("should add authorization header (and override original property)", () => {
+ const result = Utils.createHeaders({
+ headers: {
+ Authorization: "bar"
+ },
+ authorization: "foo"
+ });
+
+ assert.deepStrictEqual(result, { Authorization: "Bearer foo", "user-agent": "httpie" });
+ });
+});
+
+describe("createBody", () => {
+ it("should return 'undefined' when undefined is provided as body argument", () => {
+ assert.strictEqual(Utils.createBody(undefined), undefined);
+ });
+
+ it("should be able to prepare and stringify a JSON body", () => {
+ const body = {
+ foo: "bar"
+ };
+ const bodyStr = JSON.stringify(body);
+ const headerRef: IncomingHttpHeaders = {};
+
+ const result = Utils.createBody(body, headerRef);
+
+ assert.strictEqual(result, bodyStr);
+ assert.strictEqual(Object.keys(headerRef).length, 2);
+ assert.strictEqual(headerRef["content-type"], "application/json");
+ assert.strictEqual(headerRef["content-length"], String(Buffer.byteLength(bodyStr)));
+ });
+
+ it("should be able to prepare a FORM (URLEncoded) body", () => {
+ const body = new URLSearchParams({
+ foo: "bar"
+ });
+ const bodyStr = body.toString();
+ const headerRef: IncomingHttpHeaders = {};
+
+ const result = Utils.createBody(body, headerRef);
+
+ assert.strictEqual(result, bodyStr);
+ assert.strictEqual(Object.keys(headerRef).length, 2);
+ assert.strictEqual(headerRef["content-type"], "application/x-www-form-urlencoded");
+ assert.strictEqual(headerRef["content-length"], String(Buffer.byteLength(bodyStr)));
+ });
+
+ it("should be able to prepare a Buffer body", () => {
+ const body = Buffer.from("hello world!");
+ const headerRef: IncomingHttpHeaders = {};
+
+ const result = Utils.createBody(body, headerRef);
+
+ assert.strictEqual(result, body);
+ assert.strictEqual(Object.keys(headerRef).length, 1);
+ assert.strictEqual(headerRef["content-length"], String(Buffer.byteLength(body)));
+ });
+
+ it("should return the ReadableStream without any transformation", () => {
+ const headerRef: IncomingHttpHeaders = {};
+ const readStream = new stream.Readable();
+
+ const result = Utils.createBody(readStream, headerRef);
+
+ assert.strictEqual(result, readStream);
+ assert.strictEqual(Object.keys(headerRef).length, 0);
+ });
+});
+
+describe("createAuthorizationHeader", () => {
+ it("it should start with 'Bearer ' if the token is Bearer or empty string", () => {
+ assert.strictEqual(Utils.createAuthorizationHeader(""), "Bearer ");
+ assert.strictEqual(Utils.createAuthorizationHeader("lol"), "Bearer lol");
+ });
+
+ it("it should start with 'Basic ' for a Basic Authentication", () => {
+ const result = Utils.createAuthorizationHeader("toto:lolo");
+ const base64 = result.split(" ")[1];
+
+ assert.strictEqual(result.startsWith("Basic "), true);
+ assert.strictEqual(Buffer.from(base64, "base64").toString("ascii"), "toto:lolo");
+ });
+});
+
+describe("isHttpieError", () => {
+ it("it should be true", () => {
+ assert.strictEqual(
+ Utils.isHttpieError(new HttpieOnHttpError({} as any)),
+ true
+ );
+ assert.strictEqual(
+ Utils.isHttpieError(new HttpieFetchBodyError({ message: "ResponseFetchError", response: {} } as any)),
+ true
+ );
+ assert.strictEqual(
+ Utils.isHttpieError(new HttpieDecompressionError({ message: "UnexpectedDecompressionError", response: {} } as any)),
+ true
+ );
+ assert.strictEqual(
+ Utils.isHttpieError(new HttpieParserError({ message: "ResponseParsingError", response: {} } as any)),
+ true
+ );
+ });
+
+ it("it should be false", () => {
+ assert.strictEqual(Utils.isHttpieError(new Error()), false);
+ });
+});
+
+describe("isHTTPError", () => {
+ it("it should be true", () => {
+ assert.strictEqual(Utils.isHTTPError(new HttpieOnHttpError({} as any)), true);
+ });
+
+ it("it should be false", () => {
+ assert.strictEqual(Utils.isHTTPError(new Error()), false);
+ assert.strictEqual(
+ Utils.isHTTPError(new HttpieFetchBodyError({ message: "ResponseFetchError", response: {} } as any)),
+ false
+ );
+ assert.strictEqual(
+ Utils.isHTTPError(new HttpieDecompressionError({ message: "UnexpectedDecompressionError", response: {} } as any)),
+ false
+ );
+ assert.strictEqual(
+ Utils.isHTTPError(new HttpieParserError({ message: "ResponseParsingError", response: {} } as any)),
+ false
+ );
+ });
+});
diff --git a/tsconfig.json b/tsconfig.json
index 6b26bef..74a87f6 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "@openally/config.typescript/cjs",
+ "extends": "@openally/config.typescript",
"compilerOptions": {
"outDir": "dist",
"rootDir": "./src",