mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-06-10 06:39:01 +02:00
Merge pull request #31742 from overleaf/ii-project-sharing-join-project
[web] Join project page redesign GitOrigin-RevId: d182ec4fb744f384f824c9e63b534da02a9f8e99
This commit is contained in:
@@ -18,6 +18,7 @@ import ProjectAuditLogHandler from '../Project/ProjectAuditLogHandler.mjs'
|
||||
import Errors from '../Errors/Errors.js'
|
||||
import AuthenticationController from '../Authentication/AuthenticationController.mjs'
|
||||
import PrivilegeLevels from '../Authorization/PrivilegeLevels.mjs'
|
||||
import SplitTestHandler from '../SplitTests/SplitTestHandler.mjs'
|
||||
|
||||
// This rate limiter allows a different number of requests depending on the
|
||||
// number of callaborators a user is allowed. This is implemented by providing
|
||||
@@ -328,14 +329,26 @@ async function viewInvite(req, res) {
|
||||
// cleanup if set for register page
|
||||
delete req.session.sharedProjectData
|
||||
|
||||
const { variant: sharingUpdates } =
|
||||
await SplitTestHandler.promises.getAssignment(req, res, 'sharing-updates')
|
||||
|
||||
// finally render the invite
|
||||
res.render('project/invite/show', {
|
||||
invite,
|
||||
token,
|
||||
project,
|
||||
owner,
|
||||
title: 'Project Invite',
|
||||
})
|
||||
if (sharingUpdates === 'enabled') {
|
||||
res.render('project/invite/show', {
|
||||
token,
|
||||
projectName: project.name,
|
||||
projectId: invite.projectId,
|
||||
title: 'Project Invite',
|
||||
})
|
||||
} else {
|
||||
res.render('project/invite/show-legacy', {
|
||||
invite,
|
||||
token,
|
||||
project,
|
||||
owner,
|
||||
title: 'Project Invite',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async function acceptInvite(req, res) {
|
||||
|
||||
@@ -20,6 +20,7 @@ import UrlHelper from '../Helpers/UrlHelper.mjs'
|
||||
import UserGetter from '../User/UserGetter.mjs'
|
||||
import Settings from '@overleaf/settings'
|
||||
import LimitationsManager from '../Subscription/LimitationsManager.mjs'
|
||||
import SplitTestHandler from '../SplitTests/SplitTestHandler.mjs'
|
||||
|
||||
const { getSafeAdminDomainRedirect } = UrlHelper
|
||||
const { canRedirectToAdminDomain } = AdminAuthorizationHelper
|
||||
@@ -113,7 +114,15 @@ async function tokenAccessPage(req, res, next) {
|
||||
}
|
||||
}
|
||||
|
||||
res.render('project/token/access-react', {
|
||||
const { variant: sharingUpdates } =
|
||||
await SplitTestHandler.promises.getAssignment(req, res, 'sharing-updates')
|
||||
|
||||
const viewPath =
|
||||
sharingUpdates === 'enabled'
|
||||
? 'project/token/access-react'
|
||||
: 'project/token/access-react-legacy'
|
||||
|
||||
res.render(viewPath, {
|
||||
postUrl: makePostUrl(token),
|
||||
})
|
||||
} catch (err) {
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
extends ../../layout-marketing
|
||||
|
||||
block content
|
||||
main#main-content.content.content-alt
|
||||
.container
|
||||
.row
|
||||
.col-12.col-md-8.col-md-offset-2.offset-md-2
|
||||
.card.project-invite-accept
|
||||
.card-body
|
||||
.page-header.text-center
|
||||
h1 #{translate("user_wants_you_to_see_project", {username:owner.first_name, projectname:""})}
|
||||
br
|
||||
em #{project.name}
|
||||
.row.text-center
|
||||
.col-12.col-md-12
|
||||
p
|
||||
| #{translate("accepting_invite_as")}
|
||||
em #{user.email}
|
||||
.row
|
||||
.col-12.col-md-12
|
||||
form.form(
|
||||
data-ol-regular-form
|
||||
method='POST'
|
||||
action='/project/' + invite.projectId + '/invite/token/' + token + '/accept'
|
||||
)
|
||||
input(name='_csrf' type='hidden' value=csrfToken)
|
||||
input(name='token' type='hidden' value=token)
|
||||
.form-group.text-center
|
||||
button.btn.btn-lg.btn-primary(
|
||||
type='submit'
|
||||
data-ol-disabled-inflight
|
||||
)
|
||||
span(data-ol-inflight='idle') #{translate("join_project")}
|
||||
span(hidden data-ol-inflight='pending') #{translate("joining")}…
|
||||
.form-group.text-center
|
||||
@@ -1,35 +1,17 @@
|
||||
extends ../../layout-marketing
|
||||
extends ../../layout-website-redesign
|
||||
|
||||
block vars
|
||||
- isWebsiteRedesign = true
|
||||
|
||||
block entrypointVar
|
||||
- entrypoint = 'pages/project-invite'
|
||||
|
||||
block append meta
|
||||
meta(name='ol-user' data-type='json' content=user)
|
||||
meta(name='ol-inviteToken' data-type='string' content=token)
|
||||
meta(name='ol-projectName' data-type='string' content=projectName)
|
||||
meta(name='ol-project_id' data-type='string' content=projectId)
|
||||
|
||||
block content
|
||||
main#main-content.content.content-alt
|
||||
.container
|
||||
.row
|
||||
.col-12.col-md-8.col-md-offset-2.offset-md-2
|
||||
.card.project-invite-accept
|
||||
.card-body
|
||||
.page-header.text-center
|
||||
h1 #{translate("user_wants_you_to_see_project", {username:owner.first_name, projectname:""})}
|
||||
br
|
||||
em #{project.name}
|
||||
.row.text-center
|
||||
.col-12.col-md-12
|
||||
p
|
||||
| #{translate("accepting_invite_as")}
|
||||
em #{user.email}
|
||||
.row
|
||||
.col-12.col-md-12
|
||||
form.form(
|
||||
data-ol-regular-form
|
||||
method='POST'
|
||||
action='/project/' + invite.projectId + '/invite/token/' + token + '/accept'
|
||||
)
|
||||
input(name='_csrf' type='hidden' value=csrfToken)
|
||||
input(name='token' type='hidden' value=token)
|
||||
.form-group.text-center
|
||||
button.btn.btn-lg.btn-primary(
|
||||
type='submit'
|
||||
data-ol-disabled-inflight
|
||||
)
|
||||
span(data-ol-inflight='idle') #{translate("join_project")}
|
||||
span(hidden data-ol-inflight='pending') #{translate("joining")}…
|
||||
.form-group.text-center
|
||||
#project-invite-page
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
extends ../../layout-react
|
||||
|
||||
block entrypointVar
|
||||
- entrypoint = 'pages/token-access'
|
||||
|
||||
block vars
|
||||
- var suppressFooter = true
|
||||
- var suppressPugCookieBanner = true
|
||||
- var suppressSkipToContent = true
|
||||
|
||||
block append meta
|
||||
meta(name='ol-postUrl' data-type='string' content=postUrl)
|
||||
meta(name='ol-user' data-type='json' content=user)
|
||||
|
||||
block content
|
||||
#token-access-page
|
||||
@@ -1,16 +1,15 @@
|
||||
extends ../../layout-react
|
||||
extends ../../layout-website-redesign
|
||||
|
||||
block entrypointVar
|
||||
- entrypoint = 'pages/token-access'
|
||||
|
||||
block vars
|
||||
- var suppressFooter = true
|
||||
- var suppressPugCookieBanner = true
|
||||
- var suppressSkipToContent = true
|
||||
|
||||
block append meta
|
||||
meta(name='ol-postUrl' data-type='string' content=postUrl)
|
||||
meta(name='ol-user' data-type='json' content=user)
|
||||
|
||||
block vars
|
||||
- isWebsiteRedesign = true
|
||||
|
||||
block content
|
||||
#token-access-page
|
||||
main#main-content.content.content-alt
|
||||
#token-access-page
|
||||
|
||||
@@ -956,6 +956,7 @@
|
||||
"join_now": "",
|
||||
"join_overleaf_labs": "",
|
||||
"join_project": "",
|
||||
"join_project_lowercase": "",
|
||||
"join_team_explanation": "",
|
||||
"join_x_enterprise_group": "",
|
||||
"join_x_managed_enterprise_group": "",
|
||||
@@ -2337,6 +2338,7 @@
|
||||
"your_git_access_info_bullet_5": "",
|
||||
"your_git_access_tokens": "",
|
||||
"your_message_to_collaborators": "",
|
||||
"your_name_and_email_address_will_be_visible_to_project_editors": "",
|
||||
"your_name_and_email_address_will_be_visible_to_the_project_owner_and_other_editors": "",
|
||||
"your_new_plan": "",
|
||||
"your_password_was_detected": "",
|
||||
@@ -2362,6 +2364,7 @@
|
||||
"youre_already_setup_for_sso": "",
|
||||
"youre_creating_account_for_x_it_will_be_managed_by_y": "",
|
||||
"youre_joining": "",
|
||||
"youre_joining_x_as_y": "",
|
||||
"youre_not_eligible_for_a_free_trial": "",
|
||||
"youre_on_free_trial_which_ends_on": "",
|
||||
"youre_signed_in_as_logout": "",
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import useWaitForI18n from '@/shared/hooks/use-wait-for-i18n'
|
||||
import getMeta from '@/utils/meta'
|
||||
import Invite from '@/features/share-project/invite'
|
||||
import useAsync from '@/shared/hooks/use-async'
|
||||
import { postJSON } from '@/infrastructure/fetch-json'
|
||||
import { useLocation } from '@/shared/hooks/use-location'
|
||||
import { debugConsole } from '@/utils/debugging'
|
||||
|
||||
export default function InviteRoot() {
|
||||
const user = getMeta('ol-user')
|
||||
const projectName = getMeta('ol-projectName')
|
||||
const projectId = getMeta('ol-project_id')
|
||||
const token = getMeta('ol-inviteToken')
|
||||
const location = useLocation()
|
||||
const { isLoading, runAsync } = useAsync()
|
||||
const { isReady } = useWaitForI18n()
|
||||
|
||||
const handleSubmit = () => {
|
||||
runAsync(postJSON(`/project/${projectId}/invite/token/${token}/accept`))
|
||||
.then(() => location.assign(`/project/${projectId}`))
|
||||
.catch(debugConsole.error)
|
||||
}
|
||||
|
||||
if (!isReady) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<Invite
|
||||
projectName={projectName}
|
||||
email={user.email}
|
||||
submitHandler={handleSubmit}
|
||||
isLoading={isLoading}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import OLRow from '@/shared/components/ol/ol-row'
|
||||
import OLCol from '@/shared/components/ol/ol-col'
|
||||
import OLButton from '@/shared/components/ol/ol-button'
|
||||
import overleafLogo from '@/shared/svgs/overleaf-logo.svg'
|
||||
import getMeta from '@/utils/meta'
|
||||
|
||||
type InviteProps = {
|
||||
projectName: string
|
||||
email: string
|
||||
submitHandler: () => void
|
||||
isLoading?: boolean
|
||||
}
|
||||
|
||||
function Invite({ projectName, email, submitHandler, isLoading }: InviteProps) {
|
||||
const { t } = useTranslation()
|
||||
const { appName } = getMeta('ol-ExposedSettings')
|
||||
|
||||
return (
|
||||
<div className="container">
|
||||
<OLRow>
|
||||
<OLCol lg={{ span: 6, offset: 3 }}>
|
||||
<div className="project-join-container">
|
||||
<img src={overleafLogo} alt={appName} />
|
||||
<h1 className="h4 mb-2">
|
||||
{t('youre_joining_x_as_y', { projectName, email })}
|
||||
</h1>
|
||||
<div className="mb-4">
|
||||
{t(
|
||||
'your_name_and_email_address_will_be_visible_to_project_editors'
|
||||
)}
|
||||
</div>
|
||||
<OLButton
|
||||
variant="primary"
|
||||
size="lg"
|
||||
disabled={isLoading}
|
||||
isLoading={isLoading}
|
||||
loadingLabel={`${t('joining')}…`}
|
||||
onClick={submitHandler}
|
||||
>
|
||||
{t('join_project_lowercase')}
|
||||
</OLButton>
|
||||
</div>
|
||||
</OLCol>
|
||||
</OLRow>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Invite
|
||||
@@ -1,6 +1,8 @@
|
||||
import { FC } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import getMeta from '@/utils/meta'
|
||||
import { useFeatureFlag } from '@/shared/context/split-test-context'
|
||||
import Invite from '@/features/share-project/invite'
|
||||
|
||||
export type RequireAcceptData = {
|
||||
projectName?: string
|
||||
@@ -12,6 +14,17 @@ export const RequireAcceptScreen: FC<{
|
||||
}> = ({ requireAcceptData, sendPostRequest }) => {
|
||||
const { t } = useTranslation()
|
||||
const user = getMeta('ol-user')
|
||||
const isSharingUpdatesEnabled = useFeatureFlag('sharing-updates')
|
||||
|
||||
if (isSharingUpdatesEnabled) {
|
||||
return (
|
||||
<Invite
|
||||
projectName={requireAcceptData.projectName || 'This project'}
|
||||
email={user?.email || ''}
|
||||
submitHandler={() => sendPostRequest(true)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="container">
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
} from '@/features/token-access/components/require-accept-screen'
|
||||
import importOverleafModules from '../../../../macros/import-overleaf-module.macro'
|
||||
import MaterialIcon from '@/shared/components/material-icon'
|
||||
import { useFeatureFlag } from '@/shared/context/split-test-context'
|
||||
|
||||
type Mode = 'access-attempt' | 'v1Import' | 'requireAccept'
|
||||
|
||||
@@ -39,6 +40,7 @@ function TokenAccessRoot() {
|
||||
const [loadingScreenBrandHeight, setLoadingScreenBrandHeight] =
|
||||
useState('0px')
|
||||
const location = useLocation()
|
||||
const isSharingUpdatesEnabled = useFeatureFlag('sharing-updates')
|
||||
|
||||
const sendPostRequest = useCallback(
|
||||
(confirmedByUser = false) => {
|
||||
@@ -112,11 +114,16 @@ function TokenAccessRoot() {
|
||||
|
||||
return (
|
||||
<div className="token-access-container">
|
||||
<div className="token-access-action-header">
|
||||
<a href="/project" className="token-access-home-link">
|
||||
<MaterialIcon type="arrow_left_alt" style={{ fontSize: 'inherit' }} />
|
||||
</a>
|
||||
</div>
|
||||
{!isSharingUpdatesEnabled && (
|
||||
<div className="token-access-action-header">
|
||||
<a href="/project" className="token-access-home-link">
|
||||
<MaterialIcon
|
||||
type="arrow_left_alt"
|
||||
style={{ fontSize: 'inherit' }}
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
<div className="token-access-content">
|
||||
{mode === 'access-attempt' && (
|
||||
<AccessAttemptScreen
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import './../utils/meta'
|
||||
import '../utils/webpack-public-path'
|
||||
import './../infrastructure/error-reporter'
|
||||
import '@/i18n'
|
||||
import { createRoot } from 'react-dom/client'
|
||||
import InviteRoot from '@/features/share-project/invite-root'
|
||||
|
||||
const element = document.getElementById('project-invite-page')
|
||||
if (element) {
|
||||
const root = createRoot(element)
|
||||
root.render(<InviteRoot />)
|
||||
}
|
||||
@@ -4,9 +4,14 @@ import './../infrastructure/error-reporter'
|
||||
import '@/i18n'
|
||||
import { createRoot } from 'react-dom/client'
|
||||
import TokenAccessRoot from '../features/token-access/components/token-access-root'
|
||||
import { SplitTestProvider } from '@/shared/context/split-test-context'
|
||||
|
||||
const element = document.getElementById('token-access-page')
|
||||
if (element) {
|
||||
const root = createRoot(element)
|
||||
root.render(<TokenAccessRoot />)
|
||||
root.render(
|
||||
<SplitTestProvider>
|
||||
<TokenAccessRoot />
|
||||
</SplitTestProvider>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="104" height="120" viewBox="0 0 104 120" fill="none"><path d="M103.521 3.769C87.2881 -2.58618 28.56 -4.88324 28.4835 30.1851C11.3321 41.1344 0 58.9749 0 78.117C0 101.241 18.7593 120 41.883 120C65.0067 120 83.7659 101.241 83.7659 78.117C83.7659 60.2766 72.5869 44.9629 56.8138 38.9905C53.7511 37.842 47.1662 35.7746 41.9595 36.234C34.4558 40.9813 25.2676 50.7821 20.9798 60.5828C27.4115 52.8494 37.442 49.4804 46.4005 50.9352C59.4937 53.0791 69.5242 64.4113 69.5242 78.1936C69.5242 93.4307 57.1967 105.758 41.9595 105.758C33.537 105.758 26.0333 102.006 20.9798 96.1106C13.3995 87.3052 11.4853 77.8108 13.0166 68.546C18.2999 36.0809 56.8138 17.6279 85.4504 10.507C76.1091 15.484 59.264 23.6002 47.4725 32.4056C81.8517 45.7285 87.4412 16.7091 103.521 3.769Z" fill="#046530"/></svg>
|
||||
|
After Width: | Height: | Size: 825 B |
@@ -23,3 +23,8 @@
|
||||
font-size: var(--font-size-02);
|
||||
}
|
||||
}
|
||||
|
||||
.project-join-container {
|
||||
padding-top: var(--spacing-15);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@@ -1214,6 +1214,7 @@
|
||||
"join_now": "Join now",
|
||||
"join_overleaf_labs": "Join Overleaf Labs",
|
||||
"join_project": "Join Project",
|
||||
"join_project_lowercase": "Join project",
|
||||
"join_sl_to_view_project": "Join __appName__ to view this project",
|
||||
"join_team_explanation": "Please click the button below to join the group subscription and enjoy the benefits of an upgraded __appName__ account",
|
||||
"join_x_enterprise_group": "Join __companyName__ enterprise group",
|
||||
@@ -2905,6 +2906,7 @@
|
||||
"your_git_access_info_bullet_5": "Previously generated tokens will be shown here.",
|
||||
"your_git_access_tokens": "Your Git authentication tokens",
|
||||
"your_message_to_collaborators": "Send a message to your collaborators",
|
||||
"your_name_and_email_address_will_be_visible_to_project_editors": "Your name and email address will be visible to project editors.",
|
||||
"your_name_and_email_address_will_be_visible_to_the_project_owner_and_other_editors": "Your name and email address will be visible to the project owner and other editors.",
|
||||
"your_new_plan": "Your new plan",
|
||||
"your_password_has_been_reset": "Your password has been reset",
|
||||
@@ -2934,6 +2936,7 @@
|
||||
"youre_already_setup_for_sso": "You’re already set up for SSO",
|
||||
"youre_creating_account_for_x_it_will_be_managed_by_y": "You’re creating an account for __email__. It will be managed by __companyName__.",
|
||||
"youre_joining": "You’re joining",
|
||||
"youre_joining_x_as_y": "You’re joining __projectName__ as __email__",
|
||||
"youre_not_eligible_for_a_free_trial": "You’re not eligible for a free trial. Upgrade to start using premium features.",
|
||||
"youre_on_free_trial_which_ends_on": "You’re on a free trial which ends on <0>__date__</0>.",
|
||||
"youre_signed_in_as_logout": "You’re signed in as <0>__email__</0>. <1>Log out.</1>",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import TokenAccessPage from '@/features/token-access/components/token-access-root'
|
||||
import { SplitTestProvider } from '@/shared/context/split-test-context'
|
||||
import { location } from '@/shared/components/location'
|
||||
|
||||
describe('<TokenAccessPage/>', function () {
|
||||
@@ -9,6 +10,9 @@ describe('<TokenAccessPage/>', function () {
|
||||
cy.window().then(win => {
|
||||
win.metaAttributesCache.set('ol-postUrl', url)
|
||||
win.metaAttributesCache.set('ol-user', { email: 'test@example.com' })
|
||||
win.metaAttributesCache.set('ol-splitTestVariants', {
|
||||
'sharing-updates': 'enabled',
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -22,15 +26,21 @@ describe('<TokenAccessPage/>', function () {
|
||||
}
|
||||
).as('grantRequest')
|
||||
|
||||
cy.mount(<TokenAccessPage />)
|
||||
cy.mount(
|
||||
<SplitTestProvider>
|
||||
<TokenAccessPage />
|
||||
</SplitTestProvider>
|
||||
)
|
||||
|
||||
cy.wait('@grantRequest').then(interception => {
|
||||
expect(interception.request.body.confirmedByUser).to.be.false
|
||||
})
|
||||
|
||||
cy.get('.link-sharing-invite-header').should(
|
||||
'have.text',
|
||||
['You’re joining', 'Test Project', 'as test@example.com'].join('')
|
||||
cy.findByRole('heading', {
|
||||
name: /you’re joining Test Project as test@example.com/i,
|
||||
})
|
||||
cy.findByText(
|
||||
/your name and email address will be visible to project editors/i
|
||||
)
|
||||
|
||||
cy.intercept(
|
||||
@@ -44,7 +54,7 @@ describe('<TokenAccessPage/>', function () {
|
||||
|
||||
cy.stub(location, 'replace').as('replaceLocation')
|
||||
|
||||
cy.findByRole('button', { name: 'OK, join project' }).click()
|
||||
cy.findByRole('button', { name: /join project/i }).click()
|
||||
|
||||
cy.wait('@confirmedGrantRequest').then(interception => {
|
||||
expect(interception.request.body.confirmedByUser).to.be.true
|
||||
@@ -61,7 +71,11 @@ describe('<TokenAccessPage/>', function () {
|
||||
'grantRequest'
|
||||
)
|
||||
|
||||
cy.mount(<TokenAccessPage />)
|
||||
cy.mount(
|
||||
<SplitTestProvider>
|
||||
<TokenAccessPage />
|
||||
</SplitTestProvider>
|
||||
)
|
||||
|
||||
cy.wait('@grantRequest')
|
||||
|
||||
@@ -83,7 +97,11 @@ describe('<TokenAccessPage/>', function () {
|
||||
|
||||
cy.stub(location, 'replace').as('replaceLocation')
|
||||
|
||||
cy.mount(<TokenAccessPage />)
|
||||
cy.mount(
|
||||
<SplitTestProvider>
|
||||
<TokenAccessPage />
|
||||
</SplitTestProvider>
|
||||
)
|
||||
|
||||
cy.wait('@grantRequest')
|
||||
|
||||
@@ -102,7 +120,11 @@ describe('<TokenAccessPage/>', function () {
|
||||
|
||||
cy.stub(location, 'replace').as('replaceLocation')
|
||||
|
||||
cy.mount(<TokenAccessPage />)
|
||||
cy.mount(
|
||||
<SplitTestProvider>
|
||||
<TokenAccessPage />
|
||||
</SplitTestProvider>
|
||||
)
|
||||
|
||||
cy.wait('@grantRequest')
|
||||
|
||||
@@ -125,7 +147,11 @@ describe('<TokenAccessPage/>', function () {
|
||||
|
||||
cy.stub(location, 'replace').as('replaceLocation')
|
||||
|
||||
cy.mount(<TokenAccessPage />)
|
||||
cy.mount(
|
||||
<SplitTestProvider>
|
||||
<TokenAccessPage />
|
||||
</SplitTestProvider>
|
||||
)
|
||||
|
||||
cy.wait('@grantRequest')
|
||||
|
||||
@@ -149,7 +175,11 @@ describe('<TokenAccessPage/>', function () {
|
||||
|
||||
cy.stub(location, 'replace').as('replaceLocation')
|
||||
|
||||
cy.mount(<TokenAccessPage />)
|
||||
cy.mount(
|
||||
<SplitTestProvider>
|
||||
<TokenAccessPage />
|
||||
</SplitTestProvider>
|
||||
)
|
||||
|
||||
cy.wait('@grantRequest')
|
||||
|
||||
|
||||
@@ -763,59 +763,105 @@ describe('CollaboratorsInviteController', function () {
|
||||
})
|
||||
|
||||
describe('when the token is valid', function () {
|
||||
beforeEach(async function (ctx) {
|
||||
await new Promise(resolve => {
|
||||
ctx.res.callback = () => resolve()
|
||||
ctx.CollaboratorsInviteController.viewInvite(
|
||||
ctx.req,
|
||||
ctx.res,
|
||||
ctx.next
|
||||
describe('when the sharing-updates variant is "enabled"', function () {
|
||||
beforeEach(async function (ctx) {
|
||||
ctx.SplitTestHandler.promises.getAssignment.resolves({
|
||||
variant: 'enabled',
|
||||
})
|
||||
await new Promise(resolve => {
|
||||
ctx.res.callback = () => resolve()
|
||||
ctx.CollaboratorsInviteController.viewInvite(
|
||||
ctx.req,
|
||||
ctx.res,
|
||||
ctx.next
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
it('should render the new view template', function (ctx) {
|
||||
expect(ctx.res.render).toHaveBeenCalledTimes(1)
|
||||
expect(ctx.res.render).toHaveBeenCalledWith(
|
||||
'project/invite/show',
|
||||
expect.anything()
|
||||
)
|
||||
})
|
||||
|
||||
it('should not call next', function (ctx) {
|
||||
ctx.next.callCount.should.equal(0)
|
||||
})
|
||||
})
|
||||
|
||||
it('should render the view template', function (ctx) {
|
||||
expect(ctx.res.render).toHaveBeenCalledTimes(1)
|
||||
expect(ctx.res.render).toHaveBeenCalledWith(
|
||||
'project/invite/show',
|
||||
expect.anything()
|
||||
)
|
||||
describe('when the sharing-updates variant is "default"', function () {
|
||||
beforeEach(async function (ctx) {
|
||||
ctx.SplitTestHandler.promises.getAssignment.resolves({
|
||||
variant: 'default',
|
||||
})
|
||||
await new Promise(resolve => {
|
||||
ctx.res.callback = () => resolve()
|
||||
ctx.CollaboratorsInviteController.viewInvite(
|
||||
ctx.req,
|
||||
ctx.res,
|
||||
ctx.next
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
it('should render the legacy view template', function (ctx) {
|
||||
expect(ctx.res.render).toHaveBeenCalledTimes(1)
|
||||
expect(ctx.res.render).toHaveBeenCalledWith(
|
||||
'project/invite/show-legacy',
|
||||
expect.anything()
|
||||
)
|
||||
})
|
||||
|
||||
it('should not call next', function (ctx) {
|
||||
ctx.next.callCount.should.equal(0)
|
||||
})
|
||||
})
|
||||
|
||||
it('should not call next', function (ctx) {
|
||||
ctx.next.callCount.should.equal(0)
|
||||
})
|
||||
describe('common behaviour', function () {
|
||||
beforeEach(async function (ctx) {
|
||||
await new Promise(resolve => {
|
||||
ctx.res.callback = () => resolve()
|
||||
ctx.CollaboratorsInviteController.viewInvite(
|
||||
ctx.req,
|
||||
ctx.res,
|
||||
ctx.next
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
it('should call CollaboratorsGetter.isUserInvitedMemberOfProject', function (ctx) {
|
||||
ctx.CollaboratorsGetter.promises.isUserInvitedMemberOfProject.callCount.should.equal(
|
||||
1
|
||||
)
|
||||
ctx.CollaboratorsGetter.promises.isUserInvitedMemberOfProject
|
||||
.calledWith(ctx.currentUser._id, ctx.projectId)
|
||||
.should.equal(true)
|
||||
})
|
||||
it('should call CollaboratorsGetter.isUserInvitedMemberOfProject', function (ctx) {
|
||||
ctx.CollaboratorsGetter.promises.isUserInvitedMemberOfProject.callCount.should.equal(
|
||||
1
|
||||
)
|
||||
ctx.CollaboratorsGetter.promises.isUserInvitedMemberOfProject
|
||||
.calledWith(ctx.currentUser._id, ctx.projectId)
|
||||
.should.equal(true)
|
||||
})
|
||||
|
||||
it('should call getInviteByToken', function (ctx) {
|
||||
ctx.CollaboratorsInviteGetter.promises.getInviteByToken.callCount.should.equal(
|
||||
1
|
||||
)
|
||||
ctx.CollaboratorsInviteGetter.promises.getInviteByToken
|
||||
.calledWith(ctx.fakeProject._id, ctx.invite.token)
|
||||
.should.equal(true)
|
||||
})
|
||||
it('should call getInviteByToken', function (ctx) {
|
||||
ctx.CollaboratorsInviteGetter.promises.getInviteByToken.callCount.should.equal(
|
||||
1
|
||||
)
|
||||
ctx.CollaboratorsInviteGetter.promises.getInviteByToken
|
||||
.calledWith(ctx.fakeProject._id, ctx.invite.token)
|
||||
.should.equal(true)
|
||||
})
|
||||
|
||||
it('should call User.getUser', function (ctx) {
|
||||
ctx.UserGetter.promises.getUser.callCount.should.equal(1)
|
||||
ctx.UserGetter.promises.getUser
|
||||
.calledWith({ _id: ctx.fakeProject.owner_ref })
|
||||
.should.equal(true)
|
||||
})
|
||||
it('should call User.getUser', function (ctx) {
|
||||
ctx.UserGetter.promises.getUser.callCount.should.equal(1)
|
||||
ctx.UserGetter.promises.getUser
|
||||
.calledWith({ _id: ctx.fakeProject.owner_ref })
|
||||
.should.equal(true)
|
||||
})
|
||||
|
||||
it('should call ProjectGetter.getProject', function (ctx) {
|
||||
ctx.ProjectGetter.promises.getProject.callCount.should.equal(1)
|
||||
ctx.ProjectGetter.promises.getProject
|
||||
.calledWith(ctx.projectId)
|
||||
.should.equal(true)
|
||||
it('should call ProjectGetter.getProject', function (ctx) {
|
||||
ctx.ProjectGetter.promises.getProject.callCount.should.equal(1)
|
||||
ctx.ProjectGetter.promises.getProject
|
||||
.calledWith(ctx.projectId)
|
||||
.should.equal(true)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user