1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-02-23 00:22:19 +01:00

fix: use date-fns for date/time maths instead of (wrong) Date#setHours (#1070)

Co-authored-by: Ivar Conradi Østhus <ivarconr@gmail.com>
This commit is contained in:
Martin Lehmann 2021-10-26 20:13:30 +02:00 committed by GitHub
parent 3030666f18
commit 607b2a6657
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 22 additions and 34 deletions

View File

@ -81,6 +81,7 @@
"cookie-parser": "^1.4.5", "cookie-parser": "^1.4.5",
"cookie-session": "^2.0.0-rc.1", "cookie-session": "^2.0.0-rc.1",
"cors": "^2.8.5", "cors": "^2.8.5",
"date-fns": "^2.25.0",
"db-migrate": "0.11.12", "db-migrate": "0.11.12",
"db-migrate-pg": "1.2.2", "db-migrate-pg": "1.2.2",
"db-migrate-shared": "1.2.0", "db-migrate-shared": "1.2.0",

View File

@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { Knex } from 'knex'; import { Knex } from 'knex';
import { Logger, LogProvider } from '../logger'; import { Logger, LogProvider } from '../logger';
import { import {
@ -7,6 +6,7 @@ import {
IClientMetricsStoreV2, IClientMetricsStoreV2,
} from '../types/stores/client-metrics-store-v2'; } from '../types/stores/client-metrics-store-v2';
import NotFoundError from '../error/notfound-error'; import NotFoundError from '../error/notfound-error';
import { startOfHour } from 'date-fns';
interface ClientMetricsEnvTable { interface ClientMetricsEnvTable {
feature_name: string; feature_name: string;
@ -19,10 +19,6 @@ interface ClientMetricsEnvTable {
const TABLE = 'client_metrics_env'; const TABLE = 'client_metrics_env';
export function roundDownToHour(date: Date): Date {
return new Date(date.getTime() - (date.getTime() % 3600000));
}
const fromRow = (row: ClientMetricsEnvTable) => ({ const fromRow = (row: ClientMetricsEnvTable) => ({
featureName: row.feature_name, featureName: row.feature_name,
appName: row.app_name, appName: row.app_name,
@ -36,7 +32,7 @@ const toRow = (metric: IClientMetricsEnv) => ({
feature_name: metric.featureName, feature_name: metric.featureName,
app_name: metric.appName, app_name: metric.appName,
environment: metric.environment, environment: metric.environment,
timestamp: roundDownToHour(metric.timestamp), timestamp: startOfHour(metric.timestamp),
yes: metric.yes, yes: metric.yes,
no: metric.no, no: metric.no,
}); });
@ -57,7 +53,7 @@ export class ClientMetricsStoreV2 implements IClientMetricsStoreV2 {
feature_name: key.featureName, feature_name: key.featureName,
app_name: key.appName, app_name: key.appName,
environment: key.environment, environment: key.environment,
timestamp: roundDownToHour(key.timestamp), timestamp: startOfHour(key.timestamp),
}) })
.first(); .first();
if (row) { if (row) {
@ -88,7 +84,7 @@ export class ClientMetricsStoreV2 implements IClientMetricsStoreV2 {
feature_name: key.featureName, feature_name: key.featureName,
app_name: key.appName, app_name: key.appName,
environment: key.environment, environment: key.environment,
timestamp: roundDownToHour(key.timestamp), timestamp: startOfHour(key.timestamp),
}) })
.del(); .del();
} }

View File

@ -2,6 +2,7 @@ import dbInit, { ITestDb } from '../../helpers/database-init';
import { setupAppWithCustomConfig } from '../../helpers/test-helper'; import { setupAppWithCustomConfig } from '../../helpers/test-helper';
import getLogger from '../../../fixtures/no-logger'; import getLogger from '../../../fixtures/no-logger';
import { IClientMetricsEnv } from '../../../../lib/types/stores/client-metrics-store-v2'; import { IClientMetricsEnv } from '../../../../lib/types/stores/client-metrics-store-v2';
import { subHours } from 'date-fns';
let app; let app;
let db: ITestDb; let db: ITestDb;
@ -166,15 +167,14 @@ test('should return toggle summary', async () => {
}); });
test('should only include last hour of metrics return toggle summary', async () => { test('should only include last hour of metrics return toggle summary', async () => {
const date = new Date(); const now = new Date();
const dateHoneHourAgo = new Date(); const dateOneHourAgo = subHours(now, 1);
dateHoneHourAgo.setHours(-1);
const metrics: IClientMetricsEnv[] = [ const metrics: IClientMetricsEnv[] = [
{ {
featureName: 'demo', featureName: 'demo',
appName: 'web', appName: 'web',
environment: 'default', environment: 'default',
timestamp: date, timestamp: now,
yes: 2, yes: 2,
no: 2, no: 2,
}, },
@ -182,7 +182,7 @@ test('should only include last hour of metrics return toggle summary', async ()
featureName: 'demo', featureName: 'demo',
appName: 'web', appName: 'web',
environment: 'default', environment: 'default',
timestamp: date, timestamp: now,
yes: 3, yes: 3,
no: 2, no: 2,
}, },
@ -190,7 +190,7 @@ test('should only include last hour of metrics return toggle summary', async ()
featureName: 'demo', featureName: 'demo',
appName: 'web', appName: 'web',
environment: 'test', environment: 'test',
timestamp: date, timestamp: now,
yes: 1, yes: 1,
no: 3, no: 3,
}, },
@ -198,7 +198,7 @@ test('should only include last hour of metrics return toggle summary', async ()
featureName: 'demo', featureName: 'demo',
appName: 'backend-api', appName: 'backend-api',
environment: 'test', environment: 'test',
timestamp: date, timestamp: now,
yes: 1, yes: 1,
no: 3, no: 3,
}, },
@ -206,7 +206,7 @@ test('should only include last hour of metrics return toggle summary', async ()
featureName: 'demo', featureName: 'demo',
appName: 'backend-api', appName: 'backend-api',
environment: 'test', environment: 'test',
timestamp: dateHoneHourAgo, timestamp: dateOneHourAgo,
yes: 55, yes: 55,
no: 55, no: 55,
}, },

View File

@ -1,3 +1,4 @@
import { subDays } from 'date-fns';
import dbInit from '../helpers/database-init'; import dbInit from '../helpers/database-init';
import getLogger from '../../fixtures/no-logger'; import getLogger from '../../fixtures/no-logger';
import { IUnleashStores } from '../../../lib/types'; import { IUnleashStores } from '../../../lib/types';
@ -5,7 +6,6 @@ import {
IClientMetricsEnv, IClientMetricsEnv,
IClientMetricsStoreV2, IClientMetricsStoreV2,
} from '../../../lib/types/stores/client-metrics-store-v2'; } from '../../../lib/types/stores/client-metrics-store-v2';
import { roundDownToHour } from '../../../lib/db/client-metrics-store-v2';
let db; let db;
let stores: IUnleashStores; let stores: IUnleashStores;
@ -265,8 +265,7 @@ test('Should not fail on undefined list of metrics', async () => {
}); });
test('Should return delete old metric', async () => { test('Should return delete old metric', async () => {
const twoDaysAgo = new Date(); const twoDaysAgo = subDays(new Date(), 2);
twoDaysAgo.setHours(-48);
const metrics: IClientMetricsEnv[] = [ const metrics: IClientMetricsEnv[] = [
{ {
@ -312,8 +311,7 @@ test('Should return delete old metric', async () => {
}); });
test('Should get metric', async () => { test('Should get metric', async () => {
const twoDaysAgo = new Date(); const twoDaysAgo = subDays(new Date(), 2);
twoDaysAgo.setHours(-48);
const metrics: IClientMetricsEnv[] = [ const metrics: IClientMetricsEnv[] = [
{ {
@ -362,7 +360,7 @@ test('Should get metric', async () => {
expect(metric.no).toBe(42); expect(metric.no).toBe(42);
}); });
test('Should not exists after delete', async () => { test('Should not exist after delete', async () => {
const metric = { const metric = {
featureName: 'demo4', featureName: 'demo4',
appName: 'backend-api', appName: 'backend-api',
@ -383,15 +381,3 @@ test('Should not exists after delete', async () => {
const existAfter = await clientMetricsStore.exists(metric); const existAfter = await clientMetricsStore.exists(metric);
expect(existAfter).toBe(false); expect(existAfter).toBe(false);
}); });
test('should floor hours as expected', () => {
expect(
roundDownToHour(new Date('2019-11-12T08:44:32.499Z')).toISOString(),
).toBe('2019-11-12T08:00:00.000Z');
expect(
roundDownToHour(new Date('2019-11-12T08:59:59.999Z')).toISOString(),
).toBe('2019-11-12T08:00:00.000Z');
expect(
roundDownToHour(new Date('2019-11-12T09:01:00.999Z')).toISOString(),
).toBe('2019-11-12T09:00:00.000Z');
});

View File

@ -1961,6 +1961,11 @@ data-urls@^2.0.0:
whatwg-mimetype "^2.3.0" whatwg-mimetype "^2.3.0"
whatwg-url "^8.0.0" whatwg-url "^8.0.0"
date-fns@^2.25.0:
version "2.25.0"
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.25.0.tgz#8c5c8f1d958be3809a9a03f4b742eba894fc5680"
integrity sha512-ovYRFnTrbGPD4nqaEqescPEv1mNwvt+UTqI3Ay9SzNtey9NZnYu6E2qCcBBgJ6/2VF1zGGygpyTDITqpQQ5e+w==
date-format@^2.1.0: date-format@^2.1.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.npmjs.org/date-format/-/date-format-2.1.0.tgz" resolved "https://registry.npmjs.org/date-format/-/date-format-2.1.0.tgz"