mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-15 06:33:55 +01:00
Merge pull request #31827 from overleaf/ii-project-sharing-access-denied
[web] Project sharing access denied redesign GitOrigin-RevId: b1e3016eb7ef9e2a502e0b67abc3b10c08531fe9
This commit is contained in:
@@ -79,10 +79,16 @@ describe('<TokenAccessPage/>', function () {
|
||||
|
||||
cy.wait('@grantRequest')
|
||||
|
||||
cy.get('h3').should('have.text', 'Join Project')
|
||||
cy.get('h4').should('have.text', 'Project not found')
|
||||
|
||||
cy.findByRole('heading', { name: /sorry, this project isn’t available/i })
|
||||
cy.findByText(/the link may be broken or you may not have access rights/i)
|
||||
cy.findByRole('button', { name: 'Join Project' }).should('not.exist')
|
||||
cy.contains(
|
||||
new RegExp(
|
||||
'you are currently logged in as test@example.com. ' +
|
||||
'you might need to log in with a different email address',
|
||||
'i'
|
||||
)
|
||||
)
|
||||
})
|
||||
|
||||
it('handles a redirect response', function () {
|
||||
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
import InviteNotValid from '@/features/share-project/invite-not-valid'
|
||||
|
||||
describe('<InviteNotValid />', function () {
|
||||
const email = 'test@example.com'
|
||||
|
||||
it('renders the sorry message', function () {
|
||||
cy.mount(<InviteNotValid email={email} />)
|
||||
|
||||
cy.findByRole('heading', {
|
||||
name: /sorry, this project isn’t available/i,
|
||||
})
|
||||
})
|
||||
|
||||
it('renders the broken link message', function () {
|
||||
cy.mount(<InviteNotValid email={email} />)
|
||||
|
||||
cy.findByText(/the link may be broken or you may not have access rights/i)
|
||||
})
|
||||
|
||||
it('renders a back to projects button linking to /project', function () {
|
||||
cy.mount(<InviteNotValid email={email} />)
|
||||
|
||||
cy.findByRole('link', { name: /back to my projects/i }).should(
|
||||
'have.attr',
|
||||
'href',
|
||||
'/project'
|
||||
)
|
||||
})
|
||||
|
||||
it('renders the logged-in email', function () {
|
||||
cy.mount(<InviteNotValid email={email} />)
|
||||
|
||||
cy.contains(
|
||||
new RegExp(
|
||||
`you are currently logged in as ${email}. you might need to log in with a different email address`,
|
||||
'i'
|
||||
)
|
||||
)
|
||||
})
|
||||
|
||||
it('does not render the CTA and email when email not provided', function () {
|
||||
cy.mount(<InviteNotValid />)
|
||||
|
||||
cy.findByRole('link', { name: /back to my projects/i }).should('not.exist')
|
||||
cy.contains(
|
||||
new RegExp(
|
||||
`you are currently logged in as ${email}. you might need to log in with a different email address`,
|
||||
'i'
|
||||
)
|
||||
).should('not.exist')
|
||||
})
|
||||
})
|
||||
@@ -1035,54 +1035,108 @@ describe('CollaboratorsInviteController', function () {
|
||||
})
|
||||
|
||||
describe('when the getInviteByToken does not produce an invite', function () {
|
||||
beforeEach(async function (ctx) {
|
||||
await new Promise(resolve => {
|
||||
ctx.CollaboratorsInviteGetter.promises.getInviteByToken.resolves(null)
|
||||
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.CollaboratorsInviteGetter.promises.getInviteByToken.resolves(
|
||||
null
|
||||
)
|
||||
ctx.res.callback = () => resolve()
|
||||
ctx.CollaboratorsInviteController.viewInvite(
|
||||
ctx.req,
|
||||
ctx.res,
|
||||
ctx.next
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
it('should render the not-valid view template', function (ctx) {
|
||||
expect(ctx.res.render).toHaveBeenCalledTimes(1)
|
||||
expect(ctx.res.render).toHaveBeenCalledWith(
|
||||
'project/invite/not-valid',
|
||||
expect.anything()
|
||||
)
|
||||
})
|
||||
|
||||
it('should not call next', function (ctx) {
|
||||
ctx.next.callCount.should.equal(0)
|
||||
})
|
||||
})
|
||||
|
||||
it('should render the not-valid view template', function (ctx) {
|
||||
expect(ctx.res.render).toHaveBeenCalledTimes(1)
|
||||
expect(ctx.res.render).toHaveBeenCalledWith(
|
||||
'project/invite/not-valid',
|
||||
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.CollaboratorsInviteGetter.promises.getInviteByToken.resolves(
|
||||
null
|
||||
)
|
||||
ctx.res.callback = () => resolve()
|
||||
ctx.CollaboratorsInviteController.viewInvite(
|
||||
ctx.req,
|
||||
ctx.res,
|
||||
ctx.next
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
it('should render the not-valid-legacy view template', function (ctx) {
|
||||
expect(ctx.res.render).toHaveBeenCalledTimes(1)
|
||||
expect(ctx.res.render).toHaveBeenCalledWith(
|
||||
'project/invite/not-valid-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.CollaboratorsInviteGetter.promises.getInviteByToken.resolves(
|
||||
null
|
||||
)
|
||||
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.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.CollaboratorsGetter.promises.isUserInvitedMemberOfProject
|
||||
.calledWith(ctx.currentUser._id, ctx.projectId)
|
||||
.should.equal(true)
|
||||
})
|
||||
|
||||
it('should not call User.getUser', function (ctx) {
|
||||
ctx.UserGetter.promises.getUser.callCount.should.equal(0)
|
||||
})
|
||||
it('should not call User.getUser', function (ctx) {
|
||||
ctx.UserGetter.promises.getUser.callCount.should.equal(0)
|
||||
})
|
||||
|
||||
it('should not call ProjectGetter.getProject', function (ctx) {
|
||||
ctx.ProjectGetter.promises.getProject.callCount.should.equal(0)
|
||||
it('should not call ProjectGetter.getProject', function (ctx) {
|
||||
ctx.ProjectGetter.promises.getProject.callCount.should.equal(0)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1132,54 +1186,102 @@ describe('CollaboratorsInviteController', function () {
|
||||
})
|
||||
|
||||
describe('when User.getUser does not find a user', function () {
|
||||
beforeEach(async function (ctx) {
|
||||
await new Promise(resolve => {
|
||||
ctx.UserGetter.promises.getUser.resolves(null)
|
||||
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.UserGetter.promises.getUser.resolves(null)
|
||||
ctx.res.callback = () => resolve()
|
||||
ctx.CollaboratorsInviteController.viewInvite(
|
||||
ctx.req,
|
||||
ctx.res,
|
||||
ctx.next
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
it('should render the not-valid view template', function (ctx) {
|
||||
expect(ctx.res.render).toHaveBeenCalledTimes(1)
|
||||
expect(ctx.res.render).toHaveBeenCalledWith(
|
||||
'project/invite/not-valid',
|
||||
expect.anything()
|
||||
)
|
||||
})
|
||||
|
||||
it('should not call next', function (ctx) {
|
||||
ctx.next.callCount.should.equal(0)
|
||||
})
|
||||
})
|
||||
|
||||
it('should render the not-valid view template', function (ctx) {
|
||||
expect(ctx.res.render).toHaveBeenCalledTimes(1)
|
||||
expect(ctx.res.render).toHaveBeenCalledWith(
|
||||
'project/invite/not-valid',
|
||||
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.UserGetter.promises.getUser.resolves(null)
|
||||
ctx.res.callback = () => resolve()
|
||||
ctx.CollaboratorsInviteController.viewInvite(
|
||||
ctx.req,
|
||||
ctx.res,
|
||||
ctx.next
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
it('should render the not-valid-legacy view template', function (ctx) {
|
||||
expect(ctx.res.render).toHaveBeenCalledTimes(1)
|
||||
expect(ctx.res.render).toHaveBeenCalledWith(
|
||||
'project/invite/not-valid-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.UserGetter.promises.getUser.resolves(null)
|
||||
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
|
||||
)
|
||||
})
|
||||
it('should call getInviteByToken', function (ctx) {
|
||||
ctx.CollaboratorsInviteGetter.promises.getInviteByToken.callCount.should.equal(
|
||||
1
|
||||
)
|
||||
})
|
||||
|
||||
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 not call ProjectGetter.getProject', function (ctx) {
|
||||
ctx.ProjectGetter.promises.getProject.callCount.should.equal(0)
|
||||
it('should not call ProjectGetter.getProject', function (ctx) {
|
||||
ctx.ProjectGetter.promises.getProject.callCount.should.equal(0)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1229,54 +1331,102 @@ describe('CollaboratorsInviteController', function () {
|
||||
})
|
||||
|
||||
describe('when Project.getUser does not find a user', function () {
|
||||
beforeEach(async function (ctx) {
|
||||
await new Promise(resolve => {
|
||||
ctx.ProjectGetter.promises.getProject.resolves(null)
|
||||
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.ProjectGetter.promises.getProject.resolves(null)
|
||||
ctx.res.callback = () => resolve()
|
||||
ctx.CollaboratorsInviteController.viewInvite(
|
||||
ctx.req,
|
||||
ctx.res,
|
||||
ctx.next
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
it('should render the not-valid view template', function (ctx) {
|
||||
expect(ctx.res.render).toHaveBeenCalledTimes(1)
|
||||
expect(ctx.res.render).toHaveBeenCalledWith(
|
||||
'project/invite/not-valid',
|
||||
expect.anything()
|
||||
)
|
||||
})
|
||||
|
||||
it('should not call next', function (ctx) {
|
||||
ctx.next.callCount.should.equal(0)
|
||||
})
|
||||
})
|
||||
|
||||
it('should render the not-valid view template', function (ctx) {
|
||||
expect(ctx.res.render).toHaveBeenCalledTimes(1)
|
||||
expect(ctx.res.render).toHaveBeenCalledWith(
|
||||
'project/invite/not-valid',
|
||||
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.ProjectGetter.promises.getProject.resolves(null)
|
||||
ctx.res.callback = () => resolve()
|
||||
ctx.CollaboratorsInviteController.viewInvite(
|
||||
ctx.req,
|
||||
ctx.res,
|
||||
ctx.next
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
it('should render the not-valid-legacy view template', function (ctx) {
|
||||
expect(ctx.res.render).toHaveBeenCalledTimes(1)
|
||||
expect(ctx.res.render).toHaveBeenCalledWith(
|
||||
'project/invite/not-valid-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.ProjectGetter.promises.getProject.resolves(null)
|
||||
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
|
||||
)
|
||||
})
|
||||
it('should call getInviteByToken', function (ctx) {
|
||||
ctx.CollaboratorsInviteGetter.promises.getInviteByToken.callCount.should.equal(
|
||||
1
|
||||
)
|
||||
})
|
||||
|
||||
it('should call 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 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)
|
||||
it('should call ProjectGetter.getProject', function (ctx) {
|
||||
ctx.ProjectGetter.promises.getProject.callCount.should.equal(1)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user