diff --git a/.talismanrc b/.talismanrc index 8dc2dcc..8ebc737 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 +- filename: tests/api/global_fields/test_global_fields_api.py + 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 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..760532b 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..a80985b 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_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_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) + 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,19 +52,11 @@ 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") - 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: diff --git a/tests/unit/global_fields/test_global_fields_unittest.py b/tests/unit/global_fields/test_global_fields_unittest.py index 62499a0..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") @@ -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_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_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") + + 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")