diff --git a/packages/hoppscotch-cli/src/__tests__/e2e/commands/test.spec.ts b/packages/hoppscotch-cli/src/__tests__/e2e/commands/test.spec.ts index ba8a1abe8a..46083ca375 100644 --- a/packages/hoppscotch-cli/src/__tests__/e2e/commands/test.spec.ts +++ b/packages/hoppscotch-cli/src/__tests__/e2e/commands/test.spec.ts @@ -4,485 +4,505 @@ import { describe, expect, test } from "vitest"; import { HoppErrorCode } from "../../../types/errors"; import { getErrorCode, getTestJsonFilePath, runCLI } from "../../utils"; -describe("Test `hopp test ` command:", () => { - describe("Argument parsing", () => { - test("Errors with the code `INVALID_ARGUMENT` for not supplying enough arguments", async () => { - const args = "test"; - const { stderr } = await runCLI(args); - - const out = getErrorCode(stderr); - expect(out).toBe("INVALID_ARGUMENT"); - }); +describe("hopp test [options] ", () => { + const VALID_TEST_ARGS = `test ${getTestJsonFilePath("passes-coll.json", "collection")}`; - test("Errors with the code `INVALID_ARGUMENT` for an invalid command", async () => { - const args = "invalid-arg"; - const { stderr } = await runCLI(args); + describe("Test `hopp test ` command:", () => { + describe("Argument parsing", () => { + test("Errors with the code `INVALID_ARGUMENT` for not supplying enough arguments", async () => { + const args = "test"; + const { stderr } = await runCLI(args); - const out = getErrorCode(stderr); - expect(out).toBe("INVALID_ARGUMENT"); - }); - }); + const out = getErrorCode(stderr); + expect(out).toBe("INVALID_ARGUMENT"); + }); - describe("Supplied collection export file validations", () => { - test("Errors with the code `FILE_NOT_FOUND` if the supplied collection export file doesn't exist", async () => { - const args = "test notfound.json"; - const { stderr } = await runCLI(args); + test("Errors with the code `INVALID_ARGUMENT` for an invalid command", async () => { + const args = "invalid-arg"; + const { stderr } = await runCLI(args); - const out = getErrorCode(stderr); - expect(out).toBe("FILE_NOT_FOUND"); + const out = getErrorCode(stderr); + expect(out).toBe("INVALID_ARGUMENT"); + }); }); - test("Errors with the code UNKNOWN_ERROR if the supplied collection export file content isn't valid JSON", async () => { - const args = `test ${getTestJsonFilePath("malformed-coll.json", "collection")}`; - const { stderr } = await runCLI(args); + describe("Supplied collection export file validations", () => { + test("Errors with the code `FILE_NOT_FOUND` if the supplied collection export file doesn't exist", async () => { + const args = "test notfound.json"; + const { stderr } = await runCLI(args); - const out = getErrorCode(stderr); - expect(out).toBe("UNKNOWN_ERROR"); - }); + const out = getErrorCode(stderr); + expect(out).toBe("FILE_NOT_FOUND"); + }); - test("Errors with the code `MALFORMED_COLLECTION` if the supplied collection export file content is malformed", async () => { - const args = `test ${getTestJsonFilePath("malformed-coll-2.json", "collection")}`; - const { stderr } = await runCLI(args); + test("Errors with the code UNKNOWN_ERROR if the supplied collection export file content isn't valid JSON", async () => { + const args = `test ${getTestJsonFilePath("malformed-coll.json", "collection")}`; + const { stderr } = await runCLI(args); - const out = getErrorCode(stderr); - expect(out).toBe("MALFORMED_COLLECTION"); - }); + const out = getErrorCode(stderr); + expect(out).toBe("UNKNOWN_ERROR"); + }); - test("Errors with the code `INVALID_FILE_TYPE` if the supplied collection export file doesn't end with the `.json` extension", async () => { - const args = `test ${getTestJsonFilePath("notjson-coll.txt", "collection")}`; - const { stderr } = await runCLI(args); + test("Errors with the code `MALFORMED_COLLECTION` if the supplied collection export file content is malformed", async () => { + const args = `test ${getTestJsonFilePath("malformed-coll-2.json", "collection")}`; + const { stderr } = await runCLI(args); - const out = getErrorCode(stderr); - expect(out).toBe("INVALID_FILE_TYPE"); - }); + const out = getErrorCode(stderr); + expect(out).toBe("MALFORMED_COLLECTION"); + }); - test("Fails if the collection file includes scripts with incorrect API usage and failed assertions", async () => { - const args = `test ${getTestJsonFilePath("fails-coll.json", "collection")}`; - const { error } = await runCLI(args); + test("Errors with the code `INVALID_FILE_TYPE` if the supplied collection export file doesn't end with the `.json` extension", async () => { + const args = `test ${getTestJsonFilePath("notjson-coll.txt", "collection")}`; + const { stderr } = await runCLI(args); - expect(error).not.toBeNull(); - expect(error).toMatchObject({ - code: 1, + const out = getErrorCode(stderr); + expect(out).toBe("INVALID_FILE_TYPE"); }); - }); - }); - describe("Versioned entities", () => { - describe("Collections & Requests", () => { - const testFixtures = [ - { fileName: "coll-v1-req-v0.json", collVersion: 1, reqVersion: 0 }, - { fileName: "coll-v1-req-v1.json", collVersion: 1, reqVersion: 1 }, - { fileName: "coll-v2-req-v2.json", collVersion: 2, reqVersion: 2 }, - { fileName: "coll-v2-req-v3.json", collVersion: 2, reqVersion: 3 }, - ]; - - testFixtures.forEach(({ collVersion, fileName, reqVersion }) => { - test(`Successfully processes a supplied collection export file where the collection is based on the "v${collVersion}" schema and the request following the "v${reqVersion}" schema`, async () => { - const args = `test ${getTestJsonFilePath(fileName, "collection")}`; - const { error } = await runCLI(args); + test("Fails if the collection file includes scripts with incorrect API usage and failed assertions", async () => { + const args = `test ${getTestJsonFilePath("fails-coll.json", "collection")}`; + const { error } = await runCLI(args); - expect(error).toBeNull(); + expect(error).not.toBeNull(); + expect(error).toMatchObject({ + code: 1, }); }); }); - describe("Environments", () => { - const testFixtures = [ - { fileName: "env-v0.json", version: 0 }, - { fileName: "env-v1.json", version: 1 }, - ]; + describe("Versioned entities", () => { + describe("Collections & Requests", () => { + const testFixtures = [ + { fileName: "coll-v1-req-v0.json", collVersion: 1, reqVersion: 0 }, + { fileName: "coll-v1-req-v1.json", collVersion: 1, reqVersion: 1 }, + { fileName: "coll-v2-req-v2.json", collVersion: 2, reqVersion: 2 }, + { fileName: "coll-v2-req-v3.json", collVersion: 2, reqVersion: 3 }, + ]; + + testFixtures.forEach(({ collVersion, fileName, reqVersion }) => { + test(`Successfully processes a supplied collection export file where the collection is based on the "v${collVersion}" schema and the request following the "v${reqVersion}" schema`, async () => { + const args = `test ${getTestJsonFilePath(fileName, "collection")}`; + const { error } = await runCLI(args); + + expect(error).toBeNull(); + }); + }); + }); - testFixtures.forEach(({ fileName, version }) => { - test(`Successfully processes the supplied collection and environment export files where the environment is based on the "v${version}" schema`, async () => { - const ENV_PATH = getTestJsonFilePath(fileName, "environment"); - const args = `test ${getTestJsonFilePath("sample-coll.json", "collection")} --env ${ENV_PATH}`; - const { error } = await runCLI(args); + describe("Environments", () => { + const testFixtures = [ + { fileName: "env-v0.json", version: 0 }, + { fileName: "env-v1.json", version: 1 }, + ]; - expect(error).toBeNull(); + testFixtures.forEach(({ fileName, version }) => { + test(`Successfully processes the supplied collection and environment export files where the environment is based on the "v${version}" schema`, async () => { + const ENV_PATH = getTestJsonFilePath(fileName, "environment"); + const args = `test ${getTestJsonFilePath("sample-coll.json", "collection")} --env ${ENV_PATH}`; + const { error } = await runCLI(args); + + expect(error).toBeNull(); + }); }); }); }); - }); - test("Successfully processes a supplied collection export file of the expected format", async () => { - const args = `test ${getTestJsonFilePath("passes-coll.json", "collection")}`; - const { error } = await runCLI(args); + test("Successfully processes a supplied collection export file of the expected format", async () => { + const args = `test ${getTestJsonFilePath("passes-coll.json", "collection")}`; + const { error } = await runCLI(args); - expect(error).toBeNull(); - }); + expect(error).toBeNull(); + }); - test("Successfully inherits headers and authorization set at the root collection", async () => { - const args = `test ${getTestJsonFilePath( - "collection-level-headers-auth-coll.json", - "collection" - )}`; - const { error } = await runCLI(args); + test("Successfully inherits/overrides authorization and headers specified at the root collection at deeply nested collections", async () => { + const args = `test ${getTestJsonFilePath( + "collection-level-auth-headers-coll.json", + "collection" + )}`; + const { error } = await runCLI(args); - expect(error).toBeNull(); - }); + expect(error).toBeNull(); + }); - test("Persists environment variables set in the pre-request script for consumption in the test script", async () => { - const args = `test ${getTestJsonFilePath( - "pre-req-script-env-var-persistence-coll.json", - "collection" - )}`; - const { error } = await runCLI(args); + test( + "Successfully inherits/overrides authorization and headers at each level with multiple child collections", + async () => { + const args = `test ${getTestJsonFilePath( + "multiple-child-collections-auth-headers-coll.json", + "collection" + )}`; + const { error } = await runCLI(args); + + expect(error).toBeNull(); + }, + { timeout: 10000 } + ); + + test("Persists environment variables set in the pre-request script for consumption in the test script", async () => { + const args = `test ${getTestJsonFilePath( + "pre-req-script-env-var-persistence-coll.json", + "collection" + )}`; + const { error } = await runCLI(args); - expect(error).toBeNull(); + expect(error).toBeNull(); + }); }); -}); -describe("Test `hopp test --env ` command:", () => { - describe("Supplied environment export file validations", () => { - const VALID_TEST_ARGS = `test ${getTestJsonFilePath("passes-coll.json", "collection")}`; + describe("Test `hopp test --env ` command:", () => { + describe("Supplied environment export file validations", () => { + describe("Argument parsing", () => { + test("Errors with the code `INVALID_ARGUMENT` if no file is supplied", async () => { + const args = `${VALID_TEST_ARGS} --env`; + const { stderr } = await runCLI(args); - test("Errors with the code `INVALID_ARGUMENT` if no file is supplied", async () => { - const args = `${VALID_TEST_ARGS} --env`; - const { stderr } = await runCLI(args); + const out = getErrorCode(stderr); + expect(out).toBe("INVALID_ARGUMENT"); + }); + }); - const out = getErrorCode(stderr); - expect(out).toBe("INVALID_ARGUMENT"); - }); + test("Errors with the code `INVALID_FILE_TYPE` if the supplied environment export file doesn't end with the `.json` extension", async () => { + const args = `${VALID_TEST_ARGS} --env ${getTestJsonFilePath( + "notjson-coll.txt", + "collection" + )}`; + const { stderr } = await runCLI(args); - test("Errors with the code `INVALID_FILE_TYPE` if the supplied environment export file doesn't end with the `.json` extension", async () => { - const args = `${VALID_TEST_ARGS} --env ${getTestJsonFilePath( - "notjson-coll.txt", - "collection" - )}`; - const { stderr } = await runCLI(args); + const out = getErrorCode(stderr); + expect(out).toBe("INVALID_FILE_TYPE"); + }); + + test("Errors with the code `FILE_NOT_FOUND` if the supplied environment export file doesn't exist", async () => { + const args = `${VALID_TEST_ARGS} --env notfound.json`; + const { stderr } = await runCLI(args); - const out = getErrorCode(stderr); - expect(out).toBe("INVALID_FILE_TYPE"); + const out = getErrorCode(stderr); + expect(out).toBe("FILE_NOT_FOUND"); + }); + + test("Errors with the code `MALFORMED_ENV_FILE` on supplying a malformed environment export file", async () => { + const ENV_PATH = getTestJsonFilePath( + "malformed-envs.json", + "environment" + ); + const args = `${VALID_TEST_ARGS} --env ${ENV_PATH}`; + const { stderr } = await runCLI(args); + + const out = getErrorCode(stderr); + expect(out).toBe("MALFORMED_ENV_FILE"); + }); + + test("Errors with the code `BULK_ENV_FILE` on supplying an environment export file based on the bulk environment export format", async () => { + const ENV_PATH = getTestJsonFilePath("bulk-envs.json", "environment"); + const args = `${VALID_TEST_ARGS} --env ${ENV_PATH}`; + const { stderr } = await runCLI(args); + + const out = getErrorCode(stderr); + expect(out).toBe("BULK_ENV_FILE"); + }); }); - test("Errors with the code `FILE_NOT_FOUND` if the supplied environment export file doesn't exist", async () => { - const args = `${VALID_TEST_ARGS} --env notfound.json`; - const { stderr } = await runCLI(args); + test("Successfully resolves values from the supplied environment export file", async () => { + const TESTS_PATH = getTestJsonFilePath( + "env-flag-tests-coll.json", + "collection" + ); + const ENV_PATH = getTestJsonFilePath("env-flag-envs.json", "environment"); + const args = `test ${TESTS_PATH} --env ${ENV_PATH}`; - const out = getErrorCode(stderr); - expect(out).toBe("FILE_NOT_FOUND"); + const { error } = await runCLI(args); + expect(error).toBeNull(); }); - test("Errors with the code `MALFORMED_ENV_FILE` on supplying a malformed environment export file", async () => { - const ENV_PATH = getTestJsonFilePath( - "malformed-envs.json", + test("Successfully resolves environment variables referenced in the request body", async () => { + const COLL_PATH = getTestJsonFilePath( + "req-body-env-vars-coll.json", + "collection" + ); + const ENVS_PATH = getTestJsonFilePath( + "req-body-env-vars-envs.json", "environment" ); - const args = `${VALID_TEST_ARGS} --env ${ENV_PATH}`; - const { stderr } = await runCLI(args); + const args = `test ${COLL_PATH} --env ${ENVS_PATH}`; - const out = getErrorCode(stderr); - expect(out).toBe("MALFORMED_ENV_FILE"); + const { error } = await runCLI(args); + expect(error).toBeNull(); }); - test("Errors with the code `BULK_ENV_FILE` on supplying an environment export file based on the bulk environment export format", async () => { - const ENV_PATH = getTestJsonFilePath("bulk-envs.json", "environment"); - const args = `${VALID_TEST_ARGS} --env ${ENV_PATH}`; - const { stderr } = await runCLI(args); + test("Works with shorth `-e` flag", async () => { + const TESTS_PATH = getTestJsonFilePath( + "env-flag-tests-coll.json", + "collection" + ); + const ENV_PATH = getTestJsonFilePath("env-flag-envs.json", "environment"); + const args = `test ${TESTS_PATH} -e ${ENV_PATH}`; - const out = getErrorCode(stderr); - expect(out).toBe("BULK_ENV_FILE"); + const { error } = await runCLI(args); + expect(error).toBeNull(); }); - }); - test("Successfully resolves values from the supplied environment export file", async () => { - const TESTS_PATH = getTestJsonFilePath( - "env-flag-tests-coll.json", - "collection" - ); - const ENV_PATH = getTestJsonFilePath("env-flag-envs.json", "environment"); - const args = `test ${TESTS_PATH} --env ${ENV_PATH}`; + describe( + "Secret environment variables", + () => { + // Reads secret environment values from system environment + test("Successfully picks the values for secret environment variables from `process.env` and persists the variables set from the pre-request script", async () => { + const env = { + ...process.env, + secretBearerToken: "test-token", + secretBasicAuthUsername: "test-user", + secretBasicAuthPassword: "test-pass", + secretQueryParamValue: "secret-query-param-value", + secretBodyValue: "secret-body-value", + secretHeaderValue: "secret-header-value", + }; + + const COLL_PATH = getTestJsonFilePath( + "secret-envs-coll.json", + "collection" + ); + const ENVS_PATH = getTestJsonFilePath( + "secret-envs.json", + "environment" + ); + const args = `test ${COLL_PATH} --env ${ENVS_PATH}`; + + const { error, stdout } = await runCLI(args, { env }); + + expect(stdout).toContain( + "https://httpbin.org/basic-auth/*********/*********" + ); + expect(error).toBeNull(); + }); - const { error } = await runCLI(args); - expect(error).toBeNull(); - }); + // Prefers values specified in the environment export file over values set in the system environment + test("Successfully picks the values for secret environment variables set directly in the environment export file and persists the environment variables set from the pre-request script", async () => { + const COLL_PATH = getTestJsonFilePath( + "secret-envs-coll.json", + "collection" + ); + const ENVS_PATH = getTestJsonFilePath( + "secret-supplied-values-envs.json", + "environment" + ); + const args = `test ${COLL_PATH} --env ${ENVS_PATH}`; + + const { error, stdout } = await runCLI(args); + + expect(stdout).toContain( + "https://httpbin.org/basic-auth/*********/*********" + ); + expect(error).toBeNull(); + }); - test("Successfully resolves environment variables referenced in the request body", async () => { - const COLL_PATH = getTestJsonFilePath( - "req-body-env-vars-coll.json", - "collection" - ); - const ENVS_PATH = getTestJsonFilePath( - "req-body-env-vars-envs.json", - "environment" - ); - const args = `test ${COLL_PATH} --env ${ENVS_PATH}`; + // Values set from the scripting context takes the highest precedence + test("Setting values for secret environment variables from the pre-request script overrides values set at the supplied environment export file", async () => { + const COLL_PATH = getTestJsonFilePath( + "secret-envs-persistence-coll.json", + "collection" + ); + const ENVS_PATH = getTestJsonFilePath( + "secret-supplied-values-envs.json", + "environment" + ); + const args = `test ${COLL_PATH} --env ${ENVS_PATH}`; + + const { error, stdout } = await runCLI(args); + + expect(stdout).toContain( + "https://httpbin.org/basic-auth/*********/*********" + ); + expect(error).toBeNull(); + }); - const { error } = await runCLI(args); - expect(error).toBeNull(); - }); + test("Persists secret environment variable values set from the pre-request script for consumption in the request and post-request script context", async () => { + const COLL_PATH = getTestJsonFilePath( + "secret-envs-persistence-scripting-coll.json", + "collection" + ); + const ENVS_PATH = getTestJsonFilePath( + "secret-envs-persistence-scripting-envs.json", + "environment" + ); + const args = `test ${COLL_PATH} --env ${ENVS_PATH}`; - test("Works with shorth `-e` flag", async () => { - const TESTS_PATH = getTestJsonFilePath( - "env-flag-tests-coll.json", - "collection" + const { error } = await runCLI(args); + expect(error).toBeNull(); + }); + }, + { timeout: 10000 } ); - const ENV_PATH = getTestJsonFilePath("env-flag-envs.json", "environment"); - const args = `test ${TESTS_PATH} -e ${ENV_PATH}`; - - const { error } = await runCLI(args); - expect(error).toBeNull(); }); - describe( - "Secret environment variables", - () => { - // Reads secret environment values from system environment - test("Successfully picks the values for secret environment variables from `process.env` and persists the variables set from the pre-request script", async () => { - const env = { - ...process.env, - secretBearerToken: "test-token", - secretBasicAuthUsername: "test-user", - secretBasicAuthPassword: "test-pass", - secretQueryParamValue: "secret-query-param-value", - secretBodyValue: "secret-body-value", - secretHeaderValue: "secret-header-value", - }; - - const COLL_PATH = getTestJsonFilePath( - "secret-envs-coll.json", - "collection" - ); - const ENVS_PATH = getTestJsonFilePath( - "secret-envs.json", - "environment" - ); - const args = `test ${COLL_PATH} --env ${ENVS_PATH}`; - - const { error, stdout } = await runCLI(args, { env }); + describe("Test `hopp test --delay ` command:", () => { + describe("Argument parsing", () => { + test("Errors with the code `INVALID_ARGUMENT` on not supplying a delay value", async () => { + const args = `${VALID_TEST_ARGS} --delay`; + const { stderr } = await runCLI(args); - expect(stdout).toContain( - "https://httpbin.org/basic-auth/*********/*********" - ); - expect(error).toBeNull(); + const out = getErrorCode(stderr); + expect(out).toBe("INVALID_ARGUMENT"); }); - // Prefers values specified in the environment export file over values set in the system environment - test("Successfully picks the values for secret environment variables set directly in the environment export file and persists the environment variables set from the pre-request script", async () => { - const COLL_PATH = getTestJsonFilePath( - "secret-envs-coll.json", - "collection" - ); - const ENVS_PATH = getTestJsonFilePath( - "secret-supplied-values-envs.json", - "environment" - ); - const args = `test ${COLL_PATH} --env ${ENVS_PATH}`; - - const { error, stdout } = await runCLI(args); + test("Errors with the code `INVALID_ARGUMENT` on supplying an invalid delay value", async () => { + const args = `${VALID_TEST_ARGS} --delay 'NaN'`; + const { stderr } = await runCLI(args); - expect(stdout).toContain( - "https://httpbin.org/basic-auth/*********/*********" - ); - expect(error).toBeNull(); + const out = getErrorCode(stderr); + expect(out).toBe("INVALID_ARGUMENT"); }); + }); - // Values set from the scripting context takes the highest precedence - test("Setting values for secret environment variables from the pre-request script overrides values set at the supplied environment export file", async () => { - const COLL_PATH = getTestJsonFilePath( - "secret-envs-persistence-coll.json", - "collection" - ); - const ENVS_PATH = getTestJsonFilePath( - "secret-supplied-values-envs.json", - "environment" - ); - const args = `test ${COLL_PATH} --env ${ENVS_PATH}`; + test("Successfully performs delayed request execution for a valid delay value", async () => { + const args = `${VALID_TEST_ARGS} --delay 1`; + const { error } = await runCLI(args); - const { error, stdout } = await runCLI(args); + expect(error).toBeNull(); + }); - expect(stdout).toContain( - "https://httpbin.org/basic-auth/*********/*********" - ); - expect(error).toBeNull(); - }); + test("Works with the short `-d` flag", async () => { + const args = `${VALID_TEST_ARGS} -d 1`; + const { error } = await runCLI(args); - test("Persists secret environment variable values set from the pre-request script for consumption in the request and post-request script context", async () => { - const COLL_PATH = getTestJsonFilePath( - "secret-envs-persistence-scripting-coll.json", - "collection" - ); - const ENVS_PATH = getTestJsonFilePath( - "secret-envs-persistence-scripting-envs.json", - "environment" - ); - const args = `test ${COLL_PATH} --env ${ENVS_PATH}`; + expect(error).toBeNull(); + }); + }); - const { error } = await runCLI(args); - expect(error).toBeNull(); + describe.skip("Test `hopp test --env --token --server ` command:", () => { + const { + REQ_BODY_ENV_VARS_COLL_ID, + COLLECTION_LEVEL_HEADERS_AUTH_COLL_ID, + REQ_BODY_ENV_VARS_ENVS_ID, + PERSONAL_ACCESS_TOKEN, + } = process.env; + + if ( + !REQ_BODY_ENV_VARS_COLL_ID || + !COLLECTION_LEVEL_HEADERS_AUTH_COLL_ID || + !REQ_BODY_ENV_VARS_ENVS_ID || + !PERSONAL_ACCESS_TOKEN + ) { + return; + } + + const SERVER_URL = "https://stage-shc.hoppscotch.io/backend"; + + describe("Argument parsing", () => { + test("Errors with the code `INVALID_ARGUMENT` on not supplying a value for the `--token` flag", async () => { + const args = `test ${REQ_BODY_ENV_VARS_COLL_ID} --token`; + const { stderr } = await runCLI(args); + + const out = getErrorCode(stderr); + expect(out).toBe("INVALID_ARGUMENT"); }); - }, - { timeout: 10000 } - ); -}); -describe("Test `hopp test --delay ` command:", () => { - const VALID_TEST_ARGS = `test ${getTestJsonFilePath("passes-coll.json", "collection")}`; + test("Errors with the code `INVALID_ARGUMENT` on not supplying a value for the `--server` flag", async () => { + const args = `test ${REQ_BODY_ENV_VARS_COLL_ID} --server`; + const { stderr } = await runCLI(args); - test("Errors with the code `INVALID_ARGUMENT` on not supplying a delay value", async () => { - const args = `${VALID_TEST_ARGS} --delay`; - const { stderr } = await runCLI(args); + const out = getErrorCode(stderr); + expect(out).toBe("INVALID_ARGUMENT"); + }); + }); - const out = getErrorCode(stderr); - expect(out).toBe("INVALID_ARGUMENT"); - }); + describe("Workspace access validations", () => { + const INVALID_COLLECTION_ID = "invalid-coll-id"; + const INVALID_ENVIRONMENT_ID = "invalid-env-id"; + const INVALID_ACCESS_TOKEN = "invalid-token"; - test("Errors with the code `INVALID_ARGUMENT` on supplying an invalid delay value", async () => { - const args = `${VALID_TEST_ARGS} --delay 'NaN'`; - const { stderr } = await runCLI(args); + test("Errors with the code `TOKEN_INVALID` if the supplied access token is invalid", async () => { + const args = `test ${REQ_BODY_ENV_VARS_COLL_ID} --token ${INVALID_ACCESS_TOKEN} --server ${SERVER_URL}`; + const { stderr } = await runCLI(args); - const out = getErrorCode(stderr); - expect(out).toBe("INVALID_ARGUMENT"); - }); + const out = getErrorCode(stderr); + expect(out).toBe("TOKEN_INVALID"); + }); - test("Successfully performs delayed request execution for a valid delay value", async () => { - const args = `${VALID_TEST_ARGS} --delay 1`; - const { error } = await runCLI(args); + test("Errors with the code `INVALID_ID` if the supplied collection ID is invalid", async () => { + const args = `test ${INVALID_COLLECTION_ID} --token ${PERSONAL_ACCESS_TOKEN} --server ${SERVER_URL}`; + const { stderr } = await runCLI(args); - expect(error).toBeNull(); - }); + const out = getErrorCode(stderr); + expect(out).toBe("INVALID_ID"); + }); - test("Works with the short `-d` flag", async () => { - const args = `${VALID_TEST_ARGS} -d 1`; - const { error } = await runCLI(args); + test("Errors with the code `INVALID_ID` if the supplied environment ID is invalid", async () => { + const args = `test ${REQ_BODY_ENV_VARS_COLL_ID} --env ${INVALID_ENVIRONMENT_ID} --token ${PERSONAL_ACCESS_TOKEN} --server ${SERVER_URL}`; + const { stderr } = await runCLI(args); - expect(error).toBeNull(); - }); -}); + const out = getErrorCode(stderr); + expect(out).toBe("INVALID_ID"); + }); -describe.skip("Test `hopp test --env --token --server ` command:", () => { - const { - REQ_BODY_ENV_VARS_COLL_ID, - COLLECTION_LEVEL_HEADERS_AUTH_COLL_ID, - REQ_BODY_ENV_VARS_ENVS_ID, - PERSONAL_ACCESS_TOKEN, - } = process.env; - - if ( - !REQ_BODY_ENV_VARS_COLL_ID || - !COLLECTION_LEVEL_HEADERS_AUTH_COLL_ID || - !REQ_BODY_ENV_VARS_ENVS_ID || - !PERSONAL_ACCESS_TOKEN - ) { - return; - } - - const SERVER_URL = "https://stage-shc.hoppscotch.io/backend"; - - describe("Workspace access validations", () => { - const INVALID_COLLECTION_ID = "invalid-coll-id"; - const INVALID_ENVIRONMENT_ID = "invalid-env-id"; - const INVALID_ACCESS_TOKEN = "invalid-token"; - - test("Errors with the code `INVALID_ARGUMENT` on not supplying a value for the `--token` flag", async () => { - const args = `test ${REQ_BODY_ENV_VARS_COLL_ID} --token`; - const { stderr } = await runCLI(args); - - const out = getErrorCode(stderr); - expect(out).toBe("INVALID_ARGUMENT"); - }); + test("Errors with the code `INVALID_SERVER_URL` if not supplying a valid SH instance server URL", async () => { + // FE URL of the staging SHC instance + const INVALID_SERVER_URL = "https://stage-shc.hoppscotch.io"; + const args = `test ${REQ_BODY_ENV_VARS_COLL_ID} --env ${REQ_BODY_ENV_VARS_ENVS_ID} --token ${PERSONAL_ACCESS_TOKEN} --server ${INVALID_SERVER_URL}`; - test("Errors with the code `INVALID_ARGUMENT` on not supplying a value for the `--server` flag", async () => { - const args = `test ${REQ_BODY_ENV_VARS_COLL_ID} --server`; - const { stderr } = await runCLI(args); + const { stderr } = await runCLI(args); - const out = getErrorCode(stderr); - expect(out).toBe("INVALID_ARGUMENT"); - }); + const out = getErrorCode(stderr); + expect(out).toBe("INVALID_SERVER_URL"); + }); - test("Errors with the code `TOKEN_INVALID` if the supplied access token is invalid", async () => { - const args = `test ${REQ_BODY_ENV_VARS_COLL_ID} --token ${INVALID_ACCESS_TOKEN} --server ${SERVER_URL}`; - const { stderr } = await runCLI(args); + test("Errors with the code `SERVER_CONNECTION_REFUSED` if supplying an SH instance server URL that doesn't follow URL semantics", async () => { + const INVALID_URL = "invalid-url"; + const args = `test ${REQ_BODY_ENV_VARS_COLL_ID} --env ${REQ_BODY_ENV_VARS_ENVS_ID} --token ${PERSONAL_ACCESS_TOKEN} --server ${INVALID_URL}`; + const { stderr } = await runCLI(args); - const out = getErrorCode(stderr); - expect(out).toBe("TOKEN_INVALID"); + const out = getErrorCode(stderr); + expect(out).toBe("SERVER_CONNECTION_REFUSED"); + }); }); - test("Errors with the code `INVALID_ID` if the supplied collection ID is invalid", async () => { - const args = `test ${INVALID_COLLECTION_ID} --token ${PERSONAL_ACCESS_TOKEN} --server ${SERVER_URL}`; - const { stderr } = await runCLI(args); + test("Successfully retrieves a collection with the ID", async () => { + const args = `test ${COLLECTION_LEVEL_HEADERS_AUTH_COLL_ID} --token ${PERSONAL_ACCESS_TOKEN} --server ${SERVER_URL}`; - const out = getErrorCode(stderr); - expect(out).toBe("INVALID_ID"); + const { error } = await runCLI(args); + expect(error).toBeNull(); }); - test("Errors with the code `INVALID_ID` if the supplied environment ID is invalid", async () => { - const args = `test ${REQ_BODY_ENV_VARS_COLL_ID} --env ${INVALID_ENVIRONMENT_ID} --token ${PERSONAL_ACCESS_TOKEN} --server ${SERVER_URL}`; - const { stderr } = await runCLI(args); + test("Successfully retrieves collections and environments from a workspace using their respective IDs", async () => { + const args = `test ${REQ_BODY_ENV_VARS_COLL_ID} --env ${REQ_BODY_ENV_VARS_ENVS_ID} --token ${PERSONAL_ACCESS_TOKEN} --server ${SERVER_URL}`; - const out = getErrorCode(stderr); - expect(out).toBe("INVALID_ID"); + const { error } = await runCLI(args); + expect(error).toBeNull(); }); - test("Errors with the code `INVALID_SERVER_URL` if not supplying a valid SH instance server URL", async () => { - // FE URL of the staging SHC instance - const INVALID_SERVER_URL = "https://stage-shc.hoppscotch.io"; - const args = `test ${REQ_BODY_ENV_VARS_COLL_ID} --env ${REQ_BODY_ENV_VARS_ENVS_ID} --token ${PERSONAL_ACCESS_TOKEN} --server ${INVALID_SERVER_URL}`; - - const { stderr } = await runCLI(args); + test("Supports specifying collection file path along with environment ID", async () => { + const TESTS_PATH = getTestJsonFilePath( + "req-body-env-vars-coll.json", + "collection" + ); + const args = `test ${TESTS_PATH} --env ${REQ_BODY_ENV_VARS_ENVS_ID} --token ${PERSONAL_ACCESS_TOKEN} --server ${SERVER_URL}`; - const out = getErrorCode(stderr); - expect(out).toBe("INVALID_SERVER_URL"); + const { error } = await runCLI(args); + expect(error).toBeNull(); }); - test("Errors with the code `SERVER_CONNECTION_REFUSED` if supplying an SH instance server URL that doesn't follow URL semantics", async () => { - const INVALID_URL = "invalid-url"; - const args = `test ${REQ_BODY_ENV_VARS_COLL_ID} --env ${REQ_BODY_ENV_VARS_ENVS_ID} --token ${PERSONAL_ACCESS_TOKEN} --server ${INVALID_URL}`; - const { stderr } = await runCLI(args); + test("Supports specifying environment file path along with collection ID", async () => { + const ENV_PATH = getTestJsonFilePath( + "req-body-env-vars-envs.json", + "environment" + ); + const args = `test ${REQ_BODY_ENV_VARS_COLL_ID} --env ${ENV_PATH} --token ${PERSONAL_ACCESS_TOKEN} --server ${SERVER_URL}`; - const out = getErrorCode(stderr); - expect(out).toBe("SERVER_CONNECTION_REFUSED"); + const { error } = await runCLI(args); + expect(error).toBeNull(); }); - }); - - test("Successfully retrieves a collection with the ID", async () => { - const args = `test ${COLLECTION_LEVEL_HEADERS_AUTH_COLL_ID} --token ${PERSONAL_ACCESS_TOKEN} --server ${SERVER_URL}`; - - const { error } = await runCLI(args); - expect(error).toBeNull(); - }); - - test("Successfully retrieves collections and environments from a workspace using their respective IDs", async () => { - const args = `test ${REQ_BODY_ENV_VARS_COLL_ID} --env ${REQ_BODY_ENV_VARS_ENVS_ID} --token ${PERSONAL_ACCESS_TOKEN} --server ${SERVER_URL}`; - - const { error } = await runCLI(args); - expect(error).toBeNull(); - }); - - test("Supports specifying collection file path along with environment ID", async () => { - const TESTS_PATH = getTestJsonFilePath( - "req-body-env-vars-coll.json", - "collection" - ); - const args = `test ${TESTS_PATH} --env ${REQ_BODY_ENV_VARS_ENVS_ID} --token ${PERSONAL_ACCESS_TOKEN} --server ${SERVER_URL}`; - const { error } = await runCLI(args); - expect(error).toBeNull(); - }); - - test("Supports specifying environment file path along with collection ID", async () => { - const ENV_PATH = getTestJsonFilePath( - "req-body-env-vars-envs.json", - "environment" - ); - const args = `test ${REQ_BODY_ENV_VARS_COLL_ID} --env ${ENV_PATH} --token ${PERSONAL_ACCESS_TOKEN} --server ${SERVER_URL}`; - - const { error } = await runCLI(args); - expect(error).toBeNull(); - }); - - test("Supports specifying both collection and environment file paths", async () => { - const TESTS_PATH = getTestJsonFilePath( - "req-body-env-vars-coll.json", - "collection" - ); - const ENV_PATH = getTestJsonFilePath( - "req-body-env-vars-envs.json", - "environment" - ); - const args = `test ${TESTS_PATH} --env ${ENV_PATH} --token ${PERSONAL_ACCESS_TOKEN}`; + test("Supports specifying both collection and environment file paths", async () => { + const TESTS_PATH = getTestJsonFilePath( + "req-body-env-vars-coll.json", + "collection" + ); + const ENV_PATH = getTestJsonFilePath( + "req-body-env-vars-envs.json", + "environment" + ); + const args = `test ${TESTS_PATH} --env ${ENV_PATH} --token ${PERSONAL_ACCESS_TOKEN}`; - const { error } = await runCLI(args); - expect(error).toBeNull(); + const { error } = await runCLI(args); + expect(error).toBeNull(); + }); }); }); diff --git a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/collection-level-headers-auth-coll.json b/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/collection-level-auth-headers-coll.json similarity index 100% rename from packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/collection-level-headers-auth-coll.json rename to packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/collection-level-auth-headers-coll.json diff --git a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/multiple-child-collections-auth-headers-coll.json b/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/multiple-child-collections-auth-headers-coll.json new file mode 100644 index 0000000000..8e94b7df46 --- /dev/null +++ b/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/multiple-child-collections-auth-headers-coll.json @@ -0,0 +1,655 @@ +{ + "v": 2, + "id": "clx1f86hv000010f8szcfya0t", + "name": "Multiple child collections with authorization & headers set at each level", + "folders": [ + { + "v": 2, + "id": "clx1fjgah000110f8a5bs68gd", + "name": "folder-1", + "folders": [ + { + "v": 2, + "id": "clx1fjwmm000410f8l1gkkr1a", + "name": "folder-11", + "folders": [], + "requests": [ + { + "v": "4", + "auth": { + "authType": "inherit", + "password": "testpass", + "username": "testuser", + "authActive": true + }, + "body": { + "body": null, + "contentType": null + }, + "name": "folder-11-request", + "method": "GET", + "params": [], + "headers": [], + "endpoint": "https://httpbin.org/get", + "testScript": "// Check status code is 200\npw.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test(\"Successfully inherits authorization/header set at the parent collection level\", () => {\n pw.expect(pw.response.body.headers[\"Authorization\"]).toBe(\"Basic dGVzdHVzZXI6dGVzdHBhc3M=\")\n \n pw.expect(pw.response.body.headers[\"Custom-Header\"]).toBe(\"Custom header value overriden at folder-1\")\n pw.expect(pw.response.body.headers[\"Inherited-Header\"]).toBe(\"Inherited header at all levels\")\n})", + "preRequestScript": "", + "requestVariables": [] + } + ], + "auth": { + "authType": "inherit", + "authActive": true + }, + "headers": [ + { + "key": "key", + "value": "Set at folder-11", + "active": true + } + ] + }, + { + "v": 2, + "id": "clx1fjyxm000510f8pv90dt43", + "name": "folder-12", + "folders": [], + "requests": [ + { + "v": "4", + "auth": { + "authType": "none", + "authActive": true + }, + "body": { + "body": null, + "contentType": null + }, + "name": "folder-12-request", + "method": "GET", + "params": [], + "headers": [ + { + "key": "Custom-Header", + "value": "Custom header value overriden at folder-12-request", + "active": true + }, + { + "key": "key", + "value": "Overriden at folder-12-request", + "active": true + } + ], + "endpoint": "https://httpbin.org/get", + "testScript": "// Check status code is 200\npw.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test(\"Successfully inherits/overrides authorization/header set at the parent collection level\", () => {\n pw.expect(pw.response.body.headers[\"Authorization\"]).toBe(undefined)\n \n pw.expect(pw.response.body.headers[\"Custom-Header\"]).toBe(\"Custom header value overriden at folder-12-request\")\n pw.expect(pw.response.body.headers[\"Inherited-Header\"]).toBe(\"Inherited header at all levels\")\n pw.expect(pw.response.body.headers[\"Key\"]).toBe(\"Overriden at folder-12-request\")\n})", + "preRequestScript": "", + "requestVariables": [] + } + ], + "auth": { + "authType": "none", + "authActive": true + }, + "headers": [ + { + "key": "Custom-Header", + "value": "Custom header value overriden at folder-12", + "active": true + }, + { + "key": "key", + "value": "Set at folder-12", + "active": true + } + ] + }, + { + "v": 2, + "id": "clx1fk1cv000610f88kc3aupy", + "name": "folder-13", + "folders": [], + "requests": [ + { + "v": "4", + "auth": { + "key": "api-key", + "addTo": "HEADERS", + "value": "api-key-value", + "authType": "basic", + "password": "testpass", + "username": "testuser", + "authActive": true, + "grantTypeInfo": { + "token": "", + "isPKCE": true, + "clientID": "sfasfa", + "password": "", + "username": "", + "grantType": "AUTHORIZATION_CODE", + "authEndpoint": "asfafs", + "clientSecret": "sfasfasf", + "tokenEndpoint": "asfa", + "codeVerifierMethod": "S256" + } + }, + "body": { + "body": null, + "contentType": null + }, + "name": "folder-13-request", + "method": "GET", + "params": [], + "headers": [ + { + "key": "Custom-Header-Request-Level", + "value": "New custom header added at the folder-13-request level", + "active": true + }, + { + "key": "key", + "value": "Overriden at folder-13-request", + "active": true + } + ], + "endpoint": "https://httpbin.org/get", + "testScript": "// Check status code is 200\npw.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test(\"Successfully inherits/overrides authorization/header set at the parent collection level with new header addition\", () => {\n pw.expect(pw.response.body.headers[\"Authorization\"]).toBe(\"Basic dGVzdHVzZXI6dGVzdHBhc3M=\")\n \n pw.expect(pw.response.body.headers[\"Custom-Header\"]).toBe(\"Custom header value overriden at folder-13\")\n pw.expect(pw.response.body.headers[\"Inherited-Header\"]).toBe(\"Inherited header at all levels\")\n pw.expect(pw.response.body.headers[\"Key\"]).toBe(\"Overriden at folder-13-request\")\n pw.expect(pw.response.body.headers[\"Custom-Header-Request-Level\"]).toBe(\"New custom header added at the folder-13-request level\")\n})", + "preRequestScript": "", + "requestVariables": [] + } + ], + "auth": { + "token": "test-token", + "authType": "bearer", + "authActive": true + }, + "headers": [ + { + "key": "Custom-Header", + "value": "Custom header value overriden at folder-13", + "active": true + }, + { + "key": "key", + "value": "Set at folder-13", + "active": true + } + ] + } + ], + "requests": [ + { + "v": "4", + "auth": { + "authType": "inherit", + "authActive": true + }, + "body": { + "body": null, + "contentType": null + }, + "name": "folder-1-request", + "method": "GET", + "params": [], + "headers": [], + "endpoint": "https://httpbin.org/get", + "testScript": "// Check status code is 200\npw.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test(\"Successfully inherits authorization/header set at the parent collection level\", () => {\n pw.expect(pw.response.body.headers[\"Authorization\"]).toBe(\"Basic dGVzdHVzZXI6dGVzdHBhc3M=\")\n \n pw.expect(pw.response.body.headers[\"Custom-Header\"]).toBe(\"Custom header value overriden at folder-1\")\n pw.expect(pw.response.body.headers[\"Inherited-Header\"]).toBe(\"Inherited header at all levels\")\n})", + "preRequestScript": "", + "requestVariables": [] + } + ], + "auth": { + "authType": "inherit", + "authActive": true + }, + "headers": [ + { + "key": "Custom-Header", + "value": "Custom header value overriden at folder-1", + "active": true + } + ] + }, + { + "v": 2, + "id": "clx1fjk9o000210f8j0573pls", + "name": "folder-2", + "folders": [ + { + "v": 2, + "id": "clx1fk516000710f87sfpw6bo", + "name": "folder-21", + "folders": [], + "requests": [ + { + "v": "4", + "auth": { + "authType": "inherit", + "authActive": true + }, + "body": { + "body": null, + "contentType": null + }, + "name": "folder-21-request", + "method": "GET", + "params": [], + "headers": [], + "endpoint": "https://httpbin.org/get", + "testScript": "// Check status code is 200\npw.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test(\"Successfully inherits authorization/header set at the parent collection level\", () => {\n pw.expect(pw.response.body.headers[\"Authorization\"]).toBe(undefined)\n \n pw.expect(pw.response.body.headers[\"Custom-Header\"]).toBe(\"Custom header value overriden at folder-2\")\n pw.expect(pw.response.body.headers[\"Inherited-Header\"]).toBe(\"Inherited header at all levels\")\n})", + "preRequestScript": "", + "requestVariables": [] + } + ], + "auth": { + "authType": "inherit", + "authActive": true + }, + "headers": [ + { + "key": "key", + "value": "Set at folder-21", + "active": true + } + ] + }, + { + "v": 2, + "id": "clx1fk72t000810f8gfwkpi5y", + "name": "folder-22", + "folders": [], + "requests": [ + { + "v": "4", + "auth": { + "authType": "none", + "authActive": true + }, + "body": { + "body": null, + "contentType": null + }, + "name": "folder-22-request", + "method": "GET", + "params": [], + "headers": [ + { + "key": "Custom-Header", + "value": "Custom header value overriden at folder-22-request", + "active": true + }, + { + "key": "key", + "value": "Overriden at folder-22-request", + "active": true + } + ], + "endpoint": "https://httpbin.org/get", + "testScript": "// Check status code is 200\npw.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test(\"Successfully inherits/overrides authorization/header set at the parent collection level\", () => {\n pw.expect(pw.response.body.headers[\"Authorization\"]).toBe(undefined)\n \n pw.expect(pw.response.body.headers[\"Custom-Header\"]).toBe(\"Custom header value overriden at folder-22-request\")\n pw.expect(pw.response.body.headers[\"Inherited-Header\"]).toBe(\"Inherited header at all levels\")\n pw.expect(pw.response.body.headers[\"Key\"]).toBe(\"Overriden at folder-22-request\")\n})", + "preRequestScript": "", + "requestVariables": [] + } + ], + "auth": { + "authType": "none", + "authActive": true + }, + "headers": [ + { + "key": "Custom-Header", + "value": "Custom header value overriden at folder-22", + "active": true + }, + { + "key": "key", + "value": "Set at folder-22", + "active": true + } + ] + }, + { + "v": 2, + "id": "clx1fk95g000910f8bunhaoo8", + "name": "folder-23", + "folders": [], + "requests": [ + { + "v": "4", + "auth": { + "authType": "basic", + "password": "testpass", + "username": "testuser", + "authActive": true + }, + "body": { + "body": null, + "contentType": null + }, + "name": "folder-23-request", + "method": "GET", + "params": [], + "headers": [ + { + "key": "Custom-Header-Request-Level", + "value": "New custom header added at the folder-23-request level", + "active": true + }, + { + "key": "key", + "value": "Overriden at folder-23-request", + "active": true + } + ], + "endpoint": "https://httpbin.org/get", + "testScript": "// Check status code is 200\npw.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test(\"Successfully inherits/overrides authorization/header set at the parent collection level with new header addition\", () => {\n pw.expect(pw.response.body.headers[\"Authorization\"]).toBe(\"Basic dGVzdHVzZXI6dGVzdHBhc3M=\")\n \n pw.expect(pw.response.body.headers[\"Custom-Header\"]).toBe(\"Custom header value overriden at folder-23\")\n pw.expect(pw.response.body.headers[\"Inherited-Header\"]).toBe(\"Inherited header at all levels\")\n pw.expect(pw.response.body.headers[\"Key\"]).toBe(\"Overriden at folder-23-request\")\n pw.expect(pw.response.body.headers[\"Custom-Header-Request-Level\"]).toBe(\"New custom header added at the folder-23-request level\")\n})", + "preRequestScript": "", + "requestVariables": [] + } + ], + "auth": { + "token": "test-token", + "authType": "bearer", + "password": "testpass", + "username": "testuser", + "authActive": true + }, + "headers": [ + { + "key": "Custom-Header", + "value": "Custom header value overriden at folder-23", + "active": true + }, + { + "key": "key", + "value": "Set at folder-23", + "active": true + } + ] + } + ], + "requests": [ + { + "v": "4", + "auth": { + "authType": "none", + "authActive": true + }, + "body": { + "body": null, + "contentType": null + }, + "name": "folder-2-request", + "method": "GET", + "params": [], + "headers": [ + { + "key": "Custom-Header", + "value": "Custom header value overriden at folder-2-request", + "active": true + } + ], + "endpoint": "https://httpbin.org/get", + "testScript": "// Check status code is 200\npw.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test(\"Successfully inherits/overrides authorization/header set at the parent collection level\", () => {\n pw.expect(pw.response.body.headers[\"Authorization\"]).toBe(undefined)\n \n pw.expect(pw.response.body.headers[\"Custom-Header\"]).toBe(\"Custom header value overriden at folder-2-request\")\n pw.expect(pw.response.body.headers[\"Inherited-Header\"]).toBe(\"Inherited header at all levels\")\n})", + "preRequestScript": "", + "requestVariables": [] + } + ], + "auth": { + "authType": "none", + "authActive": true + }, + "headers": [ + { + "key": "Custom-Header", + "value": "Custom header value overriden at folder-2", + "active": true + } + ] + }, + { + "v": 2, + "id": "clx1fjmlq000310f86o4d3w2o", + "name": "folder-3", + "folders": [ + { + "v": 2, + "id": "clx1iwq0p003e10f8u8zg0p85", + "name": "folder-31", + "folders": [], + "requests": [ + { + "v": "4", + "auth": { + "authType": "inherit", + "authActive": true + }, + "body": { + "body": null, + "contentType": null + }, + "name": "folder-31-request", + "method": "GET", + "params": [], + "headers": [], + "endpoint": "https://httpbin.org/get", + "testScript": "// Check status code is 200\npw.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test(\"Successfully inherits authorization/header set at the parent collection level\", () => {\n pw.expect(pw.response.body.headers[\"Authorization\"]).toBe(\"Basic dGVzdHVzZXI6dGVzdHBhc3M=\")\n \n pw.expect(pw.response.body.headers[\"Custom-Header\"]).toBe(\"Custom header value overriden at folder-3\")\n pw.expect(pw.response.body.headers[\"Inherited-Header\"]).toBe(\"Inherited header at all levels\")\n})", + "preRequestScript": "", + "requestVariables": [] + } + ], + "auth": { + "authType": "inherit", + "authActive": true + }, + "headers": [ + { + "key": "key", + "value": "Set at folder-31", + "active": true + } + ] + }, + { + "v": 2, + "id": "clx1izut7003m10f894ip59zg", + "name": "folder-32", + "folders": [], + "requests": [ + { + "v": "4", + "auth": { + "authType": "none", + "authActive": true + }, + "body": { + "body": null, + "contentType": null + }, + "name": "folder-32-request", + "method": "GET", + "params": [], + "headers": [ + { + "key": "Custom-Header", + "value": "Custom header value overriden at folder-32-request", + "active": true + }, + { + "key": "key", + "value": "Overriden at folder-32-request", + "active": true + } + ], + "endpoint": "https://httpbin.org/get", + "testScript": "// Check status code is 200\npw.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test(\"Successfully inherits/overrides authorization/header set at the parent collection level\", () => {\n pw.expect(pw.response.body.headers[\"Authorization\"]).toBe(undefined)\n \n pw.expect(pw.response.body.headers[\"Custom-Header\"]).toBe(\"Custom header value overriden at folder-32-request\")\n pw.expect(pw.response.body.headers[\"Inherited-Header\"]).toBe(\"Inherited header at all levels\")\n pw.expect(pw.response.body.headers[\"Key\"]).toBe(\"Overriden at folder-32-request\")\n})", + "preRequestScript": "", + "requestVariables": [] + } + ], + "auth": { + "authType": "none", + "authActive": true + }, + "headers": [ + { + "key": "Custom-Header", + "value": "Custom header value overriden at folder-32", + "active": true + }, + { + "key": "key", + "value": "Set at folder-32", + "active": true + } + ] + }, + { + "v": 2, + "id": "clx1j2ka9003q10f8cdbzpgpg", + "name": "folder-33", + "folders": [], + "requests": [ + { + "v": "4", + "auth": { + "authType": "basic", + "password": "testpass", + "username": "testuser", + "authActive": true + }, + "body": { + "body": null, + "contentType": null + }, + "name": "folder-33-request", + "method": "GET", + "params": [], + "headers": [ + { + "key": "Custom-Header-Request-Level", + "value": "New custom header added at the folder-33-request level", + "active": true + }, + { + "key": "key", + "value": "Overriden at folder-33-request", + "active": true + } + ], + "endpoint": "https://httpbin.org/get", + "testScript": "// Check status code is 200\npw.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test(\"Successfully inherits/overrides authorization/header set at the parent collection level with new header addition\", () => {\n pw.expect(pw.response.body.headers[\"Authorization\"]).toBe(\"Basic dGVzdHVzZXI6dGVzdHBhc3M=\")\n \n pw.expect(pw.response.body.headers[\"Custom-Header\"]).toBe(\"Custom header value overriden at folder-33\")\n pw.expect(pw.response.body.headers[\"Inherited-Header\"]).toBe(\"Inherited header at all levels\")\n pw.expect(pw.response.body.headers[\"Key\"]).toBe(\"Overriden at folder-33-request\")\n pw.expect(pw.response.body.headers[\"Custom-Header-Request-Level\"]).toBe(\"New custom header added at the folder-33-request level\")\n})", + "preRequestScript": "", + "requestVariables": [] + } + ], + "auth": { + "token": "test-token", + "authType": "bearer", + "password": "testpass", + "username": "testuser", + "authActive": true + }, + "headers": [ + { + "key": "Custom-Header", + "value": "Custom header value overriden at folder-33", + "active": true + }, + { + "key": "key", + "value": "Set at folder-33", + "active": true + } + ] + } + ], + "requests": [ + { + "v": "4", + "auth": { + "authType": "basic", + "password": "testpass", + "username": "testuser", + "authActive": true + }, + "body": { + "body": null, + "contentType": null + }, + "name": "folder-3-request", + "method": "GET", + "params": [], + "headers": [ + { + "key": "Custom-Header-Request-Level", + "value": "New custom header added at the folder-3-request level", + "active": true + }, + { + "key": "key", + "value": "Set at folder-3-request", + "active": true + } + ], + "endpoint": "https://httpbin.org/get", + "testScript": "// Check status code is 200\npw.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test(\"Successfully inherits/overrides authorization/header set at the parent collection level with new header addition\", () => {\n pw.expect(pw.response.body.headers[\"Authorization\"]).toBe(\"Basic dGVzdHVzZXI6dGVzdHBhc3M=\")\n \n pw.expect(pw.response.body.headers[\"Custom-Header\"]).toBe(\"Custom header value overriden at folder-3\")\n pw.expect(pw.response.body.headers[\"Inherited-Header\"]).toBe(\"Inherited header at all levels\")\n pw.expect(pw.response.body.headers[\"Key\"]).toBe(\"Set at folder-3-request\")\n pw.expect(pw.response.body.headers[\"Custom-Header-Request-Level\"]).toBe(\"New custom header added at the folder-3-request level\")\n})", + "preRequestScript": "", + "requestVariables": [] + } + ], + "auth": { + "key": "testuser", + "addTo": "HEADERS", + "value": "testpass", + "authType": "basic", + "password": "testpass", + "username": "testuser", + "authActive": true + }, + "headers": [ + { + "key": "Custom-Header", + "value": "Custom header value overriden at folder-3", + "active": true + } + ] + } + ], + "requests": [ + { + "v": "4", + "auth": { + "authType": "inherit", + "authActive": true + }, + "body": { + "body": null, + "contentType": null + }, + "name": "root-collection-request", + "method": "GET", + "params": [], + "headers": [], + "endpoint": "https://httpbin.org/get", + "testScript": "// Check status code is 200\npw.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test(\"Successfully inherits authorization/header set at the parent collection level\", () => {\n pw.expect(pw.response.body.headers[\"Authorization\"]).toBe(\"Basic dGVzdHVzZXI6dGVzdHBhc3M=\")\n \n pw.expect(pw.response.body.headers[\"Custom-Header\"]).toBe(\"Custom header value set at the root collection\")\n pw.expect(pw.response.body.headers[\"Inherited-Header\"]).toBe(\"Inherited header at all levels\")\n})", + "preRequestScript": "", + "requestVariables": [] + } + ], + "auth": { + "authType": "basic", + "password": "testpass", + "username": "testuser", + "authActive": true + }, + "headers": [ + { + "key": "Custom-Header", + "value": "Custom header value set at the root collection", + "active": true + }, + { + "key": "Inherited-Header", + "value": "Inherited header at all levels", + "active": true + } + ] +} \ No newline at end of file diff --git a/packages/hoppscotch-cli/src/__tests__/unit/fixtures/workspace-access.mock.ts b/packages/hoppscotch-cli/src/__tests__/unit/fixtures/workspace-access.mock.ts index 9fe11a8321..fe12a41f4c 100644 --- a/packages/hoppscotch-cli/src/__tests__/unit/fixtures/workspace-access.mock.ts +++ b/packages/hoppscotch-cli/src/__tests__/unit/fixtures/workspace-access.mock.ts @@ -4,6 +4,7 @@ import { EnvironmentSchemaVersion, HoppCollection, } from "@hoppscotch/data"; + import { WorkspaceCollection, WorkspaceEnvironment, @@ -82,7 +83,7 @@ export const WORKSPACE_DEEPLY_NESTED_COLLECTIONS_WITH_AUTH_HEADERS_MOCK: Workspa ], }; -export const TRANFORMED_DEEPLY_NESTED_COLLECTIONS_WITH_AUTH_HEADERS_MOCK: HoppCollection = +export const TRANSFORMED_DEEPLY_NESTED_COLLECTIONS_WITH_AUTH_HEADERS_MOCK: HoppCollection = { v: CollectionSchemaVersion, id: "clx1ldkzs005t10f8rp5u60q7", @@ -473,679 +474,6 @@ export const WORKSPACE_MULTIPLE_CHILD_COLLECTIONS_WITH_AUTH_HEADERS_MOCK: Worksp ], }; -export const TRANSFORMED_MULTIPLE_CHILD_COLLECTIONS_WITH_AUTH_HEADERS_MOCK: HoppCollection = - { - v: CollectionSchemaVersion, - id: "clx1f86hv000010f8szcfya0t", - name: "Multiple child collections with authorization & headers set at each level", - folders: [ - { - v: CollectionSchemaVersion, - id: "clx1fjgah000110f8a5bs68gd", - name: "folder-1", - folders: [ - { - v: CollectionSchemaVersion, - id: "clx1fjwmm000410f8l1gkkr1a", - name: "folder-11", - folders: [], - requests: [ - { - v: "4", - auth: { - authType: "inherit", - password: "testpass", - username: "testuser", - authActive: true, - }, - body: { - body: null, - contentType: null, - }, - name: "folder-11-request", - method: "GET", - params: [], - headers: [], - endpoint: "https://httpbin.org/get", - testScript: - '// Check status code is 200\npw.test("Status code is 200", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test("Successfully inherits authorization/header set at the parent collection level", () => {\n pw.expect(pw.response.body.headers["Authorization"]).toBe("Basic dGVzdHVzZXI6dGVzdHBhc3M=")\n \n pw.expect(pw.response.body.headers["Custom-Header"]).toBe("Custom header value overriden at folder-1")\n pw.expect(pw.response.body.headers["Inherited-Header"]).toBe("Inherited header at all levels")\n})', - preRequestScript: "", - requestVariables: [], - }, - ], - auth: { - authType: "inherit", - authActive: true, - }, - headers: [ - { - key: "key", - value: "Set at folder-11", - active: true, - }, - ], - }, - { - v: CollectionSchemaVersion, - id: "clx1fjyxm000510f8pv90dt43", - name: "folder-12", - folders: [], - requests: [ - { - v: "4", - auth: { - authType: "none", - authActive: true, - }, - body: { - body: null, - contentType: null, - }, - name: "folder-12-request", - method: "GET", - params: [], - headers: [ - { - key: "Custom-Header", - value: "Custom header value overriden at folder-12-request", - active: true, - }, - { - key: "key", - value: "Overriden at folder-12-request", - active: true, - }, - ], - endpoint: "https://httpbin.org/get", - testScript: - '// Check status code is 200\npw.test("Status code is 200", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test("Successfully inherits/overrides authorization/header set at the parent collection level", () => {\n pw.expect(pw.response.body.headers["Authorization"]).toBe(undefined)\n \n pw.expect(pw.response.body.headers["Custom-Header"]).toBe("Custom header value overriden at folder-12-request")\n pw.expect(pw.response.body.headers["Inherited-Header"]).toBe("Inherited header at all levels")\n pw.expect(pw.response.body.headers["Key"]).toBe("Overriden at folder-12-request")\n})', - preRequestScript: "", - requestVariables: [], - }, - ], - auth: { - authType: "none", - authActive: true, - }, - headers: [ - { - key: "Custom-Header", - value: "Custom header value overriden at folder-12", - active: true, - }, - { - key: "key", - value: "Set at folder-12", - active: true, - }, - ], - }, - { - v: CollectionSchemaVersion, - id: "clx1fk1cv000610f88kc3aupy", - name: "folder-13", - folders: [], - requests: [ - { - v: "4", - auth: { - key: "api-key", - addTo: "HEADERS", - value: "api-key-value", - authType: "basic", - password: "testpass", - username: "testuser", - authActive: true, - grantTypeInfo: { - token: "", - isPKCE: true, - clientID: "sfasfa", - password: "", - username: "", - grantType: "AUTHORIZATION_CODE", - authEndpoint: "asfafs", - clientSecret: "sfasfasf", - tokenEndpoint: "asfa", - codeVerifierMethod: "S256", - }, - }, - body: { - body: null, - contentType: null, - }, - name: "folder-13-request", - method: "GET", - params: [], - headers: [ - { - key: "Custom-Header-Request-Level", - value: - "New custom header added at the folder-13-request level", - active: true, - }, - { - key: "key", - value: "Overriden at folder-13-request", - active: true, - }, - ], - endpoint: "https://httpbin.org/get", - testScript: - '// Check status code is 200\npw.test("Status code is 200", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test("Successfully inherits/overrides authorization/header set at the parent collection level with new header addition", () => {\n pw.expect(pw.response.body.headers["Authorization"]).toBe("Basic dGVzdHVzZXI6dGVzdHBhc3M=")\n \n pw.expect(pw.response.body.headers["Custom-Header"]).toBe("Custom header value overriden at folder-13")\n pw.expect(pw.response.body.headers["Inherited-Header"]).toBe("Inherited header at all levels")\n pw.expect(pw.response.body.headers["Key"]).toBe("Overriden at folder-13-request")\n pw.expect(pw.response.body.headers["Custom-Header-Request-Level"]).toBe("New custom header added at the folder-13-request level")\n})', - preRequestScript: "", - requestVariables: [], - }, - ], - auth: { - token: "test-token", - authType: "bearer", - authActive: true, - }, - headers: [ - { - key: "Custom-Header", - value: "Custom header value overriden at folder-13", - active: true, - }, - { - key: "key", - value: "Set at folder-13", - active: true, - }, - ], - }, - ], - requests: [ - { - v: "4", - auth: { - authType: "inherit", - authActive: true, - }, - body: { - body: null, - contentType: null, - }, - name: "folder-1-request", - method: "GET", - params: [], - headers: [], - endpoint: "https://httpbin.org/get", - testScript: - '// Check status code is 200\npw.test("Status code is 200", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test("Successfully inherits authorization/header set at the parent collection level", () => {\n pw.expect(pw.response.body.headers["Authorization"]).toBe("Basic dGVzdHVzZXI6dGVzdHBhc3M=")\n \n pw.expect(pw.response.body.headers["Custom-Header"]).toBe("Custom header value overriden at folder-1")\n pw.expect(pw.response.body.headers["Inherited-Header"]).toBe("Inherited header at all levels")\n})', - preRequestScript: "", - requestVariables: [], - }, - ], - auth: { - authType: "inherit", - authActive: true, - }, - headers: [ - { - key: "Custom-Header", - value: "Custom header value overriden at folder-1", - active: true, - }, - ], - }, - { - v: CollectionSchemaVersion, - id: "clx1fjk9o000210f8j0573pls", - name: "folder-2", - folders: [ - { - v: CollectionSchemaVersion, - id: "clx1fk516000710f87sfpw6bo", - name: "folder-21", - folders: [], - requests: [ - { - v: "4", - auth: { - authType: "inherit", - authActive: true, - }, - body: { - body: null, - contentType: null, - }, - name: "folder-21-request", - method: "GET", - params: [], - headers: [], - endpoint: "https://httpbin.org/get", - testScript: - '// Check status code is 200\npw.test("Status code is 200", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test("Successfully inherits authorization/header set at the parent collection level", () => {\n pw.expect(pw.response.body.headers["Authorization"]).toBe(undefined)\n \n pw.expect(pw.response.body.headers["Custom-Header"]).toBe("Custom header value overriden at folder-2")\n pw.expect(pw.response.body.headers["Inherited-Header"]).toBe("Inherited header at all levels")\n})', - preRequestScript: "", - requestVariables: [], - }, - ], - auth: { - authType: "inherit", - authActive: true, - }, - headers: [ - { - key: "key", - value: "Set at folder-21", - active: true, - }, - ], - }, - { - v: CollectionSchemaVersion, - id: "clx1fk72t000810f8gfwkpi5y", - name: "folder-22", - folders: [], - requests: [ - { - v: "4", - auth: { - authType: "none", - authActive: true, - }, - body: { - body: null, - contentType: null, - }, - name: "folder-22-request", - method: "GET", - params: [], - headers: [ - { - key: "Custom-Header", - value: "Custom header value overriden at folder-22-request", - active: true, - }, - { - key: "key", - value: "Overriden at folder-22-request", - active: true, - }, - ], - endpoint: "https://httpbin.org/get", - testScript: - '// Check status code is 200\npw.test("Status code is 200", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test("Successfully inherits/overrides authorization/header set at the parent collection level", () => {\n pw.expect(pw.response.body.headers["Authorization"]).toBe(undefined)\n \n pw.expect(pw.response.body.headers["Custom-Header"]).toBe("Custom header value overriden at folder-22-request")\n pw.expect(pw.response.body.headers["Inherited-Header"]).toBe("Inherited header at all levels")\n pw.expect(pw.response.body.headers["Key"]).toBe("Overriden at folder-22-request")\n})', - preRequestScript: "", - requestVariables: [], - }, - ], - auth: { - authType: "none", - authActive: true, - }, - headers: [ - { - key: "Custom-Header", - value: "Custom header value overriden at folder-22", - active: true, - }, - { - key: "key", - value: "Set at folder-22", - active: true, - }, - ], - }, - { - v: CollectionSchemaVersion, - id: "clx1fk95g000910f8bunhaoo8", - name: "folder-23", - folders: [], - requests: [ - { - v: "4", - auth: { - authType: "basic", - password: "testpass", - username: "testuser", - authActive: true, - }, - body: { - body: null, - contentType: null, - }, - name: "folder-23-request", - method: "GET", - params: [], - headers: [ - { - key: "Custom-Header-Request-Level", - value: - "New custom header added at the folder-23-request level", - active: true, - }, - { - key: "key", - value: "Overriden at folder-23-request", - active: true, - }, - ], - endpoint: "https://httpbin.org/get", - testScript: - '// Check status code is 200\npw.test("Status code is 200", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test("Successfully inherits/overrides authorization/header set at the parent collection level with new header addition", () => {\n pw.expect(pw.response.body.headers["Authorization"]).toBe("Basic dGVzdHVzZXI6dGVzdHBhc3M=")\n \n pw.expect(pw.response.body.headers["Custom-Header"]).toBe("Custom header value overriden at folder-23")\n pw.expect(pw.response.body.headers["Inherited-Header"]).toBe("Inherited header at all levels")\n pw.expect(pw.response.body.headers["Key"]).toBe("Overriden at folder-23-request")\n pw.expect(pw.response.body.headers["Custom-Header-Request-Level"]).toBe("New custom header added at the folder-23-request level")\n})', - preRequestScript: "", - requestVariables: [], - }, - ], - auth: { - token: "test-token", - authType: "bearer", - password: "testpass", - username: "testuser", - authActive: true, - }, - headers: [ - { - key: "Custom-Header", - value: "Custom header value overriden at folder-23", - active: true, - }, - { - key: "key", - value: "Set at folder-23", - active: true, - }, - ], - }, - ], - requests: [ - { - v: "4", - auth: { - authType: "none", - authActive: true, - }, - body: { - body: null, - contentType: null, - }, - name: "folder-2-request", - method: "GET", - params: [], - headers: [ - { - key: "Custom-Header", - value: "Custom header value overriden at folder-2-request", - active: true, - }, - ], - endpoint: "https://httpbin.org/get", - testScript: - '// Check status code is 200\npw.test("Status code is 200", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test("Successfully inherits/overrides authorization/header set at the parent collection level", () => {\n pw.expect(pw.response.body.headers["Authorization"]).toBe(undefined)\n \n pw.expect(pw.response.body.headers["Custom-Header"]).toBe("Custom header value overriden at folder-2-request")\n pw.expect(pw.response.body.headers["Inherited-Header"]).toBe("Inherited header at all levels")\n})', - preRequestScript: "", - requestVariables: [], - }, - ], - auth: { - authType: "none", - authActive: true, - }, - headers: [ - { - key: "Custom-Header", - value: "Custom header value overriden at folder-2", - active: true, - }, - ], - }, - { - v: CollectionSchemaVersion, - id: "clx1fjmlq000310f86o4d3w2o", - name: "folder-3", - folders: [ - { - v: CollectionSchemaVersion, - id: "clx1iwq0p003e10f8u8zg0p85", - name: "folder-31", - folders: [], - requests: [ - { - v: "4", - auth: { - authType: "inherit", - authActive: true, - }, - body: { - body: null, - contentType: null, - }, - name: "folder-31-request", - method: "GET", - params: [], - headers: [], - endpoint: "https://httpbin.org/get", - testScript: - '// Check status code is 200\npw.test("Status code is 200", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test("Successfully inherits authorization/header set at the parent collection level", () => {\n pw.expect(pw.response.body.headers["Authorization"]).toBe("Basic dGVzdHVzZXI6dGVzdHBhc3M=")\n \n pw.expect(pw.response.body.headers["Custom-Header"]).toBe("Custom header value overriden at folder-3")\n pw.expect(pw.response.body.headers["Inherited-Header"]).toBe("Inherited header at all levels")\n})', - preRequestScript: "", - requestVariables: [], - }, - ], - auth: { - authType: "inherit", - authActive: true, - }, - headers: [ - { - key: "key", - value: "Set at folder-31", - active: true, - }, - ], - }, - { - v: CollectionSchemaVersion, - id: "clx1izut7003m10f894ip59zg", - name: "folder-32", - folders: [], - requests: [ - { - v: "4", - auth: { - authType: "none", - authActive: true, - }, - body: { - body: null, - contentType: null, - }, - name: "folder-32-request", - method: "GET", - params: [], - headers: [ - { - key: "Custom-Header", - value: "Custom header value overriden at folder-32-request", - active: true, - }, - { - key: "key", - value: "Overriden at folder-32-request", - active: true, - }, - ], - endpoint: "https://httpbin.org/get", - testScript: - '// Check status code is 200\npw.test("Status code is 200", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test("Successfully inherits/overrides authorization/header set at the parent collection level", () => {\n pw.expect(pw.response.body.headers["Authorization"]).toBe(undefined)\n \n pw.expect(pw.response.body.headers["Custom-Header"]).toBe("Custom header value overriden at folder-32-request")\n pw.expect(pw.response.body.headers["Inherited-Header"]).toBe("Inherited header at all levels")\n pw.expect(pw.response.body.headers["Key"]).toBe("Overriden at folder-32-request")\n})', - preRequestScript: "", - requestVariables: [], - }, - ], - auth: { - authType: "none", - authActive: true, - }, - headers: [ - { - key: "Custom-Header", - value: "Custom header value overriden at folder-32", - active: true, - }, - { - key: "key", - value: "Set at folder-32", - active: true, - }, - ], - }, - { - v: CollectionSchemaVersion, - id: "clx1j2ka9003q10f8cdbzpgpg", - name: "folder-33", - folders: [], - requests: [ - { - v: "4", - auth: { - authType: "basic", - password: "testpass", - username: "testuser", - authActive: true, - }, - body: { - body: null, - contentType: null, - }, - name: "folder-33-request", - method: "GET", - params: [], - headers: [ - { - key: "Custom-Header-Request-Level", - value: - "New custom header added at the folder-33-request level", - active: true, - }, - { - key: "key", - value: "Overriden at folder-33-request", - active: true, - }, - ], - endpoint: "https://httpbin.org/get", - testScript: - '// Check status code is 200\npw.test("Status code is 200", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test("Successfully inherits/overrides authorization/header set at the parent collection level with new header addition", () => {\n pw.expect(pw.response.body.headers["Authorization"]).toBe("Basic dGVzdHVzZXI6dGVzdHBhc3M=")\n \n pw.expect(pw.response.body.headers["Custom-Header"]).toBe("Custom header value overriden at folder-33")\n pw.expect(pw.response.body.headers["Inherited-Header"]).toBe("Inherited header at all levels")\n pw.expect(pw.response.body.headers["Key"]).toBe("Overriden at folder-33-request")\n pw.expect(pw.response.body.headers["Custom-Header-Request-Level"]).toBe("New custom header added at the folder-33-request level")\n})', - preRequestScript: "", - requestVariables: [], - }, - ], - auth: { - token: "test-token", - authType: "bearer", - password: "testpass", - username: "testuser", - authActive: true, - }, - headers: [ - { - key: "Custom-Header", - value: "Custom header value overriden at folder-33", - active: true, - }, - { - key: "key", - value: "Set at folder-33", - active: true, - }, - ], - }, - ], - requests: [ - { - v: "4", - auth: { - authType: "basic", - password: "testpass", - username: "testuser", - authActive: true, - }, - body: { - body: null, - contentType: null, - }, - name: "folder-3-request", - method: "GET", - params: [], - headers: [ - { - key: "Custom-Header-Request-Level", - value: "New custom header added at the folder-3-request level", - active: true, - }, - { - key: "key", - value: "Set at folder-3-request", - active: true, - }, - ], - endpoint: "https://httpbin.org/get", - testScript: - '// Check status code is 200\npw.test("Status code is 200", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test("Successfully inherits/overrides authorization/header set at the parent collection level with new header addition", () => {\n pw.expect(pw.response.body.headers["Authorization"]).toBe("Basic dGVzdHVzZXI6dGVzdHBhc3M=")\n \n pw.expect(pw.response.body.headers["Custom-Header"]).toBe("Custom header value overriden at folder-3")\n pw.expect(pw.response.body.headers["Inherited-Header"]).toBe("Inherited header at all levels")\n pw.expect(pw.response.body.headers["Key"]).toBe("Set at folder-3-request")\n pw.expect(pw.response.body.headers["Custom-Header-Request-Level"]).toBe("New custom header added at the folder-3-request level")\n})', - preRequestScript: "", - requestVariables: [], - }, - ], - auth: { - key: "testuser", - addTo: "HEADERS", - value: "testpass", - authType: "basic", - password: "testpass", - username: "testuser", - authActive: true, - }, - headers: [ - { - key: "Custom-Header", - value: "Custom header value overriden at folder-3", - active: true, - }, - ], - }, - ], - requests: [ - { - v: "4", - auth: { - authType: "inherit", - authActive: true, - }, - body: { - body: null, - contentType: null, - }, - name: "root-collection-request", - method: "GET", - params: [], - headers: [], - endpoint: "https://httpbin.org/get", - testScript: - '// Check status code is 200\npw.test("Status code is 200", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test("Successfully inherits authorization/header set at the parent collection level", () => {\n pw.expect(pw.response.body.headers["Authorization"]).toBe("Basic dGVzdHVzZXI6dGVzdHBhc3M=")\n \n pw.expect(pw.response.body.headers["Custom-Header"]).toBe("Custom header value set at the root collection")\n pw.expect(pw.response.body.headers["Inherited-Header"]).toBe("Inherited header at all levels")\n})', - preRequestScript: "", - requestVariables: [], - }, - ], - auth: { - authType: "basic", - password: "testpass", - username: "testuser", - authActive: true, - }, - headers: [ - { - key: "Custom-Header", - value: "Custom header value set at the root collection", - active: true, - }, - { - key: "Inherited-Header", - value: "Inherited header at all levels", - active: true, - }, - ], - }; - // Collections with `data` field set to `null` at certain levels export const WORKSPACE_COLLECTIONS_WITHOUT_AUTH_HEADERS_AT_CERTAIN_LEVELS_MOCK: WorkspaceCollection = { @@ -1210,12 +538,12 @@ export const WORKSPACE_COLLECTIONS_WITHOUT_AUTH_HEADERS_AT_CERTAIN_LEVELS_MOCK: export const TRANSFORMED_COLLECTIONS_WITHOUT_AUTH_HEADERS_AT_CERTAIN_LEVELS_MOCK: HoppCollection = { - v: CollectionSchemaVersion, + v: 2, id: "clx1kxvao005m10f8luqivrf1", name: "Collection with no authorization/headers set", folders: [ { - v: CollectionSchemaVersion, + v: 2, id: "clx1kygjt005n10f8m1nkhjux", name: "folder-1", folders: [], @@ -1247,7 +575,7 @@ export const TRANSFORMED_COLLECTIONS_WITHOUT_AUTH_HEADERS_AT_CERTAIN_LEVELS_MOCK headers: [], }, { - v: CollectionSchemaVersion, + v: 2, id: "clx1kym98005o10f8qg17t9o2", name: "folder-2", folders: [], @@ -1285,7 +613,7 @@ export const TRANSFORMED_COLLECTIONS_WITHOUT_AUTH_HEADERS_AT_CERTAIN_LEVELS_MOCK ], }, { - v: CollectionSchemaVersion, + v: 2, id: "clx1l2bu6005r10f8daynohge", name: "folder-3", folders: [], @@ -1297,7 +625,7 @@ export const TRANSFORMED_COLLECTIONS_WITHOUT_AUTH_HEADERS_AT_CERTAIN_LEVELS_MOCK headers: [], }, { - v: CollectionSchemaVersion, + v: 2, id: "clx1l2eaz005s10f8loetbbeb", name: "folder-4", folders: [], diff --git a/packages/hoppscotch-cli/src/__tests__/unit/getters.spec.ts b/packages/hoppscotch-cli/src/__tests__/unit/getters.spec.ts index efdecddb23..8520ee2925 100644 --- a/packages/hoppscotch-cli/src/__tests__/unit/getters.spec.ts +++ b/packages/hoppscotch-cli/src/__tests__/unit/getters.spec.ts @@ -1,6 +1,6 @@ import axios from "axios"; import fs from "fs/promises"; -import { describe, expect, it, test, vi } from "vitest"; +import { describe, expect, test, vi } from "vitest"; import { CollectionSchemaVersion, @@ -48,11 +48,11 @@ describe("getters", () => { variables: [{ key: "PARAM", value: "parsed_param" }], }; - test("Empty list of meta-data.", () => { + test("Empty list of meta-data", () => { expect(getEffectiveFinalMetaData([], DEFAULT_ENV)).toSubsetEqualRight([]); }); - test("Non-empty active list of meta-data with unavailable ENV.", () => { + test("Non-empty active list of meta-data with unavailable ENV", () => { expect( getEffectiveFinalMetaData( [ @@ -67,7 +67,7 @@ describe("getters", () => { ).toSubsetEqualRight([{ active: true, key: "", value: "" }]); }); - test("Inactive list of meta-data.", () => { + test("Inactive list of meta-data", () => { expect( getEffectiveFinalMetaData( [{ active: false, key: "KEY", value: "<>" }], @@ -76,7 +76,7 @@ describe("getters", () => { ).toSubsetEqualRight([]); }); - test("Active list of meta-data.", () => { + test("Active list of meta-data", () => { expect( getEffectiveFinalMetaData( [{ active: true, key: "PARAM", value: "<>" }], @@ -90,247 +90,152 @@ describe("getters", () => { describe("getResourceContents", () => { describe("Network call failure", () => { - it("Promise rejects with the code `SERVER_CONNECTION_REFUSED` if the network call fails with the code `ECONNREFUSED`", () => { - const pathOrId = "valid-collection-id"; - const resourceType = "collection"; - const accessToken = "valid-access-token"; - const serverUrl = "invalid-url"; - - vi.spyOn(axios, "get").mockImplementation(() => { - return Promise.reject({ + const args = { + pathOrId: "test-collection-id-or-path", + resourceType: "collection" as const, + accessToken: "test-token", + serverUrl: "test-url", + }; + + const cases = [ + { + description: + "Promise rejects with the code `SERVER_CONNECTION_REFUSED` if the network call fails with the code `ECONNREFUSED`", + args, + axiosMock: { code: "ECONNREFUSED", - }); - }); - - expect( - getResourceContents({ - pathOrId, - accessToken, - serverUrl, - resourceType, - }) - ).rejects.toEqual({ - code: "SERVER_CONNECTION_REFUSED", - data: serverUrl, - }); - }); - - it("Promise rejects with the code `INVALID_SERVER_URL` if the network call fails with the code `ERR_INVALID_URL`", () => { - const pathOrId = "valid-collection-id"; - const resourceType = "collection"; - const accessToken = "valid-access-token"; - const serverUrl = "htp://example.com"; - - vi.spyOn(axios, "get").mockImplementation(() => { - return Promise.reject({ + }, + expected: { + code: "SERVER_CONNECTION_REFUSED", + data: args.serverUrl, + }, + }, + { + description: + "Promise rejects with the code `INVALID_SERVER_URL` if the network call fails with the code `ERR_INVALID_URL`", + args, + axiosMock: { code: "ERR_INVALID_URL", - }); - }); - - expect( - getResourceContents({ - pathOrId, - accessToken, - serverUrl, - resourceType, - }) - ).rejects.toEqual({ - code: "INVALID_SERVER_URL", - data: serverUrl, - }); - }); - - it("Promise rejects with the code `INVALID_SERVER_URL` if the network call succeeds and the received response content type is not `application/json`", () => { - const pathOrId = "valid-collection-id"; - const resourceType = "collection"; - const accessToken = "valid-access-token"; - const serverUrl = "https://stage-hoppscotch.io"; - - vi.spyOn(axios, "get").mockImplementation(() => { - return Promise.reject({ + }, + expected: { + code: "INVALID_SERVER_URL", + data: args.serverUrl, + }, + }, + { + description: + "Promise rejects with the code `INVALID_SERVER_URL` if the network call succeeds and the received response content type is not `application/json`", + args, + axiosMock: { message: "INVALID_CONTENT_TYPE", - }); - }); - - expect( - getResourceContents({ - pathOrId, - accessToken, - serverUrl, - resourceType, - }) - ).rejects.toEqual({ - code: "INVALID_SERVER_URL", - data: serverUrl, - }); - }); - - it("Promise rejects with the code `INVALID_SERVER_URL` if the network call fails with the code `ENOTFOUND`", () => { - const pathOrId = "valid-collection-id"; - const resourceType = "collection"; - const accessToken = "valid-access-token"; - const serverUrl = "https://stage-hoppscotch.io"; - - vi.spyOn(axios, "get").mockImplementation(() => { - return Promise.reject({ + }, + expected: { + code: "INVALID_SERVER_URL", + data: args.serverUrl, + }, + }, + { + description: + "Promise rejects with the code `INVALID_SERVER_URL` if the network call fails with the code `ENOTFOUND`", + args, + axiosMock: { code: "ENOTFOUND", - }); - }); - - expect( - getResourceContents({ - pathOrId, - accessToken, - serverUrl, - resourceType, - }) - ).rejects.toEqual({ - code: "INVALID_SERVER_URL", - data: serverUrl, - }); - }); - - it("Promise rejects with the code `INVALID_SERVER_URL` if the network call yields a response with status code of `404`", () => { - const pathOrId = "valid-collection-id"; - const resourceType = "collection"; - const accessToken = "valid-access-token"; - const serverUrl = "https://stage-hoppscotch.io"; - - vi.spyOn(axios, "get").mockImplementation(() => { - return Promise.reject({ + }, + expected: { + code: "INVALID_SERVER_URL", + data: args.serverUrl, + }, + }, + { + description: + "Promise rejects with the code `INVALID_SERVER_URL` if the network call returns a response with a status code of `404`", + args, + axiosMock: { response: { status: 404, }, - }); - }); - - expect( - getResourceContents({ - pathOrId, - accessToken, - serverUrl, - resourceType, - }) - ).rejects.toEqual({ - code: "INVALID_SERVER_URL", - data: serverUrl, - }); - }); - - it("Promise rejects with the code `TOKEN_EXPIRED` if the network call fails with the same reason", () => { - const pathOrId = "valid-collection-id"; - const resourceType = "collection"; - const accessToken = "expired-access-token"; - const serverUrl = "https://stage-hoppscotch.io/backend"; - - vi.spyOn(axios, "get").mockImplementation(() => { - return Promise.reject({ + }, + expected: { + code: "INVALID_SERVER_URL", + data: args.serverUrl, + }, + }, + { + description: + "Promise rejects with the code `TOKEN_EXPIRED` if the network call fails for the same reason", + args, + axiosMock: { response: { data: { reason: "TOKEN_EXPIRED", }, }, - }); - }); - - expect( - getResourceContents({ - pathOrId, - accessToken, - serverUrl, - resourceType, - }) - ).rejects.toEqual({ - code: "TOKEN_EXPIRED", - data: accessToken, - }); - }); - - it("Promise rejects with the code `TOKEN_INVALID` if the network call fails with the same reason", () => { - const pathOrId = "valid-collection-id"; - const resourceType = "collection"; - const accessToken = "invalid-access-token"; - const serverUrl = "https://stage-hoppscotch.io/backend"; - - vi.spyOn(axios, "get").mockImplementation(() => { - return Promise.reject({ + }, + expected: { + code: "TOKEN_EXPIRED", + data: args.accessToken, + }, + }, + { + description: + "Promise rejects with the code `TOKEN_INVALID` if the network call fails for the same reason", + args, + axiosMock: { response: { data: { reason: "TOKEN_INVALID", }, }, - }); - }); - - expect( - getResourceContents({ - pathOrId, - accessToken, - serverUrl, - resourceType, - }) - ).rejects.toEqual({ - code: "TOKEN_INVALID", - data: accessToken, - }); - }); - - it("Promise rejects with the code `INVALID_ID` if the network call fails with the same reason for a supplied collection ID", () => { - const pathOrId = "invalid-collection-id"; - const resourceType = "collection"; - const accessToken = "valid-access-token"; - const serverUrl = "https://stage-hoppscotch.io/backend"; - - vi.spyOn(axios, "get").mockImplementation(() => { - return Promise.reject({ + }, + expected: { + code: "TOKEN_INVALID", + data: args.accessToken, + }, + }, + { + description: + "Promise rejects with the code `INVALID_ID` if the network call fails for the same reason when the supplied collection ID or path is invalid", + args, + axiosMock: { response: { data: { reason: "INVALID_ID", }, }, - }); - }); - - expect( - getResourceContents({ - pathOrId, - accessToken, - serverUrl, - resourceType, - }) - ).rejects.toEqual({ - code: "INVALID_ID", - data: pathOrId, - }); - }); - - it("Promise rejects with the code `INVALID_ID` if the network call fails with the same reason for a supplied environment ID", () => { - const pathOrId = "invalid-environment-id"; - const resourceType = "environment"; - const accessToken = "valid-access-token"; - const serverUrl = "https://stage-hoppscotch.io/backend"; - - vi.spyOn(axios, "get").mockImplementation(() => { - return Promise.reject({ + }, + expected: { + code: "INVALID_ID", + data: args.pathOrId, + }, + }, + { + description: + "Promise rejects with the code `INVALID_ID` if the network call fails for the same reason when the supplied environment ID or path is invalid", + args: { + ...args, + pathOrId: "test-environment-id-or-path", + resourceType: "environment" as const, + }, + axiosMock: { response: { data: { reason: "INVALID_ID", }, }, - }); - }); + }, + expected: { + code: "INVALID_ID", + data: "test-environment-id-or-path", + }, + }, + ]; - expect( - getResourceContents({ - pathOrId, - accessToken, - serverUrl, - resourceType, - }) - ).rejects.toEqual({ - code: "INVALID_ID", - data: pathOrId, - }); + test.each(cases)("$description", ({ args, axiosMock, expected }) => { + vi.spyOn(axios, "get").mockImplementation(() => + Promise.reject(axiosMock) + ); + + expect(getResourceContents(args)).rejects.toEqual(expected); }); }); diff --git a/packages/hoppscotch-cli/src/__tests__/unit/workspace-access.spec.ts b/packages/hoppscotch-cli/src/__tests__/unit/workspace-access.spec.ts index cd2a6e5d1f..409ed4c105 100644 --- a/packages/hoppscotch-cli/src/__tests__/unit/workspace-access.spec.ts +++ b/packages/hoppscotch-cli/src/__tests__/unit/workspace-access.spec.ts @@ -5,16 +5,17 @@ import { transformWorkspaceEnvironment, } from "../../utils/workspace-access"; import { - TRANFORMED_DEEPLY_NESTED_COLLECTIONS_WITH_AUTH_HEADERS_MOCK, TRANSFORMED_COLLECTIONS_WITHOUT_AUTH_HEADERS_AT_CERTAIN_LEVELS_MOCK, + TRANSFORMED_DEEPLY_NESTED_COLLECTIONS_WITH_AUTH_HEADERS_MOCK, TRANSFORMED_ENVIRONMENT_MOCK, - TRANSFORMED_MULTIPLE_CHILD_COLLECTIONS_WITH_AUTH_HEADERS_MOCK, WORKSPACE_COLLECTIONS_WITHOUT_AUTH_HEADERS_AT_CERTAIN_LEVELS_MOCK, WORKSPACE_DEEPLY_NESTED_COLLECTIONS_WITH_AUTH_HEADERS_MOCK, WORKSPACE_ENVIRONMENT_MOCK, WORKSPACE_MULTIPLE_CHILD_COLLECTIONS_WITH_AUTH_HEADERS_MOCK, } from "./fixtures/workspace-access.mock"; +import TRANSFORMED_MULTIPLE_CHILD_COLLECTIONS_WITH_AUTH_HEADERS_MOCK from "../e2e/fixtures/collections/multiple-child-collections-auth-headers-coll.json"; + describe("workspace-access", () => { describe("transformWorkspaceCollection", () => { test("Successfully transforms collection data with deeply nested collections and authorization/headers set at each level to the `HoppCollection` format", () => { @@ -22,7 +23,7 @@ describe("workspace-access", () => { transformWorkspaceCollection( WORKSPACE_DEEPLY_NESTED_COLLECTIONS_WITH_AUTH_HEADERS_MOCK ) - ).toEqual(TRANFORMED_DEEPLY_NESTED_COLLECTIONS_WITH_AUTH_HEADERS_MOCK); + ).toEqual(TRANSFORMED_DEEPLY_NESTED_COLLECTIONS_WITH_AUTH_HEADERS_MOCK); }); test("Successfully transforms collection data with multiple child collections and authorization/headers set at each level to the `HoppCollection` format", () => { diff --git a/packages/hoppscotch-cli/src/utils/getters.ts b/packages/hoppscotch-cli/src/utils/getters.ts index e53f29cc9c..7552b4fff0 100644 --- a/packages/hoppscotch-cli/src/utils/getters.ts +++ b/packages/hoppscotch-cli/src/utils/getters.ts @@ -193,9 +193,8 @@ export const getResourceContents = async ({ : transformWorkspaceEnvironment(data as WorkspaceEnvironment); } catch (err) { const axiosErr = err as AxiosError<{ - reason?: any; + reason?: "TOKEN_EXPIRED" | "TOKEN_INVALID" | "INVALID_ID"; message: string; - error: string; statusCode: number; }>;