From 665f614c045d30422068ef725fbcc37e93ee61ef Mon Sep 17 00:00:00 2001 From: sunil-lakshman <104969541+sunil-lakshman@users.noreply.github.com> Date: Mon, 12 May 2025 15:07:20 +0530 Subject: [PATCH 01/12] Updated author name --- contentstack_management/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contentstack_management/__init__.py b/contentstack_management/__init__.py index 5ce8d29..c7f3b9e 100644 --- a/contentstack_management/__init__.py +++ b/contentstack_management/__init__.py @@ -69,7 +69,7 @@ ) __title__ = 'contentstack-management-python' -__author__ = 'ishaileshmishra' +__author__ = 'dev-ex' __status__ = 'debug' __region__ = 'na' __version__ = '1.3.3' From baad92890aa1c3e4966f6cba67719b495c93612b Mon Sep 17 00:00:00 2001 From: sunil-lakshman <104969541+sunil-lakshman@users.noreply.github.com> Date: Fri, 23 May 2025 13:21:13 +0530 Subject: [PATCH 02/12] Release 2.0 support added --- CHANGELOG.md | 6 + contentstack_management/__init__.py | 2 +- contentstack_management/auditlogs/auditlog.py | 2 - .../bulk_operations/bulk_operation.py | 92 +++++ .../content_types/content_type.py | 2 +- contentstack_management/contentstack.py | 1 - .../delivery_token/delivery_token.py | 1 - .../environments/environment.py | 1 - .../extensions/extension.py | 1 - contentstack_management/labels/label.py | 1 - contentstack_management/locale/locale.py | 1 - .../management_token/management_token.py | 1 - contentstack_management/metadata/metadata.py | 1 - .../publish_queue/publish_queue.py | 2 - .../release_items/release_item.py | 45 ++- contentstack_management/releases/release.py | 10 +- contentstack_management/roles/roles.py | 1 - contentstack_management/stack/stack.py | 5 +- .../taxonomies/taxonomy.py | 1 - contentstack_management/terms/terms.py | 1 - contentstack_management/webhooks/webhook.py | 3 +- .../workflows/workflows.py | 5 +- setup.py | 1 - tests/api/aliases/test_alias.py | 2 - tests/api/assets/test_assets.py | 5 +- tests/api/auditlogs/test_auditlogs_api.py | 2 - tests/api/branches/test_branch_api.py | 2 - .../test_bulk_operations_api.py | 2 - .../content_types/test_content_type_api.py | 2 - .../delivery_token/test_delivery_token_api.py | 2 - tests/api/entry/test_entry_api.py | 2 - .../api/environments/test_environments_api.py | 2 - tests/api/extensions/test_extension_api.py | 2 - .../global_fields/test_global_fields_api.py | 2 - tests/api/labels/test_labels_api.py | 2 - tests/api/locales/test_locale_api.py | 2 - .../test_management_token_api.py | 2 - tests/api/metadata/test_metadata_api.py | 2 - .../publish_queue/test_publish_queue_api.py | 2 - .../release_items/test_release_items_api.py | 2 - tests/api/releases/test_releases_api.py | 2 - tests/api/roles/test_roles_api.py | 2 - tests/api/taxonomies/test_taxonomy_api.py | 2 - tests/api/terms/test_terms_api.py | 2 - tests/api/webhooks/test_webhooks_api.py | 2 - tests/api/workflows/test_workflow_api.py | 2 - tests/mock/aliases/test_alias_mock.py | 2 - tests/mock/assets/test_assets_mock.py | 5 +- tests/mock/auditlogs/test_auditlogs_mock.py | 2 - tests/mock/branches/test_branch_mock.py | 2 - .../test_bulk_operations_mock.py | 3 - .../content_types/test_content_type_mock.py | 2 - .../test_delivery_token_mock.py | 2 - tests/mock/entry/test_entry_mock.py | 2 - .../environments/test_environments_mock.py | 2 - tests/mock/extensions/test_extension_mock.py | 2 - .../global_fields/test_global_fields_mock.py | 2 - tests/mock/labels/test_labels_mock.py | 2 - tests/mock/locales/test_locale_mock.py | 2 - .../test_management_token_mock.py | 2 - tests/mock/metadata/test_metadata_mock.py | 2 - tests/mock/organizations/test_org_mock.py | 2 - .../publish_queue/test_publish_queue_mock.py | 2 - .../release_items/test_release_items_mock.py | 2 - tests/mock/releases/test_releases_mock.py | 2 - tests/mock/roles/test_roles_mock.py | 2 - tests/mock/taxonomies/test_taxonomy_mock.py | 2 - tests/mock/terms/test_terms_mock.py | 2 - tests/mock/users/test_mock.py | 4 +- tests/mock/webhooks/test_webhook_mock.py | 2 - tests/mock/workflows/test_workflows_mock.py | 2 - tests/report/assets/style.css | 186 ++++++++++ tests/report/test-report.html | 323 ++++++++++++++++++ tests/unit/aliases/test_alias_unit.py | 1 - tests/unit/assets/test_assets_unit.py | 7 +- tests/unit/auditlogs/test_auditlog_unit.py | 2 - tests/unit/branches/test_branch.py | 2 - .../test_bulk_operations_unit.py | 2 - .../test_bulk_releases_unit.py | 63 ++++ tests/unit/content_types/test_content_type.py | 2 - .../test_delivery_token_unit.py | 2 - tests/unit/entry/test_entry.py | 2 - .../environments/test_environment_unit.py | 2 - tests/unit/extensions/test_extension_unit.py | 2 - .../test_global_fields_unittest.py | 2 - tests/unit/labels/test_label_unit.py | 2 - tests/unit/locales/test_locale_unit.py | 2 - .../test_management_token_unit.py | 2 - tests/unit/metadata/test_metadata_unit.py | 2 - .../unit/organizations/test_organizations.py | 1 - .../publish_queue/test_publish_queue_unit.py | 2 - .../release_items/test_release_items_unit.py | 47 ++- tests/unit/releases/test_release_unit.py | 2 - tests/unit/roles/test_roles_unit.py | 2 - tests/unit/stack/test_stack.py | 1 - tests/unit/taxonomies/test_taxonomy_unit.py | 2 - tests/unit/terms/test_terms_unit.py | 2 - tests/unit/users/test_users.py | 4 +- tests/unit/webhooks/test_webhhok_unittest.py | 2 - .../unit/workflows/test_workflows_unittest.py | 2 - 100 files changed, 781 insertions(+), 183 deletions(-) create mode 100644 tests/report/assets/style.css create mode 100644 tests/report/test-report.html create mode 100644 tests/unit/bulk_operations/test_bulk_releases_unit.py diff --git a/CHANGELOG.md b/CHANGELOG.md index e7d4a98..a6f7ffe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ ## Content Management SDK For Python --- +## v1.4.0 + +#### Date: 26 May 2025 + +- Release 2.0 support. +--- ## v1.3.3 #### Date: 12 May 2025 diff --git a/contentstack_management/__init__.py b/contentstack_management/__init__.py index c7f3b9e..849cd80 100644 --- a/contentstack_management/__init__.py +++ b/contentstack_management/__init__.py @@ -72,7 +72,7 @@ __author__ = 'dev-ex' __status__ = 'debug' __region__ = 'na' -__version__ = '1.3.3' +__version__ = '1.4.0' __host__ = 'api.contentstack.io' __protocol__ = 'https://' __api_version__ = 'v3' diff --git a/contentstack_management/auditlogs/auditlog.py b/contentstack_management/auditlogs/auditlog.py index 43caadd..3a7bf3e 100644 --- a/contentstack_management/auditlogs/auditlog.py +++ b/contentstack_management/auditlogs/auditlog.py @@ -3,9 +3,7 @@ The create(), read(), update(), and delete() methods each correspond to the CRUD operations that can be performed on the API """ -import json from ..common import Parameter -from urllib.parse import quote from .._errors import ArgumentException class Auditlog(Parameter): diff --git a/contentstack_management/bulk_operations/bulk_operation.py b/contentstack_management/bulk_operations/bulk_operation.py index 576c9a8..72cce6c 100644 --- a/contentstack_management/bulk_operations/bulk_operation.py +++ b/contentstack_management/bulk_operations/bulk_operation.py @@ -227,4 +227,96 @@ def update(self, data: dict): data = json.dumps(data) return self.client.post(url, headers = self.client.headers, data = data, params=self.params) + def add_items(self, data: dict, headers: dict = None): + """ + The Add items to bulk operation request allows you to add multiple entries and assets to a bulk operation. + + :return: The `add_items` method is returning the result of the `post` request made by the + `client.post` method. + ------------------------------- + [Example:] + >>> data = { + >>> "release": "release_uid" + >>> "action": "publish", + >>> "locale": ["en-us", "hi-in"] + >>> "reference": true + >>> "items": [ + >>> { + >>> "uid": "blt63177c0f00f20b61", + >>> "content_type_uid": "my_blog" + >>> } + >>> ] + >>> } + >>> import contentstack_management + >>> client = contentstack_management.Client(authtoken='your_authtoken') + >>> result = client.stack('api_key').bulk_operation().add_items(data).json() + + ------------------------------- + """ + if headers is not None: + self.client.headers.update(headers) + url = f"{self.path}/release/items" + data = json.dumps(data) + return self.client.post(url, headers = self.client.headers, data = data, params=self.params) + + def update_items(self, data: dict, headers: dict = None): + """ + The update items to bulk operation request allows you to update multiple entries and assets to a bulk operation. + + :return: The `update_items` method is returning the result of the `put` request made by the + `client.post` method. + ------------------------------- + [Example:] + >>> data = { + >>> "release": "release_uid", + >>> "items": [ + >>> { + >>> "uid": "entry_uid", + >>> "locale": "en-us" + >>> }, + >>> { + >>> "uid": "entry_uid", + >>> "locale": "en-us", + >>> "variant_id": "entry_variant_id" + >>> } + >>> ] + >>> or + >>> [ '$all' ] + >>> } + >>> import contentstack_management + >>> client = contentstack_management.Client(authtoken='your_authtoken') + >>> result = client.stack('api_key').bulk_operation().update_items(data).json() + + ------------------------------- + """ + if headers is not None: + self.client.headers.update(headers) + url = f"{self.path}/release/update_items" + data = json.dumps(data) + return self.client.put(url, headers = self.client.headers, data = data, params=self.params) + + def job_status(self, job_uid: str, headers: dict = None): + """ + The Job status request allows you to get the status of a bulk operation job. + + :param job_uid: The `job_uid` parameter is a string that represents the unique identifier of the job + whose status you want to retrieve + :type job_uid: str + :return: The `job_status` method is returning the result of the `get` request made by the + `client.get` method. + ------------------------------- + [Example:] + >>> import contentstack_management + >>> client = contentstack_management.Client(authtoken='your_authtoken') + >>> result = client.stack('api_key').bulk_operation().job_status('job_uid').json() + + ------------------------------- + """ + if job_uid is None: + raise ArgumentException("job_uid", "job_uid cannot be None") + if headers is not None: + self.client.headers.update(headers) + url = f"{self.path}/jobs/{quote(job_uid)}" + return self.client.get(url, headers = self.client.headers, params=self.params) + \ No newline at end of file diff --git a/contentstack_management/content_types/content_type.py b/contentstack_management/content_types/content_type.py index bc50341..d03ccf1 100644 --- a/contentstack_management/content_types/content_type.py +++ b/contentstack_management/content_types/content_type.py @@ -340,7 +340,7 @@ def imports(self, file_path): >>> response = content_type.imports() -------------------------------- """ - url = f"content_types/import" + url = "content_types/import" self.client.headers['Content-Type'] = "multipart/form-data" files = {'content_type': open(f"{file_path}", 'rb')} return self.client.post(url, headers=self.client.headers, params=self.params, files=files) diff --git a/contentstack_management/contentstack.py b/contentstack_management/contentstack.py index f839067..6cf5f05 100644 --- a/contentstack_management/contentstack.py +++ b/contentstack_management/contentstack.py @@ -1,4 +1,3 @@ -import contentstack_management from enum import Enum from ._api_client import _APIClient from contentstack_management.organizations import organization diff --git a/contentstack_management/delivery_token/delivery_token.py b/contentstack_management/delivery_token/delivery_token.py index 9af6ab9..c22a786 100644 --- a/contentstack_management/delivery_token/delivery_token.py +++ b/contentstack_management/delivery_token/delivery_token.py @@ -5,7 +5,6 @@ import json from ..common import Parameter -from urllib.parse import quote from .._errors import ArgumentException class DeliveryToken(Parameter): diff --git a/contentstack_management/environments/environment.py b/contentstack_management/environments/environment.py index 9647bdc..2f073e3 100644 --- a/contentstack_management/environments/environment.py +++ b/contentstack_management/environments/environment.py @@ -5,7 +5,6 @@ import json from ..common import Parameter -from urllib.parse import quote from .._errors import ArgumentException class Environment(Parameter): diff --git a/contentstack_management/extensions/extension.py b/contentstack_management/extensions/extension.py index f7247fe..c3f8a52 100644 --- a/contentstack_management/extensions/extension.py +++ b/contentstack_management/extensions/extension.py @@ -5,7 +5,6 @@ import json from ..common import Parameter -from urllib.parse import quote from .._errors import ArgumentException from requests_toolbelt.multipart.encoder import MultipartEncoder diff --git a/contentstack_management/labels/label.py b/contentstack_management/labels/label.py index 4a235ff..b935ac0 100644 --- a/contentstack_management/labels/label.py +++ b/contentstack_management/labels/label.py @@ -5,7 +5,6 @@ import json from ..common import Parameter -from urllib.parse import quote from .._errors import ArgumentException class Label(Parameter): diff --git a/contentstack_management/locale/locale.py b/contentstack_management/locale/locale.py index 5e57fdf..9d08671 100644 --- a/contentstack_management/locale/locale.py +++ b/contentstack_management/locale/locale.py @@ -5,7 +5,6 @@ import json from ..common import Parameter -from urllib.parse import quote from .._errors import ArgumentException class Locale(Parameter): diff --git a/contentstack_management/management_token/management_token.py b/contentstack_management/management_token/management_token.py index 23e0e81..3589d0e 100644 --- a/contentstack_management/management_token/management_token.py +++ b/contentstack_management/management_token/management_token.py @@ -5,7 +5,6 @@ import json from ..common import Parameter -from urllib.parse import quote from .._errors import ArgumentException class ManagementToken(Parameter): diff --git a/contentstack_management/metadata/metadata.py b/contentstack_management/metadata/metadata.py index 1d20a5a..1f06916 100644 --- a/contentstack_management/metadata/metadata.py +++ b/contentstack_management/metadata/metadata.py @@ -5,7 +5,6 @@ import json from ..common import Parameter -from urllib.parse import quote from .._errors import ArgumentException class Metadata(Parameter): diff --git a/contentstack_management/publish_queue/publish_queue.py b/contentstack_management/publish_queue/publish_queue.py index ffa18ec..2be0d2d 100644 --- a/contentstack_management/publish_queue/publish_queue.py +++ b/contentstack_management/publish_queue/publish_queue.py @@ -3,9 +3,7 @@ The create(), read(), update(), and delete() methods each correspond to the CRUD operations that can be performed on the API """ -import json from ..common import Parameter -from urllib.parse import quote from .._errors import ArgumentException class PublishQueue(Parameter): diff --git a/contentstack_management/release_items/release_item.py b/contentstack_management/release_items/release_item.py index c4eedd6..60bc5a3 100644 --- a/contentstack_management/release_items/release_item.py +++ b/contentstack_management/release_items/release_item.py @@ -5,7 +5,6 @@ import json from ..common import Parameter -from urllib.parse import quote from .._errors import ArgumentException class ReleaseItems(Parameter): @@ -16,11 +15,13 @@ class ReleaseItems(Parameter): methods each correspond to the CRUD operations that can be performed on the API """ - def __init__(self, client, release_uid: str): + def __init__(self, client, release_uid: str, headers: dict = None): self.client = client self.release_uid = release_uid super().__init__(self.client) self.path = f"releases/{self.release_uid}" + if headers: + self.add_header_dict(headers) def find(self): """ @@ -204,6 +205,46 @@ def delete_multiple(self, data: dict): data = json.dumps(data) return self.client.delete(url, headers = self.client.headers, data=data, params = self.params) + def move(self, data: dict): + """ + The "Move items to a different Release" request allows you to move one or more items (entries and/or assets) from one Release to another Release. + + :param data: The `data` parameter is a dictionary that contains the data to be sent in the + request body. It will be converted to a JSON string using the `json.dumps()` function before + being sent in the request + :type data: dict + :return: the result of the `post` method call on the `self.client` object. + + ------------------------------- + [Example:] + >>> data ={ + >>> "release_uid": "targe_release_uid", + >>> "item": [ + >>> { + >>> "uid": "entry_uid", + >>> "locale": "en-us" + >>> }, + >>> { + >>> "uid": "entry_uid", + >>> "locale": "en-us", + >>> "variant_id": "entry_variant_id" + >>> } + >>> ] + >>> } + >>> import contentstack_management + >>> client = contentstack_management.Client(authtoken='your_authtoken') + >>> result = result = client.stack('api_key').releases('release_uid').item().move(data) + + ------------------------------- + """ + + self.validate_release_uid() + url = f"{self.path}/items/move" + data = json.dumps(data) + return self.client.post(url, headers = self.client.headers, data=data, params = self.params) + + + def validate_release_uid(self): if self.release_uid is None or '': raise ArgumentException('Releases Uid is required') diff --git a/contentstack_management/releases/release.py b/contentstack_management/releases/release.py index e892a20..e3d3d4f 100644 --- a/contentstack_management/releases/release.py +++ b/contentstack_management/releases/release.py @@ -5,7 +5,6 @@ import json from ..common import Parameter -from urllib.parse import quote from .._errors import ArgumentException from ..release_items.release_item import ReleaseItems @@ -14,11 +13,14 @@ class Releases(Parameter): You can define a “Release” as a set of entries and assets that needs to be deployed (published or unpublished) all at once to a particular environment. """ - def __init__(self, client, release_uid: str): + def __init__(self, client, release_uid: str, headers: dict = None): self.client = client self.release_uid = release_uid super().__init__(self.client) self.path = "releases" + if headers: + self.add_header_dict(headers) + def find(self): """ @@ -192,8 +194,8 @@ def validate_uid(self): if self.release_uid is None or '': raise ArgumentException("Releases Uid is required") - def item(self): + def item(self, headers: dict = None): self.validate_uid() - return ReleaseItems(self.client, self.release_uid) + return ReleaseItems(self.client, self.release_uid, headers) \ No newline at end of file diff --git a/contentstack_management/roles/roles.py b/contentstack_management/roles/roles.py index ed1c727..ef37f2c 100644 --- a/contentstack_management/roles/roles.py +++ b/contentstack_management/roles/roles.py @@ -5,7 +5,6 @@ import json from ..common import Parameter -from urllib.parse import quote from .._errors import ArgumentException class Roles(Parameter): diff --git a/contentstack_management/stack/stack.py b/contentstack_management/stack/stack.py index 08f68d2..9d40699 100644 --- a/contentstack_management/stack/stack.py +++ b/contentstack_management/stack/stack.py @@ -1,5 +1,4 @@ import json -from .._errors import ArgumentException from ..aliases.aliases import Alias from ..assets.assets import Assets from ..branches.branches import Branch @@ -341,8 +340,8 @@ def label(self, label_uid: str = None): def bulk_operation(self): return BulkOperation(self.client) - def releases(self, release_uid: str = None): - return Releases(self.client, release_uid) + def releases(self, release_uid: str = None, headers: dict = None): + return Releases(self.client, release_uid, headers) def delivery_token(self, delivery_token: str = None): return DeliveryToken(self.client, delivery_token) diff --git a/contentstack_management/taxonomies/taxonomy.py b/contentstack_management/taxonomies/taxonomy.py index 62626f6..a6583bd 100644 --- a/contentstack_management/taxonomies/taxonomy.py +++ b/contentstack_management/taxonomies/taxonomy.py @@ -5,7 +5,6 @@ import json from ..common import Parameter -from urllib.parse import quote from .._errors import ArgumentException from ..terms.terms import Terms diff --git a/contentstack_management/terms/terms.py b/contentstack_management/terms/terms.py index 3b4a94f..cbac34a 100644 --- a/contentstack_management/terms/terms.py +++ b/contentstack_management/terms/terms.py @@ -5,7 +5,6 @@ import json from ..common import Parameter -from urllib.parse import quote from .._errors import ArgumentException class Terms(Parameter): diff --git a/contentstack_management/webhooks/webhook.py b/contentstack_management/webhooks/webhook.py index ea15fbe..f94182e 100644 --- a/contentstack_management/webhooks/webhook.py +++ b/contentstack_management/webhooks/webhook.py @@ -5,7 +5,6 @@ import json from ..common import Parameter -from urllib.parse import quote class Webhook(Parameter): """ @@ -20,7 +19,7 @@ def __init__(self, client, webhook_uid): self.webhook_uid = webhook_uid super().__init__(self.client) - self.path = f"webhooks" + self.path = "webhooks" def find(self): """ diff --git a/contentstack_management/workflows/workflows.py b/contentstack_management/workflows/workflows.py index 9019506..c9825c7 100644 --- a/contentstack_management/workflows/workflows.py +++ b/contentstack_management/workflows/workflows.py @@ -5,7 +5,6 @@ import json from ..common import Parameter -from urllib.parse import quote class Workflows(Parameter): """ @@ -20,7 +19,7 @@ def __init__(self, client, workflow_uid): self.workflow_uid = workflow_uid super().__init__(self.client) - self.path = f"workflows" + self.path = "workflows" def find(self): """ @@ -593,7 +592,7 @@ def fetch_tasks(self): ------------------------------- """ - url = f"user/assignments" + url = "user/assignments" return self.client.get(url, headers = self.client.headers, params = self.params) diff --git a/setup.py b/setup.py index fd226f9..a8b749a 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,5 @@ import os import re -import sys from setuptools import setup, find_packages with open("README.md", "r") as f: diff --git a/tests/api/aliases/test_alias.py b/tests/api/aliases/test_alias.py index e627def..e2ad89a 100644 --- a/tests/api/aliases/test_alias.py +++ b/tests/api/aliases/test_alias.py @@ -1,7 +1,5 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/api/assets/test_assets.py b/tests/api/assets/test_assets.py index 6e604ba..5f98a61 100644 --- a/tests/api/assets/test_assets.py +++ b/tests/api/assets/test_assets.py @@ -1,4 +1,3 @@ -import os import unittest import contentstack_management from tests.cred import get_credentials @@ -53,7 +52,7 @@ def test_subfolder(self): self.assertEqual(response.request.method, "GET") def test_upload(self): - file_path = f"tests/resources/mock_assets/chaat.jpeg" + file_path = "tests/resources/mock_assets/chaat.jpeg" response = self.client.stack(api_key).assets().upload(file_path) if response.status_code == 201: self.assertEqual(response.status_code, 201) @@ -61,7 +60,7 @@ def test_upload(self): self.assertEqual(response.request.method, "POST") def test_replace(self): - file_path = f"tests/resources/mock_assets/chaat.jpeg" + file_path = "tests/resources/mock_assets/chaat.jpeg" response = self.client.stack(api_key).assets(asset_uid).replace(file_path) if response.status_code == 200: self.assertEqual(response.status_code, 200) diff --git a/tests/api/auditlogs/test_auditlogs_api.py b/tests/api/auditlogs/test_auditlogs_api.py index 6cbdcf4..fa88ba9 100644 --- a/tests/api/auditlogs/test_auditlogs_api.py +++ b/tests/api/auditlogs/test_auditlogs_api.py @@ -1,7 +1,5 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/api/branches/test_branch_api.py b/tests/api/branches/test_branch_api.py index 30e928d..4ade1d0 100644 --- a/tests/api/branches/test_branch_api.py +++ b/tests/api/branches/test_branch_api.py @@ -1,7 +1,5 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/api/bulk_operations/test_bulk_operations_api.py b/tests/api/bulk_operations/test_bulk_operations_api.py index 1bf9e70..3d8e91b 100644 --- a/tests/api/bulk_operations/test_bulk_operations_api.py +++ b/tests/api/bulk_operations/test_bulk_operations_api.py @@ -1,6 +1,4 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/api/content_types/test_content_type_api.py b/tests/api/content_types/test_content_type_api.py index c6e6ec6..8b7c3f4 100644 --- a/tests/api/content_types/test_content_type_api.py +++ b/tests/api/content_types/test_content_type_api.py @@ -1,7 +1,5 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/api/delivery_token/test_delivery_token_api.py b/tests/api/delivery_token/test_delivery_token_api.py index 27c3c7d..fa63168 100644 --- a/tests/api/delivery_token/test_delivery_token_api.py +++ b/tests/api/delivery_token/test_delivery_token_api.py @@ -1,6 +1,4 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/api/entry/test_entry_api.py b/tests/api/entry/test_entry_api.py index 5c27873..daa5641 100644 --- a/tests/api/entry/test_entry_api.py +++ b/tests/api/entry/test_entry_api.py @@ -1,6 +1,4 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/api/environments/test_environments_api.py b/tests/api/environments/test_environments_api.py index 5d59f1d..26fcc78 100644 --- a/tests/api/environments/test_environments_api.py +++ b/tests/api/environments/test_environments_api.py @@ -1,6 +1,4 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/api/extensions/test_extension_api.py b/tests/api/extensions/test_extension_api.py index a1260d1..55706f3 100644 --- a/tests/api/extensions/test_extension_api.py +++ b/tests/api/extensions/test_extension_api.py @@ -1,6 +1,4 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/api/global_fields/test_global_fields_api.py b/tests/api/global_fields/test_global_fields_api.py index d1ca702..e230971 100644 --- a/tests/api/global_fields/test_global_fields_api.py +++ b/tests/api/global_fields/test_global_fields_api.py @@ -1,7 +1,5 @@ import unittest import json -import os -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/api/labels/test_labels_api.py b/tests/api/labels/test_labels_api.py index e8b570b..309855e 100644 --- a/tests/api/labels/test_labels_api.py +++ b/tests/api/labels/test_labels_api.py @@ -1,6 +1,4 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/api/locales/test_locale_api.py b/tests/api/locales/test_locale_api.py index 449430c..98968af 100644 --- a/tests/api/locales/test_locale_api.py +++ b/tests/api/locales/test_locale_api.py @@ -1,6 +1,4 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/api/management_token/test_management_token_api.py b/tests/api/management_token/test_management_token_api.py index 40bb1dd..55bbbde 100644 --- a/tests/api/management_token/test_management_token_api.py +++ b/tests/api/management_token/test_management_token_api.py @@ -1,6 +1,4 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/api/metadata/test_metadata_api.py b/tests/api/metadata/test_metadata_api.py index 9d612b9..4adacbd 100644 --- a/tests/api/metadata/test_metadata_api.py +++ b/tests/api/metadata/test_metadata_api.py @@ -1,6 +1,4 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/api/publish_queue/test_publish_queue_api.py b/tests/api/publish_queue/test_publish_queue_api.py index 1b07196..9add059 100644 --- a/tests/api/publish_queue/test_publish_queue_api.py +++ b/tests/api/publish_queue/test_publish_queue_api.py @@ -1,6 +1,4 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/api/release_items/test_release_items_api.py b/tests/api/release_items/test_release_items_api.py index e291259..fbb402e 100644 --- a/tests/api/release_items/test_release_items_api.py +++ b/tests/api/release_items/test_release_items_api.py @@ -1,6 +1,4 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/api/releases/test_releases_api.py b/tests/api/releases/test_releases_api.py index 872ea44..a96fc6f 100644 --- a/tests/api/releases/test_releases_api.py +++ b/tests/api/releases/test_releases_api.py @@ -1,6 +1,4 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/api/roles/test_roles_api.py b/tests/api/roles/test_roles_api.py index 31f3a61..603ff78 100644 --- a/tests/api/roles/test_roles_api.py +++ b/tests/api/roles/test_roles_api.py @@ -1,6 +1,4 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/api/taxonomies/test_taxonomy_api.py b/tests/api/taxonomies/test_taxonomy_api.py index b4cfba6..10e9463 100644 --- a/tests/api/taxonomies/test_taxonomy_api.py +++ b/tests/api/taxonomies/test_taxonomy_api.py @@ -1,6 +1,4 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/api/terms/test_terms_api.py b/tests/api/terms/test_terms_api.py index ee273c7..744a5d5 100644 --- a/tests/api/terms/test_terms_api.py +++ b/tests/api/terms/test_terms_api.py @@ -1,6 +1,4 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/api/webhooks/test_webhooks_api.py b/tests/api/webhooks/test_webhooks_api.py index 6abe6d1..c44a458 100644 --- a/tests/api/webhooks/test_webhooks_api.py +++ b/tests/api/webhooks/test_webhooks_api.py @@ -1,6 +1,4 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/api/workflows/test_workflow_api.py b/tests/api/workflows/test_workflow_api.py index 3766482..aedc5e3 100644 --- a/tests/api/workflows/test_workflow_api.py +++ b/tests/api/workflows/test_workflow_api.py @@ -1,6 +1,4 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/mock/aliases/test_alias_mock.py b/tests/mock/aliases/test_alias_mock.py index b08256b..911f10c 100644 --- a/tests/mock/aliases/test_alias_mock.py +++ b/tests/mock/aliases/test_alias_mock.py @@ -1,8 +1,6 @@ import json -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/mock/assets/test_assets_mock.py b/tests/mock/assets/test_assets_mock.py index 2dd6b0d..503d629 100644 --- a/tests/mock/assets/test_assets_mock.py +++ b/tests/mock/assets/test_assets_mock.py @@ -1,4 +1,3 @@ -import os import unittest import json import contentstack_management @@ -49,12 +48,12 @@ def test_subfolder(self): self.assertEqual(asset_uid, response["assets"]["uid"]) def test_upload(self): - file_path = f"tests/mock/resources/mock_assets/image.jpg" + file_path = "tests/mock/resources/mock_assets/image.jpg" response = self.client.stack(api_key).assets().upload(file_path).json() self.assertEqual("Asset created successfully.", response['notice']) def test_replace(self): - file_path = f"tests/mock/resources/mock_assets/image.jpg" + file_path = "tests/mock/resources/mock_assets/image.jpg" response = self.client.stack(api_key).assets(asset_uid).replace(file_path).json() self.assertEqual("Asset updated successfully.", response['notice']) diff --git a/tests/mock/auditlogs/test_auditlogs_mock.py b/tests/mock/auditlogs/test_auditlogs_mock.py index af294e5..015ed34 100644 --- a/tests/mock/auditlogs/test_auditlogs_mock.py +++ b/tests/mock/auditlogs/test_auditlogs_mock.py @@ -1,8 +1,6 @@ import json -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/mock/branches/test_branch_mock.py b/tests/mock/branches/test_branch_mock.py index 74e20ac..576728b 100644 --- a/tests/mock/branches/test_branch_mock.py +++ b/tests/mock/branches/test_branch_mock.py @@ -1,8 +1,6 @@ import json -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/mock/bulk_operations/test_bulk_operations_mock.py b/tests/mock/bulk_operations/test_bulk_operations_mock.py index 871060b..e65e1af 100644 --- a/tests/mock/bulk_operations/test_bulk_operations_mock.py +++ b/tests/mock/bulk_operations/test_bulk_operations_mock.py @@ -1,8 +1,5 @@ -import json -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/mock/content_types/test_content_type_mock.py b/tests/mock/content_types/test_content_type_mock.py index 2c2ffab..343dccc 100644 --- a/tests/mock/content_types/test_content_type_mock.py +++ b/tests/mock/content_types/test_content_type_mock.py @@ -1,8 +1,6 @@ import json -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/mock/delivery_token/test_delivery_token_mock.py b/tests/mock/delivery_token/test_delivery_token_mock.py index 27fda3c..a29df1a 100644 --- a/tests/mock/delivery_token/test_delivery_token_mock.py +++ b/tests/mock/delivery_token/test_delivery_token_mock.py @@ -1,8 +1,6 @@ import json -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/mock/entry/test_entry_mock.py b/tests/mock/entry/test_entry_mock.py index 8b3a774..dd3acd4 100644 --- a/tests/mock/entry/test_entry_mock.py +++ b/tests/mock/entry/test_entry_mock.py @@ -1,7 +1,5 @@ import json -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/mock/environments/test_environments_mock.py b/tests/mock/environments/test_environments_mock.py index b1542c1..f3db165 100644 --- a/tests/mock/environments/test_environments_mock.py +++ b/tests/mock/environments/test_environments_mock.py @@ -1,8 +1,6 @@ import json -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/mock/extensions/test_extension_mock.py b/tests/mock/extensions/test_extension_mock.py index 50f5049..144cad5 100644 --- a/tests/mock/extensions/test_extension_mock.py +++ b/tests/mock/extensions/test_extension_mock.py @@ -1,8 +1,6 @@ import json -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/mock/global_fields/test_global_fields_mock.py b/tests/mock/global_fields/test_global_fields_mock.py index 3097d84..34b3393 100644 --- a/tests/mock/global_fields/test_global_fields_mock.py +++ b/tests/mock/global_fields/test_global_fields_mock.py @@ -1,7 +1,5 @@ import unittest import json -import os -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/mock/labels/test_labels_mock.py b/tests/mock/labels/test_labels_mock.py index d5f316d..f0496dc 100644 --- a/tests/mock/labels/test_labels_mock.py +++ b/tests/mock/labels/test_labels_mock.py @@ -1,8 +1,6 @@ import json -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/mock/locales/test_locale_mock.py b/tests/mock/locales/test_locale_mock.py index 5e34924..e29eadf 100644 --- a/tests/mock/locales/test_locale_mock.py +++ b/tests/mock/locales/test_locale_mock.py @@ -1,8 +1,6 @@ import json -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/mock/management_token/test_management_token_mock.py b/tests/mock/management_token/test_management_token_mock.py index 9cd31d7..0beda99 100644 --- a/tests/mock/management_token/test_management_token_mock.py +++ b/tests/mock/management_token/test_management_token_mock.py @@ -1,8 +1,6 @@ import json -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/mock/metadata/test_metadata_mock.py b/tests/mock/metadata/test_metadata_mock.py index 32fa26d..31f743f 100644 --- a/tests/mock/metadata/test_metadata_mock.py +++ b/tests/mock/metadata/test_metadata_mock.py @@ -1,8 +1,6 @@ import json -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/mock/organizations/test_org_mock.py b/tests/mock/organizations/test_org_mock.py index 7b54a0f..8ef6f96 100644 --- a/tests/mock/organizations/test_org_mock.py +++ b/tests/mock/organizations/test_org_mock.py @@ -1,8 +1,6 @@ import json -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/mock/publish_queue/test_publish_queue_mock.py b/tests/mock/publish_queue/test_publish_queue_mock.py index d45ec93..8ed828f 100644 --- a/tests/mock/publish_queue/test_publish_queue_mock.py +++ b/tests/mock/publish_queue/test_publish_queue_mock.py @@ -1,8 +1,6 @@ import json -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/mock/release_items/test_release_items_mock.py b/tests/mock/release_items/test_release_items_mock.py index 1ff0a0d..771bc7d 100644 --- a/tests/mock/release_items/test_release_items_mock.py +++ b/tests/mock/release_items/test_release_items_mock.py @@ -1,7 +1,5 @@ -import os import json import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/mock/releases/test_releases_mock.py b/tests/mock/releases/test_releases_mock.py index 204c2a9..7c71a7c 100644 --- a/tests/mock/releases/test_releases_mock.py +++ b/tests/mock/releases/test_releases_mock.py @@ -1,8 +1,6 @@ import json -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/mock/roles/test_roles_mock.py b/tests/mock/roles/test_roles_mock.py index 1373383..bd391af 100644 --- a/tests/mock/roles/test_roles_mock.py +++ b/tests/mock/roles/test_roles_mock.py @@ -1,8 +1,6 @@ import json -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/mock/taxonomies/test_taxonomy_mock.py b/tests/mock/taxonomies/test_taxonomy_mock.py index 0fbcc1b..758fada 100644 --- a/tests/mock/taxonomies/test_taxonomy_mock.py +++ b/tests/mock/taxonomies/test_taxonomy_mock.py @@ -1,8 +1,6 @@ import json -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/mock/terms/test_terms_mock.py b/tests/mock/terms/test_terms_mock.py index ad6ae29..886cde0 100644 --- a/tests/mock/terms/test_terms_mock.py +++ b/tests/mock/terms/test_terms_mock.py @@ -1,7 +1,5 @@ -import os import json import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/mock/users/test_mock.py b/tests/mock/users/test_mock.py index 967ba58..6dfb917 100644 --- a/tests/mock/users/test_mock.py +++ b/tests/mock/users/test_mock.py @@ -63,7 +63,7 @@ def test_mock_user_update(self): self.assertEqual(mock_user_data['notice'], response['notice']) def test_request_password(self): - url = f"user/forgot_password" + url = "user/forgot_password" act_data = { "user": { "email": "john.doe@contentstack.com" @@ -75,7 +75,7 @@ def test_request_password(self): self.assertEqual(mock_user_data['notice'], response['notice']) def test_reset_password(self): - url = f"user/reset_password" + url = "user/reset_password" act_data = { "user": { "reset_password_token": "abcdefghijklmnop1234567890", diff --git a/tests/mock/webhooks/test_webhook_mock.py b/tests/mock/webhooks/test_webhook_mock.py index 3a8c692..3441e72 100644 --- a/tests/mock/webhooks/test_webhook_mock.py +++ b/tests/mock/webhooks/test_webhook_mock.py @@ -1,8 +1,6 @@ import json -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/mock/workflows/test_workflows_mock.py b/tests/mock/workflows/test_workflows_mock.py index b2ff418..81679d7 100644 --- a/tests/mock/workflows/test_workflows_mock.py +++ b/tests/mock/workflows/test_workflows_mock.py @@ -1,8 +1,6 @@ import json -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/report/assets/style.css b/tests/report/assets/style.css new file mode 100644 index 0000000..3edac88 --- /dev/null +++ b/tests/report/assets/style.css @@ -0,0 +1,186 @@ +body { + font-family: Helvetica, Arial, sans-serif; + font-size: 12px; + /* do not increase min-width as some may use split screens */ + min-width: 800px; + color: #999; +} + +h1 { + font-size: 24px; + color: black; +} + +h2 { + font-size: 16px; + color: black; +} + +p { + color: black; +} + +a { + color: #999; +} + +table { + border-collapse: collapse; +} + +/****************************** + * SUMMARY INFORMATION + ******************************/ +#environment td { + padding: 5px; + border: 1px solid #E6E6E6; +} +#environment tr:nth-child(odd) { + background-color: #f6f6f6; +} + +/****************************** + * TEST RESULT COLORS + ******************************/ +span.passed, +.passed .col-result { + color: green; +} + +span.skipped, +span.xfailed, +span.rerun, +.skipped .col-result, +.xfailed .col-result, +.rerun .col-result { + color: orange; +} + +span.error, +span.failed, +span.xpassed, +.error .col-result, +.failed .col-result, +.xpassed .col-result { + color: red; +} + +/****************************** + * RESULTS TABLE + * + * 1. Table Layout + * 2. Extra + * 3. Sorting items + * + ******************************/ +/*------------------ + * 1. Table Layout + *------------------*/ +#results-table { + border: 1px solid #e6e6e6; + color: #999; + font-size: 12px; + width: 100%; +} +#results-table th, +#results-table td { + padding: 5px; + border: 1px solid #E6E6E6; + text-align: left; +} +#results-table th { + font-weight: bold; +} + +/*------------------ + * 2. Extra + *------------------*/ +.log { + background-color: #e6e6e6; + border: 1px solid #e6e6e6; + color: black; + display: block; + font-family: "Courier New", Courier, monospace; + height: 230px; + overflow-y: scroll; + padding: 5px; + white-space: pre-wrap; +} +.log:only-child { + height: inherit; +} + +div.image { + border: 1px solid #e6e6e6; + float: right; + height: 240px; + margin-left: 5px; + overflow: hidden; + width: 320px; +} +div.image img { + width: 320px; +} + +div.video { + border: 1px solid #e6e6e6; + float: right; + height: 240px; + margin-left: 5px; + overflow: hidden; + width: 320px; +} +div.video video { + overflow: hidden; + width: 320px; + height: 240px; +} + +.collapsed { + display: none; +} + +.expander::after { + content: " (show details)"; + color: #BBB; + font-style: italic; + cursor: pointer; +} + +.collapser::after { + content: " (hide details)"; + color: #BBB; + font-style: italic; + cursor: pointer; +} + +/*------------------ + * 3. Sorting items + *------------------*/ +.sortable { + cursor: pointer; +} + +.sort-icon { + font-size: 0px; + float: left; + margin-right: 5px; + margin-top: 5px; + /*triangle*/ + width: 0; + height: 0; + border-left: 8px solid transparent; + border-right: 8px solid transparent; +} +.inactive .sort-icon { + /*finish triangle*/ + border-top: 8px solid #E6E6E6; +} +.asc.active .sort-icon { + /*finish triangle*/ + border-bottom: 8px solid #999; +} +.desc.active .sort-icon { + /*finish triangle*/ + border-top: 8px solid #999; +} diff --git a/tests/report/test-report.html b/tests/report/test-report.html new file mode 100644 index 0000000..dcc9aca --- /dev/null +++ b/tests/report/test-report.html @@ -0,0 +1,323 @@ + + + + + test-report.html + + + +

test-report.html

+

Report generated on 23-May-2025 at 13:03:20 by pytest-html v3.2.0

+

Summary

+

6 tests ran in 11.66 seconds.

+ 6 passed, 0 skipped, 0 failed, 0 errors, 0 expected failures, 0 unexpected passes +

Results

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ResultTestDurationLinks
Passedtests/unit/aliases/test_alias_unit.py::AliasesUnitTests::test_assign_alias2.05
+
No log output captured.
Passedtests/unit/aliases/test_alias_unit.py::AliasesUnitTests::test_delete_alias2.06
+
No log output captured.
Passedtests/unit/aliases/test_alias_unit.py::AliasesUnitTests::test_get_all_aliases2.06
+
No log output captured.
Passedtests/unit/aliases/test_alias_unit.py::AliasesUnitTests::test_get_an_alias2.04
+
No log output captured.
Passedtests/unit/assets/test_assets_unit.py::AssetsUnitTests::test_asset_type2.39
+
No log output captured.
Passedtests/unit/assets/test_assets_unit.py::AssetsUnitTests::test_create_folder0.00
+
No log output captured.
\ No newline at end of file diff --git a/tests/unit/aliases/test_alias_unit.py b/tests/unit/aliases/test_alias_unit.py index 53c7dd5..ce1051a 100644 --- a/tests/unit/aliases/test_alias_unit.py +++ b/tests/unit/aliases/test_alias_unit.py @@ -1,4 +1,3 @@ -import os import unittest import contentstack_management from tests.cred import get_credentials diff --git a/tests/unit/assets/test_assets_unit.py b/tests/unit/assets/test_assets_unit.py index 00218d0..7f276cb 100644 --- a/tests/unit/assets/test_assets_unit.py +++ b/tests/unit/assets/test_assets_unit.py @@ -1,8 +1,5 @@ -import os import unittest -import json import contentstack_management -from contentstack_management.common import Parameter from tests.cred import get_credentials credentials = get_credentials() @@ -54,13 +51,13 @@ def test_subfolder(self): self.assertEqual(response.request.body, None) def test_upload(self): - file_path = f"tests/resources/mock_assets/chaat.jpeg" + file_path = "tests/resources/mock_assets/chaat.jpeg" response = self.client.stack(api_key).assets().upload(file_path) self.assertEqual(response.request.url, f"{self.client.endpoint}assets") self.assertEqual(response.request.method, "POST") def test_replace(self): - file_path = f"tests/resources/mock_assets/chaat.jpeg" + file_path = "tests/resources/mock_assets/chaat.jpeg" response = self.client.stack(api_key).assets(asset_uid).replace(file_path) self.assertEqual(response.request.url, f"{self.client.endpoint}assets/{asset_uid}") self.assertEqual(response.request.method, "PUT") diff --git a/tests/unit/auditlogs/test_auditlog_unit.py b/tests/unit/auditlogs/test_auditlog_unit.py index ec7c3cb..20c5504 100644 --- a/tests/unit/auditlogs/test_auditlog_unit.py +++ b/tests/unit/auditlogs/test_auditlog_unit.py @@ -1,7 +1,5 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from contentstack_management._errors import ArgumentException diff --git a/tests/unit/branches/test_branch.py b/tests/unit/branches/test_branch.py index c29548c..b37cfd7 100644 --- a/tests/unit/branches/test_branch.py +++ b/tests/unit/branches/test_branch.py @@ -1,7 +1,5 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/unit/bulk_operations/test_bulk_operations_unit.py b/tests/unit/bulk_operations/test_bulk_operations_unit.py index 4f50b5b..d423ff9 100644 --- a/tests/unit/bulk_operations/test_bulk_operations_unit.py +++ b/tests/unit/bulk_operations/test_bulk_operations_unit.py @@ -1,6 +1,4 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/unit/bulk_operations/test_bulk_releases_unit.py b/tests/unit/bulk_operations/test_bulk_releases_unit.py new file mode 100644 index 0000000..5158d53 --- /dev/null +++ b/tests/unit/bulk_operations/test_bulk_releases_unit.py @@ -0,0 +1,63 @@ +import unittest +import contentstack_management +from tests.cred import get_credentials + +credentials = get_credentials() +username = credentials["username"] +password = credentials["password"] +host = credentials["host"] +api_key = credentials["api_key"] + +class BulkOperationReleaseUnitTests(unittest.TestCase): + + def setUp(self): + self.client = contentstack_management.Client(host=host) + self.client.login(username, password) + + def test_add_items(self): + data = { + "release": "release_uid", + "action": "publish", + "locale": ["en-us", "hi-in"], + "reference": True, + "items": [ + { + "uid": "blt63177c0f00f20b61", + "content_type_uid": "my_blog" + } + ] + } + + response = self.client.stack('api_key').bulk_operation().add_items(data,headers={"bulk_version":"2.0"}) + self.assertEqual(response.request.url, f"{self.client.endpoint}bulk/release/items") + self.assertEqual(response.request.method, "POST") + self.assertEqual(response.request.headers["Content-Type"], "application/json") + + def test_update_items(self): + data = { + "release": "release_uid", + "items": [ + { + "uid": "entry_uid", + "locale": "en-us" + }, + { + "uid": "entry_uid", + "locale": "en-us", + "variant_id": "entry_variant_id" + } + ] + or + [ '$all' ] + } + + response = self.client.stack('api_key').bulk_operation().update_items(data, headers={"bulk_version":"2.0"}) + self.assertEqual(response.request.url, f"{self.client.endpoint}bulk/release/update_items") + self.assertEqual(response.request.method, "PUT") + self.assertEqual(response.request.headers["Content-Type"], "application/json") + + def test_job_status(self): + response = self.client.stack('api_key').bulk_operation().job_status('job_uid', headers={"bulk_version":"2.0"}) + self.assertEqual(response.request.url, f"{self.client.endpoint}bulk/jobs/job_uid") + self.assertEqual(response.request.method, "GET") + self.assertEqual(response.request.headers["Content-Type"], "application/json") \ No newline at end of file diff --git a/tests/unit/content_types/test_content_type.py b/tests/unit/content_types/test_content_type.py index cfaed08..eed84b9 100644 --- a/tests/unit/content_types/test_content_type.py +++ b/tests/unit/content_types/test_content_type.py @@ -1,7 +1,5 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/unit/delivery_token/test_delivery_token_unit.py b/tests/unit/delivery_token/test_delivery_token_unit.py index 9c62ac2..6dd0bcc 100644 --- a/tests/unit/delivery_token/test_delivery_token_unit.py +++ b/tests/unit/delivery_token/test_delivery_token_unit.py @@ -1,6 +1,4 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/unit/entry/test_entry.py b/tests/unit/entry/test_entry.py index 82485c6..e598080 100644 --- a/tests/unit/entry/test_entry.py +++ b/tests/unit/entry/test_entry.py @@ -1,6 +1,4 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/unit/environments/test_environment_unit.py b/tests/unit/environments/test_environment_unit.py index 58e0eda..bce2b30 100644 --- a/tests/unit/environments/test_environment_unit.py +++ b/tests/unit/environments/test_environment_unit.py @@ -1,6 +1,4 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/unit/extensions/test_extension_unit.py b/tests/unit/extensions/test_extension_unit.py index b49c82f..3a8a294 100644 --- a/tests/unit/extensions/test_extension_unit.py +++ b/tests/unit/extensions/test_extension_unit.py @@ -1,6 +1,4 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/unit/global_fields/test_global_fields_unittest.py b/tests/unit/global_fields/test_global_fields_unittest.py index 4e8a723..62499a0 100644 --- a/tests/unit/global_fields/test_global_fields_unittest.py +++ b/tests/unit/global_fields/test_global_fields_unittest.py @@ -1,7 +1,5 @@ import unittest import json -import os -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/unit/labels/test_label_unit.py b/tests/unit/labels/test_label_unit.py index 17d7852..3588a3d 100644 --- a/tests/unit/labels/test_label_unit.py +++ b/tests/unit/labels/test_label_unit.py @@ -1,6 +1,4 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/unit/locales/test_locale_unit.py b/tests/unit/locales/test_locale_unit.py index 7c72bd6..a15f1f3 100644 --- a/tests/unit/locales/test_locale_unit.py +++ b/tests/unit/locales/test_locale_unit.py @@ -1,6 +1,4 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/unit/management_token/test_management_token_unit.py b/tests/unit/management_token/test_management_token_unit.py index 12897ed..28cb150 100644 --- a/tests/unit/management_token/test_management_token_unit.py +++ b/tests/unit/management_token/test_management_token_unit.py @@ -1,6 +1,4 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/unit/metadata/test_metadata_unit.py b/tests/unit/metadata/test_metadata_unit.py index a2cdd45..9a87efb 100644 --- a/tests/unit/metadata/test_metadata_unit.py +++ b/tests/unit/metadata/test_metadata_unit.py @@ -1,6 +1,4 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/unit/organizations/test_organizations.py b/tests/unit/organizations/test_organizations.py index f85b697..fa70ac1 100644 --- a/tests/unit/organizations/test_organizations.py +++ b/tests/unit/organizations/test_organizations.py @@ -1,5 +1,4 @@ import json -import os import unittest import contentstack_management diff --git a/tests/unit/publish_queue/test_publish_queue_unit.py b/tests/unit/publish_queue/test_publish_queue_unit.py index 10cb474..0a155af 100644 --- a/tests/unit/publish_queue/test_publish_queue_unit.py +++ b/tests/unit/publish_queue/test_publish_queue_unit.py @@ -1,6 +1,4 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/unit/release_items/test_release_items_unit.py b/tests/unit/release_items/test_release_items_unit.py index 830b9f5..547d9a7 100644 --- a/tests/unit/release_items/test_release_items_unit.py +++ b/tests/unit/release_items/test_release_items_unit.py @@ -1,6 +1,4 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials @@ -102,5 +100,50 @@ def test_delete_multiple(self): self.assertEqual(response.request.url, f"{self.client.endpoint}releases/{releases_uid}/items?all=True") self.assertEqual(response.request.method, "DELETE") self.assertEqual(response.request.headers["Content-Type"], "application/json") + + def test_move_items(self): + data = { + "items": [{ + "uid": "item_uid", + "version": 1, + "locale": "en-us", + "content_type_uid": "your_content_type_uid", + "action": "publish_or_unpublish" + }] + } + response = self.client.stack(api_key).releases(releases_uid).item().move(data) + self.assertEqual(response.request.url, f"{self.client.endpoint}releases/{releases_uid}/items/move") + self.assertEqual(response.request.method, "POST") + self.assertEqual(response.request.headers["Content-Type"], "application/json") + + def test_delete_release2(self): + data = { + "items": [{ + "uid": "items_uid", + "version": 1, + "locale": "ja-jp", + "content_type_uid": "category", + "action": "publish" + }] + } + response = self.client.stack(api_key).releases(releases_uid).item(headers={"release_version": '2.0'}).delete(data) + self.assertEqual(response.request.url, f"{self.client.endpoint}releases/{releases_uid}/items") + self.assertEqual(response.request.method, "DELETE") + self.assertEqual(response.request.headers["Content-Type"], "application/json") + + def test_delete_multiple2(self): + data = { + "items": [{ + "uid": "item_uid", + "locale": "en-us", + "version": 1, + "content_type_uid": "your_content_type_uid", + "action": "publish_or_unpublish" + }] + } + response = self.client.stack(api_key).releases(releases_uid).item(headers={"release_version": '2.0'}).delete_multiple(data) + self.assertEqual(response.request.url, f"{self.client.endpoint}releases/{releases_uid}/items?all=True") + self.assertEqual(response.request.method, "DELETE") + self.assertEqual(response.request.headers["Content-Type"], "application/json") diff --git a/tests/unit/releases/test_release_unit.py b/tests/unit/releases/test_release_unit.py index 2a0f366..a015605 100644 --- a/tests/unit/releases/test_release_unit.py +++ b/tests/unit/releases/test_release_unit.py @@ -1,6 +1,4 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/unit/roles/test_roles_unit.py b/tests/unit/roles/test_roles_unit.py index 24967a5..af9c611 100644 --- a/tests/unit/roles/test_roles_unit.py +++ b/tests/unit/roles/test_roles_unit.py @@ -1,6 +1,4 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/unit/stack/test_stack.py b/tests/unit/stack/test_stack.py index 039ef0f..6ddef45 100644 --- a/tests/unit/stack/test_stack.py +++ b/tests/unit/stack/test_stack.py @@ -1,5 +1,4 @@ import unittest -from urllib.parse import urlencode import contentstack_management from tests.cred import get_credentials diff --git a/tests/unit/taxonomies/test_taxonomy_unit.py b/tests/unit/taxonomies/test_taxonomy_unit.py index a0025fe..561ca88 100644 --- a/tests/unit/taxonomies/test_taxonomy_unit.py +++ b/tests/unit/taxonomies/test_taxonomy_unit.py @@ -1,6 +1,4 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/unit/terms/test_terms_unit.py b/tests/unit/terms/test_terms_unit.py index a4da86a..95ff992 100644 --- a/tests/unit/terms/test_terms_unit.py +++ b/tests/unit/terms/test_terms_unit.py @@ -1,6 +1,4 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/unit/users/test_users.py b/tests/unit/users/test_users.py index 80b6344..61eb6a3 100644 --- a/tests/unit/users/test_users.py +++ b/tests/unit/users/test_users.py @@ -53,7 +53,7 @@ def test_active_user(self): self.assertEqual(response.request.headers["Content-Type"], "application/json") def test_request_password(self): - url = f"user/forgot_password" + url = "user/forgot_password" act_data = { "user": { "email": username @@ -65,7 +65,7 @@ def test_request_password(self): self.assertEqual(response.request.headers["Content-Type"], "application/json") def test_reset_password(self): - url = f"user/reset_password" + url = "user/reset_password" act_data = { "user": { "reset_password_token": "****", diff --git a/tests/unit/webhooks/test_webhhok_unittest.py b/tests/unit/webhooks/test_webhhok_unittest.py index ff91a70..893c428 100644 --- a/tests/unit/webhooks/test_webhhok_unittest.py +++ b/tests/unit/webhooks/test_webhhok_unittest.py @@ -1,6 +1,4 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials diff --git a/tests/unit/workflows/test_workflows_unittest.py b/tests/unit/workflows/test_workflows_unittest.py index 35bac76..da7f5bd 100644 --- a/tests/unit/workflows/test_workflows_unittest.py +++ b/tests/unit/workflows/test_workflows_unittest.py @@ -1,6 +1,4 @@ -import os import unittest -from dotenv import load_dotenv import contentstack_management from tests.cred import get_credentials From 0673297e2cca05a575b7f781eca3de66f0295d82 Mon Sep 17 00:00:00 2001 From: sunil-lakshman <104969541+sunil-lakshman@users.noreply.github.com> Date: Fri, 23 May 2025 13:22:54 +0530 Subject: [PATCH 03/12] Removed test report file --- tests/report/assets/style.css | 186 -------------------- tests/report/test-report.html | 323 ---------------------------------- 2 files changed, 509 deletions(-) delete mode 100644 tests/report/assets/style.css delete mode 100644 tests/report/test-report.html diff --git a/tests/report/assets/style.css b/tests/report/assets/style.css deleted file mode 100644 index 3edac88..0000000 --- a/tests/report/assets/style.css +++ /dev/null @@ -1,186 +0,0 @@ -body { - font-family: Helvetica, Arial, sans-serif; - font-size: 12px; - /* do not increase min-width as some may use split screens */ - min-width: 800px; - color: #999; -} - -h1 { - font-size: 24px; - color: black; -} - -h2 { - font-size: 16px; - color: black; -} - -p { - color: black; -} - -a { - color: #999; -} - -table { - border-collapse: collapse; -} - -/****************************** - * SUMMARY INFORMATION - ******************************/ -#environment td { - padding: 5px; - border: 1px solid #E6E6E6; -} -#environment tr:nth-child(odd) { - background-color: #f6f6f6; -} - -/****************************** - * TEST RESULT COLORS - ******************************/ -span.passed, -.passed .col-result { - color: green; -} - -span.skipped, -span.xfailed, -span.rerun, -.skipped .col-result, -.xfailed .col-result, -.rerun .col-result { - color: orange; -} - -span.error, -span.failed, -span.xpassed, -.error .col-result, -.failed .col-result, -.xpassed .col-result { - color: red; -} - -/****************************** - * RESULTS TABLE - * - * 1. Table Layout - * 2. Extra - * 3. Sorting items - * - ******************************/ -/*------------------ - * 1. Table Layout - *------------------*/ -#results-table { - border: 1px solid #e6e6e6; - color: #999; - font-size: 12px; - width: 100%; -} -#results-table th, -#results-table td { - padding: 5px; - border: 1px solid #E6E6E6; - text-align: left; -} -#results-table th { - font-weight: bold; -} - -/*------------------ - * 2. Extra - *------------------*/ -.log { - background-color: #e6e6e6; - border: 1px solid #e6e6e6; - color: black; - display: block; - font-family: "Courier New", Courier, monospace; - height: 230px; - overflow-y: scroll; - padding: 5px; - white-space: pre-wrap; -} -.log:only-child { - height: inherit; -} - -div.image { - border: 1px solid #e6e6e6; - float: right; - height: 240px; - margin-left: 5px; - overflow: hidden; - width: 320px; -} -div.image img { - width: 320px; -} - -div.video { - border: 1px solid #e6e6e6; - float: right; - height: 240px; - margin-left: 5px; - overflow: hidden; - width: 320px; -} -div.video video { - overflow: hidden; - width: 320px; - height: 240px; -} - -.collapsed { - display: none; -} - -.expander::after { - content: " (show details)"; - color: #BBB; - font-style: italic; - cursor: pointer; -} - -.collapser::after { - content: " (hide details)"; - color: #BBB; - font-style: italic; - cursor: pointer; -} - -/*------------------ - * 3. Sorting items - *------------------*/ -.sortable { - cursor: pointer; -} - -.sort-icon { - font-size: 0px; - float: left; - margin-right: 5px; - margin-top: 5px; - /*triangle*/ - width: 0; - height: 0; - border-left: 8px solid transparent; - border-right: 8px solid transparent; -} -.inactive .sort-icon { - /*finish triangle*/ - border-top: 8px solid #E6E6E6; -} -.asc.active .sort-icon { - /*finish triangle*/ - border-bottom: 8px solid #999; -} -.desc.active .sort-icon { - /*finish triangle*/ - border-top: 8px solid #999; -} diff --git a/tests/report/test-report.html b/tests/report/test-report.html deleted file mode 100644 index dcc9aca..0000000 --- a/tests/report/test-report.html +++ /dev/null @@ -1,323 +0,0 @@ - - - - - test-report.html - - - -

test-report.html

-

Report generated on 23-May-2025 at 13:03:20 by pytest-html v3.2.0

-

Summary

-

6 tests ran in 11.66 seconds.

- 6 passed, 0 skipped, 0 failed, 0 errors, 0 expected failures, 0 unexpected passes -

Results

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ResultTestDurationLinks
Passedtests/unit/aliases/test_alias_unit.py::AliasesUnitTests::test_assign_alias2.05
-
No log output captured.
Passedtests/unit/aliases/test_alias_unit.py::AliasesUnitTests::test_delete_alias2.06
-
No log output captured.
Passedtests/unit/aliases/test_alias_unit.py::AliasesUnitTests::test_get_all_aliases2.06
-
No log output captured.
Passedtests/unit/aliases/test_alias_unit.py::AliasesUnitTests::test_get_an_alias2.04
-
No log output captured.
Passedtests/unit/assets/test_assets_unit.py::AssetsUnitTests::test_asset_type2.39
-
No log output captured.
Passedtests/unit/assets/test_assets_unit.py::AssetsUnitTests::test_create_folder0.00
-
No log output captured.
\ No newline at end of file From 174f6f8309a1b4fc999fd79c360d28c8c0996c9f Mon Sep 17 00:00:00 2001 From: sunil-lakshman <104969541+sunil-lakshman@users.noreply.github.com> Date: Thu, 5 Jun 2025 11:48:46 +0530 Subject: [PATCH 04/12] Added nested global fields support --- CHANGELOG.md | 6 +++ contentstack_management/__init__.py | 2 +- .../global_fields/global_fields.py | 54 ++++++++++++++++--- contentstack_management/stack/stack.py | 6 +-- .../global_fields/test_global_fields_api.py | 34 +++++++----- .../test_global_fields_unittest.py | 38 +++++++++++++ 6 files changed, 113 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a6f7ffe..dd99cca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ ## Content Management SDK For Python --- +## v1.5.0 + +#### Date: 09 June 2025 + +- Added Nested Global fields support. +--- ## v1.4.0 #### Date: 26 May 2025 diff --git a/contentstack_management/__init__.py b/contentstack_management/__init__.py index 849cd80..bcfeb42 100644 --- a/contentstack_management/__init__.py +++ b/contentstack_management/__init__.py @@ -72,7 +72,7 @@ __author__ = 'dev-ex' __status__ = 'debug' __region__ = 'na' -__version__ = '1.4.0' +__version__ = '1.5.0' __host__ = 'api.contentstack.io' __protocol__ = 'https://' __api_version__ = 'v3' diff --git a/contentstack_management/global_fields/global_fields.py b/contentstack_management/global_fields/global_fields.py index d681b49..0e040ed 100644 --- a/contentstack_management/global_fields/global_fields.py +++ b/contentstack_management/global_fields/global_fields.py @@ -18,10 +18,13 @@ class GlobalFields(Parameter): methods each correspond to the CRUD operations that can be performed on the API """ - def __init__(self, client, global_field_uid=None): + def __init__(self, client, global_field_uid=None, options=None): self.client = client self.global_field_uid = global_field_uid + self.options = options super().__init__(self.client) + if self.options and'api_version' in self.options: + Parameter.add_header(self, 'api_version', str(self.options['api_version'])) def find(self): """ @@ -34,7 +37,12 @@ def find(self): >>> result = client.stack("api_key").global_fields('global_field_uid').find().json() ------------------------------- """ - return self.client.get(_path, headers=self.client.headers, params = self.params) + response = self.client.get(_path, headers=self.client.headers, params = self.params) + # Remove the api_version header after request + if self.options and 'api_version' in self.options: + self.client.headers.pop('api_version', None) + + return response def fetch(self): """ @@ -50,7 +58,12 @@ def fetch(self): ------------------------------- """ url = f"{_path}/{self.global_field_uid}" - return self.client.get(url, headers=self.client.headers, params = self.params) + response = self.client.get(url, headers=self.client.headers, params = self.params) + # Remove the api_version header after request + if self.options and 'api_version' in self.options: + self.client.headers.pop('api_version', None) + + return response def create(self, data): """ @@ -74,7 +87,12 @@ def create(self, data): ------------------------------- """ data = json.dumps(data) - return self.client.post(_path, headers=self.client.headers, data=data, params = self.params) + response = self.client.post(_path, headers=self.client.headers, data=data, params = self.params) + # Remove the api_version header after request + if self.options and 'api_version' in self.options: + self.client.headers.pop('api_version', None) + + return response def update(self, data): """ @@ -99,7 +117,12 @@ def update(self, data): """ url = f"{_path}/{self.global_field_uid}" data = json.dumps(data) - return self.client.put(url, headers=self.client.headers, params=self.params, data=data) + response = self.client.put(url, headers=self.client.headers, params=self.params, data=data) + # Remove the api_version header after request + if self.options and 'api_version' in self.options: + self.client.headers.pop('api_version', None) + + return response def delete(self): """ @@ -114,7 +137,12 @@ def delete(self): ------------------------------- """ url = f"{_path}/{self.global_field_uid}" - return self.client.delete(url, headers=self.client.headers, params=self.params) + response = self.client.delete(url, headers=self.client.headers, params=self.params) + # Remove the api_version header after request + if self.options and 'api_version' in self.options: + self.client.headers.pop('api_version', None) + + return response def imports(self, file_path): """ @@ -131,7 +159,12 @@ def imports(self, file_path): """ self.client.headers['Content-Type'] = "multipart/form-data" files = {'global_field': open(f"{file_path}", 'rb')} - return self.client.post('global_fields/import', headers=self.client.headers, params=self.params, files=files) + response = self.client.post('global_fields/import', headers=self.client.headers, params=self.params, files=files) + # Remove the api_version header after request + if self.options and 'api_version' in self.options: + self.client.headers.pop('api_version', None) + + return response def export(self): """ @@ -148,4 +181,9 @@ def export(self): if self.global_field_uid is None or '': raise Exception('global_field_uid is required') url = f"{_path}/{self.global_field_uid}/export" - return self.client.get(url, headers=self.client.headers, params=self.params) + response = self.client.get(url, headers=self.client.headers, params=self.params) + # Remove the api_version header after request + if self.options and 'api_version' in self.options: + self.client.headers.pop('api_version', None) + + return response diff --git a/contentstack_management/stack/stack.py b/contentstack_management/stack/stack.py index 9d40699..8fe4ee5 100644 --- a/contentstack_management/stack/stack.py +++ b/contentstack_management/stack/stack.py @@ -293,10 +293,8 @@ def unshare(self, data): data = json.dumps(data) return self.client.post('stacks/unshare', headers=self.client.headers, params=self.params, data=data) - def global_fields(self, global_field_uid=None): - if 'api_key' not in self.client.headers: - raise Exception('api_key is required') - return GlobalFields(self.client, global_field_uid) + def global_fields(self, global_field_uid=None, options=None): + return GlobalFields(self.client, global_field_uid, options) def branch(self, branch_uid=None): return Branch(self.client, branch_uid) diff --git a/tests/api/global_fields/test_global_fields_api.py b/tests/api/global_fields/test_global_fields_api.py index e230971..8fe168e 100644 --- a/tests/api/global_fields/test_global_fields_api.py +++ b/tests/api/global_fields/test_global_fields_api.py @@ -8,7 +8,7 @@ password = credentials["password"] host = credentials["host"] api_key = credentials["api_key"] -global_field_uid = credentials["global_field_uid"] +global_field_uid = 'global_field_uid' # Replace with actual UID or fetch from response if available class GlobalFieldsApiTests(unittest.TestCase): @@ -23,13 +23,27 @@ def read_file(self, file_name): infile.close() return data - + def test_create_global_fields(self): + read_mock_global_fileds_data = self.read_file("create_global_fields.json") + read_mock_global_fileds_data = json.loads(read_mock_global_fileds_data) + response = self.client.stack(api_key).global_fields().create(read_mock_global_fileds_data) + global_field_uid = response.data.get('uid', 'global_field_uid') + self.assertIsNotNone(global_field_uid, "Global field UID should not be None") + self.assertEqual(response.status_code, 201) + + def test_create_nested_global_fields(self): + read_mock_global_fileds_data = self.read_file("create_global_fields.json") + read_mock_global_fileds_data = json.loads(read_mock_global_fileds_data) + response = self.client.stack(api_key).global_fields(options={'api_version': 3.2}).create(read_mock_global_fileds_data) + global_field_uid1 = response.data.get('uid', 'global_field_uid') + self.assertIsNotNone(global_field_uid1, "Global field UID should not be None") + self.assertEqual(response.status_code, 201) + def test_fetch_global_fields(self): response = self.client.stack(api_key).global_fields(global_field_uid).fetch() - if response.status_code == 200: - self.assertEqual(response.status_code, 200) - else: - self.assertEqual(response.status_code, 422) + self.assertEqual(response.status_code, 200) + self.assertEqual(response.data.get('uid'), global_field_uid, "Fetched global field UID should match the provided UID") + def test_find_all_global_fields(self): response = self.client.stack(api_key).global_fields().find() @@ -38,14 +52,6 @@ def test_find_all_global_fields(self): else: self.assertEqual(response.status_code, 400) - def test_create_global_fields(self): - read_mock_global_fileds_data = self.read_file("create_global_fields.json") - read_mock_global_fileds_data = json.loads(read_mock_global_fileds_data) - response = self.client.stack(api_key).global_fields().create(read_mock_global_fileds_data) - if response.status_code == 200: - self.assertEqual(response.status_code, 200) - else: - self.assertEqual(response.status_code, 422) def test_update_global_fields(self): read_mock_global_fileds_data = self.read_file("create_global_fields.json") diff --git a/tests/unit/global_fields/test_global_fields_unittest.py b/tests/unit/global_fields/test_global_fields_unittest.py index 62499a0..e233619 100644 --- a/tests/unit/global_fields/test_global_fields_unittest.py +++ b/tests/unit/global_fields/test_global_fields_unittest.py @@ -73,6 +73,44 @@ def test_export_global_fields(self): self.assertEqual(response.request.method, "GET") self.assertEqual(response.request.headers["Content-Type"], "application/json") self.assertEqual(response.request.body, None) + + def test_create_nested_global_fields(self): + read_mock_global_fileds_data = self.read_file("create_global_fields.json") + read_mock_global_fileds_data = json.loads(read_mock_global_fileds_data) + response = self.client.stack(api_key).global_fields(options={"api_version": 3.2}).create(read_mock_global_fileds_data) + self.assertEqual(response.request.url, f"{self.client.endpoint}global_fields") + self.assertEqual(response.request.method, "POST") + self.assertEqual(response.request.headers["Content-Type"], "application/json") + self.assertEqual(response.request.headers["api_version"], "3.2") + + def test_update_nested_global_fields(self): + read_mock_global_fileds_data = self.read_file("create_global_fields.json") + read_mock_global_fileds_data = json.loads(read_mock_global_fileds_data) + response = self.client.stack(api_key).global_fields(global_field_uid, options={"api_version": 3.2}).update(read_mock_global_fileds_data) + self.assertEqual(response.request.url, f"{self.client.endpoint}global_fields/{global_field_uid}") + self.assertEqual(response.request.method, "PUT") + self.assertEqual(response.request.headers["api_version"], "3.2") + + def test_delete_nested_global_fields(self): + response= self.client.stack(api_key).global_fields(global_field_uid, options={"api_version": 3.2}).delete() + self.assertEqual(response.request.url, f"{self.client.endpoint}global_fields/{global_field_uid}") + self.assertEqual(response.request.method, "DELETE") + self.assertEqual(response.request.headers["api_version"], "3.2") + + def test_get_nested_global_field(self): + response = self.client.stack(api_key).global_fields(global_field_uid, options={"api_version": 3.2}).fetch() + self.assertEqual(response.request.url, f"{self.client.endpoint}global_fields/{global_field_uid}") + self.assertEqual(response.request.method, "GET") + self.assertEqual(response.request.headers["Content-Type"], "application/json") + self.assertEqual(response.request.headers["api_version"], "3.2") + self.assertEqual(response.request.body, None) + + def test_get_all_nested_global_fields(self): + response = self.client.stack(api_key).global_fields(options={"api_version": 3.2}).find() + self.assertEqual(response.request.url, f"{self.client.endpoint}global_fields") + self.assertEqual(response.request.method, "GET") + self.assertEqual(response.request.headers["Content-Type"], "application/json") + self.assertEqual(response.request.headers["api_version"], "3.2") From 410c13b84c686314af455ca57272d0b8150c267d Mon Sep 17 00:00:00 2001 From: sunil-lakshman <104969541+sunil-lakshman@users.noreply.github.com> Date: Thu, 5 Jun 2025 11:51:29 +0530 Subject: [PATCH 05/12] ignore the dummy secret values --- .talismanrc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.talismanrc b/.talismanrc index 8dc2dcc..8904a30 100644 --- a/.talismanrc +++ b/.talismanrc @@ -354,4 +354,10 @@ fileignoreconfig: checksum: c7323b95249759bc67c33d3a89d3d2e8b3ed3d146b944682d451ebebe22567c0 - filename: .github/workflows/secrets-scan.yml checksum: d79ec3f3288964f7d117b9ad319a54c0ebc152e35f69be8fde95522034fdfb2a -version: "" \ No newline at end of file +version: "" +fileignoreconfig: +- filename: tests/api/global_fields/test_global_fields_api.py + checksum: 1cd57383fcad33cfaddc03aec9a7ee3e85b27de35e4545462fca33e74768e812 +- filename: tests/unit/global_fields/test_global_fields_unittest.py + checksum: 9bb05624cf1dadb770b3cf17fbfe915cf3133d622110da30a7dfebdeab0a315c +version: "1.0" \ No newline at end of file From 09e006f7d7e965c5601d3f51f44c1fb6234e563f Mon Sep 17 00:00:00 2001 From: sunil-lakshman <104969541+sunil-lakshman@users.noreply.github.com> Date: Thu, 5 Jun 2025 12:05:14 +0530 Subject: [PATCH 06/12] Fixed copilot PR comments --- contentstack_management/global_fields/global_fields.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contentstack_management/global_fields/global_fields.py b/contentstack_management/global_fields/global_fields.py index 0e040ed..760532b 100644 --- a/contentstack_management/global_fields/global_fields.py +++ b/contentstack_management/global_fields/global_fields.py @@ -23,7 +23,7 @@ def __init__(self, client, global_field_uid=None, options=None): self.global_field_uid = global_field_uid self.options = options super().__init__(self.client) - if self.options and'api_version' in self.options: + if self.options and 'api_version' in self.options: Parameter.add_header(self, 'api_version', str(self.options['api_version'])) def find(self): From a98ea787c6f254a347d6925fd83f533725f4bb04 Mon Sep 17 00:00:00 2001 From: sunil-lakshman <104969541+sunil-lakshman@users.noreply.github.com> Date: Thu, 5 Jun 2025 12:57:46 +0530 Subject: [PATCH 07/12] Fixed copilot PR comments --- .../test_global_fields_unittest.py | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/unit/global_fields/test_global_fields_unittest.py b/tests/unit/global_fields/test_global_fields_unittest.py index e233619..86c043a 100644 --- a/tests/unit/global_fields/test_global_fields_unittest.py +++ b/tests/unit/global_fields/test_global_fields_unittest.py @@ -39,17 +39,17 @@ def test_get_all_global_fields(self): self.assertEqual(response.request.body, None) def test_create_global_fields(self): - read_mock_global_fileds_data = self.read_file("create_global_fields.json") - read_mock_global_fileds_data = json.loads(read_mock_global_fileds_data) - response = self.client.stack(api_key).global_fields().create(read_mock_global_fileds_data) + read_mock_global_fields_data = self.read_file("create_global_fields.json") + read_mock_global_fields_data = json.loads(read_mock_global_fields_data) + response = self.client.stack(api_key).global_fields().create(read_mock_global_fields_data) self.assertEqual(response.request.url, f"{self.client.endpoint}global_fields") self.assertEqual(response.request.method, "POST") self.assertEqual(response.request.headers["Content-Type"], "application/json") def test_update_global_fields(self): - read_mock_global_fileds_data = self.read_file("create_global_fields.json") - read_mock_global_fileds_data = json.loads(read_mock_global_fileds_data) - response = self.client.stack(api_key).global_fields(global_field_uid).update(read_mock_global_fileds_data) + read_mock_global_fields_data = self.read_file("create_global_fields.json") + read_mock_global_fields_data = json.loads(read_mock_global_fields_data) + response = self.client.stack(api_key).global_fields(global_field_uid).update(read_mock_global_fields_data) self.assertEqual(response.request.url, f"{self.client.endpoint}global_fields/{global_field_uid}") self.assertEqual(response.request.method, "PUT") self.assertEqual(response.request.headers["Content-Type"], "application/json") @@ -75,18 +75,18 @@ def test_export_global_fields(self): self.assertEqual(response.request.body, None) def test_create_nested_global_fields(self): - read_mock_global_fileds_data = self.read_file("create_global_fields.json") - read_mock_global_fileds_data = json.loads(read_mock_global_fileds_data) - response = self.client.stack(api_key).global_fields(options={"api_version": 3.2}).create(read_mock_global_fileds_data) + read_mock_global_fields_data = self.read_file("create_global_fields.json") + read_mock_global_fields_data = json.loads(read_mock_global_fields_data) + response = self.client.stack(api_key).global_fields(options={"api_version": 3.2}).create(read_mock_global_fields_data) self.assertEqual(response.request.url, f"{self.client.endpoint}global_fields") self.assertEqual(response.request.method, "POST") self.assertEqual(response.request.headers["Content-Type"], "application/json") self.assertEqual(response.request.headers["api_version"], "3.2") def test_update_nested_global_fields(self): - read_mock_global_fileds_data = self.read_file("create_global_fields.json") - read_mock_global_fileds_data = json.loads(read_mock_global_fileds_data) - response = self.client.stack(api_key).global_fields(global_field_uid, options={"api_version": 3.2}).update(read_mock_global_fileds_data) + read_mock_global_fields_data = self.read_file("create_global_fields.json") + read_mock_global_fields_data = json.loads(read_mock_global_fields_data) + response = self.client.stack(api_key).global_fields(global_field_uid, options={"api_version": 3.2}).update(read_mock_global_fields_data) self.assertEqual(response.request.url, f"{self.client.endpoint}global_fields/{global_field_uid}") self.assertEqual(response.request.method, "PUT") self.assertEqual(response.request.headers["api_version"], "3.2") From 8a7420cfe6bfcd7d116d22a79c9eab15b4f91f72 Mon Sep 17 00:00:00 2001 From: sunil-lakshman <104969541+sunil-lakshman@users.noreply.github.com> Date: Thu, 5 Jun 2025 12:59:13 +0530 Subject: [PATCH 08/12] Fixed PR comments --- .talismanrc | 2 -- 1 file changed, 2 deletions(-) diff --git a/.talismanrc b/.talismanrc index 8904a30..6527e8d 100644 --- a/.talismanrc +++ b/.talismanrc @@ -354,8 +354,6 @@ fileignoreconfig: checksum: c7323b95249759bc67c33d3a89d3d2e8b3ed3d146b944682d451ebebe22567c0 - filename: .github/workflows/secrets-scan.yml checksum: d79ec3f3288964f7d117b9ad319a54c0ebc152e35f69be8fde95522034fdfb2a -version: "" -fileignoreconfig: - filename: tests/api/global_fields/test_global_fields_api.py checksum: 1cd57383fcad33cfaddc03aec9a7ee3e85b27de35e4545462fca33e74768e812 - filename: tests/unit/global_fields/test_global_fields_unittest.py From 90fd509b541e3bb2f36fb48bd459e4ba84e49100 Mon Sep 17 00:00:00 2001 From: sunil-lakshman <104969541+sunil-lakshman@users.noreply.github.com> Date: Thu, 5 Jun 2025 13:31:19 +0530 Subject: [PATCH 09/12] Fixed PR comments --- .../global_fields/test_global_fields_api.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/api/global_fields/test_global_fields_api.py b/tests/api/global_fields/test_global_fields_api.py index 8fe168e..a80985b 100644 --- a/tests/api/global_fields/test_global_fields_api.py +++ b/tests/api/global_fields/test_global_fields_api.py @@ -24,17 +24,17 @@ def read_file(self, file_name): return data def test_create_global_fields(self): - read_mock_global_fileds_data = self.read_file("create_global_fields.json") - read_mock_global_fileds_data = json.loads(read_mock_global_fileds_data) - response = self.client.stack(api_key).global_fields().create(read_mock_global_fileds_data) + read_mock_global_fields_data = self.read_file("create_global_fields.json") + read_mock_global_fields_data = json.loads(read_mock_global_fields_data) + response = self.client.stack(api_key).global_fields().create(read_mock_global_fields_data) global_field_uid = response.data.get('uid', 'global_field_uid') self.assertIsNotNone(global_field_uid, "Global field UID should not be None") self.assertEqual(response.status_code, 201) def test_create_nested_global_fields(self): - read_mock_global_fileds_data = self.read_file("create_global_fields.json") - read_mock_global_fileds_data = json.loads(read_mock_global_fileds_data) - response = self.client.stack(api_key).global_fields(options={'api_version': 3.2}).create(read_mock_global_fileds_data) + read_mock_global_fields_data = self.read_file("create_global_fields.json") + read_mock_global_fields_data = json.loads(read_mock_global_fields_data) + response = self.client.stack(api_key).global_fields(options={'api_version': 3.2}).create(read_mock_global_fields_data) global_field_uid1 = response.data.get('uid', 'global_field_uid') self.assertIsNotNone(global_field_uid1, "Global field UID should not be None") self.assertEqual(response.status_code, 201) @@ -54,9 +54,9 @@ def test_find_all_global_fields(self): def test_update_global_fields(self): - read_mock_global_fileds_data = self.read_file("create_global_fields.json") - read_mock_global_fileds_data = json.loads(read_mock_global_fileds_data) - response = self.client.stack(api_key).global_fields(global_field_uid).update(read_mock_global_fileds_data) + read_mock_global_fields_data = self.read_file("create_global_fields.json") + read_mock_global_fields_data = json.loads(read_mock_global_fields_data) + response = self.client.stack(api_key).global_fields(global_field_uid).update(read_mock_global_fields_data) if response.status_code == 200: self.assertEqual(response.status_code, 200) else: From 6ceff158bf4b618ee8a49ad7d3ffa24e582ed30d Mon Sep 17 00:00:00 2001 From: sunil-lakshman <104969541+sunil-lakshman@users.noreply.github.com> Date: Thu, 5 Jun 2025 13:32:58 +0530 Subject: [PATCH 10/12] Updated talismanrc --- .talismanrc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.talismanrc b/.talismanrc index 6527e8d..8ebc737 100644 --- a/.talismanrc +++ b/.talismanrc @@ -358,4 +358,6 @@ fileignoreconfig: checksum: 1cd57383fcad33cfaddc03aec9a7ee3e85b27de35e4545462fca33e74768e812 - filename: tests/unit/global_fields/test_global_fields_unittest.py checksum: 9bb05624cf1dadb770b3cf17fbfe915cf3133d622110da30a7dfebdeab0a315c +- filename: tests/api/global_fields/test_global_fields_api.py + checksum: ef69455a51168ea34d62a68caea0984504d3feeafb78010947fa99d7c54d9e9c version: "1.0" \ No newline at end of file From 97d790ce802bd7efe04d8e711fb8f874c1cde91f Mon Sep 17 00:00:00 2001 From: sunil-lakshman <104969541+sunil-lakshman@users.noreply.github.com> Date: Thu, 5 Jun 2025 15:09:03 +0530 Subject: [PATCH 11/12] fixed release version --- CHANGELOG.md | 9 ++------- contentstack_management/__init__.py | 2 +- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dd99cca..e1a86c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,17 +2,12 @@ ## Content Management SDK For Python --- -## v1.5.0 - -#### Date: 09 June 2025 - -- Added Nested Global fields support. ---- ## v1.4.0 -#### Date: 26 May 2025 +#### Date: 09 June 2025 - Release 2.0 support. +- Nested Global fields support --- ## v1.3.3 diff --git a/contentstack_management/__init__.py b/contentstack_management/__init__.py index bcfeb42..849cd80 100644 --- a/contentstack_management/__init__.py +++ b/contentstack_management/__init__.py @@ -72,7 +72,7 @@ __author__ = 'dev-ex' __status__ = 'debug' __region__ = 'na' -__version__ = '1.5.0' +__version__ = '1.4.0' __host__ = 'api.contentstack.io' __protocol__ = 'https://' __api_version__ = 'v3' From 0619bbd30d571359d2c5b75a2c5b4b57a6e97c17 Mon Sep 17 00:00:00 2001 From: harshithad0703 <104908717+harshithad0703@users.noreply.github.com> Date: Fri, 6 Jun 2025 18:31:14 +0530 Subject: [PATCH 12/12] Update .talismanrc --- .talismanrc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.talismanrc b/.talismanrc index 8ebc737..5a277ec 100644 --- a/.talismanrc +++ b/.talismanrc @@ -360,4 +360,12 @@ fileignoreconfig: checksum: 9bb05624cf1dadb770b3cf17fbfe915cf3133d622110da30a7dfebdeab0a315c - filename: tests/api/global_fields/test_global_fields_api.py checksum: ef69455a51168ea34d62a68caea0984504d3feeafb78010947fa99d7c54d9e9c -version: "1.0" \ No newline at end of file +- filename: tests/unit/bulk_operations/test_bulk_releases_unit.py + checksum: 6f21d8928139fe511b7477d25276c3d73d0f500d5b489ac69939f34f5ae6cad9 +- filename: tests/api/global_fields/test_global_fields_api.py + checksum: ef69455a51168ea34d62a68caea0984504d3feeafb78010947fa99d7c54d9e9c +- filename: tests/unit/release_items/test_release_items_unit.py + checksum: f92e78bc9aa8fcdf4cf8490eaa81c7ce8ce518767d9becf1393e847cc2ee12c4 +- filename: tests/unit/global_fields/test_global_fields_unittest.py + checksum: 46297a6fbf321dfe4b85a3d2c1089614af8c9590d8352238c800ad69955b4b6a +version: "1.0"