Merge pull request #16002 from overleaf/jpa-real-time-auto-join-tests

[real-time] migrate acceptance tests to auto-join

GitOrigin-RevId: fc14a4e803bfab4d07f2773c6ecbdb5459d12684
This commit is contained in:
Jakob Ackermann 2023-11-29 15:50:21 +01:00 committed by Copybot
parent 5ea17d452f
commit 5520f9eed9
18 changed files with 222 additions and 849 deletions

View file

@ -87,16 +87,7 @@ describe('applyOtUpdate', function () {
}, },
cb => { cb => {
this.client = RealTimeClient.connect() this.client = RealTimeClient.connect(this.project_id, cb)
return this.client.on('connectionAccepted', cb)
},
cb => {
return this.client.emit(
'joinProject',
{ project_id: this.project_id },
cb
)
}, },
cb => { cb => {
@ -206,21 +197,12 @@ describe('applyOtUpdate', function () {
}, },
cb => { cb => {
this.client = RealTimeClient.connect() this.client = RealTimeClient.connect(this.project_id, cb)
this.client.on('connectionAccepted', cb)
return this.client.on('otUpdateError', otUpdateError => { return this.client.on('otUpdateError', otUpdateError => {
this.otUpdateError = otUpdateError this.otUpdateError = otUpdateError
}) })
}, },
cb => {
return this.client.emit(
'joinProject',
{ project_id: this.project_id },
cb
)
},
cb => { cb => {
return this.client.emit('joinDoc', this.doc_id, cb) return this.client.emit('joinDoc', this.doc_id, cb)
}, },
@ -303,16 +285,7 @@ describe('applyOtUpdate', function () {
}, },
cb => { cb => {
this.client = RealTimeClient.connect() this.client = RealTimeClient.connect(this.project_id, cb)
return this.client.on('connectionAccepted', cb)
},
cb => {
return this.client.emit(
'joinProject',
{ project_id: this.project_id },
cb
)
}, },
cb => { cb => {
@ -393,16 +366,7 @@ describe('applyOtUpdate', function () {
}, },
cb => { cb => {
this.client = RealTimeClient.connect() this.client = RealTimeClient.connect(this.project_id, cb)
return this.client.on('connectionAccepted', cb)
},
cb => {
return this.client.emit(
'joinProject',
{ project_id: this.project_id },
cb
)
}, },
cb => { cb => {
@ -506,16 +470,7 @@ describe('applyOtUpdate', function () {
}, },
cb => { cb => {
this.client = RealTimeClient.connect() this.client = RealTimeClient.connect(this.project_id, cb)
return this.client.on('connectionAccepted', cb)
},
cb => {
return this.client.emit(
'joinProject',
{ project_id: this.project_id },
cb
)
}, },
cb => { cb => {
@ -593,16 +548,7 @@ describe('applyOtUpdate', function () {
}, },
cb => { cb => {
this.client = RealTimeClient.connect() this.client = RealTimeClient.connect(this.project_id, cb)
return this.client.on('connectionAccepted', cb)
},
cb => {
return this.client.emit(
'joinProject',
{ project_id: this.project_id },
cb
)
}, },
cb => { cb => {

View file

@ -50,39 +50,17 @@ describe('clientTracking', function () {
}, },
cb => { cb => {
this.clientA = RealTimeClient.connect() this.clientA = RealTimeClient.connect(this.project_id, cb)
return this.clientA.on('connectionAccepted', cb)
}, },
cb => { cb => {
this.clientB = RealTimeClient.connect() this.clientB = RealTimeClient.connect(this.project_id, cb)
return this.clientB.on('connectionAccepted', cb)
},
cb => {
return this.clientA.emit(
'joinProject',
{
project_id: this.project_id,
},
cb
)
}, },
cb => { cb => {
return this.clientA.emit('joinDoc', this.doc_id, cb) return this.clientA.emit('joinDoc', this.doc_id, cb)
}, },
cb => {
return this.clientB.emit(
'joinProject',
{
project_id: this.project_id,
},
cb
)
},
cb => { cb => {
this.updates = [] this.updates = []
this.clientB.on('clientTracking.clientUpdated', data => { this.clientB.on('clientTracking.clientUpdated', data => {
@ -179,38 +157,19 @@ describe('clientTracking', function () {
}, },
cb => { cb => {
this.clientA = RealTimeClient.connect() this.clientA = RealTimeClient.connect(this.project_id, cb)
return this.clientA.on('connectionAccepted', cb)
}, },
cb => { cb => {
return this.clientA.emit( RealTimeClient.setAnonSession(
'joinProject', this.project_id,
{ this.anonymousAccessToken,
project_id: this.project_id,
},
cb cb
) )
}, },
cb => { cb => {
return RealTimeClient.setSession({}, cb) this.anonymous = RealTimeClient.connect(this.project_id, cb)
},
cb => {
this.anonymous = RealTimeClient.connect()
return this.anonymous.on('connectionAccepted', cb)
},
cb => {
return this.anonymous.emit(
'joinProject',
{
project_id: this.project_id,
anonymousAccessToken: this.anonymousAccessToken,
},
cb
)
}, },
cb => { cb => {

View file

@ -63,29 +63,11 @@ describe('DrainManagerTests', function () {
return async.series( return async.series(
[ [
cb => { cb => {
this.clientA = RealTimeClient.connect() this.clientA = RealTimeClient.connect(this.project_id, cb)
return this.clientA.on('connectionAccepted', cb)
}, },
cb => { cb => {
this.clientB = RealTimeClient.connect() this.clientB = RealTimeClient.connect(this.project_id, cb)
return this.clientB.on('connectionAccepted', cb)
},
cb => {
return this.clientA.emit(
'joinProject',
{ project_id: this.project_id },
cb
)
},
cb => {
return this.clientB.emit(
'joinProject',
{ project_id: this.project_id },
cb
)
}, },
], ],
done done

View file

@ -31,10 +31,9 @@ describe('EarlyDisconnect', function () {
describe('when the client disconnects before joinProject completes', function () { describe('when the client disconnects before joinProject completes', function () {
before(function () { before(function () {
// slow down web-api requests to force the race condition // slow down web-api requests to force the race condition
let joinProject this.actualWebAPIjoinProject = MockWebServer.joinProject
this.actualWebAPIjoinProject = joinProject = MockWebServer.joinProject MockWebServer.joinProject = (...args) =>
return (MockWebServer.joinProject = (projectId, userId, cb) => setTimeout(() => this.actualWebAPIjoinProject(...args), 300)
setTimeout(() => joinProject(projectId, userId, cb), 300))
}) })
after(function () { after(function () {
@ -61,19 +60,10 @@ describe('EarlyDisconnect', function () {
}, },
cb => { cb => {
this.clientA = RealTimeClient.connect() this.clientA = RealTimeClient.connect(this.project_id, cb)
return this.clientA.on('connectionAccepted', cb) // disconnect after the handshake and before joinProject completes
}, setTimeout(() => this.clientA.disconnect(), 100)
cb => {
this.clientA.emit(
'joinProject',
{ project_id: this.project_id },
() => {}
)
// disconnect before joinProject completes
this.clientA.on('disconnect', () => cb()) this.clientA.on('disconnect', () => cb())
return this.clientA.disconnect()
}, },
cb => { cb => {
@ -122,14 +112,8 @@ describe('EarlyDisconnect', function () {
}, },
cb => { cb => {
this.clientA = RealTimeClient.connect() this.clientA = RealTimeClient.connect(
return this.clientA.on('connectionAccepted', cb) this.project_id,
},
cb => {
return this.clientA.emit(
'joinProject',
{ project_id: this.project_id },
(error, project, privilegeLevel, protocolVersion) => { (error, project, privilegeLevel, protocolVersion) => {
this.project = project this.project = project
this.privilegeLevel = privilegeLevel this.privilegeLevel = privilegeLevel
@ -210,14 +194,8 @@ describe('EarlyDisconnect', function () {
}, },
cb => { cb => {
this.clientA = RealTimeClient.connect() this.clientA = RealTimeClient.connect(
return this.clientA.on('connectionAccepted', cb) this.project_id,
},
cb => {
return this.clientA.emit(
'joinProject',
{ project_id: this.project_id },
(error, project, privilegeLevel, protocolVersion) => { (error, project, privilegeLevel, protocolVersion) => {
this.project = project this.project = project
this.privilegeLevel = privilegeLevel this.privilegeLevel = privilegeLevel

View file

@ -63,16 +63,7 @@ describe('HttpControllerTests', function () {
}, },
cb => { cb => {
this.client = RealTimeClient.connect() this.client = RealTimeClient.connect(this.project_id, cb)
return this.client.on('connectionAccepted', cb)
},
cb => {
return this.client.emit(
'joinProject',
{ project_id: this.project_id },
cb
)
}, },
cb => { cb => {

View file

@ -59,16 +59,7 @@ describe('joinDoc', function () {
}, },
cb => { cb => {
this.client = RealTimeClient.connect() this.client = RealTimeClient.connect(this.project_id, cb)
return this.client.on('connectionAccepted', cb)
},
cb => {
return this.client.emit(
'joinProject',
{ project_id: this.project_id },
cb
)
}, },
cb => { cb => {
@ -147,16 +138,7 @@ describe('joinDoc', function () {
}, },
cb => { cb => {
this.client = RealTimeClient.connect() this.client = RealTimeClient.connect(this.project_id, cb)
return this.client.on('connectionAccepted', cb)
},
cb => {
return this.client.emit(
'joinProject',
{ project_id: this.project_id },
cb
)
}, },
cb => { cb => {
@ -235,16 +217,7 @@ describe('joinDoc', function () {
}, },
cb => { cb => {
this.client = RealTimeClient.connect() this.client = RealTimeClient.connect(this.project_id, cb)
return this.client.on('connectionAccepted', cb)
},
cb => {
return this.client.emit(
'joinProject',
{ project_id: this.project_id },
cb
)
}, },
cb => { cb => {
@ -327,16 +300,7 @@ describe('joinDoc', function () {
}, },
cb => { cb => {
this.client = RealTimeClient.connect() this.client = RealTimeClient.connect(this.project_id, cb)
return this.client.on('connectionAccepted', cb)
},
cb => {
return this.client.emit(
'joinProject',
{ project_id: this.project_id },
cb
)
}, },
cb => { cb => {
@ -413,16 +377,7 @@ describe('joinDoc', function () {
}, },
cb => { cb => {
this.client = RealTimeClient.connect() this.client = RealTimeClient.connect(this.project_id, cb)
return this.client.on('connectionAccepted', cb)
},
cb => {
return this.client.emit(
'joinProject',
{ project_id: this.project_id },
cb
)
}, },
cb => { cb => {
@ -503,16 +458,7 @@ describe('joinDoc', function () {
}, },
cb => { cb => {
this.client = RealTimeClient.connect() this.client = RealTimeClient.connect(this.project_id, cb)
return this.client.on('connectionAccepted', cb)
},
cb => {
return this.client.emit(
'joinProject',
{ project_id: this.project_id },
cb
)
}, },
cb => { cb => {
@ -594,16 +540,7 @@ describe('joinDoc', function () {
}, },
cb => { cb => {
this.client = RealTimeClient.connect() this.client = RealTimeClient.connect(this.project_id, cb)
return this.client.on('connectionAccepted', cb)
},
cb => {
return this.client.emit(
'joinProject',
{ project_id: this.project_id },
cb
)
}, },
cb => { cb => {

View file

@ -36,14 +36,8 @@ describe('joinProject', function () {
}, },
cb => { cb => {
this.client = RealTimeClient.connect() this.client = RealTimeClient.connect(
return this.client.on('connectionAccepted', cb) this.project_id,
},
cb => {
return this.client.emit(
'joinProject',
{ project_id: this.project_id },
(error, project, privilegeLevel, protocolVersion) => { (error, project, privilegeLevel, protocolVersion) => {
this.project = project this.project = project
this.privilegeLevel = privilegeLevel this.privilegeLevel = privilegeLevel
@ -143,21 +137,16 @@ describe('joinProject', function () {
}, },
cb => { cb => {
RealTimeClient.setSession({}, cb) RealTimeClient.setAnonSession(
this.project_id,
this.anonymousAccessToken,
cb
)
}, },
cb => { cb => {
this.client = RealTimeClient.connect() this.client = RealTimeClient.connect(
this.client.on('connectionAccepted', cb) this.project_id,
},
cb => {
this.client.emit(
'joinProject',
{
project_id: this.project_id,
anonymousAccessToken: this.anonymousAccessToken,
},
(error, project, privilegeLevel, protocolVersion) => { (error, project, privilegeLevel, protocolVersion) => {
this.project = project this.project = project
this.privilegeLevel = privilegeLevel this.privilegeLevel = privilegeLevel
@ -246,14 +235,8 @@ describe('joinProject', function () {
}, },
cb => { cb => {
this.client = RealTimeClient.connect() this.client = RealTimeClient.connect(
return this.client.on('connectionAccepted', cb) this.project_id,
},
cb => {
return this.client.emit(
'joinProject',
{ project_id: this.project_id },
(error, project, privilegeLevel, protocolVersion) => { (error, project, privilegeLevel, protocolVersion) => {
this.error = error this.error = error
this.project = project this.project = project
@ -275,11 +258,8 @@ describe('joinProject', function () {
return it('should not have joined the project room', function (done) { return it('should not have joined the project room', function (done) {
return RealTimeClient.getConnectedClient( return RealTimeClient.getConnectedClient(
this.client.socket.sessionid, this.client.socket.sessionid,
(error, client) => { error => {
if (error) return done(error) expect(error.message).to.equal('not found')
expect(Array.from(client.rooms).includes(this.project_id)).to.equal(
false
)
return done() return done()
} }
) )
@ -308,22 +288,10 @@ describe('joinProject', function () {
}, },
cb => { cb => {
this.client = RealTimeClient.connect() this.client = RealTimeClient.connect(this.project_id, error => {
this.client.on('connectionAccepted', cb) this.error = error
}, cb()
})
cb => {
this.client.emit(
'joinProject',
{ project_id: this.project_id },
(error, project, privilegeLevel, protocolVersion) => {
this.error = error
this.project = project
this.privilegeLevel = privilegeLevel
this.protocolVersion = protocolVersion
cb()
}
)
}, },
], ],
done done
@ -335,16 +303,10 @@ describe('joinProject', function () {
}) })
it('should not have joined the project room', function (done) { it('should not have joined the project room', function (done) {
RealTimeClient.getConnectedClient( RealTimeClient.getConnectedClient(this.client.socket.sessionid, error => {
this.client.socket.sessionid, expect(error.message).to.equal('not found')
(error, client) => { done()
if (error) return done(error) })
expect(Array.from(client.rooms).includes(this.project_id)).to.equal(
false
)
done()
}
)
}) })
}) })
@ -370,22 +332,10 @@ describe('joinProject', function () {
}, },
cb => { cb => {
this.client = RealTimeClient.connect() this.client = RealTimeClient.connect(this.project_id, error => {
this.client.on('connectionAccepted', cb) this.error = error
}, cb()
})
cb => {
this.client.emit(
'joinProject',
{ project_id: this.project_id },
(error, project, privilegeLevel, protocolVersion) => {
this.error = error
this.project = project
this.privilegeLevel = privilegeLevel
this.protocolVersion = protocolVersion
cb()
}
)
}, },
], ],
done done
@ -397,16 +347,10 @@ describe('joinProject', function () {
}) })
it('should not have joined the project room', function (done) { it('should not have joined the project room', function (done) {
RealTimeClient.getConnectedClient( RealTimeClient.getConnectedClient(this.client.socket.sessionid, error => {
this.client.socket.sessionid, expect(error.message).to.equal('not found')
(error, client) => { done()
if (error) return done(error) })
expect(Array.from(client.rooms).includes(this.project_id)).to.equal(
false
)
done()
}
)
}) })
}) })
@ -416,19 +360,10 @@ describe('joinProject', function () {
return async.series( return async.series(
[ [
cb => { cb => {
this.client = RealTimeClient.connect() this.client = RealTimeClient.connect('invalid-id', error => {
return this.client.on('connectionAccepted', cb) this.error = error
}, return cb()
})
cb => {
return this.client.emit(
'joinProject',
{ project_id: 'invalid-id' },
error => {
this.error = error
return cb()
}
)
}, },
], ],
done done
@ -444,94 +379,13 @@ describe('joinProject', function () {
}) })
}) })
describe('when joining more than one project', function () {
before(function (done) {
return async.series(
[
cb => {
return FixturesManager.setUpProject(
{
privilegeLevel: 'owner',
project: {
name: 'Other Project',
},
},
(e, { project_id: projectId, user_id: userId }) => {
this.other_project_id = projectId
this.other_user_id = userId
return cb(e)
}
)
},
cb => {
return FixturesManager.setUpProject(
{
user_id: this.other_user_id,
privilegeLevel: 'owner',
project: {
name: 'Test Project',
},
},
(e, { project_id: projectId, user_id: userId }) => {
this.project_id = projectId
this.user_id = userId
return cb(e)
}
)
},
cb => {
this.client = RealTimeClient.connect()
return this.client.on('connectionAccepted', cb)
},
cb => {
return this.client.emit(
'joinProject',
{ project_id: this.project_id },
(error, project, privilegeLevel, protocolVersion) => {
this.project = project
this.privilegeLevel = privilegeLevel
this.protocolVersion = protocolVersion
return cb(error)
}
)
},
cb => {
return this.client.emit(
'joinProject',
{ project_id: this.other_project_id },
error => {
this.error = error
return cb()
}
)
},
],
done
)
})
return it('should return an error', function () {
this.error.message.should.equal('cannot join multiple projects')
})
})
describe('when over rate limit', function () { describe('when over rate limit', function () {
before(function (done) { before(function (done) {
return async.series( return async.series(
[ [
cb => { cb => {
this.client = RealTimeClient.connect() this.client = RealTimeClient.connect(
return this.client.on('connectionAccepted', cb) '429429429429429429429429', // rate-limited
},
cb => {
return this.client.emit(
'joinProject',
{ project_id: '429429429429429429429429' }, // rate-limited
error => { error => {
this.error = error this.error = error
return cb() return cb()
@ -551,7 +405,6 @@ describe('joinProject', function () {
describe('when automatically joining the project', function () { describe('when automatically joining the project', function () {
describe('when authorized', function () { describe('when authorized', function () {
let connectionAcceptedReceived = false
before(function (done) { before(function (done) {
async.series( async.series(
[ [
@ -573,19 +426,12 @@ describe('joinProject', function () {
cb => { cb => {
this.client = RealTimeClient.connect( this.client = RealTimeClient.connect(
`projectId=${this.project_id}` this.project_id,
) (err, project, permissionsLevel, protocolVersion) => {
this.client.on('connectionAccepted', () => {
connectionAcceptedReceived = true
})
this.client.on('connectionRejected', cb)
this.client.on(
'joinProjectResponse',
({ project, permissionsLevel, protocolVersion }) => {
this.project = project this.project = project
this.permissionsLevel = permissionsLevel this.permissionsLevel = permissionsLevel
this.protocolVersion = protocolVersion this.protocolVersion = protocolVersion
cb() cb(err)
} }
) )
}, },
@ -594,10 +440,6 @@ describe('joinProject', function () {
) )
}) })
it('should not emit connectionAccepted', function () {
expect(connectionAcceptedReceived).to.equal(false)
})
it('should get the project from web', function () { it('should get the project from web', function () {
MockWebServer.joinProject MockWebServer.joinProject
.calledWith(this.project_id, this.user_id) .calledWith(this.project_id, this.user_id)
@ -652,7 +494,6 @@ describe('joinProject', function () {
}) })
describe('when authorized with token', function () { describe('when authorized with token', function () {
let connectionAcceptedReceived = false
before(function (done) { before(function (done) {
async.series( async.series(
[ [
@ -682,31 +523,21 @@ describe('joinProject', function () {
}, },
cb => { cb => {
RealTimeClient.setSession( RealTimeClient.setAnonSession(
{ this.project_id,
anonTokenAccess: { this.anonymousAccessToken,
[this.project_id]: this.anonymousAccessToken,
},
},
cb cb
) )
}, },
cb => { cb => {
this.client = RealTimeClient.connect( this.client = RealTimeClient.connect(
`projectId=${this.project_id}` this.project_id,
) (err, project, permissionsLevel, protocolVersion) => {
this.client.on('connectionAccepted', () => {
connectionAcceptedReceived = true
})
this.client.on('connectionRejected', cb)
this.client.on(
'joinProjectResponse',
({ project, permissionsLevel, protocolVersion }) => {
this.project = project this.project = project
this.permissionsLevel = permissionsLevel this.permissionsLevel = permissionsLevel
this.protocolVersion = protocolVersion this.protocolVersion = protocolVersion
cb() cb(err)
} }
) )
}, },
@ -715,10 +546,6 @@ describe('joinProject', function () {
) )
}) })
it('should not emit connectionAccepted', function () {
expect(connectionAcceptedReceived).to.equal(false)
})
it('should get the project from web', function () { it('should get the project from web', function () {
MockWebServer.joinProject MockWebServer.joinProject
.calledWith( .calledWith(
@ -795,10 +622,7 @@ describe('joinProject', function () {
}, },
cb => { cb => {
this.client = RealTimeClient.connect( this.client = RealTimeClient.connect(this.project_id, err => {
`projectId=${this.project_id}`
)
this.client.on('connectionRejected', err => {
this.error = err this.error = err
cb() cb()
}) })
@ -858,10 +682,7 @@ describe('joinProject', function () {
}, },
cb => { cb => {
this.client = RealTimeClient.connect( this.client = RealTimeClient.connect(this.project_id, err => {
`projectId=${this.project_id}`
)
this.client.on('connectionRejected', err => {
this.error = err this.error = err
cb() cb()
}) })
@ -921,10 +742,7 @@ describe('joinProject', function () {
}, },
cb => { cb => {
this.client = RealTimeClient.connect( this.client = RealTimeClient.connect(this.project_id, err => {
`projectId=${this.project_id}`
)
this.client.on('connectionRejected', err => {
this.error = err this.error = err
cb() cb()
}) })
@ -968,8 +786,7 @@ describe('joinProject', function () {
async.series( async.series(
[ [
cb => { cb => {
this.client = RealTimeClient.connect('projectId=invalid-id') this.client = RealTimeClient.connect('invalid-id', err => {
this.client.on('connectionRejected', err => {
this.error = err this.error = err
cb() cb()
}) })
@ -1000,73 +817,6 @@ describe('joinProject', function () {
}) })
}) })
describe('when joining more than one project', function () {
before(function (done) {
async.series(
[
cb => {
FixturesManager.setUpProject(
{
privilegeLevel: 'owner',
project: {
name: 'Other Project',
},
},
(e, { project_id: projectId, user_id: userId }) => {
this.other_project_id = projectId
this.other_user_id = userId
cb(e)
}
)
},
cb => {
FixturesManager.setUpProject(
{
user_id: this.other_user_id,
privilegeLevel: 'owner',
project: {
name: 'Test Project',
},
},
(e, { project_id: projectId, user_id: userId }) => {
this.project_id = projectId
this.user_id = userId
cb(e)
}
)
},
cb => {
this.client = RealTimeClient.connect(
`projectId=${this.project_id}`
)
this.client.on('connectionRejected', cb)
this.client.on('joinProjectResponse', () => {
cb()
})
},
cb => {
this.client.emit(
'joinProject',
{ project_id: this.other_project_id },
error => {
this.error = error
cb()
}
)
},
],
done
)
})
it('should return an error', function () {
this.error.message.should.equal('cannot join multiple projects')
})
})
describe('when over rate limit', function () { describe('when over rate limit', function () {
let joinProjectResponseReceived = false let joinProjectResponseReceived = false
before(function (done) { before(function (done) {
@ -1074,12 +824,12 @@ describe('joinProject', function () {
[ [
cb => { cb => {
this.client = RealTimeClient.connect( this.client = RealTimeClient.connect(
'projectId=429429429429429429429429' '429429429429429429429429',
err => {
this.error = err
cb()
}
) )
this.client.on('connectionRejected', err => {
this.error = err
cb()
})
this.client.on('joinProjectResponse', () => { this.client.on('joinProjectResponse', () => {
joinProjectResponseReceived = true joinProjectResponseReceived = true
cb() cb()

View file

@ -67,16 +67,7 @@ describe('leaveDoc', function () {
}, },
cb => { cb => {
this.client = RealTimeClient.connect() this.client = RealTimeClient.connect(this.project_id, cb)
return this.client.on('connectionAccepted', cb)
},
cb => {
return this.client.emit(
'joinProject',
{ project_id: this.project_id },
cb
)
}, },
cb => { cb => {

View file

@ -45,13 +45,11 @@ describe('leaveProject', function () {
}, },
cb => { cb => {
this.clientA = RealTimeClient.connect() this.clientA = RealTimeClient.connect(this.project_id, cb)
return this.clientA.on('connectionAccepted', cb)
}, },
cb => { cb => {
this.clientB = RealTimeClient.connect() this.clientB = RealTimeClient.connect(this.project_id, cb)
this.clientB.on('connectionAccepted', cb)
this.clientBDisconnectMessages = [] this.clientBDisconnectMessages = []
return this.clientB.on( return this.clientB.on(
@ -62,32 +60,6 @@ describe('leaveProject', function () {
) )
}, },
cb => {
return this.clientA.emit(
'joinProject',
{ project_id: this.project_id },
(error, project, privilegeLevel, protocolVersion) => {
this.project = project
this.privilegeLevel = privilegeLevel
this.protocolVersion = protocolVersion
return cb(error)
}
)
},
cb => {
return this.clientB.emit(
'joinProject',
{ project_id: this.project_id },
(error, project, privilegeLevel, protocolVersion) => {
this.project = project
this.privilegeLevel = privilegeLevel
this.protocolVersion = protocolVersion
return cb(error)
}
)
},
cb => { cb => {
return FixturesManager.setUpDoc( return FixturesManager.setUpDoc(
this.project_id, this.project_id,
@ -192,14 +164,8 @@ describe('leaveProject', function () {
}, },
cb => { cb => {
this.clientA = RealTimeClient.connect() this.clientA = RealTimeClient.connect(
return this.clientA.on('connect', cb) this.project_id,
},
cb => {
return this.clientA.emit(
'joinProject',
{ project_id: this.project_id },
(error, project, privilegeLevel, protocolVersion) => { (error, project, privilegeLevel, protocolVersion) => {
this.project = project this.project = project
this.privilegeLevel = privilegeLevel this.privilegeLevel = privilegeLevel

View file

@ -79,16 +79,9 @@ describe('MatrixTests', function () {
if (err) return done(err) if (err) return done(err)
privateProjectId = projectId privateProjectId = projectId
privateDocId = docId privateDocId = docId
privateClient = RealTimeClient.connect() privateClient = RealTimeClient.connect(projectId, err => {
privateClient.on('connectionAccepted', () => { if (err) return done(err)
privateClient.emit( privateClient.emit('joinDoc', privateDocId, done)
'joinProject',
{ project_id: privateProjectId },
err => {
if (err) return done(err)
privateClient.emit('joinDoc', privateDocId, done)
}
)
}) })
} }
) )
@ -110,28 +103,19 @@ describe('MatrixTests', function () {
const USER_SETUP = { const USER_SETUP = {
anonymous: { anonymous: {
getAnonymousAccessToken() {
return readWriteAnonymousAccessToken
},
setup(cb) { setup(cb) {
RealTimeClient.setSession( RealTimeClient.setAnonSession(
{ readWriteProjectId,
anonTokenAccess: { readWriteAnonymousAccessToken,
[readWriteProjectId]: readWriteAnonymousAccessToken,
},
},
err => { err => {
if (err) return cb(err) if (err) return cb(err)
cb(null, { cb(null, {})
client: RealTimeClient.connect(),
})
} }
) )
}, },
}, },
registered: { registered: {
getAnonymousAccessToken() {},
setup(cb) { setup(cb) {
const userId = FixturesManager.getRandomId() const userId = FixturesManager.getRandomId()
const user = { _id: userId, first_name: 'Joe', last_name: 'Bloggs' } const user = { _id: userId, first_name: 'Joe', last_name: 'Bloggs' }
@ -145,14 +129,12 @@ describe('MatrixTests', function () {
) )
cb(null, { cb(null, {
user_id: userId, user_id: userId,
client: RealTimeClient.connect(),
}) })
}) })
}, },
}, },
registeredWithOwnedProject: { registeredWithOwnedProject: {
getAnonymousAccessToken() {},
setup(cb) { setup(cb) {
FixturesManager.setUpEditorSession( FixturesManager.setUpEditorSession(
{ privilegeLevel: 'owner' }, { privilegeLevel: 'owner' },
@ -168,7 +150,6 @@ describe('MatrixTests', function () {
user_id: userId, user_id: userId,
project_id: projectId, project_id: projectId,
doc_id: docId, doc_id: docId,
client: RealTimeClient.connect(),
}) })
} }
) )
@ -182,34 +163,17 @@ describe('MatrixTests', function () {
let options, client let options, client
const SESSION_SETUP = { const SESSION_SETUP = {
noop: {
getActions(cb) {
cb(null, [])
},
needsOwnProject: false,
},
joinReadWriteProject: { joinReadWriteProject: {
getActions(cb) { getActions(cb) {
const anonymousAccessToken = userItem.getAnonymousAccessToken() cb(null, [{ connect: readWriteProjectId }])
cb(null, [
{
rpc: 'joinProject',
args: [{ project_id: readWriteProjectId, anonymousAccessToken }],
},
])
}, },
needsOwnProject: false, needsOwnProject: false,
}, },
joinReadWriteProjectAndDoc: { joinReadWriteProjectAndDoc: {
getActions(cb) { getActions(cb) {
const anonymousAccessToken = userItem.getAnonymousAccessToken()
cb(null, [ cb(null, [
{ { connect: readWriteProjectId },
rpc: 'joinProject',
args: [{ project_id: readWriteProjectId, anonymousAccessToken }],
},
{ rpc: 'joinDoc', args: [readWriteDocId] }, { rpc: 'joinDoc', args: [readWriteDocId] },
]) ])
}, },
@ -218,25 +182,15 @@ describe('MatrixTests', function () {
joinOwnProject: { joinOwnProject: {
getActions(cb) { getActions(cb) {
const anonymousAccessToken = userItem.getAnonymousAccessToken() cb(null, [{ connect: options.project_id }])
cb(null, [
{
rpc: 'joinProject',
args: [{ project_id: options.project_id, anonymousAccessToken }],
},
])
}, },
needsOwnProject: true, needsOwnProject: true,
}, },
joinOwnProjectAndDoc: { joinOwnProjectAndDoc: {
getActions(cb) { getActions(cb) {
const anonymousAccessToken = userItem.getAnonymousAccessToken()
cb(null, [ cb(null, [
{ { connect: options.project_id },
rpc: 'joinProject',
args: [{ project_id: options.project_id, anonymousAccessToken }],
},
{ rpc: 'joinDoc', args: [options.doc_id] }, { rpc: 'joinDoc', args: [options.doc_id] },
]) ])
}, },
@ -250,19 +204,27 @@ describe('MatrixTests', function () {
async.eachSeries( async.eachSeries(
actions, actions,
(action, cb) => { (action, next) => {
if (action.rpc) { const cb = (...returnedArgs) => {
client.emit(action.rpc, ...action.args, (...returnedArgs) => { const error = returnedArgs.shift()
const error = returnedArgs.shift() if (action.fails) {
if (action.fails) { expect(error).to.exist
expect(error).to.exist expect(returnedArgs).to.have.length(0)
expect(returnedArgs).to.have.length(0) return next()
return cb() }
} next(error)
cb(error) }
})
if (action.connect) {
client = RealTimeClient.connect(action.connect, cb)
} else if (action.rpc) {
if (client?.socket?.connected) {
client.emit(action.rpc, ...action.args, cb)
} else {
cb(new Error('not connected!'))
}
} else { } else {
cb(new Error('unexpected action')) next(new Error('unexpected action'))
} }
}, },
done done
@ -274,10 +236,8 @@ describe('MatrixTests', function () {
beforeEach(function userSetup(done) { beforeEach(function userSetup(done) {
userItem.setup((err, _options) => { userItem.setup((err, _options) => {
if (err) return done(err) if (err) return done(err)
options = _options options = _options
client = options.client done()
client.on('connectionAccepted', done)
}) })
}) })
@ -292,18 +252,19 @@ describe('MatrixTests', function () {
joinProjectWithBadAccessToken: { joinProjectWithBadAccessToken: {
getActions(cb) { getActions(cb) {
cb(null, [ RealTimeClient.setAnonSession(
{ privateProjectId,
rpc: 'joinProject', 'invalid-access-token',
args: [ err => {
if (err) return cb(err)
cb(null, [
{ {
project_id: privateProjectId, connect: privateProjectId,
anonymousAccessToken: 'invalid-access-token', fails: 1,
}, },
], ])
fails: 1, }
}, )
])
}, },
}, },
@ -311,8 +272,7 @@ describe('MatrixTests', function () {
getActions(cb) { getActions(cb) {
cb(null, [ cb(null, [
{ {
rpc: 'joinProject', connect: privateDocId,
args: [{ project_id: privateDocId }],
fails: 1, fails: 1,
}, },
]) ])
@ -329,8 +289,7 @@ describe('MatrixTests', function () {
getActions(cb) { getActions(cb) {
cb(null, [ cb(null, [
{ {
rpc: 'joinProject', connect: privateProjectId,
args: [{ project_id: privateProjectId }],
fails: 1, fails: 1,
}, },
]) ])
@ -347,8 +306,7 @@ describe('MatrixTests', function () {
getActions(cb) { getActions(cb) {
cb(null, [ cb(null, [
{ {
rpc: 'joinProject', connect: privateProjectId,
args: [{ project_id: privateProjectId }],
fails: 1, fails: 1,
}, },
{ rpc: 'joinDoc', args: [privateDocId], fails: 1 }, { rpc: 'joinDoc', args: [privateDocId], fails: 1 },
@ -379,6 +337,7 @@ describe('MatrixTests', function () {
RealTimeClient.getConnectedClient( RealTimeClient.getConnectedClient(
client.socket.sessionid, client.socket.sessionid,
(error, client) => { (error, client) => {
if (error?.message === 'not found') return done() // disconnected
if (error) return done(error) if (error) return done(error)
expect(client.rooms).to.not.include(privateProjectId) expect(client.rooms).to.not.include(privateProjectId)
done() done()
@ -390,6 +349,7 @@ describe('MatrixTests', function () {
RealTimeClient.getConnectedClient( RealTimeClient.getConnectedClient(
client.socket.sessionid, client.socket.sessionid,
(error, client) => { (error, client) => {
if (error?.message === 'not found') return done() // disconnected
if (error) return done(error) if (error) return done(error)
expect(client.rooms).to.not.include(privateDocId) expect(client.rooms).to.not.include(privateDocId)
done() done()
@ -467,6 +427,10 @@ describe('MatrixTests', function () {
}) })
beforeEach(function sendAsUser(done) { beforeEach(function sendAsUser(done) {
if (!client?.socket?.connected) {
// disconnected clients cannot emit messages
return this.skip()
}
const userUpdate = Object.assign({}, update, { const userUpdate = Object.assign({}, update, {
hash: 'user', hash: 'user',
}) })

View file

@ -44,14 +44,8 @@ describe('PubSubRace', function () {
}, },
cb => { cb => {
this.clientA = RealTimeClient.connect() this.clientA = RealTimeClient.connect(
return this.clientA.on('connect', cb) this.project_id,
},
cb => {
return this.clientA.emit(
'joinProject',
{ project_id: this.project_id },
(error, project, privilegeLevel, protocolVersion) => { (error, project, privilegeLevel, protocolVersion) => {
this.project = project this.project = project
this.privilegeLevel = privilegeLevel this.privilegeLevel = privilegeLevel
@ -120,14 +114,8 @@ describe('PubSubRace', function () {
}, },
cb => { cb => {
this.clientA = RealTimeClient.connect() this.clientA = RealTimeClient.connect(
return this.clientA.on('connect', cb) this.project_id,
},
cb => {
return this.clientA.emit(
'joinProject',
{ project_id: this.project_id },
(error, project, privilegeLevel, protocolVersion) => { (error, project, privilegeLevel, protocolVersion) => {
this.project = project this.project = project
this.privilegeLevel = privilegeLevel this.privilegeLevel = privilegeLevel
@ -203,14 +191,8 @@ describe('PubSubRace', function () {
}, },
cb => { cb => {
this.clientA = RealTimeClient.connect() this.clientA = RealTimeClient.connect(
return this.clientA.on('connect', cb) this.project_id,
},
cb => {
return this.clientA.emit(
'joinProject',
{ project_id: this.project_id },
(error, project, privilegeLevel, protocolVersion) => { (error, project, privilegeLevel, protocolVersion) => {
this.project = project this.project = project
this.privilegeLevel = privilegeLevel this.privilegeLevel = privilegeLevel
@ -285,14 +267,8 @@ describe('PubSubRace', function () {
}, },
cb => { cb => {
this.clientA = RealTimeClient.connect() this.clientA = RealTimeClient.connect(
return this.clientA.on('connect', cb) this.project_id,
},
cb => {
return this.clientA.emit(
'joinProject',
{ project_id: this.project_id },
(error, project, privilegeLevel, protocolVersion) => { (error, project, privilegeLevel, protocolVersion) => {
this.project = project this.project = project
this.privilegeLevel = privilegeLevel this.privilegeLevel = privilegeLevel

View file

@ -80,18 +80,7 @@ describe('receiveEditorEvent', function () {
* Connect owner to project/doc * Connect owner to project/doc
*/ */
cb => { cb => {
this.owner_client = RealTimeClient.connect() this.owner_client = RealTimeClient.connect(this.project_id, cb)
return this.owner_client.on('connectionAccepted', cb)
},
cb => {
return this.owner_client.emit(
'joinProject',
{
project_id: this.project_id,
},
cb
)
}, },
cb => { cb => {
@ -120,18 +109,7 @@ describe('receiveEditorEvent', function () {
* Connect user_a to project/doc * Connect user_a to project/doc
*/ */
cb => { cb => {
this.user_a_client = RealTimeClient.connect() this.user_a_client = RealTimeClient.connect(this.project_id, cb)
return this.user_a_client.on('connectionAccepted', cb)
},
cb => {
return this.user_a_client.emit(
'joinProject',
{
project_id: this.project_id,
},
cb
)
}, },
cb => { cb => {
return this.user_a_client.emit('joinDoc', this.doc_id, cb) return this.user_a_client.emit('joinDoc', this.doc_id, cb)
@ -159,18 +137,7 @@ describe('receiveEditorEvent', function () {
* Connect user_b to project/doc * Connect user_b to project/doc
*/ */
cb => { cb => {
this.user_b_client = RealTimeClient.connect() this.user_b_client = RealTimeClient.connect(this.project_id, cb)
return this.user_b_client.on('connectionAccepted', cb)
},
cb => {
return this.user_b_client.emit(
'joinProject',
{
project_id: this.project_id,
},
cb
)
}, },
cb => { cb => {
return this.user_b_client.emit('joinDoc', this.doc_id, cb) return this.user_b_client.emit('joinDoc', this.doc_id, cb)
@ -202,18 +169,7 @@ describe('receiveEditorEvent', function () {
* Connect user_c to project/doc * Connect user_c to project/doc
*/ */
cb => { cb => {
this.user_c_client = RealTimeClient.connect() this.user_c_client = RealTimeClient.connect(this.project_id, cb)
return this.user_c_client.on('connectionAccepted', cb)
},
cb => {
return this.user_c_client.emit(
'joinProject',
{
project_id: this.project_id,
},
cb
)
}, },
cb => { cb => {
return this.user_c_client.emit('joinDoc', this.doc_id, cb) return this.user_c_client.emit('joinDoc', this.doc_id, cb)

View file

@ -56,39 +56,17 @@ describe('receiveUpdate', function () {
}, },
cb => { cb => {
this.clientA = RealTimeClient.connect() this.clientA = RealTimeClient.connect(this.project_id, cb)
return this.clientA.on('connectionAccepted', cb)
}, },
cb => { cb => {
this.clientB = RealTimeClient.connect() this.clientB = RealTimeClient.connect(this.project_id, cb)
return this.clientB.on('connectionAccepted', cb)
},
cb => {
return this.clientA.emit(
'joinProject',
{
project_id: this.project_id,
},
cb
)
}, },
cb => { cb => {
return this.clientA.emit('joinDoc', this.doc_id, cb) return this.clientA.emit('joinDoc', this.doc_id, cb)
}, },
cb => {
return this.clientB.emit(
'joinProject',
{
project_id: this.project_id,
},
cb
)
},
cb => { cb => {
return this.clientB.emit('joinDoc', this.doc_id, cb) return this.clientB.emit('joinDoc', this.doc_id, cb)
}, },
@ -120,19 +98,9 @@ describe('receiveUpdate', function () {
}, },
cb => { cb => {
this.clientC = RealTimeClient.connect() this.clientC = RealTimeClient.connect(this.project_id_second, cb)
return this.clientC.on('connectionAccepted', cb)
}, },
cb => {
return this.clientC.emit(
'joinProject',
{
project_id: this.project_id_second,
},
cb
)
},
cb => { cb => {
return this.clientC.emit('joinDoc', this.doc_id_second, cb) return this.clientC.emit('joinDoc', this.doc_id_second, cb)
}, },

View file

@ -40,17 +40,10 @@ describe('Router', function () {
}, },
cb => { cb => {
this.client = RealTimeClient.connect() this.client = RealTimeClient.connect(this.project_id, cb)
return this.client.on('connectionAccepted', cb)
}, },
cb => { cb => {
this.client = RealTimeClient.connect()
return this.client.on('connectionAccepted', cb)
},
cb => {
this.client.emit('joinProject', { project_id: this.project_id })
return setTimeout(cb, 100) return setTimeout(cb, 100)
}, },
], ],
@ -90,17 +83,11 @@ describe('Router', function () {
}, },
cb => { cb => {
this.client = RealTimeClient.connect() this.client = RealTimeClient.connect(this.project_id, cb)
return this.client.on('connectionAccepted', cb)
}, },
cb => { cb => {
this.client = RealTimeClient.connect() return this.client.emit('joinDoc', 1, 2, 3, 4, 5, error => {
return this.client.on('connectionAccepted', cb)
},
cb => {
return this.client.emit('joinProject', 1, 2, 3, 4, 5, error => {
this.error = error this.error = error
return cb() return cb()
}) })

View file

@ -9,21 +9,29 @@
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/ */
const RealTimeClient = require('./helpers/RealTimeClient') const RealTimeClient = require('./helpers/RealTimeClient')
const FixturesManager = require('./helpers/FixturesManager')
const Settings = require('@overleaf/settings') const Settings = require('@overleaf/settings')
const { expect } = require('chai') const { expect } = require('chai')
describe('SessionSockets', function () { describe('SessionSockets', function () {
before(function () { beforeEach(function (done) {
return (this.checkSocket = function (fn) { FixturesManager.setUpProject(
const client = RealTimeClient.connect() {
client.on('connectionAccepted', fn) privilegeLevel: 'owner',
client.on('connectionRejected', fn) },
return null (err, options) => {
}) if (err) return done(err)
this.checkSocket = function (fn) {
RealTimeClient.connect(options.project_id, fn)
}
done()
}
)
}) })
describe('without cookies', function () { describe('without cookies', function () {
before(function () { beforeEach(function () {
return (RealTimeClient.cookie = null) return (RealTimeClient.cookie = null)
}) })
@ -37,7 +45,7 @@ describe('SessionSockets', function () {
}) })
describe('with a different cookie', function () { describe('with a different cookie', function () {
before(function () { beforeEach(function () {
return (RealTimeClient.cookie = 'some.key=someValue') return (RealTimeClient.cookie = 'some.key=someValue')
}) })
@ -51,7 +59,7 @@ describe('SessionSockets', function () {
}) })
describe('with an invalid cookie', function () { describe('with an invalid cookie', function () {
before(function (done) { beforeEach(function (done) {
RealTimeClient.setSession({}, error => { RealTimeClient.setSession({}, error => {
if (error) { if (error) {
return done(error) return done(error)
@ -74,7 +82,7 @@ describe('SessionSockets', function () {
}) })
describe('with a valid cookie and no matching session', function () { describe('with a valid cookie and no matching session', function () {
before(function () { beforeEach(function () {
return (RealTimeClient.cookie = `${Settings.cookieName}=unknownId`) return (RealTimeClient.cookie = `${Settings.cookieName}=unknownId`)
}) })
@ -88,11 +96,6 @@ describe('SessionSockets', function () {
}) })
return describe('with a valid cookie and a matching session', function () { return describe('with a valid cookie and a matching session', function () {
before(function (done) {
RealTimeClient.setSession({}, done)
return null
})
return it('should not return an error', function (done) { return it('should not return an error', function (done) {
return this.checkSocket(error => { return this.checkSocket(error => {
expect(error).to.not.exist expect(error).to.not.exist

View file

@ -12,22 +12,17 @@
*/ */
const { expect } = require('chai') const { expect } = require('chai')
const FixturesManager = require('./helpers/FixturesManager')
const RealTimeClient = require('./helpers/RealTimeClient') const RealTimeClient = require('./helpers/RealTimeClient')
describe('Session', function () { describe('Session', function () {
return describe('with an established session', function () { return describe('with an established session', function () {
before(function (done) { before(function (done) {
this.user_id = 'mock-user-id' FixturesManager.setUpProject(
RealTimeClient.setSession( { privilegeLevel: 'owner' },
{ (error, options) => {
user: { _id: this.user_id }, if (error) return done(error)
}, this.client = RealTimeClient.connect(options.project_id, done)
error => {
if (error != null) {
throw error
}
this.client = RealTimeClient.connect()
return done()
} }
) )
return null return null

View file

@ -35,8 +35,8 @@ module.exports = MockWebServer = {
} }
const project = MockWebServer.projects[projectId] const project = MockWebServer.projects[projectId]
const privilegeLevel = const privilegeLevel =
MockWebServer.privileges[projectId][userId] || MockWebServer.privileges[projectId]?.[userId] ||
MockWebServer.privileges[projectId][anonymousAccessToken] MockWebServer.privileges[projectId]?.[anonymousAccessToken]
const userMetadata = MockWebServer.userMetadata[projectId]?.[userId] const userMetadata = MockWebServer.userMetadata[projectId]?.[userId]
return callback(null, project, privilegeLevel, userMetadata) return callback(null, project, privilegeLevel, userMetadata)
}, },
@ -65,6 +65,9 @@ module.exports = MockWebServer = {
if (error != null) { if (error != null) {
return next(error) return next(error)
} }
if (!project) {
return res.sendStatus(404)
}
return res.json({ return res.json({
project, project,
privilegeLevel, privilegeLevel,

View file

@ -54,6 +54,17 @@ module.exports = Client = {
}) })
}, },
setAnonSession(projectId, anonymousAccessToken, callback) {
Client.setSession(
{
anonTokenAccess: {
[projectId]: anonymousAccessToken,
},
},
callback
)
},
unsetSession(callback) { unsetSession(callback) {
if (callback == null) { if (callback == null) {
callback = function () {} callback = function () {}
@ -62,19 +73,29 @@ module.exports = Client = {
return callback() return callback()
}, },
connect(query) { connect(projectId, callback) {
const client = io.connect('http://localhost:3026', { const client = io.connect('http://localhost:3026', {
'force new connection': true, 'force new connection': true,
query, query: new URLSearchParams({ projectId }).toString(),
})
let disconnected = false
client.on('disconnect', () => {
disconnected = true
})
client.on('connectionRejected', err => {
// Wait for disconnect ahead of continuing with the test sequence.
setTimeout(() => {
if (!disconnected) {
throw new Error('should disconnect after connectionRejected')
}
callback(err)
}, 10)
})
client.on('joinProjectResponse', resp => {
const { publicId, project, permissionsLevel, protocolVersion } = resp
client.publicId = publicId
callback(null, project, permissionsLevel, protocolVersion)
}) })
client.on(
'connectionAccepted',
(_, publicId) => (client.publicId = publicId)
)
client.on(
'joinProjectResponse',
({ publicId }) => (client.publicId = publicId)
)
return client return client
}, },