mirror of
https://github.com/Unleash/unleash.git
synced 2024-12-22 19:07:54 +01:00
tests: add more tests for the lifecycle avg calculation query (#8698)
This PR adds more tests to check a few more cases for the lifecycle calculation query. Specifically, it tests that: - If we don't have any data for a stage, we return `null`. - We filter on projects - It correctly takes `0` days into account when calculating averages.
This commit is contained in:
parent
5733f91347
commit
0a250a7526
@ -1,4 +1,4 @@
|
||||
import { addDays } from 'date-fns';
|
||||
import { addDays, addMinutes } from 'date-fns';
|
||||
import dbInit, { type ITestDb } from '../../../test/e2e/helpers/database-init';
|
||||
import getLogger from '../../../test/fixtures/no-logger';
|
||||
import { ProjectLifecycleSummaryReadModel } from './project-lifecycle-summary-read-model';
|
||||
@ -17,6 +17,12 @@ afterAll(async () => {
|
||||
}
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await db.stores.projectStore.deleteAll();
|
||||
await db.stores.featureToggleStore.deleteAll();
|
||||
await db.stores.featureLifecycleStore.deleteAll();
|
||||
});
|
||||
|
||||
const updateFeatureStageDate = async (
|
||||
flagName: string,
|
||||
stage: string,
|
||||
@ -30,22 +36,22 @@ const updateFeatureStageDate = async (
|
||||
|
||||
describe('Average time calculation', () => {
|
||||
test('it calculates the average time for each stage', async () => {
|
||||
const project1 = await db.stores.projectStore.create({
|
||||
name: 'project1',
|
||||
id: 'project1',
|
||||
const project = await db.stores.projectStore.create({
|
||||
name: 'project',
|
||||
id: randomId(),
|
||||
});
|
||||
const now = new Date();
|
||||
|
||||
const flags = [
|
||||
{ name: randomId(), offsets: [2, 5, 6, 10] },
|
||||
{ name: randomId(), offsets: [1, null, 4, 7] },
|
||||
{ name: randomId(), offsets: [12, 25, 8, 9] },
|
||||
{ name: randomId(), offsets: [12, 25, 0, 9] },
|
||||
{ name: randomId(), offsets: [1, 2, 3, null] },
|
||||
];
|
||||
|
||||
for (const { name, offsets } of flags) {
|
||||
const created = await db.stores.featureToggleStore.create(
|
||||
project1.id,
|
||||
project.id,
|
||||
{
|
||||
name,
|
||||
createdByUserId: 1,
|
||||
@ -79,27 +85,115 @@ describe('Average time calculation', () => {
|
||||
await updateFeatureStageDate(
|
||||
created.name,
|
||||
stage,
|
||||
addDays(now, offsetFromInitial),
|
||||
addMinutes(
|
||||
addDays(now, offsetFromInitial),
|
||||
1 * (index + 1),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const readModel = new ProjectLifecycleSummaryReadModel(db.rawDatabase);
|
||||
|
||||
const result = await readModel.getAverageTimeInEachStage(project1.id);
|
||||
const result = await readModel.getAverageTimeInEachStage(project.id);
|
||||
|
||||
expect(result).toMatchObject({
|
||||
initial: 4, // (2 + 1 + 12 + 1) / 4 = 4
|
||||
'pre-live': 9, // (5 + 25 + 2 + 4) / 4 = 9
|
||||
live: 6, // (6 + 8 + 3) / 3 ~= 5.67 ~= 6
|
||||
'pre-live': 9, // (5 + 4 + 25 + 2) / 4 = 9
|
||||
live: 3, // (6 + 0 + 3) / 3 = 3
|
||||
completed: 9, // (10 + 7 + 9) / 3 ~= 8.67 ~= 9
|
||||
});
|
||||
});
|
||||
|
||||
test('it returns `null` if it has no data for something', async () => {});
|
||||
test('it rounds to the nearest whole number', async () => {});
|
||||
test('it ignores flags in other projects', async () => {});
|
||||
test('it ignores flags in other projects', async () => {});
|
||||
test('it returns `null` if it has no data for something', async () => {
|
||||
const project = await db.stores.projectStore.create({
|
||||
name: 'project',
|
||||
id: randomId(),
|
||||
});
|
||||
const readModel = new ProjectLifecycleSummaryReadModel(db.rawDatabase);
|
||||
|
||||
test("it ignores rows that don't have a next stage", async () => {});
|
||||
const result1 = await readModel.getAverageTimeInEachStage(project.id);
|
||||
|
||||
expect(result1).toMatchObject({
|
||||
initial: null,
|
||||
'pre-live': null,
|
||||
live: null,
|
||||
completed: null,
|
||||
});
|
||||
|
||||
const flag = await db.stores.featureToggleStore.create(project.id, {
|
||||
name: randomId(),
|
||||
createdByUserId: 1,
|
||||
});
|
||||
await db.stores.featureLifecycleStore.insert([
|
||||
{
|
||||
feature: flag.name,
|
||||
stage: 'initial',
|
||||
},
|
||||
]);
|
||||
|
||||
await db.stores.featureLifecycleStore.insert([
|
||||
{
|
||||
feature: flag.name,
|
||||
stage: 'pre-live',
|
||||
},
|
||||
]);
|
||||
|
||||
await updateFeatureStageDate(
|
||||
flag.name,
|
||||
'pre-live',
|
||||
addDays(new Date(), 5),
|
||||
);
|
||||
|
||||
const result2 = await readModel.getAverageTimeInEachStage(project.id);
|
||||
|
||||
expect(result2).toMatchObject({
|
||||
initial: 5,
|
||||
'pre-live': null,
|
||||
live: null,
|
||||
completed: null,
|
||||
});
|
||||
});
|
||||
|
||||
test('it ignores flags in other projects', async () => {
|
||||
const project = await db.stores.projectStore.create({
|
||||
name: 'project',
|
||||
id: randomId(),
|
||||
});
|
||||
const readModel = new ProjectLifecycleSummaryReadModel(db.rawDatabase);
|
||||
|
||||
const flag = await db.stores.featureToggleStore.create(project.id, {
|
||||
name: randomId(),
|
||||
createdByUserId: 1,
|
||||
});
|
||||
await db.stores.featureLifecycleStore.insert([
|
||||
{
|
||||
feature: flag.name,
|
||||
stage: 'initial',
|
||||
},
|
||||
]);
|
||||
|
||||
await db.stores.featureLifecycleStore.insert([
|
||||
{
|
||||
feature: flag.name,
|
||||
stage: 'pre-live',
|
||||
},
|
||||
]);
|
||||
|
||||
await updateFeatureStageDate(
|
||||
flag.name,
|
||||
'pre-live',
|
||||
addDays(new Date(), 5),
|
||||
);
|
||||
|
||||
const result =
|
||||
await readModel.getAverageTimeInEachStage('some-other-project');
|
||||
|
||||
expect(result).toMatchObject({
|
||||
initial: null,
|
||||
'pre-live': null,
|
||||
live: null,
|
||||
completed: null,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -38,10 +38,10 @@ export class ProjectLifecycleSummaryReadModel
|
||||
}
|
||||
|
||||
async getAverageTimeInEachStage(projectId: string): Promise<{
|
||||
initial: number;
|
||||
'pre-live': number;
|
||||
live: number;
|
||||
completed: number;
|
||||
initial: number | null;
|
||||
'pre-live': number | null;
|
||||
live: number | null;
|
||||
completed: number | null;
|
||||
}> {
|
||||
const q = this.db
|
||||
.with(
|
||||
@ -80,10 +80,10 @@ export class ProjectLifecycleSummaryReadModel
|
||||
return acc;
|
||||
},
|
||||
{
|
||||
initial: 0,
|
||||
'pre-live': 0,
|
||||
live: 0,
|
||||
completed: 0,
|
||||
initial: null,
|
||||
'pre-live': null,
|
||||
live: null,
|
||||
completed: null,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -294,7 +294,7 @@ const config: Config = {
|
||||
routeBasePath: '/',
|
||||
remarkPlugins: [[pluginNpm2Yarn, { sync: true }]],
|
||||
docItemComponent: '@theme/ApiItem',
|
||||
sidebarPath: './sidebars.ts'
|
||||
sidebarPath: './sidebars.ts',
|
||||
},
|
||||
theme: {
|
||||
customCss: './src/css/custom.css',
|
||||
|
Loading…
Reference in New Issue
Block a user