From aacba6ca5f31472f93a057280eabf447e4aef383 Mon Sep 17 00:00:00 2001 From: Andrew Rumble Date: Wed, 17 Sep 2025 09:05:15 +0100 Subject: [PATCH] Use valid input in test suites GitOrigin-RevId: 3529a169062df54af54ca32f00804c211a129bf1 --- .../CollaboratorsController.test.mjs | 33 +++++++----- .../CollaboratorsInviteController.test.mjs | 2 +- .../src/Editor/EditorHttpController.test.mjs | 52 +++++++++---------- .../PasswordResetController.test.mjs | 12 +++-- 4 files changed, 56 insertions(+), 43 deletions(-) diff --git a/services/web/test/unit/src/Collaborators/CollaboratorsController.test.mjs b/services/web/test/unit/src/Collaborators/CollaboratorsController.test.mjs index b8b1500881..fb36926c7e 100644 --- a/services/web/test/unit/src/Collaborators/CollaboratorsController.test.mjs +++ b/services/web/test/unit/src/Collaborators/CollaboratorsController.test.mjs @@ -1,4 +1,4 @@ -import { expect, vi } from 'vitest' +import { beforeEach, describe, expect, it, vi } from 'vitest' import sinon from 'sinon' import mongodb from 'mongodb-legacy' import Errors from '../../../../app/src/Features/Errors/Errors.js' @@ -323,8 +323,8 @@ describe('CollaboratorsController', function () { describe('setCollaboratorInfo', function () { beforeEach(function (ctx) { ctx.req.params = { - Project_id: ctx.projectId, - user_id: ctx.user._id, + Project_id: ctx.projectId.toString(), + user_id: ctx.user._id.toString(), } ctx.req.body = { privilegeLevel: 'readOnly' } }) @@ -335,7 +335,11 @@ describe('CollaboratorsController', function () { expect(status).to.equal(204) expect( ctx.CollaboratorsHandler.promises.setCollaboratorPrivilegeLevel - ).to.have.been.calledWith(ctx.projectId, ctx.user._id, 'readOnly') + ).to.have.been.calledWith( + ctx.projectId.toString(), + ctx.user._id.toString(), + 'readOnly' + ) resolve() } ctx.CollaboratorsController.setCollaboratorInfo(ctx.req, ctx.res) @@ -389,8 +393,8 @@ describe('CollaboratorsController', function () { ctx.LimitationsManager.promises .canChangeCollaboratorPrivilegeLevel ).to.have.been.calledWith( - ctx.projectId, - ctx.user._id, + ctx.projectId.toString(), + ctx.user._id.toString(), 'readAndWrite' ) resolve() @@ -416,8 +420,8 @@ describe('CollaboratorsController', function () { ctx.LimitationsManager.promises .canChangeCollaboratorPrivilegeLevel ).to.have.been.calledWith( - ctx.projectId, - ctx.user._id, + ctx.projectId.toString(), + ctx.user._id.toString(), 'readAndWrite' ) expect( @@ -451,7 +455,11 @@ describe('CollaboratorsController', function () { .to.not.have.been.called expect( ctx.CollaboratorsHandler.promises.setCollaboratorPrivilegeLevel - ).to.have.been.calledWith(ctx.projectId, ctx.user._id, 'readOnly') + ).to.have.been.calledWith( + ctx.projectId.toString(), + ctx.user._id.toString(), + 'readOnly' + ) resolve() } ctx.CollaboratorsController.setCollaboratorInfo(ctx.req, ctx.res) @@ -463,6 +471,7 @@ describe('CollaboratorsController', function () { describe('transferOwnership', function () { beforeEach(function (ctx) { + ctx.req.params = { Project_id: ctx.projectId.toString() } ctx.req.body = { user_id: ctx.user._id.toString() } }) @@ -507,11 +516,11 @@ describe('CollaboratorsController', function () { }) it('invokes HTTP forbidden error handler if the user is not a collaborator', async function (ctx) { + ctx.OwnershipTransferHandler.promises.transferOwnership.rejects( + new Errors.UserNotCollaboratorError() + ) await new Promise(resolve => { ctx.HttpErrorHandler.forbidden = sinon.spy(() => resolve()) - ctx.OwnershipTransferHandler.promises.transferOwnership.rejects( - new Errors.UserNotCollaboratorError() - ) ctx.CollaboratorsController.transferOwnership(ctx.req, ctx.res) }) }) diff --git a/services/web/test/unit/src/Collaborators/CollaboratorsInviteController.test.mjs b/services/web/test/unit/src/Collaborators/CollaboratorsInviteController.test.mjs index 35f43f4b10..8cf4fc959a 100644 --- a/services/web/test/unit/src/Collaborators/CollaboratorsInviteController.test.mjs +++ b/services/web/test/unit/src/Collaborators/CollaboratorsInviteController.test.mjs @@ -17,7 +17,7 @@ vi.mock('../../../../app/src/Features/Errors/Errors.js', () => describe('CollaboratorsInviteController', function () { beforeEach(async function (ctx) { - ctx.projectId = 'project-id-123' + ctx.projectId = '650f1f4f4f1c2c6d88f0e8b1' ctx.token = 'some-opaque-token' ctx.tokenHmac = 'some-hmac-token' ctx.targetEmail = 'user@example.com' diff --git a/services/web/test/unit/src/Editor/EditorHttpController.test.mjs b/services/web/test/unit/src/Editor/EditorHttpController.test.mjs index 5e6662deaf..a49dc2f727 100644 --- a/services/web/test/unit/src/Editor/EditorHttpController.test.mjs +++ b/services/web/test/unit/src/Editor/EditorHttpController.test.mjs @@ -1,4 +1,4 @@ -import { vi, expect } from 'vitest' +import { beforeEach, describe, it, vi, expect } from 'vitest' import sinon from 'sinon' import mongodb from 'mongodb-legacy' import Errors from '../../../../app/src/Features/Errors/Errors.js' @@ -264,9 +264,9 @@ describe('EditorHttpController', function () { describe('joinProject', function () { beforeEach(function (ctx) { - ctx.req.params = { Project_id: ctx.project._id } + ctx.req.params = { Project_id: ctx.project._id.toString() } ctx.req.query = { user_id: ctx.user._id } - ctx.req.body = { userId: ctx.user._id } + ctx.req.body = { userId: ctx.user._id.toString() } }) describe('successfully', function () { @@ -327,20 +327,20 @@ describe('EditorHttpController', function () { it('should unmark the project as deleted', function (ctx) { expect( ctx.ProjectDeleter.promises.unmarkAsDeletedByExternalSource - ).to.have.been.calledWith(ctx.project._id) + ).to.have.been.calledWith(ctx.project._id.toString()) }) }) describe('with a restricted user', function () { beforeEach(async function (ctx) { + ctx.ProjectEditorHandler.buildProjectModelView.returns( + ctx.reducedProjectView + ) + ctx.AuthorizationManager.isRestrictedUser.returns(true) + ctx.AuthorizationManager.promises.getPrivilegeLevelForProjectWithProjectAccess.resolves( + 'readOnly' + ) await new Promise(resolve => { - ctx.ProjectEditorHandler.buildProjectModelView.returns( - ctx.reducedProjectView - ) - ctx.AuthorizationManager.isRestrictedUser.returns(true) - ctx.AuthorizationManager.promises.getPrivilegeLevelForProjectWithProjectAccess.resolves( - 'readOnly' - ) ctx.res.callback = resolve ctx.EditorHttpController.joinProject(ctx.req, ctx.res) }) @@ -381,23 +381,23 @@ describe('EditorHttpController', function () { describe('with an anonymous user', function () { beforeEach(async function (ctx) { + ctx.token = 'token' + ctx.TokenAccessHandler.getRequestToken.returns(ctx.token) + ctx.ProjectEditorHandler.buildProjectModelView.returns( + ctx.reducedProjectView + ) + ctx.req.body = { + userId: 'anonymous-user', + anonymousAccessToken: ctx.token, + } + ctx.AuthorizationManager.isRestrictedUser + .withArgs(null, 'readOnly', false, false) + .returns(true) + ctx.AuthorizationManager.promises.getPrivilegeLevelForProjectWithProjectAccess + .withArgs(null, ctx.project._id.toString(), ctx.token) + .resolves('readOnly') await new Promise(resolve => { - ctx.token = 'token' - ctx.TokenAccessHandler.getRequestToken.returns(ctx.token) - ctx.ProjectEditorHandler.buildProjectModelView.returns( - ctx.reducedProjectView - ) - ctx.req.body = { - userId: 'anonymous-user', - anonymousAccessToken: ctx.token, - } ctx.res.callback = resolve - ctx.AuthorizationManager.isRestrictedUser - .withArgs(null, 'readOnly', false, false) - .returns(true) - ctx.AuthorizationManager.promises.getPrivilegeLevelForProjectWithProjectAccess - .withArgs(null, ctx.project._id, ctx.token) - .resolves('readOnly') ctx.EditorHttpController.joinProject(ctx.req, ctx.res) }) }) diff --git a/services/web/test/unit/src/PasswordReset/PasswordResetController.test.mjs b/services/web/test/unit/src/PasswordReset/PasswordResetController.test.mjs index d225c7ff81..d3dc937e3f 100644 --- a/services/web/test/unit/src/PasswordReset/PasswordResetController.test.mjs +++ b/services/web/test/unit/src/PasswordReset/PasswordResetController.test.mjs @@ -10,7 +10,7 @@ const MODULE_PATH = new URL( describe('PasswordResetController', function () { beforeEach(async function (ctx) { ctx.email = 'bob@bob.com' - ctx.user_id = 'mock-user-id' + ctx.user_id = '507f1f77bcf86cd799439011' ctx.token = 'my security token that was emailed to me' ctx.password = 'my new password' ctx.req = { @@ -416,13 +416,14 @@ describe('PasswordResetController', function () { describe('with token in query-string', function () { beforeEach(function (ctx) { ctx.req.query.passwordResetToken = ctx.token + ctx.req.query.email = 'test@example.com' }) it('should set session.resetToken and redirect', async function (ctx) { await new Promise(resolve => { ctx.req.session.should.not.have.property('resetToken') ctx.res.redirect = path => { - path.should.equal('/user/password/set') + path.should.equal('/user/password/set?email=test%40example.com') ctx.req.session.resetToken.should.equal(ctx.token) resolve() } @@ -433,6 +434,7 @@ describe('PasswordResetController', function () { describe('with expired token in query', function () { beforeEach(function (ctx) { + ctx.req.query.email = 'test@example.com' ctx.req.query.passwordResetToken = ctx.token ctx.PasswordResetHandler.promises.getUserForPasswordResetToken = sinon .stub() @@ -441,14 +443,14 @@ describe('PasswordResetController', function () { }) it('should redirect to the reset request page with an error message', async function (ctx) { - await new Promise(resolve => { + await new Promise((resolve, reject) => { ctx.res.redirect = path => { path.should.equal('/user/password/reset?error=token_expired') ctx.req.session.should.not.have.property('resetToken') resolve() } ctx.res.render = (templatePath, options) => { - resolve('should not render') + reject(new Error('should not render')) } ctx.PasswordResetController.renderSetPasswordForm(ctx.req, ctx.res) }) @@ -516,6 +518,7 @@ describe('PasswordResetController', function () { describe('with token in session', function () { beforeEach(function (ctx) { ctx.req.session.resetToken = ctx.token + ctx.req.query.email = 'test@example.com' }) it('should render the page, passing the reset token', async function (ctx) { @@ -547,6 +550,7 @@ describe('PasswordResetController', function () { ctx.req.session.should.not.have.property('resetToken') resolve() } + ctx.req.query.email = 'test@example.com' ctx.PasswordResetController.renderSetPasswordForm(ctx.req, ctx.res) }) })