Просмотр исходного кода

Merge pull request #15800 from overleaf/ab-fix-members-table-dropdown

[web] Review conditions for displaying items in members table dropdown

GitOrigin-RevId: 897ac9a1ec01a762de6bc8ac90bb41e8980f6c15
Alexandre Bourdin 2 лет назад
Родитель
Сommit
094fa5bc38

+ 84 - 61
services/web/frontend/js/features/group-management/components/members-table/dropdown-button.tsx

@@ -14,6 +14,7 @@ import Icon from '@/shared/components/icon'
 import { ManagedUserAlert } from '../../utils/types'
 import { ManagedUserAlert } from '../../utils/types'
 import { useGroupMembersContext } from '../../context/group-members-context'
 import { useGroupMembersContext } from '../../context/group-members-context'
 import getMeta from '@/utils/meta'
 import getMeta from '@/utils/meta'
+
 type resendInviteResponse = {
 type resendInviteResponse = {
   success: boolean
   success: boolean
 }
 }
@@ -38,23 +39,22 @@ export default function DropdownButton({
     runAsync: runResendManagedUserInviteAsync,
     runAsync: runResendManagedUserInviteAsync,
     isLoading: isResendingManagedUserInvite,
     isLoading: isResendingManagedUserInvite,
   } = useAsync<resendInviteResponse>()
   } = useAsync<resendInviteResponse>()
-
-  const groupSSOActive = getMeta('ol-groupSSOActive')
-  const ssoEnabledButNotAccepted = groupSSOActive && !user.enrollment?.sso
   const {
   const {
     runAsync: runResendLinkSSOInviteAsync,
     runAsync: runResendLinkSSOInviteAsync,
     isLoading: isResendingSSOLinkInvite,
     isLoading: isResendingSSOLinkInvite,
   } = useAsync<resendInviteResponse>()
   } = useAsync<resendInviteResponse>()
-
   const {
   const {
     runAsync: runResendGroupInviteAsync,
     runAsync: runResendGroupInviteAsync,
     isLoading: isResendingGroupInvite,
     isLoading: isResendingGroupInvite,
   } = useAsync<resendInviteResponse>()
   } = useAsync<resendInviteResponse>()
 
 
-  const userPending = user.invite
+  const managedUsersActive = getMeta('ol-managedUsersActive')
+  const groupSSOActive = getMeta('ol-groupSSOActive')
 
 
-  const userNotManaged =
-    !user.isEntityAdmin && !userPending && !user.enrollment?.managedBy
+  const userPending = user.invite
+  const isGroupSSOLinked =
+    !userPending && user.enrollment?.sso?.some(sso => sso.groupId === groupId)
+  const isUserManaged = !userPending && user.enrollment?.managedBy === groupId
 
 
   const handleResendManagedUserInvite = useCallback(
   const handleResendManagedUserInvite = useCallback(
     async user => {
     async user => {
@@ -178,6 +178,82 @@ export default function DropdownButton({
     removeMember(user)
     removeMember(user)
   }
   }
 
 
+  const buttons = []
+
+  if (userPending) {
+    buttons.push(
+      <MenuItemButton
+        onClick={onResendGroupInviteClick}
+        key="resend-group-invite-action"
+        data-testid="resend-group-invite-action"
+      >
+        {t('resend_group_invite')}
+        {isResendingGroupInvite ? (
+          <Icon type="spinner" spin style={{ marginLeft: '5px' }} />
+        ) : null}
+      </MenuItemButton>
+    )
+  }
+  if (managedUsersActive && !isUserManaged) {
+    buttons.push(
+      <MenuItemButton
+        onClick={onResendManagedUserInviteClick}
+        key="resend-managed-user-invite-action"
+        data-testid="resend-managed-user-invite-action"
+      >
+        {t('resend_managed_user_invite')}
+        {isResendingManagedUserInvite ? (
+          <Icon type="spinner" spin style={{ marginLeft: '5px' }} />
+        ) : null}
+      </MenuItemButton>
+    )
+  }
+  if (groupSSOActive && !isGroupSSOLinked) {
+    buttons.push(
+      <MenuItemButton
+        onClick={onResendSSOLinkInviteClick}
+        key="resend-sso-link-invite-action"
+        data-testid="resend-sso-link-invite-action"
+      >
+        {t('resend_link_sso')}
+        {isResendingSSOLinkInvite ? (
+          <Icon type="spinner" spin style={{ marginLeft: '5px' }} />
+        ) : null}
+      </MenuItemButton>
+    )
+  }
+  if (isUserManaged && !user.isEntityAdmin) {
+    buttons.push(
+      <MenuItemButton
+        className="delete-user-action"
+        key="delete-user-action"
+        data-testid="delete-user-action"
+        onClick={onDeleteUserClick}
+      >
+        {t('delete_user')}
+      </MenuItemButton>
+    )
+  } else if (!isUserManaged) {
+    buttons.push(
+      <MenuItemButton
+        key="remove-user-action"
+        data-testid="remove-user-action"
+        onClick={onRemoveFromGroup}
+        className="delete-user-action"
+      >
+        {t('remove_from_group')}
+      </MenuItemButton>
+    )
+  }
+
+  if (buttons.length === 0) {
+    buttons.push(
+      <MenuItem key="no-actions-available" data-testid="no-actions-available">
+        <span className="text-muted">{t('no_actions')}</span>
+      </MenuItem>
+    )
+  }
+
   return (
   return (
     <span className="managed-user-actions">
     <span className="managed-user-actions">
       <Dropdown
       <Dropdown
@@ -197,60 +273,7 @@ export default function DropdownButton({
           />
           />
         </Dropdown.Toggle>
         </Dropdown.Toggle>
         <Dropdown.Menu className="dropdown-menu-right managed-user-dropdown-menu">
         <Dropdown.Menu className="dropdown-menu-right managed-user-dropdown-menu">
-          {userPending ? (
-            <MenuItemButton
-              onClick={onResendGroupInviteClick}
-              data-testid="resend-group-invite-action"
-            >
-              {t('resend_group_invite')}
-              {isResendingGroupInvite ? (
-                <Icon type="spinner" spin style={{ marginLeft: '5px' }} />
-              ) : null}
-            </MenuItemButton>
-          ) : null}
-          {userNotManaged ? (
-            <MenuItemButton
-              onClick={onResendManagedUserInviteClick}
-              data-testid="resend-managed-user-invite-action"
-            >
-              {t('resend_managed_user_invite')}
-              {isResendingManagedUserInvite ? (
-                <Icon type="spinner" spin style={{ marginLeft: '5px' }} />
-              ) : null}
-            </MenuItemButton>
-          ) : null}
-          {!userPending && ssoEnabledButNotAccepted && (
-            <MenuItemButton
-              onClick={onResendSSOLinkInviteClick}
-              data-testid="resend-sso-link-invite-action"
-            >
-              {t('resend_link_sso')}
-              {isResendingSSOLinkInvite ? (
-                <Icon type="spinner" spin style={{ marginLeft: '5px' }} />
-              ) : null}
-            </MenuItemButton>
-          )}
-          {user.isEntityAdmin ? (
-            <MenuItem data-testid="no-actions-available">
-              <span className="text-muted">{t('no_actions')}</span>
-            </MenuItem>
-          ) : user.enrollment?.managedBy ? (
-            <MenuItemButton
-              className="delete-user-action"
-              data-testid="delete-user-action"
-              onClick={onDeleteUserClick}
-            >
-              {t('delete_user')}
-            </MenuItemButton>
-          ) : (
-            <MenuItemButton
-              onClick={onRemoveFromGroup}
-              className="delete-user-action"
-              data-testid="remove-user-action"
-            >
-              {t('remove_from_group')}
-            </MenuItemButton>
-          )}
+          {buttons}
         </Dropdown.Menu>
         </Dropdown.Menu>
       </Dropdown>
       </Dropdown>
     </span>
     </span>

+ 577 - 215
services/web/test/frontend/features/group-management/components/members-table/dropdown-button.spec.tsx

@@ -30,287 +30,649 @@ function mountDropDownComponent(user: User, subscriptionId: string) {
   )
   )
 }
 }
 
 
-describe('ManagedUserDropdownButton', function () {
-  const subscriptionId = '123abc'
-
-  describe('with managed user', function () {
-    const user = {
-      _id: 'some-user',
-      email: 'some.user@example.com',
-      first_name: 'Some',
-      last_name: 'User',
-      invite: false,
-      last_active_at: new Date(),
-      enrollment: {
-        managedBy: 'some-group',
-        enrolledAt: new Date(),
-      },
-      isEntityAdmin: undefined,
-    }
+describe('DropdownButton', function () {
+  const subscriptionId = '123abc123abc'
+
+  describe('with a standard group', function () {
+    describe('for a pending user (have not joined group)', function () {
+      const user: User = {
+        _id: 'some-user',
+        email: 'some.user@example.com',
+        first_name: 'Some',
+        last_name: 'User',
+        invite: true,
+        last_active_at: new Date(),
+        enrollment: {},
+        isEntityAdmin: undefined,
+      }
+
+      beforeEach(function () {
+        cy.window().then(win => {
+          win.metaAttributesCache.set('ol-users', [user])
+        })
+
+        mountDropDownComponent(user, subscriptionId)
+      })
 
 
-    beforeEach(function () {
-      cy.window().then(win => {
-        win.metaAttributesCache.set('ol-users', [user])
+      it('should render dropdown button', function () {
+        cy.get('#managed-user-dropdown-some\\.user\\@example\\.com').should(
+          'exist'
+        )
+        cy.get(`.action-btn`).should('exist')
       })
       })
-      mountDropDownComponent(user, subscriptionId)
-    })
 
 
-    it('should render dropdown button', function () {
-      cy.get('#managed-user-dropdown-some\\.user\\@example\\.com').should(
-        'exist'
-      )
-      cy.get(`.action-btn`).should('exist')
+      it('should show the correct menu when dropdown button is clicked', function () {
+        cy.get('.action-btn').click()
+        cy.findByTestId('resend-group-invite-action').should('be.visible')
+        cy.findByTestId('remove-user-action').should('be.visible')
+
+        cy.findByTestId('no-actions-available').should('not.exist')
+      })
     })
     })
 
 
-    it('should show the correct menu when dropdown button is clicked', function () {
-      cy.get('.action-btn').click()
-      cy.findByTestId('delete-user-action').should('exist')
-      cy.findByTestId('delete-user-action').then($el => {
-        Cypress.dom.isVisible($el)
+    describe('for the group admin', function () {
+      const user: User = {
+        _id: 'some-user',
+        email: 'some.user@example.com',
+        first_name: 'Some',
+        last_name: 'User',
+        invite: false,
+        last_active_at: new Date(),
+        enrollment: {},
+        isEntityAdmin: true,
+      }
+
+      beforeEach(function () {
+        cy.window().then(win => {
+          win.metaAttributesCache.set('ol-users', [user])
+        })
+        mountDropDownComponent(user, subscriptionId)
+      })
+
+      it('should render dropdown button', function () {
+        cy.get('#managed-user-dropdown-some\\.user\\@example\\.com').should(
+          'exist'
+        )
+        cy.get(`.action-btn`).should('exist')
+      })
+
+      it('should show the correct menu when dropdown button is clicked', function () {
+        cy.get('.action-btn').click()
+
+        cy.findByTestId('remove-user-action').should('be.visible')
+
+        cy.findByTestId('no-actions-available').should('not.exist')
       })
       })
     })
     })
   })
   })
 
 
-  describe('with non-managed user (have joined group)', function () {
-    const user = {
-      _id: 'some-user',
-      email: 'some.user@example.com',
-      first_name: 'Some',
-      last_name: 'User',
-      invite: false,
-      last_active_at: new Date(),
-      enrollment: {},
-      isEntityAdmin: undefined,
-    }
-
+  describe('with Managed Users enabled', function () {
     beforeEach(function () {
     beforeEach(function () {
       cy.window().then(win => {
       cy.window().then(win => {
-        win.metaAttributesCache.set('ol-users', [user])
+        win.metaAttributesCache.set('ol-managedUsersActive', true)
+        win.metaAttributesCache.set('ol-groupSSOActive', false)
       })
       })
-
-      mountDropDownComponent(user, subscriptionId)
     })
     })
 
 
-    it('should render dropdown button', function () {
-      cy.get('#managed-user-dropdown-some\\.user\\@example\\.com').should(
-        'exist'
-      )
-      cy.get(`.action-btn`).should('exist')
-    })
+    describe('for a managed group member', function () {
+      const user: User = {
+        _id: 'some-user',
+        email: 'some.user@example.com',
+        first_name: 'Some',
+        last_name: 'User',
+        invite: false,
+        last_active_at: new Date(),
+        enrollment: {
+          managedBy: subscriptionId,
+          enrolledAt: new Date(),
+        },
+        isEntityAdmin: undefined,
+      }
+
+      beforeEach(function () {
+        cy.window().then(win => {
+          win.metaAttributesCache.set('ol-users', [user])
+        })
+        mountDropDownComponent(user, subscriptionId)
+      })
 
 
-    it('should show the correct menu when dropdown button is clicked', function () {
-      cy.get('.action-btn').click()
-      cy.findByTestId('resend-managed-user-invite-action').should('exist')
-      cy.findByTestId('resend-managed-user-invite-action').then($el => {
-        Cypress.dom.isVisible($el)
+      it('should render the dropdown button', function () {
+        cy.get('#managed-user-dropdown-some\\.user\\@example\\.com').should(
+          'exist'
+        )
+        cy.get(`.action-btn`).should('exist')
       })
       })
-      cy.findByTestId('remove-user-action').should('exist')
-      cy.findByTestId('remove-user-action').then($el => {
-        Cypress.dom.isVisible($el)
+
+      it('should show the correct menu when dropdown button is clicked', function () {
+        cy.get('.action-btn').click()
+
+        cy.findByTestId('delete-user-action').should('be.visible')
+
+        cy.findByTestId('remove-user-action').should('not.exist')
+        cy.findByTestId('resend-managed-user-invite-action').should('not.exist')
+        cy.findByTestId('resend-sso-link-invite-action').should('not.exist')
+        cy.findByTestId('no-actions-available').should('not.exist')
       })
       })
     })
     })
-  })
 
 
-  describe('with pending user (have not joined group)', function () {
-    const user = {
-      _id: 'some-user',
-      email: 'some.user@example.com',
-      first_name: 'Some',
-      last_name: 'User',
-      invite: true,
-      last_active_at: new Date(),
-      enrollment: {},
-      isEntityAdmin: undefined,
-    }
+    describe('for a non-managed group member', function () {
+      const user: User = {
+        _id: 'some-user',
+        email: 'some.user@example.com',
+        first_name: 'Some',
+        last_name: 'User',
+        invite: false,
+        last_active_at: new Date(),
+        enrollment: {},
+        isEntityAdmin: undefined,
+      }
+
+      beforeEach(function () {
+        cy.window().then(win => {
+          win.metaAttributesCache.set('ol-users', [user])
+        })
+
+        mountDropDownComponent(user, subscriptionId)
+      })
 
 
-    beforeEach(function () {
-      cy.window().then(win => {
-        win.metaAttributesCache.set('ol-users', [user])
+      it('should render dropdown button', function () {
+        cy.get('#managed-user-dropdown-some\\.user\\@example\\.com').should(
+          'exist'
+        )
+        cy.get(`.action-btn`).should('exist')
       })
       })
 
 
-      mountDropDownComponent(user, subscriptionId)
-    })
+      it('should show the correct menu when dropdown button is clicked', function () {
+        cy.get('.action-btn').click()
+
+        cy.findByTestId('resend-managed-user-invite-action').should(
+          'be.visible'
+        )
+        cy.findByTestId('remove-user-action').should('be.visible')
 
 
-    it('should render dropdown button', function () {
-      cy.get('#managed-user-dropdown-some\\.user\\@example\\.com').should(
-        'exist'
-      )
-      cy.get(`.action-btn`).should('exist')
+        cy.findByTestId('resend-sso-link-invite-action').should('not.exist')
+        cy.findByTestId('no-actions-available').should('not.exist')
+      })
     })
     })
 
 
-    it('should show the correct menu when dropdown button is clicked', function () {
-      cy.get('.action-btn').click()
-      cy.findByTestId('resend-group-invite-action').should('exist')
-      cy.findByTestId('resend-group-invite-action').then($el => {
-        Cypress.dom.isVisible($el)
+    describe('for a managed group admin user', function () {
+      const user: User = {
+        _id: 'some-user',
+        email: 'some.user@example.com',
+        first_name: 'Some',
+        last_name: 'User',
+        invite: false,
+        last_active_at: new Date(),
+        enrollment: {
+          managedBy: subscriptionId,
+          enrolledAt: new Date(),
+        },
+        isEntityAdmin: true,
+      }
+
+      beforeEach(function () {
+        cy.window().then(win => {
+          win.metaAttributesCache.set('ol-users', [user])
+        })
+
+        mountDropDownComponent(user, subscriptionId)
+      })
+
+      it('should render the button', function () {
+        cy.get('#managed-user-dropdown-some\\.user\\@example\\.com').should(
+          'exist'
+        )
+        cy.get(`.action-btn`).should('exist')
       })
       })
-      cy.findByTestId('remove-user-action').should('exist')
-      cy.findByTestId('remove-user-action').then($el => {
-        Cypress.dom.isVisible($el)
+
+      it('should show the (empty) menu when the button is clicked', function () {
+        cy.get('.action-btn').click()
+        cy.findByTestId('no-actions-available').should('exist')
       })
       })
     })
     })
   })
   })
 
 
-  describe('with group admin user', function () {
-    const user = {
-      _id: 'some-user',
-      email: 'some.user@example.com',
-      first_name: 'Some',
-      last_name: 'User',
-      invite: false,
-      last_active_at: new Date(),
-      enrollment: {},
-      isEntityAdmin: true,
-    }
-
+  describe('with Group SSO enabled', function () {
     beforeEach(function () {
     beforeEach(function () {
       cy.window().then(win => {
       cy.window().then(win => {
-        win.metaAttributesCache.set('ol-users', [user])
+        win.metaAttributesCache.set('ol-managedUsersActive', false)
+        win.metaAttributesCache.set('ol-groupSSOActive', true)
       })
       })
-      mountDropDownComponent(user, subscriptionId)
     })
     })
 
 
-    it('should render dropdown button', function () {
-      cy.get('#managed-user-dropdown-some\\.user\\@example\\.com').should(
-        'exist'
-      )
-      cy.get(`.action-btn`).should('exist')
-    })
+    describe('for a group member not linked with SSO yet', function () {
+      const user: User = {
+        _id: 'some-user',
+        email: 'some.user@example.com',
+        first_name: 'Some',
+        last_name: 'User',
+        invite: false,
+        last_active_at: new Date(),
+        enrollment: {},
+        isEntityAdmin: undefined,
+      }
+
+      beforeEach(function () {
+        cy.window().then(win => {
+          win.metaAttributesCache.set('ol-users', [user])
+        })
+      })
+
+      it('should show resend invite when user is admin', function () {
+        mountDropDownComponent({ ...user, isEntityAdmin: true }, '123abc')
+        cy.get('.action-btn').click()
+        cy.findByTestId('resend-sso-link-invite-action').should('exist')
+      })
+
+      it('should not show resend invite when SSO is disabled', function () {
+        cy.window().then(win => {
+          win.metaAttributesCache.set('ol-groupSSOActive', false)
+        })
+        mountDropDownComponent(user, '123abc')
+        cy.get('.action-btn').click()
+        cy.findByTestId('resend-sso-link-invite-action').should('not.exist')
+      })
 
 
-    it('should show the (empty) menu when dropdown button is clicked', function () {
-      cy.get('.action-btn').click()
-      cy.findByTestId('no-actions-available').should('exist')
+      it('should show the resend SSO invite option when dropdown button is clicked', function () {
+        cy.window().then(win => {
+          win.metaAttributesCache.set('ol-groupSSOActive', true)
+        })
+        mountDropDownComponent(user, '123abc')
+        cy.get('.action-btn').click()
+        cy.findByTestId('resend-sso-link-invite-action').should('be.visible')
+      })
+
+      it('should make the correct post request when resend SSO invite is clicked ', function () {
+        cy.window().then(win => {
+          win.metaAttributesCache.set('ol-groupSSOActive', true)
+        })
+        cy.intercept(
+          'POST',
+          '/manage/groups/123abc/resendSSOLinkInvite/some-user',
+          { success: true }
+        ).as('resendInviteRequest')
+        mountDropDownComponent(user, '123abc')
+        cy.get('.action-btn').click()
+        cy.findByTestId('resend-sso-link-invite-action')
+          .should('exist')
+          .as('resendInvite')
+        cy.get('@resendInvite').click()
+        cy.wait('@resendInviteRequest')
+      })
     })
     })
   })
   })
 
 
-  describe('with managed group admin user', function () {
-    const user = {
-      _id: 'some-user',
-      email: 'some.user@example.com',
-      first_name: 'Some',
-      last_name: 'User',
-      invite: false,
-      last_active_at: new Date(),
-      enrollment: {
-        managedBy: 'some-group',
-        enrolledAt: new Date(),
-      },
-      isEntityAdmin: true,
-    }
-
+  describe('with Managed Users and Group SSO enabled', function () {
     beforeEach(function () {
     beforeEach(function () {
       cy.window().then(win => {
       cy.window().then(win => {
-        win.metaAttributesCache.set('ol-users', [user])
+        win.metaAttributesCache.set('ol-managedUsersActive', true)
+        win.metaAttributesCache.set('ol-groupSSOActive', true)
       })
       })
-
-      mountDropDownComponent(user, subscriptionId)
     })
     })
 
 
-    it('should render the button', function () {
-      cy.get('#managed-user-dropdown-some\\.user\\@example\\.com').should(
-        'exist'
-      )
-      cy.get(`.action-btn`).should('exist')
-    })
+    describe('for a non-managed group member with SSO linked', function () {
+      const user: User = {
+        _id: 'some-user',
+        email: 'some.user@example.com',
+        first_name: 'Some',
+        last_name: 'User',
+        invite: false,
+        last_active_at: new Date(),
+        enrollment: {
+          sso: [
+            {
+              groupId: subscriptionId,
+              linkedAt: new Date(),
+              primary: true,
+            },
+          ],
+        },
+        isEntityAdmin: undefined,
+      }
 
 
-    it('should show the (empty) menu when the button is clicked', function () {
-      cy.get('.action-btn').click()
-      cy.findByTestId('no-actions-available').should('exist')
+      beforeEach(function () {
+        cy.window().then(win => {
+          win.metaAttributesCache.set('ol-users', [user])
+        })
+
+        mountDropDownComponent(user, subscriptionId)
+      })
+
+      it('should render dropdown button', function () {
+        cy.get('#managed-user-dropdown-some\\.user\\@example\\.com').should(
+          'exist'
+        )
+        cy.get(`.action-btn`).should('exist')
+      })
+
+      it('should show the correct menu when dropdown button is clicked', function () {
+        cy.get('.action-btn').click()
+
+        cy.findByTestId('resend-managed-user-invite-action').should(
+          'be.visible'
+        )
+        cy.findByTestId('remove-user-action').should('be.visible')
+
+        cy.findByTestId('resend-sso-link-invite-action').should('not.exist')
+      })
     })
     })
-  })
 
 
-  describe('sending SSO invite reminder', function () {
-    const user = {
-      _id: 'some-user',
-      email: 'some.user@example.com',
-      first_name: 'Some',
-      last_name: 'User',
-      invite: false,
-      last_active_at: new Date(),
-      enrollment: {
-        managedBy: 'some-group',
-        enrolledAt: new Date(),
-      },
-      isEntityAdmin: undefined,
-    }
+    describe('for a non-managed group member with SSO not linked', function () {
+      const user: User = {
+        _id: 'some-user',
+        email: 'some.user@example.com',
+        first_name: 'Some',
+        last_name: 'User',
+        invite: false,
+        last_active_at: new Date(),
+        enrollment: {
+          sso: [],
+        },
+        isEntityAdmin: undefined,
+      }
 
 
-    beforeEach(function () {
-      cy.window().then(win => {
-        win.metaAttributesCache.set('ol-users', [user])
+      beforeEach(function () {
+        cy.window().then(win => {
+          win.metaAttributesCache.set('ol-users', [user])
+        })
+
+        mountDropDownComponent(user, subscriptionId)
       })
       })
-      cy.window().then(win => {
-        win.metaAttributesCache.set('ol-groupSSOActive', true)
+
+      it('should render dropdown button', function () {
+        cy.get('#managed-user-dropdown-some\\.user\\@example\\.com').should(
+          'exist'
+        )
+        cy.get(`.action-btn`).should('exist')
+      })
+
+      it('should show the correct menu when dropdown button is clicked', function () {
+        cy.get('.action-btn').click()
+
+        cy.findByTestId('resend-managed-user-invite-action').should(
+          'be.visible'
+        )
+        cy.findByTestId('remove-user-action').should('be.visible')
+        cy.findByTestId('resend-sso-link-invite-action').should('be.visible')
+
+        cy.findByTestId('no-actions-available').should('not.exist')
       })
       })
     })
     })
 
 
-    it('should show resend invite when user is admin', function () {
-      mountDropDownComponent({ ...user, isEntityAdmin: true }, '123abc')
-      cy.get('.action-btn').click()
-      cy.findByTestId('resend-sso-link-invite-action').should('exist')
+    describe('for a non-managed group admin with SSO linked', function () {
+      const user: User = {
+        _id: 'some-user',
+        email: 'some.user@example.com',
+        first_name: 'Some',
+        last_name: 'User',
+        invite: false,
+        last_active_at: new Date(),
+        enrollment: {
+          sso: [
+            {
+              groupId: subscriptionId,
+              linkedAt: new Date(),
+              primary: true,
+            },
+          ],
+        },
+        isEntityAdmin: true,
+      }
+
+      beforeEach(function () {
+        cy.window().then(win => {
+          win.metaAttributesCache.set('ol-users', [user])
+        })
+
+        mountDropDownComponent(user, subscriptionId)
+      })
+
+      it('should render dropdown button', function () {
+        cy.get('#managed-user-dropdown-some\\.user\\@example\\.com').should(
+          'exist'
+        )
+        cy.get(`.action-btn`).should('exist')
+      })
+
+      it('should show the correct menu when dropdown button is clicked', function () {
+        cy.get('.action-btn').click()
+
+        cy.findByTestId('resend-managed-user-invite-action').should(
+          'be.visible'
+        )
+        cy.findByTestId('remove-user-action').should('be.visible')
+
+        cy.findByTestId('delete-user-action').should('not.exist')
+        cy.findByTestId('resend-sso-link-invite-action').should('not.exist')
+        cy.findByTestId('no-actions-available').should('not.exist')
+      })
     })
     })
 
 
-    it('should not show resend invite when SSO is disabled', function () {
-      cy.window().then(win => {
-        win.metaAttributesCache.set('ol-groupSSOActive', false)
+    describe('for a non-managed group admin with SSO not linked', function () {
+      const user: User = {
+        _id: 'some-user',
+        email: 'some.user@example.com',
+        first_name: 'Some',
+        last_name: 'User',
+        invite: false,
+        last_active_at: new Date(),
+        enrollment: {
+          sso: [],
+        },
+        isEntityAdmin: true,
+      }
+
+      beforeEach(function () {
+        cy.window().then(win => {
+          win.metaAttributesCache.set('ol-users', [user])
+        })
+
+        mountDropDownComponent(user, subscriptionId)
+      })
+
+      it('should render dropdown button', function () {
+        cy.get('#managed-user-dropdown-some\\.user\\@example\\.com').should(
+          'exist'
+        )
+        cy.get(`.action-btn`).should('exist')
+      })
+
+      it('should show the correct menu when dropdown button is clicked', function () {
+        cy.get('.action-btn').click()
+
+        cy.findByTestId('resend-managed-user-invite-action').should(
+          'be.visible'
+        )
+        cy.findByTestId('remove-user-action').should('be.visible')
+        cy.findByTestId('delete-user-action').should('not.exist')
+        cy.findByTestId('resend-sso-link-invite-action').should('exist')
+
+        cy.findByTestId('no-actions-available').should('not.exist')
       })
       })
-      mountDropDownComponent(user, '123abc')
-      cy.get('.action-btn').click()
-      cy.findByTestId('resend-sso-link-invite-action').should('not.exist')
     })
     })
 
 
-    it('should not show resend invite when user has accepted SSO already', function () {
-      cy.window().then(win => {
-        win.metaAttributesCache.set('ol-groupSSOActive', false)
+    describe('for a managed group member with SSO not linked', function () {
+      const user: User = {
+        _id: 'some-user',
+        email: 'some.user@example.com',
+        first_name: 'Some',
+        last_name: 'User',
+        invite: false,
+        last_active_at: new Date(),
+        enrollment: {
+          managedBy: subscriptionId,
+          enrolledAt: new Date(),
+          sso: [],
+        },
+        isEntityAdmin: undefined,
+      }
+
+      beforeEach(function () {
+        cy.window().then(win => {
+          win.metaAttributesCache.set('ol-users', [user])
+        })
+        mountDropDownComponent(user, subscriptionId)
+      })
+
+      it('should render the dropdown button', function () {
+        cy.get('#managed-user-dropdown-some\\.user\\@example\\.com').should(
+          'exist'
+        )
+        cy.get(`.action-btn`).should('exist')
+      })
+
+      it('should show the correct menu when dropdown button is clicked', function () {
+        cy.get('.action-btn').click()
+
+        cy.findByTestId('delete-user-action').should('be.visible')
+
+        cy.findByTestId('remove-user-action').should('not.exist')
+        cy.findByTestId('resend-managed-user-invite-action').should('not.exist')
+        cy.findByTestId('resend-sso-link-invite-action').should('exist')
+
+        cy.findByTestId('no-actions-available').should('not.exist')
       })
       })
-      mountDropDownComponent(
-        {
-          ...user,
-          enrollment: {
-            managedBy: 'some-group',
-            enrolledAt: new Date(),
-            sso: [
-              {
-                groupId: 'abc123abc123',
-                linkedAt: new Date(),
-                primary: true,
-              },
-            ],
-          },
+    })
+
+    describe('for a managed group member with SSO linked', function () {
+      const user: User = {
+        _id: 'some-user',
+        email: 'some.user@example.com',
+        first_name: 'Some',
+        last_name: 'User',
+        invite: false,
+        last_active_at: new Date(),
+        enrollment: {
+          managedBy: subscriptionId,
+          enrolledAt: new Date(),
+          sso: [
+            {
+              groupId: subscriptionId,
+              linkedAt: new Date(),
+              primary: true,
+            },
+          ],
         },
         },
-        '123abc'
-      )
-      cy.get('.action-btn').click()
-      cy.findByTestId('resend-sso-link-invite-action').should('not.exist')
+        isEntityAdmin: undefined,
+      }
+
+      beforeEach(function () {
+        cy.window().then(win => {
+          win.metaAttributesCache.set('ol-users', [user])
+        })
+        mountDropDownComponent(user, subscriptionId)
+      })
+
+      it('should render the dropdown button', function () {
+        cy.get('#managed-user-dropdown-some\\.user\\@example\\.com').should(
+          'exist'
+        )
+        cy.get(`.action-btn`).should('exist')
+      })
+
+      it('should show the correct menu when dropdown button is clicked', function () {
+        cy.get('.action-btn').click()
+
+        cy.findByTestId('delete-user-action').should('be.visible')
+
+        cy.findByTestId('remove-user-action').should('not.exist')
+        cy.findByTestId('resend-managed-user-invite-action').should('not.exist')
+        cy.findByTestId('resend-sso-link-invite-action').should('not.exist')
+
+        cy.findByTestId('no-actions-available').should('not.exist')
+      })
     })
     })
 
 
-    it('should show the resend SSO invite option when dropdown button is clicked', function () {
-      cy.window().then(win => {
-        win.metaAttributesCache.set('ol-groupSSOActive', true)
+    describe('for a managed group admin with SSO not linked', function () {
+      const user: User = {
+        _id: 'some-user',
+        email: 'some.user@example.com',
+        first_name: 'Some',
+        last_name: 'User',
+        invite: false,
+        last_active_at: new Date(),
+        enrollment: {
+          managedBy: subscriptionId,
+          enrolledAt: new Date(),
+          sso: [],
+        },
+        isEntityAdmin: true,
+      }
+
+      beforeEach(function () {
+        cy.window().then(win => {
+          win.metaAttributesCache.set('ol-users', [user])
+        })
+
+        mountDropDownComponent(user, subscriptionId)
       })
       })
-      mountDropDownComponent(user, '123abc')
-      cy.get('.action-btn').click()
-      cy.findByTestId('resend-sso-link-invite-action').should('exist')
-      cy.findByTestId('resend-sso-link-invite-action').then($el => {
-        Cypress.dom.isVisible($el)
+
+      it('should render the button', function () {
+        cy.get('#managed-user-dropdown-some\\.user\\@example\\.com').should(
+          'exist'
+        )
+        cy.get(`.action-btn`).should('exist')
+      })
+
+      it('should show the correct menu when dropdown button is clicked', function () {
+        cy.get('.action-btn').click()
+
+        cy.findByTestId('resend-sso-link-invite-action').should('exist')
+
+        cy.findByTestId('resend-managed-user-invite-action').should('not.exist')
+        cy.findByTestId('remove-user-action').should('not.exist')
+        cy.findByTestId('delete-user-action').should('not.exist')
+        cy.findByTestId('no-actions-available').should('not.exist')
       })
       })
     })
     })
 
 
-    it('should make the correct post request when resend SSO invite is clicked ', function () {
-      cy.window().then(win => {
-        win.metaAttributesCache.set('ol-groupSSOActive', true)
+    describe('for a managed group admin with SSO linked', function () {
+      const user: User = {
+        _id: 'some-user',
+        email: 'some.user@example.com',
+        first_name: 'Some',
+        last_name: 'User',
+        invite: false,
+        last_active_at: new Date(),
+        enrollment: {
+          managedBy: subscriptionId,
+          enrolledAt: new Date(),
+          sso: [
+            {
+              groupId: subscriptionId,
+              linkedAt: new Date(),
+              primary: true,
+            },
+          ],
+        },
+        isEntityAdmin: true,
+      }
+
+      beforeEach(function () {
+        cy.window().then(win => {
+          win.metaAttributesCache.set('ol-users', [user])
+        })
+
+        mountDropDownComponent(user, subscriptionId)
+      })
+
+      it('should render the button', function () {
+        cy.get('#managed-user-dropdown-some\\.user\\@example\\.com').should(
+          'exist'
+        )
+        cy.get(`.action-btn`).should('exist')
+      })
+
+      it('should show no actions when dropdown button is clicked', function () {
+        cy.get('.action-btn').click()
+
+        cy.findByTestId('no-actions-available').should('exist')
+
+        cy.findByTestId('delete-user-action').should('not.exist')
+        cy.findByTestId('remove-user-action').should('not.exist')
+        cy.findByTestId('resend-managed-user-invite-action').should('not.exist')
+        cy.findByTestId('resend-sso-link-invite-action').should('not.exist')
       })
       })
-      cy.intercept(
-        'POST',
-        '/manage/groups/123abc/resendSSOLinkInvite/some-user',
-        { success: true }
-      ).as('resendInviteRequest')
-      mountDropDownComponent(user, '123abc')
-      cy.get('.action-btn').click()
-      cy.findByTestId('resend-sso-link-invite-action')
-        .should('exist')
-        .as('resendInvite')
-      cy.get('@resendInvite').click()
-      cy.wait('@resendInviteRequest')
     })
     })
   })
   })
 })
 })