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] JSON diffs test coverage #176770

Merged
merged 14 commits into from
Feb 19, 2024

Conversation

nikitaindik
Copy link
Contributor

@nikitaindik nikitaindik commented Feb 12, 2024

Resolves: #166163

Flaky test runner runs: 1, 2, 3, 4

Summary

This PR adds tests in accordance with the test plan that was merged earlier.

@nikitaindik nikitaindik force-pushed the json-diffs-test-coverage branch 3 times, most recently from 20a4463 to 0ae76c5 Compare February 15, 2024 02:43
@nikitaindik nikitaindik self-assigned this Feb 15, 2024
@nikitaindik nikitaindik added v8.13.0 v8.12.2 release_note:skip Skip the PR/issue when compiling release notes test-coverage issues & PRs for improving code test coverage Team:Detections and Resp Security Detection Response Team Team: SecuritySolution Security Solutions Team working on SIEM, Endpoint, Timeline, Resolver, etc. Team:Detection Rule Management Security Detection Rule Management Team Feature:Prebuilt Detection Rules Security Solution Prebuilt Detection Rules labels Feb 15, 2024
@nikitaindik nikitaindik marked this pull request as ready for review February 15, 2024 02:52
@nikitaindik nikitaindik requested a review from a team as a code owner February 15, 2024 02:52
@elasticmachine
Copy link
Contributor

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

@elasticmachine
Copy link
Contributor

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

@elasticmachine
Copy link
Contributor

Pinging @elastic/security-detection-rule-management (Team:Detection Rule Management)

Copy link
Contributor

@maximpn maximpn left a comment

Choose a reason for hiding this comment

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

@nikitaindik thank you for covering JSON diffs component by test from the test plan 👍

I haven't found a Properties should be sorted alphabetically scenario. Is it missed or it's a part of some other scenario?

My main concern is unit tests overcomplicated by matchInOrder. If I'm not missing anything it should be possible to assert Diff's component textContent and avoid hardcoded colors in the test or even completely omit it.

* otherwise `false`.
* Utilizes Lodash's `escapeRegExp` to handle special characters in the `strings` array.
*/
const matchInOrder =
Copy link
Contributor

Choose a reason for hiding this comment

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

Have you considered using Diff component's textContent instead?

I'm afraid this helper will make the test logic harder but it still doesn't protect again sensitivity to changes. Looking at the Diff's textContent below it's clear we should be able to implement many testing scenarios.

{{ "author": [ "author": [ "Alice", "Alice",- "Bob", "Charlie" "Charlie" ], ], "description": "some desc", "description": "some desc",Expand 15 unchanged lines ], ], "interval": "5m", "interval": "5m", "language": "kuery", "language": "kuery",+ "license": "GPLv3", "max_signals": 100, "max_signals": 100, "name": "Test rule", "name": "Test rule", "note": "", "note": "",Expand 19 unchanged lines ], ], "to": "now", "to": "now", "type": "query", "type": "query",- "version": 1+ "version": 2}}

For example normalizing it by removing extra spaces will make it simple to implement a test which verifies there is - "version": 1+ "version": 2. Of course it can break as well

We also shouldn't retest react-diff-view. It's enough to make sure the content is conceptually the same but how may components/tags and etc used isn't so important and will make the tests fragile.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Refactored this part in a follow-up commit

.should('not.exist');
});

it('Dynamic properties should not be included in preview', () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

This test only checks for execution_summary. What about the other fields specified in the test plan like revision and updated_at?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

These are in the React Testing Library test called "Technical properties should not be included in preview". I separated "dynamic" from "technical" because I wanted to test the "dynamic" ones in a more realistic way with a Cypress E2E test.

};

render(<RuleDiffTab oldRule={oldRule} newRule={newRule} />);
['revision', 'created_at', 'created_by', 'updated_at', 'updated_by'].forEach((property) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

it.each() is intended to pass different test data or params. It allows to display modify the test name to something like should not include "revision" in preview to make it clear what fields are checked.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Addressed in a follow-up commit

Comment on lines 1102 to 1108
cy.get('@currentRuleValue').then(($currentRuleValue) => {
const currentRuleLeftOffset = $currentRuleValue.offset()?.left || 0;
cy.get('@updateVersionValue').then(($updateVersionValue) => {
const updateVersionLeftOffset = $updateVersionValue.offset()?.left || 0;
expect(currentRuleLeftOffset).to.be.lessThan(updateVersionLeftOffset);
});
});
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here, but for the Diff library. I think this is a level of detail greater than we should have for e2e tests as smoke tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed. Removed.

Comment on lines 59 to 62
const removedBackgroundColor = 'rgb(255, 235, 233)';
const removedAccentColor = 'rgba(255, 129, 130, 0.4)';
const addedBackgroundColor = 'rgb(230, 255, 236)';
const addedAccentColor = 'rgb(171, 242, 188)';
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it possible to make these importable from their implementation file? Do these constants already exist?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Addressed in a follow-up commit

*
* The Matcher function itself has the following signature:
* @param {string} content - The content string to be checked. Not directly used in the current implementation
* but is required for the matcher's signature.
Copy link
Contributor

Choose a reason for hiding this comment

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

If I understand correctly, content needs to be passed here cause we need to return a function that is passed either to getByText and queryAllByText, and both those function require that signature.

Took me a bit to understand, maybe add this additional detail in this comment?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're right, it's too complicated. So I refactored a bit and removed this helper altogether.

Comment on lines 51 to 59
/*
Helper function to find an element with a particular text content.
React Testing Library's doesn't provide an easy way to search by text if text is split into multiple DOM elements.
*/
const getChildByTextContent = (parent: Element, textContent: string): HTMLElement => {
return Array.from(parent.querySelectorAll('*')).find(
(childElement) => childElement.textContent === textContent
) as HTMLElement;
};
Copy link
Contributor

Choose a reason for hiding this comment

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

Any reason this function and findDiffLineContaining cannot be extracted out to the top as helper functions, outside of the tests? This one is redefined on each it clause.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I thought it would be a bit easier to read if these functions are local to where they are used. But I understand that it's a matter of preference and the benefit is small, so I have no trouble moving these to the top level.


const removedLineAfter = getChildByTextContent(removedLine, '');
expect(
removedLineAfter ? window.getComputedStyle(removedLineAfter).backgroundColor : null
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 I understand why these ternary operators are needed here. How can null ever be ''?

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 catch! Looks like I forgot to change this line after refactoring.

Copy link
Contributor

@jpdjere jpdjere left a comment

Choose a reason for hiding this comment

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

Approving in general, left a couple questions and nits.

Thanks for covering this feature with tests 👍 ✅

@nikitaindik nikitaindik enabled auto-merge (squash) February 19, 2024 13:30
@nikitaindik nikitaindik merged commit cd374d2 into elastic:main Feb 19, 2024
36 of 37 checks passed
@kibana-ci
Copy link
Collaborator

💛 Build succeeded, but was flaky

Failed CI Steps

Test Failures

  • [job] [logs] FTR Configs #2 / discover/group2 adhoc data views should notify about invalid filter reffs

Metrics [docs]

Async chunks

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

id before after diff
securitySolution 11.6MB 11.6MB +39.0B

History

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

cc @nikitaindik

@kibanamachine
Copy link
Contributor

💚 All backports created successfully

Status Branch Result
8.13

Note: Successful backport PRs will be merged automatically after passing CI.

Questions ?

Please refer to the Backport tool documentation

kibanamachine added a commit that referenced this pull request Feb 19, 2024
# Backport

This will backport the following commits from `main` to `8.13`:
- [[Security Solution] JSON diffs test coverage
(#176770)](#176770)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Nikita
Indik","email":"[email protected]"},"sourceCommit":{"committedDate":"2024-02-19T15:12:51Z","message":"[Security
Solution] JSON diffs test coverage (#176770)\n\n**Resolves:
https://github.com/elastic/kibana/issues/166163**\r\n\r\nFlaky test
runner
runs:\r\n[1](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5189),\r\n[2](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5190),\r\n[3](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5191),\r\n[4](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5192)\r\n\r\n##
Summary\r\nThis PR adds tests in accordance with the
[test\r\nplan](#175958) that was
merged\r\nearlier.","sha":"cd374d23368de182a96df0948192a9bca7bdc4aa","branchLabelMapping":{"^v8.14.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","test-coverage","Team:Detections
and Resp","Team: SecuritySolution","Team:Detection Rule
Management","Feature:Prebuilt Detection
Rules","v8.13.0","v8.14.0"],"title":"[Security Solution] JSON diffs test
coverage","number":176770,"url":"https://github.com/elastic/kibana/pull/176770","mergeCommit":{"message":"[Security
Solution] JSON diffs test coverage (#176770)\n\n**Resolves:
https://github.com/elastic/kibana/issues/166163**\r\n\r\nFlaky test
runner
runs:\r\n[1](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5189),\r\n[2](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5190),\r\n[3](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5191),\r\n[4](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5192)\r\n\r\n##
Summary\r\nThis PR adds tests in accordance with the
[test\r\nplan](#175958) that was
merged\r\nearlier.","sha":"cd374d23368de182a96df0948192a9bca7bdc4aa"}},"sourceBranch":"main","suggestedTargetBranches":["8.13"],"targetPullRequestStates":[{"branch":"8.13","label":"v8.13.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v8.14.0","branchLabelMappingKey":"^v8.14.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/176770","number":176770,"mergeCommit":{"message":"[Security
Solution] JSON diffs test coverage (#176770)\n\n**Resolves:
https://github.com/elastic/kibana/issues/166163**\r\n\r\nFlaky test
runner
runs:\r\n[1](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5189),\r\n[2](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5190),\r\n[3](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5191),\r\n[4](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5192)\r\n\r\n##
Summary\r\nThis PR adds tests in accordance with the
[test\r\nplan](#175958) that was
merged\r\nearlier.","sha":"cd374d23368de182a96df0948192a9bca7bdc4aa"}}]}]
BACKPORT-->

Co-authored-by: Nikita Indik <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature:Prebuilt Detection Rules Security Solution Prebuilt Detection Rules release_note:skip Skip the PR/issue when compiling 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. test-coverage issues & PRs for improving code test coverage v8.13.0 v8.14.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Security Solution] Add test coverage for the JSON diff tab of prebuilt rule flyout
6 participants