mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-05-23 17:19:37 +02:00
Merge pull request #23806 from overleaf/ii-bs5-manage-group-managers
[web] BS5 Group managers management GitOrigin-RevId: 912fd29c3d5cf07eab0cd67e2771e60b1ba25fb3
This commit is contained in:
@@ -120,6 +120,8 @@ async function _renderManagersPage(req, res, next, template) {
|
||||
entityConfig
|
||||
)
|
||||
|
||||
await SplitTestHandler.promises.getAssignment(req, res, 'bootstrap-5-groups')
|
||||
|
||||
res.render(template, {
|
||||
name: entityName,
|
||||
users,
|
||||
|
||||
@@ -3,6 +3,10 @@ extends ../layout-marketing
|
||||
block entrypointVar
|
||||
- entrypoint = 'pages/user/subscription/group-management/group-managers'
|
||||
|
||||
block vars
|
||||
- bootstrap5PageStatus = 'enabled' // One of 'disabled', 'enabled', and 'queryStringOnly'
|
||||
- bootstrap5PageSplitTest = 'bootstrap-5-groups'
|
||||
|
||||
block append meta
|
||||
meta(name="ol-users", data-type="json", content=users)
|
||||
meta(name="ol-groupId", data-type="string", content=groupId)
|
||||
|
||||
@@ -3,6 +3,10 @@ extends ../layout-marketing
|
||||
block entrypointVar
|
||||
- entrypoint = 'pages/user/subscription/group-management/institution-managers'
|
||||
|
||||
block vars
|
||||
- bootstrap5PageStatus = 'enabled' // One of 'disabled', 'enabled', and 'queryStringOnly'
|
||||
- bootstrap5PageSplitTest = 'bootstrap-5-groups'
|
||||
|
||||
block append meta
|
||||
meta(name="ol-users", data-type="json", content=users)
|
||||
meta(name="ol-groupId", data-type="string", content=groupId)
|
||||
|
||||
@@ -3,6 +3,10 @@ extends ../layout-marketing
|
||||
block entrypointVar
|
||||
- entrypoint = 'pages/user/subscription/group-management/publisher-managers'
|
||||
|
||||
block vars
|
||||
- bootstrap5PageStatus = 'enabled' // One of 'disabled', 'enabled', and 'queryStringOnly'
|
||||
- bootstrap5PageSplitTest = 'bootstrap-5-groups'
|
||||
|
||||
block append meta
|
||||
meta(name="ol-users", data-type="json", content=users)
|
||||
meta(name="ol-groupId", data-type="string", content=groupId)
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import { useCallback, useState } from 'react'
|
||||
import { Button, Col, Form, FormControl, Row } from 'react-bootstrap'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { deleteJSON, FetchError, postJSON } from '@/infrastructure/fetch-json'
|
||||
import MaterialIcon from '../../../shared/components/material-icon'
|
||||
import Tooltip from '../../../shared/components/tooltip'
|
||||
import getMeta from '../../../utils/meta'
|
||||
import { parseEmails } from '../utils/emails'
|
||||
import ErrorAlert, { APIError } from './error-alert'
|
||||
@@ -11,6 +8,17 @@ import UserRow from './user-row'
|
||||
import useUserSelection from '../hooks/use-user-selection'
|
||||
import { User } from '../../../../../types/group-management/user'
|
||||
import { debugConsole } from '@/utils/debugging'
|
||||
import OLRow from '@/features/ui/components/ol/ol-row'
|
||||
import OLCol from '@/features/ui/components/ol/ol-col'
|
||||
import BackButton from '@/features/group-management/components/back-button'
|
||||
import OLCard from '@/features/ui/components/ol/ol-card'
|
||||
import OLButton from '@/features/ui/components/ol/ol-button'
|
||||
import OLFormControl from '@/features/ui/components/ol/ol-form-control'
|
||||
import OLFormText from '@/features/ui/components/ol/ol-form-text'
|
||||
import OLTable from '@/features/ui/components/ol/ol-table'
|
||||
import OLTooltip from '@/features/ui/components/ol/ol-tooltip'
|
||||
import OLFormCheckbox from '@/features/ui/components/ol/ol-form-checkbox'
|
||||
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
|
||||
|
||||
type ManagersPaths = {
|
||||
addMember: string
|
||||
@@ -132,136 +140,155 @@ export function ManagersTable({
|
||||
|
||||
return (
|
||||
<div className="container">
|
||||
<Row>
|
||||
<Col md={10} mdOffset={1}>
|
||||
<h1>
|
||||
<a href="/user/subscription" className="back-btn">
|
||||
<MaterialIcon
|
||||
type="arrow_back"
|
||||
accessibilityLabel={t('back_to_subscription')}
|
||||
/>
|
||||
</a>{' '}
|
||||
{groupName || translations.title}
|
||||
</h1>
|
||||
<div className="card">
|
||||
<div className="page-header">
|
||||
<OLRow>
|
||||
<OLCol lg={{ span: 10, offset: 1 }}>
|
||||
<div className="group-heading" data-testid="group-heading">
|
||||
<BackButton
|
||||
href="/user/subscription"
|
||||
accessibilityLabel={t('back_to_subscription')}
|
||||
/>
|
||||
<h1 className="heading">{groupName || translations.title}</h1>
|
||||
</div>
|
||||
<OLCard>
|
||||
<div
|
||||
className="page-header mb-4"
|
||||
data-testid="page-header-members-details"
|
||||
>
|
||||
<div className="pull-right">
|
||||
{removeMemberInflightCount > 0 ? (
|
||||
<Button bsStyle="danger" disabled>
|
||||
<OLButton variant="danger" disabled>
|
||||
{t('removing')}…
|
||||
</Button>
|
||||
</OLButton>
|
||||
) : (
|
||||
<>
|
||||
{selectedUsers.length > 0 && (
|
||||
<Button bsStyle="danger" onClick={removeManagers}>
|
||||
<OLButton variant="danger" onClick={removeManagers}>
|
||||
{translations.remove}
|
||||
</Button>
|
||||
</OLButton>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<h3>{translations.subtitle}</h3>
|
||||
<h2 className="h3 mt-0">{translations.subtitle}</h2>
|
||||
</div>
|
||||
<div className="row-spaced-small">
|
||||
<ErrorAlert error={removeMemberError} />
|
||||
<ul className="list-unstyled structured-list">
|
||||
<li className="container-fluid">
|
||||
<Row>
|
||||
<Col xs={4}>
|
||||
<label htmlFor="select-all" className="sr-only">
|
||||
{t('select_all')}
|
||||
</label>
|
||||
<input
|
||||
className="select-all"
|
||||
id="select-all"
|
||||
type="checkbox"
|
||||
autoComplete="off"
|
||||
onChange={handleSelectAllClick}
|
||||
checked={selectedUsers.length === users.length}
|
||||
<OLTable
|
||||
className="managed-users-table managed-users-list structured-list"
|
||||
data-testid="managed-users-table"
|
||||
>
|
||||
<thead>
|
||||
<tr>
|
||||
<th className="cell-checkbox">
|
||||
<BootstrapVersionSwitcher
|
||||
bs3={
|
||||
<input
|
||||
className="select-all"
|
||||
type="checkbox"
|
||||
autoComplete="off"
|
||||
onChange={handleSelectAllClick}
|
||||
checked={selectedUsers.length === users.length}
|
||||
aria-label={t('select_all')}
|
||||
data-testid="select-all-checkbox"
|
||||
/>
|
||||
}
|
||||
bs5={
|
||||
<OLFormCheckbox
|
||||
autoComplete="off"
|
||||
onChange={handleSelectAllClick}
|
||||
checked={selectedUsers.length === users.length}
|
||||
aria-label={t('select_all')}
|
||||
data-testid="select-all-checkbox"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<span className="header">{t('email')}</span>
|
||||
</Col>
|
||||
<Col xs={4}>
|
||||
<span className="header">{t('name')}</span>
|
||||
</Col>
|
||||
<Col xs={2}>
|
||||
<Tooltip
|
||||
</th>
|
||||
<th>{t('email')}</th>
|
||||
<th className="cell-name">{t('name')}</th>
|
||||
<th className="cell-last-active">
|
||||
<OLTooltip
|
||||
id="last-active-tooltip"
|
||||
description={t('last_active_description')}
|
||||
overlayProps={{
|
||||
placement: 'left',
|
||||
}}
|
||||
>
|
||||
<span className="header">
|
||||
<span>
|
||||
{t('last_active')}
|
||||
<sup>(?)</sup>
|
||||
</span>
|
||||
</Tooltip>
|
||||
</Col>
|
||||
<Col xs={2}>
|
||||
<span className="header">{t('accepted_invite')}</span>
|
||||
</Col>
|
||||
</Row>
|
||||
</li>
|
||||
{users.length === 0 && (
|
||||
<li>
|
||||
<Row>
|
||||
<Col md={12} className="text-centered">
|
||||
</OLTooltip>
|
||||
</th>
|
||||
<th className="cell-accepted-invite">
|
||||
{t('accepted_invite')}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{users.length === 0 && (
|
||||
<tr>
|
||||
<td className="text-center" colSpan={5}>
|
||||
<small>{t('no_members')}</small>
|
||||
</Col>
|
||||
</Row>
|
||||
</li>
|
||||
)}
|
||||
{users.map(user => (
|
||||
<UserRow
|
||||
key={user.email}
|
||||
user={user}
|
||||
selectUser={selectUser}
|
||||
unselectUser={unselectUser}
|
||||
selected={selectedUsers.includes(user)}
|
||||
/>
|
||||
))}
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
{users.map(user => (
|
||||
<UserRow
|
||||
key={user.email}
|
||||
user={user}
|
||||
selectUser={selectUser}
|
||||
unselectUser={unselectUser}
|
||||
selected={selectedUsers.includes(user)}
|
||||
/>
|
||||
))}
|
||||
</tbody>
|
||||
</OLTable>
|
||||
</div>
|
||||
<hr />
|
||||
<div>
|
||||
<p className="small">{t('add_more_managers')}</p>
|
||||
<ErrorAlert error={inviteError} />
|
||||
<Form horizontal onSubmit={addManagers} className="form">
|
||||
<Row>
|
||||
<Col xs={6}>
|
||||
<FormControl
|
||||
<form onSubmit={addManagers} data-testid="add-members-form">
|
||||
<OLRow>
|
||||
<OLCol xs={6}>
|
||||
<OLFormControl
|
||||
type="input"
|
||||
placeholder="jane@example.com, joe@example.com"
|
||||
aria-describedby="add-members-description"
|
||||
value={emailString}
|
||||
onChange={handleEmailsChange}
|
||||
/>
|
||||
</Col>
|
||||
<Col xs={4}>
|
||||
{inviteUserInflightCount > 0 ? (
|
||||
<Button bsStyle="primary" disabled>
|
||||
{t('adding')}…
|
||||
</Button>
|
||||
) : (
|
||||
<Button bsStyle="primary" onClick={addManagers}>
|
||||
{t('add')}
|
||||
</Button>
|
||||
)}
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col xs={8}>
|
||||
<span className="help-block">
|
||||
</OLCol>
|
||||
<OLCol xs={4}>
|
||||
<OLButton
|
||||
variant="primary"
|
||||
onClick={addManagers}
|
||||
isLoading={inviteUserInflightCount > 0}
|
||||
bs3Props={{
|
||||
loading:
|
||||
inviteUserInflightCount > 0 ? (
|
||||
<>{t('adding')}…</>
|
||||
) : (
|
||||
t('add')
|
||||
),
|
||||
}}
|
||||
>
|
||||
{t('add')}
|
||||
</OLButton>
|
||||
</OLCol>
|
||||
</OLRow>
|
||||
<OLRow>
|
||||
<OLCol xs={8}>
|
||||
<OLFormText bs3Props={{ className: 'help-block' }}>
|
||||
{t('add_comma_separated_emails_help')}
|
||||
</span>
|
||||
</Col>
|
||||
</Row>
|
||||
</Form>
|
||||
</OLFormText>
|
||||
</OLCol>
|
||||
</OLRow>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</OLCard>
|
||||
</OLCol>
|
||||
</OLRow>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import moment from 'moment'
|
||||
import { useCallback } from 'react'
|
||||
import { Col, Row } from 'react-bootstrap'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { User } from '../../../../../types/group-management/user'
|
||||
import OLFormCheckbox from '@/features/ui/components/ol/ol-form-checkbox'
|
||||
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
|
||||
import Icon from '@/shared/components/icon'
|
||||
import MaterialIcon from '@/shared/components/material-icon'
|
||||
|
||||
type GroupMemberRowProps = {
|
||||
user: User
|
||||
@@ -31,52 +34,75 @@ export default function UserRow({
|
||||
)
|
||||
|
||||
return (
|
||||
<li key={`user-${user.email}`}>
|
||||
<Row>
|
||||
<Col xs={4}>
|
||||
<label htmlFor={`select-user-${user.email}`} className="sr-only">
|
||||
{t('select_user')}
|
||||
</label>
|
||||
<input
|
||||
className="select-item"
|
||||
id={`select-user-${user.email}`}
|
||||
type="checkbox"
|
||||
autoComplete="off"
|
||||
checked={selected}
|
||||
onChange={e => handleSelectUser(e, user)}
|
||||
<tr key={`user-${user.email}`} className="managed-user-row">
|
||||
<td className="cell-checkbox">
|
||||
<BootstrapVersionSwitcher
|
||||
bs3={
|
||||
<input
|
||||
className="select-item"
|
||||
type="checkbox"
|
||||
autoComplete="off"
|
||||
checked={selected}
|
||||
onChange={e => handleSelectUser(e, user)}
|
||||
aria-label={t('select_user')}
|
||||
data-testid="select-single-checkbox"
|
||||
/>
|
||||
}
|
||||
bs5={
|
||||
<OLFormCheckbox
|
||||
autoComplete="off"
|
||||
checked={selected}
|
||||
onChange={e => handleSelectUser(e, user)}
|
||||
aria-label={t('select_user')}
|
||||
data-testid="select-single-checkbox"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</td>
|
||||
<td>{user.email}</td>
|
||||
<td className="cell-name">
|
||||
{user.first_name} {user.last_name}
|
||||
</td>
|
||||
<td className="cell-last-active">
|
||||
{user.last_active_at
|
||||
? moment(user.last_active_at).format('Do MMM YYYY')
|
||||
: 'N/A'}
|
||||
</td>
|
||||
<td className="cell-accepted-invite">
|
||||
{user.invite ? (
|
||||
<BootstrapVersionSwitcher
|
||||
bs3={
|
||||
<Icon
|
||||
type="times"
|
||||
accessibilityLabel={t('invite_not_accepted')}
|
||||
/>
|
||||
}
|
||||
bs5={
|
||||
<MaterialIcon
|
||||
type="clear"
|
||||
accessibilityLabel={t('invite_not_accepted')}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<span>{user.email}</span>
|
||||
</Col>
|
||||
<Col xs={4}>
|
||||
{user.first_name} {user.last_name}
|
||||
</Col>
|
||||
<Col xs={2}>
|
||||
{user.last_active_at
|
||||
? moment(user.last_active_at).format('Do MMM YYYY')
|
||||
: 'N/A'}
|
||||
</Col>
|
||||
<Col xs={2}>
|
||||
{user.invite ? (
|
||||
<>
|
||||
<i
|
||||
className="fa fa-times"
|
||||
aria-hidden="true"
|
||||
aria-label={t('invite_not_accepted')}
|
||||
) : (
|
||||
<BootstrapVersionSwitcher
|
||||
bs3={
|
||||
<Icon
|
||||
type="check"
|
||||
className="text-success"
|
||||
accessibilityLabel={t('accepted_invite')}
|
||||
/>
|
||||
<span className="sr-only">{t('invite_not_accepted')}</span>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<i
|
||||
className="fa fa-check text-success"
|
||||
aria-hidden="true"
|
||||
aria-label={t('accepted_invite')}
|
||||
}
|
||||
bs5={
|
||||
<MaterialIcon
|
||||
type="check"
|
||||
className="text-success"
|
||||
accessibilityLabel={t('accepted_invite')}
|
||||
/>
|
||||
<span className="sr-only">{t('accepted_invite')}</span>
|
||||
</>
|
||||
)}
|
||||
</Col>
|
||||
</Row>
|
||||
</li>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -71,6 +71,10 @@
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.cell-accepted-invite {
|
||||
width: 17%;
|
||||
}
|
||||
|
||||
&.managed-users-active {
|
||||
.cell-email {
|
||||
width: 30%;
|
||||
@@ -131,6 +135,10 @@
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.cell-accepted-invite {
|
||||
width: 17%;
|
||||
}
|
||||
|
||||
&.managed-users-active {
|
||||
.cell-email {
|
||||
width: 41%;
|
||||
|
||||
@@ -126,6 +126,10 @@
|
||||
min-width: 25px;
|
||||
}
|
||||
|
||||
.cell-accepted-invite {
|
||||
width: 17%;
|
||||
}
|
||||
|
||||
&.managed-users-active {
|
||||
.cell-email {
|
||||
width: 35%;
|
||||
@@ -185,6 +189,10 @@
|
||||
min-width: 25px;
|
||||
}
|
||||
|
||||
.cell-accepted-invite {
|
||||
width: 17%;
|
||||
}
|
||||
|
||||
&.managed-users-active {
|
||||
.cell-email {
|
||||
width: 42%;
|
||||
|
||||
@@ -35,23 +35,25 @@ describe('group managers', function () {
|
||||
})
|
||||
|
||||
it('renders the group management page', function () {
|
||||
cy.get('h1').contains('My Awesome Team')
|
||||
cy.findByRole('heading', { name: /my awesome team/i, level: 1 })
|
||||
|
||||
cy.get('ul').within(() => {
|
||||
cy.get('li:nth-child(2)').within(() => {
|
||||
cy.contains('john.doe@test.com')
|
||||
cy.contains('John Doe')
|
||||
cy.contains('15th Jan 2023')
|
||||
cy.get(`[aria-label="Invite not yet accepted"]`)
|
||||
})
|
||||
cy.findByTestId('managed-users-table')
|
||||
.find('tbody')
|
||||
.within(() => {
|
||||
cy.get('tr:nth-child(1)').within(() => {
|
||||
cy.findByText('john.doe@test.com')
|
||||
cy.findByText('John Doe')
|
||||
cy.findByText('15th Jan 2023')
|
||||
cy.findByText('Invite not yet accepted')
|
||||
})
|
||||
|
||||
cy.get('li:nth-child(3)').within(() => {
|
||||
cy.contains('bobby.lapointe@test.com')
|
||||
cy.contains('Bobby Lapointe')
|
||||
cy.contains('2nd Jan 2023')
|
||||
cy.get(`[aria-label="Accepted invite"]`)
|
||||
cy.get('tr:nth-child(2)').within(() => {
|
||||
cy.findByText('bobby.lapointe@test.com')
|
||||
cy.findByText('Bobby Lapointe')
|
||||
cy.findByText('2nd Jan 2023')
|
||||
cy.findByText('Accepted invite')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('sends an invite', function () {
|
||||
@@ -65,16 +67,20 @@ describe('group managers', function () {
|
||||
},
|
||||
})
|
||||
|
||||
cy.get('.form-control').type('someone.else@test.com')
|
||||
cy.get('button').click()
|
||||
|
||||
cy.get('ul').within(() => {
|
||||
cy.get('li:nth-child(4)').within(() => {
|
||||
cy.contains('someone.else@test.com')
|
||||
cy.contains('N/A')
|
||||
cy.get(`[aria-label="Invite not yet accepted"]`)
|
||||
})
|
||||
cy.findByTestId('add-members-form').within(() => {
|
||||
cy.findByRole('textbox').type('someone.else@test.com')
|
||||
cy.findByRole('button').click()
|
||||
})
|
||||
|
||||
cy.findByTestId('managed-users-table')
|
||||
.find('tbody')
|
||||
.within(() => {
|
||||
cy.get('tr:nth-child(3)').within(() => {
|
||||
cy.findByText('someone.else@test.com')
|
||||
cy.findByText('N/A')
|
||||
cy.findByText('Invite not yet accepted')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('tries to send an invite and displays the error', function () {
|
||||
@@ -87,31 +93,41 @@ describe('group managers', function () {
|
||||
},
|
||||
})
|
||||
|
||||
cy.get('.form-control').type('someone.else@test.com')
|
||||
cy.get('button').click()
|
||||
cy.get('.alert').contains('Error: User already added')
|
||||
cy.findByTestId('add-members-form').within(() => {
|
||||
cy.findByRole('textbox').type('someone.else@test.com')
|
||||
cy.findByRole('button').click()
|
||||
})
|
||||
cy.findByRole('alert').should('contain.text', 'Error: User already added')
|
||||
})
|
||||
|
||||
it('checks the select all checkbox', function () {
|
||||
cy.get('ul').within(() => {
|
||||
cy.get('li:nth-child(2)').within(() => {
|
||||
cy.get('.select-item').should('not.be.checked')
|
||||
cy.findByTestId('managed-users-table')
|
||||
.find('tbody')
|
||||
.within(() => {
|
||||
cy.get('tr:nth-child(1)').within(() => {
|
||||
cy.findByLabelText(/select user/i).should('not.be.checked')
|
||||
})
|
||||
cy.get('tr:nth-child(2)').within(() => {
|
||||
cy.findByLabelText(/select user/i).should('not.be.checked')
|
||||
})
|
||||
})
|
||||
cy.get('li:nth-child(3)').within(() => {
|
||||
cy.get('.select-item').should('not.be.checked')
|
||||
})
|
||||
})
|
||||
|
||||
cy.get('.select-all').click()
|
||||
cy.findByTestId('managed-users-table')
|
||||
.find('thead')
|
||||
.within(() => {
|
||||
cy.findByLabelText(/select all/i).check()
|
||||
})
|
||||
|
||||
cy.get('ul').within(() => {
|
||||
cy.get('li:nth-child(2)').within(() => {
|
||||
cy.get('.select-item').should('be.checked')
|
||||
cy.findByTestId('managed-users-table')
|
||||
.find('tbody')
|
||||
.within(() => {
|
||||
cy.get('tr:nth-child(1)').within(() => {
|
||||
cy.findByLabelText(/select user/i).should('be.checked')
|
||||
})
|
||||
cy.get('tr:nth-child(2)').within(() => {
|
||||
cy.findByLabelText(/select user/i).should('be.checked')
|
||||
})
|
||||
})
|
||||
cy.get('li:nth-child(3)').within(() => {
|
||||
cy.get('.select-item').should('be.checked')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('remove a member', function () {
|
||||
@@ -119,22 +135,26 @@ describe('group managers', function () {
|
||||
statusCode: 200,
|
||||
})
|
||||
|
||||
cy.get('ul').within(() => {
|
||||
cy.get('li:nth-child(2)').within(() => {
|
||||
cy.get('.select-item').check()
|
||||
cy.findByTestId('managed-users-table')
|
||||
.find('tbody')
|
||||
.within(() => {
|
||||
cy.get('tr:nth-child(1)').within(() => {
|
||||
cy.findByLabelText(/select user/i).check()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
cy.get('button').contains('Remove manager').click()
|
||||
cy.findByRole('button', { name: /remove manager/i }).click()
|
||||
|
||||
cy.get('ul').within(() => {
|
||||
cy.get('li:nth-child(2)').within(() => {
|
||||
cy.contains('bobby.lapointe@test.com')
|
||||
cy.contains('Bobby Lapointe')
|
||||
cy.contains('2nd Jan 2023')
|
||||
cy.get(`[aria-label="Accepted invite"]`)
|
||||
cy.findByTestId('managed-users-table')
|
||||
.find('tbody')
|
||||
.within(() => {
|
||||
cy.get('tr:nth-child(1)').within(() => {
|
||||
cy.findByText('bobby.lapointe@test.com')
|
||||
cy.findByText('Bobby Lapointe')
|
||||
cy.findByText('2nd Jan 2023')
|
||||
cy.findByText('Accepted invite')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('tries to remove a manager and displays the error', function () {
|
||||
@@ -142,13 +162,15 @@ describe('group managers', function () {
|
||||
statusCode: 500,
|
||||
})
|
||||
|
||||
cy.get('ul').within(() => {
|
||||
cy.get('li:nth-child(2)').within(() => {
|
||||
cy.get('.select-item').check()
|
||||
cy.findByTestId('managed-users-table')
|
||||
.find('tbody')
|
||||
.within(() => {
|
||||
cy.get('tr:nth-child(1)').within(() => {
|
||||
cy.findByLabelText(/select user/i).check()
|
||||
})
|
||||
})
|
||||
})
|
||||
cy.get('button').contains('Remove manager').click()
|
||||
cy.findByRole('button', { name: /remove manager/i }).click()
|
||||
|
||||
cy.get('.alert').contains('Sorry, something went wrong')
|
||||
cy.findByRole('alert').should('contain.text', 'Sorry, something went wrong')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -35,23 +35,25 @@ describe('institution managers', function () {
|
||||
})
|
||||
|
||||
it('renders the institution management page', function () {
|
||||
cy.get('h1').contains('My Awesome Institution')
|
||||
cy.findByRole('heading', { name: /my awesome institution/i, level: 1 })
|
||||
|
||||
cy.get('ul').within(() => {
|
||||
cy.get('li:nth-child(2)').within(() => {
|
||||
cy.contains('john.doe@test.com')
|
||||
cy.contains('John Doe')
|
||||
cy.contains('15th Jan 2023')
|
||||
cy.get(`[aria-label="Invite not yet accepted"]`)
|
||||
})
|
||||
cy.findByTestId('managed-users-table')
|
||||
.find('tbody')
|
||||
.within(() => {
|
||||
cy.get('tr:nth-child(1)').within(() => {
|
||||
cy.findByText('john.doe@test.com')
|
||||
cy.findByText('John Doe')
|
||||
cy.findByText('15th Jan 2023')
|
||||
cy.findByText('Invite not yet accepted')
|
||||
})
|
||||
|
||||
cy.get('li:nth-child(3)').within(() => {
|
||||
cy.contains('bobby.lapointe@test.com')
|
||||
cy.contains('Bobby Lapointe')
|
||||
cy.contains('2nd Jan 2023')
|
||||
cy.get(`[aria-label="Accepted invite"]`)
|
||||
cy.get('tr:nth-child(2)').within(() => {
|
||||
cy.findByText('bobby.lapointe@test.com')
|
||||
cy.findByText('Bobby Lapointe')
|
||||
cy.findByText('2nd Jan 2023')
|
||||
cy.findByText('Accepted invite')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('sends an invite', function () {
|
||||
@@ -65,16 +67,20 @@ describe('institution managers', function () {
|
||||
},
|
||||
})
|
||||
|
||||
cy.get('.form-control').type('someone.else@test.com')
|
||||
cy.get('button').click()
|
||||
|
||||
cy.get('ul').within(() => {
|
||||
cy.get('li:nth-child(4)').within(() => {
|
||||
cy.contains('someone.else@test.com')
|
||||
cy.contains('N/A')
|
||||
cy.get(`[aria-label="Invite not yet accepted"]`)
|
||||
})
|
||||
cy.findByTestId('add-members-form').within(() => {
|
||||
cy.findByRole('textbox').type('someone.else@test.com')
|
||||
cy.findByRole('button').click()
|
||||
})
|
||||
|
||||
cy.findByTestId('managed-users-table')
|
||||
.find('tbody')
|
||||
.within(() => {
|
||||
cy.get('tr:nth-child(3)').within(() => {
|
||||
cy.findByText('someone.else@test.com')
|
||||
cy.findByText('N/A')
|
||||
cy.findByText('Invite not yet accepted')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('tries to send an invite and displays the error', function () {
|
||||
@@ -87,31 +93,41 @@ describe('institution managers', function () {
|
||||
},
|
||||
})
|
||||
|
||||
cy.get('.form-control').type('someone.else@test.com')
|
||||
cy.get('button').click()
|
||||
cy.get('.alert').contains('Error: User already added')
|
||||
cy.findByTestId('add-members-form').within(() => {
|
||||
cy.findByRole('textbox').type('someone.else@test.com')
|
||||
cy.findByRole('button').click()
|
||||
})
|
||||
cy.findByRole('alert').should('contain.text', 'Error: User already added')
|
||||
})
|
||||
|
||||
it('checks the select all checkbox', function () {
|
||||
cy.get('ul').within(() => {
|
||||
cy.get('li:nth-child(2)').within(() => {
|
||||
cy.get('.select-item').should('not.be.checked')
|
||||
cy.findByTestId('managed-users-table')
|
||||
.find('tbody')
|
||||
.within(() => {
|
||||
cy.get('tr:nth-child(1)').within(() => {
|
||||
cy.findByLabelText(/select user/i).should('not.be.checked')
|
||||
})
|
||||
cy.get('tr:nth-child(2)').within(() => {
|
||||
cy.findByLabelText(/select user/i).should('not.be.checked')
|
||||
})
|
||||
})
|
||||
cy.get('li:nth-child(3)').within(() => {
|
||||
cy.get('.select-item').should('not.be.checked')
|
||||
})
|
||||
})
|
||||
|
||||
cy.get('.select-all').click()
|
||||
cy.findByTestId('managed-users-table')
|
||||
.find('thead')
|
||||
.within(() => {
|
||||
cy.findByLabelText(/select all/i).check()
|
||||
})
|
||||
|
||||
cy.get('ul').within(() => {
|
||||
cy.get('li:nth-child(2)').within(() => {
|
||||
cy.get('.select-item').should('be.checked')
|
||||
cy.findByTestId('managed-users-table')
|
||||
.find('tbody')
|
||||
.within(() => {
|
||||
cy.get('tr:nth-child(1)').within(() => {
|
||||
cy.findByLabelText(/select user/i).should('be.checked')
|
||||
})
|
||||
cy.get('tr:nth-child(2)').within(() => {
|
||||
cy.findByLabelText(/select user/i).should('be.checked')
|
||||
})
|
||||
})
|
||||
cy.get('li:nth-child(3)').within(() => {
|
||||
cy.get('.select-item').should('be.checked')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('remove a member', function () {
|
||||
@@ -119,22 +135,26 @@ describe('institution managers', function () {
|
||||
statusCode: 200,
|
||||
})
|
||||
|
||||
cy.get('ul').within(() => {
|
||||
cy.get('li:nth-child(2)').within(() => {
|
||||
cy.get('.select-item').check()
|
||||
cy.findByTestId('managed-users-table')
|
||||
.find('tbody')
|
||||
.within(() => {
|
||||
cy.get('tr:nth-child(1)').within(() => {
|
||||
cy.findByLabelText(/select user/i).check()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
cy.get('button').contains('Remove manager').click()
|
||||
cy.findByRole('button', { name: /remove manager/i }).click()
|
||||
|
||||
cy.get('ul').within(() => {
|
||||
cy.get('li:nth-child(2)').within(() => {
|
||||
cy.contains('bobby.lapointe@test.com')
|
||||
cy.contains('Bobby Lapointe')
|
||||
cy.contains('2nd Jan 2023')
|
||||
cy.get(`[aria-label="Accepted invite"]`)
|
||||
cy.findByTestId('managed-users-table')
|
||||
.find('tbody')
|
||||
.within(() => {
|
||||
cy.get('tr:nth-child(1)').within(() => {
|
||||
cy.findByText('bobby.lapointe@test.com')
|
||||
cy.findByText('Bobby Lapointe')
|
||||
cy.findByText('2nd Jan 2023')
|
||||
cy.findByText('Accepted invite')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('tries to remove a manager and displays the error', function () {
|
||||
@@ -142,13 +162,15 @@ describe('institution managers', function () {
|
||||
statusCode: 500,
|
||||
})
|
||||
|
||||
cy.get('ul').within(() => {
|
||||
cy.get('li:nth-child(2)').within(() => {
|
||||
cy.get('.select-item').check()
|
||||
cy.findByTestId('managed-users-table')
|
||||
.find('tbody')
|
||||
.within(() => {
|
||||
cy.get('tr:nth-child(1)').within(() => {
|
||||
cy.findByLabelText(/select user/i).check()
|
||||
})
|
||||
})
|
||||
})
|
||||
cy.get('button').contains('Remove manager').click()
|
||||
cy.findByRole('button', { name: /remove manager/i }).click()
|
||||
|
||||
cy.get('.alert').contains('Sorry, something went wrong')
|
||||
cy.findByRole('alert').should('contain.text', 'Sorry, something went wrong')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -35,23 +35,25 @@ describe('publisher managers', function () {
|
||||
})
|
||||
|
||||
it('renders the publisher management page', function () {
|
||||
cy.get('h1').contains('My Awesome Publisher')
|
||||
cy.findByRole('heading', { name: /my awesome publisher/i, level: 1 })
|
||||
|
||||
cy.get('ul').within(() => {
|
||||
cy.get('li:nth-child(2)').within(() => {
|
||||
cy.contains('john.doe@test.com')
|
||||
cy.contains('John Doe')
|
||||
cy.contains('15th Jan 2023')
|
||||
cy.get(`[aria-label="Invite not yet accepted"]`)
|
||||
})
|
||||
cy.findByTestId('managed-users-table')
|
||||
.find('tbody')
|
||||
.within(() => {
|
||||
cy.get('tr:nth-child(1)').within(() => {
|
||||
cy.findByText('john.doe@test.com')
|
||||
cy.findByText('John Doe')
|
||||
cy.findByText('15th Jan 2023')
|
||||
cy.findByText('Invite not yet accepted')
|
||||
})
|
||||
|
||||
cy.get('li:nth-child(3)').within(() => {
|
||||
cy.contains('bobby.lapointe@test.com')
|
||||
cy.contains('Bobby Lapointe')
|
||||
cy.contains('2nd Jan 2023')
|
||||
cy.get(`[aria-label="Accepted invite"]`)
|
||||
cy.get('tr:nth-child(2)').within(() => {
|
||||
cy.findByText('bobby.lapointe@test.com')
|
||||
cy.findByText('Bobby Lapointe')
|
||||
cy.findByText('2nd Jan 2023')
|
||||
cy.findByText('Accepted invite')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('sends an invite', function () {
|
||||
@@ -65,16 +67,20 @@ describe('publisher managers', function () {
|
||||
},
|
||||
})
|
||||
|
||||
cy.get('.form-control').type('someone.else@test.com')
|
||||
cy.get('button').click()
|
||||
|
||||
cy.get('ul').within(() => {
|
||||
cy.get('li:nth-child(4)').within(() => {
|
||||
cy.contains('someone.else@test.com')
|
||||
cy.contains('N/A')
|
||||
cy.get(`[aria-label="Invite not yet accepted"]`)
|
||||
})
|
||||
cy.findByTestId('add-members-form').within(() => {
|
||||
cy.findByRole('textbox').type('someone.else@test.com')
|
||||
cy.findByRole('button').click()
|
||||
})
|
||||
|
||||
cy.findByTestId('managed-users-table')
|
||||
.find('tbody')
|
||||
.within(() => {
|
||||
cy.get('tr:nth-child(3)').within(() => {
|
||||
cy.findByText('someone.else@test.com')
|
||||
cy.findByText('N/A')
|
||||
cy.findByText('Invite not yet accepted')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('tries to send an invite and displays the error', function () {
|
||||
@@ -87,31 +93,37 @@ describe('publisher managers', function () {
|
||||
},
|
||||
})
|
||||
|
||||
cy.get('.form-control').type('someone.else@test.com')
|
||||
cy.get('button').click()
|
||||
cy.get('.alert').contains('Error: User already added')
|
||||
cy.findByTestId('add-members-form').within(() => {
|
||||
cy.findByRole('textbox').type('someone.else@test.com')
|
||||
cy.findByRole('button').click()
|
||||
})
|
||||
cy.findByRole('alert').should('contain.text', 'Error: User already added')
|
||||
})
|
||||
|
||||
it('checks the select all checkbox', function () {
|
||||
cy.get('ul').within(() => {
|
||||
cy.get('li:nth-child(2)').within(() => {
|
||||
cy.get('.select-item').should('not.be.checked')
|
||||
cy.findByTestId('managed-users-table')
|
||||
.find('tbody')
|
||||
.within(() => {
|
||||
cy.get('tr:nth-child(1)').within(() => {
|
||||
cy.findByLabelText(/select user/i).should('not.be.checked')
|
||||
})
|
||||
cy.get('tr:nth-child(2)').within(() => {
|
||||
cy.findByLabelText(/select user/i).should('not.be.checked')
|
||||
})
|
||||
})
|
||||
cy.get('li:nth-child(3)').within(() => {
|
||||
cy.get('.select-item').should('not.be.checked')
|
||||
})
|
||||
})
|
||||
|
||||
cy.get('.select-all').click()
|
||||
|
||||
cy.get('ul').within(() => {
|
||||
cy.get('li:nth-child(2)').within(() => {
|
||||
cy.get('.select-item').should('be.checked')
|
||||
cy.findByTestId('managed-users-table')
|
||||
.find('tbody')
|
||||
.within(() => {
|
||||
cy.get('tr:nth-child(1)').within(() => {
|
||||
cy.findByLabelText(/select user/i).should('be.checked')
|
||||
})
|
||||
cy.get('tr:nth-child(2)').within(() => {
|
||||
cy.findByLabelText(/select user/i).should('be.checked')
|
||||
})
|
||||
})
|
||||
cy.get('li:nth-child(3)').within(() => {
|
||||
cy.get('.select-item').should('be.checked')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('remove a member', function () {
|
||||
@@ -119,22 +131,26 @@ describe('publisher managers', function () {
|
||||
statusCode: 200,
|
||||
})
|
||||
|
||||
cy.get('ul').within(() => {
|
||||
cy.get('li:nth-child(2)').within(() => {
|
||||
cy.get('.select-item').check()
|
||||
cy.findByTestId('managed-users-table')
|
||||
.find('tbody')
|
||||
.within(() => {
|
||||
cy.get('tr:nth-child(1)').within(() => {
|
||||
cy.findByLabelText(/select user/i).check()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
cy.get('button').contains('Remove manager').click()
|
||||
cy.findByRole('button', { name: 'Remove manager' }).click()
|
||||
|
||||
cy.get('ul').within(() => {
|
||||
cy.get('li:nth-child(2)').within(() => {
|
||||
cy.contains('bobby.lapointe@test.com')
|
||||
cy.contains('Bobby Lapointe')
|
||||
cy.contains('2nd Jan 2023')
|
||||
cy.get(`[aria-label="Accepted invite"]`)
|
||||
cy.findByTestId('managed-users-table')
|
||||
.find('tbody')
|
||||
.within(() => {
|
||||
cy.get('tr:nth-child(1)').within(() => {
|
||||
cy.findByText('bobby.lapointe@test.com')
|
||||
cy.findByText('Bobby Lapointe')
|
||||
cy.findByText('2nd Jan 2023')
|
||||
cy.findByText('Accepted invite')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('tries to remove a manager and displays the error', function () {
|
||||
@@ -142,13 +158,15 @@ describe('publisher managers', function () {
|
||||
statusCode: 500,
|
||||
})
|
||||
|
||||
cy.get('ul').within(() => {
|
||||
cy.get('li:nth-child(2)').within(() => {
|
||||
cy.get('.select-item').check()
|
||||
cy.findByTestId('managed-users-table')
|
||||
.find('tbody')
|
||||
.within(() => {
|
||||
cy.get('tr:nth-child(1)').within(() => {
|
||||
cy.findByLabelText(/select user/i).check()
|
||||
})
|
||||
})
|
||||
})
|
||||
cy.get('button').contains('Remove manager').click()
|
||||
cy.findByRole('button', { name: /remove manager/i }).click()
|
||||
|
||||
cy.get('.alert').contains('Sorry, something went wrong')
|
||||
cy.findByRole('alert').should('contain.text', 'Sorry, something went wrong')
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user