Browse Source

chore: more tests + bug fixs

amk-dev 8 months ago
parent
commit
dce0f6f2ef

+ 43 - 0
packages/hoppscotch-common/src/helpers/backend/helpers.ts

@@ -12,9 +12,11 @@ import { TeamRequest } from "../teams/TeamRequest"
 import { GQLError, runGQLQuery } from "./GQLClient"
 import {
   ExportAsJsonDocument,
+  GetCollectionChildrenDocument,
   GetCollectionChildrenIDsDocument,
   GetCollectionRequestsDocument,
   GetCollectionTitleAndDataDocument,
+  RootCollectionsOfTeamDocument,
 } from "./graphql"
 
 export const BACKEND_PAGE_SIZE = 10
@@ -153,3 +155,44 @@ export const getTeamCollectionJSON = async (teamID: string) =>
       teamID,
     },
   })
+
+export const getCollectionChildren = async (
+  collectionID: string,
+  cursor?: string
+) => {
+  const res = await runGQLQuery({
+    query: GetCollectionChildrenDocument,
+    variables: {
+      collectionID: collectionID,
+      cursor,
+    },
+  })
+
+  return res
+}
+
+export const getCollectionChildRequests = async (
+  collectionID: string,
+  cursor?: string
+) => {
+  const res = await runGQLQuery({
+    query: GetCollectionRequestsDocument,
+    variables: {
+      collectionID,
+      cursor,
+    },
+  })
+
+  return res
+}
+
+export const getRootCollections = async (teamID: string) => {
+  const result = await runGQLQuery({
+    query: RootCollectionsOfTeamDocument,
+    variables: {
+      teamID,
+    },
+  })
+
+  return result
+}

+ 799 - 27
packages/hoppscotch-common/src/services/new-workspace/providers/__tests__/teams.workspace.spec.ts

@@ -6,19 +6,39 @@ import {
   createChildCollection,
   createNewRootCollection,
   updateTeamCollection,
+  deleteCollection,
 } from "~/helpers/backend/mutations/TeamCollection"
 
 import * as TE from "fp-ts/TaskEither"
 import { fetchAllTeams } from "~/helpers/teams/TeamListAdapter"
 import {
+  CreateRequestInCollectionMutation,
+  DeleteCollectionMutation,
+  GetCollectionChildrenQuery,
+  GetCollectionRequestsQuery,
   GetMyTeamsQuery,
+  RootCollectionsOfTeamQuery,
+  UpdateRequestMutation,
   UpdateTeamCollectionMutation,
 } from "~/helpers/backend/graphql"
 import { Handle } from "../../handle"
 import { Workspace, WorkspaceCollection } from "../../workspace"
-import { watch } from "vue"
-import { createRequestInCollection } from "~/helpers/backend/mutations/TeamRequest"
-import { getDefaultRESTRequest } from "@hoppscotch/data"
+import {
+  createRequestInCollection,
+  updateTeamRequest,
+  deleteTeamRequest,
+} from "~/helpers/backend/mutations/TeamRequest"
+import {
+  getDefaultRESTRequest,
+  HoppRESTAuth,
+  HoppRESTHeader,
+} from "@hoppscotch/data"
+import {
+  getCollectionChildren,
+  getCollectionChildRequests,
+  getRootCollections,
+} from "~/helpers/backend/helpers"
+import { toRaw, watch } from "vue"
 
 vi.mock("./../../../../platform", () => {
   const actual = vi.importActual("./../../../../platform")
@@ -38,12 +58,15 @@ vi.mock("./../../../../helpers/backend/mutations/TeamCollection", () => {
     createNewRootCollection: vi.fn(),
     createChildCollection: vi.fn(),
     updateTeamCollection: vi.fn(),
+    deleteCollection: vi.fn(),
   }
 })
 
 vi.mock("./../../../../helpers/backend/mutations/TeamRequest", () => {
   return {
     createRequestInCollection: vi.fn(),
+    updateTeamRequest: vi.fn(),
+    deleteTeamRequest: vi.fn(),
   }
 })
 
@@ -53,6 +76,14 @@ vi.mock("./../../../../helpers/teams/TeamListAdapter", () => {
   }
 })
 
+vi.mock("./../../../../helpers/backend/helpers", () => {
+  return {
+    getCollectionChildren: vi.fn(),
+    getCollectionChildRequests: vi.fn(),
+    getRootCollections: vi.fn(),
+  }
+})
+
 describe("TeamsWorkspaceProviderService", () => {
   beforeAll(() => {
     vi.mocked(createNewRootCollection).mockReset()
@@ -98,6 +129,8 @@ describe("TeamsWorkspaceProviderService", () => {
 
   test("can create a child collection", async () => {
     mockFetchAllTeams()
+    mockGetCollectionChildren()
+    mockGetCollectionChildRequests()
 
     const container = new TestContainer()
     const teamsWorkspaceProviderService = container.bind(
@@ -121,9 +154,9 @@ describe("TeamsWorkspaceProviderService", () => {
       teamsWorkspaceProviderService
     )
 
-    const childCollectionValue = childCollection.get()
+    const childCollectionHandleRef = childCollection.get()
 
-    expect(childCollectionValue.value).toMatchInlineSnapshot(`
+    expect(childCollectionHandleRef.value).toMatchInlineSnapshot(`
       {
         "data": {
           "collectionID": "child_collection_id_0",
@@ -145,21 +178,26 @@ describe("TeamsWorkspaceProviderService", () => {
       throw new Error("FAILED_TO_GET_CHILDREN")
     }
 
-    const childrenValue = children.right.get().value.data.content.value
+    const childrenHandle = children.right.get()
 
-    expect(childrenValue).toMatchInlineSnapshot(`
-      [
-        {
-          "type": "collection",
-          "value": {
-            "collectionID": "child_collection_id_0",
-            "isLastItem": false,
-            "name": "Test Child Collection #0",
-            "parentCollectionID": "root_collection_id_0",
+    if (childrenHandle.value.type === "invalid") {
+      throw new Error("INVALID_CHILD_COLLECTION_HANDLE")
+    }
+
+    expect(toRaw(childrenHandle.value.data.content.value))
+      .toMatchInlineSnapshot(`
+        [
+          {
+            "type": "collection",
+            "value": {
+              "collectionID": "child_collection_id_0",
+              "isLastItem": true,
+              "name": "Test Child Collection #0",
+              "parentCollectionID": "root_collection_id_0",
+            },
           },
-        },
-      ]
-    `)
+        ]
+      `)
   })
 
   test("can update a collection", async () => {
@@ -183,6 +221,8 @@ describe("TeamsWorkspaceProviderService", () => {
       teamsWorkspaceProviderService
     )
 
+    const collectionHandle = collection.get()
+
     const updatedCollection =
       await teamsWorkspaceProviderService.updateRESTCollection(collection, {
         name: "Collection #0 - Updated",
@@ -193,7 +233,7 @@ describe("TeamsWorkspaceProviderService", () => {
       throw new Error("FAILED_TO_UPDATE_COLLECTION")
     }
 
-    expect(collection.get().value).toMatchInlineSnapshot(`
+    expect(collectionHandle.value).toMatchInlineSnapshot(`
       {
         "data": {
           "collectionID": "root_collection_id_0",
@@ -208,6 +248,7 @@ describe("TeamsWorkspaceProviderService", () => {
 
   test("can create a request in a collection", async () => {
     mockFetchAllTeams()
+    mockCreateRequestInCollection()
 
     const container = new TestContainer()
     const teamsWorkspaceProviderService = container.bind(
@@ -242,13 +283,580 @@ describe("TeamsWorkspaceProviderService", () => {
     expect(request.right.get().value).toMatchInlineSnapshot(`
       {
         "data": {
+          "collectionID": "root_collection_id_0",
+          "providerID": "TEAMS_WORKSPACE_PROVIDER",
+          "request": {
+            "auth": {
+              "authActive": true,
+              "authType": "none",
+            },
+            "body": {
+              "body": null,
+              "contentType": null,
+            },
+            "endpoint": "https://echo.hoppscotch.io",
+            "headers": [],
+            "method": "GET",
+            "name": "Test Request #0",
+            "params": [],
+            "preRequestScript": "",
+            "testScript": "",
+            "v": "1",
+          },
+          "requestID": "request_id_0",
+          "workspaceID": "workspace_id_0",
+        },
+        "type": "ok",
+      }
+    `)
+  })
+
+  test("can update a request in a collection", async () => {
+    mockFetchAllTeams()
+    mockCreateRequestInCollection()
+    mockUpdateTeamRequest()
+
+    const container = new TestContainer()
+    const teamsWorkspaceProviderService = container.bind(
+      TeamsWorkspaceProviderService
+    )
+
+    await teamsWorkspaceProviderService.init()
+
+    const sampleWorkspace = await getSampleWorkspaceForTesting(
+      "workspace_id_0",
+      teamsWorkspaceProviderService
+    )
+
+    const collection = await createSampleRootCollectionForTesting(
+      sampleWorkspace,
+      teamsWorkspaceProviderService
+    )
+
+    const request = await teamsWorkspaceProviderService.createRESTRequest(
+      collection,
+      {
+        ...getDefaultRESTRequest(),
+        name: "Test Request #0",
+      }
+    )
+
+    if (E.isLeft(request)) {
+      throw new Error("FAILED_TO_CREATE_REQUEST")
+    }
+
+    const requestHandle = request.right.get()
+
+    const updatedRequest =
+      await teamsWorkspaceProviderService.updateRESTRequest(request.right, {
+        name: "Request #0 - Updated",
+      })
+
+    if (E.isLeft(updatedRequest)) {
+      console.log(updatedRequest.left)
+      throw new Error("FAILED_TO_UPDATE_REQUEST")
+    }
+
+    expect(requestHandle.value).toMatchInlineSnapshot(`
+      {
+        "data": {
+          "collectionID": "root_collection_id_0",
+          "providerID": "TEAMS_WORKSPACE_PROVIDER",
+          "request": {
+            "auth": {
+              "authActive": true,
+              "authType": "none",
+            },
+            "body": {
+              "body": null,
+              "contentType": null,
+            },
+            "endpoint": "https://echo.hoppscotch.io",
+            "headers": [],
+            "method": "GET",
+            "name": "Request #0 - Updated",
+            "params": [],
+            "preRequestScript": "",
+            "testScript": "",
+            "v": "1",
+          },
+          "requestID": "request_id_0",
+          "workspaceID": "workspace_id_0",
+        },
+        "type": "ok",
+      }
+    `)
+  })
+
+  test("remove a collection", async () => {
+    mockFetchAllTeams()
+    mockDeleteRestCollection()
+
+    const container = new TestContainer()
+    const teamsWorkspaceProviderService = container.bind(
+      TeamsWorkspaceProviderService
+    )
+
+    await teamsWorkspaceProviderService.init()
+
+    const sampleWorkspace = await getSampleWorkspaceForTesting(
+      "workspace_id_0",
+      teamsWorkspaceProviderService
+    )
+
+    const collection = await createSampleRootCollectionForTesting(
+      sampleWorkspace,
+      teamsWorkspaceProviderService
+    )
+
+    const collectionHandle = collection.get()
+
+    expect(collectionHandle.value).toMatchInlineSnapshot(`
+      {
+        "data": {
+          "collectionID": "root_collection_id_0",
+          "name": "Test Collection #0",
+          "providerID": "TEAMS_WORKSPACE_PROVIDER",
+          "workspaceID": "workspace_id_0",
+        },
+        "type": "ok",
+      }
+    `)
+
+    const deletedCollection =
+      await teamsWorkspaceProviderService.removeRESTCollection(collection)
+
+    if (E.isLeft(deletedCollection)) {
+      console.log(deletedCollection.left)
+      throw new Error("FAILED_TO_DELETE_COLLECTION")
+    }
+
+    expect(collectionHandle.value).toMatchInlineSnapshot(`
+      {
+        "reason": "COLLECTION_DOES_NOT_EXIST",
+        "type": "invalid",
+      }
+    `)
+  })
+
+  test("remove rest request", async () => {
+    mockFetchAllTeams()
+    mockCreateRequestInCollection()
+    mockDeleteRestRequest()
+
+    const container = new TestContainer()
+    const teamsWorkspaceProviderService = container.bind(
+      TeamsWorkspaceProviderService
+    )
+
+    await teamsWorkspaceProviderService.init()
+
+    const sampleWorkspace = await getSampleWorkspaceForTesting(
+      "workspace_id_0",
+      teamsWorkspaceProviderService
+    )
+
+    const collection = await createSampleRootCollectionForTesting(
+      sampleWorkspace,
+      teamsWorkspaceProviderService
+    )
+
+    const request = await teamsWorkspaceProviderService.createRESTRequest(
+      collection,
+      {
+        ...getDefaultRESTRequest(),
+        name: "Test Request #0",
+      }
+    )
+
+    if (E.isLeft(request)) {
+      throw new Error("FAILED_TO_CREATE_REQUEST")
+    }
+
+    const requestHandle = request.right.get()
+
+    expect(requestHandle.value).toMatchInlineSnapshot(`
+      {
+        "data": {
+          "collectionID": "root_collection_id_0",
           "providerID": "TEAMS_WORKSPACE_PROVIDER",
+          "request": {
+            "auth": {
+              "authActive": true,
+              "authType": "none",
+            },
+            "body": {
+              "body": null,
+              "contentType": null,
+            },
+            "endpoint": "https://echo.hoppscotch.io",
+            "headers": [],
+            "method": "GET",
+            "name": "Test Request #0",
+            "params": [],
+            "preRequestScript": "",
+            "testScript": "",
+            "v": "1",
+          },
           "requestID": "request_id_0",
           "workspaceID": "workspace_id_0",
         },
         "type": "ok",
       }
     `)
+
+    const deletedRequest =
+      await teamsWorkspaceProviderService.removeRESTRequest(request.right)
+
+    if (E.isLeft(deletedRequest)) {
+      console.log(deletedRequest.left)
+      throw new Error("FAILED_TO_DELETE_REQUEST")
+    }
+
+    expect(requestHandle.value).toMatchInlineSnapshot(`
+      {
+        "reason": "REQUEST_DOES_NOT_EXIST",
+        "type": "invalid",
+      }
+    `)
+  })
+
+  test("get child collections and requests of a collection", async () => {
+    mockFetchAllTeams()
+    mockGetCollectionChildren()
+
+    const container = new TestContainer()
+    const teamsWorkspaceProviderService = container.bind(
+      TeamsWorkspaceProviderService
+    )
+
+    await teamsWorkspaceProviderService.init()
+
+    const sampleWorkspace = await getSampleWorkspaceForTesting(
+      "workspace_id_0",
+      teamsWorkspaceProviderService
+    )
+
+    const collection = await createSampleRootCollectionForTesting(
+      sampleWorkspace,
+      teamsWorkspaceProviderService
+    )
+
+    // insert one child collection
+    await createSampleChildCollectionForTesting(
+      collection,
+      teamsWorkspaceProviderService
+    )
+
+    const children =
+      await teamsWorkspaceProviderService.getRESTCollectionChildrenView(
+        collection
+      )
+
+    if (E.isLeft(children)) {
+      console.log(children.left)
+      throw new Error("FAILED_TO_GET_CHILDREN")
+    }
+
+    const childrenHandle = children.right.get()
+
+    if (childrenHandle.value.type === "invalid") {
+      throw new Error("INVALID_CHILD_COLLECTION_HANDLE")
+    }
+
+    // locally we've one child collection. when we call getRESTCollectionChildrenView, we should get a computed with that one child collection
+    expect(childrenHandle.value.data.content.value).toMatchInlineSnapshot(`
+      [
+        {
+          "type": "collection",
+          "value": {
+            "collectionID": "child_collection_id_0",
+            "isLastItem": true,
+            "name": "Test Child Collection #0",
+            "parentCollectionID": "root_collection_id_0",
+          },
+        },
+      ]
+    `)
+
+    // verify the loading state and other properties
+    expect({
+      collectionID: childrenHandle.value.data.collectionID,
+      loading: childrenHandle.value.data.loading.value,
+      providerID: childrenHandle.value.data.providerID,
+      workspaceID: childrenHandle.value.data.workspaceID,
+    }).toMatchInlineSnapshot(`
+      {
+        "collectionID": "root_collection_id_0",
+        "loading": true,
+        "providerID": "TEAMS_WORKSPACE_PROVIDER",
+        "workspaceID": "workspace_id_0",
+      }
+    `)
+
+    let resolve: (value: undefined) => void
+
+    const promise = new Promise<void>((res) => {
+      resolve = res
+    })
+
+    // wait for the value of childrenHandle to change
+    watch(childrenHandle, () => {
+      resolve(undefined)
+    })
+
+    await promise
+
+    // verify the computed value after the getChildren is resolved, here we've mocked it to return 3 child collections
+    expect(childrenHandle.value.data.content.value).toMatchInlineSnapshot(`
+      [
+        {
+          "type": "collection",
+          "value": {
+            "collectionID": "child_collection_id_0",
+            "isLastItem": false,
+            "name": "Test Child Collection #0",
+            "parentCollectionID": "root_collection_id_0",
+          },
+        },
+        {
+          "type": "collection",
+          "value": {
+            "collectionID": "child_collection_id_1",
+            "isLastItem": false,
+            "name": "Test Child Collection #1",
+            "parentCollectionID": "root_collection_id_0",
+          },
+        },
+        {
+          "type": "collection",
+          "value": {
+            "collectionID": "child_collection_id_2",
+            "isLastItem": true,
+            "name": "Test Child Collection #2",
+            "parentCollectionID": "root_collection_id_0",
+          },
+        },
+        {
+          "type": "request",
+          "value": {
+            "collectionID": "root_collection_id_0",
+            "isLastItem": false,
+            "request": {
+              "auth": {
+                "authActive": true,
+                "authType": "none",
+              },
+              "body": {
+                "body": null,
+                "contentType": null,
+              },
+              "endpoint": "https://echo.hoppscotch.io",
+              "headers": [],
+              "method": "GET",
+              "name": "Untitled",
+              "params": [],
+              "preRequestScript": "",
+              "testScript": "",
+              "v": "1",
+            },
+            "requestID": "request_id_0",
+          },
+        },
+        {
+          "type": "request",
+          "value": {
+            "collectionID": "root_collection_id_0",
+            "isLastItem": false,
+            "request": {
+              "auth": {
+                "authActive": true,
+                "authType": "none",
+              },
+              "body": {
+                "body": null,
+                "contentType": null,
+              },
+              "endpoint": "https://echo.hoppscotch.io",
+              "headers": [],
+              "method": "GET",
+              "name": "Untitled",
+              "params": [],
+              "preRequestScript": "",
+              "testScript": "",
+              "v": "1",
+            },
+            "requestID": "request_id_1",
+          },
+        },
+        {
+          "type": "request",
+          "value": {
+            "collectionID": "root_collection_id_0",
+            "isLastItem": true,
+            "request": {
+              "auth": {
+                "authActive": true,
+                "authType": "none",
+              },
+              "body": {
+                "body": null,
+                "contentType": null,
+              },
+              "endpoint": "https://echo.hoppscotch.io",
+              "headers": [],
+              "method": "GET",
+              "name": "Untitled",
+              "params": [],
+              "preRequestScript": "",
+              "testScript": "",
+              "v": "1",
+            },
+            "requestID": "request_id_2",
+          },
+        },
+      ]
+    `)
+
+    // verify the loading state and other properties
+    expect({
+      collectionID: childrenHandle.value.data.collectionID,
+      loading: childrenHandle.value.data.loading.value,
+      providerID: childrenHandle.value.data.providerID,
+      workspaceID: childrenHandle.value.data.workspaceID,
+    }).toMatchInlineSnapshot(`
+      {
+        "collectionID": "root_collection_id_0",
+        "loading": false,
+        "providerID": "TEAMS_WORKSPACE_PROVIDER",
+        "workspaceID": "workspace_id_0",
+      }
+    `)
+  })
+
+  test("get rest root collections of a workspace", async () => {
+    mockFetchAllTeams()
+    mockGetRootCollections()
+
+    const container = new TestContainer()
+    const teamsWorkspaceProviderService = container.bind(
+      TeamsWorkspaceProviderService
+    )
+
+    await teamsWorkspaceProviderService.init()
+
+    const sampleWorkspace = await getSampleWorkspaceForTesting(
+      "workspace_id_0",
+      teamsWorkspaceProviderService
+    )
+
+    const collection = await createSampleRootCollectionForTesting(
+      sampleWorkspace,
+      teamsWorkspaceProviderService
+    )
+
+    // also create a child collection to make sure we fetch the root collections only
+    await createSampleChildCollectionForTesting(
+      collection,
+      teamsWorkspaceProviderService
+    )
+
+    const rootCollections =
+      await teamsWorkspaceProviderService.getRESTRootCollectionView(
+        sampleWorkspace
+      )
+
+    if (E.isLeft(rootCollections)) {
+      console.log(rootCollections.left)
+      throw new Error("FAILED_TO_GET_ROOT_COLLECTIONS")
+    }
+
+    const rootCollectionsHandle = rootCollections.right.get()
+
+    if (rootCollectionsHandle.value.type === "invalid") {
+      throw new Error("INVALID_ROOT_COLLECTION_HANDLE")
+    }
+
+    const rootCollectionsContent = rootCollectionsHandle.value.data.collections
+
+    expect({
+      collections: rootCollectionsContent.value,
+      loading: rootCollectionsHandle.value.data.loading.value,
+      providerID: rootCollectionsHandle.value.data.providerID,
+      workspaceID: rootCollectionsHandle.value.data.workspaceID,
+    }).toMatchInlineSnapshot(`
+      {
+        "collections": [
+          {
+            "collectionID": "root_collection_id_0",
+            "isLastItem": true,
+            "name": "Test Collection #0",
+            "parentCollectionID": null,
+          },
+        ],
+        "loading": true,
+        "providerID": "TEAMS_WORKSPACE_PROVIDER",
+        "workspaceID": "workspace_id_0",
+      }
+    `)
+
+    let resolve: (value: undefined) => void
+
+    const promise = new Promise<void>((res) => {
+      resolve = res
+    })
+
+    // wait for the value of rootCollectionsHandle to change
+    watch(
+      rootCollectionsHandle,
+      () => {
+        resolve(undefined)
+      },
+      {
+        deep: true,
+      }
+    )
+
+    await promise
+
+    expect({
+      collections: rootCollectionsContent.value,
+      loading: rootCollectionsHandle.value.data.loading.value,
+      providerID: rootCollectionsHandle.value.data.providerID,
+      workspaceID: rootCollectionsHandle.value.data.workspaceID,
+    }).toMatchInlineSnapshot(`
+      {
+        "collections": [
+          {
+            "collectionID": "root_collection_id_0",
+            "isLastItem": false,
+            "name": "Test Collection #0",
+            "parentCollectionID": null,
+          },
+          {
+            "collectionID": "root_collection_id_0",
+            "isLastItem": false,
+            "name": "Test Collection #0",
+            "parentCollectionID": null,
+          },
+          {
+            "collectionID": "root_collection_id_1",
+            "isLastItem": false,
+            "name": "Test Collection #1",
+            "parentCollectionID": null,
+          },
+          {
+            "collectionID": "root_collection_id_2",
+            "isLastItem": true,
+            "name": "Test Collection #2",
+            "parentCollectionID": null,
+          },
+        ],
+        "loading": false,
+        "providerID": "TEAMS_WORKSPACE_PROVIDER",
+        "workspaceID": "workspace_id_0",
+      }
+    `)
   })
 })
 
@@ -357,17 +965,181 @@ const mockUpdateTeamCollection = () => {
 }
 
 const mockCreateRequestInCollection = () => {
-  return vi.mocked(createRequestInCollection).mockResolvedValue(
-    E.right({
+  return vi.mocked(createRequestInCollection).mockImplementation(() => {
+    return TE.right(<CreateRequestInCollectionMutation>{
       createRequestInCollection: {
-        ...getDefaultRESTRequest(),
+        collection: {
+          id: "root_collection_id_0",
+          team: {
+            id: "workspace_id_0",
+            name: "Test Team #0",
+          },
+        },
         id: "request_id_0",
       },
     })
-  )
+  })
 }
 
-// NOTE FOR TOMORROW AKASH
-// the mock for _fetchAllWorkspaces is not working
-// check the importActual section
-// might be due to the fact that the team service class is not being mocked when using the importActual
+const mockUpdateTeamRequest = () => {
+  return vi.mocked(updateTeamRequest).mockImplementation(() => {
+    return TE.right(<UpdateRequestMutation>{
+      updateRequest: {
+        id: "request_id_0",
+        title: "Request #0 - Updated",
+      },
+    })
+  })
+}
+
+const mockDeleteRestCollection = () => {
+  return vi.mocked(deleteCollection).mockImplementation(() => {
+    return TE.right(<DeleteCollectionMutation>{
+      deleteCollection: true,
+    })
+  })
+}
+
+const mockDeleteRestRequest = () => {
+  return vi.mocked(deleteTeamRequest).mockImplementation(() => {
+    return TE.right({
+      deleteRequest: true,
+    })
+  })
+}
+
+const mockGetCollectionChildren = () => {
+  return vi
+    .mocked(getCollectionChildren)
+    .mockImplementation(async (collectionID: string) => {
+      const auth: HoppRESTAuth = {
+        authType: "basic",
+        username: "test_username",
+        password: "test_password",
+        authActive: true,
+      }
+
+      const headers: HoppRESTHeader[] = [
+        {
+          key: "X-Vitest-Mocked-Header",
+          value: "mocked-header",
+          active: true,
+        },
+      ]
+
+      return E.right(<GetCollectionChildrenQuery>{
+        collection: {
+          children: [
+            {
+              id: "child_collection_id_0",
+              title: "Test Child Collection #0",
+              data: JSON.stringify({
+                auth,
+                headers,
+              }),
+            },
+            {
+              id: "child_collection_id_1",
+              title: "Test Child Collection #1",
+              data: JSON.stringify({
+                auth,
+                headers,
+              }),
+            },
+            {
+              id: "child_collection_id_2",
+              title: "Test Child Collection #2",
+              data: JSON.stringify({
+                auth,
+                headers,
+              }),
+            },
+          ],
+        },
+      })
+    })
+}
+
+const mockGetCollectionChildRequests = () => {
+  return vi.mocked(getCollectionChildRequests).mockImplementation(async () => {
+    return E.right(<GetCollectionRequestsQuery>{
+      requestsInCollection: [
+        {
+          id: "request_id_0",
+          title: "Test Request #0",
+          request: JSON.stringify(getDefaultRESTRequest()),
+        },
+        {
+          id: "request_id_1",
+          title: "Test Request #1",
+          request: JSON.stringify(getDefaultRESTRequest()),
+        },
+        {
+          id: "request_id_2",
+          title: "Test Request #2",
+          request: JSON.stringify(getDefaultRESTRequest()),
+        },
+      ],
+    })
+  })
+}
+
+const mockGetRootCollections = () => {
+  return vi.mocked(getRootCollections).mockImplementation(async () => {
+    return E.right(<RootCollectionsOfTeamQuery>{
+      rootCollectionsOfTeam: [
+        {
+          id: "root_collection_id_0",
+          title: "Test Collection #0",
+          data: JSON.stringify({
+            auth: {
+              authType: "none",
+              authActive: true,
+            },
+            headers: [
+              {
+                key: "X-Vitest-Mocked-Header",
+                value: "mocked-header",
+                active: true,
+              },
+            ],
+          }),
+        },
+        {
+          id: "root_collection_id_1",
+          title: "Test Collection #1",
+          data: JSON.stringify({
+            auth: {
+              authType: "none",
+              authActive: true,
+            },
+            headers: [
+              {
+                key: "X-Vitest-Mocked-Header",
+                value: "mocked-header",
+                active: true,
+              },
+            ],
+          }),
+        },
+        {
+          id: "root_collection_id_2",
+          title: "Test Collection #2",
+          data: JSON.stringify({
+            auth: {
+              authType: "none",
+              authActive: true,
+            },
+            headers: [
+              {
+                key: "X-Vitest-Mocked-Header",
+                value: "mocked-header",
+                active: true,
+              },
+            ],
+          }),
+        },
+      ],
+    })
+  })
+}

+ 283 - 43
packages/hoppscotch-common/src/services/new-workspace/providers/teams.workspace.ts

@@ -12,7 +12,7 @@ import {
   HoppCollection,
   HoppRESTAuth,
   HoppRESTHeader,
-  HoppRESTRequest,
+  HoppRESTHeaders,
 } from "@hoppscotch/data"
 
 import * as E from "fp-ts/Either"
@@ -34,10 +34,12 @@ import {
   RESTCollectionChildrenView,
   RESTCollectionJSONView,
   RESTCollectionLevelAuthHeadersView,
+  RESTCollectionViewItem,
   RESTSearchResultsView,
   RootRESTCollectionView,
 } from "../view"
 import {
+  GQLError,
   runGQLQuery,
   runGQLSubscription,
   runMutation,
@@ -70,6 +72,12 @@ import { HoppInheritedProperty } from "~/helpers/types/HoppInheritedProperties"
 import { initializeDownloadFile } from "~/helpers/import-export/export"
 import { TeamSearchService } from "~/helpers/teams/TeamsSearch.service"
 import { fetchAllTeams } from "~/helpers/teams/TeamListAdapter"
+import { HoppRESTRequest } from "@hoppscotch/data"
+import {
+  getCollectionChildren,
+  getCollectionChildRequests,
+  getRootCollections,
+} from "~/helpers/backend/helpers"
 
 type TeamsWorkspaceCollection = WorkspaceCollection & {
   parentCollectionID?: string
@@ -491,7 +499,12 @@ export class TeamsWorkspaceProviderService
   async updateRESTRequest(
     requestHandle: Handle<WorkspaceRequest>,
     updatedRequest: Partial<HoppRESTRequest> & { name: string }
-  ) {
+  ): Promise<
+    E.Either<
+      "INVALID_REQUEST_HANDLE" | "REQUEST_DOES_NOT_EXIST" | GQLError<any>,
+      void
+    >
+  > {
     const requestHandleRef = requestHandle.get()
 
     if (!isValidRequestHandle(requestHandleRef, this.providerID)) {
@@ -536,11 +549,18 @@ export class TeamsWorkspaceProviderService
     return E.right(undefined)
   }
 
-  async removeRESTCollection(collectionHandle: Handle<WorkspaceCollection>) {
+  async removeRESTCollection(
+    collectionHandle: Handle<WorkspaceCollection>
+  ): Promise<
+    E.Either<
+      "INVALID_COLLECTION_HANDLE" | GQLError<"team/invalid_coll_id">,
+      void
+    >
+  > {
     const collectionHandleRef = collectionHandle.get()
 
     if (!isValidCollectionHandle(collectionHandleRef, this.providerID)) {
-      return Promise.resolve(E.left("INVALID_COLLECTION_HANDLE" as const))
+      return E.left("INVALID_COLLECTION_HANDLE" as const)
     }
 
     const res = await deleteCollection(
@@ -551,14 +571,25 @@ export class TeamsWorkspaceProviderService
       return res
     }
 
-    return Promise.resolve(E.right(undefined))
+    // remove the collection from the collections
+    // the subscriptions will also take care of this
+    this.collections.value = this.collections.value.filter(
+      (collection) =>
+        collection.collectionID !== collectionHandleRef.value.data.collectionID
+    )
+
+    return E.right(undefined)
   }
 
-  async removeRESTRequest(requestHandle: Handle<WorkspaceRequest>) {
+  async removeRESTRequest(
+    requestHandle: Handle<WorkspaceRequest>
+  ): Promise<
+    E.Either<"INVALID_REQUEST_HANDLE" | GQLError<"team_req/not_found">, void>
+  > {
     const requestHandleRef = requestHandle.get()
 
     if (!isValidRequestHandle(requestHandleRef, this.providerID)) {
-      return Promise.resolve(E.left("INVALID_REQUEST_HANDLE" as const))
+      return E.left("INVALID_REQUEST_HANDLE" as const)
     }
 
     const res = await deleteTeamRequest(requestHandleRef.value.data.requestID)()
@@ -567,7 +598,13 @@ export class TeamsWorkspaceProviderService
       return res
     }
 
-    return Promise.resolve(E.right(undefined))
+    // remove the request from the requests
+    // the subscriptions will also take care of this
+    this.requests.value = this.requests.value.filter(
+      (request) => request.requestID !== requestHandleRef.value.data.requestID
+    )
+
+    return E.right(undefined)
   }
 
   getWorkspaces(): HandleRef<HandleRef<Workspace>[], "LOADING_WORKSPACES"> {
@@ -666,6 +703,119 @@ export class TeamsWorkspaceProviderService
   ): Promise<E.Either<never, Handle<RESTCollectionChildrenView>>> {
     const collectionHandleRef = collectionHandle.get()
 
+    const isFetchingCollection = ref(false)
+    const isFetchingRequests = ref(false)
+
+    const isFetchingChildren = computed(() => {
+      return isFetchingCollection.value || isFetchingRequests.value
+    })
+
+    if (isValidCollectionHandle(collectionHandleRef, this.providerID)) {
+      isFetchingCollection.value = true
+      // fetch the child collections
+      getCollectionChildren(collectionHandleRef.value.data.collectionID)
+        .then((children) => {
+          if (E.isLeft(children) || !children.right.collection?.children) {
+            return
+          }
+
+          // remove the existing children
+          this.collections.value = this.collections.value.filter(
+            (collection) =>
+              collection.parentCollectionID !==
+              collectionHandleRef.value.data.collectionID
+          )
+
+          let previousOrder: string | null = null
+
+          // now push the new children
+          this.collections.value.push(
+            ...children.right.collection?.children.map((collection) => {
+              const collectionProperties = collection.data
+                ? JSON.parse(collection.data)
+                : null
+
+              let auth: HoppRESTAuth = {
+                authType: "inherit",
+                authActive: true,
+              }
+
+              let headers: HoppRESTHeader[] = []
+
+              const authParsingRes = HoppRESTAuth.safeParse(
+                collectionProperties?.auth
+              )
+
+              const headersParsingRes = HoppRESTHeaders.safeParse(
+                collectionProperties?.headers
+              )
+
+              if (authParsingRes.success) {
+                auth = authParsingRes.data
+              }
+
+              if (headersParsingRes.success) {
+                headers = headersParsingRes.data
+              }
+
+              const order = generateKeyBetween(previousOrder, null)
+              previousOrder = order
+
+              return {
+                collectionID: collection.id,
+                providerID: this.providerID,
+                workspaceID: collectionHandleRef.value.data.workspaceID,
+                name: collection.title,
+                parentCollectionID: collectionHandleRef.value.data.collectionID,
+                order,
+                auth: auth,
+                headers: headers,
+              }
+            })
+          )
+        })
+        .finally(() => {
+          isFetchingCollection.value = false
+        })
+
+      // fetch the child requests
+      getCollectionChildRequests(collectionHandleRef.value.data.collectionID)
+        .then((requests) => {
+          if (E.isLeft(requests)) {
+            return
+          }
+
+          // remove the existing requests
+          this.requests.value = this.requests.value.filter(
+            (request) =>
+              request.collectionID !==
+              collectionHandleRef.value.data.collectionID
+          )
+
+          let previousOrder: string | null = null
+
+          // now push the new requests
+          this.requests.value.push(
+            ...requests.right.requestsInCollection.map((request) => {
+              const order = generateKeyBetween(previousOrder, null)
+              previousOrder = order
+
+              return {
+                requestID: request.id,
+                providerID: this.providerID,
+                workspaceID: collectionHandleRef.value.data.workspaceID,
+                collectionID: collectionHandleRef.value.data.collectionID,
+                request: JSON.parse(request.request), // TODO: validation
+                order,
+              }
+            })
+          )
+        })
+        .finally(() => {
+          isFetchingRequests.value = false
+        })
+    }
+
     return E.right({
       get: lazy(() =>
         computed(() => {
@@ -677,23 +827,52 @@ export class TeamsWorkspaceProviderService
           }
 
           // TODO: Why computed in a computed ? doing this to make typescript happy here, check later
-          const collectionChildren = computed(() =>
-            sortByOrder(
+          const collectionChildren = computed(() => {
+            const sortedAndFilteredCollections = sortByOrder(
               this.collections.value.filter(
                 (collection) =>
                   collection.parentCollectionID ===
                   collectionHandleRef.value.data.collectionID
               )
-            ).map((collection) => ({
-              type: "collection" as const,
-              value: {
-                collectionID: collection.collectionID,
-                name: collection.name,
-                parentCollectionID: collection.parentCollectionID ?? null,
-                isLastItem: false,
-              },
-            }))
-          )
+            )
+
+            const collections = sortedAndFilteredCollections.map(
+              (collection, index) =>
+                <RESTCollectionViewItem>{
+                  type: "collection" as const,
+                  value: {
+                    collectionID: collection.collectionID,
+                    name: collection.name,
+                    parentCollectionID: collection.parentCollectionID ?? null,
+                    isLastItem:
+                      index === sortedAndFilteredCollections.length - 1,
+                  },
+                }
+            )
+
+            const sortedAndFilteredRequests = sortByOrder(
+              this.requests.value.filter(
+                (request) =>
+                  request.collectionID ===
+                  collectionHandleRef.value.data.collectionID
+              )
+            )
+
+            const requests = sortedAndFilteredRequests.map(
+              (request, index) =>
+                <RESTCollectionViewItem>{
+                  type: "request",
+                  value: {
+                    request: request.request,
+                    collectionID: request.collectionID,
+                    isLastItem: index === sortedAndFilteredRequests.length - 1,
+                    requestID: request.requestID,
+                  },
+                }
+            )
+
+            return [...collections, ...requests]
+          })
 
           if (!isValidCollectionHandle(collectionHandleRef, this.providerID)) {
             return {
@@ -708,7 +887,7 @@ export class TeamsWorkspaceProviderService
               providerID: collectionHandleRef.value.data.providerID,
               workspaceID: collectionHandleRef.value.data.workspaceID,
               content: collectionChildren,
-              loading: ref(false), // TODO: make this dynamic
+              loading: isFetchingChildren,
             },
             type: "ok" as const,
           }
@@ -722,6 +901,74 @@ export class TeamsWorkspaceProviderService
   ): Promise<E.Either<never, Handle<RootRESTCollectionView>>> {
     const workspaceHandleRef = workspaceHandle.get()
 
+    const isFetchingRootCollections = ref(false)
+
+    if (isValidWorkspaceHandle(workspaceHandleRef, this.providerID)) {
+      isFetchingRootCollections.value = true
+
+      // fetch the root collections
+      getRootCollections(workspaceHandleRef.value.data.workspaceID)
+        .then((collections) => {
+          if (E.isLeft(collections)) {
+            return
+          }
+
+          // remove the existing collections
+          this.collections.value = this.collections.value.filter(
+            (collection) => !collection.parentCollectionID
+          )
+
+          let previousOrder: string | null = null
+
+          this.collections.value.push(
+            ...collections.right.rootCollectionsOfTeam.map((collection) => {
+              const collectionProperties = collection.data
+                ? JSON.parse(collection.data)
+                : null
+
+              let auth: HoppRESTAuth = {
+                authType: "none",
+                authActive: true,
+              }
+
+              let headers: HoppRESTHeader[] = []
+
+              const authParsingRes = HoppRESTAuth.safeParse(
+                collectionProperties?.auth
+              )
+
+              const headersParsingRes = HoppRESTHeaders.safeParse(
+                collectionProperties?.headers
+              )
+
+              if (authParsingRes.success) {
+                auth = authParsingRes.data
+              }
+
+              if (headersParsingRes.success) {
+                headers = headersParsingRes.data
+              }
+
+              const order = generateKeyBetween(previousOrder, null)
+              previousOrder = order
+
+              return {
+                collectionID: collection.id,
+                providerID: this.providerID,
+                workspaceID: workspaceHandleRef.value.data.workspaceID,
+                name: collection.title,
+                order,
+                auth: auth,
+                headers: headers,
+              }
+            })
+          )
+        })
+        .finally(() => {
+          isFetchingRootCollections.value = false
+        })
+    }
+
     return E.right({
       get: lazy(() =>
         computed(() => {
@@ -732,25 +979,30 @@ export class TeamsWorkspaceProviderService
             }
           }
 
-          const rootCollections = computed(() =>
-            sortByOrder(
+          const rootCollections = computed(() => {
+            const filteredAndSorted = sortByOrder(
               this.collections.value.filter(
                 (collection) => !collection.parentCollectionID
               )
-            ).map((collection) => ({
-              collectionID: collection.collectionID,
-              name: collection.name,
-              isLastItem: false,
-              parentCollectionID: null,
-            }))
-          )
+            )
+
+            return filteredAndSorted.map((collection, index) => {
+              return {
+                collectionID: collection.collectionID,
+                name: collection.name,
+                isLastItem: index === filteredAndSorted.length - 1,
+                parentCollectionID: null,
+              }
+            })
+          })
 
           return {
             data: {
               workspaceID: workspaceHandleRef.value.data.workspaceID,
               providerID: this.providerID,
+              // this won't be triggered
               collections: rootCollections,
-              loading: ref(false), // TODO: make this dynamic
+              loading: isFetchingRootCollections,
             },
             type: "ok" as const,
           }
@@ -1634,18 +1886,6 @@ const fetchRootCollections = async (teamID: string, cursor?: string) => {
   return result
 }
 
-const getCollectionChildren = async (collectionID: string, cursor?: string) => {
-  const res = await runGQLQuery({
-    query: GetCollectionChildrenDocument,
-    variables: {
-      collectionID: collectionID,
-      cursor,
-    },
-  })
-
-  return res
-}
-
 const runTeamCollectionAddedSubscription = (teamID: string) =>
   runGQLSubscription({
     query: TeamCollectionAddedDocument,