mirror of
https://github.com/Unleash/unleash.git
synced 2025-07-21 13:47:39 +02:00
271 lines
8.7 KiB
TypeScript
271 lines
8.7 KiB
TypeScript
import {
|
|
useRecentlyUsedConstraints,
|
|
areConstraintsEqual,
|
|
} from './useRecentlyUsedConstraints';
|
|
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';
|
|
|
|
const createTestConstraint = (
|
|
contextName: string,
|
|
operator: Operator = IN,
|
|
values = [contextName],
|
|
): IConstraint => ({
|
|
contextName,
|
|
operator,
|
|
values,
|
|
});
|
|
|
|
describe('areConstraintsEqual', () => {
|
|
it('should return true for constraints with identical content', () => {
|
|
const constraint1: IConstraint = {
|
|
contextName: 'userId',
|
|
operator: IN,
|
|
values: ['user1', 'user2'],
|
|
inverted: false,
|
|
};
|
|
|
|
const constraint2: IConstraint = {
|
|
contextName: 'userId',
|
|
operator: IN,
|
|
values: ['user1', 'user2'],
|
|
inverted: false,
|
|
};
|
|
|
|
expect(areConstraintsEqual(constraint1, constraint2)).toBe(true);
|
|
});
|
|
|
|
it('should return true for constraints with same values in different order', () => {
|
|
const constraint1: IConstraint = {
|
|
contextName: 'userId',
|
|
operator: IN,
|
|
values: ['user1', 'user2', 'user3'],
|
|
};
|
|
|
|
const constraint2: IConstraint = {
|
|
contextName: 'userId',
|
|
operator: IN,
|
|
values: ['user2', 'user3', 'user1'],
|
|
};
|
|
|
|
expect(areConstraintsEqual(constraint1, constraint2)).toBe(true);
|
|
});
|
|
|
|
it('should return false for constraints with different content', () => {
|
|
const constraint1: IConstraint = {
|
|
contextName: 'userId',
|
|
operator: IN,
|
|
values: ['user1', 'user2'],
|
|
};
|
|
|
|
const constraint2: IConstraint = {
|
|
contextName: 'userId',
|
|
operator: IN,
|
|
values: ['user1', 'user3'],
|
|
};
|
|
|
|
expect(areConstraintsEqual(constraint1, constraint2)).toBe(false);
|
|
});
|
|
|
|
it('should return false for constraints with different operators', () => {
|
|
const constraint1: IConstraint = {
|
|
contextName: 'userId',
|
|
operator: IN,
|
|
values: ['user1'],
|
|
};
|
|
|
|
const constraint2: IConstraint = {
|
|
contextName: 'userId',
|
|
operator: STR_CONTAINS,
|
|
values: ['user1'],
|
|
};
|
|
|
|
expect(areConstraintsEqual(constraint1, constraint2)).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('useRecentlyUsedConstraints', () => {
|
|
beforeEach(() => {
|
|
window.localStorage.clear();
|
|
});
|
|
|
|
it('should initialize with empty array when no items in localStorage', () => {
|
|
const { result } = renderHook(() => useRecentlyUsedConstraints());
|
|
|
|
expect(result.current.items).toEqual([]);
|
|
});
|
|
|
|
it('should initialize with initial items if provided', () => {
|
|
const initialItems = [createTestConstraint('userId')];
|
|
const { result } = renderHook(() =>
|
|
useRecentlyUsedConstraints(initialItems),
|
|
);
|
|
|
|
expect(result.current.items).toEqual(initialItems);
|
|
});
|
|
|
|
it('should add new items to the beginning of the list', () => {
|
|
const { result } = renderHook(() => useRecentlyUsedConstraints());
|
|
|
|
act(() => {
|
|
result.current.addItem(createTestConstraint('userId'));
|
|
});
|
|
expect(result.current.items[0].contextName).toBe('userId');
|
|
|
|
act(() => {
|
|
result.current.addItem(createTestConstraint('email'));
|
|
});
|
|
expect(result.current.items[0].contextName).toBe('email');
|
|
expect(result.current.items[1].contextName).toBe('userId');
|
|
});
|
|
|
|
it('should handle array of constraints when adding items', () => {
|
|
const { result } = renderHook(() => useRecentlyUsedConstraints());
|
|
|
|
const constraints = [
|
|
createTestConstraint('userId'),
|
|
createTestConstraint('email'),
|
|
createTestConstraint('appName'),
|
|
];
|
|
|
|
act(() => {
|
|
result.current.addItem(constraints);
|
|
});
|
|
|
|
expect(result.current.items.length).toBe(3);
|
|
expect(result.current.items[0].contextName).toBe('appName');
|
|
expect(result.current.items[1].contextName).toBe('email');
|
|
expect(result.current.items[2].contextName).toBe('userId');
|
|
});
|
|
|
|
it('should limit stored items to maximum of 3', () => {
|
|
const { result } = renderHook(() => useRecentlyUsedConstraints());
|
|
|
|
act(() => {
|
|
result.current.addItem(createTestConstraint('userId'));
|
|
result.current.addItem(createTestConstraint('email'));
|
|
result.current.addItem(createTestConstraint('countryId'));
|
|
result.current.addItem(createTestConstraint('appName'));
|
|
});
|
|
|
|
expect(result.current.items.length).toBe(3);
|
|
expect(result.current.items[0].contextName).toBe('appName');
|
|
expect(result.current.items[1].contextName).toBe('countryId');
|
|
expect(result.current.items[2].contextName).toBe('email');
|
|
});
|
|
|
|
it('should also limit to max of 3 items when adding an array of constraints', () => {
|
|
const { result } = renderHook(() => useRecentlyUsedConstraints());
|
|
|
|
const constraints = [
|
|
createTestConstraint('userId'),
|
|
createTestConstraint('email'),
|
|
createTestConstraint('appName'),
|
|
createTestConstraint('countryId'),
|
|
];
|
|
|
|
act(() => {
|
|
result.current.addItem(constraints);
|
|
});
|
|
|
|
expect(result.current.items.length).toBe(3);
|
|
});
|
|
|
|
it('should not add duplicate constraints', () => {
|
|
const { result } = renderHook(() => useRecentlyUsedConstraints());
|
|
|
|
const constraint1 = createTestConstraint('userId', IN, [
|
|
'user1',
|
|
'user2',
|
|
]);
|
|
const constraint2 = createTestConstraint('email');
|
|
|
|
act(() => {
|
|
result.current.addItem(constraint1);
|
|
result.current.addItem(constraint2);
|
|
});
|
|
expect(result.current.items.length).toBe(2);
|
|
|
|
const duplicateConstraint = createTestConstraint('userId', IN, [
|
|
'user1',
|
|
'user2',
|
|
]);
|
|
act(() => {
|
|
result.current.addItem(duplicateConstraint);
|
|
});
|
|
|
|
expect(result.current.items.length).toBe(2);
|
|
expect(result.current.items[0].contextName).toBe('userId');
|
|
expect(result.current.items[1].contextName).toBe('email');
|
|
});
|
|
|
|
it('should not add duplicate constraints with values in different order', () => {
|
|
const { result } = renderHook(() => useRecentlyUsedConstraints());
|
|
|
|
const constraint1 = {
|
|
contextName: 'userId',
|
|
operator: IN,
|
|
values: ['user1', 'user2', 'user3'],
|
|
} as IConstraint;
|
|
|
|
act(() => {
|
|
result.current.addItem(constraint1);
|
|
});
|
|
expect(result.current.items.length).toBe(1);
|
|
|
|
// Same constraint but with values in different order
|
|
const sameConstraintDifferentOrder = {
|
|
contextName: 'userId',
|
|
operator: IN,
|
|
values: ['user3', 'user1', 'user2'],
|
|
} as IConstraint;
|
|
|
|
act(() => {
|
|
result.current.addItem(sameConstraintDifferentOrder);
|
|
});
|
|
|
|
// Should not add a duplicate, just move it to the top
|
|
expect(result.current.items.length).toBe(1);
|
|
expect(result.current.items[0].contextName).toBe('userId');
|
|
// The values array in the stored item should be the one from the most recently added item
|
|
expect(result.current.items[0].values).toEqual([
|
|
'user3',
|
|
'user1',
|
|
'user2',
|
|
]);
|
|
});
|
|
|
|
it('should handle duplicates in an array of constraints', () => {
|
|
const { result } = renderHook(() => useRecentlyUsedConstraints());
|
|
|
|
const constraints = [
|
|
createTestConstraint('userId', IN, ['user1', 'user2']),
|
|
createTestConstraint('email'),
|
|
createTestConstraint('userId', IN, ['user1', 'user2']), // Duplicate
|
|
];
|
|
|
|
act(() => {
|
|
result.current.addItem(constraints);
|
|
});
|
|
|
|
expect(result.current.items.length).toBe(2);
|
|
expect(result.current.items[0].contextName).toBe('userId');
|
|
expect(result.current.items[1].contextName).toBe('email');
|
|
});
|
|
|
|
it('should persist items to localStorage', () => {
|
|
const { result } = renderHook(() => useRecentlyUsedConstraints());
|
|
|
|
act(() => {
|
|
result.current.addItem(createTestConstraint('userId'));
|
|
});
|
|
|
|
const { result: newResult } = renderHook(() =>
|
|
useRecentlyUsedConstraints(),
|
|
);
|
|
|
|
expect(newResult.current.items[0].contextName).toBe('userId');
|
|
});
|
|
});
|