Files
overleaf-cep/services/real-time/test/unit/js/EventLogger.test.js
Andrew Rumble 3073c94522 Merge pull request #30215 from overleaf/ar/convert-real-time-to-esm
[real-time] convert real time to esm

GitOrigin-RevId: 7cc530cc977549d3274be42585735e1fd72cad5f
2026-01-13 09:06:30 +00:00

121 lines
3.7 KiB
JavaScript

import { vi, expect, describe, beforeEach, afterEach, it } from 'vitest'
import sinon from 'sinon'
import tk from 'timekeeper'
const modulePath = '../../../app/js/EventLogger'
describe('EventLogger', function () {
beforeEach(async function (ctx) {
ctx.start = Date.now()
tk.freeze(new Date(ctx.start))
vi.doMock('@overleaf/metrics', () => ({
default: (ctx.metrics = { inc: sinon.stub() }),
}))
ctx.EventLogger = (await import(modulePath)).default
ctx.channel = 'applied-ops'
ctx.id_1 = 'random-hostname:abc-1'
ctx.message_1 = 'message-1'
ctx.id_2 = 'random-hostname:abc-2'
ctx.message_2 = 'message-2'
})
afterEach(function () {
tk.reset()
})
describe('checkEventOrder', function () {
describe('when the events are in order', function () {
beforeEach(function (ctx) {
ctx.EventLogger.checkEventOrder(ctx.channel, ctx.id_1, ctx.message_1)
ctx.status = ctx.EventLogger.checkEventOrder(
ctx.channel,
ctx.id_2,
ctx.message_2
)
})
it('should accept events in order', function (ctx) {
expect(ctx.status).to.be.undefined
})
it('should increment the valid event metric', function (ctx) {
ctx.metrics.inc
.calledWith(`event.${ctx.channel}.valid`)
.should.equals(true)
})
})
describe('when there is a duplicate events', function () {
beforeEach(function (ctx) {
ctx.EventLogger.checkEventOrder(ctx.channel, ctx.id_1, ctx.message_1)
ctx.status = ctx.EventLogger.checkEventOrder(
ctx.channel,
ctx.id_1,
ctx.message_1
)
})
it('should return "duplicate" for the same event', function (ctx) {
expect(ctx.status).to.equal('duplicate')
})
it('should increment the duplicate event metric', function (ctx) {
ctx.metrics.inc
.calledWith(`event.${ctx.channel}.duplicate`)
.should.equals(true)
})
})
describe('when there are out of order events', function () {
beforeEach(function (ctx) {
ctx.EventLogger.checkEventOrder(ctx.channel, ctx.id_1, ctx.message_1)
ctx.EventLogger.checkEventOrder(ctx.channel, ctx.id_2, ctx.message_2)
ctx.status = ctx.EventLogger.checkEventOrder(
ctx.channel,
ctx.id_1,
ctx.message_1
)
})
it('should return "out-of-order" for the event', function (ctx) {
expect(ctx.status).to.equal('out-of-order')
})
it('should increment the out-of-order event metric', function (ctx) {
ctx.metrics.inc
.calledWith(`event.${ctx.channel}.out-of-order`)
.should.equals(true)
})
})
describe('after MAX_STALE_TIME_IN_MS', function () {
it('should flush old entries', function (ctx) {
let status
ctx.EventLogger.MAX_EVENTS_BEFORE_CLEAN = 10
ctx.EventLogger.checkEventOrder(ctx.channel, ctx.id_1, ctx.message_1)
for (let i = 1; i <= 8; i++) {
status = ctx.EventLogger.checkEventOrder(
ctx.channel,
ctx.id_1,
ctx.message_1
)
expect(status).to.equal('duplicate')
}
// the next event should flush the old entries aboce
ctx.EventLogger.MAX_STALE_TIME_IN_MS = 1000
tk.freeze(new Date(ctx.start + 5 * 1000))
// because we flushed the entries this should not be a duplicate
ctx.EventLogger.checkEventOrder(ctx.channel, 'other-1', ctx.message_2)
status = ctx.EventLogger.checkEventOrder(
ctx.channel,
ctx.id_1,
ctx.message_1
)
expect(status).to.be.undefined
})
})
})
})