mirror of
https://github.com/Unleash/unleash.git
synced 2025-02-23 00:22:19 +01:00
fix: onboarding events corner cases (#8057)
This commit is contained in:
parent
08d9b92e55
commit
b350bd11a7
@ -302,6 +302,7 @@ class UserStore implements IUserStore {
|
|||||||
async getFirstUserDate(): Promise<Date | null> {
|
async getFirstUserDate(): Promise<Date | null> {
|
||||||
const firstInstanceUser = await this.db('users')
|
const firstInstanceUser = await this.db('users')
|
||||||
.select('created_at')
|
.select('created_at')
|
||||||
|
.where('is_system', '=', false)
|
||||||
.orderBy('created_at', 'asc')
|
.orderBy('created_at', 'asc')
|
||||||
.first();
|
.first();
|
||||||
|
|
||||||
|
@ -35,9 +35,60 @@ beforeEach(async () => {
|
|||||||
await stores.featureToggleStore.deleteAll();
|
await stores.featureToggleStore.deleteAll();
|
||||||
await stores.projectStore.deleteAll();
|
await stores.projectStore.deleteAll();
|
||||||
await stores.onboardingStore.deleteAll();
|
await stores.onboardingStore.deleteAll();
|
||||||
|
await stores.userStore.deleteAll();
|
||||||
jest.useRealTimers();
|
jest.useRealTimers();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Default project should take first user created instead of project created as start time', async () => {
|
||||||
|
jest.useFakeTimers();
|
||||||
|
jest.setSystemTime(new Date());
|
||||||
|
const { userStore, featureToggleStore, projectStore, projectReadModel } =
|
||||||
|
stores;
|
||||||
|
|
||||||
|
// default projects are created in advance and should be ignored
|
||||||
|
await projectStore.create({ id: 'default', name: 'irrelevant' });
|
||||||
|
|
||||||
|
jest.advanceTimersByTime(minutesToMilliseconds(1));
|
||||||
|
const user = await userStore.insert({});
|
||||||
|
await featureToggleStore.create('default', {
|
||||||
|
name: 'test-default',
|
||||||
|
createdByUserId: user.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
jest.advanceTimersByTime(minutesToMilliseconds(1));
|
||||||
|
await onboardingService.insert({
|
||||||
|
type: 'flag-created',
|
||||||
|
flag: 'test-default',
|
||||||
|
});
|
||||||
|
await onboardingService.insert({ type: 'pre-live', flag: 'test-default' });
|
||||||
|
await onboardingService.insert({ type: 'live', flag: 'test-default' });
|
||||||
|
|
||||||
|
const { rows: projectEvents } = await db.rawDatabase.raw(
|
||||||
|
'SELECT * FROM onboarding_events_project',
|
||||||
|
);
|
||||||
|
expect(projectEvents).toMatchObject([
|
||||||
|
{ event: 'first-flag', time_to_event: 60, project: 'default' },
|
||||||
|
{
|
||||||
|
event: 'first-pre-live',
|
||||||
|
time_to_event: 60,
|
||||||
|
project: 'default',
|
||||||
|
},
|
||||||
|
{ event: 'first-live', time_to_event: 60, project: 'default' },
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Ignore system user in onboarding events', async () => {
|
||||||
|
// system users are not counted towards onboarding metrics
|
||||||
|
await db.rawDatabase.raw('INSERT INTO users (is_system) VALUES (true)');
|
||||||
|
|
||||||
|
await onboardingService.insert({ type: 'first-user-login' });
|
||||||
|
|
||||||
|
const { rows: instanceEvents } = await db.rawDatabase.raw(
|
||||||
|
'SELECT * FROM onboarding_events_instance',
|
||||||
|
);
|
||||||
|
expect(instanceEvents).toMatchObject([]);
|
||||||
|
});
|
||||||
|
|
||||||
test('Storing onboarding events', async () => {
|
test('Storing onboarding events', async () => {
|
||||||
jest.useFakeTimers();
|
jest.useFakeTimers();
|
||||||
jest.setSystemTime(new Date());
|
jest.setSystemTime(new Date());
|
||||||
|
@ -124,8 +124,15 @@ export class OnboardingService {
|
|||||||
);
|
);
|
||||||
if (!project) return;
|
if (!project) return;
|
||||||
|
|
||||||
|
const startDate =
|
||||||
|
project.project === 'default'
|
||||||
|
? await this.userStore.getFirstUserDate()
|
||||||
|
: project.createdAt || null;
|
||||||
|
|
||||||
|
if (!startDate) return;
|
||||||
|
|
||||||
const timeToEvent = millisecondsToSeconds(
|
const timeToEvent = millisecondsToSeconds(
|
||||||
new Date().getTime() - project.createdAt.getTime(),
|
Date.now() - startDate.getTime(),
|
||||||
);
|
);
|
||||||
await this.onboardingStore.insertProjectEvent({
|
await this.onboardingStore.insertProjectEvent({
|
||||||
type: event.type,
|
type: event.type,
|
||||||
|
Loading…
Reference in New Issue
Block a user