-
Notifications
You must be signed in to change notification settings - Fork 55
CM-22159 add unit tests coverage #103
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
Merged
Merged
Changes from 4 commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
665ba07
CM-22159 add coverage to measure coverage percent and view coverage r…
MarshalX 710475a
CM-22159 add tests for auth client
MarshalX cdefa87
CM-22159 add tests for token and dev based clients
MarshalX 26588ce
CM-22159 add tests for scan client (zipped_file_scan)
MarshalX 5723f5d
CM-22159 add tests for --output option
MarshalX 17b573d
CM-22159 fix GHA
MarshalX 7c09bb2
excl test
MarshalX 92f19c1
fix sast
MarshalX 94ad7ec
fix typos
MarshalX 3e57bb8
fix sast?
MarshalX 5d065e5
fix sast??
MarshalX 2a629ff
fix sast???
MarshalX f8823ab
fix sast.
MarshalX File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| [run] | ||
| omit = | ||
| # ignore all test cases in tests/ | ||
| tests/* |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,9 @@ | ||
| __pycache__ | ||
| /build/ | ||
| /*.egg-info/ | ||
| /dist/ | ||
| /dist/ | ||
|
|
||
| # coverage | ||
| .coverage | ||
| htmlcov | ||
| coverage.* |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| import pytest | ||
| import responses | ||
|
|
||
| from cyclient.cycode_token_based_client import CycodeTokenBasedClient | ||
|
|
||
|
|
||
| _EXPECTED_API_TOKEN = 'someJWT' | ||
|
|
||
| _CLIENT_ID = 'b1234568-0eaa-1234-beb8-6f0c12345678' | ||
| _CLIENT_SECRET = 'a12345a-42b2-1234-3bdd-c0130123456' | ||
|
|
||
|
|
||
| @pytest.fixture(scope='session') | ||
| def token_based_client() -> CycodeTokenBasedClient: | ||
| return CycodeTokenBasedClient(_CLIENT_ID, _CLIENT_SECRET) | ||
|
|
||
|
|
||
| @pytest.fixture(scope='session') | ||
| def api_token_url(token_based_client: CycodeTokenBasedClient) -> str: | ||
| return f'{token_based_client.api_url}/api/v1/auth/api-token' | ||
|
|
||
|
|
||
| @pytest.fixture(scope='session') | ||
| def api_token_response(api_token_url) -> responses.Response: | ||
| return responses.Response( | ||
| method=responses.POST, | ||
| url=api_token_url, | ||
| json={ | ||
| 'token': _EXPECTED_API_TOKEN, | ||
| 'refresh_token': '12345678-0c68-1234-91ba-a13123456789', | ||
| 'expires_in': 86400 | ||
| }, | ||
| status=200 | ||
| ) | ||
|
|
||
|
|
||
| @pytest.fixture(scope='session') | ||
| @responses.activate | ||
| def api_token(token_based_client: CycodeTokenBasedClient, api_token_response: responses.Response) -> str: | ||
| responses.add(api_token_response) | ||
| return token_based_client.api_token |
Empty file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| from cyclient.scan_config.scan_config_creator import DefaultScanConfig | ||
|
|
||
|
|
||
| def test_get_service_name(): | ||
| default_scan_config = DefaultScanConfig() | ||
|
|
||
| assert default_scan_config.get_service_name('secret') == 'secret' | ||
| assert default_scan_config.get_service_name('iac') == 'iac' | ||
| assert default_scan_config.get_service_name('sca') == 'scans' | ||
| assert default_scan_config.get_service_name('sast') == 'scans' | ||
|
|
||
|
|
||
| def test_get_scans_prefix(): | ||
| default_scan_config = DefaultScanConfig() | ||
|
|
||
| assert default_scan_config.get_scans_prefix() == 'scans' | ||
|
|
||
|
|
||
| def test_get_detections_prefix(): | ||
| default_scan_config = DefaultScanConfig() | ||
|
|
||
| assert default_scan_config.get_detections_prefix() == 'detections' |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| from cyclient.scan_config.scan_config_creator import DevScanConfig | ||
|
|
||
|
|
||
| def test_get_service_name(): | ||
| dev_scan_config = DevScanConfig() | ||
|
|
||
| assert dev_scan_config.get_service_name('secret') == '5025' | ||
| assert dev_scan_config.get_service_name('iac') == '5026' | ||
| assert dev_scan_config.get_service_name('sca') == '5004' | ||
| assert dev_scan_config.get_service_name('sast') == '5004' | ||
|
|
||
|
|
||
| def test_get_scans_prefix(): | ||
| dev_scan_config = DevScanConfig() | ||
|
|
||
| assert dev_scan_config.get_scans_prefix() == '5004' | ||
|
|
||
|
|
||
| def test_get_detections_prefix(): | ||
| dev_scan_config = DevScanConfig() | ||
|
|
||
| assert dev_scan_config.get_detections_prefix() == '5016' |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,177 @@ | ||
| import pytest | ||
| import requests | ||
| import responses | ||
| from requests import Timeout | ||
|
|
||
| from cyclient.auth_client import AuthClient | ||
| from cyclient.models import AuthenticationSession, ApiTokenGenerationPollingResponse, \ | ||
| ApiTokenGenerationPollingResponseSchema | ||
| from cli.exceptions.custom_exceptions import CycodeError | ||
|
|
||
|
|
||
| @pytest.fixture(scope='module') | ||
| def code_challenge() -> str: | ||
| from cli.auth.auth_manager import AuthManager | ||
| code_challenge, _ = AuthManager()._generate_pkce_code_pair() | ||
| return code_challenge | ||
|
|
||
|
|
||
| @pytest.fixture(scope='module') | ||
| def code_verifier() -> str: | ||
| from cli.auth.auth_manager import AuthManager | ||
| _, code_verifier = AuthManager()._generate_pkce_code_pair() | ||
| return code_verifier | ||
|
|
||
|
|
||
| @pytest.fixture(scope='module', name='client') | ||
| def auth_client() -> AuthClient: | ||
| return AuthClient() | ||
|
|
||
|
|
||
| @pytest.fixture(scope='module', name='start_url') | ||
| def auth_start_url(client: AuthClient) -> str: | ||
| # TODO(MarshalX): create database of constants of endpoints. remove hardcoded paths | ||
| return client.cycode_client.build_full_url( | ||
| client.cycode_client.api_url, | ||
| f'{client.AUTH_CONTROLLER_PATH}/start' | ||
| ) | ||
|
|
||
|
|
||
| @pytest.fixture(scope='module', name='token_url') | ||
| def auth_token_url(client: AuthClient) -> str: | ||
| return client.cycode_client.build_full_url( | ||
| client.cycode_client.api_url, | ||
| f'{client.AUTH_CONTROLLER_PATH}/token' | ||
| ) | ||
|
|
||
|
|
||
| _SESSION_ID = '4cff1234-a209-47ed-ab2f-85676912345c' | ||
|
|
||
|
|
||
| @responses.activate | ||
| def test_start_session_success(client: AuthClient, start_url: str, code_challenge: str): | ||
| responses.add( | ||
| responses.POST, | ||
| start_url, | ||
| json={'session_id': _SESSION_ID}, | ||
| status=200, | ||
| ) | ||
|
|
||
| session_response = client.start_session(code_challenge) | ||
| assert isinstance(session_response, AuthenticationSession) | ||
| assert session_response.session_id == _SESSION_ID | ||
|
|
||
|
|
||
| @responses.activate | ||
| def test_start_session_timeout(client: AuthClient, start_url: str, code_challenge: str): | ||
| responses.add(responses.POST, start_url, status=504) | ||
| timeout_response = requests.post(start_url) | ||
MarshalX marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| responses.reset() | ||
|
|
||
| timeout_error = Timeout() | ||
| timeout_error.response = timeout_response | ||
|
|
||
| responses.add(responses.POST, start_url, body=timeout_error) | ||
|
|
||
| with pytest.raises(CycodeError) as e_info: | ||
| client.start_session(code_challenge) | ||
|
|
||
| assert e_info.value.status_code == 504 | ||
|
|
||
|
|
||
| @responses.activate | ||
| def test_start_session_http_error(client: AuthClient, start_url: str, code_challenge: str): | ||
| responses.add(responses.POST, start_url, status=401) | ||
|
|
||
| with pytest.raises(CycodeError) as e_info: | ||
| client.start_session(code_challenge) | ||
|
|
||
| assert e_info.value.status_code == 401 | ||
|
|
||
|
|
||
| @responses.activate | ||
| def test_get_api_token_success_pending(client: AuthClient, token_url: str, code_verifier: str): | ||
| expected_status = 'Pending' | ||
| expected_api_token = None | ||
|
|
||
| responses.add( | ||
| responses.POST, | ||
| token_url, | ||
| json={'status': expected_status, 'api_token': expected_api_token}, | ||
| status=200, | ||
| ) | ||
|
|
||
| api_token_polling_response = client.get_api_token(_SESSION_ID, code_verifier) | ||
| assert isinstance(api_token_polling_response, ApiTokenGenerationPollingResponse) | ||
| assert api_token_polling_response.status == expected_status | ||
| assert api_token_polling_response.api_token == expected_api_token | ||
|
|
||
|
|
||
| @responses.activate | ||
| def test_get_api_token_success_completed(client: AuthClient, token_url: str, code_verifier: str): | ||
| expected_status = 'Completed' | ||
| expected_json = { | ||
| 'status': expected_status, | ||
| 'api_token': { | ||
| 'clientId': 'b123458-0eaa-4010-beb4-6f0c54612345', | ||
| 'secret': 'a123450a-42b2-4ad5-8bdd-c0130123456', | ||
| 'description': 'cycode cli api token', | ||
| 'createdByUserId': None, | ||
| 'createdAt': '2023-04-26T11:38:54+00:00' | ||
| } | ||
| } | ||
| expected_response = ApiTokenGenerationPollingResponseSchema().load(expected_json) | ||
|
|
||
| responses.add( | ||
| responses.POST, | ||
| token_url, | ||
| json=expected_json, | ||
| status=200, | ||
| ) | ||
|
|
||
| api_token_polling_response = client.get_api_token(_SESSION_ID, code_verifier) | ||
| assert isinstance(api_token_polling_response, ApiTokenGenerationPollingResponse) | ||
| assert api_token_polling_response.status == expected_status | ||
| assert api_token_polling_response.api_token.client_id == expected_response.api_token.client_id | ||
| assert api_token_polling_response.api_token.secret == expected_response.api_token.secret | ||
| assert api_token_polling_response.api_token.description == expected_response.api_token.description | ||
|
|
||
|
|
||
| @responses.activate | ||
| def test_get_api_token_http_error_valid_response(client: AuthClient, token_url: str, code_verifier: str): | ||
| # TODO(MarshalX): ask Michal about such cases or dive into code of platform | ||
| expected_status = 'Pending' | ||
| expected_api_token = None | ||
|
|
||
| responses.add( | ||
| responses.POST, | ||
| token_url, | ||
| json={'status': expected_status, 'api_token': expected_api_token}, | ||
| status=418, # any code between 400 and 600 | ||
| ) | ||
|
|
||
| api_token_polling_response = client.get_api_token(_SESSION_ID, code_verifier) | ||
| assert isinstance(api_token_polling_response, ApiTokenGenerationPollingResponse) | ||
| assert api_token_polling_response.status == expected_status | ||
| assert api_token_polling_response.api_token == expected_api_token | ||
|
|
||
|
|
||
| @responses.activate | ||
| def test_get_api_token_http_error_invalid_response(client: AuthClient, token_url: str, code_verifier: str): | ||
| responses.add( | ||
| responses.POST, | ||
| token_url, | ||
| body='Invalid body', | ||
| status=418, # any code between 400 and 600 | ||
| ) | ||
|
|
||
| api_token_polling_response = client.get_api_token(_SESSION_ID, code_verifier) | ||
| assert api_token_polling_response is None | ||
|
|
||
|
|
||
| @responses.activate | ||
| def test_get_api_token_not_excepted_exception(client: AuthClient, token_url: str, code_verifier: str): | ||
| responses.add(responses.POST, token_url, body=Timeout()) | ||
|
|
||
| api_token_polling_response = client.get_api_token(_SESSION_ID, code_verifier) | ||
| assert api_token_polling_response is None | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| from cyclient import config | ||
| from cyclient.cycode_client import CycodeClient | ||
|
|
||
|
|
||
| def test_init_values_from_config(): | ||
| client = CycodeClient() | ||
|
|
||
| assert client.api_url == config.cycode_api_url | ||
| assert client.timeout == config.timeout |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| from cyclient import config, __version__ | ||
| from cyclient.cycode_client_base import CycodeClientBase | ||
|
|
||
|
|
||
| def test_mandatory_headers(): | ||
| expected_headers = { | ||
| 'User-Agent': f'cycode-cli_{__version__}', | ||
| } | ||
|
|
||
| client = CycodeClientBase(config.cycode_api_url) | ||
|
|
||
| assert client.MANDATORY_HEADERS == expected_headers | ||
|
|
||
|
|
||
| def test_get_request_headers(): | ||
| client = CycodeClientBase(config.cycode_api_url) | ||
|
|
||
| assert client.get_request_headers() == client.MANDATORY_HEADERS | ||
|
|
||
|
|
||
| def test_get_request_headers_with_additional(): | ||
| client = CycodeClientBase(config.cycode_api_url) | ||
|
|
||
| additional_headers = { | ||
| 'Authorize': 'Token test' | ||
| } | ||
| expected_headers = {**client.MANDATORY_HEADERS, **additional_headers} | ||
|
|
||
| assert client.get_request_headers(additional_headers) == expected_headers | ||
|
|
||
|
|
||
| def test_build_full_url(): | ||
| url = config.cycode_api_url | ||
| client = CycodeClientBase(url) | ||
|
|
||
| endpoint = 'test' | ||
| expected_url = f'{url}/{endpoint}' | ||
|
|
||
| assert client.build_full_url(url, endpoint) == expected_url |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| from cyclient import config | ||
| from cyclient.cycode_dev_based_client import CycodeDevBasedClient | ||
|
|
||
|
|
||
| def test_get_request_headers(): | ||
| client = CycodeDevBasedClient(config.cycode_api_url) | ||
|
|
||
| dev_based_headers = { | ||
| 'X-Tenant-Id': config.dev_tenant_id | ||
| } | ||
| expected_headers = {**client.MANDATORY_HEADERS, **dev_based_headers} | ||
|
|
||
| assert client.get_request_headers() == expected_headers | ||
|
|
||
|
|
||
| def test_build_full_url(): | ||
| url = config.cycode_api_url | ||
| client = CycodeDevBasedClient(url) | ||
|
|
||
| endpoint = 'test' | ||
| expected_url = f'{url}:{endpoint}' | ||
|
|
||
| assert client.build_full_url(url, endpoint) == expected_url |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.