Browse Source

more tests + bug fixs

amk-dev 8 months ago
parent
commit
8a89b29fee

+ 301 - 0
packages/hoppscotch-common/src/services/new-workspace/providers/__tests__/reordering-utils.spec.ts

@@ -0,0 +1,301 @@
+import { describe, it, expect, beforeEach, test } from "vitest"
+import * as E from "fp-ts/Either"
+import { moveItems, reorderItems, sortByOrder } from "../teams.workspace"
+
+type Item = {
+  id: string
+  parentID: string | null
+  name: string
+  order: string
+}
+
+/**
+ * test structure we're working with
+ *
+ * item 1
+ *  item 1_1
+ *      item_1_1_1
+ *      item_1_1_2
+ *  item 1_2
+ *  item 1_3
+ *  item 1_4
+ * item 2
+ *
+ */
+
+describe("reorder items", async () => {
+  let items: Item[]
+
+  beforeEach(() => {
+    items = [
+      { id: "item-1", parentID: null, name: "item 1", order: "a0" },
+      { id: "item-1_1", parentID: "item-1", name: "item 1_1", order: "a0" },
+      {
+        id: "item-1_1_1",
+        parentID: "item-1_1",
+        name: "item 1_1_1",
+        order: "a0",
+      },
+      {
+        id: "item-1_1_2",
+        parentID: "item-1_1",
+        name: "item 1_1_2",
+        order: "a1",
+      },
+      { id: "item-1_2", parentID: "item-1", name: "item 1_2", order: "a1" },
+      { id: "item-1_3", parentID: "item-1", name: "item 1_3", order: "a2" },
+      { id: "item-1_4", parentID: "item-1", name: "item 1_4", order: "a3" },
+      { id: "item-2", parentID: null, name: "item 2", order: "a1" },
+    ]
+  })
+
+  test("can reorder items to the top of the list", () => {
+    const result = reorderItems("item-2", "item-1", items, "id", "parentID")
+
+    if (E.isLeft(result)) {
+      console.log(result.left)
+      throw new Error("SOMETHING WENT WRONG WHILE REORDERING")
+    }
+
+    expect(sortByOrder(result.right.filter((item) => !item.parentID)))
+      .toMatchInlineSnapshot(`
+      [
+        {
+          "id": "item-2",
+          "name": "item 2",
+          "order": "Zz",
+          "parentID": null,
+        },
+        {
+          "id": "item-1",
+          "name": "item 1",
+          "order": "a0",
+          "parentID": null,
+        },
+      ]
+    `)
+  })
+
+  test("can reorder items to the bottom of the list", () => {
+    const result = reorderItems("item-1", null, items, "id", "parentID")
+
+    if (E.isLeft(result)) {
+      console.log(result.left)
+      throw new Error("SOMETHING WENT WRONG WHILE REORDERING")
+    }
+
+    expect(sortByOrder(result.right.filter((item) => !item.parentID)))
+      .toMatchInlineSnapshot(`
+      [
+        {
+          "id": "item-2",
+          "name": "item 2",
+          "order": "a1",
+          "parentID": null,
+        },
+        {
+          "id": "item-1",
+          "name": "item 1",
+          "order": "a2",
+          "parentID": null,
+        },
+      ]
+    `)
+  })
+
+  test("can reorder items to the middle of the list", () => {
+    // move item-1_3 to above item-1_2
+    const result = reorderItems("item-1_3", "item-1_2", items, "id", "parentID")
+
+    if (E.isLeft(result)) {
+      console.log(result.left)
+      throw new Error("SOMETHING WENT WRONG WHILE REORDERING")
+    }
+
+    expect(
+      sortByOrder(result.right.filter((item) => item.parentID === "item-1"))
+    ).toMatchInlineSnapshot(`
+      [
+        {
+          "id": "item-1_1",
+          "name": "item 1_1",
+          "order": "a0",
+          "parentID": "item-1",
+        },
+        {
+          "id": "item-1_3",
+          "name": "item 1_3",
+          "order": "a0V",
+          "parentID": "item-1",
+        },
+        {
+          "id": "item-1_2",
+          "name": "item 1_2",
+          "order": "a1",
+          "parentID": "item-1",
+        },
+        {
+          "id": "item-1_4",
+          "name": "item 1_4",
+          "order": "a3",
+          "parentID": "item-1",
+        },
+      ]
+    `)
+  })
+
+  test("can move an item to another parent with no children", () => {
+    // move item-1_1_2 to item-2
+    const result = moveItems("item-1_1_2", "item-2", items, "id", "parentID")
+
+    if (E.isLeft(result)) {
+      console.log(result.left)
+      throw new Error("SOMETHING WENT WRONG WHILE REORDERING")
+    }
+
+    // check if the item_1_1_2 is removed from its parent
+    expect(
+      sortByOrder(result.right.filter((item) => item.parentID === "item-1_1"))
+    ).toMatchInlineSnapshot(`
+      [
+        {
+          "id": "item-1_1_1",
+          "name": "item 1_1_1",
+          "order": "a0",
+          "parentID": "item-1_1",
+        },
+      ]
+    `)
+
+    // check if item_1_1_2 is inserted into its destinationParent
+    expect(
+      sortByOrder(result.right.filter((item) => item.parentID === "item-2"))
+    ).toMatchInlineSnapshot(`
+      [
+        {
+          "id": "item-1_1_2",
+          "name": "item 1_1_2",
+          "order": "a0",
+          "parentID": "item-2",
+        },
+      ]
+    `)
+  })
+
+  test("can move an item to another parent with children", () => {
+    const result = moveItems("item-1_2", "item-1_1", items, "id", "parentID")
+
+    if (E.isLeft(result)) {
+      console.log(result.left)
+      throw new Error("SOMETHING WENT WRONG WHILE REORDERING")
+    }
+
+    expect(
+      sortByOrder(result.right.filter((item) => item.parentID === "item-1"))
+    ).toMatchInlineSnapshot(`
+      [
+        {
+          "id": "item-1_1",
+          "name": "item 1_1",
+          "order": "a0",
+          "parentID": "item-1",
+        },
+        {
+          "id": "item-1_3",
+          "name": "item 1_3",
+          "order": "a2",
+          "parentID": "item-1",
+        },
+        {
+          "id": "item-1_4",
+          "name": "item 1_4",
+          "order": "a3",
+          "parentID": "item-1",
+        },
+      ]
+    `)
+
+    expect(
+      sortByOrder(result.right.filter((item) => item.parentID === "item-1_1"))
+    ).toMatchInlineSnapshot(`
+      [
+        {
+          "id": "item-1_1_1",
+          "name": "item 1_1_1",
+          "order": "a0",
+          "parentID": "item-1_1",
+        },
+        {
+          "id": "item-1_1_2",
+          "name": "item 1_1_2",
+          "order": "a1",
+          "parentID": "item-1_1",
+        },
+        {
+          "id": "item-1_2",
+          "name": "item 1_2",
+          "order": "a2",
+          "parentID": "item-1_1",
+        },
+      ]
+    `)
+  })
+
+  test("can move an item to root", () => {
+    const result = moveItems("item-1_1", null, items, "id", "parentID")
+
+    if (E.isLeft(result)) {
+      console.log(result.left)
+      throw new Error("SOMETHING WENT WRONG WHILE REORDERING")
+    }
+
+    expect(sortByOrder(result.right.filter((item) => item.parentID === null)))
+      .toMatchInlineSnapshot(`
+      [
+        {
+          "id": "item-1",
+          "name": "item 1",
+          "order": "a0",
+          "parentID": null,
+        },
+        {
+          "id": "item-2",
+          "name": "item 2",
+          "order": "a1",
+          "parentID": null,
+        },
+        {
+          "id": "item-1_1",
+          "name": "item 1_1",
+          "order": "a2",
+          "parentID": null,
+        },
+      ]
+    `)
+
+    expect(
+      sortByOrder(result.right.filter((item) => item.parentID === "item-1"))
+    ).toMatchInlineSnapshot(`
+      [
+        {
+          "id": "item-1_2",
+          "name": "item 1_2",
+          "order": "a1",
+          "parentID": "item-1",
+        },
+        {
+          "id": "item-1_3",
+          "name": "item 1_3",
+          "order": "a2",
+          "parentID": "item-1",
+        },
+        {
+          "id": "item-1_4",
+          "name": "item 1_4",
+          "order": "a3",
+          "parentID": "item-1",
+        },
+      ]
+    `)
+  })
+})

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

@@ -1,5 +1,8 @@
-import { beforeAll, describe, expect, test, vi } from "vitest"
-import { TeamsWorkspaceProviderService } from "./../teams.workspace"
+import { beforeAll, beforeEach, describe, expect, test, vi } from "vitest"
+import {
+  sortByOrder,
+  TeamsWorkspaceProviderService,
+} from "./../teams.workspace"
 import * as E from "fp-ts/Either"
 import * as E from "fp-ts/Either"
 import { TestContainer } from "dioc/testing"
 import { TestContainer } from "dioc/testing"
 import {
 import {
@@ -8,6 +11,7 @@ import {
   updateTeamCollection,
   updateTeamCollection,
   deleteCollection,
   deleteCollection,
   moveRESTTeamCollection,
   moveRESTTeamCollection,
+  updateOrderRESTTeamCollection,
 } from "~/helpers/backend/mutations/TeamCollection"
 } from "~/helpers/backend/mutations/TeamCollection"
 
 
 import * as TE from "fp-ts/TaskEither"
 import * as TE from "fp-ts/TaskEither"
@@ -20,7 +24,10 @@ import {
   GetCollectionRequestsQuery,
   GetCollectionRequestsQuery,
   GetMyTeamsQuery,
   GetMyTeamsQuery,
   MoveRestTeamCollectionMutation,
   MoveRestTeamCollectionMutation,
+  MoveRestTeamRequestMutation,
   RootCollectionsOfTeamQuery,
   RootCollectionsOfTeamQuery,
+  UpdateCollectionOrderMutation,
+  UpdateLookUpRequestOrderMutation,
   UpdateRequestMutation,
   UpdateRequestMutation,
   UpdateTeamCollectionMutation,
   UpdateTeamCollectionMutation,
 } from "~/helpers/backend/graphql"
 } from "~/helpers/backend/graphql"
@@ -30,6 +37,8 @@ import {
   createRequestInCollection,
   createRequestInCollection,
   updateTeamRequest,
   updateTeamRequest,
   deleteTeamRequest,
   deleteTeamRequest,
+  moveRESTTeamRequest,
+  updateOrderRESTTeamRequest,
 } from "~/helpers/backend/mutations/TeamRequest"
 } from "~/helpers/backend/mutations/TeamRequest"
 import {
 import {
   getDefaultRESTRequest,
   getDefaultRESTRequest,
@@ -65,6 +74,7 @@ vi.mock("./../../../../helpers/backend/mutations/TeamCollection", () => {
     updateTeamCollection: vi.fn(),
     updateTeamCollection: vi.fn(),
     deleteCollection: vi.fn(),
     deleteCollection: vi.fn(),
     moveRESTTeamCollection: vi.fn(),
     moveRESTTeamCollection: vi.fn(),
+    updateOrderRESTTeamCollection: vi.fn(),
   }
   }
 })
 })
 
 
@@ -73,6 +83,8 @@ vi.mock("./../../../../helpers/backend/mutations/TeamRequest", () => {
     createRequestInCollection: vi.fn(),
     createRequestInCollection: vi.fn(),
     updateTeamRequest: vi.fn(),
     updateTeamRequest: vi.fn(),
     deleteTeamRequest: vi.fn(),
     deleteTeamRequest: vi.fn(),
+    moveRESTTeamRequest: vi.fn(),
+    updateOrderRESTTeamRequest: vi.fn(),
   }
   }
 })
 })
 
 
@@ -1476,14 +1488,17 @@ describe("TeamsWorkspaceProviderService", () => {
     `)
     `)
   })
   })
 
 
-  describe("move rest collections", () => {
+  describe("move + reorder", () => {
     // todo: abstract the vars like this for all the tests
     // todo: abstract the vars like this for all the tests
     let sampleWorkspace: Handle<Workspace>
     let sampleWorkspace: Handle<Workspace>
     let teamsWorkspaceProviderService: TeamsWorkspaceProviderService
     let teamsWorkspaceProviderService: TeamsWorkspaceProviderService
 
 
-    beforeAll(async () => {
+    beforeEach(async () => {
       mockFetchAllTeams()
       mockFetchAllTeams()
       mockMoveTeamCollection()
       mockMoveTeamCollection()
+      mockMoveTeamRequest()
+      mockUpdateOrderRESTTeamCollection()
+      mockUpdateOrderRESTTeamRequest()
 
 
       const container = new TestContainer()
       const container = new TestContainer()
       teamsWorkspaceProviderService = container.bind(
       teamsWorkspaceProviderService = container.bind(
@@ -1500,7 +1515,7 @@ describe("TeamsWorkspaceProviderService", () => {
       seedCollectionsForMovingReorderingExporting(teamsWorkspaceProviderService)
       seedCollectionsForMovingReorderingExporting(teamsWorkspaceProviderService)
     })
     })
 
 
-    test.only("root collection to root collection", async () => {
+    test("root collection to root collection", async () => {
       const sourceCollectionHandle =
       const sourceCollectionHandle =
         await teamsWorkspaceProviderService.getCollectionHandle(
         await teamsWorkspaceProviderService.getCollectionHandle(
           sampleWorkspace,
           sampleWorkspace,
@@ -1511,7 +1526,7 @@ describe("TeamsWorkspaceProviderService", () => {
         throw new Error("FAILED_TO_GET_SOURCE_COLLECTION")
         throw new Error("FAILED_TO_GET_SOURCE_COLLECTION")
       }
       }
 
 
-      teamsWorkspaceProviderService.moveRESTCollection(
+      await teamsWorkspaceProviderService.moveRESTCollection(
         sourceCollectionHandle.right,
         sourceCollectionHandle.right,
         "root_collection_0"
         "root_collection_0"
       )
       )
@@ -1522,8 +1537,415 @@ describe("TeamsWorkspaceProviderService", () => {
           (collection) => collection.parentCollectionID === "root_collection_0"
           (collection) => collection.parentCollectionID === "root_collection_0"
         )
         )
 
 
-      expect(childrenAfterMoving).toMatchInlineSnapshot()
+      const rootCollectionsAfterMoving =
+        teamsWorkspaceProviderService.collections.value.filter(
+          (collection) => !collection.parentCollectionID
+        )
+
+      // no more root_collection_1 here, because we moved it
+      expect(rootCollectionsAfterMoving).toMatchInlineSnapshot(`
+        [
+          {
+            "auth": {
+              "authActive": true,
+              "authType": "inherit",
+            },
+            "collectionID": "root_collection_0",
+            "headers": [],
+            "name": "Root Collection 0",
+            "order": "a0",
+            "providerID": "TEAMS_WORKSPACE_PROVIDER",
+            "workspaceID": "workspace_id_0",
+          },
+        ]
+      `)
+
+      // can find the root_collection_1 as the child of root_collection_0
+      expect(childrenAfterMoving).toMatchInlineSnapshot(`
+        [
+          {
+            "auth": {
+              "authActive": true,
+              "authType": "inherit",
+            },
+            "collectionID": "child_collection_0_0",
+            "headers": [],
+            "name": "Child Collection 0 0",
+            "order": "a0",
+            "parentCollectionID": "root_collection_0",
+            "providerID": "TEAMS_WORKSPACE_PROVIDER",
+            "workspaceID": "workspace_id_0",
+          },
+          {
+            "auth": {
+              "authActive": true,
+              "authType": "inherit",
+            },
+            "collectionID": "child_collection_0_1",
+            "headers": [],
+            "name": "Child Collection 0 1",
+            "order": "a1",
+            "parentCollectionID": "root_collection_0",
+            "providerID": "TEAMS_WORKSPACE_PROVIDER",
+            "workspaceID": "workspace_id_0",
+          },
+          {
+            "auth": {
+              "authActive": true,
+              "authType": "inherit",
+            },
+            "collectionID": "child_collection_0_2",
+            "headers": [],
+            "name": "Child Collection 0 2",
+            "order": "a2",
+            "parentCollectionID": "root_collection_0",
+            "providerID": "TEAMS_WORKSPACE_PROVIDER",
+            "workspaceID": "workspace_id_0",
+          },
+          {
+            "auth": {
+              "authActive": true,
+              "authType": "inherit",
+            },
+            "collectionID": "root_collection_1",
+            "headers": [],
+            "name": "Root Collection 1",
+            "order": "a3",
+            "parentCollectionID": "root_collection_0",
+            "providerID": "TEAMS_WORKSPACE_PROVIDER",
+            "workspaceID": "workspace_id_0",
+          },
+        ]
+      `)
     })
     })
+
+    test("child collection to root collection", async () => {
+      const sourceCollectionHandle =
+        await teamsWorkspaceProviderService.getCollectionHandle(
+          sampleWorkspace,
+          "child_collection_0_1"
+        )
+
+      if (E.isLeft(sourceCollectionHandle)) {
+        throw new Error("FAILED_TO_GET_SOURCE_COLLECTION")
+      }
+
+      await teamsWorkspaceProviderService.moveRESTCollection(
+        sourceCollectionHandle.right,
+        "root_collection_1"
+      )
+
+      // accessing for tests, otherwise it's a private property
+      const childrenAfterMoving =
+        teamsWorkspaceProviderService.collections.value.filter(
+          (collection) => collection.parentCollectionID === "root_collection_1"
+        )
+
+      const sourceCollectionSiblingsAfterMoving =
+        teamsWorkspaceProviderService.collections.value.filter(
+          (col) => col.parentCollectionID === "root_collection_0"
+        )
+
+      expect(childrenAfterMoving).toMatchInlineSnapshot(`
+        [
+          {
+            "auth": {
+              "authActive": true,
+              "authType": "inherit",
+            },
+            "collectionID": "child_collection_0_1",
+            "headers": [],
+            "name": "Child Collection 0 1",
+            "order": "a3",
+            "parentCollectionID": "root_collection_1",
+            "providerID": "TEAMS_WORKSPACE_PROVIDER",
+            "workspaceID": "workspace_id_0",
+          },
+          {
+            "auth": {
+              "authActive": true,
+              "authType": "inherit",
+            },
+            "collectionID": "child_collection_1_0",
+            "headers": [],
+            "name": "Child Collection 1 0",
+            "order": "a0",
+            "parentCollectionID": "root_collection_1",
+            "providerID": "TEAMS_WORKSPACE_PROVIDER",
+            "workspaceID": "workspace_id_0",
+          },
+          {
+            "auth": {
+              "authActive": true,
+              "authType": "inherit",
+            },
+            "collectionID": "child_collection_1_1",
+            "headers": [],
+            "name": "Child Collection 1 1",
+            "order": "a1",
+            "parentCollectionID": "root_collection_1",
+            "providerID": "TEAMS_WORKSPACE_PROVIDER",
+            "workspaceID": "workspace_id_0",
+          },
+          {
+            "auth": {
+              "authActive": true,
+              "authType": "inherit",
+            },
+            "collectionID": "child_collection_1_2",
+            "headers": [],
+            "name": "Child Collection 1 2",
+            "order": "a2",
+            "parentCollectionID": "root_collection_1",
+            "providerID": "TEAMS_WORKSPACE_PROVIDER",
+            "workspaceID": "workspace_id_0",
+          },
+        ]
+      `)
+
+      expect(sourceCollectionSiblingsAfterMoving).toMatchInlineSnapshot(`
+        [
+          {
+            "auth": {
+              "authActive": true,
+              "authType": "inherit",
+            },
+            "collectionID": "child_collection_0_0",
+            "headers": [],
+            "name": "Child Collection 0 0",
+            "order": "a0",
+            "parentCollectionID": "root_collection_0",
+            "providerID": "TEAMS_WORKSPACE_PROVIDER",
+            "workspaceID": "workspace_id_0",
+          },
+          {
+            "auth": {
+              "authActive": true,
+              "authType": "inherit",
+            },
+            "collectionID": "child_collection_0_2",
+            "headers": [],
+            "name": "Child Collection 0 2",
+            "order": "a2",
+            "parentCollectionID": "root_collection_0",
+            "providerID": "TEAMS_WORKSPACE_PROVIDER",
+            "workspaceID": "workspace_id_0",
+          },
+        ]
+      `)
+    })
+
+    test.only("move a request to another collection", async () => {
+      const sourceRequestHandle =
+        await teamsWorkspaceProviderService.getRequestHandle(
+          sampleWorkspace,
+          "request_0_0"
+        )
+
+      if (E.isLeft(sourceRequestHandle)) {
+        throw new Error("FAILED_TO_GET_SOURCE_REQUEST")
+      }
+
+      const res = await teamsWorkspaceProviderService.moveRESTRequest(
+        sourceRequestHandle.right,
+        "child_collection_1_0"
+      )
+
+      if (E.isLeft(res)) {
+        throw new Error("FAILED_TO_MOVE_REQUEST")
+      }
+
+      const requestsAfterMoving =
+        teamsWorkspaceProviderService.requests.value.filter(
+          (collection) => collection.collectionID === "child_collection_1_0"
+        )
+
+      const sourceRequestSiblingsAfterMoving =
+        teamsWorkspaceProviderService.requests.value.filter(
+          (req) => req.collectionID === "root_collection_0"
+        )
+
+      expect(
+        sortByOrder(
+          requestsAfterMoving.map((item) => {
+            return {
+              collectionID: item.collectionID,
+              order: item.order,
+              providerID: item.providerID,
+              workspaceID: item.workspaceID,
+              requestID: item.requestID,
+            }
+          })
+        )
+      ).toMatchInlineSnapshot(`
+        [
+          {
+            "collectionID": "child_collection_1_0",
+            "order": "a0",
+            "providerID": "TEAMS_WORKSPACE_PROVIDER",
+            "requestID": "nested_request_1_0_0",
+            "workspaceID": "workspace_id_0",
+          },
+          {
+            "collectionID": "child_collection_1_0",
+            "order": "a1",
+            "providerID": "TEAMS_WORKSPACE_PROVIDER",
+            "requestID": "request_0_0",
+            "workspaceID": "workspace_id_0",
+          },
+        ]
+      `)
+
+      expect(
+        sortByOrder(
+          sourceRequestSiblingsAfterMoving.map((item) => {
+            return {
+              collectionID: item.collectionID,
+              order: item.order,
+              providerID: item.providerID,
+              workspaceID: item.workspaceID,
+              requestID: item.requestID,
+            }
+          })
+        )
+      ).toMatchInlineSnapshot(`
+        [
+          {
+            "collectionID": "root_collection_0",
+            "order": "a1",
+            "providerID": "TEAMS_WORKSPACE_PROVIDER",
+            "requestID": "request_0_1",
+            "workspaceID": "workspace_id_0",
+          },
+        ]
+      `)
+    })
+
+    test("reorder a collection", async () => {
+      const sourceCollectionHandle =
+        await teamsWorkspaceProviderService.getCollectionHandle(
+          sampleWorkspace,
+          "child_collection_0_1"
+        )
+
+      if (E.isLeft(sourceCollectionHandle)) {
+        throw new Error("FAILED_TO_GET_SOURCE_COLLECTION")
+      }
+
+      const res = await teamsWorkspaceProviderService.reorderRESTCollection(
+        sourceCollectionHandle.right,
+        "child_collection_0_0"
+      )
+
+      if (E.isLeft(res)) {
+        throw new Error("FAILED_TO_REORDER_COLLECTION")
+      }
+
+      const childrenAfterReordering =
+        teamsWorkspaceProviderService.collections.value.filter(
+          (collection) => collection.parentCollectionID === "root_collection_0"
+        )
+
+      expect(sortByOrder(childrenAfterReordering)).toMatchInlineSnapshot(`
+        [
+          {
+            "auth": {
+              "authActive": true,
+              "authType": "inherit",
+            },
+            "collectionID": "child_collection_0_1",
+            "headers": [],
+            "name": "Child Collection 0 1",
+            "order": "Zz",
+            "parentCollectionID": "root_collection_0",
+            "providerID": "TEAMS_WORKSPACE_PROVIDER",
+            "workspaceID": "workspace_id_0",
+          },
+          {
+            "auth": {
+              "authActive": true,
+              "authType": "inherit",
+            },
+            "collectionID": "child_collection_0_0",
+            "headers": [],
+            "name": "Child Collection 0 0",
+            "order": "a0",
+            "parentCollectionID": "root_collection_0",
+            "providerID": "TEAMS_WORKSPACE_PROVIDER",
+            "workspaceID": "workspace_id_0",
+          },
+          {
+            "auth": {
+              "authActive": true,
+              "authType": "inherit",
+            },
+            "collectionID": "child_collection_0_2",
+            "headers": [],
+            "name": "Child Collection 0 2",
+            "order": "a2",
+            "parentCollectionID": "root_collection_0",
+            "providerID": "TEAMS_WORKSPACE_PROVIDER",
+            "workspaceID": "workspace_id_0",
+          },
+        ]
+      `)
+    })
+
+    test("reorder a request", async () => {
+      const sourceRequestHandle =
+        await teamsWorkspaceProviderService.getRequestHandle(
+          sampleWorkspace,
+          "request_0_0"
+        )
+
+      if (E.isLeft(sourceRequestHandle)) {
+        throw new Error("FAILED_TO_GET_SOURCE_REQUEST")
+      }
+
+      const res = await teamsWorkspaceProviderService.reorderRESTRequest(
+        sourceRequestHandle.right,
+        "root_collection_0",
+        null
+      )
+
+      if (E.isLeft(res)) {
+        throw new Error("FAILED_TO_REORDER_REQUEST")
+      }
+
+      const requestsAfterReordering =
+        teamsWorkspaceProviderService.requests.value.filter(
+          (collection) => collection.collectionID === "root_collection_0"
+        )
+
+      expect(
+        sortByOrder(requestsAfterReordering).map((req) => ({
+          collectionID: req.collectionID,
+          order: req.order,
+          providerID: req.providerID,
+          requestID: req.requestID,
+          workspaceID: req.workspaceID,
+        }))
+      ).toMatchInlineSnapshot(`
+        [
+          {
+            "collectionID": "root_collection_0",
+            "order": "a1",
+            "providerID": "TEAMS_WORKSPACE_PROVIDER",
+            "requestID": "request_0_1",
+            "workspaceID": "workspace_id_0",
+          },
+          {
+            "collectionID": "root_collection_0",
+            "order": "a2",
+            "providerID": "TEAMS_WORKSPACE_PROVIDER",
+            "requestID": "request_0_0",
+            "workspaceID": "workspace_id_0",
+          },
+        ]
+      `)
+    })
+
+    // skipping detailed tests, because reorderItems + moveItems, the methods used in reorders and moves are already tested in a separate test suite
   })
   })
 })
 })
 
 
@@ -1845,6 +2267,32 @@ const mockMoveTeamCollection = () => {
   })
   })
 }
 }
 
 
+const mockMoveTeamRequest = () => {
+  return vi.mocked(moveRESTTeamRequest).mockImplementation(() => {
+    return TE.right(<MoveRestTeamRequestMutation>{
+      moveRequest: {
+        id: "whatever",
+      },
+    })
+  })
+}
+
+const mockUpdateOrderRESTTeamCollection = () => {
+  return vi.mocked(updateOrderRESTTeamCollection).mockImplementation(() => {
+    return TE.right(<UpdateCollectionOrderMutation>{
+      updateCollectionOrder: true,
+    })
+  })
+}
+
+const mockUpdateOrderRESTTeamRequest = () => {
+  return vi.mocked(updateOrderRESTTeamRequest).mockImplementation(() => {
+    return TE.right(<UpdateLookUpRequestOrderMutation>{
+      updateLookUpRequestOrder: true,
+    })
+  })
+}
+
 const seedCollectionsForMovingReorderingExporting = (
 const seedCollectionsForMovingReorderingExporting = (
   teamsWorkspaceProviderService: TeamsWorkspaceProviderService
   teamsWorkspaceProviderService: TeamsWorkspaceProviderService
 ) => {
 ) => {
@@ -1874,9 +2322,6 @@ const seedCollectionsForMovingReorderingExporting = (
    *    - request_1_2
    *    - request_1_2
    */
    */
 
 
-  // test cases
-  // 1. move root collection 1 to root collection 0
-
   teamsWorkspaceProviderService._setCollections([
   teamsWorkspaceProviderService._setCollections([
     {
     {
       collectionID: "root_collection_0",
       collectionID: "root_collection_0",
@@ -2033,4 +2478,79 @@ const seedCollectionsForMovingReorderingExporting = (
       parentCollectionID: "root_collection_1",
       parentCollectionID: "root_collection_1",
     },
     },
   ])
   ])
+
+  teamsWorkspaceProviderService._setRequests([
+    {
+      requestID: "request_0_0",
+      collectionID: "root_collection_0",
+      providerID: "TEAMS_WORKSPACE_PROVIDER",
+      order: "a0",
+      request: getDefaultRESTRequest(),
+      workspaceID: "workspace_id_0",
+    },
+    {
+      requestID: "request_0_1",
+      collectionID: "root_collection_0",
+      providerID: "TEAMS_WORKSPACE_PROVIDER",
+      order: "a1",
+      request: getDefaultRESTRequest(),
+      workspaceID: "workspace_id_0",
+    },
+    {
+      requestID: "nested_request_0_0_0",
+      collectionID: "child_collection_0_0",
+      providerID: "TEAMS_WORKSPACE_PROVIDER",
+      order: "a0",
+      request: getDefaultRESTRequest(),
+      workspaceID: "workspace_id_0",
+    },
+    {
+      requestID: "nested_request_0_0_1",
+      collectionID: "child_collection_0_0",
+      providerID: "TEAMS_WORKSPACE_PROVIDER",
+      order: "a1",
+      request: getDefaultRESTRequest(),
+      workspaceID: "workspace_id_0",
+    },
+    {
+      requestID: "request_1_0",
+      collectionID: "root_collection_1",
+      providerID: "TEAMS_WORKSPACE_PROVIDER",
+      order: "a0",
+      request: getDefaultRESTRequest(),
+      workspaceID: "workspace_id_0",
+    },
+    {
+      requestID: "request_1_1",
+      collectionID: "root_collection_1",
+      providerID: "TEAMS_WORKSPACE_PROVIDER",
+      order: "a1",
+      request: getDefaultRESTRequest(),
+      workspaceID: "workspace_id_0",
+    },
+    {
+      requestID: "request_1_2",
+      collectionID: "root_collection_1",
+      providerID: "TEAMS_WORKSPACE_PROVIDER",
+      order: "a2",
+      request: getDefaultRESTRequest(),
+      workspaceID: "workspace_id_0",
+    },
+    {
+      requestID: "nested_request_1_0_0",
+      collectionID: "child_collection_1_0",
+      providerID: "TEAMS_WORKSPACE_PROVIDER",
+      order: "a0",
+      request: getDefaultRESTRequest(),
+      workspaceID: "workspace_id_0",
+    },
+    {
+      requestID: "nested_nested_request_1_0_0_0",
+      collectionID: "nested_child_collection_1_0_0",
+      providerID: "TEAMS_WORKSPACE_PROVIDER",
+      order: "a0",
+      request: getDefaultRESTRequest(),
+      workspaceID: "workspace_id_0",
+    },
+  ])
 }
 }

+ 140 - 87
packages/hoppscotch-common/src/services/new-workspace/providers/teams.workspace.ts

@@ -23,14 +23,17 @@ import {
   updateTeamCollection,
   updateTeamCollection,
   deleteCollection,
   deleteCollection,
   moveRESTTeamCollection,
   moveRESTTeamCollection,
+  updateOrderRESTTeamCollection,
 } from "~/helpers/backend/mutations/TeamCollection"
 } from "~/helpers/backend/mutations/TeamCollection"
 import {
 import {
   createRequestInCollection,
   createRequestInCollection,
   updateTeamRequest,
   updateTeamRequest,
   deleteTeamRequest,
   deleteTeamRequest,
+  moveRESTTeamRequest,
+  updateOrderRESTTeamRequest,
 } from "~/helpers/backend/mutations/TeamRequest"
 } from "~/helpers/backend/mutations/TeamRequest"
 import { createTeam } from "~/helpers/backend/mutations/Team"
 import { createTeam } from "~/helpers/backend/mutations/Team"
-import { Ref, computed, ref, watch } from "vue"
+import { Ref, computed, ref } from "vue"
 import {
 import {
   RESTCollectionChildrenView,
   RESTCollectionChildrenView,
   RESTCollectionJSONView,
   RESTCollectionJSONView,
@@ -330,6 +333,11 @@ export class TeamsWorkspaceProviderService
     this.collections.value = collections
     this.collections.value = collections
   }
   }
 
 
+  // for testing purposes
+  _setRequests(requests: TeamsWorkspaceRequest[]) {
+    this.requests.value = requests
+  }
+
   async createRESTChildCollection(
   async createRESTChildCollection(
     parentCollectionHandle: Handle<WorkspaceCollection>,
     parentCollectionHandle: Handle<WorkspaceCollection>,
     newChildCollection: Partial<HoppCollection> & { name: string }
     newChildCollection: Partial<HoppCollection> & { name: string }
@@ -1345,7 +1353,6 @@ export class TeamsWorkspaceProviderService
     })
     })
   }
   }
 
 
-  // TODO: right now you're not calling the BE for this akash, include it later
   async moveRESTCollection(
   async moveRESTCollection(
     collectionHandle: Handle<WorkspaceCollection>,
     collectionHandle: Handle<WorkspaceCollection>,
     destinationCollectionID: string | null
     destinationCollectionID: string | null
@@ -1374,33 +1381,26 @@ export class TeamsWorkspaceProviderService
       return E.left(moveRES.left)
       return E.left(moveRES.left)
     }
     }
 
 
-    // find the sibling collections, and move the collection to the end of that collection
-    // also consider the destinationCollectionID being null, in that case, move it to the root
-    const siblingCollections = this.collections.value.filter(
-      (collection) => collection.parentCollectionID === destinationCollectionID
+    const localMoveRES = moveItems(
+      collection.collectionID,
+      destinationCollectionID,
+      // TODO: undefined v/s null thing, fix later
+      this.collections.value,
+      "collectionID",
+      "parentCollectionID"
     )
     )
 
 
-    const lastSibling = siblingCollections.at(-1)
-
-    const order = generateKeyBetween(lastSibling?.order, null)
-
-    // TODO: check this type error
-    this.collections.value = this.collections.value.map((col) => {
-      if (col.collectionID === collection.collectionID) {
-        return {
-          ...col,
-          parentCollectionID: destinationCollectionID ?? undefined,
-          order,
-        }
-      }
+    if (E.isLeft(localMoveRES)) {
+      return E.left(localMoveRES.left)
+    }
 
 
-      return col
-    })
+    // TODO: for now casting, make sure to prevent type widening when passing collections to moveItems
+    this.collections.value = localMoveRES.right as TeamsWorkspaceCollection[]
 
 
-    return Promise.resolve(E.right(undefined))
+    return E.right(undefined)
   }
   }
 
 
-  moveRESTRequest(
+  async moveRESTRequest(
     requestHandle: Handle<WorkspaceRequest>,
     requestHandle: Handle<WorkspaceRequest>,
     destinationCollectionID: string
     destinationCollectionID: string
   ): Promise<E.Either<unknown, void>> {
   ): Promise<E.Either<unknown, void>> {
@@ -1427,30 +1427,33 @@ export class TeamsWorkspaceProviderService
       return Promise.resolve(E.left("DESTINATION_COLLECTION_DOES_NOT_EXIST"))
       return Promise.resolve(E.left("DESTINATION_COLLECTION_DOES_NOT_EXIST"))
     }
     }
 
 
-    const siblingRequests = this.requests.value.filter(
-      (request) => request.collectionID === destinationCollectionID
-    )
+    const moveRES = await moveRESTTeamRequest(
+      requestHandleRef.value.data.requestID,
+      destinationCollectionID
+    )()
 
 
-    const lastSibling = siblingRequests.at(-1)
+    if (E.isLeft(moveRES)) {
+      return E.left(moveRES.left)
+    }
 
 
-    const order = generateKeyBetween(lastSibling?.order, null)
+    const localMoveRES = moveItems(
+      request.requestID,
+      destinationCollectionID,
+      this.requests.value,
+      "requestID",
+      "collectionID"
+    )
 
 
-    this.requests.value = this.requests.value.map((req) => {
-      if (req.requestID === request.requestID) {
-        return {
-          ...req,
-          collectionID: destinationCollectionID,
-          order,
-        }
-      }
+    if (E.isLeft(localMoveRES)) {
+      return E.left(localMoveRES.left)
+    }
 
 
-      return req
-    })
+    this.requests.value = localMoveRES.right
 
 
     return Promise.resolve(E.right(undefined))
     return Promise.resolve(E.right(undefined))
   }
   }
 
 
-  reorderRESTCollection(
+  async reorderRESTCollection(
     collectionHandle: Handle<WorkspaceCollection>,
     collectionHandle: Handle<WorkspaceCollection>,
     destinationCollectionID: string | null
     destinationCollectionID: string | null
   ): Promise<E.Either<unknown, void>> {
   ): Promise<E.Either<unknown, void>> {
@@ -1469,14 +1472,18 @@ export class TeamsWorkspaceProviderService
       return Promise.resolve(E.left("COLLECTION_DOES_NOT_EXIST" as const))
       return Promise.resolve(E.left("COLLECTION_DOES_NOT_EXIST" as const))
     }
     }
 
 
-    const nextCollection = this.collections.value.find(
-      (collection) => collection.collectionID === destinationCollectionID
-    )
-
-    const reorderOperation = reorderItemsWithoutChangingParent(
+    const reorderRes = await updateOrderRESTTeamCollection(
       collection.collectionID,
       collection.collectionID,
-      nextCollection?.collectionID ?? null,
+      destinationCollectionID
+    )()
 
 
+    if (E.isLeft(reorderRes)) {
+      return reorderRes
+    }
+
+    const reorderOperation = reorderItems(
+      collection.collectionID,
+      destinationCollectionID,
       // TODO: undefined v/s null thing, fix later
       // TODO: undefined v/s null thing, fix later
       this.orderedCollections.value,
       this.orderedCollections.value,
       "collectionID",
       "collectionID",
@@ -1487,13 +1494,14 @@ export class TeamsWorkspaceProviderService
       return Promise.resolve(reorderOperation)
       return Promise.resolve(reorderOperation)
     }
     }
 
 
-    // TODO: might be due to figuring out the return type. fix later
-    this.collections.value = reorderOperation.right
+    // TODO: for now casting, make sure to prevent type widening when passing collections to moveItems
+    this.collections.value =
+      reorderOperation.right as TeamsWorkspaceCollection[]
 
 
     return Promise.resolve(E.right(undefined))
     return Promise.resolve(E.right(undefined))
   }
   }
 
 
-  reorderRESTRequest(
+  async reorderRESTRequest(
     requestHandle: Handle<WorkspaceRequest>,
     requestHandle: Handle<WorkspaceRequest>,
     destinationCollectionID: string,
     destinationCollectionID: string,
     destinationRequestID: string | null
     destinationRequestID: string | null
@@ -1512,25 +1520,31 @@ export class TeamsWorkspaceProviderService
       return Promise.resolve(E.left("REQUEST_DOES_NOT_EXIST" as const))
       return Promise.resolve(E.left("REQUEST_DOES_NOT_EXIST" as const))
     }
     }
 
 
-    const nextRequest = this.requests.value.find(
-      (request) => request.requestID === destinationRequestID
-    )
+    const reorderRes = await updateOrderRESTTeamRequest(
+      request.requestID,
+      destinationRequestID,
+      destinationCollectionID
+    )()
+
+    if (E.isLeft(reorderRes)) {
+      return reorderRes
+    }
 
 
-    const reorderOperation = reorderItemsWithoutChangingParent(
+    const localReorderRes = reorderItems(
       request.requestID,
       request.requestID,
-      nextRequest?.requestID ?? null,
-      this.orderedRequests.value,
+      destinationRequestID,
+      this.requests.value,
       "requestID",
       "requestID",
       "collectionID"
       "collectionID"
     )
     )
 
 
-    if (E.isLeft(reorderOperation)) {
-      return Promise.resolve(reorderOperation)
+    if (E.isLeft(localReorderRes)) {
+      return Promise.resolve(localReorderRes)
     }
     }
 
 
-    this.requests.value = reorderOperation.right
+    this.requests.value = localReorderRes.right
 
 
-    return Promise.resolve(E.right(undefined))
+    return E.right(undefined)
   }
   }
 
 
   // this might be temporary, might move this to decor
   // this might be temporary, might move this to decor
@@ -1836,7 +1850,7 @@ export class TeamsWorkspaceProviderService
 
 
       const { request, nextRequest } = result.right.requestOrderUpdated
       const { request, nextRequest } = result.right.requestOrderUpdated
 
 
-      const reorderOperation = reorderItemsWithoutChangingParent(
+      const reorderOperation = reorderItems(
         request.id,
         request.id,
         nextRequest?.id ?? null,
         nextRequest?.id ?? null,
         this.orderedRequests.value,
         this.orderedRequests.value,
@@ -2058,7 +2072,8 @@ const testProvider = async () => {
 
 
 window.testProvider = testProvider
 window.testProvider = testProvider
 
 
-const reorderItemsWithoutChangingParent = <
+// TODO: throw an error if source and destination doesnt have the same parent
+export const reorderItems = <
   ParentIDKey extends keyof Reorderable,
   ParentIDKey extends keyof Reorderable,
   IDKey extends keyof Reorderable,
   IDKey extends keyof Reorderable,
   Reorderable extends { order: string } & {
   Reorderable extends { order: string } & {
@@ -2079,54 +2094,92 @@ const reorderItemsWithoutChangingParent = <
     return E.left("SOURCE_ITEM_NOT_FOUND_WHILE_REORDERING")
     return E.left("SOURCE_ITEM_NOT_FOUND_WHILE_REORDERING")
   }
   }
 
 
-  let destinationItem: Reorderable | undefined
-  let destinationOrder: string | null = null
+  const siblingItems = sortByOrder(
+    items.filter((item) => item[parentIDKey] === sourceItem[parentIDKey])
+  )
+
+  let previousItem: Reorderable | undefined
+  let nextItem: Reorderable | undefined
 
 
-  if (destinationItemID) {
-    destinationItem = items.find((item) => item[idKey] === destinationItemID)
+  if (!destinationItemID) {
+    previousItem = siblingItems.at(-1)
+  } else {
+    const destinationIndex = siblingItems.findIndex(
+      (item) => item[idKey] === destinationItemID
+    )
 
 
-    if (!destinationItem) {
+    if (!destinationIndex && destinationIndex !== 0) {
       return E.left("DESTINATION_ITEM_NOT_FOUND_WHILE_REORDERING")
       return E.left("DESTINATION_ITEM_NOT_FOUND_WHILE_REORDERING")
     }
     }
 
 
-    destinationOrder = destinationItem.order
+    previousItem = siblingItems[destinationIndex - 1]
+    nextItem = siblingItems[destinationIndex]
   }
   }
 
 
-  const siblingItems = items.filter(
-    (item) => item[parentIDKey] === sourceItem[parentIDKey]
+  const newOrder = generateKeyBetween(
+    previousItem?.order ?? null,
+    nextItem?.order ?? null
   )
   )
 
 
-  const previousItem = (() => {
-    // if the destination order is null, we're moving the collection to the end of the list
-    if (destinationOrder === null) {
-      return E.right(siblingItems.at(-1))
-    }
-
-    const destinationCollection = siblingItems.find(
-      (collection) => collection[idKey] === destinationItemID
+  return E.right(
+    items.map((item) =>
+      item[idKey] === sourceItemID
+        ? {
+            ...item,
+            order: newOrder,
+          }
+        : item
     )
     )
+  )
+}
 
 
-    if (!destinationCollection) {
-      return E.left("DESTINATION_ITEM_NOT_FOUND")
-    }
+export const moveItems = <
+  ParentIDKey extends keyof Reorderable,
+  IDKey extends keyof Reorderable,
+  Reorderable extends { order: string } & {
+    [key in ParentIDKey]: string | null
+  } & {
+    [key in IDKey]: string
+  },
+>(
+  sourceItemID: string,
+  destinationParentID: string | null,
+  items: Reorderable[],
+  idKey: IDKey,
+  parentIDKey: ParentIDKey
+): E.Either<
+  | "SOURCE_ITEM_NOT_FOUND_WHILE_MOVING"
+  | "DESTINATION_PARENT_NOT_FOUND_WHILE_MOVING",
+  Reorderable[]
+> => {
+  const destinationParent = items.find(
+    (item) => item[idKey] === destinationParentID
+  )
+
+  if (!destinationParent && destinationParentID) {
+    return E.left("DESTINATION_PARENT_NOT_FOUND_WHILE_MOVING")
+  }
 
 
-    return E.right(destinationCollection)
-  })()
+  const sourceItem = items.find((item) => item[idKey] === sourceItemID)
 
 
-  if (E.isLeft(previousItem)) {
-    return previousItem
+  if (!sourceItem) {
+    return E.left("SOURCE_ITEM_NOT_FOUND_WHILE_MOVING")
   }
   }
 
 
-  const newOrder = generateKeyBetween(
-    previousItem.right?.order ?? null,
-    destinationItem?.order ?? null
+  const siblingItems = sortByOrder(
+    items.filter((item) => item[parentIDKey] === destinationParentID)
   )
   )
 
 
+  const lastSibling = siblingItems.at(-1)
+
+  const newOrder = generateKeyBetween(lastSibling?.order, null)
+
   return E.right(
   return E.right(
     items.map((item) =>
     items.map((item) =>
       item[idKey] === sourceItemID
       item[idKey] === sourceItemID
         ? {
         ? {
             ...item,
             ...item,
+            [parentIDKey]: destinationParentID,
             order: newOrder,
             order: newOrder,
           }
           }
         : item
         : item
@@ -2134,7 +2187,7 @@ const reorderItemsWithoutChangingParent = <
   )
   )
 }
 }
 
 
-const sortByOrder = <OrderedItem extends { order: string }>(
+export const sortByOrder = <OrderedItem extends { order: string }>(
   items: OrderedItem[]
   items: OrderedItem[]
 ) => {
 ) => {
   return items.sort((item1, item2) => {
   return items.sort((item1, item2) => {