also save awaySince timestamp

This commit is contained in:
Ulf Gebhardt 2025-04-02 10:27:54 +02:00
parent 8e5f5fefb3
commit d22e608094
Signed by: ulfgebhardt
GPG Key ID: DA6B843E748679C9
3 changed files with 54 additions and 7 deletions

View File

@ -55,6 +55,7 @@ export default {
invitedBy: { type: 'relationship', relationship: 'INVITED', target: 'User', direction: 'in' },
lastActiveAt: { type: 'string', isoDate: true },
lastOnlineStatus: { type: 'string' },
awaySince: { type: 'string', isoDate: true },
createdAt: { type: 'string', isoDate: true, default: () => new Date().toISOString() },
updatedAt: {
type: 'string',

View File

@ -777,6 +777,9 @@ describe('updateOnlineStatus', () => {
await expect(dbUser.toJson()).resolves.toMatchObject({
lastOnlineStatus: 'online',
})
await expect(dbUser.toJson()).resolves.not.toMatchObject({
awaySince: expect.any(String),
})
})
})
@ -799,6 +802,38 @@ describe('updateOnlineStatus', () => {
const dbUser = neode.hydrateFirst(result, 'u', neode.model('User'))
await expect(dbUser.toJson()).resolves.toMatchObject({
lastOnlineStatus: 'away',
awaySince: expect.any(String),
})
})
it('stores the timestamp of the first away call', async () => {
await expect(mutate({ mutation: updateOnlineStatus, variables })).resolves.toEqual(
expect.objectContaining({
data: { updateOnlineStatus: true },
}),
)
const cypher = 'MATCH (u:User {id: $id}) RETURN u'
const result = await neode.cypher(cypher, { id: authenticatedUser.id })
const dbUser = neode.hydrateFirst(result, 'u', neode.model('User'))
await expect(dbUser.toJson()).resolves.toMatchObject({
lastOnlineStatus: 'away',
awaySince: expect.any(String),
})
const awaySince = (await dbUser.toJson()).awaySince
await expect(mutate({ mutation: updateOnlineStatus, variables })).resolves.toEqual(
expect.objectContaining({
data: { updateOnlineStatus: true },
}),
)
const result2 = await neode.cypher(cypher, { id: authenticatedUser.id })
const dbUser2 = neode.hydrateFirst(result2, 'u', neode.model('User'))
await expect(dbUser2.toJson()).resolves.toMatchObject({
lastOnlineStatus: 'away',
awaySince,
})
})
})

View File

@ -320,16 +320,27 @@ export default {
user: { id },
} = context
const CYPHER_AWAY = `
MATCH (user:User {id: $id})
WITH user,
CASE user.lastOnlineStatus
WHEN 'away' THEN user.awaySince
ELSE toString(datetime())
END AS awaySince
SET user.awaySince = awaySince
SET user.lastOnlineStatus = $status
`
const CYPHER_ONLINE = `
MATCH (user:User {id: $id})
SET user.awaySince = null
SET user.lastOnlineStatus = $status
`
// Last Online Time is saved as `lastActiveAt`
const session = context.driver.session()
await session.writeTransaction((transaction) => {
return transaction.run(
`
MATCH (user:User {id: $id})
SET user.lastOnlineStatus = $status
`,
{ id, status },
)
// return transaction.run(status === 'away' ? CYPHER_AWAY : CYPHER_ONLINE, { id, status })
return transaction.run(status === 'away' ? CYPHER_AWAY : CYPHER_ONLINE, { id, status })
})
return true