1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-01-25 00:07:47 +01:00

fix: correctly filter for to dates (#8567)

This change fixes a bug in the event filter's `to` query parameter.

The problem was that in an attempt to make it inclusive, we also
stripped it of the `IS:` prefix, which meant it had no effect. This
change fixes that by first splitting the value, fixing only the
date (because we want it to include the entire day), and then joining
it back together.
This commit is contained in:
Thomas Heartman 2024-10-29 09:42:15 +01:00 committed by GitHub
parent 03eee8ab61
commit b276d5a89c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 71 additions and 9 deletions

View File

@ -13,7 +13,7 @@ import { ApiTokenType } from '../../types/models/api-token';
import { EVENTS_CREATED_BY_PROCESSED } from '../../metric-events';
import type { IQueryParam } from '../feature-toggle/types/feature-toggle-strategies-store-type';
import { parseSearchOperatorValue } from '../feature-search/search-utils';
import { endOfDay, formatISO } from 'date-fns';
import { addDays, formatISO } from 'date-fns';
import type { IPrivateProjectChecker } from '../private-project/privateProjectCheckerType';
import type { ProjectAccess } from '../private-project/privateProjectStore';
import type { IAccessReadModel } from '../access/access-read-model-type';
@ -184,18 +184,20 @@ export default class EventService {
}
if (params.to) {
const parsed = parseSearchOperatorValue(
'created_at',
formatISO(endOfDay(new Date(params.to)), {
representation: 'date',
}),
);
const parsed = parseSearchOperatorValue('created_at', params.to);
if (parsed) {
const values = parsed.values
.filter((v): v is string => v !== null)
.map((date) =>
formatISO(addDays(new Date(date), 1), {
representation: 'date',
}),
);
queryParams.push({
field: parsed.field,
operator: 'IS_BEFORE',
values: parsed.values,
values,
});
}
}

View File

@ -339,6 +339,66 @@ test('should include dates created on the `to` date', async () => {
});
});
test('should not include events before `from` or after `to`', async () => {
await eventService.storeEvent({
type: FEATURE_CREATED,
project: 'default',
data: { featureName: 'early-event' },
createdBy: 'test-user',
createdByUserId: TEST_USER_ID,
ip: '127.0.0.1',
});
await eventService.storeEvent({
type: FEATURE_CREATED,
project: 'default',
data: { featureName: 'late-event' },
createdBy: 'test-user',
createdByUserId: TEST_USER_ID,
ip: '127.0.0.1',
});
await eventService.storeEvent({
type: FEATURE_CREATED,
project: 'default',
data: { featureName: 'goldilocks' },
createdBy: 'test-user',
createdByUserId: TEST_USER_ID,
ip: '127.0.0.1',
});
const { events } = await eventService.getEvents();
const earlyEvent = events.find((e) => e.data.featureName === 'early-event');
await db.rawDatabase.raw(
`UPDATE events SET created_at = created_at - interval '1 day' where id = ?`,
[earlyEvent?.id],
);
const lateEvent = events.find((e) => e.data.featureName === 'late-event');
await db.rawDatabase.raw(
`UPDATE events SET created_at = created_at + interval '1 day' where id = ?`,
[lateEvent?.id],
);
const today = new Date();
const todayString = today.toISOString().split('T')[0];
const { body } = await searchEvents({
from: `IS:${todayString}`,
to: `IS:${todayString}`,
});
expect(body).toMatchObject({
events: [
{
type: FEATURE_CREATED,
data: { featureName: 'goldilocks' },
},
],
total: 1,
});
});
test('should paginate with offset and limit', async () => {
for (let i = 0; i < 5; i++) {
await eventService.storeEvent({