mirror of
https://github.com/Unleash/unleash.git
synced 2025-02-04 00:18:01 +01:00
238 lines
6.2 KiB
TypeScript
238 lines
6.2 KiB
TypeScript
import dbInit, { type ITestDb } from '../../../test/e2e/helpers/database-init';
|
|
import getLogger from '../../../test/fixtures/no-logger';
|
|
import {
|
|
type IFeatureToggleStore,
|
|
type ILastSeenStore,
|
|
type IOnboardingStore,
|
|
SYSTEM_USER,
|
|
} from '../../types';
|
|
import type { IOnboardingReadModel } from './onboarding-read-model-type';
|
|
import type ClientInstanceService from '../metrics/instance/instance-service';
|
|
import {
|
|
type IUnleashTest,
|
|
setupAppWithCustomConfig,
|
|
} from '../../../test/e2e/helpers/test-helper';
|
|
import { ApiTokenType } from '../../types/models/api-token';
|
|
|
|
let db: ITestDb;
|
|
let onboardingReadModel: IOnboardingReadModel;
|
|
let onBoardingStore: IOnboardingStore;
|
|
let featureToggleStore: IFeatureToggleStore;
|
|
let lastSeenStore: ILastSeenStore;
|
|
let instanceService: ClientInstanceService;
|
|
let app: IUnleashTest;
|
|
|
|
beforeAll(async () => {
|
|
db = await dbInit('onboarding_read_model', getLogger, {
|
|
experimental: { flags: {} },
|
|
});
|
|
|
|
app = await setupAppWithCustomConfig(
|
|
db.stores,
|
|
{
|
|
experimental: {
|
|
flags: {
|
|
strictSchemaValidation: true,
|
|
},
|
|
},
|
|
},
|
|
db.rawDatabase,
|
|
);
|
|
|
|
onboardingReadModel = db.stores.onboardingReadModel;
|
|
onBoardingStore = db.stores.onboardingStore;
|
|
featureToggleStore = db.stores.featureToggleStore;
|
|
lastSeenStore = db.stores.lastSeenStore;
|
|
instanceService = app.services.clientInstanceService;
|
|
});
|
|
|
|
afterAll(async () => {
|
|
if (db) {
|
|
await db.destroy();
|
|
}
|
|
});
|
|
|
|
beforeEach(async () => {
|
|
await featureToggleStore.deleteAll();
|
|
});
|
|
|
|
test('can get instance onboarding durations', async () => {
|
|
const initialResult =
|
|
await onboardingReadModel.getInstanceOnboardingMetrics();
|
|
expect(initialResult).toMatchObject({
|
|
firstLogin: null,
|
|
secondLogin: null,
|
|
firstFeatureFlag: null,
|
|
firstPreLive: null,
|
|
firstLive: null,
|
|
});
|
|
|
|
await onBoardingStore.insertInstanceEvent({
|
|
type: 'first-user-login',
|
|
timeToEvent: 0,
|
|
});
|
|
|
|
const firstLoginResult =
|
|
await onboardingReadModel.getInstanceOnboardingMetrics();
|
|
expect(firstLoginResult).toMatchObject({
|
|
firstLogin: 0,
|
|
secondLogin: null,
|
|
});
|
|
|
|
await onBoardingStore.insertInstanceEvent({
|
|
type: 'second-user-login',
|
|
timeToEvent: 10,
|
|
});
|
|
|
|
await onBoardingStore.insertInstanceEvent({
|
|
type: 'flag-created',
|
|
timeToEvent: 20,
|
|
});
|
|
|
|
await onBoardingStore.insertInstanceEvent({
|
|
type: 'pre-live',
|
|
timeToEvent: 30,
|
|
});
|
|
|
|
await onBoardingStore.insertInstanceEvent({
|
|
type: 'live',
|
|
timeToEvent: 40,
|
|
});
|
|
|
|
const secondLoginResult =
|
|
await onboardingReadModel.getInstanceOnboardingMetrics();
|
|
expect(secondLoginResult).toMatchObject({
|
|
firstLogin: 0,
|
|
secondLogin: 10,
|
|
firstFeatureFlag: 20,
|
|
firstPreLive: 30,
|
|
firstLive: 40,
|
|
});
|
|
});
|
|
|
|
test('can get instance onboarding durations', async () => {
|
|
await onBoardingStore.insertProjectEvent({
|
|
project: 'default',
|
|
type: 'flag-created',
|
|
timeToEvent: 20,
|
|
});
|
|
|
|
await onBoardingStore.insertProjectEvent({
|
|
project: 'default',
|
|
type: 'pre-live',
|
|
timeToEvent: 30,
|
|
});
|
|
|
|
await onBoardingStore.insertProjectEvent({
|
|
project: 'default',
|
|
type: 'live',
|
|
timeToEvent: 40,
|
|
});
|
|
|
|
const projectOnboardingResult =
|
|
await onboardingReadModel.getProjectsOnboardingMetrics();
|
|
|
|
expect(projectOnboardingResult).toMatchObject([
|
|
{
|
|
project: 'default',
|
|
firstFeatureFlag: 20,
|
|
firstPreLive: 30,
|
|
firstLive: 40,
|
|
},
|
|
]);
|
|
});
|
|
|
|
test('can get project onboarding status', async () => {
|
|
const onboardingStartedResult =
|
|
await onboardingReadModel.getOnboardingStatusForProject('default');
|
|
|
|
expect(onboardingStartedResult).toMatchObject({
|
|
status: 'onboarding-started',
|
|
});
|
|
|
|
await featureToggleStore.create('default', {
|
|
name: 'my-flag',
|
|
createdByUserId: SYSTEM_USER.id,
|
|
});
|
|
|
|
const firstFlagResult =
|
|
await onboardingReadModel.getOnboardingStatusForProject('default');
|
|
|
|
expect(firstFlagResult).toMatchObject({
|
|
status: 'first-flag-created',
|
|
feature: 'my-flag',
|
|
});
|
|
|
|
await lastSeenStore.setLastSeen([
|
|
{
|
|
environment: 'default',
|
|
featureName: 'my-flag',
|
|
},
|
|
]);
|
|
|
|
const onboardedResult =
|
|
await onboardingReadModel.getOnboardingStatusForProject('default');
|
|
|
|
expect(onboardedResult).toMatchObject({
|
|
status: 'onboarded',
|
|
});
|
|
});
|
|
|
|
test('archived feature counts as onboarded', async () => {
|
|
await featureToggleStore.create('default', {
|
|
name: 'my-flag',
|
|
createdByUserId: SYSTEM_USER.id,
|
|
});
|
|
|
|
await lastSeenStore.setLastSeen([
|
|
{
|
|
environment: 'default',
|
|
featureName: 'my-flag',
|
|
},
|
|
]);
|
|
|
|
await featureToggleStore.archive('my-flag');
|
|
|
|
const onboardedResult =
|
|
await onboardingReadModel.getOnboardingStatusForProject('default');
|
|
|
|
expect(onboardedResult).toMatchObject({
|
|
status: 'onboarded',
|
|
});
|
|
});
|
|
|
|
test('sdk register also onboards a project', async () => {
|
|
await featureToggleStore.create('default', {
|
|
name: 'my-flag',
|
|
createdByUserId: SYSTEM_USER.id,
|
|
});
|
|
|
|
const defaultProjectToken =
|
|
await app.services.apiTokenService.createApiTokenWithProjects({
|
|
type: ApiTokenType.CLIENT,
|
|
projects: ['default'],
|
|
environment: 'default',
|
|
tokenName: 'tester',
|
|
});
|
|
|
|
await app.request
|
|
.post('/api/client/register')
|
|
.set('Authorization', defaultProjectToken.secret)
|
|
.send({
|
|
appName: 'multi-project-app',
|
|
instanceId: 'instance-1',
|
|
strategies: ['default'],
|
|
started: Date.now(),
|
|
interval: 10,
|
|
});
|
|
|
|
await instanceService.bulkAdd();
|
|
|
|
const onboardedResult =
|
|
await onboardingReadModel.getOnboardingStatusForProject('default');
|
|
|
|
expect(onboardedResult).toMatchObject({
|
|
status: 'onboarded',
|
|
});
|
|
});
|