Browse Source

fix: show file chip for the selected file in binary body (#4562)

Co-authored-by: jamesgeorge007 <25279263+jamesgeorge007@users.noreply.github.com>
Akash K 3 months ago
parent
commit
9cc1e47b39

+ 704 - 2
packages/hoppscotch-cli/src/__tests__/unit/fixtures/workspace-access.mock.ts

@@ -178,6 +178,7 @@ export const TRANSFORMED_DEEPLY_NESTED_COLLECTIONS_WITH_AUTH_HEADERS_MOCK: HoppC
                   key: "X-Test-Header",
                   value: "Overriden at FolderB",
                   active: true,
+                  description: "",
                 },
               ],
             },
@@ -475,8 +476,707 @@ export const WORKSPACE_MULTIPLE_CHILD_COLLECTIONS_WITH_AUTH_HEADERS_MOCK: Worksp
           collectionID: "clx1f86hv000010f8szcfya0t",
           teamID: "clws3hg58000011o8h07glsb1",
           title: "root-collection-request",
-          request:
-            '{"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":[]}',
+          request: `{"v":"${RESTReqSchemaVersion}","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":[],"responses":{}}`,
+        },
+      ],
+    },
+  ];
+
+export const TRANSFORMED_MULTIPLE_CHILD_COLLECTIONS_WITH_AUTH_HEADERS_MOCK: HoppCollection[] =
+  [
+    {
+      v: 5,
+      id: "clx1f86hv000010f8szcfya0t",
+      name: "Multiple child collections with authorization & headers set at each level",
+      folders: [
+        {
+          v: 5,
+          id: "clx1fjgah000110f8a5bs68gd",
+          name: "folder-1",
+          folders: [
+            {
+              v: 5,
+              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,
+                  description: "",
+                },
+              ],
+            },
+            {
+              v: 5,
+              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,
+                  description: "",
+                },
+                {
+                  key: "key",
+                  value: "Set at folder-12",
+                  active: true,
+                  description: "",
+                },
+              ],
+            },
+            {
+              v: 5,
+              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,
+                  description: "",
+                },
+                {
+                  key: "key",
+                  value: "Set at folder-13",
+                  active: true,
+                  description: "",
+                },
+              ],
+            },
+          ],
+          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,
+              description: "",
+            },
+          ],
+        },
+        {
+          v: 5,
+          id: "clx1fjk9o000210f8j0573pls",
+          name: "folder-2",
+          folders: [
+            {
+              v: 5,
+              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,
+                  description: "",
+                },
+              ],
+            },
+            {
+              v: 5,
+              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,
+                  description: "",
+                },
+                {
+                  key: "key",
+                  value: "Set at folder-22",
+                  active: true,
+                  description: "",
+                },
+              ],
+            },
+            {
+              v: 5,
+              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,
+                  description: "",
+                },
+                {
+                  key: "key",
+                  value: "Set at folder-23",
+                  active: true,
+                  description: "",
+                },
+              ],
+            },
+          ],
+          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,
+              description: "",
+            },
+          ],
+        },
+        {
+          v: 5,
+          id: "clx1fjmlq000310f86o4d3w2o",
+          name: "folder-3",
+          folders: [
+            {
+              v: 5,
+              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,
+                  description: "",
+                },
+              ],
+            },
+            {
+              v: 5,
+              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,
+                  description: "",
+                },
+                {
+                  key: "key",
+                  value: "Set at folder-32",
+                  active: true,
+                  description: "",
+                },
+              ],
+            },
+            {
+              v: 5,
+              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,
+                  description: "",
+                },
+                {
+                  key: "key",
+                  value: "Set at folder-33",
+                  active: true,
+                  description: "",
+                },
+              ],
+            },
+          ],
+          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,
+              description: "",
+            },
+          ],
+        },
+      ],
+      requests: [
+        {
+          v: RESTReqSchemaVersion,
+          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: [],
+          responses: {},
+        },
+      ],
+      auth: {
+        authType: "basic",
+        password: "testpass",
+        username: "testuser",
+        authActive: true,
+      },
+      headers: [
+        {
+          key: "Custom-Header",
+          value: "Custom header value set at the root collection",
+          active: true,
+          description: "",
+        },
+        {
+          key: "Inherited-Header",
+          value: "Inherited header at all levels",
+          active: true,
+          description: "",
         },
       ],
     },
@@ -620,6 +1320,7 @@ export const TRANSFORMED_COLLECTIONS_WITHOUT_AUTH_HEADERS_AT_CERTAIN_LEVELS_MOCK
               key: "Custom-Header",
               value: "Set at folder-2",
               active: true,
+              description: "",
             },
           ],
         },
@@ -650,6 +1351,7 @@ export const TRANSFORMED_COLLECTIONS_WITHOUT_AUTH_HEADERS_AT_CERTAIN_LEVELS_MOCK
               key: "Custom-Header",
               value: "Set at folder-4",
               active: true,
+              description: "",
             },
           ],
         },

+ 2 - 32
packages/hoppscotch-cli/src/__tests__/unit/workspace-access.spec.ts

@@ -1,7 +1,4 @@
-import { HoppCollection } from "@hoppscotch/data";
-import { entityReference } from "verzod";
 import { describe, expect, test } from "vitest";
-import { z } from "zod";
 
 import {
   transformWorkspaceCollections,
@@ -11,36 +8,13 @@ import {
   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";
-
-// Helper function to validate against `HoppCollection` schema and apply relevant migrations
-const migrateCollections = (collections: unknown[]): HoppCollection[] => {
-  const collectionSchemaParsedResult = z
-    .array(entityReference(HoppCollection))
-    .safeParse(collections);
-
-  if (!collectionSchemaParsedResult.success) {
-    throw new Error(
-      `Incoming collections failed schema validation: ${JSON.stringify(collections, null, 2)}`
-    );
-  }
-
-  return collectionSchemaParsedResult.data.map(
-    ({ _ref_id, folders, ...rest }) => {
-      return {
-        ...rest,
-        folders: migrateCollections(folders),
-      };
-    }
-  );
-};
-
 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", () => {
@@ -52,15 +26,11 @@ describe("workspace-access", () => {
     });
 
     test("Successfully transforms collection data with multiple child collections and authorization/headers set at each level to the `HoppCollection` format", () => {
-      const migratedCollections = migrateCollections([
-        TRANSFORMED_MULTIPLE_CHILD_COLLECTIONS_WITH_AUTH_HEADERS_MOCK,
-      ]);
-
       expect(
         transformWorkspaceCollections(
           WORKSPACE_MULTIPLE_CHILD_COLLECTIONS_WITH_AUTH_HEADERS_MOCK
         )
-      ).toEqual(migratedCollections);
+      ).toEqual(TRANSFORMED_MULTIPLE_CHILD_COLLECTIONS_WITH_AUTH_HEADERS_MOCK);
     });
 
     test("Adds the default value for `auth` & `header` fields while transforming collections without authorization/headers set at certain levels", () => {

+ 22 - 2
packages/hoppscotch-cli/src/options/test/env.ts

@@ -1,4 +1,4 @@
-import { Environment } from "@hoppscotch/data";
+import { Environment, NonSecretEnvironment } from "@hoppscotch/data";
 import { entityReference } from "verzod";
 import { z } from "zod";
 
@@ -63,7 +63,27 @@ export async function parseEnvsData(options: TestCmdEnvironmentOptions) {
       envPairs.push({ key, value, secret: false });
     }
   } else if (HoppEnvExportObjectResult.type === "ok") {
-    envPairs.push(...HoppEnvExportObjectResult.value.variables);
+    // Original environment variables from the supplied export file
+    const originalEnvVariables = (contents as NonSecretEnvironment).variables;
+
+    // Above environment variables conforming to the latest schema
+    // `value` fields if specified will be omitted for secret environment variables
+    const migratedEnvVariables = HoppEnvExportObjectResult.value.variables;
+
+    // The values supplied for secret environment variables have to be considered in the CLI
+    // For each secret environment variable, include the value in case supplied
+    const resolvedEnvVariables = migratedEnvVariables.map((variable, idx) => {
+      if (variable.secret && originalEnvVariables[idx].value) {
+        return {
+          ...variable,
+          value: originalEnvVariables[idx].value,
+        };
+      }
+
+      return variable;
+    });
+
+    envPairs.push(...resolvedEnvVariables);
   }
 
   return <HoppEnvs>{ global: [], selected: envPairs };

+ 16 - 2
packages/hoppscotch-cli/src/utils/workspace-access.ts

@@ -3,6 +3,8 @@ import {
   Environment,
   EnvironmentSchemaVersion,
   HoppCollection,
+  HoppRESTAuth,
+  HoppRESTHeaders,
   HoppRESTRequest,
 } from "@hoppscotch/data";
 
@@ -34,6 +36,7 @@ interface WorkspaceRequest {
 
 /**
  * Transforms the incoming list of workspace requests by applying `JSON.parse` to the `request` field.
+ * It includes the `v` field indicating the schema version, but migration is handled already at the `parseCollectionData()` helper function.
  *
  * @param {WorkspaceRequest[]} requests - An array of workspace request objects to be transformed.
  * @returns {HoppRESTRequest[]} The transformed array of requests conforming to the `HoppRESTRequest` type.
@@ -65,6 +68,8 @@ export const transformWorkspaceEnvironment = (
     return variable;
   });
 
+  // The response doesn't include a way to infer the schema version, so it's set to the latest version
+  // Any relevant migrations have to be accounted here
   return {
     v: EnvironmentSchemaVersion,
     variables: transformedEnvVars,
@@ -84,10 +89,19 @@ export const transformWorkspaceCollections = (
   return collections.map((collection) => {
     const { id, title, data, requests, folders } = collection;
 
-    const parsedData = data ? JSON.parse(data) : {};
+    const parsedData: { auth?: HoppRESTAuth; headers?: HoppRESTHeaders } = data
+      ? JSON.parse(data)
+      : {};
+
     const { auth = { authType: "inherit", authActive: true }, headers = [] } =
       parsedData;
 
+    const migratedHeaders = headers.map((header) =>
+      header.description ? header : { ...header, description: "" }
+    );
+
+    // The response doesn't include a way to infer the schema version, so it's set to the latest version
+    // Any relevant migrations have to be accounted here
     return {
       v: CollectionSchemaVersion,
       id,
@@ -95,7 +109,7 @@ export const transformWorkspaceCollections = (
       folders: transformWorkspaceCollections(folders),
       requests: transformWorkspaceRequests(requests),
       auth,
-      headers,
+      headers: migratedHeaders,
     };
   });
 };

+ 1 - 1
packages/hoppscotch-common/package.json

@@ -94,7 +94,7 @@
     "url": "0.11.4",
     "util": "0.12.5",
     "uuid": "10.0.0",
-    "verzod": "0.2.2",
+    "verzod": "0.2.3",
     "vue": "3.5.12",
     "vue-i18n": "10.0.4",
     "vue-pdf-embed": "2.1.0",

+ 6 - 2
packages/hoppscotch-common/src/components/http/BodyBinary.vue

@@ -56,7 +56,11 @@ const handleFileChange = (e: Event) => {
 }
 </script>
 <template>
-  <span>
+  <div class="flex items-center px-4 py-2">
+    <HoppSmartFileChip v-if="props.modelValue.body">{{
+      props.modelValue.body.name
+    }}</HoppSmartFileChip>
+
     <label :for="`attachment-binary-body`" class="p-0">
       <input
         :id="`attachment-binary-body`"
@@ -66,5 +70,5 @@ const handleFileChange = (e: Event) => {
         @change="handleFileChange"
       />
     </label>
-  </span>
+  </div>
 </template>

+ 4 - 0
packages/hoppscotch-common/src/services/inspection/inspectors/interceptors.inspector.ts

@@ -33,6 +33,10 @@ export class InterceptorsInspectorService extends Service implements Inspector {
     req: Readonly<Ref<HoppRESTRequest | HoppRESTResponseOriginalRequest>>
   ) {
     return computed((): InspectorResult[] => {
+      if (!req.value) {
+        return []
+      }
+
       const isBinaryBody =
         req.value.body.contentType === "application/octet-stream"
 

+ 17 - 8
packages/hoppscotch-common/src/services/persistence/__tests__/__mocks__/index.ts

@@ -27,25 +27,31 @@ export const REST_COLLECTIONS_MOCK: HoppCollection[] = [
   {
     v: 5,
     name: "Echo",
-    folders: [],
     requests: [
       {
         v: RESTReqSchemaVersion,
-        endpoint: "https://echo.hoppscotch.io",
         name: "Echo test",
+        method: "GET",
+        endpoint: "https://echo.hoppscotch.io",
         params: [],
         headers: [],
-        method: "GET",
-        auth: { authType: "none", authActive: true },
         preRequestScript: "",
         testScript: "",
-        body: { contentType: null, body: null },
+        auth: {
+          authType: "none",
+          authActive: true,
+        },
+        body: {
+          contentType: null,
+          body: null,
+        },
         requestVariables: [],
         responses: {},
       },
     ],
     auth: { authType: "none", authActive: true },
     headers: [],
+    folders: [],
   },
 ]
 
@@ -53,20 +59,23 @@ export const GQL_COLLECTIONS_MOCK: HoppCollection[] = [
   {
     v: 5,
     name: "Echo",
-    folders: [],
     requests: [
       {
         v: 7,
         name: "Echo test",
         url: "https://echo.hoppscotch.io/graphql",
         headers: [],
-        variables: '{\n  "id": "1"\n}',
         query: "query Request { url }",
-        auth: { authType: "none", authActive: true },
+        variables: '{\n  "id": "1"\n}',
+        auth: {
+          authType: "none",
+          authActive: true,
+        },
       },
     ],
     auth: { authType: "none", authActive: true },
     headers: [],
+    folders: [],
   },
 ]
 

+ 1 - 1
packages/hoppscotch-data/package.json

@@ -46,7 +46,7 @@
     "lodash": "4.17.21",
     "parser-ts": "0.7.0",
     "uuid": "10.0.0",
-    "verzod": "0.2.2",
+    "verzod": "0.2.3",
     "zod": "3.23.8"
   }
 }

+ 1 - 1
packages/hoppscotch-selfhost-desktop/package.json

@@ -36,7 +36,7 @@
     "tauri": "link:@tauri-apps/api/tauri",
     "tauri-plugin-store-api": "0.0.0",
     "util": "0.12.5",
-    "verzod": "0.2.2",
+    "verzod": "0.2.3",
     "vue": "3.3.9",
     "workbox-window": "6.6.0",
     "zod": "3.22.4"

Some files were not shown because too many files changed in this diff