From ecdf27076daac4caca4d0c5ee5282e9e19de71cf Mon Sep 17 00:00:00 2001 From: "deepsource-autofix[bot]" <62050782+deepsource-autofix[bot]@users.noreply.github.com> Date: Tue, 16 Jan 2024 04:49:16 +0000 Subject: [PATCH] style: format code with Black This commit fixes the style issues introduced in 1b12fb2 according to the output from Black. Details: None --- codeinsight_sdk/client.py | 79 ++++++----- codeinsight_sdk/exceptions.py | 17 ++- codeinsight_sdk/experimental.py | 28 ++-- codeinsight_sdk/handler.py | 2 +- codeinsight_sdk/handlers/__init__.py | 2 +- codeinsight_sdk/handlers/inventory.py | 19 +-- codeinsight_sdk/handlers/project.py | 182 +++++++++++++++----------- codeinsight_sdk/handlers/report.py | 6 +- codeinsight_sdk/models.py | 10 +- examples/example-1-list-projects.py | 1 - examples/example-9-dataframe.py | 2 +- examples/shared.py | 5 +- tests/test_client.py | 91 ++++++++----- tests/test_experimental.py | 27 ++-- tests/test_handlers.py | 2 +- tests/test_models.py | 28 ++-- tests/test_not_implemented.py | 12 +- 17 files changed, 306 insertions(+), 207 deletions(-) diff --git a/codeinsight_sdk/client.py b/codeinsight_sdk/client.py index 80f4785..db7d539 100644 --- a/codeinsight_sdk/client.py +++ b/codeinsight_sdk/client.py @@ -8,22 +8,23 @@ logger = logging.getLogger(__name__) + class CodeInsightClient: """Client for the code insight API.""" - def __init__(self, - base_url: str, - api_token: str, - timeout: int = 60, - verify_ssl: bool = True, - experimental: bool = False - ): - + def __init__( + self, + base_url: str, + api_token: str, + timeout: int = 60, + verify_ssl: bool = True, + experimental: bool = False, + ): self.base_url = base_url self.api_url = f"{base_url}/codeinsight/api" self.__api_token = api_token self.__api_headers = { - 'Content-Type': 'application/json', + "Content-Type": "application/json", "Authorization": "Bearer %s" % self.__api_token, "User-Agent": "codeinsight_sdk_python", } @@ -31,11 +32,19 @@ def __init__(self, self.__verify_ssl = verify_ssl self.experimental_enabled = experimental - def request(self, method, url_part: str, params: dict = None, body: any = None, data: any = None, content_type: str = None): + def request( + self, + method, + url_part: str, + params: dict = None, + body: any = None, + data: any = None, + content_type: str = None, + ): url = f"{self.api_url}/{url_part}" # Iterate over params and remove any that are None (Empty) - if(params): + if params: for k, v in list(params.items()): if v is None: del params[k] @@ -43,66 +52,72 @@ def request(self, method, url_part: str, params: dict = None, body: any = None, # Update headers if content_type is specified headers = self.__api_headers if content_type: - headers['Content-Type'] = content_type + headers["Content-Type"] = content_type - response = requests.request(method, url, - headers=self.__api_headers, params=params, json=body, data=data, - timeout=self.__timeout, verify=self.__verify_ssl) + response = requests.request( + method, + url, + headers=self.__api_headers, + params=params, + json=body, + data=data, + timeout=self.__timeout, + verify=self.__verify_ssl, + ) if not response.ok: - logger.error(f"Error: {response.status_code} - {response.reason}", exc_info=True) + logger.error( + f"Error: {response.status_code} - {response.reason}", exc_info=True + ) logger.error(response.text) - raise CodeInsightError(response) + raise CodeInsightError(response) return response @property def projects(self) -> ProjectHandler: return ProjectHandler(self) - + @property def reports(self) -> ReportHandler: return ReportHandler(self) - + @property def inventories(self): return InventoryHandler(self) - + @property def experimental(self) -> ExperimentalHandler: if self.experimental_enabled == False: raise CodeInsightError("Experimental API is not enabled for this instance") else: return ExperimentalHandler(self) - - + # Coming soon...? - def vulnerabilites(self): raise NotImplementedError - + def users(self): raise NotImplementedError - + def licenses(self): raise NotImplementedError - + def tasks(self): raise NotImplementedError - + def rules(self): raise NotImplementedError - + def files(self): raise NotImplementedError - + def folders(self): raise NotImplementedError - + def jobs(self): raise NotImplementedError - + def components(self): raise NotImplementedError - diff --git a/codeinsight_sdk/exceptions.py b/codeinsight_sdk/exceptions.py index 334cc19..455127d 100644 --- a/codeinsight_sdk/exceptions.py +++ b/codeinsight_sdk/exceptions.py @@ -1,24 +1,29 @@ - import requests import json -class GenericError(Exception): #pragma: no cover + +class GenericError(Exception): # pragma: no cover """Generic error class, catch-all for most code insight API errors.""" + pass -class NotYetImplementedError(Exception): #pragma: no cover + +class NotYetImplementedError(Exception): # pragma: no cover """Error class for API features that have not yet been implemented.""" + pass + class CodeInsightError(GenericError): """Error class for code insight API errors.""" + def __init__(self, response: requests.Response): try: resp = response.json() self.code = response.status_code - self.message = resp['Error: '] - self.arguments = resp['Arguments: '] - self.error = resp['Key: '] + self.message = resp["Error: "] + self.arguments = resp["Arguments: "] + self.error = resp["Key: "] self.add_note(f"Arguments: {self.arguments}") super().__init__("Error: %s - %s" % (self.code, self.message)) diff --git a/codeinsight_sdk/experimental.py b/codeinsight_sdk/experimental.py index ffb1610..d1fa830 100644 --- a/codeinsight_sdk/experimental.py +++ b/codeinsight_sdk/experimental.py @@ -1,27 +1,32 @@ from .handler import Handler from .models import ProjectInventoryItem + class ExperimentalHandler(Handler): def __init__(self, client): super().__init__(client) - + def get(self): # Do nothing, there is no get for this handler pass - - def get_project_vulnerabilities(self, project_id:int) -> list[ProjectInventoryItem]: + + def get_project_vulnerabilities( + self, project_id: int + ) -> list[ProjectInventoryItem]: """ Get all vulnerabilities for a project. - + Args: project_id (int): The project id. - + Returns: dict: The vulnerabilities. """ # First we get the inventory summary for the project with vulnerability summary # Then we iterate over the inventory items and calling the inventory vulnerability endpoint for each item with a vulnerability - inventory = self.client.projects.get_inventory_summary(project_id, vulnerabilitySummary=True) + inventory = self.client.projects.get_inventory_summary( + project_id, vulnerabilitySummary=True + ) # Iterate over the inventory items, find which have vulnerabilities. item: ProjectInventoryItem @@ -29,15 +34,16 @@ def get_project_vulnerabilities(self, project_id:int) -> list[ProjectInventoryIt for item in inventory: if item.vulnerabilitySummary is None: continue - + # If the item has a vulnerability, get the vulnerability details for this item and append it - if sum(item.vulnerabilitySummary[0]['CvssV3'].values()) > 0: - - vul_detail = self.client.inventories.get_inventory_vulnerabilities(item.id) + if sum(item.vulnerabilitySummary[0]["CvssV3"].values()) > 0: + vul_detail = self.client.inventories.get_inventory_vulnerabilities( + item.id + ) item.vulnerabilities = vul_detail vuln_items.append(item) else: # If the item has no vulnerabilities, skip it continue - return vuln_items \ No newline at end of file + return vuln_items diff --git a/codeinsight_sdk/handler.py b/codeinsight_sdk/handler.py index 8a0b5b3..838031d 100644 --- a/codeinsight_sdk/handler.py +++ b/codeinsight_sdk/handler.py @@ -4,6 +4,7 @@ from .models import Project, ProjectInventory, ProjectInventoryItem, Report from .exceptions import CodeInsightError + class Handler(abc.ABC): def __init__(self, client): self.client = client @@ -12,4 +13,3 @@ def __init__(self, client): @abc.abstractmethod def get(self): pass - diff --git a/codeinsight_sdk/handlers/__init__.py b/codeinsight_sdk/handlers/__init__.py index e549db5..346c530 100644 --- a/codeinsight_sdk/handlers/__init__.py +++ b/codeinsight_sdk/handlers/__init__.py @@ -1,3 +1,3 @@ from .inventory import InventoryHandler from .project import ProjectHandler -from .report import ReportHandler \ No newline at end of file +from .report import ReportHandler diff --git a/codeinsight_sdk/handlers/inventory.py b/codeinsight_sdk/handlers/inventory.py index 8de2e5a..0a9db84 100644 --- a/codeinsight_sdk/handlers/inventory.py +++ b/codeinsight_sdk/handlers/inventory.py @@ -1,13 +1,14 @@ from ..models import ProjectInventoryItem, Vulnerability from ..handler import Handler + class InventoryHandler(Handler): - """ Handles operations related to inventories.""" + """Handles operations related to inventories.""" def __init__(self, client): super().__init__(client) self.cls = ProjectInventoryItem - + def get(self, inventoryId: int) -> list[ProjectInventoryItem]: """ Get an inventory item by id. @@ -21,13 +22,13 @@ def get(self, inventoryId: int) -> list[ProjectInventoryItem]: path = f"inventories/{inventoryId}" resp = self.client.request("GET", url_part=path) inventory = [] - for inv_item in resp.json()['data']: + for inv_item in resp.json()["data"]: inventory.append(ProjectInventoryItem.from_dict(inv_item)) return inventory - - def get_inventory_vulnerabilities(self, inventoryId: int, - limit: int = 25, - offset: int = 1) -> list[Vulnerability]: + + def get_inventory_vulnerabilities( + self, inventoryId: int, limit: int = 25, offset: int = 1 + ) -> list[Vulnerability]: """ Get all vulnerabilities for an inventory item. @@ -44,7 +45,7 @@ def get_inventory_vulnerabilities(self, inventoryId: int, # TODO - Iterate pages inventory_vuls: list(Vulnerability) = [] - for v in resp.json()['data']: + for v in resp.json()["data"]: inventory_vuls.append(Vulnerability.from_dict(v)) - return inventory_vuls \ No newline at end of file + return inventory_vuls diff --git a/codeinsight_sdk/handlers/project.py b/codeinsight_sdk/handlers/project.py index 65e7a71..71f4a03 100644 --- a/codeinsight_sdk/handlers/project.py +++ b/codeinsight_sdk/handlers/project.py @@ -5,18 +5,23 @@ from ..exceptions import CodeInsightError + class ProjectHandler(Handler): def __init__(self, client): super().__init__(client) self.cls = Project - def create(self, name:str, description:str = None, folder:str = None, - scanProfileName:str = None, - owner:str = None, - risk:str = None, - folderId:int = None, - customFields:List[dict] = None, - ) -> int: + def create( + self, + name: str, + description: str = None, + folder: str = None, + scanProfileName: str = None, + owner: str = None, + risk: str = None, + folderId: int = None, + customFields: List[dict] = None, + ) -> int: """ Creates a project. @@ -29,23 +34,24 @@ def create(self, name:str, description:str = None, folder:str = None, Project: The created project id. """ path = "projects" - data = {"name": name, - "description": description, - "folderName": folder, - "scanProfileName": scanProfileName, - "owner": owner, - "risk": risk, - "folderId": folderId, - "customFields": customFields} + data = { + "name": name, + "description": description, + "folderName": folder, + "scanProfileName": scanProfileName, + "owner": owner, + "risk": risk, + "folderId": folderId, + "customFields": customFields, + } resp = self.client.request("POST", url_part=path, body=data) try: - project_id = resp.json()['data']['id'] + project_id = resp.json()["data"]["id"] except KeyError: raise CodeInsightError(resp) return project_id - - #Note API endpoints switch between projects and project... + # Note API endpoints switch between projects and project... def all(self) -> List[Project]: """ Retrieves all projects from the server. @@ -57,11 +63,11 @@ def all(self) -> List[Project]: path = "projects" resp = self.client.request("GET", url_part=path) projects = [] - for project_data in resp.json()['data']: + for project_data in resp.json()["data"]: projects.append(self.cls.from_dict(project_data)) return projects - def get(self, id:int) -> Project: + def get(self, id: int) -> Project: """ Retrieves a project by its ID. @@ -73,10 +79,10 @@ def get(self, id:int) -> Project: """ path = f"projects/{id}" resp = self.client.request("GET", url_part=path) - project_data = resp.json()['data'] + project_data = resp.json()["data"] return self.cls.from_dict(project_data) - def get_id(self, project_name:str) -> int: + def get_id(self, project_name: str) -> int: """ Retrieves the ID of a project based on its name. @@ -90,17 +96,22 @@ def get_id(self, project_name:str) -> int: params = {"projectName": project_name} resp = self.client.request("GET", url_part=path, params=params) try: - project_id = resp.json()['Content: '] # Yes, the key is called 'Content: ' ... + project_id = resp.json()[ + "Content: " + ] # Yes, the key is called 'Content: ' ... except KeyError: raise CodeInsightError(resp) return project_id - def get_inventory_summary(self, project_id:int, - vulnerabilitySummary : bool = False, - cvssVersion: str = 'ANY', - published: str = 'ALL', - offset:int = 1, - limit:int = 25) -> List[ProjectInventoryItem]: + def get_inventory_summary( + self, + project_id: int, + vulnerabilitySummary: bool = False, + cvssVersion: str = "ANY", + published: str = "ALL", + offset: int = 1, + limit: int = 25, + ) -> List[ProjectInventoryItem]: """ Retrieves the inventory summary for a specific project. @@ -116,76 +127,91 @@ def get_inventory_summary(self, project_id:int, List[ProjectInventoryItem]: A list of ProjectInventoryItem objects representing the inventory summary. """ path = f"projects/{project_id}/inventorySummary" - params = {"vulnerabilitySummary": vulnerabilitySummary, - "cvssVersion": cvssVersion, - "published": published, - "offset": offset, - "limit": limit + params = { + "vulnerabilitySummary": vulnerabilitySummary, + "cvssVersion": cvssVersion, + "published": published, + "offset": offset, + "limit": limit, } resp = self.client.request("GET", url_part=path, params=params) - current_page = int(resp.headers['current-page']) - number_of_pages = int(resp.headers['number-of-pages']) - total_records = int(resp.headers['total-records']) + current_page = int(resp.headers["current-page"]) + number_of_pages = int(resp.headers["number-of-pages"]) + total_records = int(resp.headers["total-records"]) inventory = [] - for inv_item in resp.json()['data']: + for inv_item in resp.json()["data"]: inventory.append(ProjectInventoryItem.from_dict(inv_item)) - + # Iterate through all the pages if number_of_pages > offset: - params.update({"offset": offset+1}) + params.update({"offset": offset + 1}) chunk = self.get_inventory_summary(project_id, **params) # Only append the inventory records inventory.extend(chunk) return inventory - - def get_inventory(self,project_id:int, - skip_vulnerabilities: bool = False, - published:bool = True, - vendor:str = None, - product:str = None, - page_size: int = 100, - page: int = 1, - review_status: str = None, - alerts: str = None, - include_files: bool = True - ) -> ProjectInventory: + + def get_inventory( + self, + project_id: int, + skip_vulnerabilities: bool = False, + published: bool = True, + vendor: str = None, + product: str = None, + page_size: int = 100, + page: int = 1, + review_status: str = None, + alerts: str = None, + include_files: bool = True, + ) -> ProjectInventory: path = f"project/inventory/{project_id}" - params = {"skipVulnerabilities": skip_vulnerabilities, - "published": published, - "vendor": vendor, - "product": product, - "page": page, - "pageSize": page_size, - "reviewStatus": review_status, - "alerts": alerts, - "includeFiles": include_files} + params = { + "skipVulnerabilities": skip_vulnerabilities, + "published": published, + "vendor": vendor, + "product": product, + "page": page, + "pageSize": page_size, + "reviewStatus": review_status, + "alerts": alerts, + "includeFiles": include_files, + } resp = self.client.request("GET", url_part=path, params=params) project_inventory = resp.json() project = ProjectInventory.from_dict(project_inventory) # Iterate through all the pages - if int(resp.headers['number-of-pages']) > page: - chunk = self.get_inventory(project_id, page=page+1) + if int(resp.headers["number-of-pages"]) > page: + chunk = self.get_inventory(project_id, page=page + 1) # Only append the inventory records project.inventoryItems.extend(chunk.inventoryItems) return project - - def upload_codebase(self, project_id:int, - codebase_path:str, - deleteExistingFileOnServer: bool = False, - expansionLevel: int = 1, - deleteArchiveAfterExpand: bool = False, - archiveDirSuffix: str = None, - ) -> int: + + def upload_codebase( + self, + project_id: int, + codebase_path: str, + deleteExistingFileOnServer: bool = False, + expansionLevel: int = 1, + deleteArchiveAfterExpand: bool = False, + archiveDirSuffix: str = None, + ) -> int: path = "project/uploadProjectCodebase" - params = {"projectId": project_id, - "deleteExistingFileOnServer": deleteExistingFileOnServer, - "expansionLevel": expansionLevel, - "deleteArchiveAfterExpand": deleteArchiveAfterExpand, - "archiveDirSuffix": archiveDirSuffix} - code_file = {"file": open(codebase_path, 'rb')} + params = { + "projectId": project_id, + "deleteExistingFileOnServer": deleteExistingFileOnServer, + "expansionLevel": expansionLevel, + "deleteArchiveAfterExpand": deleteArchiveAfterExpand, + "archiveDirSuffix": archiveDirSuffix, + } + code_file = {"file": open(codebase_path, "rb")} content_type = "application/octet-stream" - resp = self.client.request("POST", url_part=path, params=params, data=code_file,content_type=content_type) + resp = self.client.request( + "POST", + url_part=path, + params=params, + data=code_file, + content_type=content_type, + ) return resp.status_code diff --git a/codeinsight_sdk/handlers/report.py b/codeinsight_sdk/handlers/report.py index bb382ca..3da0b4b 100644 --- a/codeinsight_sdk/handlers/report.py +++ b/codeinsight_sdk/handlers/report.py @@ -22,7 +22,7 @@ def __init__(self, client): super().__init__(client) self.cls = Report - def get(self, id:int): + def get(self, id: int): """ Retrieves a report by its ID. @@ -35,7 +35,7 @@ def get(self, id:int): """ path = f"reports/{id}" resp = self.client.request("GET", url_part=path) - report_data = resp.json()['data'] + report_data = resp.json()["data"] report = self.cls.from_dict(report_data) return report @@ -50,6 +50,6 @@ def all(self): path = "reports" resp = self.client.request("GET", url_part=path) reports = [] - for report_data in resp.json()['data']: + for report_data in resp.json()["data"]: reports.append(self.cls.from_dict(report_data)) return reports diff --git a/codeinsight_sdk/models.py b/codeinsight_sdk/models.py index 81adf43..026013c 100644 --- a/codeinsight_sdk/models.py +++ b/codeinsight_sdk/models.py @@ -5,6 +5,7 @@ from dataclasses_json import DataClassJsonMixin, dataclass_json from typing import Any, Optional, List, Dict + @dataclass class Project(DataClassJsonMixin): id: int @@ -26,6 +27,7 @@ class Vulnerability(DataClassJsonMixin): vulnerabilityCvssV3Score: int vulnerabilityCvssV3Severity: str + @dataclass class ProjectInventoryItem(DataClassJsonMixin): itemNumber: int @@ -45,12 +47,14 @@ class ProjectInventoryItem(DataClassJsonMixin): vulnerabilitySummary: Optional[List[Dict[str, Dict]]] = None filePaths: Optional[List[str]] = None -@dataclass_json #Trying this style instead of DataClassJsonMixin + +@dataclass_json # Trying this style instead of DataClassJsonMixin @dataclass -class ProjectInventory(): +class ProjectInventory: projectId: int inventoryItems: List[ProjectInventoryItem] + @dataclass class Report(DataClassJsonMixin): id: int @@ -61,4 +65,4 @@ class Report(DataClassJsonMixin): enableProjectPicker: bool order: int createdDateTime: str - updatedDateTime: str \ No newline at end of file + updatedDateTime: str diff --git a/examples/example-1-list-projects.py b/examples/example-1-list-projects.py index f02f11d..220b35d 100644 --- a/examples/example-1-list-projects.py +++ b/examples/example-1-list-projects.py @@ -8,4 +8,3 @@ print(client.projects.all()) - diff --git a/examples/example-9-dataframe.py b/examples/example-9-dataframe.py index 6ef25f8..c3ee1c8 100644 --- a/examples/example-9-dataframe.py +++ b/examples/example-9-dataframe.py @@ -8,4 +8,4 @@ inventory = client.project_inventory.get(1) -df = pd.DataFrame(inventory.__dict__['inventoryItems']) \ No newline at end of file +df = pd.DataFrame(inventory.__dict__["inventoryItems"]) diff --git a/examples/shared.py b/examples/shared.py index b5a3277..da598ef 100644 --- a/examples/shared.py +++ b/examples/shared.py @@ -1,3 +1,2 @@ - -BASE_URL = 'https://api.revenera.com' -AUTH_TOKEN = 'test' \ No newline at end of file +BASE_URL = "https://api.revenera.com" +AUTH_TOKEN = "test" diff --git a/tests/test_client.py b/tests/test_client.py index afe4e8e..e957268 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -13,14 +13,15 @@ TEST_URL = "https://api.revenera.com" TEST_API_TOKEN = "your_api_token" + class TestCodeInsightClient: @pytest.fixture def client(self): return CodeInsightClient(TEST_URL, TEST_API_TOKEN) - + def test_client(self, client): assert client.base_url == TEST_URL - + def test_client_expertimental_disabled(self, client): assert client.experimental_enabled == False @@ -30,44 +31,54 @@ def test_endpoint_not_found(self, client): with pytest.raises(Exception): client.projects.all() + class TestProjectEndpoints: @pytest.fixture def client(self): return CodeInsightClient(TEST_URL, TEST_API_TOKEN) - + def test_create_project(self, client): project_name = "Test" with requests_mock.Mocker() as m: m.post(f"{TEST_URL}/codeinsight/api/projects", text='{"data": {"id":1}}') project_id = client.projects.create(project_name) assert project_id == 1 - + def test_get_all_projects(self, client): with requests_mock.Mocker() as m: - m.get(f"{TEST_URL}/codeinsight/api/projects", text='{"data": [{"id":1, "name":"Test"}, {"id":2, "name":"Test 2"}]}') + m.get( + f"{TEST_URL}/codeinsight/api/projects", + text='{"data": [{"id":1, "name":"Test"}, {"id":2, "name":"Test 2"}]}', + ) projects = client.projects.all() assert len(projects) > 0 def test_get_project_id(self, client): project_name = "Test" with requests_mock.Mocker() as m: - m.get(f"{TEST_URL}/codeinsight/api/project/id", text='{ "Content: ": 1 }') # Yes, the key is called 'Content: ' ... + m.get( + f"{TEST_URL}/codeinsight/api/project/id", text='{ "Content: ": 1 }' + ) # Yes, the key is called 'Content: ' ... project_id = client.projects.get_id(project_name) assert project_id == 1 - def test_get_project_id_invalid(self,client): + def test_get_project_id_invalid(self, client): project_name = "Invalid_Project" fake_response_json = """{ "Arguments: " : ["",""], "Key: ": " InvalidProjectNameParm", "Error: ": "The project name entered was not found" } """ with requests_mock.Mocker() as m: - # Note, the key names end with a colon and space '...: ' - m.get(f"{TEST_URL}/codeinsight/api/project/id", text=fake_response_json, status_code=400) + # Note, the key names end with a colon and space '...: ' + m.get( + f"{TEST_URL}/codeinsight/api/project/id", + text=fake_response_json, + status_code=400, + ) with pytest.raises(CodeInsightError): client.projects.get_id(project_name) - - def test_get_project(self,client): + + def test_get_project(self, client): project_id = 1 fake_response_json = """ { "data": { "id": 1, @@ -96,7 +107,10 @@ def test_get_project(self,client): }} """ with requests_mock.Mocker() as m: - m.get(f"{TEST_URL}/codeinsight/api/projects/{project_id}", text=fake_response_json) + m.get( + f"{TEST_URL}/codeinsight/api/projects/{project_id}", + text=fake_response_json, + ) project = client.projects.get(project_id) assert project.id == 1 assert project.name == "Test" @@ -105,7 +119,7 @@ def test_get_project(self,client): assert project.vulnerabilities["CvssV2"]["High"] == 2 assert project.vulnerabilities["CvssV2"]["Unknown"] == 4 - def test_get_project_inventory_multipage(self,client): + def test_get_project_inventory_multipage(self, client): project_id = 1 total_pages = 4 total_records = total_pages * 2 @@ -121,23 +135,32 @@ def test_get_project_inventory_multipage(self,client): ]} """ with requests_mock.Mocker() as m: - m.get(f"{TEST_URL}/codeinsight/api/project/inventory/{project_id}", - text=fake_response_json, headers=response_header) + m.get( + f"{TEST_URL}/codeinsight/api/project/inventory/{project_id}", + text=fake_response_json, + headers=response_header, + ) project_inventory = client.projects.get_inventory(project_id) assert project_inventory.projectId == project_id assert len(project_inventory.inventoryItems) == total_records - assert project_inventory.inventoryItems[0].vulnerabilities[0].vulnerabilityName == "CVE-2020-1234" - - def test_upload_codebase(self,client): + assert ( + project_inventory.inventoryItems[0].vulnerabilities[0].vulnerabilityName + == "CVE-2020-1234" + ) + + def test_upload_codebase(self, client): project_id = 1 codebase_path = "tests/resources/test_codebase.zip" with requests_mock.Mocker() as m: - m.post(f"{TEST_URL}/codeinsight/api/project/uploadProjectCodebase", text='{"data": {"id":1}}') + m.post( + f"{TEST_URL}/codeinsight/api/project/uploadProjectCodebase", + text='{"data": {"id":1}}', + ) resp = client.projects.upload_codebase(project_id, codebase_path) assert resp == 200 #### FIX THIS! #### - def test_get_project_inventory_summary(self,client): + def test_get_project_inventory_summary(self, client): project_id = 1 total_pages = 4 total_records = total_pages * 2 @@ -174,9 +197,14 @@ def test_get_project_inventory_summary(self,client): } """ with requests_mock.Mocker() as m: - m.get(f"{TEST_URL}/codeinsight/api/projects/{project_id}/inventorySummary", - text=fake_response_json, headers=response_header) - project_inventory_summary = client.projects.get_inventory_summary(project_id) + m.get( + f"{TEST_URL}/codeinsight/api/projects/{project_id}/inventorySummary", + text=fake_response_json, + headers=response_header, + ) + project_inventory_summary = client.projects.get_inventory_summary( + project_id + ) assert len(project_inventory_summary) == 8 assert project_inventory_summary[1].id == 12346 @@ -186,8 +214,8 @@ class TestReportsEndpoints: @pytest.fixture def client(self): return CodeInsightClient(TEST_URL, TEST_API_TOKEN) - - def test_get_reports_all(self,client): + + def test_get_reports_all(self, client): fake_response_json = """ { "data": [ { "id": 1, @@ -216,14 +244,13 @@ def test_get_reports_all(self,client): } """ with requests_mock.Mocker() as m: - m.get(f"{TEST_URL}/codeinsight/api/reports", - text=fake_response_json) + m.get(f"{TEST_URL}/codeinsight/api/reports", text=fake_response_json) reports = client.reports.all() assert len(reports) == 2 assert reports[1].id == 2 assert reports[1].enabled == False - def test_get_report(self,client): + def test_get_report(self, client): report_id = 1 fake_response_json = """ { "data": { @@ -240,8 +267,10 @@ def test_get_report(self,client): } """ with requests_mock.Mocker() as m: - m.get(f"{TEST_URL}/codeinsight/api/reports/{report_id}", - text=fake_response_json) + m.get( + f"{TEST_URL}/codeinsight/api/reports/{report_id}", + text=fake_response_json, + ) report = client.reports.get(1) assert report.id == 1 - assert report.enabled == True \ No newline at end of file + assert report.enabled == True diff --git a/tests/test_experimental.py b/tests/test_experimental.py index fe0e0ea..4e358d8 100644 --- a/tests/test_experimental.py +++ b/tests/test_experimental.py @@ -13,14 +13,15 @@ TEST_URL = "https://api.revenera.com" TEST_API_TOKEN = "your_api_token" + class TestExperimental: @pytest.fixture def client(self): return CodeInsightClient(TEST_URL, TEST_API_TOKEN, experimental=True) - + def test_experimental_enabled(self, client): assert client.experimental_enabled == True - + def test_get_project_vulnerabilities(self, client): project_id = 1 total_pages = 4 @@ -86,11 +87,21 @@ def test_get_project_vulnerabilities(self, client): "vulnerabilityCvssV3Severity":"CRITICAL"} ] } """ with requests_mock.Mocker() as m: - m.get(f"{TEST_URL}/codeinsight/api/projects/{project_id}/inventorySummary", - text=fake_response_json, headers=response_header) - m.get(f"{TEST_URL}/codeinsight/api/inventories/12346/vulnerabilities", - text=mock_resp_vuln, headers=response_header) - vulnerable_items = client.experimental.get_project_vulnerabilities(project_id) + m.get( + f"{TEST_URL}/codeinsight/api/projects/{project_id}/inventorySummary", + text=fake_response_json, + headers=response_header, + ) + m.get( + f"{TEST_URL}/codeinsight/api/inventories/12346/vulnerabilities", + text=mock_resp_vuln, + headers=response_header, + ) + vulnerable_items = client.experimental.get_project_vulnerabilities( + project_id + ) assert len(vulnerable_items) > 0 assert vulnerable_items[0].vulnerabilities is not None - assert vulnerable_items[0].vulnerabilities[1].vulnerabilityName == "CVE-987-65432" + assert ( + vulnerable_items[0].vulnerabilities[1].vulnerabilityName == "CVE-987-65432" + ) diff --git a/tests/test_handlers.py b/tests/test_handlers.py index 6bc3bdd..c8d5298 100644 --- a/tests/test_handlers.py +++ b/tests/test_handlers.py @@ -8,4 +8,4 @@ class TestHandlers(object): @pytest.fixture def client(self): - return CodeInsightClient("","") + return CodeInsightClient("", "") diff --git a/tests/test_models.py b/tests/test_models.py index 1f94387..29e7763 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -2,29 +2,33 @@ from codeinsight_sdk.models import Project, Report + class TestProject(object): @pytest.fixture def project(self): return Project(id=1, name="Test") - + def test_project(self, project): assert project.id == 1 assert project.name == "Test" assert isinstance(project, Project) - + + class TestReport(object): @pytest.fixture def report(self): - return Report(id=1, - name="Test", - path="path/to/report", - default=True, - enabled=True, - enableProjectPicker=True, - order=1, - createdDateTime="Today", - updatedDateTime="Tomorrow") - + return Report( + id=1, + name="Test", + path="path/to/report", + default=True, + enabled=True, + enableProjectPicker=True, + order=1, + createdDateTime="Today", + updatedDateTime="Tomorrow", + ) + def test_report(self, report): assert report.id == 1 assert report.enabled == True diff --git a/tests/test_not_implemented.py b/tests/test_not_implemented.py index b00177c..33960a5 100644 --- a/tests/test_not_implemented.py +++ b/tests/test_not_implemented.py @@ -2,21 +2,21 @@ from codeinsight_sdk import CodeInsightClient -class TestNotImplemented(object): +class TestNotImplemented(object): @pytest.fixture def client(self): - return CodeInsightClient("","") + return CodeInsightClient("", "") - ## Coming soon features ## + ## Coming soon features ## def test_vulnerabilities(self, client): with pytest.raises(NotImplementedError): client.vulnerabilites() - + def test_users(self, client): with pytest.raises(NotImplementedError): client.users() - + def test_licenses(self, client): with pytest.raises(NotImplementedError): client.licenses() @@ -35,4 +35,4 @@ def test_files(self, client): def test_folders(self, client): with pytest.raises(NotImplementedError): - client.folders() \ No newline at end of file + client.folders()