mirror of
https://github.com/Unleash/unleash.git
synced 2024-12-22 19:07:54 +01:00
chore: Backport 4.22.3 (#3508)
<!-- Thanks for creating a PR! To make it easier for reviewers and everyone else to understand what your changes relate to, please add some relevant content to the headings below. Feel free to ignore or delete sections that you don't think are relevant. Thank you! ❤️ --> Backports stickiness fixes ## About the changes <!-- Describe the changes introduced. What are they and why are they being introduced? Feel free to also add screenshots or steps to view the changes if they're visual. --> <!-- Does it close an issue? Multiple? --> Closes # <!-- (For internal contributors): Does it relate to an issue on public roadmap? --> <!-- Relates to [roadmap](https://github.com/orgs/Unleash/projects/10) item: # --> ### Important files <!-- PRs can contain a lot of changes, but not all changes are equally important. Where should a reviewer start looking to get an overview of the changes? Are any files particularly important? --> ## Discussion points <!-- Anything about the PR you'd like to discuss before it gets merged? Got any questions or doubts? --> --------- Signed-off-by: andreas-unleash <andreas@getunleash.ai> Co-authored-by: Gastón Fournier <gaston@getunleash.io> Co-authored-by: GitHub Actions Bot <> Co-authored-by: Mateusz Kwasniewski <kwasniewski.mateusz@gmail.com>
This commit is contained in:
parent
014a8a2280
commit
60a2c1a996
@ -15,7 +15,6 @@ describe('notifications', () => {
|
||||
cy.runBefore();
|
||||
});
|
||||
|
||||
// This one is failing on CI: https://github.com/Unleash/unleash/actions/runs/4609305167/jobs/8160244872#step:4:193
|
||||
it.skip('should create a notification when a feature is created in a project', () => {
|
||||
cy.login_UI();
|
||||
cy.createUser_API(userName, EDITOR).then(value => {
|
||||
@ -41,7 +40,7 @@ describe('notifications', () => {
|
||||
cy.get("[data-testid='NOTIFICATIONS_BUTTON']").click();
|
||||
|
||||
//then
|
||||
// cy.get("[data-testid='UNREAD_NOTIFICATIONS']").should('exist');
|
||||
cy.get("[data-testid='UNREAD_NOTIFICATIONS']").should('exist');
|
||||
cy.get("[data-testid='NOTIFICATIONS_LIST']").should(
|
||||
'contain.text',
|
||||
`New feature ${featureToggleName}`
|
||||
|
@ -74,7 +74,7 @@ export const FeatureStrategyCreate = () => {
|
||||
forceRefreshCache(feature);
|
||||
ref.current = feature;
|
||||
}
|
||||
}, [feature]);
|
||||
}, [feature.name]);
|
||||
|
||||
useEffect(() => {
|
||||
if (strategyDefinition) {
|
||||
|
@ -273,7 +273,13 @@ export const EnvironmentVariantsModal = ({
|
||||
isChangeRequestConfigured(environment?.name || '') &&
|
||||
uiConfig.flags.crOnVariants;
|
||||
|
||||
const stickiness = variants[0]?.stickiness || defaultStickiness;
|
||||
const stickiness = useMemo(() => {
|
||||
if (!loading) {
|
||||
return variants[0]?.stickiness || defaultStickiness;
|
||||
}
|
||||
return '';
|
||||
}, [loading, defaultStickiness, JSON.stringify(variants[0] ?? {})]);
|
||||
|
||||
const stickinessOptions = useMemo(
|
||||
() => [
|
||||
'default',
|
||||
@ -296,7 +302,7 @@ export const EnvironmentVariantsModal = ({
|
||||
};
|
||||
|
||||
const onStickinessChange = (value: string) => {
|
||||
updateStickiness(value).catch(console.warn);
|
||||
updateStickiness(value);
|
||||
};
|
||||
|
||||
const [error, setError] = useState<string | undefined>();
|
||||
@ -308,14 +314,13 @@ export const EnvironmentVariantsModal = ({
|
||||
}, [apiPayload.error]);
|
||||
|
||||
const handleClose = () => {
|
||||
updateStickiness(defaultStickiness).then();
|
||||
updateStickiness(defaultStickiness);
|
||||
setOpen(false);
|
||||
};
|
||||
|
||||
if (loading || stickiness === '') {
|
||||
return <Loader />;
|
||||
}
|
||||
|
||||
return (
|
||||
<SidebarModal open={open} onClose={handleClose} label="">
|
||||
<FormTemplate
|
||||
|
@ -12,10 +12,10 @@ import {
|
||||
parseParameterString,
|
||||
} from 'utils/parseParameter';
|
||||
import { StickinessSelect } from './StickinessSelect/StickinessSelect';
|
||||
import { useOptionalPathParam } from 'hooks/useOptionalPathParam';
|
||||
import { useDefaultProjectSettings } from 'hooks/useDefaultProjectSettings';
|
||||
import Loader from '../../../common/Loader/Loader';
|
||||
import { useMemo } from 'react';
|
||||
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
|
||||
|
||||
interface IFlexibleStrategyProps {
|
||||
parameters: IFeatureStrategyParameters;
|
||||
@ -29,7 +29,7 @@ const FlexibleStrategy = ({
|
||||
parameters,
|
||||
editable = true,
|
||||
}: IFlexibleStrategyProps) => {
|
||||
const projectId = useOptionalPathParam('projectId');
|
||||
const projectId = useRequiredPathParam('projectId');
|
||||
const { defaultStickiness, loading } = useDefaultProjectSettings(projectId);
|
||||
|
||||
const onUpdate = (field: string) => (newValue: string) => {
|
||||
|
@ -41,7 +41,6 @@ export const StickinessSelect = ({
|
||||
);
|
||||
|
||||
const stickinessOptions = resolveStickinessOptions();
|
||||
|
||||
return (
|
||||
<Select
|
||||
id="stickiness-select"
|
||||
|
@ -13,6 +13,7 @@ const fallbackProject: IProject = {
|
||||
description: 'Default',
|
||||
favorite: false,
|
||||
mode: 'open',
|
||||
defaultStickiness: 'default',
|
||||
stats: {
|
||||
archivedCurrentWindow: 0,
|
||||
archivedPastWindow: 0,
|
||||
|
@ -1,57 +1,19 @@
|
||||
import useUiConfig from './api/getters/useUiConfig/useUiConfig';
|
||||
import { SWRConfiguration } from 'swr';
|
||||
import { useCallback } from 'react';
|
||||
import handleErrorResponses from './api/getters/httpErrorResponseHandler';
|
||||
import { useConditionalSWR } from './api/getters/useConditionalSWR/useConditionalSWR';
|
||||
import { ProjectMode } from 'component/project/Project/hooks/useProjectForm';
|
||||
import { formatApiPath } from 'utils/formatPath';
|
||||
import useProject from './api/getters/useProject/useProject';
|
||||
|
||||
export interface ISettingsResponse {
|
||||
defaultStickiness?: string;
|
||||
mode?: ProjectMode;
|
||||
}
|
||||
const DEFAULT_STICKINESS = 'default';
|
||||
export const useDefaultProjectSettings = (
|
||||
projectId?: string,
|
||||
options?: SWRConfiguration
|
||||
) => {
|
||||
export const useDefaultProjectSettings = (projectId: string) => {
|
||||
const { uiConfig } = useUiConfig();
|
||||
|
||||
const PATH = `api/admin/projects/${projectId}/settings`;
|
||||
const { projectScopedStickiness } = uiConfig.flags;
|
||||
|
||||
const { data, isLoading, error, mutate } =
|
||||
useConditionalSWR<ISettingsResponse>(
|
||||
Boolean(projectId) && Boolean(projectScopedStickiness),
|
||||
{},
|
||||
['useDefaultProjectSettings', PATH],
|
||||
() => fetcher(formatApiPath(PATH)),
|
||||
options
|
||||
);
|
||||
|
||||
const defaultStickiness = (): string => {
|
||||
if (!isLoading) {
|
||||
if (data?.defaultStickiness) {
|
||||
return data?.defaultStickiness;
|
||||
}
|
||||
return DEFAULT_STICKINESS;
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
const refetch = useCallback(() => {
|
||||
mutate().catch(console.warn);
|
||||
}, [mutate]);
|
||||
const { project, loading, error } = useProject(projectId);
|
||||
return {
|
||||
defaultStickiness: defaultStickiness(),
|
||||
refetch,
|
||||
loading: isLoading,
|
||||
defaultStickiness: Boolean(projectScopedStickiness)
|
||||
? project.defaultStickiness
|
||||
: DEFAULT_STICKINESS,
|
||||
mode: project.mode,
|
||||
loading: loading,
|
||||
error,
|
||||
};
|
||||
};
|
||||
|
||||
const fetcher = (path: string) => {
|
||||
return fetch(path)
|
||||
.then(handleErrorResponses('Project stickiness data'))
|
||||
.then(res => res.json());
|
||||
};
|
||||
|
@ -24,6 +24,7 @@ export interface IProject {
|
||||
favorite: boolean;
|
||||
features: IFeatureToggleListItem[];
|
||||
mode: 'open' | 'protected';
|
||||
defaultStickiness: string;
|
||||
}
|
||||
|
||||
export interface IProjectHealthReport extends IProject {
|
||||
|
@ -33,7 +33,7 @@ const COLUMNS = [
|
||||
'updated_at',
|
||||
];
|
||||
const TABLE = 'projects';
|
||||
const SETTINGS_COLUMNS = ['project_mode'];
|
||||
const SETTINGS_COLUMNS = ['project_mode', 'default_stickiness'];
|
||||
const SETTINGS_TABLE = 'project_settings';
|
||||
|
||||
export interface IEnvironmentProjectLink {
|
||||
@ -531,6 +531,7 @@ class ProjectStore implements IProjectStore {
|
||||
health: row.health ?? 100,
|
||||
updatedAt: row.updated_at || new Date(),
|
||||
mode: row.project_mode || 'open',
|
||||
defaultStickiness: row.default_stickiness || 'default',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -798,13 +798,12 @@ export default class ProjectService {
|
||||
: Promise.resolve(false),
|
||||
this.projectStatsStore.getProjectStats(projectId),
|
||||
]);
|
||||
|
||||
return {
|
||||
stats: projectStats,
|
||||
name: project.name,
|
||||
description: project.description,
|
||||
mode: project.mode,
|
||||
defaultStickiness: project.defaultStickiness || 'default',
|
||||
defaultStickiness: project.defaultStickiness,
|
||||
health: project.health || 0,
|
||||
favorite: favorite,
|
||||
updatedAt: project.updatedAt,
|
||||
|
@ -372,7 +372,7 @@ export interface IProject {
|
||||
updatedAt?: Date;
|
||||
changeRequestsEnabled?: boolean;
|
||||
mode: ProjectMode;
|
||||
defaultStickiness?: string;
|
||||
defaultStickiness: string;
|
||||
}
|
||||
|
||||
export interface ICustomRole {
|
||||
|
@ -525,7 +525,12 @@ describe('Interacting with features using project IDs that belong to other proje
|
||||
rootRole: RoleName.ADMIN,
|
||||
});
|
||||
await app.services.projectService.createProject(
|
||||
{ name: otherProject, id: otherProject, mode: 'open' },
|
||||
{
|
||||
name: otherProject,
|
||||
id: otherProject,
|
||||
mode: 'open',
|
||||
defaultStickiness: 'clientId',
|
||||
},
|
||||
dummyAdmin,
|
||||
);
|
||||
|
||||
|
@ -101,7 +101,7 @@ const createProject = async (id: string, name: string): Promise<void> => {
|
||||
email: `${randomId()}@example.com`,
|
||||
});
|
||||
await app.services.projectService.createProject(
|
||||
{ id, name, mode: 'open' },
|
||||
{ id, name, mode: 'open', defaultStickiness: 'default' },
|
||||
user,
|
||||
);
|
||||
};
|
||||
|
@ -43,6 +43,7 @@ beforeAll(async () => {
|
||||
name: 'Test Project',
|
||||
description: 'Fancy',
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'clientId',
|
||||
};
|
||||
const user = await stores.userStore.insert({
|
||||
name: 'Some Name',
|
||||
|
@ -107,6 +107,7 @@ test('should list all projects', async () => {
|
||||
name: 'New project',
|
||||
description: 'Blah',
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'default',
|
||||
};
|
||||
|
||||
await projectService.createProject(project, user);
|
||||
@ -121,6 +122,7 @@ test('should create new project', async () => {
|
||||
name: 'New project',
|
||||
description: 'Blah',
|
||||
mode: 'protected' as const,
|
||||
defaultStickiness: 'default',
|
||||
};
|
||||
|
||||
await projectService.createProject(project, user);
|
||||
@ -138,6 +140,7 @@ test('should delete project', async () => {
|
||||
name: 'New project',
|
||||
description: 'Blah',
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'default',
|
||||
};
|
||||
|
||||
await projectService.createProject(project, user);
|
||||
@ -156,12 +159,14 @@ test('should not be able to delete project with toggles', async () => {
|
||||
name: 'New project',
|
||||
description: 'Blah',
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'clientId',
|
||||
};
|
||||
await projectService.createProject(project, user);
|
||||
await stores.featureToggleStore.create(project.id, {
|
||||
name: 'test-project-delete',
|
||||
project: project.id,
|
||||
enabled: false,
|
||||
defaultStickiness: 'default',
|
||||
});
|
||||
|
||||
try {
|
||||
@ -192,6 +197,7 @@ test('should not be able to create existing project', async () => {
|
||||
name: 'New project',
|
||||
description: 'Blah',
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'default',
|
||||
};
|
||||
try {
|
||||
await projectService.createProject(project, user);
|
||||
@ -223,6 +229,7 @@ test('should update project', async () => {
|
||||
name: 'New project',
|
||||
description: 'Blah',
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'default',
|
||||
};
|
||||
|
||||
const updatedProject = {
|
||||
@ -230,6 +237,7 @@ test('should update project', async () => {
|
||||
name: 'New name',
|
||||
description: 'Blah longer desc',
|
||||
mode: 'protected' as const,
|
||||
defaultStickiness: 'userId',
|
||||
};
|
||||
|
||||
await projectService.createProject(project, user);
|
||||
@ -240,6 +248,7 @@ test('should update project', async () => {
|
||||
expect(updatedProject.name).toBe(readProject.name);
|
||||
expect(updatedProject.description).toBe(readProject.description);
|
||||
expect(updatedProject.mode).toBe('protected');
|
||||
expect(updatedProject.defaultStickiness).toBe('userId');
|
||||
});
|
||||
|
||||
test('should update project without existing settings', async () => {
|
||||
@ -248,6 +257,7 @@ test('should update project without existing settings', async () => {
|
||||
name: 'New project',
|
||||
description: 'Blah',
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'default',
|
||||
};
|
||||
|
||||
const updatedProject = {
|
||||
@ -255,6 +265,7 @@ test('should update project without existing settings', async () => {
|
||||
name: 'New name',
|
||||
description: 'Blah longer desc',
|
||||
mode: 'protected' as const,
|
||||
defaultStickiness: 'clientId',
|
||||
};
|
||||
|
||||
await projectService.createProject(project, user);
|
||||
@ -269,6 +280,7 @@ test('should update project without existing settings', async () => {
|
||||
expect(updatedProject.name).toBe(readProject.name);
|
||||
expect(updatedProject.description).toBe(readProject.description);
|
||||
expect(updatedProject.mode).toBe('protected');
|
||||
expect(updatedProject.defaultStickiness).toBe('clientId');
|
||||
});
|
||||
|
||||
test('should give error when getting unknown project', async () => {
|
||||
@ -285,6 +297,7 @@ test('should get list of users with access to project', async () => {
|
||||
name: 'New project',
|
||||
description: 'Blah',
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'clientId',
|
||||
};
|
||||
await projectService.createProject(project, user);
|
||||
const { users } = await projectService.getAccessToProject(project.id);
|
||||
@ -307,6 +320,7 @@ test('should add a member user to the project', async () => {
|
||||
name: 'New project',
|
||||
description: 'Blah',
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'clientId',
|
||||
};
|
||||
await projectService.createProject(project, user);
|
||||
|
||||
@ -363,6 +377,7 @@ test('should add admin users to the project', async () => {
|
||||
name: 'New project',
|
||||
description: 'Blah',
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'clientId',
|
||||
};
|
||||
await projectService.createProject(project, user);
|
||||
|
||||
@ -410,6 +425,7 @@ test('add user should fail if user already have access', async () => {
|
||||
name: 'New project',
|
||||
description: 'Blah',
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'clientId',
|
||||
};
|
||||
await projectService.createProject(project, user);
|
||||
|
||||
@ -445,6 +461,7 @@ test('should remove user from the project', async () => {
|
||||
name: 'New project',
|
||||
description: 'Blah',
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'clientId',
|
||||
};
|
||||
await projectService.createProject(project, user);
|
||||
|
||||
@ -480,6 +497,7 @@ test('should not remove user from the project', async () => {
|
||||
name: 'New project',
|
||||
description: 'Blah',
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'clientId',
|
||||
};
|
||||
await projectService.createProject(project, user);
|
||||
|
||||
@ -504,6 +522,7 @@ test('should not change project if feature toggle project does not match current
|
||||
name: 'New project',
|
||||
description: 'Blah',
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'clientId',
|
||||
};
|
||||
|
||||
const toggle = { name: 'test-toggle' };
|
||||
@ -531,6 +550,7 @@ test('should return 404 if no project is found with the project id', async () =>
|
||||
name: 'New project',
|
||||
description: 'Blah',
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'clientId',
|
||||
};
|
||||
|
||||
const toggle = { name: 'test-toggle-2' };
|
||||
@ -556,6 +576,7 @@ test('should fail if user is not authorized', async () => {
|
||||
name: 'New project',
|
||||
description: 'Blah',
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'clientId',
|
||||
};
|
||||
|
||||
const projectDestination = {
|
||||
@ -563,6 +584,7 @@ test('should fail if user is not authorized', async () => {
|
||||
name: 'New project 2',
|
||||
description: 'Blah',
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'clientId',
|
||||
};
|
||||
|
||||
const toggle = { name: 'test-toggle-3' };
|
||||
@ -594,11 +616,13 @@ test('should change project when checks pass', async () => {
|
||||
id: randomId(),
|
||||
name: randomId(),
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'clientId',
|
||||
};
|
||||
const projectB = {
|
||||
id: randomId(),
|
||||
name: randomId(),
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'clientId',
|
||||
};
|
||||
const toggle = { name: randomId() };
|
||||
|
||||
@ -623,11 +647,13 @@ test('changing project should emit event even if user does not have a username s
|
||||
id: randomId(),
|
||||
name: randomId(),
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'default',
|
||||
};
|
||||
const projectB = {
|
||||
id: randomId(),
|
||||
name: randomId(),
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'clientId',
|
||||
};
|
||||
const toggle = { name: randomId() };
|
||||
await projectService.createProject(projectA, user);
|
||||
@ -649,11 +675,13 @@ test('should require equal project environments to move features', async () => {
|
||||
id: randomId(),
|
||||
name: randomId(),
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'clientId',
|
||||
};
|
||||
const projectB = {
|
||||
id: randomId(),
|
||||
name: randomId(),
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'clientId',
|
||||
};
|
||||
const environment = { name: randomId(), type: 'production' };
|
||||
const toggle = { name: randomId() };
|
||||
@ -683,6 +711,7 @@ test('A newly created project only gets connected to enabled environments', asyn
|
||||
name: 'New environment project',
|
||||
description: 'Blah',
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'clientId',
|
||||
};
|
||||
const enabledEnv = 'connection_test';
|
||||
await db.stores.environmentStore.create({
|
||||
@ -710,6 +739,7 @@ test('should have environments sorted in order', async () => {
|
||||
name: 'Environment testing project',
|
||||
description: '',
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'clientId',
|
||||
};
|
||||
const first = 'test';
|
||||
const second = 'abc';
|
||||
@ -749,6 +779,7 @@ test('should add a user to the project with a custom role', async () => {
|
||||
name: 'New project',
|
||||
description: 'Blah',
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'clientId',
|
||||
};
|
||||
await projectService.createProject(project, user);
|
||||
|
||||
@ -800,6 +831,7 @@ test('should delete role entries when deleting project', async () => {
|
||||
name: 'New project',
|
||||
description: 'Blah',
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'clientId',
|
||||
};
|
||||
|
||||
await projectService.createProject(project, user);
|
||||
@ -852,6 +884,7 @@ test('should change a users role in the project', async () => {
|
||||
name: 'New project',
|
||||
description: 'Blah',
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'clientId',
|
||||
};
|
||||
|
||||
await projectService.createProject(project, user);
|
||||
@ -919,6 +952,7 @@ test('should update role for user on project', async () => {
|
||||
name: 'New project',
|
||||
description: 'Blah',
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'clientId',
|
||||
};
|
||||
await projectService.createProject(project, user);
|
||||
|
||||
@ -957,6 +991,7 @@ test('should able to assign role without existing members', async () => {
|
||||
name: 'New project',
|
||||
description: 'Blah',
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'clientId',
|
||||
};
|
||||
await projectService.createProject(project, user);
|
||||
|
||||
@ -1000,6 +1035,7 @@ test('should not update role for user on project when she is the owner', async (
|
||||
name: 'New project',
|
||||
description: 'Blah',
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'clientId',
|
||||
};
|
||||
await projectService.createProject(project, user);
|
||||
|
||||
@ -1034,6 +1070,7 @@ test('Should allow bulk update of group permissions', async () => {
|
||||
id: 'bulk-update-project',
|
||||
name: 'bulk-update-project',
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'clientId',
|
||||
};
|
||||
await projectService.createProject(project, user.id);
|
||||
const groupStore = stores.groupStore;
|
||||
@ -1111,6 +1148,7 @@ test('Should allow bulk update of only groups', async () => {
|
||||
id: 'bulk-update-project-only',
|
||||
name: 'bulk-update-project-only',
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'clientId',
|
||||
};
|
||||
const groupStore = stores.groupStore;
|
||||
|
||||
@ -1152,6 +1190,7 @@ test('should only count active feature toggles for project', async () => {
|
||||
name: 'New project',
|
||||
description: 'Blah',
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'clientId',
|
||||
};
|
||||
|
||||
await projectService.createProject(project, user);
|
||||
@ -1180,6 +1219,7 @@ test('should list projects with all features archived', async () => {
|
||||
name: 'Listed project',
|
||||
description: 'Blah',
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'clientId',
|
||||
};
|
||||
|
||||
await projectService.createProject(project, user);
|
||||
@ -1216,6 +1256,7 @@ test('should calculate average time to production', async () => {
|
||||
id: 'average-time-to-prod',
|
||||
name: 'average-time-to-prod',
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'clientId',
|
||||
};
|
||||
|
||||
await projectService.createProject(project, user.id);
|
||||
@ -1274,6 +1315,7 @@ test('should calculate average time to production ignoring some items', async ()
|
||||
id: 'average-time-to-prod-corner-cases',
|
||||
name: 'average-time-to-prod',
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'clientId',
|
||||
};
|
||||
const makeEvent = (featureName: string) => ({
|
||||
enabled: true,
|
||||
@ -1362,6 +1404,7 @@ test('should get correct amount of features created in current and past window',
|
||||
id: 'features-created',
|
||||
name: 'features-created',
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'clientId',
|
||||
};
|
||||
|
||||
await projectService.createProject(project, user.id);
|
||||
@ -1398,6 +1441,7 @@ test('should get correct amount of features archived in current and past window'
|
||||
id: 'features-archived',
|
||||
name: 'features-archived',
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'clientId',
|
||||
};
|
||||
|
||||
await projectService.createProject(project, user.id);
|
||||
@ -1448,6 +1492,7 @@ test('should get correct amount of project members for current and past window',
|
||||
id: 'features-members',
|
||||
name: 'features-members',
|
||||
mode: 'open' as const,
|
||||
defaultStickiness: 'default',
|
||||
};
|
||||
|
||||
await projectService.createProject(project, user.id);
|
||||
|
1
src/test/fixtures/fake-project-store.ts
vendored
1
src/test/fixtures/fake-project-store.ts
vendored
@ -55,6 +55,7 @@ export default class FakeProjectStore implements IProjectStore {
|
||||
health: 100,
|
||||
createdAt: new Date(),
|
||||
mode: 'open',
|
||||
defaultStickiness: 'default',
|
||||
};
|
||||
this.projects.push(newProj);
|
||||
return newProj;
|
||||
|
Loading…
Reference in New Issue
Block a user