From 6f65f199034936fbf8385593dfd27a06fcca42bd Mon Sep 17 00:00:00 2001
From: Deepika Guliani <dguliani@gitlab.com>
Date: Wed, 18 Dec 2024 11:09:33 +0000
Subject: [PATCH] Show Related MR's in dev widget with deduplication

Changelog: added
---
 .../javascripts/graphql_shared/constants.js   |   1 +
 .../work_item_development.vue                 |  51 +++++-
 ...ork_item_development_relationship_list.vue |  49 ++---
 .../graphql/merge_request.fragment.graphql    |  39 ++++
 .../work_item_development.fragment.graphql    |  26 +++
 .../work_item_development.query.graphql       |  16 ++
 ...work_item_development.subscription.graphql |  16 ++
 .../work_item_widgets.fragment.graphql        |  51 ------
 .../work_item_development.fragment.graphql    |  35 ++++
 .../work_item_widgets.fragment.graphql        |  61 -------
 .../work_item_development_spec.js             | 168 +++++++++---------
 .../work_items/work_item_detail_spec.rb       |   1 +
 ...item_development_relationship_list_spec.js |  22 ++-
 .../work_item_development_spec.js             | 136 ++++++--------
 spec/frontend/work_items/mock_data.js         |  67 ++++++-
 .../work_items/work_items_shared_examples.rb  |   2 +
 16 files changed, 422 insertions(+), 319 deletions(-)
 create mode 100644 app/assets/javascripts/work_items/graphql/merge_request.fragment.graphql
 create mode 100644 app/assets/javascripts/work_items/graphql/work_item_development.fragment.graphql
 create mode 100644 app/assets/javascripts/work_items/graphql/work_item_development.query.graphql
 create mode 100644 app/assets/javascripts/work_items/graphql/work_item_development.subscription.graphql
 create mode 100644 ee/app/assets/javascripts/work_items/graphql/work_item_development.fragment.graphql

diff --git a/app/assets/javascripts/graphql_shared/constants.js b/app/assets/javascripts/graphql_shared/constants.js
index 681a8f371b2aa..6e8f75426835c 100644
--- a/app/assets/javascripts/graphql_shared/constants.js
+++ b/app/assets/javascripts/graphql_shared/constants.js
@@ -34,6 +34,7 @@ export const TYPENAME_TODO = 'Todo';
 export const TYPENAME_USER = 'User';
 export const TYPENAME_VULNERABILITY = 'Vulnerability';
 export const TYPENAME_WORK_ITEM = 'WorkItem';
+export const TYPENAME_WORK_ITEM_RELATED_BRANCH = 'WorkItemRelatedBranch';
 export const TYPE_ORGANIZATION = 'Organizations::Organization';
 export const TYPE_USERS_SAVED_REPLY = 'Users::SavedReply';
 export const TYPE_WORKSPACE = 'RemoteDevelopment::Workspace';
diff --git a/app/assets/javascripts/work_items/components/work_item_development/work_item_development.vue b/app/assets/javascripts/work_items/components/work_item_development/work_item_development.vue
index c484d6e73a395..6465f6391f393 100644
--- a/app/assets/javascripts/work_items/components/work_item_development/work_item_development.vue
+++ b/app/assets/javascripts/work_items/components/work_item_development/work_item_development.vue
@@ -6,6 +6,8 @@ import { s__, __ } from '~/locale';
 import { findWidget } from '~/issues/list/utils';
 
 import workItemByIidQuery from '~/work_items/graphql/work_item_by_iid.query.graphql';
+import workItemDevelopmentQuery from '~/work_items/graphql/work_item_development.query.graphql';
+import workItemDevelopmentUpdatedSubscription from '~/work_items/graphql/work_item_development.subscription.graphql';
 import {
   sprintfWorkItem,
   WIDGET_TYPE_DEVELOPMENT,
@@ -78,6 +80,7 @@ export default {
     return {
       error: undefined,
       workItem: {},
+      workItemDevelopment: {},
       showCreateBranchAndMrModal: false,
       showBranchFlow: true,
       showMergeRequestFlow: false,
@@ -95,16 +98,18 @@ export default {
     workItemTypeName() {
       return this.workItem?.workItemType?.name;
     },
-    workItemDevelopment() {
-      return findWidget(WIDGET_TYPE_DEVELOPMENT, this.workItem);
-    },
     isLoading() {
-      return this.$apollo.queries.workItem.loading;
+      return (
+        this.$apollo.queries.workItem.loading || this.$apollo.queries.workItemDevelopment.loading
+      );
     },
     willAutoCloseByMergeRequest() {
       return this.workItemDevelopment?.willAutoCloseByMergeRequest;
     },
-    linkedMergeRequests() {
+    relatedMergeRequests() {
+      return this.workItemDevelopment?.relatedMergeRequests?.nodes || [];
+    },
+    closingMergeRequests() {
       return this.workItemDevelopment?.closingMergeRequests?.nodes || [];
     },
     featureFlags() {
@@ -119,18 +124,19 @@ export default {
     isRelatedDevelopmentListEmpty() {
       return (
         !this.error &&
-        this.linkedMergeRequests.length === 0 &&
+        this.relatedMergeRequests.length === 0 &&
+        this.closingMergeRequests.length === 0 &&
         this.featureFlags.length === 0 &&
         this.relatedBranches.length === 0
       );
     },
     showAutoCloseInformation() {
       return (
-        this.linkedMergeRequests.length > 0 && this.willAutoCloseByMergeRequest && !this.isLoading
+        this.closingMergeRequests.length > 0 && this.willAutoCloseByMergeRequest && !this.isLoading
       );
     },
     openStateText() {
-      return this.linkedMergeRequests.length > 1
+      return this.closingMergeRequests.length > 1
         ? sprintfWorkItem(this.$options.i18n.openStateText, this.workItemTypeName)
         : sprintfWorkItem(
             this.$options.i18n.openStateWithOneMergeRequestText,
@@ -204,6 +210,35 @@ export default {
         this.error = e.message || this.$options.i18n.fetchError;
       },
     },
+    workItemDevelopment: {
+      query: workItemDevelopmentQuery,
+      variables() {
+        return {
+          id: this.workItemId,
+        };
+      },
+      update(data) {
+        return findWidget(WIDGET_TYPE_DEVELOPMENT, data?.workItem) || {};
+      },
+      skip() {
+        return !this.workItemIid;
+      },
+      error(e) {
+        this.$emit('error', this.$options.i18n.fetchError);
+        this.error = e.message || this.$options.i18n.fetchError;
+      },
+      subscribeToMore: {
+        document: workItemDevelopmentUpdatedSubscription,
+        variables() {
+          return {
+            id: this.workItem.id,
+          };
+        },
+        skip() {
+          return !this.workItem?.id;
+        },
+      },
+    },
   },
   methods: {
     openModal(createBranch = true, createMergeRequest = false) {
diff --git a/app/assets/javascripts/work_items/components/work_item_development/work_item_development_relationship_list.vue b/app/assets/javascripts/work_items/components/work_item_development/work_item_development_relationship_list.vue
index e792034830678..2a2119e3be8c5 100644
--- a/app/assets/javascripts/work_items/components/work_item_development/work_item_development_relationship_list.vue
+++ b/app/assets/javascripts/work_items/components/work_item_development/work_item_development_relationship_list.vue
@@ -1,8 +1,11 @@
 <script>
 import { GlButton } from '@gitlab/ui';
-import { uniqueId } from 'lodash';
-import { renderGFM } from '~/behaviors/markdown/render_gfm';
-import { TYPENAME_FEATURE_FLAG } from '~/graphql_shared/constants';
+import { unionBy, uniqueId, map } from 'lodash';
+import {
+  TYPENAME_FEATURE_FLAG,
+  TYPENAME_MERGE_REQUEST,
+  TYPENAME_WORK_ITEM_RELATED_BRANCH,
+} from '~/graphql_shared/constants';
 
 import WorkItemDevelopmentMrItem from './work_item_development_mr_item.vue';
 import WorkItemDevelopmentBranchItem from './work_item_development_branch_item.vue';
@@ -31,10 +34,20 @@ export default {
     list() {
       return [...this.sortedFeatureFlags, ...this.mergeRequests, ...this.relatedBranches];
     },
+    mergeRequests() {
+      return unionBy(
+        map(this.closingMergeRequests, 'mergeRequest'),
+        this.relatedMergeRequests,
+        'id',
+      );
+    },
     relatedBranches() {
       return this.workItemDevWidget.relatedBranches?.nodes || [];
     },
-    mergeRequests() {
+    relatedMergeRequests() {
+      return this.workItemDevWidget.relatedMergeRequests?.nodes || [];
+    },
+    closingMergeRequests() {
       return this.workItemDevWidget.closingMergeRequests?.nodes || [];
     },
     featureFlags() {
@@ -48,10 +61,6 @@ export default {
       return [...enabledFlags, ...disabledFlags];
     },
   },
-  mounted() {
-    // render the popovers of the merge requests
-    renderGFM(this.$refs['list-body']);
-  },
   methods: {
     itemComponent(item) {
       let component;
@@ -68,7 +77,8 @@ export default {
       return component;
     },
     isMergeRequest(item) {
-      return item.fromMrDescription !== undefined;
+      // eslint-disable-next-line no-underscore-dangle
+      return item.__typename === TYPENAME_MERGE_REQUEST;
     },
     isFeatureFlag(item) {
       // eslint-disable-next-line no-underscore-dangle
@@ -76,31 +86,28 @@ export default {
     },
     isBranch(item) {
       // eslint-disable-next-line no-underscore-dangle
-      return item.__typename === 'WorkItemRelatedBranch';
-    },
-    async toggleShowLess() {
-      this.showLess = !this.showLess;
-      await this.$nextTick();
-      renderGFM(this.$refs['list-body']);
+      return item.__typename === TYPENAME_WORK_ITEM_RELATED_BRANCH;
     },
     itemId(item) {
-      return item?.id || item?.mergeRequest?.id || uniqueId('branch-id-');
-    },
-    itemObject(item) {
-      return this.isMergeRequest(item) ? item.mergeRequest : item;
+      return item?.id || uniqueId('branch-id-');
     },
   },
 };
 </script>
 <template>
   <div>
-    <ul ref="list-body" class="gl-m-0 gl-list-none gl-p-0" data-testid="work-item-dev-items-list">
+    <ul
+      ref="list-body"
+      class="gl-m-0 gl-list-none gl-p-0"
+      data-testid="work-item-dev-items-list"
+      :data-list-length="list.length"
+    >
       <li
         v-for="item in list"
         :key="itemId(item)"
         class="gl-border-b gl-py-4 first:!gl-pt-0 last:gl-border-none last:!gl-pb-0"
       >
-        <component :is="itemComponent(item)" :item-content="itemObject(item)" :is-modal="isModal" />
+        <component :is="itemComponent(item)" :item-content="item" :is-modal="isModal" />
       </li>
     </ul>
   </div>
diff --git a/app/assets/javascripts/work_items/graphql/merge_request.fragment.graphql b/app/assets/javascripts/work_items/graphql/merge_request.fragment.graphql
new file mode 100644
index 0000000000000..ce132e5f378de
--- /dev/null
+++ b/app/assets/javascripts/work_items/graphql/merge_request.fragment.graphql
@@ -0,0 +1,39 @@
+#import "~/work_items/graphql/milestone.fragment.graphql"
+
+fragment MergeRequestFragment on MergeRequest {
+  id
+  iid
+  title
+  webUrl
+  state
+  sourceBranch
+  reference
+  headPipeline {
+    id
+    detailedStatus {
+      id
+      icon
+      text
+      detailsPath
+    }
+  }
+  milestone {
+    ...MilestoneFragment
+  }
+  project {
+    id
+    name
+    namespace {
+      path
+    }
+  }
+  assignees {
+    nodes {
+      webUrl
+      id
+      name
+      webPath
+      avatarUrl
+    }
+  }
+}
diff --git a/app/assets/javascripts/work_items/graphql/work_item_development.fragment.graphql b/app/assets/javascripts/work_items/graphql/work_item_development.fragment.graphql
new file mode 100644
index 0000000000000..267e83b7338ee
--- /dev/null
+++ b/app/assets/javascripts/work_items/graphql/work_item_development.fragment.graphql
@@ -0,0 +1,26 @@
+#import "~/work_items/graphql/merge_request.fragment.graphql"
+
+fragment WorkItemDevelopmentFragment on WorkItemWidgetDevelopment {
+  type
+  willAutoCloseByMergeRequest
+  relatedBranches {
+    nodes {
+      name
+      comparePath
+    }
+  }
+  relatedMergeRequests {
+    nodes {
+      ...MergeRequestFragment
+    }
+  }
+  closingMergeRequests {
+    nodes {
+      id
+      fromMrDescription
+      mergeRequest {
+        ...MergeRequestFragment
+      }
+    }
+  }
+}
diff --git a/app/assets/javascripts/work_items/graphql/work_item_development.query.graphql b/app/assets/javascripts/work_items/graphql/work_item_development.query.graphql
new file mode 100644
index 0000000000000..14943d1251a94
--- /dev/null
+++ b/app/assets/javascripts/work_items/graphql/work_item_development.query.graphql
@@ -0,0 +1,16 @@
+#import "ee_else_ce/work_items/graphql/work_item_development.fragment.graphql"
+
+query workItemDevelopment($id: WorkItemID!) {
+  workItem(id: $id) {
+    id
+    iid
+    namespace {
+      id
+    }
+    widgets {
+      ... on WorkItemWidgetDevelopment {
+        ...WorkItemDevelopmentFragment
+      }
+    }
+  }
+}
diff --git a/app/assets/javascripts/work_items/graphql/work_item_development.subscription.graphql b/app/assets/javascripts/work_items/graphql/work_item_development.subscription.graphql
new file mode 100644
index 0000000000000..2a8454bad3f30
--- /dev/null
+++ b/app/assets/javascripts/work_items/graphql/work_item_development.subscription.graphql
@@ -0,0 +1,16 @@
+#import "ee_else_ce/work_items/graphql/work_item_development.fragment.graphql"
+
+subscription workItemDevelopmentUpdated($id: WorkItemID!) {
+  workItemUpdated(workItemId: $id) {
+    id
+    iid
+    namespace {
+      id
+    }
+    widgets {
+      ... on WorkItemWidgetDevelopment {
+        ...WorkItemDevelopmentFragment
+      }
+    }
+  }
+}
diff --git a/app/assets/javascripts/work_items/graphql/work_item_widgets.fragment.graphql b/app/assets/javascripts/work_items/graphql/work_item_widgets.fragment.graphql
index 5899a3094dcfe..523947fee0f17 100644
--- a/app/assets/javascripts/work_items/graphql/work_item_widgets.fragment.graphql
+++ b/app/assets/javascripts/work_items/graphql/work_item_widgets.fragment.graphql
@@ -93,57 +93,6 @@ fragment WorkItemWidgets on WorkItemWidget {
       }
     }
   }
-  ... on WorkItemWidgetDevelopment {
-    type
-    willAutoCloseByMergeRequest
-    relatedBranches {
-      nodes {
-        name
-        comparePath
-      }
-    }
-    closingMergeRequests {
-      nodes {
-        fromMrDescription
-        mergeRequest {
-          iid
-          id
-          title
-          webUrl
-          state
-          sourceBranch
-          reference
-          headPipeline {
-            detailedStatus {
-              id
-              icon
-              text
-              detailsPath
-            }
-          }
-          milestone {
-            ...MilestoneFragment
-          }
-          project {
-            id
-            name
-            namespace {
-              path
-            }
-          }
-          assignees {
-            nodes {
-              webUrl
-              id
-              name
-              webPath
-              avatarUrl
-            }
-          }
-        }
-      }
-    }
-  }
   ... on WorkItemWidgetCrmContacts {
     contacts {
       nodes {
diff --git a/ee/app/assets/javascripts/work_items/graphql/work_item_development.fragment.graphql b/ee/app/assets/javascripts/work_items/graphql/work_item_development.fragment.graphql
new file mode 100644
index 0000000000000..c9410eb244d56
--- /dev/null
+++ b/ee/app/assets/javascripts/work_items/graphql/work_item_development.fragment.graphql
@@ -0,0 +1,35 @@
+#import "~/work_items/graphql/merge_request.fragment.graphql"
+
+fragment WorkItemDevelopmentFragment on WorkItemWidgetDevelopment {
+  type
+  willAutoCloseByMergeRequest
+  featureFlags {
+    nodes {
+      id
+      active
+      name
+      path
+      reference
+    }
+  }
+  relatedBranches {
+    nodes {
+      name
+      comparePath
+    }
+  }
+  relatedMergeRequests {
+    nodes {
+      ...MergeRequestFragment
+    }
+  }
+  closingMergeRequests {
+    nodes {
+      id
+      fromMrDescription
+      mergeRequest {
+        ...MergeRequestFragment
+      }
+    }
+  }
+}
diff --git a/ee/app/assets/javascripts/work_items/graphql/work_item_widgets.fragment.graphql b/ee/app/assets/javascripts/work_items/graphql/work_item_widgets.fragment.graphql
index cfc5e388ee9ea..153dc31a9674e 100644
--- a/ee/app/assets/javascripts/work_items/graphql/work_item_widgets.fragment.graphql
+++ b/ee/app/assets/javascripts/work_items/graphql/work_item_widgets.fragment.graphql
@@ -135,67 +135,6 @@ fragment WorkItemWidgets on WorkItemWidget {
     textColor
   }
 
-  ... on WorkItemWidgetDevelopment {
-    type
-    willAutoCloseByMergeRequest
-    relatedBranches {
-      nodes {
-        name
-        comparePath
-      }
-    }
-    featureFlags {
-      nodes {
-        id
-        active
-        name
-        path
-        reference
-      }
-    }
-    closingMergeRequests {
-      nodes {
-        fromMrDescription
-        mergeRequest {
-          iid
-          id
-          title
-          webUrl
-          state
-          sourceBranch
-          reference
-          headPipeline {
-            detailedStatus {
-              id
-              icon
-              text
-              detailsPath
-            }
-          }
-          milestone {
-            ...MilestoneFragment
-          }
-          project {
-            id
-            name
-            namespace {
-              path
-            }
-          }
-          assignees {
-            nodes {
-              webUrl
-              id
-              name
-              webPath
-              avatarUrl
-            }
-          }
-        }
-      }
-    }
-  }
-
   ... on WorkItemWidgetLinkedItems {
     linkedItems {
       nodes {
diff --git a/ee/spec/frontend/work_items/components/work_item_development/work_item_development_spec.js b/ee/spec/frontend/work_items/components/work_item_development/work_item_development_spec.js
index 5d5e1918872f2..861abf025e59b 100644
--- a/ee/spec/frontend/work_items/components/work_item_development/work_item_development_spec.js
+++ b/ee/spec/frontend/work_items/components/work_item_development/work_item_development_spec.js
@@ -1,16 +1,17 @@
 import Vue from 'vue';
-import MockAdapter from 'axios-mock-adapter';
 import VueApollo from 'vue-apollo';
-import axios from 'axios';
-import { HTTP_STATUS_OK } from '~/lib/utils/http_status';
+import { map } from 'lodash';
 import { mountExtended, shallowMountExtended } from 'helpers/vue_test_utils_helper';
 import createMockApollo from 'helpers/mock_apollo_helper';
 import { createMockDirective } from 'helpers/vue_mock_directive';
 import workItemByIidQuery from '~/work_items/graphql/work_item_by_iid.query.graphql';
+import workItemDevelopmentQuery from '~/work_items/graphql/work_item_development.query.graphql';
+import workItemDevelopmentUpdatedSubscription from '~/work_items/graphql/work_item_development.subscription.graphql';
 import waitForPromises from 'helpers/wait_for_promises';
 
 import {
-  workItemResponseFactory,
+  workItemByIidResponseFactory,
+  workItemDevelopmentResponse,
   workItemDevelopmentFragmentResponse,
   workItemDevelopmentMRNodes,
   workItemDevelopmentFeatureFlagNodes,
@@ -29,110 +30,100 @@ describe('WorkItemDevelopment EE', () => {
 
   let wrapper;
   let mockApollo;
-  let mock;
 
-  const workItemWithMRListOnly = workItemResponseFactory({
-    developmentWidgetPresent: true,
+  const workItemSuccessQueryHandler = jest
+    .fn()
+    .mockResolvedValue(workItemByIidResponseFactory({ canUpdate: true }));
+
+  const devWidgetWithMRListOnly = workItemDevelopmentResponse({
     developmentItems: workItemDevelopmentFragmentResponse({
       mrNodes: workItemDevelopmentMRNodes,
       willAutoCloseByMergeRequest: true,
       featureFlagNodes: [],
       branchNodes: [],
+      relatedMergeRequests: [],
     }),
   });
 
-  const workItemWithFlagListOnly = workItemResponseFactory({
-    developmentWidgetPresent: true,
+  const devWidgetWithFlagListOnly = workItemDevelopmentResponse({
     developmentItems: workItemDevelopmentFragmentResponse({
       mrNodes: [],
       willAutoCloseByMergeRequest: false,
       featureFlagNodes: workItemDevelopmentFeatureFlagNodes,
       branchNodes: [],
+      relatedMergeRequests: [],
     }),
-    canUpdate: true,
   });
 
-  const workItemWithBranchListOnly = workItemResponseFactory({
-    developmentWidgetPresent: true,
+  const devWidgetWithBranchListOnly = workItemDevelopmentResponse({
     developmentItems: workItemDevelopmentFragmentResponse({
       mrNodes: [],
       willAutoCloseByMergeRequest: false,
       featureFlagNodes: [],
       branchNodes: workItemRelatedBranchNodes,
+      relatedMergeRequests: [],
+    }),
+  });
+
+  const devWidgetWithRelatedMRListOnly = workItemDevelopmentResponse({
+    developmentItems: workItemDevelopmentFragmentResponse({
+      mrNodes: [],
+      willAutoCloseByMergeRequest: false,
+      featureFlagNodes: [],
+      branchNodes: [],
+      relatedMergeRequests: map(workItemDevelopmentMRNodes, 'mergeRequest'),
     }),
-    canUpdate: true,
   });
 
-  const workItemWithNoDevItems = workItemResponseFactory({
-    developmentWidgetPresent: true,
+  const devWidgetWithNoDevItems = workItemDevelopmentResponse({
     developmentItems: workItemDevelopmentFragmentResponse({
       mrNodes: [],
       willAutoCloseByMergeRequest: false,
       featureFlagNodes: [],
       branchNodes: [],
+      relatedMergeRequests: [],
     }),
-    canUpdate: true,
   });
 
-  const workItemWithAllDevItems = workItemResponseFactory({
-    developmentWidgetPresent: true,
+  const devWidgetWithWithAllDevItems = workItemDevelopmentResponse({
     developmentItems: workItemDevelopmentFragmentResponse({
       mrNodes: workItemDevelopmentMRNodes,
       willAutoCloseByMergeRequest: true,
       featureFlagNodes: workItemDevelopmentFeatureFlagNodes,
       branchNodes: workItemRelatedBranchNodes,
+      relatedMergeRequests: map(workItemDevelopmentMRNodes, 'mergeRequest'),
     }),
   });
 
-  const successQueryHandler = jest.fn().mockResolvedValue({
-    data: {
-      workspace: {
-        __typename: 'Project',
-        id: 'gid://gitlab/Project/1',
-        workItem: workItemWithFlagListOnly.data.workItem,
-      },
-    },
-  });
+  const devWidgetsuccessQueryHandler = jest.fn().mockResolvedValue(devWidgetWithMRListOnly);
 
-  const successQueryHandlerWithOnlyMRList = jest.fn().mockResolvedValue({
-    data: {
-      workspace: {
-        __typename: 'Project',
-        id: 'gid://gitlab/Project/1',
-        workItem: workItemWithMRListOnly.data.workItem,
-      },
-    },
-  });
+  const devWidgetSuccessQueryHandlerWithOnlyMRList = jest
+    .fn()
+    .mockResolvedValue(devWidgetWithMRListOnly);
 
-  const successQueryHandlerWithOnlyBranchList = jest.fn().mockResolvedValue({
-    data: {
-      workspace: {
-        __typename: 'Project',
-        id: 'gid://gitlab/Project/1',
-        workItem: workItemWithBranchListOnly.data.workItem,
-      },
-    },
-  });
+  const devWidgetSuccessQueryHandlerWithFlagListOnly = jest
+    .fn()
+    .mockResolvedValue(devWidgetWithFlagListOnly);
 
-  const successQueryHandlerWithNoDevItem = jest.fn().mockResolvedValue({
-    data: {
-      workspace: {
-        __typename: 'Project',
-        id: 'gid://gitlab/Project/1',
-        workItem: workItemWithNoDevItems.data.workItem,
-      },
-    },
-  });
+  const devWidgetSuccessQueryHandlerWithOnlyRelatedMRList = jest
+    .fn()
+    .mockResolvedValue(devWidgetWithRelatedMRListOnly);
 
-  const successQueryHandlerWithAllDevItemsList = jest.fn().mockResolvedValue({
-    data: {
-      workspace: {
-        __typename: 'Project',
-        id: 'gid://gitlab/Project/1',
-        workItem: workItemWithAllDevItems.data.workItem,
-      },
-    },
-  });
+  const devWidgetSuccessQueryHandlerWithOnlyBranchList = jest
+    .fn()
+    .mockResolvedValue(devWidgetWithBranchListOnly);
+
+  const devWidgetSuccessQueryHandlerWithNoDevItem = jest
+    .fn()
+    .mockResolvedValue(devWidgetWithNoDevItems);
+
+  const devWidgetSuccessQueryHandlerWithAllDevItemsList = jest
+    .fn()
+    .mockResolvedValue(devWidgetWithWithAllDevItems);
+
+  const workItemDevelopmentUpdatedSubscriptionHandler = jest
+    .fn()
+    .mockResolvedValue({ data: { workItemUpdated: null } });
 
   const createComponent = ({
     mountFn = mountExtended,
@@ -140,10 +131,15 @@ describe('WorkItemDevelopment EE', () => {
     workItemIid = '1',
     workItemFullPath = 'full-path',
     workItemType = 'Issue',
-    workItemQueryHandler = successQueryHandler,
+    workItemQueryHandler = workItemSuccessQueryHandler,
     workItemsAlphaEnabled = true,
+    workItemDevelopmentQueryHandler = devWidgetsuccessQueryHandler,
   } = {}) => {
-    mockApollo = createMockApollo([[workItemByIidQuery, workItemQueryHandler]]);
+    mockApollo = createMockApollo([
+      [workItemByIidQuery, workItemQueryHandler],
+      [workItemDevelopmentQuery, workItemDevelopmentQueryHandler],
+      [workItemDevelopmentUpdatedSubscription, workItemDevelopmentUpdatedSubscriptionHandler],
+    ]);
 
     wrapper = mountFn(WorkItemDevelopment, {
       apolloProvider: mockApollo,
@@ -172,23 +168,9 @@ describe('WorkItemDevelopment EE', () => {
   const findCreateMRButton = () => wrapper.findByTestId('create-mr-button');
   const findCreateBranchButton = () => wrapper.findByTestId('create-branch-button');
 
-  beforeEach(() => {
-    mock = new MockAdapter(axios);
-    mock.onGet('/full-path/-/issues/1/can_create_branch').reply(HTTP_STATUS_OK, {
-      can_create_branch: true,
-      suggested_branch_name: 'suggested_branch_name',
-    });
-    return createComponent();
-  });
-
-  afterEach(() => {
-    mock.restore();
-  });
-
   describe('when the list of MRs is empty but there is a Feature Flag list', () => {
     it(`hides 'Create MR' and 'Create branch' buttons when flag enabled`, async () => {
       createComponent({
-        workItemQueryHandler: successQueryHandler,
         workItemsAlphaEnabled: true,
       });
       await waitForPromises();
@@ -199,7 +181,6 @@ describe('WorkItemDevelopment EE', () => {
 
     it(`hides 'Create MR' and 'Create branch' buttons when flag disabled`, async () => {
       createComponent({
-        workItemQueryHandler: successQueryHandler,
         workItemsAlphaEnabled: false,
       });
       await waitForPromises();
@@ -212,7 +193,7 @@ describe('WorkItemDevelopment EE', () => {
   describe('when the list of Feature Flag is empty but there is a MR list', () => {
     it(`hides 'Create MR' and 'Create branch' buttons when flag enabled`, async () => {
       createComponent({
-        workItemQueryHandler: successQueryHandlerWithOnlyMRList,
+        workItemDevelopmentQueryHandler: devWidgetSuccessQueryHandlerWithOnlyMRList,
         workItemsAlphaEnabled: true,
       });
       await waitForPromises();
@@ -223,7 +204,7 @@ describe('WorkItemDevelopment EE', () => {
 
     it(`hides 'Create MR' and 'Create branch' buttons when flag disabled`, async () => {
       createComponent({
-        workItemQueryHandler: successQueryHandlerWithOnlyMRList,
+        workItemDevelopmentQueryHandler: devWidgetSuccessQueryHandlerWithOnlyMRList,
         workItemsAlphaEnabled: false,
       });
       await waitForPromises();
@@ -236,7 +217,7 @@ describe('WorkItemDevelopment EE', () => {
   describe('when both the list of Feature flags and MRs are empty', () => {
     it(`hides 'Create MR' and 'Create branch' buttons when flag disabled`, async () => {
       createComponent({
-        workItemQueryHandler: successQueryHandlerWithNoDevItem,
+        workItemDevelopmentQueryHandler: devWidgetSuccessQueryHandlerWithFlagListOnly,
         workItemsAlphaEnabled: false,
       });
       await waitForPromises();
@@ -249,7 +230,7 @@ describe('WorkItemDevelopment EE', () => {
   describe('when both the list of Feature flags and MRs exist', () => {
     it(`hides 'Create MR' and 'Create branch' buttons when flag disabled`, async () => {
       createComponent({
-        workItemQueryHandler: successQueryHandlerWithAllDevItemsList,
+        workItemDevelopmentQueryHandler: devWidgetSuccessQueryHandlerWithAllDevItemsList,
         workItemsAlphaEnabled: false,
       });
       await waitForPromises();
@@ -259,17 +240,28 @@ describe('WorkItemDevelopment EE', () => {
     });
   });
 
+  it('should not show the widget when any of the dev item is not available', async () => {
+    createComponent({
+      mountFn: shallowMountExtended,
+      workItemDevelopmentQueryHandler: devWidgetSuccessQueryHandlerWithNoDevItem,
+    });
+    await waitForPromises();
+
+    expect(findRelationshipList().exists()).toBe(false);
+  });
+
   it.each`
     description        | successQueryResolveHandler
-    ${'feature flags'} | ${successQueryHandler}
-    ${'MRs'}           | ${successQueryHandlerWithOnlyMRList}
-    ${'branches'}      | ${successQueryHandlerWithOnlyBranchList}
+    ${'feature flags'} | ${devWidgetSuccessQueryHandlerWithFlagListOnly}
+    ${'MRs'}           | ${devWidgetSuccessQueryHandlerWithOnlyMRList}
+    ${'branches'}      | ${devWidgetSuccessQueryHandlerWithOnlyBranchList}
+    ${'related MRs'}   | ${devWidgetSuccessQueryHandlerWithOnlyRelatedMRList}
   `(
     'should show the relationship list when there is only a list of $description',
     async ({ successQueryResolveHandler }) => {
       createComponent({
         mountFn: shallowMountExtended,
-        workItemQueryHandler: successQueryResolveHandler,
+        workItemDevelopmentQueryHandler: successQueryResolveHandler,
       });
       await waitForPromises();
 
diff --git a/spec/features/work_items/work_item_detail_spec.rb b/spec/features/work_items/work_item_detail_spec.rb
index 557783e1292bd..bb7477ac55979 100644
--- a/spec/features/work_items/work_item_detail_spec.rb
+++ b/spec/features/work_items/work_item_detail_spec.rb
@@ -106,6 +106,7 @@
   context 'for user not signed in' do
     before do
       visit work_items_path
+      wait_for_all_requests
     end
 
     it 'todos action is not displayed' do
diff --git a/spec/frontend/work_items/components/work_item_development/work_item_development_relationship_list_spec.js b/spec/frontend/work_items/components/work_item_development/work_item_development_relationship_list_spec.js
index b8fa90510c2d5..c4d5f8b9e1bb2 100644
--- a/spec/frontend/work_items/components/work_item_development/work_item_development_relationship_list_spec.js
+++ b/spec/frontend/work_items/components/work_item_development/work_item_development_relationship_list_spec.js
@@ -1,5 +1,9 @@
+import { map } from 'lodash';
 import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
-import { workItemDevelopmentFragmentResponse } from 'jest/work_items/mock_data';
+import {
+  workItemDevelopmentFragmentResponse,
+  workItemDevelopmentMRNodes,
+} from 'jest/work_items/mock_data';
 import WorkItemDevelopmentRelationshipList from '~/work_items/components/work_item_development/work_item_development_relationship_list.vue';
 
 describe('WorkItemDevelopmentRelationshipList', () => {
@@ -21,4 +25,20 @@ describe('WorkItemDevelopmentRelationshipList', () => {
       expect(findDevList().exists()).toBe(true);
     });
   });
+
+  it('deduplicates the closingMRs and relatedMRs on frontend', () => {
+    createComponent({
+      workItemDevWidget: workItemDevelopmentFragmentResponse({
+        mrNodes: workItemDevelopmentMRNodes,
+        willAutoCloseByMergeRequest: false,
+        relatedMergeRequests: map(workItemDevelopmentMRNodes, 'mergeRequest'),
+        branchNodes: [],
+        featureFlagNodes: [],
+      }),
+    });
+
+    expect(Number(findDevList().attributes('data-list-length'))).toEqual(
+      workItemDevelopmentMRNodes.length,
+    );
+  });
 });
diff --git a/spec/frontend/work_items/components/work_item_development/work_item_development_spec.js b/spec/frontend/work_items/components/work_item_development/work_item_development_spec.js
index 8247a088fc8de..42a8682cae885 100644
--- a/spec/frontend/work_items/components/work_item_development/work_item_development_spec.js
+++ b/spec/frontend/work_items/components/work_item_development/work_item_development_spec.js
@@ -9,13 +9,16 @@ import { mountExtended, shallowMountExtended } from 'helpers/vue_test_utils_help
 import createMockApollo from 'helpers/mock_apollo_helper';
 import { createMockDirective } from 'helpers/vue_mock_directive';
 import workItemByIidQuery from '~/work_items/graphql/work_item_by_iid.query.graphql';
+import workItemDevelopmentQuery from '~/work_items/graphql/work_item_development.query.graphql';
+import workItemDevelopmentUpdatedSubscription from '~/work_items/graphql/work_item_development.subscription.graphql';
 import waitForPromises from 'helpers/wait_for_promises';
 import { STATE_CLOSED, STATE_OPEN } from '~/work_items/constants';
 
 import {
-  workItemResponseFactory,
+  workItemByIidResponseFactory,
   workItemDevelopmentFragmentResponse,
   workItemDevelopmentMRNodes,
+  workItemDevelopmentResponse,
 } from 'jest/work_items/mock_data';
 
 import WorkItemDevelopment from '~/work_items/components/work_item_development/work_item_development.vue';
@@ -30,100 +33,50 @@ describe('WorkItemDevelopment CE', () => {
   let wrapper;
   let mockApollo;
 
-  const workItem = workItemResponseFactory({ developmentWidgetPresent: true, canUpdate: true });
-  const workItemWithOneMR = workItemResponseFactory({
-    developmentWidgetPresent: true,
+  const workItemSucessQueryHandler = ({ state = STATE_OPEN } = {}) => {
+    return jest.fn().mockResolvedValue(workItemByIidResponseFactory({ canUpdate: true, state }));
+  };
+
+  const devWidgetWithOneMR = workItemDevelopmentResponse({
     developmentItems: workItemDevelopmentFragmentResponse({
       mrNodes: [workItemDevelopmentMRNodes[0]],
       willAutoCloseByMergeRequest: true,
       featureFlagNodes: null,
       branchNodes: [],
+      relatedMergeRequests: [],
     }),
   });
-  const workItemWithMRList = workItemResponseFactory({
-    developmentWidgetPresent: true,
+
+  const devWidgetWithMoreThanOneMR = workItemDevelopmentResponse({
     developmentItems: workItemDevelopmentFragmentResponse({
       mrNodes: workItemDevelopmentMRNodes,
       willAutoCloseByMergeRequest: true,
       featureFlagNodes: null,
       branchNodes: [],
+      relatedMergeRequests: [],
     }),
   });
 
-  const projectWorkItemResponseWithMRList = {
-    data: {
-      workspace: {
-        __typename: 'Project',
-        id: 'gid://gitlab/Project/1',
-        workItem: workItem.data.workItem,
-      },
-    },
-  };
-
-  const closedWorkItemWithAutoCloseFlagEnabled = {
-    data: {
-      workspace: {
-        __typename: 'Project',
-        id: 'gid://gitlab/Project/1',
-        workItem: {
-          ...workItemWithMRList.data.workItem,
-          state: STATE_CLOSED,
-        },
-      },
-    },
-  };
-
-  const openWorkItemWithAutoCloseFlagEnabledAndOneMR = {
-    data: {
-      workspace: {
-        __typename: 'Project',
-        id: 'gid://gitlab/Project/1',
-        workItem: workItemWithOneMR.data.workItem,
-      },
-    },
-  };
-
-  const openWorkItemWithAutoCloseFlagEnabledAndMRList = {
-    data: {
-      workspace: {
-        __typename: 'Project',
-        id: 'gid://gitlab/Project/1',
-        workItem: workItemWithMRList.data.workItem,
-      },
-    },
-  };
-
-  const successQueryHandler = jest.fn().mockResolvedValue(projectWorkItemResponseWithMRList);
-
-  const workItemWithAutoCloseFlagEnabled = workItemResponseFactory({
-    developmentWidgetPresent: true,
+  const devWidgetWithAutoCloseDisabled = workItemDevelopmentResponse({
     developmentItems: workItemDevelopmentFragmentResponse({
       mrNodes: workItemDevelopmentMRNodes,
-      willAutoCloseByMergeRequest: true,
+      willAutoCloseByMergeRequest: false,
       featureFlagNodes: null,
       branchNodes: [],
+      relatedMergeRequests: [],
     }),
   });
 
-  const successQueryHandlerWorkItemWithAutoCloseFlagEnabled = jest.fn().mockResolvedValue({
-    data: {
-      workspace: {
-        __typename: 'Project',
-        id: 'gid://gitlab/Project/1',
-        workItem: workItemWithAutoCloseFlagEnabled.data.workItem,
-      },
-    },
-  });
-
-  const successQueryHandlerWithOneMR = jest
+  const devWidgetSuccessHandlerWithAutoCloseDisabled = jest
     .fn()
-    .mockResolvedValue(openWorkItemWithAutoCloseFlagEnabledAndOneMR);
-  const successQueryHandlerWithMRList = jest
+    .mockResolvedValue(devWidgetWithAutoCloseDisabled);
+  const devWidgetSuccessQueryHandlerWithOneMR = jest.fn().mockResolvedValue(devWidgetWithOneMR);
+  const devWidgeSuccessQueryHandlerWithMRList = jest
     .fn()
-    .mockResolvedValue(openWorkItemWithAutoCloseFlagEnabledAndMRList);
-  const successQueryHandlerWithClosedWorkItem = jest
+    .mockResolvedValue(devWidgetWithMoreThanOneMR);
+  const workItemDevelopmentUpdatedSubscriptionHandler = jest
     .fn()
-    .mockResolvedValue(closedWorkItemWithAutoCloseFlagEnabled);
+    .mockResolvedValue({ data: { workItemUpdated: null } });
 
   const createComponent = ({
     mountFn = shallowMountExtended,
@@ -131,10 +84,15 @@ describe('WorkItemDevelopment CE', () => {
     workItemIid = '1',
     workItemFullPath = 'full-path',
     workItemType = 'Issue',
-    workItemQueryHandler = successQueryHandler,
+    workItemQueryHandler = workItemSucessQueryHandler(),
     workItemsAlphaEnabled = true,
+    workItemDevelopmentQueryHandler = devWidgetSuccessQueryHandlerWithOneMR,
   } = {}) => {
-    mockApollo = createMockApollo([[workItemByIidQuery, workItemQueryHandler]]);
+    mockApollo = createMockApollo([
+      [workItemByIidQuery, workItemQueryHandler],
+      [workItemDevelopmentQuery, workItemDevelopmentQueryHandler],
+      [workItemDevelopmentUpdatedSubscription, workItemDevelopmentUpdatedSubscriptionHandler],
+    ]);
 
     wrapper = mountFn(WorkItemDevelopment, {
       apolloProvider: mockApollo,
@@ -171,6 +129,8 @@ describe('WorkItemDevelopment CE', () => {
     wrapper.findComponent(WorkItemCreateBranchMergeRequestModal);
   const findDropdownGroups = () =>
     findCreateOptionsDropdown().findAllComponents(GlDisclosureDropdownGroup);
+  const findWorkItemCreateMergeRequestModal = () =>
+    wrapper.findComponent(WorkItemCreateBranchMergeRequestModal);
 
   describe('Default', () => {
     it('should show the widget label', async () => {
@@ -186,6 +146,19 @@ describe('WorkItemDevelopment CE', () => {
 
       expect(findAddButton().exists()).toBe(true);
     });
+
+    it('does not render the modal when the queries are still loading', () => {
+      createComponent({ workItemsAlphaEnabled: true, mountFn: mountExtended });
+
+      expect(findWorkItemCreateMergeRequestModal().exists()).toBe(false);
+    });
+
+    it('renders the modal when the queries are have loaded', async () => {
+      createComponent({ workItemsAlphaEnabled: true, mountFn: mountExtended });
+      await waitForPromises();
+
+      expect(findWorkItemCreateMergeRequestModal().exists()).toBe(true);
+    });
   });
 
   describe('when the response is successful', () => {
@@ -201,7 +174,9 @@ describe('WorkItemDevelopment CE', () => {
     });
 
     it('when auto close flag is disabled, should not show the "i" indicator', async () => {
-      createComponent();
+      createComponent({
+        workItemDevelopmentQueryHandler: devWidgetSuccessHandlerWithAutoCloseDisabled,
+      });
       await waitForPromises();
 
       expect(findMoreInformation().exists()).toBe(false);
@@ -209,7 +184,7 @@ describe('WorkItemDevelopment CE', () => {
 
     it('when auto close flag is enabled, should show the "i" indicator', async () => {
       createComponent({
-        workItemQueryHandler: successQueryHandlerWorkItemWithAutoCloseFlagEnabled,
+        workItemDevelopmentQueryHandler: devWidgetSuccessQueryHandlerWithOneMR,
       });
 
       await waitForPromises();
@@ -218,15 +193,16 @@ describe('WorkItemDevelopment CE', () => {
     });
 
     it.each`
-      queryHandler                             | message                                                            | workItemState   | linkedMRsNumber
-      ${successQueryHandlerWithOneMR}          | ${'This task will be closed when the following is merged.'}        | ${STATE_OPEN}   | ${1}
-      ${successQueryHandlerWithMRList}         | ${'This task will be closed when any of the following is merged.'} | ${STATE_OPEN}   | ${workItemDevelopmentMRNodes.length}
-      ${successQueryHandlerWithClosedWorkItem} | ${'The task was closed automatically when a branch was merged.'}   | ${STATE_CLOSED} | ${workItemDevelopmentMRNodes.length}
+      developmentWidgetQueryHandler            | message                                                            | workItemState   | linkedMRsNumber
+      ${devWidgetSuccessQueryHandlerWithOneMR} | ${'This task will be closed when the following is merged.'}        | ${STATE_OPEN}   | ${1}
+      ${devWidgeSuccessQueryHandlerWithMRList} | ${'This task will be closed when any of the following is merged.'} | ${STATE_OPEN}   | ${workItemDevelopmentMRNodes.length}
+      ${devWidgeSuccessQueryHandlerWithMRList} | ${'The task was closed automatically when a branch was merged.'}   | ${STATE_CLOSED} | ${workItemDevelopmentMRNodes.length}
     `(
       'when the workItemState is `$workItemState` and number of linked MRs is `$linkedMRsNumber` shows message `$message`',
-      async ({ queryHandler, message }) => {
+      async ({ developmentWidgetQueryHandler, message, workItemState }) => {
         createComponent({
-          workItemQueryHandler: queryHandler,
+          workItemQueryHandler: workItemSucessQueryHandler({ state: workItemState }),
+          workItemDevelopmentQueryHandler: developmentWidgetQueryHandler,
         });
 
         await waitForPromises();
diff --git a/spec/frontend/work_items/mock_data.js b/spec/frontend/work_items/mock_data.js
index 8ebe0ef301ef1..b811bba467923 100644
--- a/spec/frontend/work_items/mock_data.js
+++ b/spec/frontend/work_items/mock_data.js
@@ -1,3 +1,4 @@
+import { map } from 'lodash';
 import { EMOJI_THUMBS_UP, EMOJI_THUMBS_DOWN } from '~/emoji/constants';
 import { WIDGET_TYPE_LINKED_ITEMS, NEW_WORK_ITEM_IID, STATE_CLOSED } from '~/work_items/constants';
 
@@ -938,6 +939,7 @@ export const workItemBlockedByLinkedItemsResponse = {
 
 export const workItemDevelopmentMRNodes = [
   {
+    id: 'gid://gitlab/MergeRequestsClosingIssues/61',
     fromMrDescription: true,
     mergeRequest: {
       iid: '13',
@@ -977,6 +979,7 @@ export const workItemDevelopmentMRNodes = [
     __typename: 'WorkItemClosingMergeRequest',
   },
   {
+    id: 'gid://gitlab/MergeRequestsClosingIssues/62',
     fromMrDescription: true,
     mergeRequest: {
       iid: '15',
@@ -1006,6 +1009,7 @@ export const workItemDevelopmentMRNodes = [
     __typename: 'WorkItemClosingMergeRequest',
   },
   {
+    id: 'gid://gitlab/MergeRequestsClosingIssues/63',
     fromMrDescription: true,
     mergeRequest: {
       iid: '14',
@@ -1035,6 +1039,7 @@ export const workItemDevelopmentMRNodes = [
     __typename: 'WorkItemClosingMergeRequest',
   },
   {
+    id: 'gid://gitlab/MergeRequestsClosingIssues/64',
     fromMrDescription: true,
     mergeRequest: {
       iid: '12',
@@ -1074,6 +1079,7 @@ export const workItemDevelopmentMRNodes = [
     __typename: 'WorkItemClosingMergeRequest',
   },
   {
+    id: 'gid://gitlab/MergeRequestsClosingIssues/65',
     fromMrDescription: true,
     mergeRequest: {
       iid: '11',
@@ -1186,10 +1192,15 @@ export const workItemDevelopmentFragmentResponse = ({
   willAutoCloseByMergeRequest = false,
   featureFlagNodes = workItemDevelopmentFeatureFlagNodes,
   branchNodes = workItemRelatedBranchNodes,
+  relatedMergeRequests = map(workItemDevelopmentMRNodes, 'mergeRequest'),
 } = {}) => {
   return {
     type: 'DEVELOPMENT',
     willAutoCloseByMergeRequest,
+    relatedMergeRequests: {
+      nodes: relatedMergeRequests,
+      __typename: 'MergeRequestConnection',
+    },
     featureFlags: {
       nodes: featureFlagNodes,
       __typename: 'FeatureFlagConnection',
@@ -1206,6 +1217,53 @@ export const workItemDevelopmentFragmentResponse = ({
   };
 };
 
+export const workItemDevelopmentResponse = ({
+  iid = '1',
+  id = 'gid://gitlab/WorkItem/1',
+  developmentItems,
+} = {}) => ({
+  data: {
+    workItem: {
+      __typename: 'WorkItem',
+      id,
+      iid,
+      namespace: {
+        __typename: 'Project',
+        id: '1',
+      },
+      widgets: [
+        {
+          __typename: 'WorkItemWidgetIteration',
+        },
+        {
+          __typename: 'WorkItemWidgetWeight',
+        },
+        {
+          __typename: 'WorkItemWidgetAssignees',
+        },
+        {
+          __typename: 'WorkItemWidgetLabels',
+        },
+        {
+          __typename: 'WorkItemWidgetDescription',
+        },
+        {
+          __typename: 'WorkItemWidgetHierarchy',
+        },
+        {
+          __typename: 'WorkItemWidgetStartAndDueDate',
+        },
+        {
+          __typename: 'WorkItemWidgetMilestone',
+        },
+        {
+          ...developmentItems,
+        },
+      ],
+    },
+  },
+});
+
 export const workItemResponseFactory = ({
   iid = '1',
   id = 'gid://gitlab/WorkItem/1',
@@ -1231,7 +1289,6 @@ export const workItemResponseFactory = ({
   healthStatusWidgetPresent = true,
   notesWidgetPresent = true,
   designWidgetPresent = true,
-  developmentWidgetPresent = true,
   confidential = false,
   discussionLocked = false,
   canInviteMembers = false,
@@ -1256,7 +1313,6 @@ export const workItemResponseFactory = ({
   awardEmoji = mockAwardsWidget,
   state = 'OPEN',
   linkedItems = mockEmptyLinkedItems,
-  developmentItems = workItemDevelopmentFragmentResponse(),
   color = '#1068bf',
   editableWeightWidget = true,
   hasParent = false,
@@ -1570,13 +1626,6 @@ export const workItemResponseFactory = ({
               type: 'DESIGNS',
             }
           : { type: 'MOCK TYPE' },
-        developmentWidgetPresent
-          ? {
-              ...developmentItems,
-            }
-          : {
-              type: 'MOCK TYPE',
-            },
         crmContactsWidgetPresent
           ? {
               __typename: 'WorkItemWidgetCrmContacts',
diff --git a/spec/support/shared_examples/features/work_items/work_items_shared_examples.rb b/spec/support/shared_examples/features/work_items/work_items_shared_examples.rb
index d1095cf26f95a..7fbdb52919ee8 100644
--- a/spec/support/shared_examples/features/work_items/work_items_shared_examples.rb
+++ b/spec/support/shared_examples/features/work_items/work_items_shared_examples.rb
@@ -170,6 +170,7 @@ def click_reply_and_enter_slash
     click_button 'assign yourself'
 
     expect(page).to have_link(user.name)
+    wait_for_requests
     using_session :other_session do
       expect(page).to have_link(user.name)
     end
@@ -216,6 +217,7 @@ def click_reply_and_enter_slash
     end
 
     expect(page).to have_css '.gl-label', text: label2.title
+    wait_for_requests
     using_session :other_session do
       expect(page).to have_css '.gl-label', text: label2.title
     end
-- 
GitLab