Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[8.x] [Security Solution][Notes] - switch the securitySolutionNotesEnables feature flag to securitySolutionNotesDisabled (#196778) #198206

Merged
merged 1 commit into from
Oct 29, 2024
Merged
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 @@ -94,9 +94,9 @@ export const allowedExperimentalValues = Object.freeze({
endpointManagementSpaceAwarenessEnabled: false,

/**
* Enables new notes
* Disables new notes
*/
securitySolutionNotesEnabled: false,
securitySolutionNotesDisabled: false,

/**
* Disables entity and alert previews
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ const RowActionComponent = ({
[columnHeaders, timelineNonEcsData]
);

const securitySolutionNotesEnabled = useIsExperimentalFeatureEnabled(
'securitySolutionNotesEnabled'
const securitySolutionNotesDisabled = useIsExperimentalFeatureEnabled(
'securitySolutionNotesDisabled'
);

const handleOnEventDetailPanelOpened = useCallback(() => {
Expand Down Expand Up @@ -175,12 +175,12 @@ const RowActionComponent = ({
showCheckboxes={showCheckboxes}
tabType={tabType}
timelineId={tableId}
toggleShowNotes={securitySolutionNotesEnabled ? toggleShowNotes : undefined}
toggleShowNotes={securitySolutionNotesDisabled ? undefined : toggleShowNotes}
width={width}
setEventsLoading={setEventsLoading}
setEventsDeleted={setEventsDeleted}
refetch={refetch}
showNotes={securitySolutionNotesEnabled ? true : false}
showNotes={!securitySolutionNotesDisabled}
/>
)}
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ import { useGlobalFullScreen } from '../../containers/use_full_screen';
import { licenseService } from '../../hooks/use_license';
import { mockHistory } from '../../mock/router';
import { DEFAULT_EVENTS_STACK_BY_VALUE } from './histogram_configurations';
import { useIsExperimentalFeatureEnabled } from '../../hooks/use_experimental_features';

jest.mock('../../hooks/use_experimental_features');

const mockGetDefaultControlColumn = jest.fn();
jest.mock('../../../timelines/components/timeline/body/control_columns', () => ({
Expand Down Expand Up @@ -95,6 +98,7 @@ describe('EventsQueryTabBody', () => {
};

beforeEach(() => {
(useIsExperimentalFeatureEnabled as jest.Mock).mockReturnValue(false);
jest.clearAllMocks();
});

Expand All @@ -106,7 +110,7 @@ describe('EventsQueryTabBody', () => {
);

expect(queryByText('MockedStatefulEventsViewer')).toBeInTheDocument();
expect(mockGetDefaultControlColumn).toHaveBeenCalledWith(4);
expect(mockGetDefaultControlColumn).toHaveBeenCalledWith(5);
});

it('renders the matrix histogram when globalFullScreen is false', () => {
Expand Down Expand Up @@ -186,7 +190,19 @@ describe('EventsQueryTabBody', () => {
expect(spy).toHaveBeenCalled();
});

it('only have 4 columns on Action bar for non-Enterprise user', () => {
it('should have 5 columns on Action bar for non-Enterprise user', () => {
render(
<TestProviders>
<EventsQueryTabBody {...commonProps} />
</TestProviders>
);

expect(mockGetDefaultControlColumn).toHaveBeenCalledWith(5);
});

it('should have 4 columns on Action bar for non-Enterprise user and securitySolutionNotesDisabled is true', () => {
(useIsExperimentalFeatureEnabled as jest.Mock).mockReturnValue(true);

render(
<TestProviders>
<EventsQueryTabBody {...commonProps} />
Expand All @@ -196,10 +212,23 @@ describe('EventsQueryTabBody', () => {
expect(mockGetDefaultControlColumn).toHaveBeenCalledWith(4);
});

it('shows 5 columns on Action bar for Enterprise user', () => {
it('should 6 columns on Action bar for Enterprise user', () => {
const licenseServiceMock = licenseService as jest.Mocked<typeof licenseService>;
licenseServiceMock.isEnterprise.mockReturnValue(true);

render(
<TestProviders>
<EventsQueryTabBody {...commonProps} />
</TestProviders>
);

expect(mockGetDefaultControlColumn).toHaveBeenCalledWith(6);
});

it('should 6 columns on Action bar for Enterprise user and securitySolutionNotesDisabled is true', () => {
const licenseServiceMock = licenseService as jest.Mocked<typeof licenseService>;
licenseServiceMock.isEnterprise.mockReturnValue(true);
(useIsExperimentalFeatureEnabled as jest.Mock).mockReturnValue(true);

render(
<TestProviders>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,10 @@ const EventsQueryTabBodyComponent: React.FC<EventsQueryTabBodyComponentProps> =
const [defaultNumberFormat] = useUiSetting$<string>(DEFAULT_NUMBER_FORMAT);
const isEnterprisePlus = useLicense().isEnterprise();
let ACTION_BUTTON_COUNT = isEnterprisePlus ? 6 : 5;
const securitySolutionNotesEnabled = useIsExperimentalFeatureEnabled(
'securitySolutionNotesEnabled'
const securitySolutionNotesDisabled = useIsExperimentalFeatureEnabled(
'securitySolutionNotesDisabled'
);
if (!securitySolutionNotesEnabled) {
if (securitySolutionNotesDisabled) {
ACTION_BUTTON_COUNT--;
}
const leadingControlColumns = useMemo(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,8 +255,8 @@ const ActionsComponent: React.FC<ActionProps> = ({
onEventDetailsPanelOpened();
}, [activeStep, incrementStep, isTourAnchor, isTourShown, onEventDetailsPanelOpened]);

const securitySolutionNotesEnabled = useIsExperimentalFeatureEnabled(
'securitySolutionNotesEnabled'
const securitySolutionNotesDisabled = useIsExperimentalFeatureEnabled(
'securitySolutionNotesDisabled'
);

/* only applicable for new event based notes */
Expand All @@ -270,7 +270,7 @@ const ActionsComponent: React.FC<ActionProps> = ({

/* note ids associated with the document AND attached to the current timeline, used for pinning */
const timelineNoteIds = useMemo(() => {
if (securitySolutionNotesEnabled) {
if (!securitySolutionNotesDisabled) {
// if timeline is unsaved, there is no notes associated to timeline yet
return savedObjectId ? documentBasedNotesInTimeline.map((note) => note.noteId) : [];
}
Expand All @@ -280,13 +280,13 @@ const ActionsComponent: React.FC<ActionProps> = ({
eventId,
documentBasedNotesInTimeline,
savedObjectId,
securitySolutionNotesEnabled,
securitySolutionNotesDisabled,
]);

/* note count of the document */
const notesCount = useMemo(
() => (securitySolutionNotesEnabled ? documentBasedNotes.length : timelineNoteIds.length),
[documentBasedNotes, timelineNoteIds, securitySolutionNotesEnabled]
() => (securitySolutionNotesDisabled ? timelineNoteIds.length : documentBasedNotes.length),
[documentBasedNotes, timelineNoteIds, securitySolutionNotesDisabled]
);

// we hide the analyzer icon if the data is not available for the resolver
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ export const getUseActionColumnHook =
}

// we only want to show the note icon if the new notes system feature flag is enabled
const securitySolutionNotesEnabled = useIsExperimentalFeatureEnabled(
'securitySolutionNotesEnabled'
const securitySolutionNotesDisabled = useIsExperimentalFeatureEnabled(
'securitySolutionNotesDisabled'
);
if (!securitySolutionNotesEnabled) {
if (securitySolutionNotesDisabled) {
ACTION_BUTTON_COUNT--;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ export const LeftPanel: FC<Partial<DocumentDetailsProps>> = memo(({ path }) => {
const { openLeftPanel } = useExpandableFlyoutApi();
const { eventId, indexName, scopeId, getFieldsData, isPreview } = useDocumentDetailsContext();
const eventKind = getField(getFieldsData('event.kind'));
const securitySolutionNotesEnabled = useIsExperimentalFeatureEnabled(
'securitySolutionNotesEnabled'
const securitySolutionNotesDisabled = useIsExperimentalFeatureEnabled(
'securitySolutionNotesDisabled'
);

const [visualizationInFlyoutEnabled] = useUiSetting$<boolean>(
Expand All @@ -49,14 +49,14 @@ export const LeftPanel: FC<Partial<DocumentDetailsProps>> = memo(({ path }) => {
eventKind === EventKind.signal
? [tabs.insightsTab, tabs.investigationTab, tabs.responseTab]
: [tabs.insightsTab];
if (securitySolutionNotesEnabled && !isPreview) {
if (!securitySolutionNotesDisabled && !isPreview) {
tabList.push(tabs.notesTab);
}
if (visualizationInFlyoutEnabled && !isPreview) {
return [tabs.visualizeTab, ...tabList];
}
return tabList;
}, [eventKind, isPreview, securitySolutionNotesEnabled, visualizationInFlyoutEnabled]);
}, [eventKind, isPreview, securitySolutionNotesDisabled, visualizationInFlyoutEnabled]);

const selectedTabId = useMemo(() => {
const defaultTab = tabsDisplayed[0].id;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ describe('<AlertHeaderTitle />', () => {
});

it('should render notes section if experimental flag is enabled', () => {
(useIsExperimentalFeatureEnabled as jest.Mock).mockReturnValue(true);
(useIsExperimentalFeatureEnabled as jest.Mock).mockReturnValue(false);

const { getByTestId } = renderHeader(mockContextValue);
expect(getByTestId(NOTES_TITLE_TEST_ID)).toBeInTheDocument();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ export const AlertHeaderTitle = memo(() => {
refetchFlyoutData,
getFieldsData,
} = useDocumentDetailsContext();
const securitySolutionNotesEnabled = useIsExperimentalFeatureEnabled(
'securitySolutionNotesEnabled'
const securitySolutionNotesDisabled = useIsExperimentalFeatureEnabled(
'securitySolutionNotesDisabled'
);

const { isAlert, ruleName, timestamp, ruleId } = useBasicDataFromDetailsData(
Expand Down Expand Up @@ -98,7 +98,30 @@ export const AlertHeaderTitle = memo(() => {
/>
)}
<EuiSpacer size="m" />
{securitySolutionNotesEnabled ? (
{securitySolutionNotesDisabled ? (
<EuiFlexGroup
direction="row"
gutterSize="s"
responsive={false}
wrap
data-test-subj={ALERT_SUMMARY_PANEL_TEST_ID}
>
<EuiFlexItem>
<DocumentStatus />
</EuiFlexItem>
<EuiFlexItem>
<RiskScore />
</EuiFlexItem>
<EuiFlexItem>
<Assignees
eventId={eventId}
assignedUserIds={alertAssignees}
onAssigneesUpdated={onAssigneesUpdated}
isPreview={isPreview}
/>
</EuiFlexItem>
</EuiFlexGroup>
) : (
<EuiFlexGroup
direction="row"
gutterSize="s"
Expand Down Expand Up @@ -132,29 +155,6 @@ export const AlertHeaderTitle = memo(() => {
</EuiFlexGroup>
</EuiFlexItem>
</EuiFlexGroup>
) : (
<EuiFlexGroup
direction="row"
gutterSize="s"
responsive={false}
wrap
data-test-subj={ALERT_SUMMARY_PANEL_TEST_ID}
>
<EuiFlexItem>
<DocumentStatus />
</EuiFlexItem>
<EuiFlexItem>
<RiskScore />
</EuiFlexItem>
<EuiFlexItem>
<Assignees
eventId={eventId}
assignedUserIds={alertAssignees}
onAssigneesUpdated={onAssigneesUpdated}
isPreview={isPreview}
/>
</EuiFlexItem>
</EuiFlexGroup>
)}
</>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ export const links: LinkItem = {
path: NOTES_PATH,
skipUrlState: true,
hideTimeline: true,
experimentalKey: 'securitySolutionNotesEnabled',
hideWhenExperimentalKey: 'securitySolutionNotesDisabled',
},
],
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ const NotesTelemetry = () => (
);

export const ManagementContainer = memo(() => {
const securitySolutionNotesEnabled = useIsExperimentalFeatureEnabled(
'securitySolutionNotesEnabled'
const securitySolutionNotesDisabled = useIsExperimentalFeatureEnabled(
'securitySolutionNotesDisabled'
);

const {
Expand Down Expand Up @@ -162,7 +162,7 @@ export const ManagementContainer = memo(() => {
hasPrivilege={canReadActionsLogManagement}
/>

{securitySolutionNotesEnabled && (
{!securitySolutionNotesDisabled && (
<Route path={MANAGEMENT_ROUTING_NOTES_PATH} component={NotesTelemetry} />
)}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,24 +45,24 @@ describe('useFetchNotes', () => {
expect(typeof result.current.onLoad).toBe('function');
});

it('should not dispatch action when securitySolutionNotesEnabled is false', () => {
mockedUseIsExperimentalFeatureEnabled.mockReturnValue(false);
it('should not dispatch action when securitySolutionNotesDisabled is true', () => {
mockedUseIsExperimentalFeatureEnabled.mockReturnValue(true);
const { result } = renderHook(() => useFetchNotes());

result.current.onLoad([{ _id: '1' }]);
expect(mockDispatch).not.toHaveBeenCalled();
});

it('should not dispatch action when events array is empty', () => {
mockedUseIsExperimentalFeatureEnabled.mockReturnValue(true);
mockedUseIsExperimentalFeatureEnabled.mockReturnValue(false);
const { result } = renderHook(() => useFetchNotes());

result.current.onLoad([]);
expect(mockDispatch).not.toHaveBeenCalled();
});

it('should dispatch fetchNotesByDocumentIds with correct ids when conditions are met', () => {
mockedUseIsExperimentalFeatureEnabled.mockReturnValue(true);
mockedUseIsExperimentalFeatureEnabled.mockReturnValue(false);
const { result } = renderHook(() => useFetchNotes());

const events = [{ _id: '1' }, { _id: '2' }, { _id: '3' }];
Expand All @@ -74,7 +74,7 @@ describe('useFetchNotes', () => {
});

it('should memoize onLoad function', () => {
mockedUseIsExperimentalFeatureEnabled.mockReturnValue(true);
mockedUseIsExperimentalFeatureEnabled.mockReturnValue(false);
const { result, rerender } = renderHook(() => useFetchNotes());

const firstOnLoad = result.current.onLoad;
Expand All @@ -84,7 +84,7 @@ describe('useFetchNotes', () => {
expect(firstOnLoad).toBe(secondOnLoad);
});

it('should update onLoad when securitySolutionNotesEnabled changes', () => {
it('should update onLoad when securitySolutionNotesDisabled changes', () => {
mockedUseIsExperimentalFeatureEnabled.mockReturnValue(true);
const { result, rerender } = renderHook(() => useFetchNotes());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,19 @@ export interface UseFetchNotesResult {
*/
export const useFetchNotes = (): UseFetchNotesResult => {
const dispatch = useDispatch();
const securitySolutionNotesEnabled = useIsExperimentalFeatureEnabled(
'securitySolutionNotesEnabled'
const securitySolutionNotesDisabled = useIsExperimentalFeatureEnabled(
'securitySolutionNotesDisabled'
);
const onLoad = useCallback(
(events: Array<Partial<{ _id: string }>>) => {
if (!securitySolutionNotesEnabled || events.length === 0) return;
if (securitySolutionNotesDisabled || events.length === 0) return;

const eventIds: string[] = events
.map((event) => event._id)
.filter((id) => id != null) as string[];
dispatch(fetchNotesByDocumentIds({ documentIds: eventIds }));
},
[dispatch, securitySolutionNotesEnabled]
[dispatch, securitySolutionNotesDisabled]
);

return { onLoad };
Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/security_solution/public/notes/links.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@ export const links: LinkItem = {
}),
],
links: [],
experimentalKey: 'securitySolutionNotesEnabled',
hideWhenExperimentalKey: 'securitySolutionNotesDisabled',
};
Loading