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

[Security Solution] Add rule snooze settings on the rule details page #155407

Merged

Conversation

maximpn
Copy link
Contributor

@maximpn maximpn commented Apr 20, 2023

Addresses: #155406

Summary

This PR adds rule snoozing support on the Rule Details page.

Screen.Recording.2023-04-20.at.15.49.31.mov

Checklist

@maximpn maximpn added Team:Detections and Resp Security Detection Response Team Team: SecuritySolution Security Solutions Team working on SIEM, Endpoint, Timeline, Resolver, etc. release_note:feature Makes this part of the condensed release notes Team:Detection Rule Management Security Detection Rule Management Team Feature:Rule Creation Security Solution Detection Rule Creation workflow Feature:Rule Details Security Solution Detection Rule Details page v8.8.0 labels Apr 20, 2023
@maximpn maximpn self-assigned this Apr 20, 2023
@maximpn maximpn marked this pull request as ready for review April 20, 2023 15:14
@maximpn maximpn requested review from a team as code owners April 20, 2023 15:14
@maximpn maximpn requested a review from xcrzx April 20, 2023 15:14
@elasticmachine
Copy link
Contributor

Pinging @elastic/security-detections-response (Team:Detections and Resp)

@elasticmachine
Copy link
Contributor

Pinging @elastic/security-solution (Team: SecuritySolution)

@banderror banderror removed the Feature:Rule Creation Security Solution Detection Rule Creation workflow label Apr 20, 2023
Copy link
Contributor

@xcrzx xcrzx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, @maximpn, for working on this feature! I have tested the PR locally, and it works as expected. Overall, the implementation looks good. I have left a few comments for further improvements; please let me know if you want to discuss them over Zoom.

Comment on lines +90 to +92
jest.mock('./components/rule_details_snooze_settings', () => ({
RuleDetailsSnoozeSettings: () => <></>,
}));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, it's the 14th mock added to this test file 😅.
Honestly, it might be better just to delete this messy test altogether.

Relying heavily on mocks in a single test isn't great for several reasons:

  1. Bad readability: Too many mocks make reading and understanding the test difficult. In this case, there are ~170 LoC mock definitions, roughly half of the test file.
  2. Fragility: Mocks can cause tests to break easily when the code changes. This is because mocks assume certain things about how the system works, and if those things change, the test will fail even if everything else is still working fine.
  3. Violation of encapsulation: Mocks usually rely on implementation detail. This makes introducing code changes without breaking tests hard, slowing development.
  4. Fake test scenarios: When using too many mocks, you basically test mocks instead of actual code. This can cause tests to pass or fail regardless of the existing system behavior.

Copy link
Contributor Author

@maximpn maximpn Apr 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I totally agree with the comment though I'd like to abstain from any other changes in the test file in this PR. It more or less outside of scope here so I'd rather address test file refactoring in a subsequent PR if you don't mind.

Comment on lines 43 to 46
/**
* Rule SO's id (not ruleId) to snooze settings map,
*/
data: Record<string, RuleSnoozeSettings>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure how "Rule SO's id" is related to this structure.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment is fixed, it should reflect the data field's essence better.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The layout is a bit off on smaller screens:

Screenshot 2023-04-21 at 12 05 08

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately this problem takes more time to be fixed. I've created a task to address this bug after feature freeze.

Comment on lines +112 to +134
const {
state: { rulesSnoozeSettings },
} = useRulesTableContext();

return useMemo(
() => ({
field: 'snooze',
name: i18n.COLUMN_SNOOZE,
render: (_, rule: Rule) => <RuleSnoozeBadge id={rule.id} />,
render: (_, rule: Rule) => {
const snoozeSettings = rulesSnoozeSettings.data[rule.id];
const { isFetching, isError } = rulesSnoozeSettings;

return (
<RuleSnoozeBadge
snoozeSettings={snoozeSettings}
error={
isError || (!snoozeSettings && !isFetching)
? rulesTableI18n.UNABLE_TO_FETCH_RULES_SNOOZE_SETTINGS
: undefined
}
/>
);
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to abstract the settings and error retrieval logic into a reusable hook. Something like:

const { snoozingSettings, error } = useRuleSnoozingSettings(rule.id)

Moreover, this logic is duplicated in the RuleDetailsSnoozeSettings component. It would be better to encapsulate it inside the RuleSnoozeBadge component instead of handling the data access part outside. The component might try to get the rule settings from the table context if it's available and fall back to data fetching in other cases.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I'm gonna address this in the next PR for adding support of rule snooze on the rule editing page.

@@ -40,8 +40,18 @@ import { RuleSource } from './rules_table_saved_state';
import { useRulesTableSavedState } from './use_rules_table_saved_state';

interface RulesSnoozeSettings {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not related to this PR directly.

I was thinking about the snooze state inside the table context, and it seems a bit alien there. If I understood correctly, its purpose is to batch outgoing HTTP requests, i.e., send a single rule snooze request instead of 1 x N table rows. So I think it would be better to create an abstraction just for that. It could be a data hook that doesn't trigger a request immediately but waits some time and accumulates request params if other similar hooks are present on the page. Something similar to the GraphQL dataloader batching functionality but adapted for usage with react query.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, I also had some similar ideas already. My main concern is to make it simple, maintainable and reusable as creating such functionality only for one feature is time consuming. I think we can take the thoughts into account and analyze the possibilities when the snoozing epic is done.

@kibana-ci
Copy link
Collaborator

💛 Build succeeded, but was flaky

Failed CI Steps

Test Failures

  • [job] [logs] Security Solution Tests #1 / Detection rules, bulk edit Timeline templates Apply timeline template to custom rules

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
securitySolution 3831 3832 +1

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
securitySolution 9.1MB 9.1MB +808.0B
Unknown metric groups

ESLint disabled line counts

id before after diff
securitySolution 394 397 +3

Total ESLint disabled count

id before after diff
securitySolution 474 477 +3

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

cc @maximpn

Copy link
Contributor

@xcrzx xcrzx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

@maximpn maximpn merged commit 84e6e36 into elastic:main Apr 24, 2023
@kibanamachine kibanamachine added the backport:skip This commit does not require backporting label Apr 24, 2023
@maximpn maximpn deleted the support-snooze-settings-on-rule-details-page branch April 24, 2023 09:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport:skip This commit does not require backporting Feature:Rule Details Security Solution Detection Rule Details page release_note:feature Makes this part of the condensed release notes Team:Detection Rule Management Security Detection Rule Management Team Team:Detections and Resp Security Detection Response Team Team: SecuritySolution Security Solutions Team working on SIEM, Endpoint, Timeline, Resolver, etc. v8.8.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants