From e78652f8ee70e1ad48e0d376200c9d75a9fa2213 Mon Sep 17 00:00:00 2001 From: guptadev21 Date: Mon, 2 Dec 2024 14:48:00 +0530 Subject: [PATCH 01/13] =?UTF-8?q?=E2=9C=A8=20Feat:=20add=20async=20client?= =?UTF-8?q?=20and=20methods?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyproject.toml | 2 + rapyuta_io_sdk_v2/__init__.py | 1 + rapyuta_io_sdk_v2/async_client.py | 1448 +++++++++++++++++++++++++++++ rapyuta_io_sdk_v2/client.py | 26 +- uv.lock | 28 + 5 files changed, 1503 insertions(+), 2 deletions(-) create mode 100644 rapyuta_io_sdk_v2/async_client.py diff --git a/pyproject.toml b/pyproject.toml index abc7c84..44d4fa2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,4 +37,6 @@ dev = [ "anyio>=4.5.2", "asyncer>=0.0.8", "typing-extensions>=4.12.2", + "pytest-asyncio>=0.24.0", + "asyncmock>=0.4.2", ] diff --git a/rapyuta_io_sdk_v2/__init__.py b/rapyuta_io_sdk_v2/__init__.py index c53ba64..5a73f74 100644 --- a/rapyuta_io_sdk_v2/__init__.py +++ b/rapyuta_io_sdk_v2/__init__.py @@ -2,5 +2,6 @@ from rapyuta_io_sdk_v2.client import Client from rapyuta_io_sdk_v2.config import Configuration from rapyuta_io_sdk_v2.utils import walk_pages +from rapyuta_io_sdk_v2.async_client import AsyncClient __version__ = "0.0.1" diff --git a/rapyuta_io_sdk_v2/async_client.py b/rapyuta_io_sdk_v2/async_client.py new file mode 100644 index 0000000..599c6e7 --- /dev/null +++ b/rapyuta_io_sdk_v2/async_client.py @@ -0,0 +1,1448 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Rapyuta Robotics +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import platform + +import httpx +from munch import Munch + +from rapyuta_io_sdk_v2.config import Configuration +from rapyuta_io_sdk_v2.utils import handle_and_munchify_response, handle_server_errors + + +class AsyncClient(object): + """AsyncClient class for the SDK.""" + + def __init__(self, config=None, **kwargs): + self.config = config or Configuration() + timeout = kwargs.get("timeout", 10) + self.c = httpx.AsyncClient( + timeout=timeout, + limits=httpx.Limits( + max_keepalive_connections=5, + max_connections=5, + keepalive_expiry=30, + ), + headers={ + "User-Agent": ( + "rio-sdk-v2;N/A;{};{};{} {}".format( + platform.processor() or platform.machine(), + platform.system(), + platform.release(), + platform.version(), + ) + ) + }, + ) + self.sync_client = httpx.Client( + timeout=timeout, + limits=httpx.Limits( + max_keepalive_connections=5, + max_connections=5, + keepalive_expiry=30, + ), + headers={ + "User-Agent": ( + "rio-sdk-v2;N/A;{};{};{} {}".format( + platform.processor() or platform.machine(), + platform.system(), + platform.release(), + platform.version(), + ) + ) + }, + ) + self.rip_host = self.config.hosts.get("rip_host") + self.v2api_host = self.config.hosts.get("v2api_host") + + def get_auth_token(self, email: str, password: str) -> str: + """Get the authentication token for the user. + + Args: + email (str) + password (str) + + Returns: + str: authentication token + """ + response = self.sync_client.post( + url=f"{self.rip_host}/user/login", + headers={"Content-Type": "application/json"}, + json={ + "email": email, + "password": password, + }, + ) + handle_server_errors(response) + return response.json()["data"].get("token") + + def login( + self, + email: str, + password: str, + ) -> None: + """Get the authentication token for the user. + + Args: + email (str) + password (str) + environment (str) + + Returns: + str: authentication token + """ + + token = self.get_auth_token(email, password) + self.config.auth_token = token + + @handle_and_munchify_response + def logout(self, token: str = None) -> Munch: + """Expire the authentication token. + + Args: + token (str): The token to expire. + """ + + if token is None: + token = self.config.auth_token + + return self.sync_client.post( + url=f"{self.rip_host}/user/logout", + headers={ + "Content-Type": "application/json", + "Authorization": f"Bearer {token}", + }, + ) + + async def refresh_token(self, token: str = None, set_token: bool = True) -> str: + """Refresh the authentication token. + + Args: + token (str): The token to refresh. + set_token (bool): Set the refreshed token in the configuration. + + Returns: + str: The refreshed token. + """ + + if token is None: + token = self.config.auth_token + + response = await self.c.post( + url=f"{self.rip_host}/refreshtoken", + headers={"Content-Type": "application/json"}, + json={"token": token}, + ) + handle_server_errors(response) + if set_token: + self.config.auth_token = response.json()["data"].get("token") + return response.json()["data"].get("token") + + def set_organization(self, organization_guid: str) -> None: + """Set the organization GUID. + + Args: + organization_guid (str): Organization GUID + """ + self.config.set_organization(organization_guid) + + def set_project(self, project_guid: str) -> None: + """Set the project GUID. + + Args: + project_guid (str): Project GUID + """ + self.config.set_project(project_guid) + + # ----------------- Projects ----------------- + @handle_and_munchify_response + async def list_projects( + self, + cont: int = 0, + limit: int = 50, + label_selector: list[str] = None, + status: list[str] = None, + organizations: list[str] = None, + **kwargs, + ) -> Munch: + """List all projects in an organization. + + Args: + cont (int, optional): Start index of projects. Defaults to 0. + limit (int, optional): Number of projects to list. Defaults to 50. + label_selector (list[str], optional): Define labelSelector to get projects from. Defaults to None. + status (list[str], optional): Define status to get projects from. Defaults to None. + organizations (list[str], optional): Define organizations to get projects from. Defaults to None. + + Returns: + Munch: List of projects as a Munch object. + """ + + return await self.c.get( + url=f"{self.v2api_host}/v2/projects/", + headers=self.config.get_headers(with_project=False, **kwargs), + params={ + "continue": cont, + "limit": limit, + "status": status, + "organizations": organizations, + "labelSelector": label_selector, + }, + ) + + @handle_and_munchify_response + async def get_project(self, project_guid: str = None, **kwargs) -> Munch: + """Get a project by its GUID. + + If no project or organization GUID is provided, + the async default project and organization GUIDs will + be picked from the current configuration. + + Args: + project_guid (str): user provided project GUID or config project GUID + + Raises: + ValueError: If organization_guid or project_guid is None + + Returns: + Munch: Project details as a Munch object. + """ + if project_guid is None: + project_guid = self.config.project_guid + + if not project_guid: + raise ValueError("project_guid is required") + + return await self.c.get( + url=f"{self.v2api_host}/v2/projects/{project_guid}/", + headers=self.config.get_headers(with_project=False, **kwargs), + ) + + @handle_and_munchify_response + async def create_project(self, body: dict, **kwargs) -> Munch: + """Create a new project. + + Args: + body (object): Project details + + Returns: + Munch: Project details as a Munch object. + """ + + return await self.c.post( + url=f"{self.v2api_host}/v2/projects/", + headers=self.config.get_headers(with_project=False, **kwargs), + json=body, + ) + + @handle_and_munchify_response + async def update_project( + self, body: dict, project_guid: str = None, **kwargs + ) -> Munch: + """Update a project by its GUID. + + Returns: + Munch: Project details as a Munch object. + """ + + return await self.c.put( + url=f"{self.v2api_host}/v2/projects/{project_guid}/", + headers=self.config.get_headers(with_project=False, **kwargs), + json=body, + ) + + @handle_and_munchify_response + async def delete_project(self, project_guid: str, **kwargs) -> Munch: + """Delete a project by its GUID. + + Args: + project_guid (str): Project GUID + + Returns: + Munch: Project details as a Munch object. + """ + + return await self.c.delete( + url=f"{self.v2api_host}/v2/projects/{project_guid}/", + headers=self.config.get_headers(with_project=False, **kwargs), + ) + + @handle_and_munchify_response + async def update_project_owner( + self, body: dict, project_guid: str = None, **kwargs + ) -> Munch: + """Update the owner of a project by its GUID. + + Returns: + Munch: Project details as a Munch object. + """ + project_guid = project_guid or self.config.project_guid + + return await self.c.put( + url=f"{self.v2api_host}/v2/projects/{project_guid}/owner/", + headers=self.config.get_headers(**kwargs), + json=body, + ) + + # -------------------Package------------------- + @handle_and_munchify_response + async def list_packages( + self, + cont: int = 0, + limit: int = 50, + label_selector: list[str] = None, + name: str = None, + regions: list[str] = None, + **kwargs, + ) -> Munch: + """List all packages in a project. + + Args: + cont (int, optional): Start index of packages. Defaults to 0. + limit (int, optional): Number of packages to list. Defaults to 50. + label_selector (list[str], optional): Define labelSelector to get packages from. Defaults to None. + name (str, optional): Define name to get packages from. Defaults to None. + regions (list[str], optional): Define regions to get packages from. Defaults to None. + + Returns: + Munch: List of packages as a Munch object. + """ + + return await self.c.get( + url=f"{self.v2api_host}/v2/packages/", + headers=self.config.get_headers(**kwargs), + params={ + "continue": cont, + "limit": limit, + "labelSelector": label_selector, + "name": name, + "regions": regions, + }, + ) + + @handle_and_munchify_response + async def create_package(self, body: dict, **kwargs) -> Munch: + """Create a new package. + + The Payload is the JSON format of the Package Manifest. + For a documented example, run the rio explain package command. + + Returns: + Munch: Package details as a Munch object. + """ + + return await self.c.post( + url=f"{self.v2api_host}/v2/packages/", + headers=self.config.get_headers(**kwargs), + json=body, + ) + + @handle_and_munchify_response + async def get_package( + self, name: str, project_guid: str = None, version: str = None, **kwargs + ) -> Munch: + """Get a package by its name. + + Args: + name (str): Package name + project_guid (str, optional): Project GUID. Defaults to None. + version (str, optional): Package version. Defaults to None. + + Returns: + Munch: Package details as a Munch object. + """ + + return await self.c.get( + url=f"{self.v2api_host}/v2/packages/{name}/", + headers=self.config.get_headers(project_guid=project_guid, **kwargs), + params={"version": version}, + ) + + @handle_and_munchify_response + async def delete_package(self, name: str, **kwargs) -> Munch: + """Delete a package by its name. + + Args: + name (str): Package name + + Returns: + Munch: Package details as a Munch object. + """ + + return await self.c.delete( + url=f"{self.v2api_host}/v2/packages/{name}/", + headers=self.config.get_headers(**kwargs), + ) + + # -------------------Deployment------------------- + @handle_and_munchify_response + async def list_deployments( + self, + cont: int = 0, + dependencies: bool = False, + deviceName: str = None, + guids: list[str] = None, + label_selector: list[str] = None, + limit: int = 50, + name: str = None, + names: list[str] = None, + packageName: str = None, + packageVersion: str = None, + phases: list[str] = None, + regions: list[str] = None, + **kwargs, + ) -> Munch: + """List all deployments in a project. + + Args: + cont (int, optional): Start index of deployments. Defaults to 0. + dependencies (bool, optional): Filter by dependencies. Defaults to False. + deviceName (str, optional): Filter deployments by device name. Defaults to None. + guids (list[str], optional): Filter by GUIDs. Defaults to None. + label_selector (list[str], optional): Define labelSelector to get deployments from. Defaults to None. + limit (int, optional): Number of deployments to list. Defaults to 50. + name (str, optional): Define name to get deployments from. Defaults to None. + names (list[str], optional): Define names to get deployments from. Defaults to None. + packageName (str, optional): Filter by package name. Defaults to None. + packageVersion (str, optional): Filter by package version. Defaults to None. + phases (list[str], optional): Filter by phases. Available values : InProgress, Provisioning, Succeeded, FailedToUpdate, FailedToStart, Stopped. Defaults to None. + regions (list[str], optional): Filter by regions. Defaults to None. + + Returns: + Munch: List of deployments as a Munch object. + """ + + return await self.c.get( + url=f"{self.v2api_host}/v2/deployments/", + headers=self.config.get_headers(**kwargs), + params={ + "continue": cont, + "limit": limit, + "dependencies": dependencies, + "deviceName": deviceName, + "guids": guids, + "labelSelector": label_selector, + "name": name, + "names": names, + "packageName": packageName, + "packageVersion": packageVersion, + "phases": phases, + "regions": regions, + }, + ) + + @handle_and_munchify_response + async def create_deployment(self, body: dict, **kwargs) -> Munch: + """Create a new deployment. + + Args: + body (object): Deployment details + + Returns: + Munch: Deployment details as a Munch object. + """ + + return await self.c.post( + url=f"{self.v2api_host}/v2/deployments/", + headers=self.config.get_headers(**kwargs), + json=body, + ) + + @handle_and_munchify_response + async def get_deployment(self, name: str, **kwargs) -> Munch: + """Get a deployment by its name. + + Returns: + Munch: Deployment details as a Munch object. + """ + + return await self.c.get( + url=f"{self.v2api_host}/v2/deployments/{name}/", + headers=self.config.get_headers(**kwargs), + ) + + @handle_and_munchify_response + async def update_deployment(self, name: str, body: dict, **kwargs) -> Munch: + """Update a deployment by its name. + + Returns: + Munch: Deployment details as a Munch object. + """ + + return await self.c.put( + url=f"{self.v2api_host}/v2/deployments/{name}/", + headers=self.config.get_headers(**kwargs), + json=body, + ) + + @handle_and_munchify_response + async def delete_deployment(self, name: str, **kwargs) -> Munch: + """Delete a deployment by its name. + + Returns: + Munch: Deployment details as a Munch object. + """ + + return await self.c.delete( + url=f"{self.v2api_host}/v2/deployments/{name}/", + headers=self.config.get_headers(**kwargs), + ) + + @handle_and_munchify_response + async def get_deployment_graph(self, name: str, **kwargs) -> Munch: + """Get a deployment graph by its name. [Experimental] + + Returns: + Munch: Deployment graph as a Munch object. + """ + + return await self.c.get( + url=f"{self.v2api_host}/v2/deployments/{name}/graph/", + headers=self.config.get_headers(**kwargs), + ) + + @handle_and_munchify_response + async def get_deployment_history( + self, name: str, guid: str = None, **kwargs + ) -> Munch: + """Get a deployment history by its name. + + Returns: + Munch: Deployment history as a Munch object. + """ + + return await self.c.get( + url=f"{self.v2api_host}/v2/deployments/{name}/history/", + headers=self.config.get_headers(**kwargs), + params={"guid": guid}, + ) + + # -------------------Disks------------------- + @handle_and_munchify_response + async def list_disks( + self, + cont: int = 0, + label_selector: list[str] = None, + limit: int = 50, + name: str = None, + names: list[str] = None, + regions: list[str] = None, + status: list[str] = None, + **kwargs, + ) -> Munch: + """List all disks in a project. + + Args: + cont (int, optional): Start index of disks. Defaults to 0. + label_selector (list[str], optional): Define labelSelector to get disks from. Defaults to None. + limit (int, optional): Number of disks to list. Defaults to 50. + name (str, optional): Define name to get disks from. Defaults to None. + names (list[str], optional): Define names to get disks from. Defaults to None. + regions (list[str], optional): Define regions to get disks from. Defaults to None. + status (list[str], optional): Define status to get disks from. Available values : Available, Bound, Released, Failed, Pending.Defaults to None. + + + Returns: + Munch: List of disks as a Munch object. + """ + + return await self.c.get( + url=f"{self.v2api_host}/v2/disks/", + headers=self.config.get_headers(**kwargs), + params={ + "continue": cont, + "limit": limit, + "labelSelector": label_selector, + "name": name, + "names": names, + "regions": regions, + "status": status, + }, + ) + + @handle_and_munchify_response + async def get_disk(self, name: str, **kwargs) -> Munch: + """Get a disk by its name. + + Args: + name (str): Disk name + + Returns: + Munch: Disk details as a Munch object. + """ + + return await self.c.get( + url=f"{self.v2api_host}/v2/disks/{name}/", + headers=self.config.get_headers(**kwargs), + ) + + @handle_and_munchify_response + async def create_disk(self, body: str, **kwargs) -> Munch: + """Create a new disk. + + Returns: + Munch: Disk details as a Munch object. + """ + + return await self.c.post( + url=f"{self.v2api_host}/v2/disks/", + headers=self.config.get_headers(**kwargs), + json=body, + ) + + @handle_and_munchify_response + async def delete_disk(self, name: str, **kwargs) -> Munch: + """Delete a disk by its name. + + Args: + name (str): Disk name + + Returns: + Munch: Disk details as a Munch object. + """ + + return await self.c.delete( + url=f"{self.v2api_host}/v2/disks/{name}/", + headers=self.config.get_headers(**kwargs), + ) + + # -------------------Static Routes------------------- + @handle_and_munchify_response + async def list_staticroutes( + self, + cont: int = 0, + guids: list[str] = None, + label_selector: list[str] = None, + limit: int = 50, + name: str = None, + names: list[str] = None, + regions: list[str] = None, + **kwargs, + ) -> Munch: + """List all static routes in a project. + + Args: + cont (int, optional): Start index of static routes. Defaults to 0. + guids (list[str], optional): Define guids to get static routes from. Defaults to None. + label_selector (list[str], optional): Define labelSelector to get static routes from. Defaults to None. + limit (int, optional): Number of static routes to list. Defaults to 50. + name (str, optional): Define name to get static routes from. Defaults to None. + names (list[str], optional): Define names to get static routes from. Defaults to None. + regions (list[str], optional): Define regions to get static routes from. Defaults to None. + + Returns: + Munch: List of static routes as a Munch object. + """ + + return await self.c.get( + url=f"{self.v2api_host}/v2/staticroutes/", + headers=self.config.get_headers(**kwargs), + params={ + "continue": cont, + "limit": limit, + "guids": guids, + "labelSelector": label_selector, + "name": name, + "names": names, + "regions": regions, + }, + ) + + @handle_and_munchify_response + async def create_staticroute(self, body: dict, **kwargs) -> Munch: + """Create a new static route. + + Returns: + Munch: Static route details as a Munch object. + """ + + return await self.c.post( + url=f"{self.v2api_host}/v2/staticroutes/", + headers=self.config.get_headers(**kwargs), + json=body, + ) + + @handle_and_munchify_response + async def get_staticroute(self, name: str, **kwargs) -> Munch: + """Get a static route by its name. + + Args: + name (str): Static route name + + Returns: + Munch: Static route details as a Munch object. + """ + + return await self.c.get( + url=f"{self.v2api_host}/v2/staticroutes/{name}/", + headers=self.config.get_headers(**kwargs), + ) + + @handle_and_munchify_response + async def update_staticroute(self, name: str, body: dict, **kwargs) -> Munch: + """Update a static route by its name. + + Args: + name (str): Static route name + body (dict): Update details + + Returns: + Munch: Static route details as a Munch object. + """ + + return await self.c.put( + url=f"{self.v2api_host}/v2/staticroutes/{name}/", + headers=self.config.get_headers(**kwargs), + json=body, + ) + + @handle_and_munchify_response + async def delete_staticroute(self, name: str, **kwargs) -> Munch: + """Delete a static route by its name. + + Args: + name (str): Static route name + + Returns: + Munch: Static route details as a Munch object. + """ + + return await self.c.delete( + url=f"{self.v2api_host}/v2/staticroutes/{name}/", + headers=self.config.get_headers(**kwargs), + ) + + # -------------------Networks------------------- + @handle_and_munchify_response + async def list_networks( + self, + cont: int = 0, + deviceName: str = None, + label_selector: list[str] = None, + limit: int = 50, + name: str = None, + names: list[str] = None, + networkType: str = None, + phases: list[str] = None, + regions: list[str] = None, + status: list[str] = None, + **kwargs, + ) -> Munch: + """List all networks in a project. + + Args: + cont (int, optional): Start index of networks. Defaults to 0. + deviceName (str, optional): Filter networks by device name. Defaults to None. + label_selector (list[str], optional): Define labelSelector to get networks from. Defaults to None. + limit (int, optional): Number of networks to list. Defaults to 50. + name (str, optional): Define name to get networks from. Defaults to None. + names (list[str], optional): Define names to get networks from. Defaults to None. + networkType (str, optional): Define network type to get networks from. Defaults to None. + phases (list[str], optional): Define phases to get networks from. Available values : InProgress, Provisioning, Succeeded, FailedToUpdate, FailedToStart, Stopped. Defaults to None. + regions (list[str], optional): Define regions to get networks from. Defaults to None. + status (list[str], optional): Define status to get networks from. Available values : Running, Pending, Error, Unknown, Stopped. Defaults to None. + + Returns: + Munch: List of networks as a Munch object. + """ + + return await self.c.get( + url=f"{self.v2api_host}/v2/networks/", + headers=self.config.get_headers(**kwargs), + params={ + "continue": cont, + "limit": limit, + "deviceName": deviceName, + "labelSelector": label_selector, + "name": name, + "names": names, + "networkType": networkType, + "phases": phases, + "regions": regions, + "status": status, + }, + ) + + @handle_and_munchify_response + async def create_network(self, body: dict, **kwargs) -> Munch: + """Create a new network. + + Returns: + Munch: Network details as a Munch object. + """ + + return await self.c.post( + url=f"{self.v2api_host}/v2/networks/", + headers=self.config.get_headers(**kwargs), + json=body, + ) + + @handle_and_munchify_response + async def get_network(self, name: str, **kwargs) -> Munch: + """Get a network by its name. + + Args: + name (str): Network name + + Returns: + Munch: Network details as a Munch object. + """ + + return await self.c.get( + url=f"{self.v2api_host}/v2/networks/{name}/", + headers=self.config.get_headers(**kwargs), + ) + + @handle_and_munchify_response + async def delete_network(self, name: str, **kwargs) -> Munch: + """Delete a network by its name. + + Args: + name (str): Network name + + Returns: + Munch: Network details as a Munch object. + """ + + return await self.c.delete( + url=f"{self.v2api_host}/v2/networks/{name}/", + headers=self.config.get_headers(**kwargs), + ) + + # -------------------Secrets------------------- + @handle_and_munchify_response + async def list_secrets( + self, + cont: int = 0, + label_selector: list[str] = None, + limit: int = 50, + name: str = None, + names: list[str] = None, + regions: list[str] = None, + **kwargs, + ) -> Munch: + """List all secrets in a project. + + Args: + cont (int, optional): Start index of secrets. Defaults to 0. + label_selector (list[str], optional): Define labelSelector to get secrets from. Defaults to None. + limit (int, optional): Number of secrets to list. Defaults to 50. + name (str, optional): Define name to get secrets from. Defaults to None. + names (list[str], optional): Define names to get secrets from. Defaults to None. + regions (list[str], optional): Define regions to get secrets from. Defaults to None. + + Returns: + Munch: List of secrets as a Munch object. + """ + + return await self.c.get( + url=f"{self.v2api_host}/v2/secrets/", + headers=self.config.get_headers(**kwargs), + params={ + "continue": cont, + "limit": limit, + "labelSelector": label_selector, + "name": name, + "names": names, + "regions": regions, + }, + ) + + @handle_and_munchify_response + async def create_secret(self, body: dict, **kwargs) -> Munch: + """Create a new secret. + + Returns: + Munch: Secret details as a Munch object. + """ + + return await self.c.post( + url=f"{self.v2api_host}/v2/secrets/", + headers=self.config.get_headers(*kwargs), + json=body, + ) + + @handle_and_munchify_response + async def get_secret(self, name: str, **kwargs) -> Munch: + """Get a secret by its name. + + Args: + name (str): Secret name + + Returns: + Munch: Secret details as a Munch object. + """ + + return await self.c.get( + url=f"{self.v2api_host}/v2/secrets/{name}/", + headers=self.config.get_headers(**kwargs), + ) + + @handle_and_munchify_response + async def update_secret(self, name: str, body: dict, **kwargs) -> Munch: + """Update a secret by its name. + + Args: + name (str): Secret name + body (dict): Update details + + Returns: + Munch: Secret details as a Munch object. + """ + + return await self.c.put( + url=f"{self.v2api_host}/v2/secrets/{name}/", + headers=self.config.get_headers(**kwargs), + json=body, + ) + + @handle_and_munchify_response + async def delete_secret(self, name: str, **kwargs) -> Munch: + """Delete a secret by its name. + + Args: + name (str): Secret name + + Returns: + Munch: Secret details as a Munch object. + """ + + return await self.c.delete( + url=f"{self.v2api_host}/v2/secrets/{name}/", + headers=self.config.get_headers(**kwargs), + ) + + # -------------------Config Trees------------------- + @handle_and_munchify_response + async def list_configtrees( + self, + cont: int = 0, + label_selector: list[str] = None, + limit: int = 50, + name: str = None, + regions: list[str] = None, + **kwargs, + ) -> Munch: + """List all config trees in a project. + + Args: + cont (int, optional): Start index of config trees. Defaults to 0. + label_selector (list[str], optional): Define labelSelector to get config trees from. Defaults to None. + limit (int, optional): Number of config trees to list. Defaults to 50. + name (str, optional): Define name to get config trees from. Defaults to None. + regions (list[str], optional): Define regions to get config trees from. Defaults to None. + + Returns: + Munch: List of config trees as a Munch object. + """ + + return await self.c.get( + url=f"{self.v2api_host}/v2/configtrees/", + headers=self.config.get_headers(**kwargs), + params={ + "continue": cont, + "limit": limit, + "labelSelector": label_selector, + "name": name, + "regions": regions, + }, + ) + + @handle_and_munchify_response + async def create_configtree(self, body: dict, **kwargs) -> Munch: + """Create a new config tree. + + Args: + body (object): Config tree details + + Returns: + Munch: Config tree details as a Munch object. + """ + + return await self.c.post( + url=f"{self.v2api_host}/v2/configtrees/", + headers=self.config.get_headers(**kwargs), + json=body, + ) + + @handle_and_munchify_response + async def get_configtree( + self, + name: str, + contentTypes: list[str] = None, + includeData: bool = False, + keyPrefixes: list[str] = None, + revision: str = None, + **kwargs, + ) -> Munch: + """Get a config tree by its name. + + Args: + name (str): Config tree name + contentTypes (list[str], optional): Define contentTypes to get config tree from. Defaults to None. + includeData (bool, optional): Include data. Defaults to False. + keyPrefixes (list[str], optional): Define keyPrefixes to get config tree from. Defaults to None. + revision (str, optional): Define revision to get config tree from. Defaults to None. + + Returns: + Munch: Config tree details as a Munch object. + """ + + return await self.c.get( + url=f"{self.v2api_host}/v2/configtrees/{name}/", + headers=self.config.get_headers(**kwargs), + params={ + "contentTypes": contentTypes, + "includeData": includeData, + "keyPrefixes": keyPrefixes, + "revision": revision, + }, + ) + + @handle_and_munchify_response + async def set_configtree_revision( + self, name: str, configtree: object, project_guid: str = None, **kwargs + ) -> Munch: + """Set a config tree revision. + + Args: + name (str): Config tree name + configtree (object): Config tree details + project_guid (str, optional): Project GUID. async defaults to None. + + Returns: + Munch: Config tree details as a Munch object. + """ + + return await self.c.put( + url=f"{self.v2api_host}/v2/configtrees/{name}/", + headers=self.config.get_headers(project_guid=project_guid, **kwargs), + json=configtree, + ) + + @handle_and_munchify_response + async def update_configtree(self, name: str, body: dict, **kwargs) -> Munch: + """Update a config tree by its name. + + Args: + name (str): Config tree name + body (dict): Update details + + Returns: + Munch: Config tree details as a Munch object. + """ + + return await self.c.put( + url=f"{self.v2api_host}/v2/configtrees/{name}/", + headers=self.config.get_headers(**kwargs), + json=body, + ) + + @handle_and_munchify_response + async def delete_configtree(self, name: str, **kwargs) -> Munch: + """Delete a config tree by its name. + + Args: + name (str): Config tree name + + Returns: + Munch: Config tree details as a Munch object. + """ + + return await self.c.delete( + url=f"{self.v2api_host}/v2/configtrees/{name}/", + headers=self.config.get_headers(**kwargs), + ) + + @handle_and_munchify_response + async def list_revisions( + self, + name: str, + cont: int = 0, + limit: int = 50, + committed: bool = False, + label_selector: list[str] = None, + regions: list[str] = None, + **kwargs, + ) -> Munch: + """List all revisions of a config tree. + + Args: + name (str): Config tree name + cont (int, optional): Continue param . Defaults to 0. + limit (int, optional): Limit param . Defaults to 50. + committed (bool, optional): Committed. Defaults to False. + label_selector (list[str], optional): Define labelSelector to get revisions from. Defaults to None. + regions (list[str], optional): Define regions to get revisions from. Defaults to None. + + Returns: + Munch: List of revisions as a Munch object. + """ + + return await self.c.get( + url=f"{self.v2api_host}/v2/configtrees/{name}/revisions/", + headers=self.config.get_headers(**kwargs), + params={ + "continue": cont, + "limit": limit, + "committed": committed, + "labelSelector": label_selector, + "regions": regions, + }, + ) + + @handle_and_munchify_response + async def create_revision( + self, name: str, body: dict, project_guid: str = None, **kwargs + ) -> Munch: + """Create a new revision. + + Args: + name (str): Config tree name + body (object): Revision details + project_guid (str): Project GUID (optional) + + Returns: + Munch: Revision details as a Munch object. + """ + + return await self.c.post( + url=f"{self.v2api_host}/v2/configtrees/{name}/revisions/", + headers=self.config.get_headers(project_guid=project_guid, **kwargs), + json=body, + ) + + @handle_and_munchify_response + async def put_keys_in_revision( + self, name: str, revision_id: str, configValues: list[dict], **kwargs + ) -> Munch: + """Put keys in a revision. + + Args: + name (str): Config tree name + revision_id (str): Config tree revision ID + configValues (list[dict]): Config values + + Returns: + Munch: Revision details as a Munch object. + """ + + return await self.c.put( + url=f"{self.v2api_host}/v2/configtrees/{name}/revisions/{revision_id}/keys/", + headers=self.config.get_headers(**kwargs), + json=configValues, + ) + + @handle_and_munchify_response + async def commit_revision( + self, + name: str, + revision_id: str, + configTreeRevision: object, + project_guid: str = None, + **kwargs, + ) -> Munch: + """Commit a revision. + + Args: + name (str): Config tree name + revision_id (str): Config tree revision ID + configTreeRevision (object): Config tree revision details + project_guid (str, optional): Project GUID. Defaults to None. + + Returns: + Munch: Revision details as a Munch object. + """ + + return await self.c.patch( + url=f"{self.v2api_host}/v2/configtrees/{name}/revisions/{revision_id}/commit/", + headers=self.config.get_headers(project_guid=project_guid, **kwargs), + json=configTreeRevision, + ) + + @handle_and_munchify_response + async def get_key_in_revision( + self, name: str, revision_id: str, key: str, project_guid: str = None, **kwargs + ) -> Munch: + """Get a key in a revision. + + Args: + name (str): Config tree name + revision_id (str): Config tree revision ID + key (str): Key + project_guid (str, optional): Project GUID. async defaults to None. + + Returns: + Munch: Key details as a Munch object. + """ + + return await self.c.get( + url=f"{self.v2api_host}/v2/configtrees/{name}/revisions/{revision_id}/{key}/", + headers=self.config.get_headers(project_guid=project_guid, **kwargs), + ) + + @handle_and_munchify_response + async def put_key_in_revision( + self, name: str, revision_id: str, key: str, project_guid: str = None, **kwargs + ) -> Munch: + """Put a key in a revision. + + Args: + name (str): Config tree name + revision_id (str): Config tree revision ID + key (str): Key + project_guid (str, optional): Project GUID. async defaults to None. + + Returns: + Munch: Key details as a Munch object. + """ + + return await self.c.put( + url=f"{self.v2api_host}/v2/configtrees/{name}/revisions/{revision_id}/{key}/", + headers=self.config.get_headers(project_guid=project_guid, **kwargs), + ) + + @handle_and_munchify_response + async def delete_key_in_revision( + self, name: str, revision_id: str, key: str, project_guid: str = None, **kwargs + ) -> Munch: + """Delete a key in a revision. + + Args: + name (str): Config tree name + revision_id (str): Config tree revision ID + key (str): Key + project_guid (str, optional): Project GUID. async defaults to None. + + Returns: + Munch: Key details as a Munch object. + """ + + return await self.c.delete( + url=f"{self.v2api_host}/v2/configtrees/{name}/revisions/{revision_id}/{key}/", + headers=self.config.get_headers(project_guid=project_guid, **kwargs), + ) + + @handle_and_munchify_response + async def rename_key_in_revision( + self, + name: str, + revision_id: str, + key: str, + configKeyRename: object, + project_guid: str = None, + **kwargs, + ) -> Munch: + """Rename a key in a revision. + + Args: + name (str): Config tree name + revision_id (str): Config tree revision ID + key (str): Key + configKeyRename (object): Key rename details + project_guid (str, optional): Project GUID. async defaults to None. + + Returns: + Munch: Key details as a Munch object. + """ + + return await self.c.patch( + url=f"{self.v2api_host}/v2/configtrees/{name}/revisions/{revision_id}/{key}/", + headers=self.config.get_headers(project_guid=project_guid, **kwargs), + json=configKeyRename, + ) + + # Managed Service API + @handle_and_munchify_response + async def list_providers(self) -> Munch: + """List all providers. + + Returns: + Munch: List of providers as a Munch object. + """ + + return await self.c.get( + url=f"{self.v2api_host}/v2/managedservices/providers/", + headers=self.config.get_headers(with_project=False), + ) + + @handle_and_munchify_response + async def list_instances( + self, + cont: int = 0, + limit: int = 50, + label_selector: list[str] = None, + regions: list[str] = None, + guid: str = None, + name: str = None, + ): + """List all instances in a project. + + Args: + cont (int, optional): Start index of instances. Defaults to 0. + limit (int, optional): Number of instances to list. Defaults to 50. + label_selector (list[str], optional): Define labelSelector to get instances from. Defaults to None. + regions (list[str], optional): Define regions to get instances from. Defaults to None. + guid (str, optional): Defaults to None. + name (str, optional): Defaults to None. + + Returns: + Munch: List of instances as a Munch object. + """ + return await self.c.get( + url=f"{self.v2api_host}/v2/managedservices/", + headers=self.config.get_headers(), + params={ + "continue": cont, + "limit": limit, + "labelSelector": label_selector, + "regions": regions, + "guid": guid, + "name": name, + }, + ) + + @handle_and_munchify_response + async def get_instance(self, name: str) -> Munch: + """Get an instance by its name. + + Args: + name (str): Instance name + + Returns: + Munch: Instance details as a Munch object. + """ + + return await self.c.get( + url=f"{self.v2api_host}/v2/managedservices/{name}/", + headers=self.config.get_headers(), + ) + + @handle_and_munchify_response + async def create_instance(self, body: dict) -> Munch: + """Create a new instance. + + Returns: + Munch: Instance details as a Munch object. + """ + + return await self.c.post( + url=f"{self.v2api_host}/v2/managedservices/", + headers=self.config.get_headers(), + json=body, + ) + + @handle_and_munchify_response + async def delete_instance(self, name: str) -> Munch: + """Delete an instance. + + Returns: + Munch: Instance details as a Munch object. + """ + + return await self.c.delete( + url=f"{self.v2api_host}/v2/managedservices/{name}/", + headers=self.config.get_headers(), + ) + + @handle_and_munchify_response + async def list_instance_bindings( + self, + instance_name: str, + cont: int = 0, + limit: int = 50, + label_selector: list[str] = None, + regions: list[str] = None, + guid: str = None, + name: str = None, + ): + """List all instance bindings in a project. + + Args: + instance_name (str): Instance name. + cont (int, optional): Start index of instance bindings. Defaults to 0. + limit (int, optional): Number of instance bindings to list. Defaults to 50. + label_selector (list[str], optional): Define labelSelector to get instance bindings from. Defaults to None. + regions (list[str], optional): Define regions to get instance bindings from. Defaults to None. + guid (str, optional): Defaults to None. + name (str, optional): Defaults to None. + + Returns: + Munch: List of instance bindings as a Munch object. + """ + return await self.c.get( + url=f"{self.v2api_host}/v2/managedservices/{instance_name}/bindings/", + headers=self.config.get_headers(), + params={ + "continue": cont, + "limit": limit, + "labelSelector": label_selector, + "regions": regions, + "guid": guid, + "name": name, + }, + ) + + @handle_and_munchify_response + async def create_instance_binding(self, instance_name: str, body: dict) -> Munch: + """Create a new instance binding. + + Args: + instance_name (str): Instance name. + body (object): Instance binding details. + + Returns: + Munch: Instance binding details as a Munch object. + """ + + return await self.c.post( + url=f"{self.v2api_host}/v2/managedservices/{instance_name}/bindings/", + headers=self.config.get_headers(), + json=body, + ) + + @handle_and_munchify_response + async def get_instance_binding(self, instance_name: str, name: str) -> Munch: + """Get an instance binding by its name. + + Args: + instance_name (str): Instance name. + name (str): Instance binding name. + + Returns: + Munch: Instance binding details as a Munch object. + """ + + return await self.c.get( + url=f"{self.v2api_host}/v2/managedservices/{instance_name}/bindings/{name}/", + headers=self.config.get_headers(), + ) + + @handle_and_munchify_response + async def delete_instance_binding(self, instance_name: str, name: str) -> Munch: + """Delete an instance binding. + + Args: + instance_name (str): Instance name. + name (str): Instance binding name. + + Returns: + Munch: Instance binding details as a Munch object. + """ + + return await self.c.delete( + url=f"{self.v2api_host}/v2/managedservices/{instance_name}/bindings/{name}/", + headers=self.config.get_headers(), + ) diff --git a/rapyuta_io_sdk_v2/client.py b/rapyuta_io_sdk_v2/client.py index bf9b5dd..611f544 100644 --- a/rapyuta_io_sdk_v2/client.py +++ b/rapyuta_io_sdk_v2/client.py @@ -112,11 +112,12 @@ def logout(self, token: str = None) -> Munch: }, ) - def refresh_token(self, token: str = None) -> str: + def refresh_token(self, token: str = None, set_token: bool = True) -> str: """Refresh the authentication token. Args: token (str): The token to refresh. + set_token (bool): Set the refreshed token in the configuration. Returns: str: The refreshed token. @@ -131,6 +132,8 @@ def refresh_token(self, token: str = None) -> str: json={"token": token}, ) handle_server_errors(response) + if set_token: + self.config.auth_token = response.json()["data"].get("token") return response.json()["data"].get("token") def set_organization(self, organization_guid: str) -> None: @@ -341,6 +344,11 @@ def get_package( ) -> Munch: """Get a package by its name. + Args: + name (str): Package name + project_guid (str, optional): Project GUID. Defaults to None. + version (str, optional): Package version. Defaults to None. + Returns: Munch: Package details as a Munch object. """ @@ -355,6 +363,9 @@ def get_package( def delete_package(self, name: str, **kwargs) -> Munch: """Delete a package by its name. + Args: + name (str): Package name + Returns: Munch: Package details as a Munch object. """ @@ -1102,10 +1113,15 @@ def create_revision( @handle_and_munchify_response def put_keys_in_revision( - self, name: str, revision_id: str, configValues: list[(object)], **kwargs + self, name: str, revision_id: str, configValues: list[(dict)], **kwargs ) -> Munch: """Put keys in a revision. + Args: + name (str): Config tree name + revision_id (str): Config tree revision ID + configValues (list[dict]): Config values + Returns: Munch: Revision details as a Munch object. """ @@ -1127,6 +1143,12 @@ def commit_revision( ) -> Munch: """Commit a revision. + Args: + name (str): Config tree name + revision_id (str): Config tree revision ID + configTreeRevision (object): Config tree revision details + project_guid (str, optional): Project GUID. Defaults to None. + Returns: Munch: Revision details as a Munch object. """ diff --git a/uv.lock b/uv.lock index ef9d636..2ee4075 100644 --- a/uv.lock +++ b/uv.lock @@ -29,6 +29,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8a/04/15b6ca6b7842eda2748bda0a0af73f2d054e9344320f8bba01f994294bcb/asyncer-0.0.8-py3-none-any.whl", hash = "sha256:5920d48fc99c8f8f0f1576e1882f5022885589c5fcbc46ce4224ec3e53776eeb", size = 9209 }, ] +[[package]] +name = "asyncmock" +version = "0.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mock" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c8/58/fa6b3147951a8d82cc78e628dffee0aa5838328c52ebfee4e0ddceb5d92b/asyncmock-0.4.2.tar.gz", hash = "sha256:c251889d542e98fe5f7ece2b5b8643b7d62b50a5657d34a4cbce8a1d5170d750", size = 3191 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/03/e3/873f433eca053c92d3cdb9336a379ee025bc1a86d4624ef87bf97a9ac7bc/asyncmock-0.4.2-py3-none-any.whl", hash = "sha256:fd8bc4e7813251a8959d1140924ccba3adbbc7af885dba7047c67f73c0b664b1", size = 4190 }, +] + [[package]] name = "certifi" version = "2024.8.30" @@ -249,6 +261,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/6b/77/7440a06a8ead44c7757a64362dd22df5760f9b12dc5f11b6188cd2fc27a0/pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2", size = 342341 }, ] +[[package]] +name = "pytest-asyncio" +version = "0.24.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/52/6d/c6cf50ce320cf8611df7a1254d86233b3df7cc07f9b5f5cbcb82e08aa534/pytest_asyncio-0.24.0.tar.gz", hash = "sha256:d081d828e576d85f875399194281e92bf8a68d60d72d1a2faf2feddb6c46b276", size = 49855 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/96/31/6607dab48616902f76885dfcf62c08d929796fc3b2d2318faf9fd54dbed9/pytest_asyncio-0.24.0-py3-none-any.whl", hash = "sha256:a811296ed596b69bf0b6f3dc40f83bcaf341b155a269052d82efa2b25ac7037b", size = 18024 }, +] + [[package]] name = "pytest-cov" version = "5.0.0" @@ -287,9 +311,11 @@ dependencies = [ dev = [ { name = "anyio" }, { name = "asyncer" }, + { name = "asyncmock" }, { name = "coverage" }, { name = "mock" }, { name = "pytest" }, + { name = "pytest-asyncio" }, { name = "pytest-cov" }, { name = "pytest-mock" }, { name = "typing-extensions" }, @@ -305,9 +331,11 @@ requires-dist = [ dev = [ { name = "anyio", specifier = ">=4.5.2" }, { name = "asyncer", specifier = ">=0.0.8" }, + { name = "asyncmock", specifier = ">=0.4.2" }, { name = "coverage", specifier = ">=7.6.1" }, { name = "mock", specifier = ">=5.1.0" }, { name = "pytest", specifier = ">=8.3.3" }, + { name = "pytest-asyncio", specifier = ">=0.24.0" }, { name = "pytest-cov", specifier = ">=5.0.0" }, { name = "pytest-mock", specifier = ">=3.14.0" }, { name = "typing-extensions", specifier = ">=4.12.2" }, From 3e84554372ec2159a624fbad5cfd656aa21fdffc Mon Sep 17 00:00:00 2001 From: guptadev21 Date: Mon, 2 Dec 2024 16:19:43 +0530 Subject: [PATCH 02/13] =?UTF-8?q?=E2=9C=A8=20feat:=20add=20async=20tests?= =?UTF-8?q?=20for=20project?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/async_tests/test_project.py | 99 +++++++++++++++++++ tests/{ => sync_tests}/test_config.py | 0 tests/{ => sync_tests}/test_configtree.py | 0 tests/{ => sync_tests}/test_deployment.py | 0 tests/{ => sync_tests}/test_disk.py | 0 tests/{ => sync_tests}/test_main.py | 0 tests/{ => sync_tests}/test_managedservice.py | 0 tests/{ => sync_tests}/test_network.py | 0 tests/{ => sync_tests}/test_package.py | 0 tests/{ => sync_tests}/test_project.py | 0 tests/{ => sync_tests}/test_secret.py | 0 tests/{ => sync_tests}/test_staticroute.py | 0 tests/utils/test_util.py | 12 ++- 13 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 tests/async_tests/test_project.py rename tests/{ => sync_tests}/test_config.py (100%) rename tests/{ => sync_tests}/test_configtree.py (100%) rename tests/{ => sync_tests}/test_deployment.py (100%) rename tests/{ => sync_tests}/test_disk.py (100%) rename tests/{ => sync_tests}/test_main.py (100%) rename tests/{ => sync_tests}/test_managedservice.py (100%) rename tests/{ => sync_tests}/test_network.py (100%) rename tests/{ => sync_tests}/test_package.py (100%) rename tests/{ => sync_tests}/test_project.py (100%) rename tests/{ => sync_tests}/test_secret.py (100%) rename tests/{ => sync_tests}/test_staticroute.py (100%) diff --git a/tests/async_tests/test_project.py b/tests/async_tests/test_project.py new file mode 100644 index 0000000..b41b02f --- /dev/null +++ b/tests/async_tests/test_project.py @@ -0,0 +1,99 @@ +import pytest +import pytest_asyncio +import httpx +from munch import Munch +from asyncmock import AsyncMock + +from tests.utils.test_util import ( + async_client as client, # noqa: F401 + project_body, +) + + +@pytest.mark.asyncio +async def test_list_projects_success(client, mocker: AsyncMock): # noqa: F811 + mock_get = mocker.patch("httpx.AsyncClient.get") + + mock_get.return_value = httpx.Response( + status_code=200, + json={ + "metadata": {"continue": 1}, + "items": [{"name": "test-project", "guid": "mock_project_guid"}], + }, + ) + + response = await client.list_projects() + + assert isinstance(response, Munch) + assert response["items"] == [{"name": "test-project", "guid": "mock_project_guid"}] + + +@pytest.mark.asyncio +async def test_create_project_success(client, mocker: AsyncMock): + mock_post = mocker.patch("httpx.AsyncClient.post") + + mock_post.return_value = httpx.Response( + status_code=200, + json={ + "kind": "Project", + "metadata": {"name": "test-project", "guid": "mock_project_guid"}, + "spec": { + "users": [ + {"userGUID": "mock_user_guid", "emailID": "test.user@example.com"} + ] + }, + }, + ) + + response = await client.create_project(project_body) + + assert isinstance(response, Munch) + assert response["metadata"]["guid"] == "mock_project_guid" + +@pytest.mark.asyncio +async def test_get_project_success(client, mocker: AsyncMock): + mock_get = mocker.patch("httpx.AsyncClient.get") + + mock_get.return_value = httpx.Response( + status_code=200, + json={ + "kind": "Project", + "metadata": {"name": "test-project", "guid": "mock_project_guid"}, + } + ) + + response = await client.get_project("mock_project_guid") + + assert isinstance(response, Munch) + assert response["metadata"]["guid"] == "mock_project_guid" + +@pytest.mark.asyncio +async def test_update_project_success(client, mocker: AsyncMock): + mock_put = mocker.patch("httpx.AsyncClient.put") + + mock_put.return_value = httpx.Response( + status_code=200, + json={ + "kind": "Project", + "metadata": {"name": "test-project", "guid": "mock_project_guid"}, + } + ) + + response = await client.update_project("mock_project_guid", project_body) + + assert isinstance(response, Munch) + assert response["metadata"]["guid"] == "mock_project_guid" + +@pytest.mark.asyncio +async def test_delete_project_success(client, mocker: AsyncMock): + mock_delete = mocker.patch("httpx.AsyncClient.delete") + + mock_delete.return_value = httpx.Response( + status_code=200, + json={"success": True} + ) + + response = await client.delete_project("mock_project_guid") + + assert isinstance(response, Munch) + assert response["success"] is True diff --git a/tests/test_config.py b/tests/sync_tests/test_config.py similarity index 100% rename from tests/test_config.py rename to tests/sync_tests/test_config.py diff --git a/tests/test_configtree.py b/tests/sync_tests/test_configtree.py similarity index 100% rename from tests/test_configtree.py rename to tests/sync_tests/test_configtree.py diff --git a/tests/test_deployment.py b/tests/sync_tests/test_deployment.py similarity index 100% rename from tests/test_deployment.py rename to tests/sync_tests/test_deployment.py diff --git a/tests/test_disk.py b/tests/sync_tests/test_disk.py similarity index 100% rename from tests/test_disk.py rename to tests/sync_tests/test_disk.py diff --git a/tests/test_main.py b/tests/sync_tests/test_main.py similarity index 100% rename from tests/test_main.py rename to tests/sync_tests/test_main.py diff --git a/tests/test_managedservice.py b/tests/sync_tests/test_managedservice.py similarity index 100% rename from tests/test_managedservice.py rename to tests/sync_tests/test_managedservice.py diff --git a/tests/test_network.py b/tests/sync_tests/test_network.py similarity index 100% rename from tests/test_network.py rename to tests/sync_tests/test_network.py diff --git a/tests/test_package.py b/tests/sync_tests/test_package.py similarity index 100% rename from tests/test_package.py rename to tests/sync_tests/test_package.py diff --git a/tests/test_project.py b/tests/sync_tests/test_project.py similarity index 100% rename from tests/test_project.py rename to tests/sync_tests/test_project.py diff --git a/tests/test_secret.py b/tests/sync_tests/test_secret.py similarity index 100% rename from tests/test_secret.py rename to tests/sync_tests/test_secret.py diff --git a/tests/test_staticroute.py b/tests/sync_tests/test_staticroute.py similarity index 100% rename from tests/test_staticroute.py rename to tests/sync_tests/test_staticroute.py diff --git a/tests/utils/test_util.py b/tests/utils/test_util.py index a18174d..2109849 100644 --- a/tests/utils/test_util.py +++ b/tests/utils/test_util.py @@ -1,6 +1,6 @@ import pytest -from rapyuta_io_sdk_v2 import Client, Configuration +from rapyuta_io_sdk_v2 import Client, Configuration, AsyncClient # Fixture to initialize the Client @@ -14,6 +14,16 @@ def client(): return client +@pytest.fixture +def async_client(): + client = AsyncClient() + client.config.hosts["v2api_host"] = "https://mock-api.rapyuta.io" + client.auth_token = "mock_token" + client.organization_guid = "mock_org_guid" + client.project = "mock_project_guid" + return client + + @pytest.fixture def mock_response_project(): return { From ca0d35885d7c053a882d6fc717f3b14b65611532 Mon Sep 17 00:00:00 2001 From: guptadev21 Date: Mon, 2 Dec 2024 16:25:08 +0530 Subject: [PATCH 03/13] =?UTF-8?q?=F0=9F=91=B7=20Chore:=20run=20unit=20test?= =?UTF-8?q?s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/quality-checks.yml | 3 ++- tests/async_tests/test_project.py | 40 ++++++++++++++-------------- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index 2eac29b..d8900cc 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -28,4 +28,5 @@ jobs: run: | uv sync --all-extras --dev source .venv/bin/activate - uv run pytest tests/ \ No newline at end of file + uv run pytest tests/sync_tests --cov + uv run pytest tests/async_tests --cov \ No newline at end of file diff --git a/tests/async_tests/test_project.py b/tests/async_tests/test_project.py index b41b02f..e405da0 100644 --- a/tests/async_tests/test_project.py +++ b/tests/async_tests/test_project.py @@ -1,5 +1,5 @@ import pytest -import pytest_asyncio +import pytest_asyncio # noqa: F401 import httpx from munch import Munch from asyncmock import AsyncMock @@ -29,7 +29,7 @@ async def test_list_projects_success(client, mocker: AsyncMock): # noqa: F811 @pytest.mark.asyncio -async def test_create_project_success(client, mocker: AsyncMock): +async def test_create_project_success(client, mocker: AsyncMock): # noqa: F811 mock_post = mocker.patch("httpx.AsyncClient.post") mock_post.return_value = httpx.Response( @@ -49,9 +49,10 @@ async def test_create_project_success(client, mocker: AsyncMock): assert isinstance(response, Munch) assert response["metadata"]["guid"] == "mock_project_guid" - + + @pytest.mark.asyncio -async def test_get_project_success(client, mocker: AsyncMock): +async def test_get_project_success(client, mocker: AsyncMock): # noqa: F811 mock_get = mocker.patch("httpx.AsyncClient.get") mock_get.return_value = httpx.Response( @@ -59,16 +60,17 @@ async def test_get_project_success(client, mocker: AsyncMock): json={ "kind": "Project", "metadata": {"name": "test-project", "guid": "mock_project_guid"}, - } + }, ) - + response = await client.get_project("mock_project_guid") - + assert isinstance(response, Munch) assert response["metadata"]["guid"] == "mock_project_guid" - + + @pytest.mark.asyncio -async def test_update_project_success(client, mocker: AsyncMock): +async def test_update_project_success(client, mocker: AsyncMock): # noqa: F811 mock_put = mocker.patch("httpx.AsyncClient.put") mock_put.return_value = httpx.Response( @@ -76,24 +78,22 @@ async def test_update_project_success(client, mocker: AsyncMock): json={ "kind": "Project", "metadata": {"name": "test-project", "guid": "mock_project_guid"}, - } + }, ) - + response = await client.update_project("mock_project_guid", project_body) - + assert isinstance(response, Munch) assert response["metadata"]["guid"] == "mock_project_guid" - + + @pytest.mark.asyncio -async def test_delete_project_success(client, mocker: AsyncMock): +async def test_delete_project_success(client, mocker: AsyncMock): # noqa: F811 mock_delete = mocker.patch("httpx.AsyncClient.delete") - mock_delete.return_value = httpx.Response( - status_code=200, - json={"success": True} - ) - + mock_delete.return_value = httpx.Response(status_code=200, json={"success": True}) + response = await client.delete_project("mock_project_guid") - + assert isinstance(response, Munch) assert response["success"] is True From 08895095ce5488838693076a0b0fe3c8c0527736 Mon Sep 17 00:00:00 2001 From: guptadev21 Date: Tue, 3 Dec 2024 11:35:42 +0530 Subject: [PATCH 04/13] chore: update --- rapyuta_io_sdk_v2/async_client.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/rapyuta_io_sdk_v2/async_client.py b/rapyuta_io_sdk_v2/async_client.py index 599c6e7..6093a05 100644 --- a/rapyuta_io_sdk_v2/async_client.py +++ b/rapyuta_io_sdk_v2/async_client.py @@ -1126,14 +1126,14 @@ async def create_revision( @handle_and_munchify_response async def put_keys_in_revision( - self, name: str, revision_id: str, configValues: list[dict], **kwargs + self, name: str, revision_id: str, config_values: list[dict], **kwargs ) -> Munch: """Put keys in a revision. Args: name (str): Config tree name revision_id (str): Config tree revision ID - configValues (list[dict]): Config values + config_values (list[dict]): Config values Returns: Munch: Revision details as a Munch object. @@ -1142,7 +1142,7 @@ async def put_keys_in_revision( return await self.c.put( url=f"{self.v2api_host}/v2/configtrees/{name}/revisions/{revision_id}/keys/", headers=self.config.get_headers(**kwargs), - json=configValues, + json=config_values, ) @handle_and_munchify_response @@ -1150,7 +1150,7 @@ async def commit_revision( self, name: str, revision_id: str, - configTreeRevision: object, + config_tree_revision: dict, project_guid: str = None, **kwargs, ) -> Munch: @@ -1159,7 +1159,7 @@ async def commit_revision( Args: name (str): Config tree name revision_id (str): Config tree revision ID - configTreeRevision (object): Config tree revision details + config_tree_revision (dict): Config tree revision details project_guid (str, optional): Project GUID. Defaults to None. Returns: @@ -1169,7 +1169,7 @@ async def commit_revision( return await self.c.patch( url=f"{self.v2api_host}/v2/configtrees/{name}/revisions/{revision_id}/commit/", headers=self.config.get_headers(project_guid=project_guid, **kwargs), - json=configTreeRevision, + json=config_tree_revision, ) @handle_and_munchify_response @@ -1241,7 +1241,7 @@ async def rename_key_in_revision( name: str, revision_id: str, key: str, - configKeyRename: object, + config_key_rename: dict, project_guid: str = None, **kwargs, ) -> Munch: @@ -1251,7 +1251,7 @@ async def rename_key_in_revision( name (str): Config tree name revision_id (str): Config tree revision ID key (str): Key - configKeyRename (object): Key rename details + config_key_rename (dict): Key rename details project_guid (str, optional): Project GUID. async defaults to None. Returns: @@ -1261,7 +1261,7 @@ async def rename_key_in_revision( return await self.c.patch( url=f"{self.v2api_host}/v2/configtrees/{name}/revisions/{revision_id}/{key}/", headers=self.config.get_headers(project_guid=project_guid, **kwargs), - json=configKeyRename, + json=config_key_rename, ) # Managed Service API From a1c16718b2886314f4498ada1ee1068962ef06cc Mon Sep 17 00:00:00 2001 From: guptadev21 Date: Wed, 4 Dec 2024 10:47:25 +0530 Subject: [PATCH 05/13] =?UTF-8?q?=E2=9C=A8=20feat:=20add=20async=20tests?= =?UTF-8?q?=20for=20package=20management?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/async_tests/test_package.py | 63 +++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 tests/async_tests/test_package.py diff --git a/tests/async_tests/test_package.py b/tests/async_tests/test_package.py new file mode 100644 index 0000000..705c4cf --- /dev/null +++ b/tests/async_tests/test_package.py @@ -0,0 +1,63 @@ +import pytest +import pytest_asyncio # noqa: F401 +import httpx +from munch import Munch +from asyncmock import AsyncMock + +from tests.utils.test_util import ( + async_client as client, # noqa: F401 + package_body, +) + + +@pytest.mark.asyncio +async def test_list_packages_success(client, mocker: AsyncMock): # noqa: F811 + mock_get = mocker.patch("httpx.AsyncClient.get") + + mock_get.return_value = httpx.Response( + status_code=200, + json={ + "metadata": {"continue": 1}, + "items": [{"name": "test_package", "guid": "mock_package_guid"}], + }, + ) + + response = await client.list_packages() + + assert isinstance(response, Munch) + assert response["items"] == [{"name": "test_package", "guid": "mock_package_guid"}] + + +@pytest.mark.asyncio +async def test_list_packages_not_found(client, mocker: AsyncMock): # noqa: F811 + mock_get = mocker.patch("httpx.AsyncClient.get") + + mock_get.return_value = httpx.Response( + status_code=404, + json={"error": "not found"}, + ) + + with pytest.raises(Exception) as exc: + await client.list_packages() + assert str(exc.value) == "not found" + + +@pytest.mark.asyncio +async def test_create_package_success(client, mocker: AsyncMock): # noqa: F811 + mock_post = mocker.patch("httpx.AsyncClient.post") + + mock_post.return_value = httpx.Response( + status_code=200, + json={ + "kind": "Package", + "metadata": {"name": "test-package", "guid": "mock_package_guid"}, + "spec": { + "users": [{"userGUID": "mock_user_guid", "emailID": "mock_email"}] + }, + }, + ) + + response = await client.create_package(package_body) + + assert isinstance(response, Munch) + assert response["metadata"]["guid"] == "mock_package_guid" From 433c58fa30d87279e2a5abe995da3301846e9041 Mon Sep 17 00:00:00 2001 From: guptadev21 Date: Wed, 4 Dec 2024 11:07:25 +0530 Subject: [PATCH 06/13] chore: update --- rapyuta_io_sdk_v2/async_client.py | 48 +++++++++++++++---------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/rapyuta_io_sdk_v2/async_client.py b/rapyuta_io_sdk_v2/async_client.py index 6093a05..7e82228 100644 --- a/rapyuta_io_sdk_v2/async_client.py +++ b/rapyuta_io_sdk_v2/async_client.py @@ -392,14 +392,14 @@ async def list_deployments( self, cont: int = 0, dependencies: bool = False, - deviceName: str = None, + device_name: str = None, guids: list[str] = None, label_selector: list[str] = None, limit: int = 50, name: str = None, names: list[str] = None, - packageName: str = None, - packageVersion: str = None, + package_name: str = None, + package_version: str = None, phases: list[str] = None, regions: list[str] = None, **kwargs, @@ -409,14 +409,14 @@ async def list_deployments( Args: cont (int, optional): Start index of deployments. Defaults to 0. dependencies (bool, optional): Filter by dependencies. Defaults to False. - deviceName (str, optional): Filter deployments by device name. Defaults to None. + device_name (str, optional): Filter deployments by device name. Defaults to None. guids (list[str], optional): Filter by GUIDs. Defaults to None. label_selector (list[str], optional): Define labelSelector to get deployments from. Defaults to None. limit (int, optional): Number of deployments to list. Defaults to 50. name (str, optional): Define name to get deployments from. Defaults to None. names (list[str], optional): Define names to get deployments from. Defaults to None. - packageName (str, optional): Filter by package name. Defaults to None. - packageVersion (str, optional): Filter by package version. Defaults to None. + package_name (str, optional): Filter by package name. Defaults to None. + package_version (str, optional): Filter by package version. Defaults to None. phases (list[str], optional): Filter by phases. Available values : InProgress, Provisioning, Succeeded, FailedToUpdate, FailedToStart, Stopped. Defaults to None. regions (list[str], optional): Filter by regions. Defaults to None. @@ -431,13 +431,13 @@ async def list_deployments( "continue": cont, "limit": limit, "dependencies": dependencies, - "deviceName": deviceName, + "deviceName": device_name, "guids": guids, "labelSelector": label_selector, "name": name, "names": names, - "packageName": packageName, - "packageVersion": packageVersion, + "packageName": package_name, + "packageVersion": package_version, "phases": phases, "regions": regions, }, @@ -729,12 +729,12 @@ async def delete_staticroute(self, name: str, **kwargs) -> Munch: async def list_networks( self, cont: int = 0, - deviceName: str = None, + device_name: str = None, label_selector: list[str] = None, limit: int = 50, name: str = None, names: list[str] = None, - networkType: str = None, + network_type: str = None, phases: list[str] = None, regions: list[str] = None, status: list[str] = None, @@ -744,12 +744,12 @@ async def list_networks( Args: cont (int, optional): Start index of networks. Defaults to 0. - deviceName (str, optional): Filter networks by device name. Defaults to None. + device_name (str, optional): Filter networks by device name. Defaults to None. label_selector (list[str], optional): Define labelSelector to get networks from. Defaults to None. limit (int, optional): Number of networks to list. Defaults to 50. name (str, optional): Define name to get networks from. Defaults to None. names (list[str], optional): Define names to get networks from. Defaults to None. - networkType (str, optional): Define network type to get networks from. Defaults to None. + network_type (str, optional): Define network type to get networks from. Defaults to None. phases (list[str], optional): Define phases to get networks from. Available values : InProgress, Provisioning, Succeeded, FailedToUpdate, FailedToStart, Stopped. Defaults to None. regions (list[str], optional): Define regions to get networks from. Defaults to None. status (list[str], optional): Define status to get networks from. Available values : Running, Pending, Error, Unknown, Stopped. Defaults to None. @@ -764,11 +764,11 @@ async def list_networks( params={ "continue": cont, "limit": limit, - "deviceName": deviceName, + "deviceName": device_name, "labelSelector": label_selector, "name": name, "names": names, - "networkType": networkType, + "networkType": network_type, "phases": phases, "regions": regions, "status": status, @@ -981,9 +981,9 @@ async def create_configtree(self, body: dict, **kwargs) -> Munch: async def get_configtree( self, name: str, - contentTypes: list[str] = None, - includeData: bool = False, - keyPrefixes: list[str] = None, + content_type: list[str] = None, + include_data: bool = False, + key_prefixes: list[str] = None, revision: str = None, **kwargs, ) -> Munch: @@ -991,9 +991,9 @@ async def get_configtree( Args: name (str): Config tree name - contentTypes (list[str], optional): Define contentTypes to get config tree from. Defaults to None. - includeData (bool, optional): Include data. Defaults to False. - keyPrefixes (list[str], optional): Define keyPrefixes to get config tree from. Defaults to None. + content_types (list[str], optional): Define contentTypes to get config tree from. Defaults to None. + include_data (bool, optional): Include data. Defaults to False. + key_prefixes (list[str], optional): Define keyPrefixes to get config tree from. Defaults to None. revision (str, optional): Define revision to get config tree from. Defaults to None. Returns: @@ -1004,9 +1004,9 @@ async def get_configtree( url=f"{self.v2api_host}/v2/configtrees/{name}/", headers=self.config.get_headers(**kwargs), params={ - "contentTypes": contentTypes, - "includeData": includeData, - "keyPrefixes": keyPrefixes, + "contentTypes": content_type, + "includeData": include_data, + "keyPrefixes": key_prefixes, "revision": revision, }, ) From ae2f54bdda98b9294b2ebd3f9d2248e45e9a7ae5 Mon Sep 17 00:00:00 2001 From: Pallab Pain Date: Wed, 4 Dec 2024 12:15:44 +0530 Subject: [PATCH 07/13] chore: format code and remove unused dependencies --- pyproject.toml | 82 ++++++++++++++++++++++++- tests/async_tests/test_package.py | 4 +- tests/sync_tests/test_configtree.py | 4 +- tests/sync_tests/test_deployment.py | 4 +- tests/sync_tests/test_managedservice.py | 8 +-- tests/sync_tests/test_project.py | 4 +- tests/utils/test_util.py | 4 +- 7 files changed, 87 insertions(+), 23 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 44d4fa2..5020f32 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,9 +34,87 @@ dev = [ "pytest-cov>=5.0.0", "pytest-mock>=3.14.0", "pytest>=8.3.3", - "anyio>=4.5.2", - "asyncer>=0.0.8", "typing-extensions>=4.12.2", "pytest-asyncio>=0.24.0", "asyncmock>=0.4.2", ] + + +[tool.ruff] +# Exclude a variety of commonly ignored directories. +exclude = [ + ".bzr", + ".direnv", + ".eggs", + ".git", + ".git-rewrite", + ".hg", + ".ipynb_checkpoints", + ".mypy_cache", + ".nox", + ".pants.d", + ".pyenv", + ".pytest_cache", + ".pytype", + ".ruff_cache", + ".svn", + ".tox", + ".venv", + ".vscode", + "__pypackages__", + "_build", + "buck-out", + "build", + "dist", + "node_modules", + "site-packages", + "venv", +] + +# Same as Black. +line-length = 90 +indent-width = 4 + +# Assume Python 3.8 +target-version = "py38" + +[tool.ruff.lint] +# Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default. +# Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or +# McCabe complexity (`C901`) by default. +select = ["E4", "E7", "E9", "F", "B", "Q", "W"] +ignore = ["E741", "B904"] + +# Allow fix for all enabled rules (when `--fix`) is provided. +fixable = ["ALL"] +unfixable = [] + +# Allow unused variables when underscore-prefixed. +dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" + +[tool.ruff.format] +# Like Black, use double quotes for strings. +quote-style = "double" + +# Like Black, indent with spaces, rather than tabs. +indent-style = "space" + +# Like Black, respect magic trailing commas. +skip-magic-trailing-comma = false + +# Like Black, automatically detect the appropriate line ending. +line-ending = "auto" + +# Enable auto-formatting of code examples in docstrings. Markdown, +# reStructuredText code/literal blocks and doctests are all supported. +# +# This is currently disabled by default, but it is planned for this +# to be opt-out in the future. +docstring-code-format = false + +# Set the line length limit used when formatting code snippets in +# docstrings. +# +# This only has an effect when the `docstring-code-format` setting is +# enabled. +docstring-code-line-length = "dynamic" diff --git a/tests/async_tests/test_package.py b/tests/async_tests/test_package.py index 705c4cf..cf6380e 100644 --- a/tests/async_tests/test_package.py +++ b/tests/async_tests/test_package.py @@ -51,9 +51,7 @@ async def test_create_package_success(client, mocker: AsyncMock): # noqa: F811 json={ "kind": "Package", "metadata": {"name": "test-package", "guid": "mock_package_guid"}, - "spec": { - "users": [{"userGUID": "mock_user_guid", "emailID": "mock_email"}] - }, + "spec": {"users": [{"userGUID": "mock_user_guid", "emailID": "mock_email"}]}, }, ) diff --git a/tests/sync_tests/test_configtree.py b/tests/sync_tests/test_configtree.py index f9efd85..5c837b9 100644 --- a/tests/sync_tests/test_configtree.py +++ b/tests/sync_tests/test_configtree.py @@ -205,9 +205,7 @@ def test_update_configtree_success(client, mocker: MockerFixture): # noqa: F811 } # Call the update_configtree method - response = client.update_configtree( - name="mock_configtree_name", body=configtree_body - ) + response = client.update_configtree(name="mock_configtree_name", body=configtree_body) # Validate the response assert isinstance(response, Munch) diff --git a/tests/sync_tests/test_deployment.py b/tests/sync_tests/test_deployment.py index 19ea9fe..2ffaa19 100644 --- a/tests/sync_tests/test_deployment.py +++ b/tests/sync_tests/test_deployment.py @@ -195,9 +195,7 @@ def test_update_deployment_success(client, deployment_body, mocker: MockerFixtur if v is not None } - response = client.update_deployment( - name="mock_deployment_name", body=deployment_body - ) + response = client.update_deployment(name="mock_deployment_name", body=deployment_body) assert isinstance(response, Munch) assert response["metadata"]["guid"] == "test_deployment_guid" diff --git a/tests/sync_tests/test_managedservice.py b/tests/sync_tests/test_managedservice.py index f6304fc..0d88ac7 100644 --- a/tests/sync_tests/test_managedservice.py +++ b/tests/sync_tests/test_managedservice.py @@ -35,9 +35,7 @@ def test_list_providers_success(client, mocker: MockerFixture): # noqa: F811 # Validate the response assert isinstance(response, Munch) - assert response["items"] == [ - {"name": "test-provider", "guid": "mock_provider_guid"} - ] + assert response["items"] == [{"name": "test-provider", "guid": "mock_provider_guid"}] def test_list_instances_success(client, mocker: MockerFixture): # noqa: F811 @@ -69,9 +67,7 @@ def test_list_instances_success(client, mocker: MockerFixture): # noqa: F811 # Validate the response assert isinstance(response, Munch) - assert response["items"] == [ - {"name": "test-instance", "guid": "mock_instance_guid"} - ] + assert response["items"] == [{"name": "test-instance", "guid": "mock_instance_guid"}] def test_get_instance_success(client, mocker: MockerFixture): # noqa: F811 diff --git a/tests/sync_tests/test_project.py b/tests/sync_tests/test_project.py index 8259f2e..9987d70 100644 --- a/tests/sync_tests/test_project.py +++ b/tests/sync_tests/test_project.py @@ -242,9 +242,7 @@ def test_update_project_success(client, mock_response_project, mocker: MockerFix } # Call the update_project method - response = client.update_project( - project_guid="mock_project_guid", body=project_body - ) + response = client.update_project(project_guid="mock_project_guid", body=project_body) # Validate the response assert isinstance(response, Munch) diff --git a/tests/utils/test_util.py b/tests/utils/test_util.py index 2109849..0a40217 100644 --- a/tests/utils/test_util.py +++ b/tests/utils/test_util.py @@ -30,9 +30,7 @@ def mock_response_project(): "kind": "Project", "metadata": {"name": "test-project", "guid": "mock_project_guid"}, "spec": { - "users": [ - {"userGUID": "mock_user_guid", "emailID": "test.user@example.com"} - ] + "users": [{"userGUID": "mock_user_guid", "emailID": "test.user@example.com"}] }, } From 0baad0d437512c3a9f40615f5a88975d87f8cb57 Mon Sep 17 00:00:00 2001 From: Pallab Pain Date: Wed, 4 Dec 2024 12:17:14 +0530 Subject: [PATCH 08/13] chore: organize imports --- rapyuta_io_sdk_v2/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rapyuta_io_sdk_v2/__init__.py b/rapyuta_io_sdk_v2/__init__.py index 5a73f74..3f0d943 100644 --- a/rapyuta_io_sdk_v2/__init__.py +++ b/rapyuta_io_sdk_v2/__init__.py @@ -1,7 +1,7 @@ # ruff: noqa +from rapyuta_io_sdk_v2.async_client import AsyncClient from rapyuta_io_sdk_v2.client import Client from rapyuta_io_sdk_v2.config import Configuration from rapyuta_io_sdk_v2.utils import walk_pages -from rapyuta_io_sdk_v2.async_client import AsyncClient __version__ = "0.0.1" From 7ed9458734ef5d274fe7a6420c0ac57fdaad15b4 Mon Sep 17 00:00:00 2001 From: guptadev21 Date: Wed, 4 Dec 2024 12:42:39 +0530 Subject: [PATCH 09/13] chore: update --- tests/async_tests/test_package.py | 6 ++---- tests/async_tests/test_project.py | 6 ++---- tests/sync_tests/test_config.py | 2 +- tests/sync_tests/test_configtree.py | 3 ++- tests/sync_tests/test_deployment.py | 3 ++- tests/sync_tests/test_disk.py | 3 ++- tests/sync_tests/test_main.py | 2 +- tests/sync_tests/test_managedservice.py | 2 +- tests/sync_tests/test_network.py | 3 ++- tests/sync_tests/test_package.py | 3 ++- tests/sync_tests/test_project.py | 4 ++-- tests/sync_tests/test_secret.py | 3 ++- tests/sync_tests/test_staticroute.py | 3 ++- tests/utils/fixtures.py | 23 +++++++++++++++++++++++ tests/utils/{test_util.py => util.py} | 21 --------------------- 15 files changed, 46 insertions(+), 41 deletions(-) create mode 100644 tests/utils/fixtures.py rename tests/utils/{test_util.py => util.py} (84%) diff --git a/tests/async_tests/test_package.py b/tests/async_tests/test_package.py index cf6380e..329b0da 100644 --- a/tests/async_tests/test_package.py +++ b/tests/async_tests/test_package.py @@ -4,10 +4,8 @@ from munch import Munch from asyncmock import AsyncMock -from tests.utils.test_util import ( - async_client as client, # noqa: F401 - package_body, -) +from tests.utils.util import package_body +from tests.utils.fixtures import async_client as client # noqa: F401 @pytest.mark.asyncio diff --git a/tests/async_tests/test_project.py b/tests/async_tests/test_project.py index e405da0..1e940ae 100644 --- a/tests/async_tests/test_project.py +++ b/tests/async_tests/test_project.py @@ -4,10 +4,8 @@ from munch import Munch from asyncmock import AsyncMock -from tests.utils.test_util import ( - async_client as client, # noqa: F401 - project_body, -) +from tests.utils.util import project_body +from tests.utils.fixtures import async_client as client # noqa: F401 @pytest.mark.asyncio diff --git a/tests/sync_tests/test_config.py b/tests/sync_tests/test_config.py index f15f745..9bfa89a 100644 --- a/tests/sync_tests/test_config.py +++ b/tests/sync_tests/test_config.py @@ -1,6 +1,6 @@ import json from rapyuta_io_sdk_v2.config import Configuration -from tests.utils.test_util import mock_config # noqa: F401 +from tests.utils.util import mock_config # noqa: F401 def test_from_file(mocker): diff --git a/tests/sync_tests/test_configtree.py b/tests/sync_tests/test_configtree.py index 5c837b9..e473a65 100644 --- a/tests/sync_tests/test_configtree.py +++ b/tests/sync_tests/test_configtree.py @@ -3,7 +3,8 @@ from munch import Munch from pytest_mock import MockerFixture -from tests.utils.test_util import client, configtree_body # noqa: F401 +from tests.utils.util import configtree_body # noqa: F401 +from tests.utils.fixtures import client # noqa: F401 def test_list_configtrees_success(client, mocker: MockerFixture): # noqa: F811 diff --git a/tests/sync_tests/test_deployment.py b/tests/sync_tests/test_deployment.py index 2ffaa19..73d243b 100644 --- a/tests/sync_tests/test_deployment.py +++ b/tests/sync_tests/test_deployment.py @@ -3,7 +3,8 @@ from munch import Munch from pytest_mock import MockerFixture -from tests.utils.test_util import client, deployment_body # noqa: F401 +from tests.utils.util import deployment_body # noqa: F401 +from tests.utils.fixtures import client # noqa: F401 def test_list_deployments_success(client, mocker: MockerFixture): # noqa: F811 diff --git a/tests/sync_tests/test_disk.py b/tests/sync_tests/test_disk.py index 6d194b9..1214826 100644 --- a/tests/sync_tests/test_disk.py +++ b/tests/sync_tests/test_disk.py @@ -3,7 +3,8 @@ from munch import Munch from pytest_mock import MockerFixture -from tests.utils.test_util import client, disk_body # noqa: F401 +from tests.utils.util import disk_body # noqa: F401 +from tests.utils.fixtures import client # noqa: F401 def test_list_disks_success(client, mocker: MockerFixture): # noqa: F811 diff --git a/tests/sync_tests/test_main.py b/tests/sync_tests/test_main.py index a8fa660..f1f0ebe 100644 --- a/tests/sync_tests/test_main.py +++ b/tests/sync_tests/test_main.py @@ -2,7 +2,7 @@ import pytest from pytest_mock import MockerFixture -from tests.utils.test_util import client # noqa: F401 +from tests.utils.fixtures import client # noqa: F401 def test_get_auth_token_success(client, mocker: MockerFixture): # noqa: F811 diff --git a/tests/sync_tests/test_managedservice.py b/tests/sync_tests/test_managedservice.py index 0d88ac7..074f737 100644 --- a/tests/sync_tests/test_managedservice.py +++ b/tests/sync_tests/test_managedservice.py @@ -3,7 +3,7 @@ from munch import Munch from pytest_mock import MockerFixture -from tests.utils.test_util import client # noqa: F401 +from tests.utils.fixtures import client # noqa: F401 def test_list_providers_success(client, mocker: MockerFixture): # noqa: F811 diff --git a/tests/sync_tests/test_network.py b/tests/sync_tests/test_network.py index 11a6cf6..3fb020c 100644 --- a/tests/sync_tests/test_network.py +++ b/tests/sync_tests/test_network.py @@ -3,7 +3,8 @@ from munch import Munch from pytest_mock import MockerFixture -from tests.utils.test_util import client, network_body # noqa: F401 +from tests.utils.util import network_body # noqa: F401 +from tests.utils.fixtures import client # noqa: F401 def test_list_networks_success(client, mocker: MockerFixture): # noqa: F811 diff --git a/tests/sync_tests/test_package.py b/tests/sync_tests/test_package.py index 3f7d6d8..a7a0d1b 100644 --- a/tests/sync_tests/test_package.py +++ b/tests/sync_tests/test_package.py @@ -3,7 +3,8 @@ from munch import Munch from pytest_mock import MockerFixture -from tests.utils.test_util import client, package_body # noqa: F401 +from tests.utils.util import package_body # noqa: F401 +from tests.utils.fixtures import client # noqa: F401 def test_list_packages_success(client, mocker: MockerFixture): # noqa: F811 diff --git a/tests/sync_tests/test_project.py b/tests/sync_tests/test_project.py index 9987d70..d0296e5 100644 --- a/tests/sync_tests/test_project.py +++ b/tests/sync_tests/test_project.py @@ -3,11 +3,11 @@ from munch import Munch from pytest_mock import MockerFixture -from tests.utils.test_util import ( - client, # noqa: F401 +from tests.utils.util import ( mock_response_project, # noqa: F401 project_body, ) # noqa: F401 +from tests.utils.fixtures import client # noqa: F401 # Test function for list_projects diff --git a/tests/sync_tests/test_secret.py b/tests/sync_tests/test_secret.py index 48a8054..9862f65 100644 --- a/tests/sync_tests/test_secret.py +++ b/tests/sync_tests/test_secret.py @@ -3,7 +3,8 @@ from munch import Munch from pytest_mock import MockerFixture -from tests.utils.test_util import client, secret_body # noqa: F401 +from tests.utils.util import secret_body # noqa: F401 +from tests.utils.fixtures import client # noqa: F401 def test_list_secrets_success(client, mocker: MockerFixture): # noqa: F811 diff --git a/tests/sync_tests/test_staticroute.py b/tests/sync_tests/test_staticroute.py index 8436a38..f95a03b 100644 --- a/tests/sync_tests/test_staticroute.py +++ b/tests/sync_tests/test_staticroute.py @@ -3,7 +3,8 @@ from munch import Munch from pytest_mock import MockerFixture -from tests.utils.test_util import client, staticroute_body # noqa: F401 +from tests.utils.util import staticroute_body # noqa: F401 +from tests.utils.fixtures import client # noqa: F401 def test_list_staticroutes_success(client, mocker: MockerFixture): # noqa: F811 diff --git a/tests/utils/fixtures.py b/tests/utils/fixtures.py new file mode 100644 index 0000000..440275c --- /dev/null +++ b/tests/utils/fixtures.py @@ -0,0 +1,23 @@ +import pytest +from rapyuta_io_sdk_v2 import Client, AsyncClient + + +# Fixture to initialize the Client +@pytest.fixture +def client(): + client = Client() + client.config.hosts["v2api_host"] = "https://mock-api.rapyuta.io" + client.auth_token = "mock_token" + client.organization_guid = "mock_org_guid" + client.project = "mock_project_guid" + return client + + +@pytest.fixture +def async_client(): + client = AsyncClient() + client.config.hosts["v2api_host"] = "https://mock-api.rapyuta.io" + client.auth_token = "mock_token" + client.organization_guid = "mock_org_guid" + client.project = "mock_project_guid" + return client diff --git a/tests/utils/test_util.py b/tests/utils/util.py similarity index 84% rename from tests/utils/test_util.py rename to tests/utils/util.py index 0a40217..c702999 100644 --- a/tests/utils/test_util.py +++ b/tests/utils/util.py @@ -3,27 +3,6 @@ from rapyuta_io_sdk_v2 import Client, Configuration, AsyncClient -# Fixture to initialize the Client -@pytest.fixture -def client(): - client = Client() - client.config.hosts["v2api_host"] = "https://mock-api.rapyuta.io" - client.auth_token = "mock_token" - client.organization_guid = "mock_org_guid" - client.project = "mock_project_guid" - return client - - -@pytest.fixture -def async_client(): - client = AsyncClient() - client.config.hosts["v2api_host"] = "https://mock-api.rapyuta.io" - client.auth_token = "mock_token" - client.organization_guid = "mock_org_guid" - client.project = "mock_project_guid" - return client - - @pytest.fixture def mock_response_project(): return { From 936e2d2b8e64de97d72bbba53899e254367daaac Mon Sep 17 00:00:00 2001 From: guptadev21 Date: Wed, 4 Dec 2024 12:45:46 +0530 Subject: [PATCH 10/13] chore: update --- tests/utils/util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/utils/util.py b/tests/utils/util.py index c702999..08e5887 100644 --- a/tests/utils/util.py +++ b/tests/utils/util.py @@ -1,6 +1,6 @@ import pytest -from rapyuta_io_sdk_v2 import Client, Configuration, AsyncClient +from rapyuta_io_sdk_v2 import Configuration @pytest.fixture From 97b734e83c278af4e37bd9bed97f2e8762788f36 Mon Sep 17 00:00:00 2001 From: guptadev21 Date: Thu, 5 Dec 2024 11:18:47 +0530 Subject: [PATCH 11/13] =?UTF-8?q?=E2=9C=A8=20Feat:=20add=20and=20refactore?= =?UTF-8?q?d=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added some async tests and removed get_headers(kind of fixture) from tests as client fixture already writing values in config add new select rule in configuration --- .github/workflows/quality-checks.yml | 3 +- pyproject.toml | 2 +- rapyuta_io_sdk_v2/client.py | 19 +- rapyuta_io_sdk_v2/utils.py | 35 ++ tests/async_tests/test_configtree_async.py | 363 ++++++++++++++++++ tests/async_tests/test_deployment_async.py | 153 ++++++++ tests/async_tests/test_disk_async.py | 142 +++++++ .../async_tests/test_managedservice_async.py | 208 ++++++++++ tests/async_tests/test_network_async.py | 124 ++++++ ...{test_package.py => test_package_async.py} | 49 ++- ...{test_project.py => test_project_async.py} | 2 +- tests/async_tests/test_secret_async.py | 146 +++++++ tests/async_tests/test_staticroute_async.py | 148 +++++++ tests/{utils/util.py => data/mock_data.py} | 0 tests/sync_tests/test_config.py | 2 +- tests/sync_tests/test_configtree.py | 200 +--------- tests/sync_tests/test_deployment.py | 100 +---- tests/sync_tests/test_disk.py | 90 +---- tests/sync_tests/test_main.py | 8 +- tests/sync_tests/test_managedservice.py | 119 +----- tests/sync_tests/test_network.py | 74 +--- tests/sync_tests/test_package.py | 61 +-- tests/sync_tests/test_project.py | 121 +----- tests/sync_tests/test_secret.py | 71 +--- tests/sync_tests/test_staticroute.py | 87 +---- tests/utils/fixtures.py | 14 +- uv.lock | 17 - 27 files changed, 1486 insertions(+), 872 deletions(-) create mode 100644 tests/async_tests/test_configtree_async.py create mode 100644 tests/async_tests/test_deployment_async.py create mode 100644 tests/async_tests/test_disk_async.py create mode 100644 tests/async_tests/test_managedservice_async.py create mode 100644 tests/async_tests/test_network_async.py rename tests/async_tests/{test_package.py => test_package_async.py} (54%) rename tests/async_tests/{test_project.py => test_project_async.py} (98%) create mode 100644 tests/async_tests/test_secret_async.py create mode 100644 tests/async_tests/test_staticroute_async.py rename tests/{utils/util.py => data/mock_data.py} (100%) diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index d8900cc..b225d91 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -28,5 +28,4 @@ jobs: run: | uv sync --all-extras --dev source .venv/bin/activate - uv run pytest tests/sync_tests --cov - uv run pytest tests/async_tests --cov \ No newline at end of file + uv run pytest tests/ --cov \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 5020f32..61ca75f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -82,7 +82,7 @@ target-version = "py38" # Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default. # Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or # McCabe complexity (`C901`) by default. -select = ["E4", "E7", "E9", "F", "B", "Q", "W"] +select = ["E4", "E7", "E9", "F", "B", "Q", "W", "N816"] ignore = ["E741", "B904"] # Allow fix for all enabled rules (when `--fix`) is provided. diff --git a/rapyuta_io_sdk_v2/client.py b/rapyuta_io_sdk_v2/client.py index 611f544..0a86fce 100644 --- a/rapyuta_io_sdk_v2/client.py +++ b/rapyuta_io_sdk_v2/client.py @@ -181,7 +181,6 @@ def get_project(self, project_guid: str = None, **kwargs) -> Munch: headers=self.config.get_headers(with_project=False, **kwargs), ) - # @handle_and_munchify_response @handle_and_munchify_response def list_projects( self, @@ -1113,14 +1112,14 @@ def create_revision( @handle_and_munchify_response def put_keys_in_revision( - self, name: str, revision_id: str, configValues: list[(dict)], **kwargs + self, name: str, revision_id: str, config_values: list[(dict)], **kwargs ) -> Munch: """Put keys in a revision. Args: name (str): Config tree name revision_id (str): Config tree revision ID - configValues (list[dict]): Config values + config_values (list[dict]): Config values Returns: Munch: Revision details as a Munch object. @@ -1129,7 +1128,7 @@ def put_keys_in_revision( return self.c.put( url=f"{self.v2api_host}/v2/configtrees/{name}/revisions/{revision_id}/keys/", headers=self.config.get_headers(**kwargs), - json=configValues, + json=config_values, ) @handle_and_munchify_response @@ -1137,7 +1136,7 @@ def commit_revision( self, name: str, revision_id: str, - configTreeRevision: dict, + config_tree_revision: dict, project_guid: str = None, **kwargs, ) -> Munch: @@ -1146,7 +1145,7 @@ def commit_revision( Args: name (str): Config tree name revision_id (str): Config tree revision ID - configTreeRevision (object): Config tree revision details + config_tree_revision (dict): Config tree revision details project_guid (str, optional): Project GUID. Defaults to None. Returns: @@ -1156,7 +1155,7 @@ def commit_revision( return self.c.patch( url=f"{self.v2api_host}/v2/configtrees/{name}/revisions/{revision_id}/commit/", headers=self.config.get_headers(project_guid=project_guid, **kwargs), - json=configTreeRevision, + json=config_tree_revision, ) @handle_and_munchify_response @@ -1228,7 +1227,7 @@ def rename_key_in_revision( name: str, revision_id: str, key: str, - configKeyRename: dict, + config_key_rename: dict, project_guid: str = None, **kwargs, ) -> Munch: @@ -1238,7 +1237,7 @@ def rename_key_in_revision( name (str): Config tree name revision_id (str): Config tree revision ID key (str): Key - configKeyRename (object): Key rename details + config_key_rename (object): Key rename details project_guid (str, optional): Project GUID. Defaults to None. Returns: @@ -1248,7 +1247,7 @@ def rename_key_in_revision( return self.c.patch( url=f"{self.v2api_host}/v2/configtrees/{name}/revisions/{revision_id}/{key}/", headers=self.config.get_headers(project_guid=project_guid, **kwargs), - json=configKeyRename, + json=config_key_rename, ) # Managed Service API diff --git a/rapyuta_io_sdk_v2/utils.py b/rapyuta_io_sdk_v2/utils.py index c6ac788..e16fcd9 100644 --- a/rapyuta_io_sdk_v2/utils.py +++ b/rapyuta_io_sdk_v2/utils.py @@ -149,3 +149,38 @@ def walk_pages( cont = data.get("metadata", {}).get("continue") if cont is None: break + + +async def walk_pages_async( + func: typing.Callable, + *args, + limit: int = 50, + cont: int = 0, + **kwargs, +) -> typing.AsyncGenerator: + """A generator function to paginate through list API results. + + Args: + func (callable): The API function to call, must accept `cont` and `limit` as arguments. + *args: Positional arguments to pass to the API function. + limit (int, optional): Maximum number of items to return. Defaults to 50. + cont (int, optional): Initial continuation token. Defaults to 0. + **kwargs: Additional keyword arguments to pass to the API function. + + Yields: + Munch: Each item from the API response. + """ + while True: + data = await func(cont, limit, *args, **kwargs) + + items = data.get("items", []) + if not items: + break + + for item in items: + yield munchify(item) + + # Update `cont` for the next page + cont = data.get("metadata", {}).get("continue") + if cont is None: + break diff --git a/tests/async_tests/test_configtree_async.py b/tests/async_tests/test_configtree_async.py new file mode 100644 index 0000000..6b3adfd --- /dev/null +++ b/tests/async_tests/test_configtree_async.py @@ -0,0 +1,363 @@ +import httpx +import pytest +import pytest_asyncio # noqa: F401 +from munch import Munch +from asyncmock import AsyncMock + +from tests.data.mock_data import configtree_body # noqa: F401 +from tests.utils.fixtures import async_client as client # noqa: F401 + + +@pytest.mark.asyncio +async def test_list_configtrees_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.get method + mock_get = mocker.patch("httpx.AsyncClient.get") + + # Set up the mock responses for pagination + mock_get.return_value = httpx.Response( + status_code=200, + json={ + "metadata": {"continue": 1}, + "items": [{"name": "test-configtree", "guid": "mock_configtree_guid"}], + }, + ) + + # Call the list_configtrees method + response = await client.list_configtrees() + + # Validate the response + assert isinstance(response, Munch) + assert response["items"] == [ + {"name": "test-configtree", "guid": "mock_configtree_guid"} + ] + + +@pytest.mark.asyncio +async def test_list_configtrees_bad_gateway(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.get method + mock_get = mocker.patch("httpx.AsyncClient.get") + + # Set up the mock response + mock_get.return_value = httpx.Response( + status_code=502, + json={"error": "bad gateway"}, + ) + + # Call the list_configtrees method + with pytest.raises(Exception) as exc: + await client.list_configtrees() + + assert str(exc.value) == "bad gateway" + + +@pytest.mark.asyncio +async def test_create_configtree_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.post method + mock_post = mocker.patch("httpx.AsyncClient.post") + + # Set up the mock response + mock_post.return_value = httpx.Response( + status_code=201, + json={ + "metadata": {"guid": "test_configtree_guid", "name": "test_configtree"}, + }, + ) + + # Call the create_configtree method + response = await client.create_configtree(configtree_body) + + # Validate the response + assert isinstance(response, Munch) + assert response["metadata"]["guid"] == "test_configtree_guid" + + +@pytest.mark.asyncio +async def test_create_configtree_service_unavailable(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.post method + mock_post = mocker.patch("httpx.AsyncClient.post") + + # Set up the mock response + mock_post.return_value = httpx.Response( + status_code=503, + json={"error": "service unavailable"}, + ) + + # Call the create_configtree method + with pytest.raises(Exception) as exc: + await client.create_configtree(configtree_body) + + assert str(exc.value) == "service unavailable" + + +@pytest.mark.asyncio +async def test_get_configtree_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.get method + mock_get = mocker.patch("httpx.AsyncClient.get") + + # Set up the mock response + mock_get.return_value = httpx.Response( + status_code=200, + json={ + "metadata": {"guid": "test_configtree_guid", "name": "test_configtree"}, + }, + ) + + # Call the get_configtree method + response = await client.get_configtree(name="mock_configtree_name") + + # Validate the response + assert isinstance(response, Munch) + assert response.metadata.guid == "test_configtree_guid" + assert response.metadata.name == "test_configtree" + + +@pytest.mark.asyncio +async def test_set_configtree_revision_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.put method + mock_put = mocker.patch("httpx.AsyncClient.put") + + # Set up the mock response + mock_put.return_value = httpx.Response( + status_code=200, + json={ + "metadata": {"guid": "test_configtree_guid", "name": "test_configtree"}, + }, + ) + + # Call the set_configtree_revision method + response = await client.set_configtree_revision( + name="mock_configtree_name", configtree=configtree_body + ) + + # Validate the response + assert isinstance(response, Munch) + assert response.metadata.guid == "test_configtree_guid" + assert response.metadata.name == "test_configtree" + + +@pytest.mark.asyncio +async def test_update_configtree_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.put method + mock_put = mocker.patch("httpx.AsyncClient.put") + + # Set up the mock response + mock_put.return_value = httpx.Response( + status_code=200, + json={ + "metadata": {"guid": "test_configtree_guid", "name": "test_configtree"}, + }, + ) + + # Call the update_configtree method + response = await client.update_configtree( + name="mock_configtree_name", body=configtree_body + ) + + # Validate the response + assert isinstance(response, Munch) + assert response.metadata.guid == "test_configtree_guid" + assert response.metadata.name == "test_configtree" + + +@pytest.mark.asyncio +async def test_delete_configtree_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.delete method + mock_delete = mocker.patch("httpx.AsyncClient.delete") + + # Set up the mock response + mock_delete.return_value = httpx.Response( + status_code=204, + json={"success": True}, + ) + + # Call the delete_configtree method + response = await client.delete_configtree(name="mock_configtree_name") + + # Validate the response + assert response["success"] is True + + +@pytest.mark.asyncio +async def test_list_revisions_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.get method + mock_get = mocker.patch("httpx.AsyncClient.get") + + # Set up the mock responses for pagination + mock_get.return_value = httpx.Response( + status_code=200, + json={ + "metadata": {"continue": 1}, + "items": [{"name": "test-configtree", "guid": "mock_configtree_guid"}], + }, + ) + + # Call the list_revisions method + response = await client.list_revisions(name="mock_configtree_name") + + # Validate the response + assert isinstance(response, Munch) + assert response["items"] == [ + {"name": "test-configtree", "guid": "mock_configtree_guid"} + ] + + +@pytest.mark.asyncio +async def test_create_revision_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.post method + mock_post = mocker.patch("httpx.AsyncClient.post") + + # Set up the mock response + mock_post.return_value = httpx.Response( + status_code=201, + json={ + "metadata": {"guid": "test_revision_guid", "name": "test_revision"}, + }, + ) + + # Call the create_revision method + response = await client.create_revision( + name="mock_configtree_name", body=configtree_body + ) + + # Validate the response + assert isinstance(response, Munch) + assert response["metadata"]["guid"] == "test_revision_guid" + + +@pytest.mark.asyncio +async def test_put_keys_in_revision_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.put method + mock_put = mocker.patch("httpx.AsyncClient.put") + + # Set up the mock response + mock_put.return_value = httpx.Response( + status_code=200, + json={ + "metadata": {"guid": "test_revision_guid", "name": "test_revision"}, + }, + ) + + # Call the put_keys_in_revision method + response = await client.put_keys_in_revision( + name="mock_configtree_name", + revision_id="mock_revision_id", + config_values=["mock_value1", "mock_value2"], + ) + + # Validate the response + assert isinstance(response, Munch) + assert response.metadata.guid == "test_revision_guid" + assert response.metadata.name == "test_revision" + + +@pytest.mark.asyncio +async def test_commit_revision_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.put method + mock_patch = mocker.patch("httpx.AsyncClient.patch") + + # Set up the mock response + mock_patch.return_value = httpx.Response( + status_code=200, + json={ + "metadata": {"guid": "test_revision_guid", "name": "test_revision"}, + }, + ) + + # Call the commit_revision method + response = await client.commit_revision( + name="mock_configtree_name", + revision_id="mock_revision_id", + config_tree_revision=configtree_body, + ) + + # Validate the response + assert isinstance(response, Munch) + assert response.metadata.guid == "test_revision_guid" + assert response.metadata.name == "test_revision" + + +@pytest.mark.asyncio +async def test_get_key_in_revision(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.get method + mock_get = mocker.patch("httpx.AsyncClient.get") + + # Set up the mock response + mock_get.return_value = httpx.Response( + status_code=200, + json={ + "metadata": {"guid": "test_revision_guid", "name": "test_revision"}, + }, + ) + + # Call the get_key_in_revision method + response = await client.get_key_in_revision( + name="mock_configtree_name", revision_id="mock_revision_id", key="mock_key" + ) + + # Validate the response + assert isinstance(response, Munch) + assert response.metadata.guid == "test_revision_guid" + assert response.metadata.name == "test_revision" + + +@pytest.mark.asyncio +async def test_put_key_in_revision_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.put method + mock_put = mocker.patch("httpx.AsyncClient.put") + + # Set up the mock response + mock_put.return_value = httpx.Response( + status_code=200, + json={ + "metadata": {"guid": "test_revision_guid", "name": "test_revision"}, + }, + ) + + # Call the put_key_in_revision method + response = await client.put_key_in_revision( + name="mock_configtree_name", revision_id="mock_revision_id", key="mock_key" + ) + + # Validate the response + assert isinstance(response, Munch) + assert response.metadata.guid == "test_revision_guid" + assert response.metadata.name == "test_revision" + + +@pytest.mark.asyncio +async def test_delete_key_in_revision_success(client, mocker: AsyncMock): # noqa: F811 + mock_delete = mocker.patch("httpx.AsyncClient.delete") + + mock_delete.return_value = httpx.Response( + status_code=204, + json={"success": True}, + ) + + response = await client.delete_key_in_revision( + name="mock_configtree_name", revision_id="mock_revision_id", key="mock_key" + ) + + assert response["success"] is True + + +@pytest.mark.asyncio +async def test_rename_key_in_revision_success(client, mocker: AsyncMock): # noqa: F811 + mock_patch = mocker.patch("httpx.AsyncClient.patch") + + mock_patch.return_value = httpx.Response( + status_code=200, + json={ + "metadata": {"guid": "test_revision_guid", "name": "test_revision"}, + }, + ) + + response = await client.rename_key_in_revision( + name="mock_configtree_name", + revision_id="mock_revision_id", + key="mock_key", + config_key_rename={"metadata": {"name": "test_key"}}, + ) + + assert isinstance(response, Munch) + assert response.metadata.guid == "test_revision_guid" + assert response.metadata.name == "test_revision" diff --git a/tests/async_tests/test_deployment_async.py b/tests/async_tests/test_deployment_async.py new file mode 100644 index 0000000..f124148 --- /dev/null +++ b/tests/async_tests/test_deployment_async.py @@ -0,0 +1,153 @@ +import httpx +import pytest +import pytest_asyncio # noqa: F401 +from munch import Munch +from asyncmock import AsyncMock + +from tests.data.mock_data import deployment_body # noqa: F401 +from tests.utils.fixtures import async_client as client # noqa: F401 + + +@pytest.mark.asyncio +async def test_list_deployments_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.get") method + mock_get = mocker.patch("httpx.AsyncClient.get") + + # Set up the mock responses for pagination + mock_get.return_value = httpx.Response( + status_code=200, + json={ + "metadata": {"continue": 1}, + "items": [{"name": "test-deployment", "guid": "mock_deployment_guid"}], + }, + ) + + # Call the list_deployments method + response = await client.list_deployments() + + # Validate the response + assert isinstance(response, Munch) + assert response["items"] == [ + {"name": "test-deployment", "guid": "mock_deployment_guid"} + ] + + +@pytest.mark.asyncio +async def test_list_deployments_not_found(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.get") method + mock_get = mocker.patch("httpx.AsyncClient.get") + + # Set up the mock response + mock_get.return_value = httpx.Response( + status_code=404, + json={"error": "not found"}, + ) + + with pytest.raises(Exception) as exc: + await client.list_deployments() + + assert str(exc.value) == "not found" + + +@pytest.mark.asyncio +async def test_get_deployment_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.get") method + mock_get = mocker.patch("httpx.AsyncClient.get") + + # Set up the mock response + mock_get.return_value = httpx.Response( + status_code=200, + json={ + "kind": "Deployment", + "metadata": {"guid": "test_deployment_guid", "name": "test_deployment"}, + }, + ) + + # Call the get_deployment method + response = await client.get_deployment(name="mock_deployment_name") + + # Validate the response + assert isinstance(response, Munch) + assert response["metadata"]["guid"] == "test_deployment_guid" + + +@pytest.mark.asyncio +async def test_get_deployment_not_found(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.get") method + mock_get = mocker.patch("httpx.AsyncClient.get") + + # Set up the mock response + mock_get.return_value = httpx.Response( + status_code=404, + json={"error": "deployment not found"}, + ) + + # Call the get_deployment method + with pytest.raises(Exception) as exc: + await client.get_deployment(name="mock_deployment_name") + + assert str(exc.value) == "deployment not found" + + +@pytest.mark.asyncio +async def test_create_deployment_success(client, deployment_body, mocker: AsyncMock): # noqa: F811 + mock_post = mocker.patch("httpx.AsyncClient.post") + + mock_post.return_value = httpx.Response( + status_code=200, + json={ + "kind": "Deployment", + "metadata": {"guid": "test_deployment_guid", "name": "test_deployment"}, + }, + ) + + response = await client.create_deployment(body=deployment_body) + + assert isinstance(response, Munch) + assert response["metadata"]["guid"] == "test_deployment_guid" + + +@pytest.mark.asyncio +async def test_create_deployment_unauthorized(client, deployment_body, mocker: AsyncMock): # noqa: F811 + mock_post = mocker.patch("httpx.AsyncClient.post") + + mock_post.return_value = httpx.Response( + status_code=401, + json={"error": "unauthorized"}, + ) + + with pytest.raises(Exception) as exc: + await client.create_deployment(body=deployment_body) + + assert str(exc.value) == "unauthorized" + + +@pytest.mark.asyncio +async def test_update_deployment_success(client, deployment_body, mocker: AsyncMock): # noqa: F811 + mock_put = mocker.patch("httpx.AsyncClient.put") + + mock_put.return_value = httpx.Response( + status_code=200, + json={ + "kind": "Deployment", + "metadata": {"guid": "test_deployment_guid", "name": "test_deployment"}, + }, + ) + + response = await client.update_deployment( + name="mock_deployment_name", body=deployment_body + ) + + assert isinstance(response, Munch) + assert response["metadata"]["guid"] == "test_deployment_guid" + + +@pytest.mark.asyncio +async def test_delete_deployment_success(client, mocker: AsyncMock): # noqa: F811 + mock_delete = mocker.patch("httpx.AsyncClient.delete") + + mock_delete.return_value = httpx.Response(status_code=204, json={"success": True}) + + response = await client.delete_deployment(name="mock_deployment_name") + + assert response["success"] is True diff --git a/tests/async_tests/test_disk_async.py b/tests/async_tests/test_disk_async.py new file mode 100644 index 0000000..78f7d1a --- /dev/null +++ b/tests/async_tests/test_disk_async.py @@ -0,0 +1,142 @@ +import httpx +import pytest +import pytest_asyncio # noqa: F401 +from munch import Munch +from asyncmock import AsyncMock + +from tests.data.mock_data import disk_body # noqa: F401 +from tests.utils.fixtures import async_client as client # noqa: F401 + + +@pytest.mark.asyncio +async def test_list_disks_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.get method + mock_get = mocker.patch("httpx.AsyncClient.get") + + # Set up mock responses for pagination + mock_get.return_value = httpx.Response( + status_code=200, + json={ + "metadata": {"continue": 1}, + "items": [{"name": "test-disk", "guid": "mock_disk_guid"}], + }, + ) + + # Call the list_disks method + response = await client.list_disks() + + # Validate the response + assert isinstance(response, Munch) + assert response["items"] == [{"name": "test-disk", "guid": "mock_disk_guid"}] + + +@pytest.mark.asyncio +async def test_list_disks_not_found(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.get method + mock_get = mocker.patch("httpx.AsyncClient.get") + + # Set up the mock response + mock_get.return_value = httpx.Response( + status_code=404, + json={"error": "not found"}, + ) + + with pytest.raises(Exception) as exc: + await client.list_disks() + + assert str(exc.value) == "not found" + + +@pytest.mark.asyncio +async def test_get_disk_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.get method + mock_get = mocker.patch("httpx.AsyncClient.get") + + # Set up the mock response + mock_get.return_value = httpx.Response( + status_code=200, + json={ + "kind": "Disk", + "metadata": {"guid": "test_disk_guid", "name": "mock_disk_name"}, + }, + ) + + # Call the get_disk method + response = await client.get_disk(name="mock_disk_name") + + # Validate the response + assert isinstance(response, Munch) + assert response["metadata"]["guid"] == "test_disk_guid" + + +@pytest.mark.asyncio +async def test_get_disk_not_found(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.get method + mock_get = mocker.patch("httpx.AsyncClient.get") + + # Set up the mock response + mock_get.return_value = httpx.Response( + status_code=404, + json={"error": "disk not found"}, + ) + + # Call the get_disk method + with pytest.raises(Exception) as exc: + await client.get_disk(name="mock_disk_name") + + assert str(exc.value) == "disk not found" + + +@pytest.mark.asyncio +async def test_create_disk_success(client, disk_body, mocker: AsyncMock): # noqa: F811 + mock_post = mocker.patch("httpx.AsyncClient.post") + + mock_post.return_value = httpx.Response( + status_code=200, + json={ + "kind": "Disk", + "metadata": {"guid": "test_disk_guid", "name": "test_disk"}, + }, + ) + + response = await client.create_disk(body=disk_body, project_guid="mock_project_guid") + + assert isinstance(response, Munch) + assert response.metadata.guid == "test_disk_guid" + assert response.metadata.name == "test_disk" + + +@pytest.mark.asyncio +async def test_delete_disk_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.delete method + mock_delete = mocker.patch("httpx.AsyncClient.delete") + + # Set up the mock response + mock_delete.return_value = httpx.Response( + status_code=204, + json={"success": True}, + ) + + # Call the delete_disk method + response = await client.delete_disk(name="mock_disk_name") + + # Validate the response + assert response["success"] is True + + +@pytest.mark.asyncio +async def test_delete_disk_not_found(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.delete method + mock_delete = mocker.patch("httpx.AsyncClient.delete") + + # Set up the mock response + mock_delete.return_value = httpx.Response( + status_code=404, + json={"error": "disk not found"}, + ) + + # Call the delete_disk method + with pytest.raises(Exception) as exc: + await client.delete_disk(name="mock_disk_name") + + assert str(exc.value) == "disk not found" diff --git a/tests/async_tests/test_managedservice_async.py b/tests/async_tests/test_managedservice_async.py new file mode 100644 index 0000000..d670583 --- /dev/null +++ b/tests/async_tests/test_managedservice_async.py @@ -0,0 +1,208 @@ +import httpx +import pytest # noqa: F401 +from munch import Munch +from asyncmock import AsyncMock + +from tests.utils.fixtures import async_client as client # noqa: F401 + + +@pytest.mark.asyncio +async def test_list_providers_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.get method + mock_get = mocker.patch("httpx.AsyncClient.get") + + # Set up the mock responses for pagination + mock_get.return_value = httpx.Response( + status_code=200, + json={ + "metadata": {"continue": 1}, + "items": [{"name": "test-provider", "guid": "mock_provider_guid"}], + }, + ) + + # Call the list_providers method + response = await client.list_providers() + + # Validate the response + assert isinstance(response, Munch) + assert response["items"] == [{"name": "test-provider", "guid": "mock_provider_guid"}] + + +@pytest.mark.asyncio +async def test_list_instances_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.get method + mock_get = mocker.patch("httpx.AsyncClient.get") + + # Set up the mock responses for pagination + mock_get.return_value = httpx.Response( + status_code=200, + json={ + "metadata": {"continue": 1}, + "items": [{"name": "test-instance", "guid": "mock_instance_guid"}], + }, + ) + + # Call the list_instances method + response = await client.list_instances() + + # Validate the response + assert isinstance(response, Munch) + assert response["items"] == [{"name": "test-instance", "guid": "mock_instance_guid"}] + + +@pytest.mark.asyncio +async def test_get_instance_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.get method + mock_get = mocker.patch("httpx.AsyncClient.get") + + # Set up the mock response + mock_get.return_value = httpx.Response( + status_code=200, + json={ + "metadata": {"guid": "test_instance_guid", "name": "test_instance"}, + }, + ) + + # Call the get_instance method + response = await client.get_instance(name="mock_instance_name") + + # Validate the response + assert isinstance(response, Munch) + assert response.metadata.guid == "test_instance_guid" + + +@pytest.mark.asyncio +async def test_create_instance_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.post method + mock_post = mocker.patch("httpx.AsyncClient.post") + + # Set up the mock response + mock_post.return_value = httpx.Response( + status_code=201, + json={ + "metadata": {"guid": "test_instance_guid", "name": "test_instance"}, + }, + ) + + # Call the create_instance method + response = await client.create_instance(body={"name": "test_instance"}) + + # Validate the response + assert isinstance(response, Munch) + assert response.metadata.guid == "test_instance_guid" + + +@pytest.mark.asyncio +async def test_delete_instance_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.delete method + mock_delete = mocker.patch("httpx.AsyncClient.delete") + + # Set up the mock response + mock_delete.return_value = httpx.Response( + status_code=204, + json={"success": True}, + ) + + # Call the delete_instance method + response = await client.delete_instance(name="mock_instance_name") + + # Validate the response + assert response["success"] is True + + +@pytest.mark.asyncio +async def test_list_instance_bindings_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.get method + mock_get = mocker.patch("httpx.AsyncClient.get") + + # Set up the mock responses for pagination + mock_get.return_value = httpx.Response( + status_code=200, + json={ + "metadata": {"continue": 1}, + "items": [ + {"name": "test-instance-binding", "guid": "mock_instance_binding_guid"} + ], + }, + ) + + # Call the list_instance_bindings method + response = await client.list_instance_bindings("mock_instance_name") + + # Validate the response + assert isinstance(response, Munch) + assert response["items"] == [ + {"name": "test-instance-binding", "guid": "mock_instance_binding_guid"} + ] + + +@pytest.mark.asyncio +async def test_get_instance_binding_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.get method + mock_get = mocker.patch("httpx.AsyncClient.get") + + # Set up the mock response + mock_get.return_value = httpx.Response( + status_code=200, + json={ + "metadata": { + "guid": "test_instance_binding_guid", + "name": "test_instance_binding", + }, + }, + ) + + # Call the get_instance_binding method + response = await client.get_instance_binding( + name="mock_instance_binding_name", instance_name="mock_instance_name" + ) + + # Validate the response + assert isinstance(response, Munch) + assert response.metadata.guid == "test_instance_binding_guid" + + +@pytest.mark.asyncio +async def test_create_instance_binding_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.post method + mock_post = mocker.patch("httpx.AsyncClient.post") + + # Set up the mock response + mock_post.return_value = httpx.Response( + status_code=201, + json={ + "metadata": { + "guid": "test_instance_binding_guid", + "name": "test_instance_binding", + }, + }, + ) + + # Call the create_instance_binding method + response = await client.create_instance_binding( + body={"name": "test_instance_binding"}, instance_name="mock_instance_name" + ) + + # Validate the response + assert isinstance(response, Munch) + assert response.metadata.guid == "test_instance_binding_guid" + + +@pytest.mark.asyncio +async def test_delete_instance_binding_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.delete method + mock_delete = mocker.patch("httpx.AsyncClient.delete") + + # Set up the mock response + mock_delete.return_value = httpx.Response( + status_code=204, + json={"success": True}, + ) + + # Call the delete_instance_binding method + response = await client.delete_instance_binding( + name="mock_instance_binding_name", instance_name="mock_instance_name" + ) + + # Validate the response + assert response["success"] is True diff --git a/tests/async_tests/test_network_async.py b/tests/async_tests/test_network_async.py new file mode 100644 index 0000000..0512404 --- /dev/null +++ b/tests/async_tests/test_network_async.py @@ -0,0 +1,124 @@ +import httpx +import pytest +import pytest_asyncio # noqa: F401 +from munch import Munch +from asyncmock import AsyncMock + +from tests.data.mock_data import network_body # noqa: F401 +from tests.utils.fixtures import async_client as client # noqa: F401 + + +@pytest.mark.asyncio +async def test_list_networks_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.get method + mock_get = mocker.patch("httpx.AsyncClient.get") + + # Set up the mock responses for pagination + mock_get.return_value = httpx.Response( + status_code=200, + json={ + "metadata": {"continue": 1}, + "items": [{"name": "test-network", "guid": "mock_network_guid"}], + }, + ) + + # Call the list_networks method + response = await client.list_networks() + + # Validate the response + assert isinstance(response, Munch) + assert response["items"] == [{"name": "test-network", "guid": "mock_network_guid"}] + + +@pytest.mark.asyncio +async def test_list_networks_not_found(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.get method + mock_get = mocker.patch("httpx.AsyncClient.get") + + # Set up the mock response + mock_get.return_value = httpx.Response( + status_code=404, + json={"error": "not found"}, + ) + + with pytest.raises(Exception) as exc: + await client.list_networks() + + assert str(exc.value) == "not found" + + +@pytest.mark.asyncio +async def test_create_network_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.post method + mock_post = mocker.patch("httpx.AsyncClient.post") + + # Set up the mock response + mock_post.return_value = httpx.Response( + status_code=201, + json={ + "metadata": {"guid": "mock_network_guid", "name": "test-network"}, + }, + ) + + # Call the create_network method + response = await client.create_network(body=network_body) + + # Validate the response + assert isinstance(response, Munch) + assert response["metadata"]["name"] == "test-network" + + +@pytest.mark.asyncio +async def test_create_network_failure(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.post method + mock_post = mocker.patch("httpx.AsyncClient.post") + + # Set up the mock response + mock_post.return_value = httpx.Response( + status_code=409, + json={"error": "already exists"}, + ) + + with pytest.raises(Exception) as exc: + await client.create_network(body=network_body) + + assert str(exc.value) == "already exists" + + +@pytest.mark.asyncio +async def test_get_network_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.get method + mock_get = mocker.patch("httpx.AsyncClient.get") + + # Set up the mock response + mock_get.return_value = httpx.Response( + status_code=200, + json={ + "metadata": {"guid": "mock_network_guid", "name": "test-network"}, + }, + ) + + # Call the get_network method + response = await client.get_network(name="test-network") + + # Validate the response + assert isinstance(response, Munch) + assert response["metadata"]["guid"] == "mock_network_guid" + + +@pytest.mark.asyncio +async def test_delete_network_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.delete method + mock_delete = mocker.patch("httpx.AsyncClient.delete") + + # Set up the mock response + mock_delete.return_value = httpx.Response( + status_code=204, + json={"success": True}, + ) + + # Call the delete_network method + response = await client.delete_network(name="test-network") + + # Validate the response + assert response["success"] is True diff --git a/tests/async_tests/test_package.py b/tests/async_tests/test_package_async.py similarity index 54% rename from tests/async_tests/test_package.py rename to tests/async_tests/test_package_async.py index 329b0da..cc40cea 100644 --- a/tests/async_tests/test_package.py +++ b/tests/async_tests/test_package_async.py @@ -4,7 +4,7 @@ from munch import Munch from asyncmock import AsyncMock -from tests.utils.util import package_body +from tests.data.mock_data import package_body from tests.utils.fixtures import async_client as client # noqa: F401 @@ -57,3 +57,50 @@ async def test_create_package_success(client, mocker: AsyncMock): # noqa: F811 assert isinstance(response, Munch) assert response["metadata"]["guid"] == "mock_package_guid" + + +@pytest.mark.asyncio +async def test_get_package_success(client, mocker: AsyncMock): # noqa: F811 + mock_get = mocker.patch("httpx.AsyncClient.get") + + mock_get.return_value = httpx.Response( + status_code=200, + json={ + "kind": "Package", + "metadata": {"name": "test-package", "guid": "mock_package_guid"}, + "spec": {"users": [{"userGUID": "mock_user_guid", "emailID": "mock_email"}]}, + }, + ) + + response = await client.get_package("mock_package_guid") + + assert isinstance(response, Munch) + assert response["metadata"]["guid"] == "mock_package_guid" + + +@pytest.mark.asyncio +async def test_get_package_not_found(client, mocker: AsyncMock): # noqa: F811 + mock_get = mocker.patch("httpx.AsyncClient.get") + + mock_get.return_value = httpx.Response( + status_code=404, + json={"error": "not found"}, + ) + + with pytest.raises(Exception) as exc: + await client.get_package("mock_package_guid") + assert str(exc.value) == "not found" + + +@pytest.mark.asyncio +async def test_delete_package_success(client, mocker: AsyncMock): # noqa: F811 + mock_delete = mocker.patch("httpx.AsyncClient.delete") + + mock_delete.return_value = httpx.Response( + status_code=204, + json={"success": True}, + ) + + response = await client.delete_package("mock_package_guid") + + assert response["success"] is True diff --git a/tests/async_tests/test_project.py b/tests/async_tests/test_project_async.py similarity index 98% rename from tests/async_tests/test_project.py rename to tests/async_tests/test_project_async.py index 1e940ae..8f4956c 100644 --- a/tests/async_tests/test_project.py +++ b/tests/async_tests/test_project_async.py @@ -4,7 +4,7 @@ from munch import Munch from asyncmock import AsyncMock -from tests.utils.util import project_body +from tests.data.mock_data import project_body from tests.utils.fixtures import async_client as client # noqa: F401 diff --git a/tests/async_tests/test_secret_async.py b/tests/async_tests/test_secret_async.py new file mode 100644 index 0000000..3e86a65 --- /dev/null +++ b/tests/async_tests/test_secret_async.py @@ -0,0 +1,146 @@ +import httpx +import pytest +import pytest_asyncio # noqa: F401 +from munch import Munch +from asyncmock import AsyncMock + +from tests.data.mock_data import secret_body # noqa: F401 +from tests.utils.fixtures import async_client as client # noqa: F401 + + +@pytest.mark.asyncio +async def test_list_secrets_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.get method + mock_get = mocker.patch("httpx.AsyncClient.get") + + # Set up mock responses for pagination + mock_get.return_value = httpx.Response( + status_code=200, + json={ + "metadata": {"continue": 1}, + "items": [{"name": "test-secret", "guid": "mock_secret_guid"}], + }, + ) + + # Call the list_secrets method + response = await client.list_secrets() + + # Validate the response + assert isinstance(response, Munch) + assert response["items"] == [{"name": "test-secret", "guid": "mock_secret_guid"}] + + +@pytest.mark.asyncio +async def test_list_secrets_not_found(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.get method + mock_get = mocker.patch("httpx.AsyncClient.get") + + # Set up the mock response + mock_get.return_value = httpx.Response( + status_code=404, + json={"error": "not found"}, + ) + + with pytest.raises(Exception) as exc: + await client.list_secrets() + + assert str(exc.value) == "not found" + + +@pytest.mark.asyncio +async def test_create_secret_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.post method + mock_post = mocker.patch("httpx.AsyncClient.post") + + # Set up the mock response + mock_post.return_value = httpx.Response( + status_code=201, + json={ + "metadata": {"guid": "test_secret_guid", "name": "test_secret"}, + }, + ) + + # Call the create_secret method + response = await client.create_secret(secret_body) + + # Validate the response + assert isinstance(response, Munch) + assert response.metadata.guid == "test_secret_guid" + + +@pytest.mark.asyncio +async def test_create_secret_already_exists(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.post method + mock_post = mocker.patch("httpx.AsyncClient.post") + + # Set up the mock response + mock_post.return_value = httpx.Response( + status_code=409, + json={"error": "secret already exists"}, + ) + + with pytest.raises(Exception) as exc: + await client.create_secret(secret_body) + + assert str(exc.value) == "secret already exists" + + +@pytest.mark.asyncio +async def test_update_secret_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.put method + mock_put = mocker.patch("httpx.AsyncClient.put") + + # Set up the mock response + mock_put.return_value = httpx.Response( + status_code=200, + json={ + "metadata": {"guid": "test_secret_guid", "name": "test_secret"}, + }, + ) + + # Call the update_secret method + response = await client.update_secret("mock_secret_guid", body=secret_body) + + # Validate the response + assert isinstance(response, Munch) + assert response.metadata.guid == "test_secret_guid" + + +@pytest.mark.asyncio +async def test_delete_secret_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.delete method + mock_delete = mocker.patch("httpx.AsyncClient.delete") + + # Set up the mock response + mock_delete.return_value = httpx.Response( + status_code=204, + json={"success": True}, + ) + + # Call the delete_secret method + response = await client.delete_secret("mock_secret_guid") + + # Validate the response + assert response == {"success": True} + + +@pytest.mark.asyncio +async def test_get_secret_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.get method + mock_get = mocker.patch("httpx.AsyncClient.get") + + # Set up the mock response + mock_get.return_value = httpx.Response( + status_code=200, + json={ + "metadata": {"guid": "test_secret_guid", "name": "test_secret"}, + }, + ) + + # Call the get_secret method + response = await client.get_secret("mock_secret_guid") + + # Validate the response + assert isinstance(response, Munch) + assert response.metadata.guid == "test_secret_guid" + assert response.metadata.name == "test_secret" diff --git a/tests/async_tests/test_staticroute_async.py b/tests/async_tests/test_staticroute_async.py new file mode 100644 index 0000000..91e7da3 --- /dev/null +++ b/tests/async_tests/test_staticroute_async.py @@ -0,0 +1,148 @@ +import httpx +import pytest +from munch import Munch +from asyncmock import AsyncMock + +from tests.data.mock_data import staticroute_body # noqa: F401 +from tests.utils.fixtures import async_client as client # noqa: F401 + + +@pytest.mark.asyncio +async def test_list_staticroutes_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.get method + mock_get = mocker.patch("httpx.AsyncClient.get") + + # Set up the mock responses for pagination + mock_get.return_value = httpx.Response( + status_code=200, + json={ + "metadata": {"continue": 1}, + "items": [{"name": "test-staticroute", "guid": "mock_staticroute_guid"}], + }, + ) + + # Call the list_staticroutes method + response = await client.list_staticroutes() + + # Validate the response + assert isinstance(response, Munch) + assert response["items"] == [ + {"name": "test-staticroute", "guid": "mock_staticroute_guid"} + ] + + +@pytest.mark.asyncio +async def test_list_staticroutes_not_found(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.get method + mock_get = mocker.patch("httpx.AsyncClient.get") + + # Set up the mock response + mock_get.return_value = httpx.Response( + status_code=404, + json={"error": "not found"}, + ) + + with pytest.raises(Exception) as exc: + await client.list_staticroutes() + + assert str(exc.value) == "not found" + + +@pytest.mark.asyncio +async def test_create_staticroute_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.post method + mock_post = mocker.patch("httpx.AsyncClient.post") + + # Set up the mock response + mock_post.return_value = httpx.Response( + status_code=201, + json={ + "metadata": {"guid": "test_staticroute_guid", "name": "test_staticroute"}, + }, + ) + + # Call the create_staticroute method + response = await client.create_staticroute(body=staticroute_body) + + # Validate the response + assert isinstance(response, Munch) + assert response.metadata.guid == "test_staticroute_guid" + + +@pytest.mark.asyncio +async def test_create_staticroute_bad_request(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.post method + mock_post = mocker.patch("httpx.AsyncClient.post") + + # Set up the mock response + mock_post.return_value = httpx.Response( + status_code=409, + json={"error": "already exists"}, + ) + + with pytest.raises(Exception) as exc: + await client.create_staticroute(body=staticroute_body) + + assert str(exc.value) == "already exists" + + +@pytest.mark.asyncio +async def test_get_staticroute_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.get method + mock_get = mocker.patch("httpx.AsyncClient.get") + + # Set up the mock response + mock_get.return_value = httpx.Response( + status_code=200, + json={ + "metadata": {"guid": "test_staticroute_guid", "name": "test_staticroute"}, + }, + ) + + # Call the get_staticroute method + response = await client.get_staticroute(name="mock_staticroute_name") + + # Validate the response + assert isinstance(response, Munch) + assert response.metadata.guid == "test_staticroute_guid" + + +@pytest.mark.asyncio +async def test_update_staticroute_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.put method + mock_put = mocker.patch("httpx.AsyncClient.put") + + # Set up the mock response + mock_put.return_value = httpx.Response( + status_code=200, + json={ + "metadata": {"guid": "test_staticroute_guid", "name": "test_staticroute"}, + }, + ) + + # Call the update_staticroute method + response = await client.update_staticroute( + name="mock_staticroute_name", body=staticroute_body + ) + + # Validate the response + assert isinstance(response, Munch) + assert response.metadata.guid == "test_staticroute_guid" + + +@pytest.mark.asyncio +async def test_delete_staticroute_success(client, mocker: AsyncMock): # noqa: F811 + # Mock the httpx.AsyncClient.delete method + mock_delete = mocker.patch("httpx.AsyncClient.delete") + + # Set up the mock response + mock_delete.return_value = httpx.Response( + status_code=204, + json={"success": True}, + ) + + # Call the delete_staticroute method + response = await client.delete_staticroute(name="mock_staticroute_name") + + # Validate the response + assert response["success"] is True diff --git a/tests/utils/util.py b/tests/data/mock_data.py similarity index 100% rename from tests/utils/util.py rename to tests/data/mock_data.py diff --git a/tests/sync_tests/test_config.py b/tests/sync_tests/test_config.py index 9bfa89a..3d5edf7 100644 --- a/tests/sync_tests/test_config.py +++ b/tests/sync_tests/test_config.py @@ -1,6 +1,6 @@ import json from rapyuta_io_sdk_v2.config import Configuration -from tests.utils.util import mock_config # noqa: F401 +from tests.data.mock_data import mock_config # noqa: F401 def test_from_file(mocker): diff --git a/tests/sync_tests/test_configtree.py b/tests/sync_tests/test_configtree.py index e473a65..978e94c 100644 --- a/tests/sync_tests/test_configtree.py +++ b/tests/sync_tests/test_configtree.py @@ -1,13 +1,13 @@ import httpx import pytest from munch import Munch -from pytest_mock import MockerFixture +from pytest_mock import MockFixture -from tests.utils.util import configtree_body # noqa: F401 +from tests.data.mock_data import configtree_body # noqa: F401 from tests.utils.fixtures import client # noqa: F401 -def test_list_configtrees_success(client, mocker: MockerFixture): # noqa: F811 +def test_list_configtrees_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.get method mock_get = mocker.patch("httpx.Client.get") @@ -20,17 +20,6 @@ def test_list_configtrees_success(client, mocker: MockerFixture): # noqa: F811 }, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - }.items() - if v is not None - } - # Call the list_configtrees method response = client.list_configtrees() @@ -41,7 +30,7 @@ def test_list_configtrees_success(client, mocker: MockerFixture): # noqa: F811 ] -def test_list_configtrees_bad_gateway(client, mocker: MockerFixture): # noqa: F811 +def test_list_configtrees_bad_gateway(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.get method mock_get = mocker.patch("httpx.Client.get") @@ -51,13 +40,6 @@ def test_list_configtrees_bad_gateway(client, mocker: MockerFixture): # noqa: F json={"error": "bad gateway"}, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True: { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - } - # Call the list_configtrees method with pytest.raises(Exception) as exc: client.list_configtrees() @@ -65,7 +47,7 @@ def test_list_configtrees_bad_gateway(client, mocker: MockerFixture): # noqa: F assert str(exc.value) == "bad gateway" -def test_create_configtree_success(client, mocker: MockerFixture): # noqa: F811 +def test_create_configtree_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.post method mock_post = mocker.patch("httpx.Client.post") @@ -77,13 +59,6 @@ def test_create_configtree_success(client, mocker: MockerFixture): # noqa: F811 }, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True: { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - } - # Call the create_configtree method response = client.create_configtree(configtree_body) @@ -92,7 +67,7 @@ def test_create_configtree_success(client, mocker: MockerFixture): # noqa: F811 assert response["metadata"]["guid"] == "test_configtree_guid" -def test_create_configtree_service_unavailable(client, mocker: MockerFixture): # noqa: F811 +def test_create_configtree_service_unavailable(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.post method mock_post = mocker.patch("httpx.Client.post") @@ -102,13 +77,6 @@ def test_create_configtree_service_unavailable(client, mocker: MockerFixture): json={"error": "service unavailable"}, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True: { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - } - # Call the create_configtree method with pytest.raises(Exception) as exc: client.create_configtree(configtree_body) @@ -116,7 +84,7 @@ def test_create_configtree_service_unavailable(client, mocker: MockerFixture): assert str(exc.value) == "service unavailable" -def test_get_configtree_success(client, mocker: MockerFixture): # noqa: F811 +def test_get_configtree_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.get method mock_get = mocker.patch("httpx.Client.get") @@ -128,17 +96,6 @@ def test_get_configtree_success(client, mocker: MockerFixture): # noqa: F811 }, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True, **kwargs: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": kwargs.get("project_guid") if with_project else None, - }.items() - if v is not None - } - # Call the get_configtree method response = client.get_configtree(name="mock_configtree_name") @@ -148,7 +105,7 @@ def test_get_configtree_success(client, mocker: MockerFixture): # noqa: F811 assert response.metadata.name == "test_configtree" -def test_set_configtree_revision_success(client, mocker: MockerFixture): # noqa: F811 +def test_set_configtree_revision_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.put method mock_put = mocker.patch("httpx.Client.put") @@ -160,17 +117,6 @@ def test_set_configtree_revision_success(client, mocker: MockerFixture): # noqa }, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True, **kwargs: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": kwargs.get("project_guid") if with_project else None, - }.items() - if v is not None - } - # Call the set_configtree_revision method response = client.set_configtree_revision( name="mock_configtree_name", configtree=configtree_body @@ -182,7 +128,7 @@ def test_set_configtree_revision_success(client, mocker: MockerFixture): # noqa assert response.metadata.name == "test_configtree" -def test_update_configtree_success(client, mocker: MockerFixture): # noqa: F811 +def test_update_configtree_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.put method mock_put = mocker.patch("httpx.Client.put") @@ -194,17 +140,6 @@ def test_update_configtree_success(client, mocker: MockerFixture): # noqa: F811 }, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True, **kwargs: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": kwargs.get("project_guid") if with_project else None, - }.items() - if v is not None - } - # Call the update_configtree method response = client.update_configtree(name="mock_configtree_name", body=configtree_body) @@ -214,7 +149,7 @@ def test_update_configtree_success(client, mocker: MockerFixture): # noqa: F811 assert response.metadata.name == "test_configtree" -def test_delete_configtree_success(client, mocker: MockerFixture): # noqa: F811 +def test_delete_configtree_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.delete method mock_delete = mocker.patch("httpx.Client.delete") @@ -224,17 +159,6 @@ def test_delete_configtree_success(client, mocker: MockerFixture): # noqa: F811 json={"success": True}, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True, **kwargs: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": kwargs.get("project_guid") if with_project else None, - }.items() - if v is not None - } - # Call the delete_configtree method response = client.delete_configtree(name="mock_configtree_name") @@ -242,7 +166,7 @@ def test_delete_configtree_success(client, mocker: MockerFixture): # noqa: F811 assert response["success"] is True -def test_list_revisions_success(client, mocker: MockerFixture): # noqa: F811 +def test_list_revisions_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.get method mock_get = mocker.patch("httpx.Client.get") @@ -255,17 +179,6 @@ def test_list_revisions_success(client, mocker: MockerFixture): # noqa: F811 }, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - }.items() - if v is not None - } - # Call the list_revisions method response = client.list_revisions(name="mock_configtree_name") @@ -276,7 +189,7 @@ def test_list_revisions_success(client, mocker: MockerFixture): # noqa: F811 ] -def test_create_revision_success(client, mocker: MockerFixture): # noqa: F811 +def test_create_revision_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.post method mock_post = mocker.patch("httpx.Client.post") @@ -288,13 +201,6 @@ def test_create_revision_success(client, mocker: MockerFixture): # noqa: F811 }, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True, **kwargs: { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": kwargs.get("project_guid") if with_project else None, - } - # Call the create_revision method response = client.create_revision(name="mock_configtree_name", body=configtree_body) @@ -303,7 +209,7 @@ def test_create_revision_success(client, mocker: MockerFixture): # noqa: F811 assert response["metadata"]["guid"] == "test_revision_guid" -def test_put_keys_in_revision_success(client, mocker: MockerFixture): # noqa: F811 +def test_put_keys_in_revision_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.put method mock_put = mocker.patch("httpx.Client.put") @@ -315,22 +221,11 @@ def test_put_keys_in_revision_success(client, mocker: MockerFixture): # noqa: F }, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True, **kwargs: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": kwargs.get("project_guid") if with_project else None, - }.items() - if v is not None - } - # Call the put_keys_in_revision method response = client.put_keys_in_revision( name="mock_configtree_name", revision_id="mock_revision_id", - configValues=["mock_value1", "mock_value2"], + config_values=["mock_value1", "mock_value2"], ) # Validate the response @@ -339,7 +234,7 @@ def test_put_keys_in_revision_success(client, mocker: MockerFixture): # noqa: F assert response.metadata.name == "test_revision" -def test_commit_revision_success(client, mocker: MockerFixture): # noqa: F811 +def test_commit_revision_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.put method mock_patch = mocker.patch("httpx.Client.patch") @@ -351,22 +246,11 @@ def test_commit_revision_success(client, mocker: MockerFixture): # noqa: F811 }, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True, **kwargs: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": kwargs.get("project_guid") if with_project else None, - }.items() - if v is not None - } - # Call the commit_revision method response = client.commit_revision( name="mock_configtree_name", revision_id="mock_revision_id", - configTreeRevision=configtree_body, + config_tree_revision=configtree_body, ) # Validate the response @@ -375,7 +259,7 @@ def test_commit_revision_success(client, mocker: MockerFixture): # noqa: F811 assert response.metadata.name == "test_revision" -def test_get_key_in_revision(client, mocker: MockerFixture): # noqa: F811 +def test_get_key_in_revision(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.get method mock_get = mocker.patch("httpx.Client.get") @@ -387,17 +271,6 @@ def test_get_key_in_revision(client, mocker: MockerFixture): # noqa: F811 }, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True, **kwargs: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": kwargs.get("project_guid") if with_project else None, - }.items() - if v is not None - } - # Call the get_key_in_revision method response = client.get_key_in_revision( name="mock_configtree_name", revision_id="mock_revision_id", key="mock_key" @@ -409,7 +282,7 @@ def test_get_key_in_revision(client, mocker: MockerFixture): # noqa: F811 assert response.metadata.name == "test_revision" -def test_put_key_in_revision_success(client, mocker: MockerFixture): # noqa: F811 +def test_put_key_in_revision_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.put method mock_put = mocker.patch("httpx.Client.put") @@ -421,17 +294,6 @@ def test_put_key_in_revision_success(client, mocker: MockerFixture): # noqa: F8 }, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True, **kwargs: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": kwargs.get("project_guid") if with_project else None, - }.items() - if v is not None - } - # Call the put_key_in_revision method response = client.put_key_in_revision( name="mock_configtree_name", revision_id="mock_revision_id", key="mock_key" @@ -443,7 +305,7 @@ def test_put_key_in_revision_success(client, mocker: MockerFixture): # noqa: F8 assert response.metadata.name == "test_revision" -def test_delete_key_in_revision_success(client, mocker: MockerFixture): # noqa: F811 +def test_delete_key_in_revision_success(client, mocker: MockFixture): # noqa: F811 mock_delete = mocker.patch("httpx.Client.delete") mock_delete.return_value = httpx.Response( @@ -451,16 +313,6 @@ def test_delete_key_in_revision_success(client, mocker: MockerFixture): # noqa: json={"success": True}, ) - client.config.get_headers = lambda with_project=True, **kwargs: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": kwargs.get("project_guid") if with_project else None, - }.items() - if v is not None - } - response = client.delete_key_in_revision( name="mock_configtree_name", revision_id="mock_revision_id", key="mock_key" ) @@ -468,7 +320,7 @@ def test_delete_key_in_revision_success(client, mocker: MockerFixture): # noqa: assert response["success"] is True -def test_rename_key_in_revision_success(client, mocker: MockerFixture): # noqa: F811 +def test_rename_key_in_revision_success(client, mocker: MockFixture): # noqa: F811 mock_patch = mocker.patch("httpx.Client.patch") mock_patch.return_value = httpx.Response( @@ -478,21 +330,11 @@ def test_rename_key_in_revision_success(client, mocker: MockerFixture): # noqa: }, ) - client.config.get_headers = lambda with_project=True, **kwargs: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": kwargs.get("project_guid") if with_project else None, - }.items() - if v is not None - } - response = client.rename_key_in_revision( name="mock_configtree_name", revision_id="mock_revision_id", key="mock_key", - configKeyRename={"metadata": {"name": "test_key"}}, + config_key_rename={"metadata": {"name": "test_key"}}, ) assert isinstance(response, Munch) diff --git a/tests/sync_tests/test_deployment.py b/tests/sync_tests/test_deployment.py index 73d243b..3e30af4 100644 --- a/tests/sync_tests/test_deployment.py +++ b/tests/sync_tests/test_deployment.py @@ -1,13 +1,13 @@ import httpx import pytest from munch import Munch -from pytest_mock import MockerFixture +from pytest_mock import MockFixture -from tests.utils.util import deployment_body # noqa: F401 +from tests.data.mock_data import deployment_body # noqa: F401 from tests.utils.fixtures import client # noqa: F401 -def test_list_deployments_success(client, mocker: MockerFixture): # noqa: F811 +def test_list_deployments_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.get method mock_get = mocker.patch("httpx.Client.get") @@ -20,17 +20,6 @@ def test_list_deployments_success(client, mocker: MockerFixture): # noqa: F811 }, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - }.items() - if v is not None - } - # Call the list_deployments method response = client.list_deployments() @@ -41,7 +30,7 @@ def test_list_deployments_success(client, mocker: MockerFixture): # noqa: F811 ] -def test_list_deployments_not_found(client, mocker: MockerFixture): # noqa: F811 +def test_list_deployments_not_found(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.get method mock_get = mocker.patch("httpx.Client.get") @@ -51,20 +40,13 @@ def test_list_deployments_not_found(client, mocker: MockerFixture): # noqa: F81 json={"error": "not found"}, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True: { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - } - with pytest.raises(Exception) as exc: client.list_deployments() assert str(exc.value) == "not found" -def test_get_deployment_success(client, mocker: MockerFixture): # noqa: F811 +def test_get_deployment_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.get method mock_get = mocker.patch("httpx.Client.get") @@ -77,17 +59,6 @@ def test_get_deployment_success(client, mocker: MockerFixture): # noqa: F811 }, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=False, **kwargs: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": kwargs.get("project_guid") if with_project else None, - }.items() - if v is not None - } - # Call the get_deployment method response = client.get_deployment(name="mock_deployment_name") @@ -96,7 +67,7 @@ def test_get_deployment_success(client, mocker: MockerFixture): # noqa: F811 assert response["metadata"]["guid"] == "test_deployment_guid" -def test_get_deployment_not_found(client, mocker: MockerFixture): # noqa: F811 +def test_get_deployment_not_found(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.get method mock_get = mocker.patch("httpx.Client.get") @@ -106,17 +77,6 @@ def test_get_deployment_not_found(client, mocker: MockerFixture): # noqa: F811 json={"error": "deployment not found"}, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=False, **kwargs: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": kwargs.get("project_guid") if with_project else None, - }.items() - if v is not None - } - # Call the get_deployment method with pytest.raises(Exception) as exc: client.get_deployment(name="mock_deployment_name") @@ -124,7 +84,7 @@ def test_get_deployment_not_found(client, mocker: MockerFixture): # noqa: F811 assert str(exc.value) == "deployment not found" -def test_create_deployment_success(client, deployment_body, mocker: MockerFixture): # noqa: F811 +def test_create_deployment_success(client, deployment_body, mocker: MockFixture): # noqa: F811 mock_post = mocker.patch("httpx.Client.post") mock_post.return_value = httpx.Response( @@ -135,23 +95,13 @@ def test_create_deployment_success(client, deployment_body, mocker: MockerFixtur }, ) - client.config.get_headers = lambda with_project=True, **kwargs: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": kwargs.get("project_guid") if with_project else None, - }.items() - if v is not None - } - response = client.create_deployment(body=deployment_body) assert isinstance(response, Munch) assert response["metadata"]["guid"] == "test_deployment_guid" -def test_create_deployment_unauthorized(client, deployment_body, mocker: MockerFixture): # noqa: F811 +def test_create_deployment_unauthorized(client, deployment_body, mocker: MockFixture): # noqa: F811 mock_post = mocker.patch("httpx.Client.post") mock_post.return_value = httpx.Response( @@ -159,23 +109,13 @@ def test_create_deployment_unauthorized(client, deployment_body, mocker: MockerF json={"error": "unauthorized"}, ) - client.config.get_headers = lambda with_project=True, **kwargs: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": kwargs.get("project_guid") if with_project else None, - }.items() - if v is not None - } - with pytest.raises(Exception) as exc: client.create_deployment(body=deployment_body) assert str(exc.value) == "unauthorized" -def test_update_deployment_success(client, deployment_body, mocker: MockerFixture): # noqa: F811 +def test_update_deployment_success(client, deployment_body, mocker: MockFixture): # noqa: F811 mock_put = mocker.patch("httpx.Client.put") mock_put.return_value = httpx.Response( @@ -186,37 +126,17 @@ def test_update_deployment_success(client, deployment_body, mocker: MockerFixtur }, ) - client.config.get_headers = lambda with_project=True, **kwargs: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": kwargs.get("project_guid") if with_project else None, - }.items() - if v is not None - } - response = client.update_deployment(name="mock_deployment_name", body=deployment_body) assert isinstance(response, Munch) assert response["metadata"]["guid"] == "test_deployment_guid" -def test_delete_deployment_success(client, mocker: MockerFixture): # noqa: F811 +def test_delete_deployment_success(client, mocker: MockFixture): # noqa: F811 mock_delete = mocker.patch("httpx.Client.delete") mock_delete.return_value = httpx.Response(status_code=204, json={"success": True}) - client.config.get_headers = lambda with_project=True, **kwargs: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": kwargs.get("project_guid") if with_project else None, - }.items() - if v is not None - } - response = client.delete_deployment(name="mock_deployment_name") assert response["success"] is True diff --git a/tests/sync_tests/test_disk.py b/tests/sync_tests/test_disk.py index 1214826..cb9e01e 100644 --- a/tests/sync_tests/test_disk.py +++ b/tests/sync_tests/test_disk.py @@ -1,13 +1,13 @@ import httpx import pytest from munch import Munch -from pytest_mock import MockerFixture +from pytest_mock import MockFixture -from tests.utils.util import disk_body # noqa: F401 +from tests.data.mock_data import disk_body # noqa: F401 from tests.utils.fixtures import client # noqa: F401 -def test_list_disks_success(client, mocker: MockerFixture): # noqa: F811 +def test_list_disks_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.get method mock_get = mocker.patch("httpx.Client.get") @@ -20,17 +20,6 @@ def test_list_disks_success(client, mocker: MockerFixture): # noqa: F811 }, ) - # Override get_headers to return mocked headers without None values - client.config.get_headers = lambda with_project=True: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - }.items() - if v is not None - } - # Call the list_disks method response = client.list_disks() @@ -39,7 +28,7 @@ def test_list_disks_success(client, mocker: MockerFixture): # noqa: F811 assert response["items"] == [{"name": "test-disk", "guid": "mock_disk_guid"}] -def test_list_disks_not_found(client, mocker: MockerFixture): # noqa: F811 +def test_list_disks_not_found(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.get method mock_get = mocker.patch("httpx.Client.get") @@ -49,20 +38,13 @@ def test_list_disks_not_found(client, mocker: MockerFixture): # noqa: F811 json={"error": "not found"}, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True: { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - } - with pytest.raises(Exception) as exc: client.list_disks() assert str(exc.value) == "not found" -def test_get_disk_success(client, mocker: MockerFixture): # noqa: F811 +def test_get_disk_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.get method mock_get = mocker.patch("httpx.Client.get") @@ -75,17 +57,6 @@ def test_get_disk_success(client, mocker: MockerFixture): # noqa: F811 }, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=False, **kwargs: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": kwargs.get("project_guid") if with_project else None, - }.items() - if v is not None - } - # Call the get_disk method response = client.get_disk(name="mock_disk_name") @@ -94,7 +65,7 @@ def test_get_disk_success(client, mocker: MockerFixture): # noqa: F811 assert response["metadata"]["guid"] == "test_disk_guid" -def test_get_disk_not_found(client, mocker: MockerFixture): # noqa: F811 +def test_get_disk_not_found(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.get method mock_get = mocker.patch("httpx.Client.get") @@ -104,17 +75,6 @@ def test_get_disk_not_found(client, mocker: MockerFixture): # noqa: F811 json={"error": "disk not found"}, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=False, **kwargs: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": kwargs.get("project_guid") if with_project else None, - }.items() - if v is not None - } - # Call the get_disk method with pytest.raises(Exception) as exc: client.get_disk(name="mock_disk_name") @@ -122,7 +82,7 @@ def test_get_disk_not_found(client, mocker: MockerFixture): # noqa: F811 assert str(exc.value) == "disk not found" -def test_create_disk_success(client, disk_body, mocker: MockerFixture): # noqa: F811 +def test_create_disk_success(client, disk_body, mocker: MockFixture): # noqa: F811 mock_post = mocker.patch("httpx.Client.post") mock_post.return_value = httpx.Response( @@ -133,16 +93,6 @@ def test_create_disk_success(client, disk_body, mocker: MockerFixture): # noqa: }, ) - client.config.get_headers = lambda with_project=True, **kwargs: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": kwargs.get("project_guid") if with_project else None, - }.items() - if v is not None - } - response = client.create_disk(body=disk_body, project_guid="mock_project_guid") assert isinstance(response, Munch) @@ -150,7 +100,7 @@ def test_create_disk_success(client, disk_body, mocker: MockerFixture): # noqa: assert response.metadata.name == "test_disk" -def test_delete_disk_success(client, mocker: MockerFixture): # noqa: F811 +def test_delete_disk_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.delete method mock_delete = mocker.patch("httpx.Client.delete") @@ -160,17 +110,6 @@ def test_delete_disk_success(client, mocker: MockerFixture): # noqa: F811 json={"success": True}, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=False, **kwargs: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": kwargs.get("project_guid") if with_project else None, - }.items() - if v is not None - } - # Call the delete_disk method response = client.delete_disk(name="mock_disk_name") @@ -178,7 +117,7 @@ def test_delete_disk_success(client, mocker: MockerFixture): # noqa: F811 assert response["success"] is True -def test_delete_disk_not_found(client, mocker: MockerFixture): # noqa: F811 +def test_delete_disk_not_found(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.delete method mock_delete = mocker.patch("httpx.Client.delete") @@ -188,17 +127,6 @@ def test_delete_disk_not_found(client, mocker: MockerFixture): # noqa: F811 json={"error": "disk not found"}, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=False, **kwargs: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": kwargs.get("project_guid") if with_project else None, - }.items() - if v is not None - } - # Call the delete_disk method with pytest.raises(Exception) as exc: client.delete_disk(name="mock_disk_name") diff --git a/tests/sync_tests/test_main.py b/tests/sync_tests/test_main.py index f1f0ebe..b906dae 100644 --- a/tests/sync_tests/test_main.py +++ b/tests/sync_tests/test_main.py @@ -1,11 +1,11 @@ import httpx import pytest -from pytest_mock import MockerFixture +from pytest_mock import MockFixture from tests.utils.fixtures import client # noqa: F401 -def test_get_auth_token_success(client, mocker: MockerFixture): # noqa: F811 +def test_get_auth_token_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.post method mock_post = mocker.patch("httpx.Client.post") @@ -26,7 +26,7 @@ def test_get_auth_token_success(client, mocker: MockerFixture): # noqa: F811 assert response == "mock_token" -def test_login_success(client, mocker: MockerFixture): # noqa: F811 +def test_login_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.post method mock_post = mocker.patch("httpx.Client.post") @@ -42,7 +42,7 @@ def test_login_success(client, mocker: MockerFixture): # noqa: F811 assert client.config.auth_token == "mock_token_2" -def test_login_failure(client, mocker: MockerFixture): # noqa: F811 +def test_login_failure(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.post method mock_post = mocker.patch("httpx.Client.post") diff --git a/tests/sync_tests/test_managedservice.py b/tests/sync_tests/test_managedservice.py index 074f737..cdd08d3 100644 --- a/tests/sync_tests/test_managedservice.py +++ b/tests/sync_tests/test_managedservice.py @@ -1,12 +1,12 @@ import httpx import pytest # noqa: F401 from munch import Munch -from pytest_mock import MockerFixture +from pytest_mock import MockFixture from tests.utils.fixtures import client # noqa: F401 -def test_list_providers_success(client, mocker: MockerFixture): # noqa: F811 +def test_list_providers_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.get method mock_get = mocker.patch("httpx.Client.get") @@ -19,17 +19,6 @@ def test_list_providers_success(client, mocker: MockerFixture): # noqa: F811 }, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - }.items() - if v is not None - } - # Call the list_providers method response = client.list_providers() @@ -38,7 +27,7 @@ def test_list_providers_success(client, mocker: MockerFixture): # noqa: F811 assert response["items"] == [{"name": "test-provider", "guid": "mock_provider_guid"}] -def test_list_instances_success(client, mocker: MockerFixture): # noqa: F811 +def test_list_instances_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.get method mock_get = mocker.patch("httpx.Client.get") @@ -51,17 +40,6 @@ def test_list_instances_success(client, mocker: MockerFixture): # noqa: F811 }, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - }.items() - if v is not None - } - # Call the list_instances method response = client.list_instances() @@ -70,7 +48,7 @@ def test_list_instances_success(client, mocker: MockerFixture): # noqa: F811 assert response["items"] == [{"name": "test-instance", "guid": "mock_instance_guid"}] -def test_get_instance_success(client, mocker: MockerFixture): # noqa: F811 +def test_get_instance_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.get method mock_get = mocker.patch("httpx.Client.get") @@ -82,17 +60,6 @@ def test_get_instance_success(client, mocker: MockerFixture): # noqa: F811 }, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - }.items() - if v is not None - } - # Call the get_instance method response = client.get_instance(name="mock_instance_name") @@ -101,7 +68,7 @@ def test_get_instance_success(client, mocker: MockerFixture): # noqa: F811 assert response.metadata.guid == "test_instance_guid" -def test_create_instance_success(client, mocker: MockerFixture): # noqa: F811 +def test_create_instance_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.post method mock_post = mocker.patch("httpx.Client.post") @@ -113,17 +80,6 @@ def test_create_instance_success(client, mocker: MockerFixture): # noqa: F811 }, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - }.items() - if v is not None - } - # Call the create_instance method response = client.create_instance(body={"name": "test_instance"}) @@ -132,7 +88,7 @@ def test_create_instance_success(client, mocker: MockerFixture): # noqa: F811 assert response.metadata.guid == "test_instance_guid" -def test_delete_instance_success(client, mocker: MockerFixture): # noqa: F811 +def test_delete_instance_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.delete method mock_delete = mocker.patch("httpx.Client.delete") @@ -142,17 +98,6 @@ def test_delete_instance_success(client, mocker: MockerFixture): # noqa: F811 json={"success": True}, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - }.items() - if v is not None - } - # Call the delete_instance method response = client.delete_instance(name="mock_instance_name") @@ -160,7 +105,7 @@ def test_delete_instance_success(client, mocker: MockerFixture): # noqa: F811 assert response["success"] is True -def test_list_instance_bindings_success(client, mocker: MockerFixture): # noqa: F811 +def test_list_instance_bindings_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.get method mock_get = mocker.patch("httpx.Client.get") @@ -175,17 +120,6 @@ def test_list_instance_bindings_success(client, mocker: MockerFixture): # noqa: }, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - }.items() - if v is not None - } - # Call the list_instance_bindings method response = client.list_instance_bindings("mock_instance_name") @@ -196,7 +130,7 @@ def test_list_instance_bindings_success(client, mocker: MockerFixture): # noqa: ] -def test_get_instance_binding_success(client, mocker: MockerFixture): # noqa: F811 +def test_get_instance_binding_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.get method mock_get = mocker.patch("httpx.Client.get") @@ -211,17 +145,6 @@ def test_get_instance_binding_success(client, mocker: MockerFixture): # noqa: F }, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - }.items() - if v is not None - } - # Call the get_instance_binding method response = client.get_instance_binding( name="mock_instance_binding_name", instance_name="mock_instance_name" @@ -232,7 +155,7 @@ def test_get_instance_binding_success(client, mocker: MockerFixture): # noqa: F assert response.metadata.guid == "test_instance_binding_guid" -def test_create_instance_binding_success(client, mocker: MockerFixture): # noqa: F811 +def test_create_instance_binding_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.post method mock_post = mocker.patch("httpx.Client.post") @@ -247,17 +170,6 @@ def test_create_instance_binding_success(client, mocker: MockerFixture): # noqa }, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - }.items() - if v is not None - } - # Call the create_instance_binding method response = client.create_instance_binding( body={"name": "test_instance_binding"}, instance_name="mock_instance_name" @@ -268,7 +180,7 @@ def test_create_instance_binding_success(client, mocker: MockerFixture): # noqa assert response.metadata.guid == "test_instance_binding_guid" -def test_delete_instance_binding_success(client, mocker: MockerFixture): # noqa: F811 +def test_delete_instance_binding_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.delete method mock_delete = mocker.patch("httpx.Client.delete") @@ -278,17 +190,6 @@ def test_delete_instance_binding_success(client, mocker: MockerFixture): # noqa json={"success": True}, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - }.items() - if v is not None - } - # Call the delete_instance_binding method response = client.delete_instance_binding( name="mock_instance_binding_name", instance_name="mock_instance_name" diff --git a/tests/sync_tests/test_network.py b/tests/sync_tests/test_network.py index 3fb020c..6fe9826 100644 --- a/tests/sync_tests/test_network.py +++ b/tests/sync_tests/test_network.py @@ -1,13 +1,13 @@ import httpx import pytest from munch import Munch -from pytest_mock import MockerFixture +from pytest_mock import MockFixture -from tests.utils.util import network_body # noqa: F401 +from tests.data.mock_data import network_body # noqa: F401 from tests.utils.fixtures import client # noqa: F401 -def test_list_networks_success(client, mocker: MockerFixture): # noqa: F811 +def test_list_networks_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.get method mock_get = mocker.patch("httpx.Client.get") @@ -20,17 +20,6 @@ def test_list_networks_success(client, mocker: MockerFixture): # noqa: F811 }, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - }.items() - if v is not None - } - # Call the list_networks method response = client.list_networks() @@ -39,7 +28,7 @@ def test_list_networks_success(client, mocker: MockerFixture): # noqa: F811 assert response["items"] == [{"name": "test-network", "guid": "mock_network_guid"}] -def test_list_networks_not_found(client, mocker: MockerFixture): # noqa: F811 +def test_list_networks_not_found(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.get method mock_get = mocker.patch("httpx.Client.get") @@ -49,20 +38,13 @@ def test_list_networks_not_found(client, mocker: MockerFixture): # noqa: F811 json={"error": "not found"}, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True: { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - } - with pytest.raises(Exception) as exc: client.list_networks() assert str(exc.value) == "not found" -def test_create_network_success(client, mocker: MockerFixture): # noqa: F811 +def test_create_network_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.post method mock_post = mocker.patch("httpx.Client.post") @@ -74,17 +56,6 @@ def test_create_network_success(client, mocker: MockerFixture): # noqa: F811 }, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - }.items() - if v is not None - } - # Call the create_network method response = client.create_network(body=network_body) @@ -93,7 +64,7 @@ def test_create_network_success(client, mocker: MockerFixture): # noqa: F811 assert response["metadata"]["name"] == "test-network" -def test_create_network_failure(client, mocker: MockerFixture): # noqa: F811 +def test_create_network_failure(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.post method mock_post = mocker.patch("httpx.Client.post") @@ -103,20 +74,13 @@ def test_create_network_failure(client, mocker: MockerFixture): # noqa: F811 json={"error": "already exists"}, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True: { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - } - with pytest.raises(Exception) as exc: client.create_network(body=network_body) assert str(exc.value) == "already exists" -def test_get_network_success(client, mocker: MockerFixture): # noqa: F811 +def test_get_network_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.get method mock_get = mocker.patch("httpx.Client.get") @@ -128,17 +92,6 @@ def test_get_network_success(client, mocker: MockerFixture): # noqa: F811 }, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - }.items() - if v is not None - } - # Call the get_network method response = client.get_network(name="test-network") @@ -147,7 +100,7 @@ def test_get_network_success(client, mocker: MockerFixture): # noqa: F811 assert response["metadata"]["guid"] == "mock_network_guid" -def test_delete_network_success(client, mocker: MockerFixture): # noqa: F811 +def test_delete_network_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.delete method mock_delete = mocker.patch("httpx.Client.delete") @@ -157,17 +110,6 @@ def test_delete_network_success(client, mocker: MockerFixture): # noqa: F811 json={"success": True}, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - }.items() - if v is not None - } - # Call the delete_network method response = client.delete_network(name="test-network") diff --git a/tests/sync_tests/test_package.py b/tests/sync_tests/test_package.py index a7a0d1b..c8c8991 100644 --- a/tests/sync_tests/test_package.py +++ b/tests/sync_tests/test_package.py @@ -1,13 +1,13 @@ import httpx import pytest from munch import Munch -from pytest_mock import MockerFixture +from pytest_mock import MockFixture -from tests.utils.util import package_body # noqa: F401 +from tests.data.mock_data import package_body # noqa: F401 from tests.utils.fixtures import client # noqa: F401 -def test_list_packages_success(client, mocker: MockerFixture): # noqa: F811 +def test_list_packages_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.get method mock_get = mocker.patch("httpx.Client.get") @@ -20,17 +20,6 @@ def test_list_packages_success(client, mocker: MockerFixture): # noqa: F811 }, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - }.items() - if v is not None - } - # Call the list_packages method response = client.list_packages() @@ -39,7 +28,7 @@ def test_list_packages_success(client, mocker: MockerFixture): # noqa: F811 assert response["items"] == [{"name": "test_package", "guid": "mock_package_guid"}] -def test_list_packages_not_found(client, mocker: MockerFixture): # noqa: F811 +def test_list_packages_not_found(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.get method mock_get = mocker.patch("httpx.Client.get") @@ -49,13 +38,6 @@ def test_list_packages_not_found(client, mocker: MockerFixture): # noqa: F811 json={"error": "not found"}, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True: { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - } - # Call the list_packages method with pytest.raises(Exception) as exc: client.list_packages() @@ -65,7 +47,7 @@ def test_list_packages_not_found(client, mocker: MockerFixture): # noqa: F811 # assert response. == "not found" -def test_get_package_success(client, mocker: MockerFixture): # noqa: F811 +def test_get_package_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.get method mock_get = mocker.patch("httpx.Client.get") @@ -77,17 +59,6 @@ def test_get_package_success(client, mocker: MockerFixture): # noqa: F811 }, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True, **kwargs: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": kwargs.get("project_guid") if with_project else None, - }.items() - if v is not None - } - # Call the get_package method response = client.get_package(name="mock_package_name") @@ -97,7 +68,7 @@ def test_get_package_success(client, mocker: MockerFixture): # noqa: F811 assert response.metadata.name == "test_package" -def test_get_package_not_found(client, mocker: MockerFixture): # noqa: F811 +def test_get_package_not_found(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.get method mock_get = mocker.patch("httpx.Client.get") @@ -107,13 +78,6 @@ def test_get_package_not_found(client, mocker: MockerFixture): # noqa: F811 json={"error": "not found"}, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True, **kwargs: { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": kwargs.get("package_guid") if with_project else None, - } - # Call the get_package method with pytest.raises(Exception) as exc: client.get_package(name="mock_package_name") @@ -122,7 +86,7 @@ def test_get_package_not_found(client, mocker: MockerFixture): # noqa: F811 assert str(exc.value) == "not found" -def test_create_package_success(client, package_body, mocker: MockerFixture): # noqa: F811 +def test_create_package_success(client, package_body, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.post method mock_post = mocker.patch("httpx.Client.post") @@ -134,17 +98,6 @@ def test_create_package_success(client, package_body, mocker: MockerFixture): # }, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True, **kwargs: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": kwargs.get("project_guid") if with_project else None, - }.items() - if v is not None - } - # Call the create_package method response = client.create_package(body=package_body) diff --git a/tests/sync_tests/test_project.py b/tests/sync_tests/test_project.py index d0296e5..b398052 100644 --- a/tests/sync_tests/test_project.py +++ b/tests/sync_tests/test_project.py @@ -1,9 +1,9 @@ import httpx import pytest from munch import Munch -from pytest_mock import MockerFixture +from pytest_mock import MockFixture -from tests.utils.util import ( +from tests.data.mock_data import ( mock_response_project, # noqa: F401 project_body, ) # noqa: F401 @@ -11,7 +11,7 @@ # Test function for list_projects -def test_list_projects_success(client, mocker: MockerFixture): # noqa: F811 +def test_list_projects_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.get method mock_get = mocker.patch("httpx.Client.get") @@ -24,17 +24,6 @@ def test_list_projects_success(client, mocker: MockerFixture): # noqa: F811 }, ) - # Override get_headers to return mocked headers without None values - client.config.get_headers = lambda with_project: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - }.items() - if v is not None - } - # Call the list_projects method response = client.list_projects() @@ -43,7 +32,7 @@ def test_list_projects_success(client, mocker: MockerFixture): # noqa: F811 assert response["items"] == [{"name": "test-project", "guid": "mock_project_guid"}] -def test_list_projects_unauthorized(client, mocker: MockerFixture): # noqa: F811 +def test_list_projects_unauthorized(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.get method mock_get = mocker.patch("httpx.Client.get") @@ -53,17 +42,6 @@ def test_list_projects_unauthorized(client, mocker: MockerFixture): # noqa: F81 json={"error": "unauthorized permission access"}, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=False, **kwargs: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - }.items() - if v is not None - } - # Call the list_projects method with pytest.raises(Exception) as exc: client.list_projects() @@ -72,7 +50,7 @@ def test_list_projects_unauthorized(client, mocker: MockerFixture): # noqa: F81 assert str(exc.value) == "unauthorized permission access" -def test_list_projects_not_found(client, mocker: MockerFixture): # noqa: F811 +def test_list_projects_not_found(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.get method mock_get = mocker.patch("httpx.Client.get") @@ -82,17 +60,6 @@ def test_list_projects_not_found(client, mocker: MockerFixture): # noqa: F811 json={"error": "not found"}, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=False, **kwargs: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - }.items() - if v is not None - } - # Call the list_projects method with pytest.raises(Exception) as exc: client.list_projects() @@ -101,7 +68,7 @@ def test_list_projects_not_found(client, mocker: MockerFixture): # noqa: F811 assert str(exc.value) == "not found" -def test_get_project_success(client, mock_response_project, mocker: MockerFixture): # noqa: F811 +def test_get_project_success(client, mock_response_project, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.get method mock_get = mocker.patch("httpx.Client.get") @@ -114,17 +81,6 @@ def test_get_project_success(client, mock_response_project, mocker: MockerFixtur }, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=False, **kwargs: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": kwargs.get("project_guid") if with_project else None, - }.items() - if v is not None - } - # Call the get_project method response = client.get_project(project_guid="mock_project_guid") @@ -133,7 +89,7 @@ def test_get_project_success(client, mock_response_project, mocker: MockerFixtur assert response["metadata"]["guid"] == "test_project_guid" -def test_get_project_not_found(client, mocker: MockerFixture): # noqa: F811 +def test_get_project_not_found(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.get method mock_get = mocker.patch("httpx.Client.get") @@ -143,17 +99,6 @@ def test_get_project_not_found(client, mocker: MockerFixture): # noqa: F811 json={"error": "project not found"}, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=False, **kwargs: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": kwargs.get("project_guid") if with_project else None, - }.items() - if v is not None - } - # Call the get_project method with pytest.raises(Exception) as exc: client.get_project(project_guid="mock_project_guid") @@ -162,7 +107,7 @@ def test_get_project_not_found(client, mocker: MockerFixture): # noqa: F811 assert str(exc.value) == "project not found" -def test_create_project_success(client, mock_response_project, mocker: MockerFixture): # noqa: F811 +def test_create_project_success(client, mock_response_project, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.post method mock_post = mocker.patch("httpx.Client.post") @@ -172,17 +117,6 @@ def test_create_project_success(client, mock_response_project, mocker: MockerFix json=mock_response_project, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=False, **kwargs: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": kwargs.get("project_guid") if with_project else None, - }.items() - if v is not None - } - # Call the create_project method response = client.create_project(body=project_body) @@ -191,7 +125,7 @@ def test_create_project_success(client, mock_response_project, mocker: MockerFix assert response["metadata"]["guid"] == "mock_project_guid" -def test_create_project_unauthorized(client, mocker: MockerFixture): # noqa: F811 +def test_create_project_unauthorized(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.post method mock_post = mocker.patch("httpx.Client.post") @@ -201,17 +135,6 @@ def test_create_project_unauthorized(client, mocker: MockerFixture): # noqa: F8 json={"error": "unauthorized permission access"}, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=False, **kwargs: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": kwargs.get("project_guid") if with_project else None, - }.items() - if v is not None - } - # Call the create_project method with pytest.raises(Exception) as exc: client.create_project(body=project_body) @@ -220,7 +143,7 @@ def test_create_project_unauthorized(client, mocker: MockerFixture): # noqa: F8 assert str(exc.value) == "unauthorized permission access" -def test_update_project_success(client, mock_response_project, mocker: MockerFixture): # noqa: F811 +def test_update_project_success(client, mock_response_project, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.put method mock_put = mocker.patch("httpx.Client.put") @@ -230,17 +153,6 @@ def test_update_project_success(client, mock_response_project, mocker: MockerFix json=mock_response_project, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=False, **kwargs: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": kwargs.get("project_guid") if with_project else None, - }.items() - if v is not None - } - # Call the update_project method response = client.update_project(project_guid="mock_project_guid", body=project_body) @@ -249,24 +161,13 @@ def test_update_project_success(client, mock_response_project, mocker: MockerFix assert response["metadata"]["guid"] == "mock_project_guid" -def test_delete_project_success(client, mock_response_project, mocker: MockerFixture): # noqa: F811 +def test_delete_project_success(client, mock_response_project, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.delete method mock_delete = mocker.patch("httpx.Client.delete") # Set up the mock response mock_delete.return_value = httpx.Response(status_code=200, json={"success": True}) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=False, **kwargs: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": kwargs.get("project_guid") if with_project else None, - }.items() - if v is not None - } - # Call the delete_project method response = client.delete_project(project_guid="mock_project_guid") diff --git a/tests/sync_tests/test_secret.py b/tests/sync_tests/test_secret.py index 9862f65..5d1e6ad 100644 --- a/tests/sync_tests/test_secret.py +++ b/tests/sync_tests/test_secret.py @@ -1,13 +1,13 @@ import httpx import pytest from munch import Munch -from pytest_mock import MockerFixture +from pytest_mock import MockFixture -from tests.utils.util import secret_body # noqa: F401 +from tests.data.mock_data import secret_body # noqa: F401 from tests.utils.fixtures import client # noqa: F401 -def test_list_secrets_success(client, mocker: MockerFixture): # noqa: F811 +def test_list_secrets_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.get method mock_get = mocker.patch("httpx.Client.get") @@ -20,17 +20,6 @@ def test_list_secrets_success(client, mocker: MockerFixture): # noqa: F811 }, ) - # Override get_headers to return mocked headers without None values - client.config.get_headers = lambda with_project=True: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - }.items() - if v is not None - } - # Call the list_secrets method response = client.list_secrets() @@ -39,7 +28,7 @@ def test_list_secrets_success(client, mocker: MockerFixture): # noqa: F811 assert response["items"] == [{"name": "test-secret", "guid": "mock_secret_guid"}] -def test_list_secrets_not_found(client, mocker: MockerFixture): # noqa: F811 +def test_list_secrets_not_found(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.get method mock_get = mocker.patch("httpx.Client.get") @@ -49,20 +38,13 @@ def test_list_secrets_not_found(client, mocker: MockerFixture): # noqa: F811 json={"error": "not found"}, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True: { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - } - with pytest.raises(Exception) as exc: client.list_secrets() assert str(exc.value) == "not found" -def test_create_secret_success(client, mocker: MockerFixture): # noqa: F811 +def test_create_secret_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.post method mock_post = mocker.patch("httpx.Client.post") @@ -74,13 +56,6 @@ def test_create_secret_success(client, mocker: MockerFixture): # noqa: F811 }, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True: { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - } - # Call the create_secret method response = client.create_secret(secret_body) @@ -89,7 +64,7 @@ def test_create_secret_success(client, mocker: MockerFixture): # noqa: F811 assert response.metadata.guid == "test_secret_guid" -def test_create_secret_already_exists(client, mocker: MockerFixture): # noqa: F811 +def test_create_secret_already_exists(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.post method mock_post = mocker.patch("httpx.Client.post") @@ -99,20 +74,13 @@ def test_create_secret_already_exists(client, mocker: MockerFixture): # noqa: F json={"error": "secret already exists"}, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True: { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - } - with pytest.raises(Exception) as exc: client.create_secret(secret_body) assert str(exc.value) == "secret already exists" -def test_update_secret_success(client, mocker: MockerFixture): # noqa: F811 +def test_update_secret_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.put method mock_put = mocker.patch("httpx.Client.put") @@ -124,13 +92,6 @@ def test_update_secret_success(client, mocker: MockerFixture): # noqa: F811 }, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True: { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - } - # Call the update_secret method response = client.update_secret("mock_secret_guid", body=secret_body) @@ -139,7 +100,7 @@ def test_update_secret_success(client, mocker: MockerFixture): # noqa: F811 assert response.metadata.guid == "test_secret_guid" -def test_delete_secret_success(client, mocker: MockerFixture): # noqa: F811 +def test_delete_secret_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.delete method mock_delete = mocker.patch("httpx.Client.delete") @@ -149,13 +110,6 @@ def test_delete_secret_success(client, mocker: MockerFixture): # noqa: F811 json={"success": True}, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True: { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - } - # Call the delete_secret method response = client.delete_secret("mock_secret_guid") @@ -163,7 +117,7 @@ def test_delete_secret_success(client, mocker: MockerFixture): # noqa: F811 assert response == {"success": True} -def test_get_secret_success(client, mocker: MockerFixture): # noqa: F811 +def test_get_secret_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.get method mock_get = mocker.patch("httpx.Client.get") @@ -175,13 +129,6 @@ def test_get_secret_success(client, mocker: MockerFixture): # noqa: F811 }, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True: { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - } - # Call the get_secret method response = client.get_secret("mock_secret_guid") diff --git a/tests/sync_tests/test_staticroute.py b/tests/sync_tests/test_staticroute.py index f95a03b..24bb1eb 100644 --- a/tests/sync_tests/test_staticroute.py +++ b/tests/sync_tests/test_staticroute.py @@ -1,13 +1,13 @@ import httpx import pytest from munch import Munch -from pytest_mock import MockerFixture +from pytest_mock import MockFixture -from tests.utils.util import staticroute_body # noqa: F401 +from tests.data.mock_data import staticroute_body # noqa: F401 from tests.utils.fixtures import client # noqa: F401 -def test_list_staticroutes_success(client, mocker: MockerFixture): # noqa: F811 +def test_list_staticroutes_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.get method mock_get = mocker.patch("httpx.Client.get") @@ -20,17 +20,6 @@ def test_list_staticroutes_success(client, mocker: MockerFixture): # noqa: F811 }, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - }.items() - if v is not None - } - # Call the list_staticroutes method response = client.list_staticroutes() @@ -41,7 +30,7 @@ def test_list_staticroutes_success(client, mocker: MockerFixture): # noqa: F811 ] -def test_list_staticroutes_not_found(client, mocker: MockerFixture): # noqa: F811 +def test_list_staticroutes_not_found(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.get method mock_get = mocker.patch("httpx.Client.get") @@ -51,20 +40,13 @@ def test_list_staticroutes_not_found(client, mocker: MockerFixture): # noqa: F8 json={"error": "not found"}, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True: { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - } - with pytest.raises(Exception) as exc: client.list_staticroutes() assert str(exc.value) == "not found" -def test_create_staticroute_success(client, mocker: MockerFixture): # noqa: F811 +def test_create_staticroute_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.post method mock_post = mocker.patch("httpx.Client.post") @@ -76,17 +58,6 @@ def test_create_staticroute_success(client, mocker: MockerFixture): # noqa: F81 }, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - }.items() - if v is not None - } - # Call the create_staticroute method response = client.create_staticroute(body=staticroute_body) @@ -95,7 +66,7 @@ def test_create_staticroute_success(client, mocker: MockerFixture): # noqa: F81 assert response.metadata.guid == "test_staticroute_guid" -def test_create_staticroute_bad_request(client, mocker: MockerFixture): # noqa: F811 +def test_create_staticroute_bad_request(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.post method mock_post = mocker.patch("httpx.Client.post") @@ -105,20 +76,13 @@ def test_create_staticroute_bad_request(client, mocker: MockerFixture): # noqa: json={"error": "already exists"}, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True: { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - } - with pytest.raises(Exception) as exc: client.create_staticroute(body=staticroute_body) assert str(exc.value) == "already exists" -def test_get_staticroute_success(client, mocker: MockerFixture): # noqa: F811 +def test_get_staticroute_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.get method mock_get = mocker.patch("httpx.Client.get") @@ -130,17 +94,6 @@ def test_get_staticroute_success(client, mocker: MockerFixture): # noqa: F811 }, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - }.items() - if v is not None - } - # Call the get_staticroute method response = client.get_staticroute(name="mock_staticroute_name") @@ -149,7 +102,7 @@ def test_get_staticroute_success(client, mocker: MockerFixture): # noqa: F811 assert response.metadata.guid == "test_staticroute_guid" -def test_update_staticroute_success(client, mocker: MockerFixture): # noqa: F811 +def test_update_staticroute_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.put method mock_put = mocker.patch("httpx.Client.put") @@ -161,17 +114,6 @@ def test_update_staticroute_success(client, mocker: MockerFixture): # noqa: F81 }, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=True: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": "mock_project_guid" if with_project else None, - }.items() - if v is not None - } - # Call the update_staticroute method response = client.update_staticroute( name="mock_staticroute_name", body=staticroute_body @@ -182,7 +124,7 @@ def test_update_staticroute_success(client, mocker: MockerFixture): # noqa: F81 assert response.metadata.guid == "test_staticroute_guid" -def test_delete_staticroute_success(client, mocker: MockerFixture): # noqa: F811 +def test_delete_staticroute_success(client, mocker: MockFixture): # noqa: F811 # Mock the httpx.Client.delete method mock_delete = mocker.patch("httpx.Client.delete") @@ -192,17 +134,6 @@ def test_delete_staticroute_success(client, mocker: MockerFixture): # noqa: F81 json={"success": True}, ) - # Override get_headers to return the mocked headers without None values - client.config.get_headers = lambda with_project=False: { - k: v - for k, v in { - "Authorization": f"Bearer {client.auth_token}", - "organizationguid": client.organization_guid, - "project": None, - }.items() - if v is not None - } - # Call the delete_staticroute method response = client.delete_staticroute(name="mock_staticroute_name") diff --git a/tests/utils/fixtures.py b/tests/utils/fixtures.py index 440275c..2ec867b 100644 --- a/tests/utils/fixtures.py +++ b/tests/utils/fixtures.py @@ -7,9 +7,10 @@ def client(): client = Client() client.config.hosts["v2api_host"] = "https://mock-api.rapyuta.io" - client.auth_token = "mock_token" - client.organization_guid = "mock_org_guid" - client.project = "mock_project_guid" + client.config.auth_token = "mock_token" + client.config.organization_guid = "mock_org_guid" + client.config.project_guid = "mock_project_guid" + client.config.environment = "mock" return client @@ -17,7 +18,8 @@ def client(): def async_client(): client = AsyncClient() client.config.hosts["v2api_host"] = "https://mock-api.rapyuta.io" - client.auth_token = "mock_token" - client.organization_guid = "mock_org_guid" - client.project = "mock_project_guid" + client.config.auth_token = "mock_token" + client.config.organization_guid = "mock_org_guid" + client.config.project_guid = "mock_project_guid" + client.config.environment = "mock" return client diff --git a/uv.lock b/uv.lock index 2ee4075..6071ac1 100644 --- a/uv.lock +++ b/uv.lock @@ -16,19 +16,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1b/b4/f7e396030e3b11394436358ca258a81d6010106582422f23443c16ca1873/anyio-4.5.2-py3-none-any.whl", hash = "sha256:c011ee36bc1e8ba40e5a81cb9df91925c218fe9b778554e0b56a21e1b5d4716f", size = 89766 }, ] -[[package]] -name = "asyncer" -version = "0.0.8" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "anyio" }, - { name = "typing-extensions", marker = "python_full_version < '3.10'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/ff/67/7ea59c3e69eaeee42e7fc91a5be67ca5849c8979acac2b920249760c6af2/asyncer-0.0.8.tar.gz", hash = "sha256:a589d980f57e20efb07ed91d0dbe67f1d2fd343e7142c66d3a099f05c620739c", size = 18217 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8a/04/15b6ca6b7842eda2748bda0a0af73f2d054e9344320f8bba01f994294bcb/asyncer-0.0.8-py3-none-any.whl", hash = "sha256:5920d48fc99c8f8f0f1576e1882f5022885589c5fcbc46ce4224ec3e53776eeb", size = 9209 }, -] - [[package]] name = "asyncmock" version = "0.4.2" @@ -309,8 +296,6 @@ dependencies = [ [package.dev-dependencies] dev = [ - { name = "anyio" }, - { name = "asyncer" }, { name = "asyncmock" }, { name = "coverage" }, { name = "mock" }, @@ -329,8 +314,6 @@ requires-dist = [ [package.metadata.requires-dev] dev = [ - { name = "anyio", specifier = ">=4.5.2" }, - { name = "asyncer", specifier = ">=0.0.8" }, { name = "asyncmock", specifier = ">=0.4.2" }, { name = "coverage", specifier = ">=7.6.1" }, { name = "mock", specifier = ">=5.1.0" }, From 2ec17ef3a9e564b76d69f9a969e5e51bb5e96031 Mon Sep 17 00:00:00 2001 From: guptadev21 Date: Thu, 5 Dec 2024 15:09:43 +0530 Subject: [PATCH 12/13] chore: update --- rapyuta_io_sdk_v2/async_client.py | 7 +++-- rapyuta_io_sdk_v2/client.py | 52 +++++++++++++++---------------- 2 files changed, 30 insertions(+), 29 deletions(-) diff --git a/rapyuta_io_sdk_v2/async_client.py b/rapyuta_io_sdk_v2/async_client.py index 7e82228..92eca49 100644 --- a/rapyuta_io_sdk_v2/async_client.py +++ b/rapyuta_io_sdk_v2/async_client.py @@ -461,7 +461,7 @@ async def create_deployment(self, body: dict, **kwargs) -> Munch: ) @handle_and_munchify_response - async def get_deployment(self, name: str, **kwargs) -> Munch: + async def get_deployment(self, name: str, guid: str = None,**kwargs) -> Munch: """Get a deployment by its name. Returns: @@ -471,6 +471,7 @@ async def get_deployment(self, name: str, **kwargs) -> Munch: return await self.c.get( url=f"{self.v2api_host}/v2/deployments/{name}/", headers=self.config.get_headers(**kwargs), + params={"guid": guid}, ) @handle_and_munchify_response @@ -981,7 +982,7 @@ async def create_configtree(self, body: dict, **kwargs) -> Munch: async def get_configtree( self, name: str, - content_type: list[str] = None, + content_types: list[str] = None, include_data: bool = False, key_prefixes: list[str] = None, revision: str = None, @@ -1004,7 +1005,7 @@ async def get_configtree( url=f"{self.v2api_host}/v2/configtrees/{name}/", headers=self.config.get_headers(**kwargs), params={ - "contentTypes": content_type, + "contentTypes": content_types, "includeData": include_data, "keyPrefixes": key_prefixes, "revision": revision, diff --git a/rapyuta_io_sdk_v2/client.py b/rapyuta_io_sdk_v2/client.py index 0a86fce..6043e5e 100644 --- a/rapyuta_io_sdk_v2/client.py +++ b/rapyuta_io_sdk_v2/client.py @@ -380,14 +380,14 @@ def list_deployments( self, cont: int = 0, dependencies: bool = False, - deviceName: str = None, + device_name: str = None, guids: list[str] = None, label_selector: list[str] = None, limit: int = 50, name: str = None, names: list[str] = None, - packageName: str = None, - packageVersion: str = None, + package_name: str = None, + package_version: str = None, phases: list[str] = None, regions: list[str] = None, **kwargs, @@ -397,14 +397,14 @@ def list_deployments( Args: cont (int, optional): Start index of deployments. Defaults to 0. dependencies (bool, optional): Filter by dependencies. Defaults to False. - deviceName (str, optional): Filter deployments by device name. Defaults to None. + device_name (str, optional): Filter deployments by device name. Defaults to None. guids (list[str], optional): Filter by GUIDs. Defaults to None. label_selector (list[str], optional): Define labelSelector to get deployments from. Defaults to None. limit (int, optional): Number of deployments to list. Defaults to 50. name (str, optional): Define name to get deployments from. Defaults to None. names (list[str], optional): Define names to get deployments from. Defaults to None. - packageName (str, optional): Filter by package name. Defaults to None. - packageVersion (str, optional): Filter by package version. Defaults to None. + package_name (str, optional): Filter by package name. Defaults to None. + package_version (str, optional): Filter by package version. Defaults to None. phases (list[str], optional): Filter by phases. Available values : InProgress, Provisioning, Succeeded, FailedToUpdate, FailedToStart, Stopped. Defaults to None. regions (list[str], optional): Filter by regions. Defaults to None. @@ -419,13 +419,13 @@ def list_deployments( "continue": cont, "limit": limit, "dependencies": dependencies, - "deviceName": deviceName, + "deviceName": device_name, "guids": guids, "labelSelector": label_selector, "name": name, "names": names, - "packageName": packageName, - "packageVersion": packageVersion, + "packageName": package_name, + "packageVersion": package_version, "phases": phases, "regions": regions, }, @@ -459,7 +459,7 @@ def get_deployment(self, name: str, guid: str = None, **kwargs) -> Munch: return self.c.get( url=f"{self.v2api_host}/v2/deployments/{name}/", headers=self.config.get_headers(**kwargs), - json={"guid": guid}, + params={"guid": guid}, ) @handle_and_munchify_response @@ -715,12 +715,12 @@ def delete_staticroute(self, name: str, **kwargs) -> Munch: def list_networks( self, cont: int = 0, - deviceName: str = None, + device_name: str = None, label_selector: list[str] = None, limit: int = 50, name: str = None, names: list[str] = None, - networkType: str = None, + network_type: str = None, phases: list[str] = None, regions: list[str] = None, status: list[str] = None, @@ -730,12 +730,12 @@ def list_networks( Args: cont (int, optional): Start index of networks. Defaults to 0. - deviceName (str, optional): Filter networks by device name. Defaults to None. + device_name (str, optional): Filter networks by device name. Defaults to None. label_selector (list[str], optional): Define labelSelector to get networks from. Defaults to None. limit (int, optional): Number of networks to list. Defaults to 50. name (str, optional): Define name to get networks from. Defaults to None. names (list[str], optional): Define names to get networks from. Defaults to None. - networkType (str, optional): Define network type to get networks from. Defaults to None. + network_type (str, optional): Define network type to get networks from. Defaults to None. phases (list[str], optional): Define phases to get networks from. Available values : InProgress, Provisioning, Succeeded, FailedToUpdate, FailedToStart, Stopped. Defaults to None. regions (list[str], optional): Define regions to get networks from. Defaults to None. status (list[str], optional): Define status to get networks from. Available values : Running, Pending, Error, Unknown, Stopped. Defaults to None. @@ -750,11 +750,11 @@ def list_networks( params={ "continue": cont, "limit": limit, - "deviceName": deviceName, + "deviceName": device_name, "labelSelector": label_selector, "name": name, "names": names, - "networkType": networkType, + "networkType": network_type, "phases": phases, "regions": regions, "status": status, @@ -967,9 +967,9 @@ def create_configtree(self, body: dict, **kwargs) -> Munch: def get_configtree( self, name: str, - contentTypes: list[str] = None, - includeData: bool = False, - keyPrefixes: list[str] = None, + content_types: list[str] = None, + include_data: bool = False, + key_prefixes: list[str] = None, revision: str = None, **kwargs, ) -> Munch: @@ -977,9 +977,9 @@ def get_configtree( Args: name (str): Config tree name - contentTypes (list[str], optional): Define contentTypes to get config tree from. Defaults to None. - includeData (bool, optional): Include data. Defaults to False. - keyPrefixes (list[str], optional): Define keyPrefixes to get config tree from. Defaults to None. + content_types (list[str], optional): Define contentTypes to get config tree from. Defaults to None. + include_data (bool, optional): Include data. Defaults to False. + key_prefixes (list[str], optional): Define keyPrefixes to get config tree from. Defaults to None. revision (str, optional): Define revision to get config tree from. Defaults to None. Returns: @@ -990,9 +990,9 @@ def get_configtree( url=f"{self.v2api_host}/v2/configtrees/{name}/", headers=self.config.get_headers(**kwargs), params={ - "contentTypes": contentTypes, - "includeData": includeData, - "keyPrefixes": keyPrefixes, + "contentTypes": content_types, + "includeData": include_data, + "keyPrefixes": key_prefixes, "revision": revision, }, ) @@ -1112,7 +1112,7 @@ def create_revision( @handle_and_munchify_response def put_keys_in_revision( - self, name: str, revision_id: str, config_values: list[(dict)], **kwargs + self, name: str, revision_id: str, config_values: list[dict], **kwargs ) -> Munch: """Put keys in a revision. From 03acda9862f9db4ef7c49d2b1b030710da6191bb Mon Sep 17 00:00:00 2001 From: Pallab Pain Date: Thu, 5 Dec 2024 16:42:34 +0530 Subject: [PATCH 13/13] chore: update docstring and reformat --- rapyuta_io_sdk_v2/async_client.py | 2 +- rapyuta_io_sdk_v2/config.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/rapyuta_io_sdk_v2/async_client.py b/rapyuta_io_sdk_v2/async_client.py index 92eca49..bc74486 100644 --- a/rapyuta_io_sdk_v2/async_client.py +++ b/rapyuta_io_sdk_v2/async_client.py @@ -461,7 +461,7 @@ async def create_deployment(self, body: dict, **kwargs) -> Munch: ) @handle_and_munchify_response - async def get_deployment(self, name: str, guid: str = None,**kwargs) -> Munch: + async def get_deployment(self, name: str, guid: str = None, **kwargs) -> Munch: """Get a deployment by its name. Returns: diff --git a/rapyuta_io_sdk_v2/config.py b/rapyuta_io_sdk_v2/config.py index 8c7f1d8..bd24e21 100644 --- a/rapyuta_io_sdk_v2/config.py +++ b/rapyuta_io_sdk_v2/config.py @@ -78,8 +78,9 @@ def get_headers( """Get the headers for the configuration. Args: + organization_guid (str): The organization guid. with_project (bool): Whether to include the project headers. - **kwargs: Arbitrary keyword arguments. + project_guid (str): The project guid. Returns: dict: Headers for the configuration.