mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-15 06:33:55 +01:00
Merge pull request #35936 from overleaf/ii-workspaces-subscription-admin-settings
Shared Workspace settings for subscription admins GitOrigin-RevId: 61cc45a48aaf1709905e98b3cccf09b50e2afa84
This commit is contained in:
+135
@@ -2,6 +2,7 @@ import { expect } from 'chai'
|
||||
import { screen } from '@testing-library/react'
|
||||
import ManagedGroupSubscriptions from '../../../../../../frontend/js/features/subscription/components/dashboard/managed-group-subscriptions'
|
||||
import { ManagedGroupSubscription } from '../../../../../../types/subscription/dashboard/subscription'
|
||||
import { MetaTag } from '@/utils/meta'
|
||||
import {
|
||||
cleanUpContext,
|
||||
renderWithSubscriptionDashContext,
|
||||
@@ -531,5 +532,139 @@ describe('<ManagedGroupSubscriptions />', function () {
|
||||
expect(screen.queryByText('Feature controls')).to.be.null
|
||||
})
|
||||
})
|
||||
|
||||
describe('Shared Workspace', function () {
|
||||
// metaAttributesCache isn't cleared between tests, so ol-splitTestVariants leaks from
|
||||
// earlier tests. Every test below sets it explicitly to stay independent of run order.
|
||||
function splitTestVariants(enabled: boolean): MetaTag {
|
||||
return {
|
||||
name: 'ol-splitTestVariants',
|
||||
value: enabled ? { 'shared-workspace': 'enabled' } : {},
|
||||
}
|
||||
}
|
||||
|
||||
it('renders the feature controls row for a non-managed group when the feature is enabled', async function () {
|
||||
renderWithSubscriptionDashContext(<ManagedGroupSubscriptions />, {
|
||||
metaTags: [
|
||||
{
|
||||
name: 'ol-managedGroupSubscriptions',
|
||||
value: makeSubscription({
|
||||
managedUsersEnabled: false,
|
||||
features: {
|
||||
groupSSO: false,
|
||||
managedUsers: false,
|
||||
sharedWorkspace: true,
|
||||
},
|
||||
}),
|
||||
},
|
||||
{ name: 'ol-usersEmail', value: adminEmail },
|
||||
splitTestVariants(true),
|
||||
],
|
||||
})
|
||||
await screen.findByText('Feature controls')
|
||||
})
|
||||
|
||||
it('renders the feature controls row for a non-managed group when the feature is unset', async function () {
|
||||
renderWithSubscriptionDashContext(<ManagedGroupSubscriptions />, {
|
||||
metaTags: [
|
||||
{
|
||||
name: 'ol-managedGroupSubscriptions',
|
||||
value: makeSubscription({
|
||||
managedUsersEnabled: false,
|
||||
features: { groupSSO: false, managedUsers: false },
|
||||
}),
|
||||
},
|
||||
{ name: 'ol-usersEmail', value: adminEmail },
|
||||
splitTestVariants(true),
|
||||
],
|
||||
})
|
||||
await screen.findByText('Feature controls')
|
||||
})
|
||||
|
||||
it('does not render the feature controls row when the split test is not enabled', function () {
|
||||
renderWithSubscriptionDashContext(<ManagedGroupSubscriptions />, {
|
||||
metaTags: [
|
||||
{
|
||||
name: 'ol-managedGroupSubscriptions',
|
||||
value: makeSubscription({
|
||||
managedUsersEnabled: false,
|
||||
features: {
|
||||
groupSSO: false,
|
||||
managedUsers: false,
|
||||
sharedWorkspace: true,
|
||||
},
|
||||
}),
|
||||
},
|
||||
{ name: 'ol-usersEmail', value: adminEmail },
|
||||
splitTestVariants(false),
|
||||
],
|
||||
})
|
||||
expect(screen.queryByText('Feature controls')).to.be.null
|
||||
})
|
||||
|
||||
it('does not render the feature controls row when Overleaf Support has disabled the feature', function () {
|
||||
renderWithSubscriptionDashContext(<ManagedGroupSubscriptions />, {
|
||||
metaTags: [
|
||||
{
|
||||
name: 'ol-managedGroupSubscriptions',
|
||||
value: makeSubscription({
|
||||
managedUsersEnabled: false,
|
||||
features: {
|
||||
groupSSO: false,
|
||||
managedUsers: false,
|
||||
sharedWorkspace: false,
|
||||
},
|
||||
}),
|
||||
},
|
||||
{ name: 'ol-usersEmail', value: adminEmail },
|
||||
splitTestVariants(true),
|
||||
],
|
||||
})
|
||||
expect(screen.queryByText('Feature controls')).to.be.null
|
||||
})
|
||||
|
||||
it('does not render the feature controls row when the user is not the group admin', function () {
|
||||
renderWithSubscriptionDashContext(<ManagedGroupSubscriptions />, {
|
||||
metaTags: [
|
||||
{
|
||||
name: 'ol-managedGroupSubscriptions',
|
||||
value: makeSubscription({
|
||||
managedUsersEnabled: false,
|
||||
features: {
|
||||
groupSSO: false,
|
||||
managedUsers: false,
|
||||
sharedWorkspace: true,
|
||||
},
|
||||
}),
|
||||
},
|
||||
{ name: 'ol-usersEmail', value: 'other@example.com' },
|
||||
splitTestVariants(true),
|
||||
],
|
||||
})
|
||||
expect(screen.queryByText('Feature controls')).to.be.null
|
||||
})
|
||||
|
||||
it('does not render the feature controls row when the group is not on a Pro plan', function () {
|
||||
renderWithSubscriptionDashContext(<ManagedGroupSubscriptions />, {
|
||||
metaTags: [
|
||||
{
|
||||
name: 'ol-managedGroupSubscriptions',
|
||||
value: makeSubscription({
|
||||
managedUsersEnabled: false,
|
||||
planLevelName: 'Standard',
|
||||
features: {
|
||||
groupSSO: false,
|
||||
managedUsers: false,
|
||||
sharedWorkspace: true,
|
||||
},
|
||||
}),
|
||||
},
|
||||
{ name: 'ol-usersEmail', value: adminEmail },
|
||||
splitTestVariants(true),
|
||||
],
|
||||
})
|
||||
expect(screen.queryByText('Feature controls')).to.be.null
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1122,6 +1122,183 @@ describe('EmailBuilder', function () {
|
||||
})
|
||||
})
|
||||
|
||||
describe('groupSharedWorkspaceDisabledForOwner', function () {
|
||||
beforeEach(function (ctx) {
|
||||
ctx.emailAddress = 'example@overleaf.com'
|
||||
ctx.opts = {
|
||||
to: ctx.emailAddress,
|
||||
groupName: 'Example Group',
|
||||
firstName: 'Joe',
|
||||
}
|
||||
ctx.email = ctx.EmailBuilder.buildEmail(
|
||||
'groupSharedWorkspaceDisabledForOwner',
|
||||
ctx.opts
|
||||
)
|
||||
ctx.expectedUrl = `${ctx.settings.siteUrl}/project`
|
||||
})
|
||||
|
||||
it('should build the email', function (ctx) {
|
||||
expect(ctx.email.html).to.exist
|
||||
expect(ctx.email.text).to.exist
|
||||
})
|
||||
|
||||
describe('HTML email', function () {
|
||||
it('should include a CTA button and a fallback CTA link', function (ctx) {
|
||||
const dom = cheerio.load(ctx.email.html)
|
||||
expect(ctx.email.subject).to.equal(
|
||||
'Your shared workspace has been disabled'
|
||||
)
|
||||
expect(ctx.email.html).to.contain(
|
||||
'Your projects are back in your personal list.'
|
||||
)
|
||||
expect(ctx.email.html).to.contain(
|
||||
`Your group administrator has disabled the shared workspace for ${ctx.opts.groupName}.`
|
||||
)
|
||||
const buttonLink = dom('a:contains("Open your projects")')
|
||||
expect(buttonLink.length).to.equal(1)
|
||||
expect(buttonLink.attr('href')).to.equal(ctx.expectedUrl)
|
||||
expect(ctx.email.html).to.contain('copy and paste this link')
|
||||
expect(ctx.email.html).to.contain(ctx.expectedUrl)
|
||||
})
|
||||
})
|
||||
|
||||
describe('plain text email', function () {
|
||||
it('should contain the CTA link', function (ctx) {
|
||||
expect(ctx.email.text).to.contain(ctx.expectedUrl)
|
||||
})
|
||||
})
|
||||
|
||||
it('escapes the group name in the HTML email', function (ctx) {
|
||||
const email = ctx.EmailBuilder.buildEmail(
|
||||
'groupSharedWorkspaceDisabledForOwner',
|
||||
{ ...ctx.opts, groupName: '<script>alert(1)</script>' }
|
||||
)
|
||||
expect(email.html).to.not.contain('<script>alert(1)</script>')
|
||||
expect(email.html).to.contain('<script>alert(1)</script>')
|
||||
})
|
||||
})
|
||||
|
||||
describe('groupSharedWorkspaceDisabledForMember', function () {
|
||||
beforeEach(function (ctx) {
|
||||
ctx.emailAddress = 'example@overleaf.com'
|
||||
ctx.opts = {
|
||||
to: ctx.emailAddress,
|
||||
groupName: 'Example Group',
|
||||
firstName: 'Joe',
|
||||
}
|
||||
ctx.email = ctx.EmailBuilder.buildEmail(
|
||||
'groupSharedWorkspaceDisabledForMember',
|
||||
ctx.opts
|
||||
)
|
||||
ctx.expectedUrl = `${ctx.settings.siteUrl}/project`
|
||||
})
|
||||
|
||||
it('should build the email', function (ctx) {
|
||||
expect(ctx.email.html).to.exist
|
||||
expect(ctx.email.text).to.exist
|
||||
})
|
||||
|
||||
describe('HTML email', function () {
|
||||
it('should include a CTA button and a fallback CTA link', function (ctx) {
|
||||
const dom = cheerio.load(ctx.email.html)
|
||||
expect(ctx.email.subject).to.equal(
|
||||
"Your group's shared workspace has been disabled"
|
||||
)
|
||||
expect(ctx.email.html).to.contain(
|
||||
"Here's what's changed for your group."
|
||||
)
|
||||
expect(ctx.email.html).to.contain(
|
||||
`Your group administrator has disabled the shared workspace for ${ctx.opts.groupName}.`
|
||||
)
|
||||
const buttonLink = dom('a:contains("Open your projects")')
|
||||
expect(buttonLink.length).to.equal(1)
|
||||
expect(buttonLink.attr('href')).to.equal(ctx.expectedUrl)
|
||||
expect(ctx.email.html).to.contain('copy and paste this link')
|
||||
expect(ctx.email.html).to.contain(ctx.expectedUrl)
|
||||
})
|
||||
})
|
||||
|
||||
describe('plain text email', function () {
|
||||
it('should contain the CTA link', function (ctx) {
|
||||
expect(ctx.email.text).to.contain(ctx.expectedUrl)
|
||||
})
|
||||
})
|
||||
|
||||
it('escapes the group name in the HTML email', function (ctx) {
|
||||
const email = ctx.EmailBuilder.buildEmail(
|
||||
'groupSharedWorkspaceDisabledForMember',
|
||||
{ ...ctx.opts, groupName: '<script>alert(1)</script>' }
|
||||
)
|
||||
expect(email.html).to.not.contain('<script>alert(1)</script>')
|
||||
expect(email.html).to.contain('<script>alert(1)</script>')
|
||||
})
|
||||
})
|
||||
|
||||
describe('groupSharedWorkspaceDisabledForAdmin', function () {
|
||||
beforeEach(function (ctx) {
|
||||
ctx.emailAddress = 'example@overleaf.com'
|
||||
ctx.opts = {
|
||||
to: ctx.emailAddress,
|
||||
groupName: 'Example Group',
|
||||
firstName: 'Joe',
|
||||
}
|
||||
ctx.email = ctx.EmailBuilder.buildEmail(
|
||||
'groupSharedWorkspaceDisabledForAdmin',
|
||||
ctx.opts
|
||||
)
|
||||
ctx.expectedUrl = `${ctx.settings.siteUrl}/project`
|
||||
})
|
||||
|
||||
it('should build the email', function (ctx) {
|
||||
expect(ctx.email.html).to.exist
|
||||
expect(ctx.email.text).to.exist
|
||||
})
|
||||
|
||||
describe('HTML email', function () {
|
||||
it('should include a CTA button and a fallback CTA link', function (ctx) {
|
||||
const dom = cheerio.load(ctx.email.html)
|
||||
expect(ctx.email.subject).to.equal(
|
||||
`Shared workspace disabled for ${ctx.opts.groupName}`
|
||||
)
|
||||
expect(ctx.email.html).to.contain(
|
||||
"Here's a summary of what changed for your group."
|
||||
)
|
||||
expect(ctx.email.html).to.contain(
|
||||
`You’ve disabled the shared workspace for ${ctx.opts.groupName}. Here's a summary of what happened.`
|
||||
)
|
||||
expect(ctx.email.html).to.contain(
|
||||
'Projects in the workspace have been returned to their owners and are no longer visible to the whole group.'
|
||||
)
|
||||
expect(ctx.email.html).to.contain(
|
||||
'Each project is now shared only with the collaborators the owner had already added.'
|
||||
)
|
||||
expect(ctx.email.html).to.contain(
|
||||
'Group members have been notified of the change.'
|
||||
)
|
||||
const buttonLink = dom('a:contains("Open your projects")')
|
||||
expect(buttonLink.length).to.equal(1)
|
||||
expect(buttonLink.attr('href')).to.equal(ctx.expectedUrl)
|
||||
expect(ctx.email.html).to.contain('copy and paste this link')
|
||||
expect(ctx.email.html).to.contain(ctx.expectedUrl)
|
||||
})
|
||||
})
|
||||
|
||||
describe('plain text email', function () {
|
||||
it('should contain the CTA link', function (ctx) {
|
||||
expect(ctx.email.text).to.contain(ctx.expectedUrl)
|
||||
})
|
||||
})
|
||||
|
||||
it('escapes the group name in the HTML email', function (ctx) {
|
||||
const email = ctx.EmailBuilder.buildEmail(
|
||||
'groupSharedWorkspaceDisabledForAdmin',
|
||||
{ ...ctx.opts, groupName: '<script>alert(1)</script>' }
|
||||
)
|
||||
expect(email.html).to.not.contain('<script>alert(1)</script>')
|
||||
expect(email.html).to.contain('<script>alert(1)</script>')
|
||||
})
|
||||
})
|
||||
|
||||
describe('groupDomainCapturedByGroupChanged', function () {
|
||||
it('should build active-domain-capture email', function (ctx) {
|
||||
const email = ctx.EmailBuilder.buildEmail(
|
||||
|
||||
Reference in New Issue
Block a user