diff --git a/packages/hoppscotch-common/src/components/http/TestResult.vue b/packages/hoppscotch-common/src/components/http/TestResult.vue
index 24b491bc3..a21b1b287 100644
--- a/packages/hoppscotch-common/src/components/http/TestResult.vue
+++ b/packages/hoppscotch-common/src/components/http/TestResult.vue
@@ -79,6 +79,13 @@
status="updations"
global
/>
+
?",
- "set": "fn(value: ?)"
+ "set": "fn(value: ?)",
+ "unset": "fn(value: ?)"
},
"Promise.prototype": {
"catch": {
diff --git a/packages/hoppscotch-common/src/helpers/terndoc/pw-pre.json b/packages/hoppscotch-common/src/helpers/terndoc/pw-pre.json
index 8a70a6c35..2a34c1834 100644
--- a/packages/hoppscotch-common/src/helpers/terndoc/pw-pre.json
+++ b/packages/hoppscotch-common/src/helpers/terndoc/pw-pre.json
@@ -3,6 +3,7 @@
"pw": {
"env": {
"set": "fn(key: string, value: string)",
+ "unset": "fn(key: string)",
"get": "fn(key: string) -> string",
"getResolve": "fn(key: string) -> string",
"resolve": "fn(value: string) -> string"
diff --git a/packages/hoppscotch-common/src/helpers/terndoc/pw-test.json b/packages/hoppscotch-common/src/helpers/terndoc/pw-test.json
index 21137a65a..3b5883555 100644
--- a/packages/hoppscotch-common/src/helpers/terndoc/pw-test.json
+++ b/packages/hoppscotch-common/src/helpers/terndoc/pw-test.json
@@ -22,6 +22,7 @@
},
"env": {
"set": "fn(key: string, value: string)",
+ "unset": "fn(key: string)",
"get": "fn(key: string) -> string",
"getResolve": "fn(key: string) -> string",
"resolve": "fn(value: string) -> string"
diff --git a/packages/hoppscotch-js-sandbox/src/__tests__/preRequest.spec.ts b/packages/hoppscotch-js-sandbox/src/__tests__/preRequest.spec.ts
index d3c3cc9cd..cf7ce824a 100644
--- a/packages/hoppscotch-js-sandbox/src/__tests__/preRequest.spec.ts
+++ b/packages/hoppscotch-js-sandbox/src/__tests__/preRequest.spec.ts
@@ -1,8 +1,9 @@
-import { runPreRequestScript } from "~/pre-request/node-vm"
import "@relmify/jest-fp-ts"
-describe("execPreRequestScript", () => {
- test("returns the updated envirionment properly", () => {
+import { runPreRequestScript } from "~/pre-request/node-vm"
+
+describe("runPreRequestScript", () => {
+ test("returns the updated environment properly", () => {
return expect(
runPreRequestScript(
`
diff --git a/packages/hoppscotch-js-sandbox/src/__tests__/testing/envs/unset.spec.ts b/packages/hoppscotch-js-sandbox/src/__tests__/testing/envs/unset.spec.ts
new file mode 100644
index 000000000..aeda66d71
--- /dev/null
+++ b/packages/hoppscotch-js-sandbox/src/__tests__/testing/envs/unset.spec.ts
@@ -0,0 +1,243 @@
+import * as TE from "fp-ts/TaskEither"
+import { pipe } from "fp-ts/function"
+
+import { runTestScript } from "~/test-runner/node-vm"
+import { TestResponse, TestResult } from "~/types"
+
+const fakeResponse: TestResponse = {
+ status: 200,
+ body: "hoi",
+ headers: [],
+}
+
+const func = (script: string, envs: TestResult["envs"]) =>
+ pipe(
+ runTestScript(script, envs, fakeResponse),
+ TE.map((x) => x.envs)
+ )
+
+const funcTest = (script: string, envs: TestResult["envs"]) =>
+ pipe(
+ runTestScript(script, envs, fakeResponse),
+ TE.map((x) => x.tests)
+ )
+
+describe("pw.env.unset", () => {
+ test("removes the variable set in selected environment correctly", () => {
+ return expect(
+ func(
+ `
+ pw.env.unset("baseUrl")
+ `,
+ {
+ global: [],
+ selected: [
+ {
+ key: "baseUrl",
+ value: "https://echo.hoppscotch.io",
+ },
+ ],
+ }
+ )()
+ ).resolves.toEqualRight(
+ expect.objectContaining({
+ selected: [],
+ })
+ )
+ })
+
+ test("removes the variable set in global environment correctly", () => {
+ return expect(
+ func(
+ `
+ pw.env.unset("baseUrl")
+ `,
+ {
+ global: [
+ {
+ key: "baseUrl",
+ value: "https://echo.hoppscotch.io",
+ },
+ ],
+ selected: [],
+ }
+ )()
+ ).resolves.toEqualRight(
+ expect.objectContaining({
+ global: [],
+ })
+ )
+ })
+
+ test("removes the variable from selected environment if the entry is present in both selected and global environments", () => {
+ return expect(
+ func(
+ `
+ pw.env.unset("baseUrl")
+ `,
+ {
+ global: [
+ {
+ key: "baseUrl",
+ value: "https://httpbin.org",
+ },
+ ],
+ selected: [
+ {
+ key: "baseUrl",
+ value: "https://echo.hoppscotch.io",
+ },
+ ],
+ }
+ )()
+ ).resolves.toEqualRight(
+ expect.objectContaining({
+ global: [
+ {
+ key: "baseUrl",
+ value: "https://httpbin.org",
+ },
+ ],
+ selected: [],
+ })
+ )
+ })
+
+ test("removes the initial occurrence of an entry if duplicate entries exist in the selected environment", () => {
+ return expect(
+ func(
+ `
+ pw.env.unset("baseUrl")
+ `,
+ {
+ global: [
+ {
+ key: "baseUrl",
+ value: "https://echo.hoppscotch.io",
+ },
+ ],
+ selected: [
+ {
+ key: "baseUrl",
+ value: "https://httpbin.org",
+ },
+ {
+ key: "baseUrl",
+ value: "https://echo.hoppscotch.io",
+ },
+ ],
+ }
+ )()
+ ).resolves.toEqualRight(
+ expect.objectContaining({
+ global: [
+ {
+ key: "baseUrl",
+ value: "https://echo.hoppscotch.io",
+ },
+ ],
+ selected: [
+ {
+ key: "baseUrl",
+ value: "https://echo.hoppscotch.io",
+ },
+ ],
+ })
+ )
+ })
+
+ test("removes the initial occurrence of an entry if duplicate entries exist in the global environment", () => {
+ return expect(
+ func(
+ `
+ pw.env.unset("baseUrl")
+ `,
+ {
+ global: [
+ {
+ key: "baseUrl",
+ value: "https://httpbin.org/",
+ },
+ {
+ key: "baseUrl",
+ value: "https://echo.hoppscotch.io",
+ },
+ ],
+ selected: [],
+ }
+ )()
+ ).resolves.toEqualRight(
+ expect.objectContaining({
+ global: [
+ {
+ key: "baseUrl",
+ value: "https://echo.hoppscotch.io",
+ },
+ ],
+ selected: [],
+ })
+ )
+ })
+
+ test("no change if attempting to delete non-existent keys", () => {
+ return expect(
+ func(
+ `
+ pw.env.unset("baseUrl")
+ `,
+ {
+ global: [],
+ selected: [],
+ }
+ )()
+ ).resolves.toEqualRight(
+ expect.objectContaining({
+ global: [],
+ selected: [],
+ })
+ )
+ })
+
+ test("keys should be a string", () => {
+ return expect(
+ func(
+ `
+ pw.env.unset(5)
+ `,
+ {
+ global: [],
+ selected: [],
+ }
+ )()
+ ).resolves.toBeLeft()
+ })
+
+ test("set environment values are reflected in the script execution", () => {
+ return expect(
+ funcTest(
+ `
+ pw.env.unset("baseUrl")
+ pw.expect(pw.env.get("baseUrl")).toBe(undefined)
+ `,
+ {
+ global: [],
+ selected: [
+ {
+ key: "baseUrl",
+ value: "https://echo.hoppscotch.io",
+ },
+ ],
+ }
+ )()
+ ).resolves.toEqualRight([
+ expect.objectContaining({
+ expectResults: [
+ {
+ status: "pass",
+ message: "Expected 'undefined' to be 'undefined'",
+ },
+ ],
+ }),
+ ])
+ })
+})
diff --git a/packages/hoppscotch-js-sandbox/src/__tests__/testing/test-runner.spec.ts b/packages/hoppscotch-js-sandbox/src/__tests__/testing/test-runner.spec.ts
index 234ab73e4..214ee7d6d 100644
--- a/packages/hoppscotch-js-sandbox/src/__tests__/testing/test-runner.spec.ts
+++ b/packages/hoppscotch-js-sandbox/src/__tests__/testing/test-runner.spec.ts
@@ -16,8 +16,8 @@ const func = (script: string, res: TestResponse) =>
TE.map((x) => x.tests)
)
-describe("execTestScript function behavior", () => {
- test("returns a resolved promise for a valid test scripts with all green", () => {
+describe("runTestScript", () => {
+ test("returns a resolved promise for a valid test script with all green", () => {
return expect(
func(
`
diff --git a/packages/hoppscotch-js-sandbox/src/utils.ts b/packages/hoppscotch-js-sandbox/src/utils.ts
index 84dc59ff1..f7920ff88 100644
--- a/packages/hoppscotch-js-sandbox/src/utils.ts
+++ b/packages/hoppscotch-js-sandbox/src/utils.ts
@@ -18,6 +18,63 @@ const getEnv = (envName: string, envs: TestResult["envs"]) => {
)
}
+const findEnvIndex = (
+ envName: string,
+ envList: SelectedEnvItem[] | GlobalEnvItem[]
+): number => {
+ return envList.findIndex(
+ (envItem: SelectedEnvItem) => envItem.key === envName
+ )
+}
+
+const setEnv = (
+ envName: string,
+ envValue: string,
+ envs: TestResult["envs"]
+): TestResult["envs"] => {
+ const { global, selected } = envs
+
+ const indexInSelected = findEnvIndex(envName, selected)
+ const indexInGlobal = findEnvIndex(envName, global)
+
+ if (indexInSelected >= 0) {
+ selected[indexInSelected].value = envValue
+ } else if (indexInGlobal >= 0) {
+ global[indexInGlobal].value = envValue
+ } else {
+ selected.push({
+ key: envName,
+ value: envValue,
+ })
+ }
+
+ return {
+ global,
+ selected,
+ }
+}
+
+const unsetEnv = (
+ envName: string,
+ envs: TestResult["envs"]
+): TestResult["envs"] => {
+ const { global, selected } = envs
+
+ const indexInSelected = findEnvIndex(envName, selected)
+ const indexInGlobal = findEnvIndex(envName, global)
+
+ if (indexInSelected >= 0) {
+ selected.splice(indexInSelected, 1)
+ } else if (indexInGlobal >= 0) {
+ global.splice(indexInGlobal, 1)
+ }
+
+ return {
+ global,
+ selected,
+ }
+}
+
// Compiles shared scripting API methods for use in both pre and post request scripts
const getSharedMethods = (envs: TestResult["envs"]) => {
let updatedEnvs = envs
@@ -79,6 +136,16 @@ const getSharedMethods = (envs: TestResult["envs"]) => {
return undefined
}
+ const envUnsetFn = (key: any) => {
+ if (typeof key !== "string") {
+ throw new Error("Expected key to be a string")
+ }
+
+ updatedEnvs = unsetEnv(key, updatedEnvs)
+
+ return undefined
+ }
+
const envResolveFn = (value: any) => {
if (typeof value !== "string") {
throw new Error("Expected value to be a string")
@@ -101,6 +168,7 @@ const getSharedMethods = (envs: TestResult["envs"]) => {
get: envGetFn,
getResolve: envGetResolveFn,
set: envSetFn,
+ unset: envUnsetFn,
resolve: envResolveFn,
},
},
@@ -108,51 +176,6 @@ const getSharedMethods = (envs: TestResult["envs"]) => {
}
}
-const setEnv = (
- envName: string,
- envValue: string,
- envs: TestResult["envs"]
-): TestResult["envs"] => {
- const { global, selected } = envs
-
- const indexInSelected = selected.findIndex(
- (x: SelectedEnvItem) => x.key === envName
- )
-
- // Found the match in selected
- if (indexInSelected >= 0) {
- selected[indexInSelected].value = envValue
-
- return {
- global,
- selected,
- }
- }
-
- const indexInGlobal = global.findIndex((x: GlobalEnvItem) => x.key == envName)
-
- // Found a match in globals
- if (indexInGlobal >= 0) {
- global[indexInGlobal].value = envValue
-
- return {
- global,
- selected,
- }
- }
-
- // Didn't find in both places, create a new variable in selected
- selected.push({
- key: envName,
- value: envValue,
- })
-
- return {
- global,
- selected,
- }
-}
-
export function preventCyclicObjects(
obj: Record
): E.Left | E.Right> {