diff --git a/src/lib/features/feature-toggle/feature-toggle-strategies-store.ts b/src/lib/features/feature-toggle/feature-toggle-strategies-store.ts index 6cc8a369f080..4fca52ad3e79 100644 --- a/src/lib/features/feature-toggle/feature-toggle-strategies-store.ts +++ b/src/lib/features/feature-toggle/feature-toggle-strategies-store.ts @@ -25,6 +25,7 @@ import { ensureStringValue, mapValues } from '../../util'; import { IFeatureProjectUserParams } from './feature-toggle-controller'; import { Db } from '../../db/db'; import Raw = Knex.Raw; +import { isAfter } from 'date-fns'; const COLUMNS = [ 'id', @@ -383,7 +384,6 @@ class FeatureStrategiesStore implements IFeatureStrategiesStore { acc.description = r.description; acc.project = r.project; acc.stale = r.stale; - acc.lastSeenAt = r.last_seen_at; acc.createdAt = r.created_at; acc.type = r.type; @@ -395,8 +395,11 @@ class FeatureStrategiesStore implements IFeatureStrategiesStore { } if ( - acc.lastSeenAt === undefined || - new Date(r.env_last_seen_at) > new Date(acc.lastSeenAt) + acc.lastSeenAt == null || + isAfter( + new Date(r.env_last_seen_at), + new Date(acc[r.feature_name]), + ) ) { acc.lastSeenAt = r.env_last_seen_at; } @@ -626,7 +629,7 @@ class FeatureStrategiesStore implements IFeatureStrategiesStore { getAggregatedSearchData(rows): IFeatureOverview { return rows.reduce((acc, row) => { - if (acc[row.feature_name] !== undefined) { + if (acc[row.feature_name]) { const environmentExists = acc[ row.feature_name ].environments.some( @@ -671,9 +674,10 @@ class FeatureStrategiesStore implements IFeatureStrategiesStore { } const featureRow = acc[row.feature_name]; if ( - featureRow.lastSeenAt === undefined || - new Date(row.env_last_seen_at) > - new Date(featureRow.last_seen_at) + isAfter( + new Date(row.env_last_seen_at), + new Date(featureRow.lastSeenAt), + ) ) { featureRow.lastSeenAt = row.env_last_seen_at; } @@ -683,7 +687,7 @@ class FeatureStrategiesStore implements IFeatureStrategiesStore { getFeatureOverviewData(rows): IFeatureOverview { return rows.reduce((acc, row) => { - if (acc[row.feature_name] !== undefined) { + if (acc[row.feature_name]) { const environmentExists = acc[ row.feature_name ].environments.some( @@ -718,9 +722,10 @@ class FeatureStrategiesStore implements IFeatureStrategiesStore { } const featureRow = acc[row.feature_name]; if ( - featureRow.lastSeenAt === undefined || - new Date(row.env_last_seen_at) > - new Date(featureRow.last_seen_at) + isAfter( + new Date(row.env_last_seen_at), + new Date(featureRow.lastSeenAt), + ) ) { featureRow.lastSeenAt = row.env_last_seen_at; } diff --git a/src/lib/features/feature-toggle/tests/feature-toggle-service.e2e.test.ts b/src/lib/features/feature-toggle/tests/feature-toggle-service.e2e.test.ts index c36534d603d5..f5e518398f80 100644 --- a/src/lib/features/feature-toggle/tests/feature-toggle-service.e2e.test.ts +++ b/src/lib/features/feature-toggle/tests/feature-toggle-service.e2e.test.ts @@ -719,13 +719,14 @@ test('Should return last seen at per environment', async () => { db.rawDatabase, ); - const { environments } = await service.getFeature({ + const { environments, lastSeenAt } = await service.getFeature({ featureName, projectId: 'default', environmentVariants: false, }); expect(environments[0].lastSeenAt).toEqual(new Date(date)); + expect(lastSeenAt).toEqual(new Date(date)); // Test with feature flag on const config = createTestConfig(); @@ -746,4 +747,5 @@ test('Should return last seen at per environment', async () => { expect(featureToggle.environments[0].lastSeenAt).toEqual( new Date(lastSeenAtStoreDate), ); + expect(featureToggle.lastSeenAt).toEqual(new Date(lastSeenAtStoreDate)); }); diff --git a/src/test/e2e/api/admin/project/projects.e2e.test.ts b/src/test/e2e/api/admin/project/projects.e2e.test.ts index 0ae6f6ad0466..b9c232f02534 100644 --- a/src/test/e2e/api/admin/project/projects.e2e.test.ts +++ b/src/test/e2e/api/admin/project/projects.e2e.test.ts @@ -183,6 +183,7 @@ test('response should include last seen at per environment', async () => { .expect(200); expect(body.features[0].environments[0].lastSeenAt).toEqual(testDate); + expect(body.features[0].lastSeenAt).toEqual(testDate); const appWithLastSeenRefactor = await setupAppWithCustomConfig( db.stores, @@ -198,6 +199,9 @@ test('response should include last seen at per environment', async () => { expect(response.body.features[0].environments[0].lastSeenAt).toEqual( '2023-10-01T12:34:56.000Z', ); + expect(response.body.features[0].lastSeenAt).toEqual( + '2023-10-01T12:34:56.000Z', + ); }); test('response should include last seen at per environment for multiple environments', async () => { @@ -239,16 +243,19 @@ test('response should include last seen at per environment for multiple environm 'multiple-environment-last-seen-at', db.rawDatabase, 'default', + '2023-10-01 12:32:56', ); await insertLastSeenAt( 'multiple-environment-last-seen-at', db.rawDatabase, 'development', + '2023-10-01 12:34:56', ); await insertLastSeenAt( 'multiple-environment-last-seen-at', db.rawDatabase, 'production', + '2023-10-01 12:33:56', ); const { body } = await appWithLastSeenRefactor.request @@ -261,11 +268,13 @@ test('response should include last seen at per environment for multiple environm const [def, development, production] = featureEnvironments; expect(def.name).toBe('default'); - expect(def.lastSeenAt).toEqual('2023-10-01T12:34:56.000Z'); + expect(def.lastSeenAt).toEqual('2023-10-01T12:32:56.000Z'); expect(development.name).toBe('development'); expect(development.lastSeenAt).toEqual('2023-10-01T12:34:56.000Z'); expect(production.name).toBe('production'); - expect(production.lastSeenAt).toEqual('2023-10-01T12:34:56.000Z'); + expect(production.lastSeenAt).toEqual('2023-10-01T12:33:56.000Z'); + + expect(body.features[1].lastSeenAt).toBe('2023-10-01T12:34:56.000Z'); });