Contentstack 2.6.1__tar.gz → 2.7.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {contentstack-2.6.1 → contentstack-2.7.0}/Contentstack.egg-info/PKG-INFO +1 -1
- {contentstack-2.6.1 → contentstack-2.7.0}/Contentstack.egg-info/SOURCES.txt +2 -1
- {contentstack-2.6.1 → contentstack-2.7.0}/PKG-INFO +1 -1
- {contentstack-2.6.1 → contentstack-2.7.0}/contentstack/__init__.py +1 -1
- {contentstack-2.6.1 → contentstack-2.7.0}/contentstack/contenttype.py +6 -3
- {contentstack-2.6.1 → contentstack-2.7.0}/contentstack/entry.py +6 -3
- {contentstack-2.6.1 → contentstack-2.7.0}/contentstack/variants.py +30 -16
- {contentstack-2.6.1 → contentstack-2.7.0}/tests/test_entry.py +43 -0
- contentstack-2.7.0/tests/test_variants.py +199 -0
- {contentstack-2.6.1 → contentstack-2.7.0}/Contentstack.egg-info/dependency_links.txt +0 -0
- {contentstack-2.6.1 → contentstack-2.7.0}/Contentstack.egg-info/not-zip-safe +0 -0
- {contentstack-2.6.1 → contentstack-2.7.0}/Contentstack.egg-info/requires.txt +0 -0
- {contentstack-2.6.1 → contentstack-2.7.0}/Contentstack.egg-info/top_level.txt +0 -0
- {contentstack-2.6.1 → contentstack-2.7.0}/LICENSE +0 -0
- {contentstack-2.6.1 → contentstack-2.7.0}/README.md +0 -0
- {contentstack-2.6.1 → contentstack-2.7.0}/contentstack/asset.py +0 -0
- {contentstack-2.6.1 → contentstack-2.7.0}/contentstack/assetquery.py +0 -0
- {contentstack-2.6.1 → contentstack-2.7.0}/contentstack/basequery.py +0 -0
- {contentstack-2.6.1 → contentstack-2.7.0}/contentstack/controller.py +0 -0
- {contentstack-2.6.1 → contentstack-2.7.0}/contentstack/deep_merge_lp.py +0 -0
- {contentstack-2.6.1 → contentstack-2.7.0}/contentstack/endpoint.py +0 -0
- {contentstack-2.6.1 → contentstack-2.7.0}/contentstack/entryqueryable.py +0 -0
- {contentstack-2.6.1 → contentstack-2.7.0}/contentstack/error_messages.py +0 -0
- {contentstack-2.6.1 → contentstack-2.7.0}/contentstack/globalfields.py +0 -0
- {contentstack-2.6.1 → contentstack-2.7.0}/contentstack/https_connection.py +0 -0
- {contentstack-2.6.1 → contentstack-2.7.0}/contentstack/image_transform.py +0 -0
- {contentstack-2.6.1 → contentstack-2.7.0}/contentstack/query.py +0 -0
- {contentstack-2.6.1 → contentstack-2.7.0}/contentstack/region_refresh.py +0 -0
- {contentstack-2.6.1 → contentstack-2.7.0}/contentstack/stack.py +0 -0
- {contentstack-2.6.1 → contentstack-2.7.0}/contentstack/taxonomy.py +0 -0
- {contentstack-2.6.1 → contentstack-2.7.0}/contentstack/utility.py +0 -0
- {contentstack-2.6.1 → contentstack-2.7.0}/setup.cfg +0 -0
- {contentstack-2.6.1 → contentstack-2.7.0}/setup.py +0 -0
- {contentstack-2.6.1 → contentstack-2.7.0}/tests/test_assets.py +0 -0
- {contentstack-2.6.1 → contentstack-2.7.0}/tests/test_basequery.py +0 -0
- {contentstack-2.6.1 → contentstack-2.7.0}/tests/test_early_fetch.py +0 -0
- {contentstack-2.6.1 → contentstack-2.7.0}/tests/test_early_find.py +0 -0
- {contentstack-2.6.1 → contentstack-2.7.0}/tests/test_endpoint.py +0 -0
- {contentstack-2.6.1 → contentstack-2.7.0}/tests/test_global_fields.py +0 -0
- {contentstack-2.6.1 → contentstack-2.7.0}/tests/test_live_preview.py +0 -0
- {contentstack-2.6.1 → contentstack-2.7.0}/tests/test_query.py +0 -0
- {contentstack-2.6.1 → contentstack-2.7.0}/tests/test_stack.py +0 -0
- {contentstack-2.6.1 → contentstack-2.7.0}/tests/test_taxonomies.py +0 -0
|
@@ -42,7 +42,7 @@ def get_contentstack_endpoint(region='us', service='', omit_https=False):
|
|
|
42
42
|
__title__ = 'contentstack-delivery-python'
|
|
43
43
|
__author__ = 'contentstack'
|
|
44
44
|
__status__ = 'debug'
|
|
45
|
-
__version__ = 'v2.
|
|
45
|
+
__version__ = 'v2.7.0'
|
|
46
46
|
__endpoint__ = 'cdn.contentstack.io'
|
|
47
47
|
__email__ = 'support@contentstack.com'
|
|
48
48
|
__developer_email__ = 'mobile@contentstack.com'
|
|
@@ -119,17 +119,20 @@ class ContentType:
|
|
|
119
119
|
result = self.http_instance.get(url)
|
|
120
120
|
return result
|
|
121
121
|
|
|
122
|
-
def variants(self, variant_uid: str | list[str], params: dict = None):
|
|
122
|
+
def variants(self, variant_uid: str | list[str], branch: str = None, params: dict = None):
|
|
123
123
|
"""
|
|
124
124
|
Fetches the variants of the content type
|
|
125
|
-
:param variant_uid: {str} --
|
|
126
|
-
:
|
|
125
|
+
:param variant_uid: {str | list[str]} -- variant UID or list of variant UIDs
|
|
126
|
+
:param branch: {str} -- optional branch name to scope the variant request
|
|
127
|
+
:param params: {dict} -- optional query parameters
|
|
128
|
+
:return: Variants, so you can chain this call.
|
|
127
129
|
"""
|
|
128
130
|
return Variants(
|
|
129
131
|
http_instance=self.http_instance,
|
|
130
132
|
content_type_uid=self.__content_type_uid,
|
|
131
133
|
entry_uid=None,
|
|
132
134
|
variant_uid=variant_uid,
|
|
135
|
+
branch=branch,
|
|
133
136
|
params=params,
|
|
134
137
|
logger=None
|
|
135
138
|
)
|
|
@@ -267,17 +267,20 @@ class Entry(EntryQueryable):
|
|
|
267
267
|
return merged_response # Now correctly returns a dictionary
|
|
268
268
|
raise ValueError(ErrorMessages.MISSING_LIVE_PREVIEW_KEYS)
|
|
269
269
|
|
|
270
|
-
def variants(self, variant_uid: str | list[str], params: dict = None):
|
|
270
|
+
def variants(self, variant_uid: str | list[str], branch: str = None, params: dict = None):
|
|
271
271
|
"""
|
|
272
272
|
Fetches the variants of the entry
|
|
273
|
-
:param variant_uid: {str} --
|
|
274
|
-
:
|
|
273
|
+
:param variant_uid: {str | list[str]} -- variant UID or list of variant UIDs
|
|
274
|
+
:param branch: {str} -- optional branch name to scope the variant request
|
|
275
|
+
:param params: {dict} -- optional query parameters
|
|
276
|
+
:return: Variants, so you can chain this call.
|
|
275
277
|
"""
|
|
276
278
|
return Variants(
|
|
277
279
|
http_instance=self.http_instance,
|
|
278
280
|
content_type_uid=self.content_type_id,
|
|
279
281
|
entry_uid=self.entry_uid,
|
|
280
282
|
variant_uid=variant_uid,
|
|
283
|
+
branch=branch,
|
|
281
284
|
params=params,
|
|
282
285
|
logger=self.logger
|
|
283
286
|
)
|
|
@@ -20,6 +20,7 @@ class Variants(EntryQueryable):
|
|
|
20
20
|
content_type_uid=None,
|
|
21
21
|
entry_uid=None,
|
|
22
22
|
variant_uid=None,
|
|
23
|
+
branch=None,
|
|
23
24
|
params=None,
|
|
24
25
|
logger=None):
|
|
25
26
|
|
|
@@ -30,29 +31,47 @@ class Variants(EntryQueryable):
|
|
|
30
31
|
self.content_type_id = content_type_uid
|
|
31
32
|
self.entry_uid = entry_uid
|
|
32
33
|
self.variant_uid = variant_uid
|
|
34
|
+
self.branch = branch
|
|
33
35
|
self.logger = logger or logging.getLogger(__name__)
|
|
34
36
|
self.entry_param = params or {}
|
|
35
37
|
|
|
38
|
+
def _prepare_variant_headers(self):
|
|
39
|
+
headers = self.http_instance.headers.copy()
|
|
40
|
+
if isinstance(self.variant_uid, str):
|
|
41
|
+
headers['x-cs-variant-uid'] = self.variant_uid
|
|
42
|
+
elif isinstance(self.variant_uid, list):
|
|
43
|
+
headers['x-cs-variant-uid'] = ','.join(self.variant_uid)
|
|
44
|
+
if self.branch is not None:
|
|
45
|
+
headers['branch'] = self.branch
|
|
46
|
+
return headers
|
|
47
|
+
|
|
48
|
+
def _apply_variant_headers(self, headers):
|
|
49
|
+
self._original_branch = self.http_instance.headers.get('branch')
|
|
50
|
+
self.http_instance.headers.update(headers)
|
|
51
|
+
|
|
52
|
+
def _cleanup_variant_headers(self):
|
|
53
|
+
self.http_instance.headers.pop('x-cs-variant-uid', None)
|
|
54
|
+
if self.branch is not None:
|
|
55
|
+
if self._original_branch is not None:
|
|
56
|
+
self.http_instance.headers['branch'] = self._original_branch
|
|
57
|
+
else:
|
|
58
|
+
self.http_instance.headers.pop('branch', None)
|
|
59
|
+
|
|
36
60
|
def find(self, params=None):
|
|
37
61
|
"""
|
|
38
62
|
find the variants of the entry of a particular content type
|
|
39
63
|
:param self.variant_uid: {str} -- self.variant_uid
|
|
40
64
|
:return: Entry, so you can chain this call.
|
|
41
65
|
"""
|
|
42
|
-
headers = self.
|
|
43
|
-
if isinstance(self.variant_uid, str):
|
|
44
|
-
headers['x-cs-variant-uid'] = self.variant_uid
|
|
45
|
-
elif isinstance(self.variant_uid, list):
|
|
46
|
-
headers['x-cs-variant-uid'] = ','.join(self.variant_uid)
|
|
47
|
-
|
|
66
|
+
headers = self._prepare_variant_headers()
|
|
48
67
|
if params is not None:
|
|
49
68
|
self.entry_param.update(params)
|
|
50
69
|
encoded_params = parse.urlencode(self.entry_param)
|
|
51
70
|
endpoint = self.http_instance.endpoint
|
|
52
71
|
url = f'{endpoint}/content_types/{self.content_type_id}/entries?{encoded_params}'
|
|
53
|
-
self.
|
|
72
|
+
self._apply_variant_headers(headers)
|
|
54
73
|
result = self.http_instance.get(url)
|
|
55
|
-
self.
|
|
74
|
+
self._cleanup_variant_headers()
|
|
56
75
|
return result
|
|
57
76
|
|
|
58
77
|
def fetch(self, params=None):
|
|
@@ -77,18 +96,13 @@ class Variants(EntryQueryable):
|
|
|
77
96
|
if self.entry_uid is None:
|
|
78
97
|
raise ValueError(ErrorMessages.ENTRY_UID_REQUIRED)
|
|
79
98
|
else:
|
|
80
|
-
headers = self.
|
|
81
|
-
if isinstance(self.variant_uid, str):
|
|
82
|
-
headers['x-cs-variant-uid'] = self.variant_uid
|
|
83
|
-
elif isinstance(self.variant_uid, list):
|
|
84
|
-
headers['x-cs-variant-uid'] = ','.join(self.variant_uid)
|
|
85
|
-
|
|
99
|
+
headers = self._prepare_variant_headers()
|
|
86
100
|
if params is not None:
|
|
87
101
|
self.entry_param.update(params)
|
|
88
102
|
encoded_params = parse.urlencode(self.entry_param)
|
|
89
103
|
endpoint = self.http_instance.endpoint
|
|
90
104
|
url = f'{endpoint}/content_types/{self.content_type_id}/entries/{self.entry_uid}?{encoded_params}'
|
|
91
|
-
self.
|
|
105
|
+
self._apply_variant_headers(headers)
|
|
92
106
|
result = self.http_instance.get(url)
|
|
93
|
-
self.
|
|
107
|
+
self._cleanup_variant_headers()
|
|
94
108
|
return result
|
|
@@ -9,6 +9,7 @@ ENVIRONMENT = config.ENVIRONMENT
|
|
|
9
9
|
HOST = config.HOST
|
|
10
10
|
FAQ_UID = config.FAQ_UID # Add this in your config.py
|
|
11
11
|
VARIANT_UID = config.VARIANT_UID
|
|
12
|
+
BRANCH = getattr(config, 'BRANCH', None)
|
|
12
13
|
|
|
13
14
|
class TestEntry(unittest.TestCase):
|
|
14
15
|
|
|
@@ -318,6 +319,48 @@ class TestEntry(unittest.TestCase):
|
|
|
318
319
|
result = entry.fetch()
|
|
319
320
|
self.assertIn('variants', result['entry']['publish_details'])
|
|
320
321
|
|
|
322
|
+
@unittest.skipIf(BRANCH is None, "config.BRANCH is required for branch variant tests")
|
|
323
|
+
def test_41a_entry_variants_with_branch(self):
|
|
324
|
+
"""Test single entry variants with branch"""
|
|
325
|
+
content_type = self.stack.content_type('faq')
|
|
326
|
+
result = content_type.entry(FAQ_UID).variants(VARIANT_UID, BRANCH).fetch()
|
|
327
|
+
self.assertIn('variants', result['entry']['publish_details'])
|
|
328
|
+
|
|
329
|
+
@unittest.skipIf(BRANCH is None, "config.BRANCH is required for branch variant tests")
|
|
330
|
+
def test_41b_entry_variants_multiple_uids_with_branch(self):
|
|
331
|
+
"""Test single entry variants with multiple UIDs and branch"""
|
|
332
|
+
content_type = self.stack.content_type('faq')
|
|
333
|
+
result = content_type.entry(FAQ_UID).variants([VARIANT_UID], BRANCH).fetch()
|
|
334
|
+
self.assertIn('variants', result['entry']['publish_details'])
|
|
335
|
+
|
|
336
|
+
@unittest.skipIf(BRANCH is None, "config.BRANCH is required for branch variant tests")
|
|
337
|
+
def test_41c_content_type_variants_find_with_branch(self):
|
|
338
|
+
"""Test entries query variants with branch"""
|
|
339
|
+
content_type = self.stack.content_type('faq')
|
|
340
|
+
result = content_type.variants(VARIANT_UID, BRANCH).find()
|
|
341
|
+
self.assertIn('variants', result['entries'][0]['publish_details'])
|
|
342
|
+
|
|
343
|
+
@unittest.skipIf(BRANCH is None, "config.BRANCH is required for branch variant tests")
|
|
344
|
+
def test_41d_content_type_variants_multiple_uids_find_with_branch(self):
|
|
345
|
+
"""Test entries query variants with multiple UIDs and branch"""
|
|
346
|
+
content_type = self.stack.content_type('faq')
|
|
347
|
+
result = content_type.variants([VARIANT_UID], BRANCH).find()
|
|
348
|
+
self.assertIn('variants', result['entries'][0]['publish_details'])
|
|
349
|
+
|
|
350
|
+
@unittest.skipIf(BRANCH is None, "config.BRANCH is required for branch variant tests")
|
|
351
|
+
def test_41e_content_type_variants_branch_as_keyword_arg(self):
|
|
352
|
+
"""Test content_type.variants() with branch passed as keyword argument"""
|
|
353
|
+
content_type = self.stack.content_type('faq')
|
|
354
|
+
result = content_type.variants(VARIANT_UID, branch=BRANCH).find()
|
|
355
|
+
self.assertIn('variants', result['entries'][0]['publish_details'])
|
|
356
|
+
|
|
357
|
+
@unittest.skipIf(BRANCH is None, "config.BRANCH is required for branch variant tests")
|
|
358
|
+
def test_41f_content_type_variants_branch_with_params(self):
|
|
359
|
+
"""Test content_type.variants() with branch and extra query params"""
|
|
360
|
+
content_type = self.stack.content_type('faq')
|
|
361
|
+
result = content_type.variants(VARIANT_UID, branch=BRANCH, params={'locale': 'en-us'}).find()
|
|
362
|
+
self.assertIn('variants', result['entries'][0]['publish_details'])
|
|
363
|
+
|
|
321
364
|
def test_42_entry_environment_removal(self):
|
|
322
365
|
"""Test entry remove_environment method"""
|
|
323
366
|
entry = (self.stack.content_type('faq')
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Unit tests for Variants branch support in contentstack.variants
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
from unittest.mock import MagicMock
|
|
7
|
+
from urllib.parse import urlencode
|
|
8
|
+
|
|
9
|
+
from contentstack.variants import Variants
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@pytest.fixture
|
|
13
|
+
def mock_http_instance():
|
|
14
|
+
mock = MagicMock()
|
|
15
|
+
mock.endpoint = "https://cdn.contentstack.io/v3"
|
|
16
|
+
mock.headers = {
|
|
17
|
+
"api_key": "api_key",
|
|
18
|
+
"access_token": "delivery_token",
|
|
19
|
+
"environment": "test_env",
|
|
20
|
+
}
|
|
21
|
+
mock.get = MagicMock(return_value={"entries": []})
|
|
22
|
+
return mock
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@pytest.fixture
|
|
26
|
+
def variants(mock_http_instance):
|
|
27
|
+
return Variants(
|
|
28
|
+
http_instance=mock_http_instance,
|
|
29
|
+
content_type_uid="faq",
|
|
30
|
+
entry_uid="entry_uid",
|
|
31
|
+
variant_uid="variant_uid",
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _capture_headers_on_get(mock_http_instance):
|
|
36
|
+
captured = {}
|
|
37
|
+
|
|
38
|
+
def _get(url):
|
|
39
|
+
captured["headers"] = mock_http_instance.headers.copy()
|
|
40
|
+
return {"entries": []}
|
|
41
|
+
|
|
42
|
+
mock_http_instance.get.side_effect = _get
|
|
43
|
+
return captured
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class TestVariantsBranch:
|
|
47
|
+
def test_fetch_sets_variant_and_branch_headers(self, mock_http_instance):
|
|
48
|
+
captured = _capture_headers_on_get(mock_http_instance)
|
|
49
|
+
variants = Variants(
|
|
50
|
+
http_instance=mock_http_instance,
|
|
51
|
+
content_type_uid="faq",
|
|
52
|
+
entry_uid="entry_uid",
|
|
53
|
+
variant_uid="variant_uid",
|
|
54
|
+
branch="dev_branch",
|
|
55
|
+
)
|
|
56
|
+
variants.fetch()
|
|
57
|
+
|
|
58
|
+
assert captured["headers"]["x-cs-variant-uid"] == "variant_uid"
|
|
59
|
+
assert captured["headers"]["branch"] == "dev_branch"
|
|
60
|
+
|
|
61
|
+
def test_fetch_multiple_variant_uids_with_branch(self, mock_http_instance):
|
|
62
|
+
captured = _capture_headers_on_get(mock_http_instance)
|
|
63
|
+
variants = Variants(
|
|
64
|
+
http_instance=mock_http_instance,
|
|
65
|
+
content_type_uid="faq",
|
|
66
|
+
entry_uid="entry_uid",
|
|
67
|
+
variant_uid=["variant1", "variant2"],
|
|
68
|
+
branch="dev_branch",
|
|
69
|
+
)
|
|
70
|
+
variants.fetch()
|
|
71
|
+
|
|
72
|
+
assert captured["headers"]["x-cs-variant-uid"] == "variant1,variant2"
|
|
73
|
+
assert captured["headers"]["branch"] == "dev_branch"
|
|
74
|
+
|
|
75
|
+
def test_find_sets_variant_and_branch_headers(self, mock_http_instance):
|
|
76
|
+
captured = _capture_headers_on_get(mock_http_instance)
|
|
77
|
+
variants = Variants(
|
|
78
|
+
http_instance=mock_http_instance,
|
|
79
|
+
content_type_uid="faq",
|
|
80
|
+
entry_uid=None,
|
|
81
|
+
variant_uid="variant_uid",
|
|
82
|
+
branch="dev_branch",
|
|
83
|
+
)
|
|
84
|
+
variants.find()
|
|
85
|
+
|
|
86
|
+
assert captured["headers"]["x-cs-variant-uid"] == "variant_uid"
|
|
87
|
+
assert captured["headers"]["branch"] == "dev_branch"
|
|
88
|
+
|
|
89
|
+
def test_fetch_restores_stack_branch_after_request(self, mock_http_instance):
|
|
90
|
+
mock_http_instance.headers["branch"] = "main"
|
|
91
|
+
variants = Variants(
|
|
92
|
+
http_instance=mock_http_instance,
|
|
93
|
+
content_type_uid="faq",
|
|
94
|
+
entry_uid="entry_uid",
|
|
95
|
+
variant_uid="variant_uid",
|
|
96
|
+
branch="dev_branch",
|
|
97
|
+
)
|
|
98
|
+
variants.fetch()
|
|
99
|
+
|
|
100
|
+
assert "x-cs-variant-uid" not in mock_http_instance.headers
|
|
101
|
+
assert mock_http_instance.headers["branch"] == "main"
|
|
102
|
+
|
|
103
|
+
def test_fetch_removes_branch_when_stack_had_none(self, mock_http_instance):
|
|
104
|
+
variants = Variants(
|
|
105
|
+
http_instance=mock_http_instance,
|
|
106
|
+
content_type_uid="faq",
|
|
107
|
+
entry_uid="entry_uid",
|
|
108
|
+
variant_uid="variant_uid",
|
|
109
|
+
branch="dev_branch",
|
|
110
|
+
)
|
|
111
|
+
variants.fetch()
|
|
112
|
+
|
|
113
|
+
assert "branch" not in mock_http_instance.headers
|
|
114
|
+
assert "x-cs-variant-uid" not in mock_http_instance.headers
|
|
115
|
+
|
|
116
|
+
def test_fetch_without_branch_uses_stack_branch(self, mock_http_instance):
|
|
117
|
+
mock_http_instance.headers["branch"] = "main"
|
|
118
|
+
variants = Variants(
|
|
119
|
+
http_instance=mock_http_instance,
|
|
120
|
+
content_type_uid="faq",
|
|
121
|
+
entry_uid="entry_uid",
|
|
122
|
+
variant_uid="variant_uid",
|
|
123
|
+
)
|
|
124
|
+
variants.fetch()
|
|
125
|
+
|
|
126
|
+
assert mock_http_instance.headers["branch"] == "main"
|
|
127
|
+
assert "x-cs-variant-uid" not in mock_http_instance.headers
|
|
128
|
+
|
|
129
|
+
def test_fetch_cleans_up_variant_header_only(self, variants, mock_http_instance):
|
|
130
|
+
variants.fetch()
|
|
131
|
+
|
|
132
|
+
assert "x-cs-variant-uid" not in mock_http_instance.headers
|
|
133
|
+
assert mock_http_instance.headers["environment"] == "test_env"
|
|
134
|
+
|
|
135
|
+
def test_fetch_builds_expected_url(self, variants, mock_http_instance):
|
|
136
|
+
variants.fetch()
|
|
137
|
+
expected_url = (
|
|
138
|
+
"https://cdn.contentstack.io/v3/content_types/faq/entries/entry_uid?"
|
|
139
|
+
)
|
|
140
|
+
mock_http_instance.get.assert_called_once()
|
|
141
|
+
assert mock_http_instance.get.call_args[0][0].startswith(expected_url)
|
|
142
|
+
|
|
143
|
+
def test_find_builds_expected_url(self, mock_http_instance):
|
|
144
|
+
variants = Variants(
|
|
145
|
+
http_instance=mock_http_instance,
|
|
146
|
+
content_type_uid="faq",
|
|
147
|
+
entry_uid=None,
|
|
148
|
+
variant_uid="variant_uid",
|
|
149
|
+
branch="dev_branch",
|
|
150
|
+
)
|
|
151
|
+
variants.find(params={"locale": "en-us"})
|
|
152
|
+
expected_params = urlencode({"locale": "en-us"})
|
|
153
|
+
expected_url = (
|
|
154
|
+
f"https://cdn.contentstack.io/v3/content_types/faq/entries?{expected_params}"
|
|
155
|
+
)
|
|
156
|
+
mock_http_instance.get.assert_called_once_with(expected_url)
|
|
157
|
+
|
|
158
|
+
def test_entry_variants_passes_branch(self, mock_http_instance):
|
|
159
|
+
from contentstack.entry import Entry
|
|
160
|
+
|
|
161
|
+
entry = Entry(
|
|
162
|
+
http_instance=mock_http_instance,
|
|
163
|
+
content_type_uid="faq",
|
|
164
|
+
entry_uid="entry_uid",
|
|
165
|
+
)
|
|
166
|
+
result = entry.variants("variant_uid", "dev_branch")
|
|
167
|
+
assert isinstance(result, Variants)
|
|
168
|
+
assert result.branch == "dev_branch"
|
|
169
|
+
assert result.variant_uid == "variant_uid"
|
|
170
|
+
|
|
171
|
+
def test_content_type_variants_passes_branch(self, mock_http_instance):
|
|
172
|
+
from contentstack.contenttype import ContentType
|
|
173
|
+
|
|
174
|
+
content_type = ContentType(mock_http_instance, "faq")
|
|
175
|
+
result = content_type.variants(["variant1", "variant2"], "dev_branch")
|
|
176
|
+
assert isinstance(result, Variants)
|
|
177
|
+
assert result.branch == "dev_branch"
|
|
178
|
+
assert result.variant_uid == ["variant1", "variant2"]
|
|
179
|
+
|
|
180
|
+
def test_variants_backward_compatible_params_kwarg(self, mock_http_instance):
|
|
181
|
+
from contentstack.entry import Entry
|
|
182
|
+
|
|
183
|
+
entry = Entry(
|
|
184
|
+
http_instance=mock_http_instance,
|
|
185
|
+
content_type_uid="faq",
|
|
186
|
+
entry_uid="entry_uid",
|
|
187
|
+
)
|
|
188
|
+
result = entry.variants("variant_uid", params={"locale": "en-us"})
|
|
189
|
+
assert result.branch is None
|
|
190
|
+
assert result.entry_param == {"locale": "en-us"}
|
|
191
|
+
|
|
192
|
+
def test_content_type_variants_fetch_raises_without_entry_uid(self, mock_http_instance):
|
|
193
|
+
from contentstack.contenttype import ContentType
|
|
194
|
+
import pytest
|
|
195
|
+
|
|
196
|
+
content_type = ContentType(mock_http_instance, "faq")
|
|
197
|
+
variants = content_type.variants("variant_uid")
|
|
198
|
+
with pytest.raises(ValueError):
|
|
199
|
+
variants.fetch()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|