Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
getSegmentChangesThatWouldBeOverwritten,
getStrategyChangesThatWouldBeOverwritten,
} from './strategy-change-diff-calculation.js';
import { constraintId } from 'constants/constraintId.js';

describe('Strategy change conflict detection', () => {
const existingStrategy: IFeatureStrategy = {
Expand Down Expand Up @@ -175,6 +176,7 @@ describe('Strategy change conflict detection', () => {
operator: 'IN' as const,
contextName: 'appName',
caseInsensitive: false,
[constraintId]: 'id1',
},
],
variants: [
Expand Down Expand Up @@ -230,6 +232,7 @@ describe('Strategy change conflict detection', () => {
operator: 'IN' as const,
contextName: 'appName',
caseInsensitive: false,
[constraintId]: 'id2',
},
],
};
Expand All @@ -249,6 +252,7 @@ describe('Strategy change conflict detection', () => {
inverted: false,
operator: 'IN' as const,
values: ['blah'],
[constraintId]: 'id2',
},
],
},
Expand Down Expand Up @@ -478,6 +482,7 @@ describe('Segment change conflict detection', () => {
operator: 'IN' as const,
contextName: 'appName',
caseInsensitive: false,
[constraintId]: 'id3',
},
],
};
Expand All @@ -494,6 +499,7 @@ describe('Segment change conflict detection', () => {
operator: 'IN' as const,
contextName: 'appName',
caseInsensitive: false,
[constraintId]: 'id4',
},
],
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { ConstraintsList } from 'component/common/ConstraintsList/ConstraintsLis
import { EditableConstraint } from 'component/feature/FeatureStrategy/FeatureStrategyConstraints/EditableConstraint/EditableConstraint';
import { createEmptyConstraint } from '../../../../utils/createEmptyConstraint.ts';
import { constraintId } from 'constants/constraintId.ts';
import { v4 as uuidv4 } from 'uuid';
export interface IEditableConstraintsListRef {
addConstraint?: (contextName: string) => void;
}
Expand Down Expand Up @@ -44,7 +43,6 @@ export const EditableConstraintsList = forwardRef<
if (!constraints.every((constraint) => constraintId in constraint)) {
setConstraints(
constraints.map((constraint) => ({
[constraintId]: uuidv4(),
...constraint,
})),
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { createEmptyConstraint } from 'utils/createEmptyConstraint';
import { fromIConstraint, toIConstraint } from './editable-constraint-type.ts';
import { constraintId } from 'constants/constraintId';
import type { IConstraint } from 'interfaces/strategy.ts';

test('mapping to and from retains the constraint id', () => {
const constraint = createEmptyConstraint('context');
Expand All @@ -11,18 +10,6 @@ test('mapping to and from retains the constraint id', () => {
);
});

test('mapping to an editable constraint adds a constraint id if there is none', () => {
const constraint: IConstraint = createEmptyConstraint('context');
delete constraint[constraintId];

const editableConstraint = fromIConstraint(constraint);

expect(editableConstraint[constraintId]).toBeDefined();

const iConstraint = toIConstraint(editableConstraint);
expect(iConstraint[constraintId]).toEqual(editableConstraint[constraintId]);
});

test('mapping from an empty constraint removes redundant value / values', () => {
const constraint = { ...createEmptyConstraint('context'), value: '' };
expect(constraint).toHaveProperty('value');
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { constraintId } from 'constants/constraintId';
import {
type DateOperator,
isDateOperator,
Expand All @@ -11,7 +10,6 @@ import {
isSemVerOperator,
} from 'constants/operators';
import type { IConstraint } from 'interfaces/strategy';
import { v4 as uuidv4 } from 'uuid';

type EditableConstraintBase = Omit<
IConstraint,
Expand Down Expand Up @@ -74,14 +72,12 @@ export const fromIConstraint = (
const { value, values, operator, ...rest } = constraint;
if (isSingleValueOperator(operator)) {
return {
[constraintId]: uuidv4(),
...rest,
operator,
value: value ?? '',
};
} else {
return {
[constraintId]: uuidv4(),
...rest,
operator,
values: new Set(values),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { vi } from 'vitest';
import { testServerRoute, testServerSetup } from 'utils/testServer';
import type { ContextFieldSchema } from 'openapi';
import { NUM_EQ } from '@server/util/constants';
import { constraintId } from 'constants/constraintId.js';

const server = testServerSetup();

Expand All @@ -25,6 +26,7 @@ test('calls onUpdate with new state', async () => {
contextName: 'context-field',
operator: NOT_IN,
values: ['A', 'B'],
[constraintId]: 'constraint id',
};

const onUpdate = vi.fn();
Expand Down Expand Up @@ -71,6 +73,7 @@ describe('validators', () => {
contextName: 'context-field',
operator: operator,
value: '',
[constraintId]: 'constraint id',
};

const { result } = renderHook(() =>
Expand All @@ -94,6 +97,7 @@ describe('validators', () => {
contextName: 'context-field',
operator: operator,
value: '',
[constraintId]: 'constraint id',
};

const { result } = renderHook(() =>
Expand All @@ -117,6 +121,7 @@ describe('validators', () => {
contextName: 'context-field',
operator: operator,
value: '',
[constraintId]: 'constraint id',
};

const { result } = renderHook(() =>
Expand All @@ -140,6 +145,7 @@ describe('validators', () => {
contextName: 'context-field',
operator: operator,
values: [],
[constraintId]: 'constraint id',
};

const { result } = renderHook(() =>
Expand All @@ -162,6 +168,7 @@ describe('validators', () => {
contextName: 'context-field',
operator: operator,
values: ['a', 'b'],
[constraintId]: 'constraint id',
};

const { result } = renderHook(() =>
Expand Down Expand Up @@ -189,6 +196,7 @@ describe('legal values', () => {
contextName: definition.name,
operator: IN,
values: [],
[constraintId]: 'constraint id',
};

const { result } = renderHook(() =>
Expand All @@ -206,6 +214,7 @@ describe('legal values', () => {
contextName: definition.name,
operator: IN,
values: [],
[constraintId]: 'constraint id',
};

const { result } = renderHook(() =>
Expand All @@ -231,6 +240,7 @@ describe('legal values', () => {
contextName: 'field-with-no-legal-values',
operator: IN,
values: [],
[constraintId]: 'constraint id',
};

const { result } = renderHook(() =>
Expand All @@ -244,6 +254,7 @@ describe('legal values', () => {
contextName: definition.name,
operator: IN,
values: ['A', 'B'],
[constraintId]: 'constraint id',
};

const { result } = renderHook(() =>
Expand All @@ -260,6 +271,7 @@ describe('legal values', () => {
contextName: definition.name,
operator: NUM_EQ,
values: [],
[constraintId]: 'constraint id',
};

const { result } = renderHook(() =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { renderHook, act } from '@testing-library/react';
import type { IConstraint } from 'interfaces/strategy';
import { IN, STR_CONTAINS } from 'constants/operators';
import type { Operator } from 'constants/operators';
import { constraintId } from 'constants/constraintId.ts';

const createTestConstraint = (
contextName: string,
Expand All @@ -15,6 +16,7 @@ const createTestConstraint = (
contextName,
operator,
values,
[constraintId]: 'constraint id',
});

describe('areConstraintsEqual', () => {
Expand All @@ -24,13 +26,15 @@ describe('areConstraintsEqual', () => {
operator: IN,
values: ['user1', 'user2'],
inverted: false,
[constraintId]: 'constraint id',
};

const constraint2: IConstraint = {
contextName: 'userId',
operator: IN,
values: ['user1', 'user2'],
inverted: false,
[constraintId]: 'constraint id',
};

expect(areConstraintsEqual(constraint1, constraint2)).toBe(true);
Expand All @@ -41,12 +45,14 @@ describe('areConstraintsEqual', () => {
contextName: 'userId',
operator: IN,
values: ['user1', 'user2', 'user3'],
[constraintId]: 'constraint id',
};

const constraint2: IConstraint = {
contextName: 'userId',
operator: IN,
values: ['user2', 'user3', 'user1'],
[constraintId]: 'constraint id',
};

expect(areConstraintsEqual(constraint1, constraint2)).toBe(true);
Expand All @@ -57,12 +63,14 @@ describe('areConstraintsEqual', () => {
contextName: 'userId',
operator: IN,
values: ['user1', 'user2'],
[constraintId]: 'constraint id',
};

const constraint2: IConstraint = {
contextName: 'userId',
operator: IN,
values: ['user1', 'user3'],
[constraintId]: 'constraint id',
};

expect(areConstraintsEqual(constraint1, constraint2)).toBe(false);
Expand All @@ -73,12 +81,14 @@ describe('areConstraintsEqual', () => {
contextName: 'userId',
operator: IN,
values: ['user1'],
[constraintId]: 'constraint id',
};

const constraint2: IConstraint = {
contextName: 'userId',
operator: STR_CONTAINS,
values: ['user1'],
[constraintId]: 'constraint id',
};

expect(areConstraintsEqual(constraint1, constraint2)).toBe(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import {
} from '@server/types/permissions';
import { StrategyItem } from 'component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/StrategyItem';
import type { IFeatureStrategy } from 'interfaces/strategy';
import { constraintId } from 'constants/constraintId';
import { v4 as uuidv4 } from 'uuid';

interface ProjectEnvironmentDefaultStrategyProps {
environment: ProjectEnvironmentType;
Expand Down Expand Up @@ -55,7 +57,11 @@ export const ProjectEnvironmentDefaultStrategy = ({
return {
...baseDefaultStrategy,
disabled: false,
constraints: baseDefaultStrategy.constraints ?? [],
constraints:
baseDefaultStrategy.constraints?.map((constraint) => ({
...constraint,
[constraintId]: uuidv4(),
})) ?? [],
title: baseDefaultStrategy.title ?? '',
parameters: baseDefaultStrategy.parameters ?? {},
};
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/component/segments/SegmentForm.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { IConstraint, IConstraintWithId } from 'interfaces/strategy';
import type { IConstraint } from 'interfaces/strategy';
import { SegmentFormStepOne } from './SegmentFormStepOne.tsx';
import { SegmentFormStepTwo } from './SegmentFormStepTwo.tsx';
import type React from 'react';
Expand All @@ -14,7 +14,7 @@ interface ISegmentProps {
name: string;
description: string;
project?: string;
constraints: IConstraintWithId[];
constraints: IConstraint[];
setName: React.Dispatch<React.SetStateAction<string>>;
setDescription: React.Dispatch<React.SetStateAction<string>>;
setProject: React.Dispatch<React.SetStateAction<string | undefined>>;
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/component/segments/SegmentFormStepTwo.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
CREATE_SEGMENT,
UPDATE_PROJECT_SEGMENT,
} from 'component/providers/AccessProvider/permissions';
import type { IConstraintWithId } from 'interfaces/strategy.ts';
import type { IConstraint } from 'interfaces/strategy.ts';

const server = testServerSetup();

Expand All @@ -26,7 +26,7 @@ const setupRoutes = () => {

const defaultProps = {
project: undefined,
constraints: [] as IConstraintWithId[],
constraints: [] as IConstraint[],
setConstraints: vi.fn(),
setCurrentStep: vi.fn(),
mode: 'create' as const,
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/component/segments/SegmentFormStepTwo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
UPDATE_SEGMENT,
} from 'component/providers/AccessProvider/permissions';
import useUnleashContext from 'hooks/api/getters/useUnleashContext/useUnleashContext';
import type { IConstraint, IConstraintWithId } from 'interfaces/strategy';
import type { IConstraint } from 'interfaces/strategy';
import { useNavigate } from 'react-router-dom';
import { EditableConstraintsList } from 'component/common/NewConstraintAccordion/ConstraintsList/EditableConstraintsList';
import type { IEditableConstraintsListRef } from 'component/common/NewConstraintAccordion/ConstraintsList/EditableConstraintsList';
Expand All @@ -33,7 +33,7 @@ import { GO_BACK } from 'constants/navigate';

interface ISegmentFormPartTwoProps {
project?: string;
constraints: IConstraintWithId[];
constraints: IConstraint[];
setConstraints: React.Dispatch<React.SetStateAction<IConstraint[]>>;
setCurrentStep: React.Dispatch<React.SetStateAction<SegmentFormStep>>;
mode: SegmentFormMode;
Expand Down
7 changes: 2 additions & 5 deletions frontend/src/component/segments/hooks/useSegmentForm.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import type { IConstraint, IConstraintWithId } from 'interfaces/strategy';
import type { IConstraint } from 'interfaces/strategy';
import { useEffect, useState } from 'react';
import { useSegmentValidation } from 'hooks/api/getters/useSegmentValidation/useSegmentValidation';
import { v4 as uuidv4 } from 'uuid';
import { constraintId } from 'constants/constraintId';

export const useSegmentForm = (
initialName = '',
Expand All @@ -14,10 +12,9 @@ export const useSegmentForm = (
const [description, setDescription] = useState(initialDescription);
const [project, setProject] = useState<string | undefined>(initialProject);
const initialConstraintsWithId = initialConstraints.map((constraint) => ({
[constraintId]: uuidv4(),
...constraint,
}));
const [constraints, setConstraints] = useState<IConstraintWithId[]>(
const [constraints, setConstraints] = useState<IConstraint[]>(
initialConstraintsWithId,
);
const [errors, setErrors] = useState({});
Expand Down
Loading
Loading