Merge pull request #28019 from overleaf/em-dsmp-comment-event

DS mobile notification for comment added/replied to

GitOrigin-RevId: 602983c679ed415bf8dd8fbf83b328e5ee832e2b
This commit is contained in:
Eric Mc Sween
2025-08-25 09:00:11 -04:00
committed by Copybot
parent 8c3fe3bd31
commit 201e5c49aa
4 changed files with 75 additions and 22 deletions

24
package-lock.json generated
View File

@@ -22014,6 +22014,29 @@
"resolved": "https://registry.npmjs.org/events-listener/-/events-listener-1.1.0.tgz",
"integrity": "sha512-Kd3EgYfODHueq6GzVfs/VUolh2EgJsS8hkO3KpnDrxVjU3eq63eXM2ujXkhPP+OkeUOhL8CxdfZbQXzryb5C4g=="
},
"node_modules/eventsource-client": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/eventsource-client/-/eventsource-client-1.1.4.tgz",
"integrity": "sha512-CKnqZTwXCnHN2EqrEB9eLSjMMRqHum09VOsikkgSPoa2Jr2XgQnX7P1Fxhnnj/UHxi3GQ2xVsXDKIktEes07bg==",
"dev": true,
"license": "MIT",
"dependencies": {
"eventsource-parser": "^3.0.0"
},
"engines": {
"node": ">=18.0.0"
}
},
"node_modules/eventsource-client/node_modules/eventsource-parser": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.3.tgz",
"integrity": "sha512-nVpZkTMM9rF6AQ9gPJpFsNAMt48wIzB5TQgiTLdHiuO8XEDhUgZEhqKlZWXbIzo9VmJ/HvysHqEaVeD5v9TPvA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=20.0.0"
}
},
"node_modules/eventsource-parser": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-1.1.2.tgz",
@@ -44791,6 +44814,7 @@
"eslint-plugin-testing-library": "^7.1.1",
"eslint-plugin-unicorn": "^56.0.0",
"events": "^3.3.0",
"eventsource-client": "^1.1.4",
"fake-indexeddb": "^6.0.0",
"fetch-mock": "^12.5.2",
"formik": "^2.2.9",

View File

@@ -300,6 +300,7 @@
"eslint-plugin-testing-library": "^7.1.1",
"eslint-plugin-unicorn": "^56.0.0",
"events": "^3.3.0",
"eventsource-client": "^1.1.4",
"fake-indexeddb": "^6.0.0",
"fetch-mock": "^12.5.2",
"formik": "^2.2.9",

View File

@@ -395,7 +395,8 @@ describe('Deleting a project', function () {
expect(error).not.to.exist
expect(res.statusCode).to.equal(200)
expect(MockChatApi.projects[this.projectId.toString()]).not.to.exist
expect(MockChatApi.projects.has(this.projectId.toString())).to.be
.false
done()
}
)

View File

@@ -2,42 +2,69 @@ import AbstractMockApi from './AbstractMockApi.mjs'
class MockChatApi extends AbstractMockApi {
reset() {
this.projects = {}
this.projects = new Map()
}
getGlobalMessages(req, res) {
res.json(this.projects[req.params.project_id] || [])
getThread(projectId, threadId) {
let threads = this.projects.get(projectId)
if (threads == null) {
threads = new Map()
this.projects.set(projectId, threads)
}
let thread = threads.get(threadId)
if (thread == null) {
thread = []
threads.set(threadId, thread)
}
return thread
}
sendGlobalMessage(req, res) {
const projectId = req.params.project_id
sendMessage(projectId, threadId, props) {
const message = {
id: Math.random().toString(),
content: req.body.content,
content: props.content,
timestamp: Date.now(),
user_id: req.body.user_id,
user_id: props.user_id,
}
this.projects[projectId] = this.projects[projectId] || []
this.projects[projectId].push(message)
res.json(Object.assign({ room_id: projectId }, message))
const thread = this.getThread(projectId, threadId)
thread.push(message)
return { room_id: projectId, ...message }
}
destroyProject(req, res) {
const projectId = req.params.project_id
delete this.projects[projectId]
res.sendStatus(204)
destroyProject(projectId) {
this.projects.delete(projectId)
}
applyRoutes() {
this.app.get('/project/:project_id/messages', (req, res) =>
this.getGlobalMessages(req, res)
this.app.get('/project/:project_id/messages', (req, res) => {
res.json(this.getThread(req.params.project_id, 'global'))
})
this.app.post('/project/:project_id/messages', (req, res) => {
res.json(this.sendMessage(req.params.project_id, 'global', req.body))
})
this.app.get(
'/project/:project_id/thread/:thread_id/messages',
(req, res) => {
res.json(this.getThread(req.params.project_id, req.params.thread_id))
}
)
this.app.post('/project/:project_id/messages', (req, res) =>
this.sendGlobalMessage(req, res)
)
this.app.delete('/project/:project_id', (req, res) =>
this.destroyProject(req, res)
this.app.post(
'/project/:project_id/thread/:thread_id/messages',
(req, res) => {
res.json(
this.sendMessage(
req.params.project_id,
req.params.thread_id,
req.body
)
)
}
)
this.app.delete('/project/:project_id', (req, res) => {
const projectId = req.params.project_id
this.destroyProject(projectId)
res.sendStatus(204)
})
}
}