Skip to content

Commit 5259051

Browse files
author
Martin Kudlej
committed
add support for mixed entity names in one collection
add CMS files, sections, pages, layouts, partials add related unit tests
1 parent 9fb2dbd commit 5259051

File tree

5 files changed

+336
-1
lines changed

5 files changed

+336
-1
lines changed

tests/integration/conftest.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,3 +497,54 @@ def fields_definition(api, fields_definitions_params):
497497
entity = api.fields_definitions.create(fields_definitions_params)
498498
yield entity
499499
cleanup(entity)
500+
501+
502+
@pytest.fixture(scope="module")
503+
def cms_file_data():
504+
"""CMS file fixture data"""
505+
return dict(path=f"/path{get_suffix()}", downloadable=True)
506+
507+
508+
@pytest.fixture(scope="module")
509+
def cms_file_files(active_docs_body):
510+
"""CMS file fixture files.
511+
File object can be used instead of file body 'active_docs_body',
512+
see https://requests.readthedocs.io/en/latest/user/advanced/#post-multiple-multipart-encoded-files """
513+
return {'attachment': (f"name-{get_suffix()}", active_docs_body, 'application/json', {'Expires': '0'})}
514+
515+
516+
@pytest.fixture(scope="module")
517+
def cms_file(api, cms_file_data, cms_file_files):
518+
"""CMS file fixture"""
519+
entity = api.cms_files.create(params={}, files=cms_file_files, data=cms_file_data)
520+
yield entity
521+
cleanup(entity)
522+
523+
524+
@pytest.fixture(scope="module")
525+
def cms_section_params(cms_file):
526+
"""CMS section fixture params"""
527+
return dict(title=f"title-{get_suffix()}", public=True, partial_path=f"/path-{get_suffix()}",
528+
cms_file_ids=[cms_file['id']])
529+
530+
531+
@pytest.fixture(scope="module")
532+
def cms_section(api, cms_section_params):
533+
"""CMS section fixture"""
534+
entity = api.cms_sections.create(cms_section_params)
535+
yield entity
536+
cleanup(entity)
537+
538+
539+
@pytest.fixture(scope="module")
540+
def cms_partial_params():
541+
"""CMS partial fixture params"""
542+
return dict(type='partial', system_name=f"sname-{get_suffix()}", draft=f"draft-{get_suffix()}")
543+
544+
545+
@pytest.fixture(scope="module")
546+
def cms_partial(api, cms_partial_params):
547+
"""CMS partial fixture"""
548+
entity = api.cms_partials.create(cms_partial_params)
549+
yield entity
550+
cleanup(entity)
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
from tests.integration import asserts
2+
from .asserts import assert_resource, assert_resource_params
3+
4+
5+
# Files
6+
def test_file_list(api, cms_file):
7+
""" List all files. """
8+
assert len(list(api.cms_files.list())) >= 1
9+
10+
11+
def test_file_can_be_created(cms_file_data, cms_file):
12+
""" Is file created properly? """
13+
assert_resource(cms_file)
14+
assert_resource_params(cms_file, cms_file_data)
15+
16+
17+
def test_file_can_be_read(api, cms_file_data, cms_file):
18+
""" It is possible to get file by ID? """
19+
read = api.cms_files.read(cms_file.entity_id)
20+
asserts.assert_resource(read)
21+
asserts.assert_resource_params(read, cms_file_data)
22+
23+
24+
def test_file_can_be_read_by_name(api, cms_file_data, cms_file):
25+
""" It is possible to get file by name? """
26+
file_path = cms_file['path']
27+
read = api.cms_files[file_path]
28+
asserts.assert_resource(read)
29+
asserts.assert_resource_params(read, cms_file_data)
30+
31+
32+
def test_file_can_be_updated(cms_file_data, cms_file):
33+
""" Can be file object updated? """
34+
updated_path = cms_file['path'] = cms_file['path'] + 'up'
35+
cms_file.update()
36+
assert cms_file['path'] == updated_path
37+
updated = cms_file.read()
38+
assert updated['path'] == updated_path
39+
assert cms_file['path'] == updated_path
40+
41+
42+
# Sections
43+
# builtin
44+
45+
def test_builtin_section_list(api):
46+
""" List all sections. """
47+
assert len(list(api.cms_builtin_sections.list())) >= 1
48+
49+
50+
def test_builtin_section_can_be_read(api):
51+
""" It is possible to get section by ID? """
52+
cms_section = next(api.cms_builtin_sections.list())
53+
read = api.cms_sections.read(cms_section.entity_id)
54+
asserts.assert_resource(read)
55+
56+
# user
57+
58+
59+
def test_section_list(api, cms_section):
60+
""" List all sections. """
61+
assert len(list(api.cms_sections.list())) >= 1
62+
63+
64+
def test_section_can_be_created(cms_section_params, cms_section):
65+
""" Is section created properly? """
66+
assert_resource(cms_section)
67+
assert_resource_params(cms_section, cms_section_params)
68+
69+
70+
def test_section_can_be_read(api, cms_section_params, cms_section):
71+
""" It is possible to get section by ID? """
72+
read = api.cms_sections.read(cms_section.entity_id)
73+
asserts.assert_resource(read)
74+
asserts.assert_resource_params(read, cms_section_params)
75+
76+
77+
def test_section_can_be_updated(cms_section_params, cms_section):
78+
""" Can be section object updated? """
79+
updated_title = cms_section['title'] = cms_section['title'] + 'up'
80+
cms_section.update()
81+
assert cms_section['title'] == updated_title
82+
updated = cms_section.read()
83+
assert updated['title'] == updated_title
84+
assert cms_section['title'] == updated_title
85+
86+
# Partials
87+
# builtin
88+
89+
90+
def test_builtin_partials_list(api):
91+
""" List all sections. """
92+
assert len(list(api.cms_builtin_partials.list())) >= 1
93+
94+
95+
def test_builtin_partial_can_be_read(api):
96+
""" It is possible to get partial by ID? """
97+
cms_partial = next(api.cms_builtin_partials.list())
98+
read = api.cms_builtin_partials.read(cms_partial.entity_id)
99+
asserts.assert_resource(read)
100+
101+
# user
102+
103+
104+
def test_partial_list(api, cms_partial):
105+
""" List all user defined partials. """
106+
assert len(list(api.cms_partials.list())) >= 1
107+
108+
109+
def test_partial_can_be_created(cms_partial_params, cms_partial):
110+
""" Is partial created properly? """
111+
assert_resource(cms_partial)
112+
assert_resource_params(cms_partial, cms_partial_params)
113+
114+
115+
def test_partial_can_be_read(api, cms_partial_params, cms_partial):
116+
""" It is possible to get partial by ID? """
117+
read = api.cms_partials.read(cms_partial.entity_id)
118+
asserts.assert_resource(read)
119+
asserts.assert_resource_params(read, cms_partial_params)
120+
121+
122+
def test_partial_can_be_updated(cms_partial_params, cms_partial):
123+
""" Can be partial object updated? """
124+
updated_draft = cms_partial['draft'] = cms_partial['draft'] + 'up'
125+
cms_partial.update()
126+
assert cms_partial['draft'] == updated_draft
127+
updated = cms_partial.read()
128+
assert updated['draft'] == updated_draft
129+
assert cms_partial['draft'] == updated_draft
130+
131+
# # TODO pages, builtin_pages, layouts, template publishing

threescale_api/client.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ def __init__(self, url: str, token: str,
5050
self._invoices = resources.Invoices(self, instance_klass=resources.Invoice)
5151
self._fields_definitions =\
5252
resources.FieldsDefinitions(self, instance_klass=resources.FieldsDefinition)
53+
self._cms_files = resources.CmsFiles(self, instance_klass=resources.CmsFile)
54+
self._cms_sections = resources.CmsSections(self, instance_klass=resources.CmsSection)
55+
self._cms_builtin_sections = resources.CmsBuiltinSections(self, instance_klass=resources.CmsSection)
56+
self._cms_pages = resources.CmsPages(self, instance_klass=resources.CmsPage)
57+
self._cms_builtin_pages = resources.CmsBuiltinPages(self, instance_klass=resources.CmsPage)
58+
self._cms_layouts = resources.CmsLayouts(self, instance_klass=resources.CmsLayout)
59+
self._cms_builtin_partials = resources.CmsBuiltinPartials(self, instance_klass=resources.CmsPartial)
60+
self._cms_partials = resources.CmsPartials(self, instance_klass=resources.CmsPartial)
5361

5462
if wait >= 0:
5563
self.wait_for_tenant()
@@ -255,6 +263,38 @@ def invoices(self) -> resources.Invoices:
255263
def fields_definitions(self) -> resources.FieldsDefinitions:
256264
return self._fields_definitions
257265

266+
@property
267+
def cms_files(self) -> resources.CmsFiles:
268+
return self._cms_files
269+
270+
@property
271+
def cms_sections(self) -> resources.CmsSections:
272+
return self._cms_sections
273+
274+
@property
275+
def cms_builtin_sections(self) -> resources.CmsBuiltinSections:
276+
return self._cms_builtin_sections
277+
278+
@property
279+
def cms_pages(self) -> resources.CmsPages:
280+
return self._cms_pages
281+
282+
@property
283+
def cms_builtin_pages(self) -> resources.CmsBuiltinPages:
284+
return self._cms_builtin_pages
285+
286+
@property
287+
def cms_layouts(self) -> resources.CmsLayouts:
288+
return self._cms_layouts
289+
290+
@property
291+
def cms_partials(self) -> resources.CmsPartials:
292+
return self._cms_partials
293+
294+
@property
295+
def cms_builtin_partials(self) -> resources.CmsBuiltinPartials:
296+
return self._cms_builtin_partials
297+
258298

259299
class RestApiClient:
260300
def __init__(self, url: str, token: str, throws: bool = True, ssl_verify: bool = True):

threescale_api/resources.py

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -913,6 +913,94 @@ def __init__(self, *args, entity_name='fields_definition',
913913
def url(self) -> str:
914914
return self.threescale_client.admin_api_url + '/fields_definitions'
915915

916+
917+
class CmsClient(DefaultClient):
918+
def __init__(self, *args, **kwargs):
919+
super().__init__(*args, **kwargs)
920+
921+
def _list(self, **kwargs):
922+
if "page" in kwargs.get("params", {}):
923+
return super()._list(**kwargs)
924+
925+
pagenum = 1
926+
927+
kwargs = kwargs.copy()
928+
if "params" not in kwargs:
929+
kwargs["params"] = {}
930+
931+
kwargs["params"]["page"] = pagenum
932+
kwargs["params"]["per_page"] = 100
933+
934+
page = super()._list(**kwargs)
935+
936+
while len(page):
937+
for i in page:
938+
yield i
939+
pagenum += 1
940+
kwargs["params"]["page"] = pagenum
941+
page = super()._list(**kwargs)
942+
943+
def __iter__(self):
944+
return self._list()
945+
946+
947+
class CmsFiles(CmsClient):
948+
def __init__(self, *args, entity_name='file', entity_collection='files', **kwargs):
949+
super().__init__(*args, entity_name=entity_name,
950+
entity_collection=entity_collection, **kwargs)
951+
952+
@property
953+
def url(self) -> str:
954+
return self.threescale_client.admin_api_url + '/cms/files'
955+
956+
957+
class CmsSections(CmsClient):
958+
def __init__(self, *args, entity_name='section', entity_collection='sections', **kwargs):
959+
super().__init__(*args, entity_name=entity_name,
960+
entity_collection=entity_collection, **kwargs)
961+
962+
@property
963+
def url(self) -> str:
964+
return self.threescale_client.admin_api_url + '/cms/sections'
965+
966+
class CmsBuiltinSections(CmsSections):
967+
def __init__(self, *args, entity_name='builtin_section', entity_collection='sections', **kwargs):
968+
super().__init__(*args, entity_name=entity_name,
969+
entity_collection=entity_collection, **kwargs)
970+
971+
972+
class CmsTemplates(CmsClient):
973+
def __init__(self, *args, entity_collection='templates', **kwargs):
974+
super().__init__(*args, entity_collection=entity_collection, **kwargs)
975+
976+
@property
977+
def url(self) -> str:
978+
return self.threescale_client.admin_api_url + '/cms/templates'
979+
980+
981+
class CmsPages(CmsTemplates):
982+
def __init__(self, *args, entity_name='page', **kwargs):
983+
super().__init__(*args, entity_name=entity_name, **kwargs)
984+
985+
986+
class CmsBuiltinPages(CmsTemplates):
987+
def __init__(self, *args, entity_name='builtin_page', **kwargs):
988+
super().__init__(*args, entity_name=entity_name, **kwargs)
989+
990+
991+
class CmsLayouts(CmsTemplates):
992+
def __init__(self, *args, entity_name='layout', **kwargs):
993+
super().__init__(*args, entity_name=entity_name, **kwargs)
994+
995+
996+
class CmsPartials(CmsTemplates):
997+
def __init__(self, *args, entity_name='partial', **kwargs):
998+
super().__init__(*args, entity_name=entity_name, **kwargs)
999+
1000+
1001+
class CmsBuiltinPartials(CmsTemplates):
1002+
def __init__(self, *args, entity_name='builtin_partial', **kwargs):
1003+
super().__init__(*args, entity_name=entity_name, **kwargs)
9161004
# Resources
9171005

9181006

@@ -1462,3 +1550,28 @@ def __init__(self, entity_name='name', **kwargs):
14621550
class DevPortalAuthProvider(DefaultResource):
14631551
def __init__(self, entity_name='name', **kwargs):
14641552
super().__init__(entity_name=entity_name, **kwargs)
1553+
1554+
1555+
class CmsFile(DefaultResource):
1556+
def __init__(self, entity_name='path', **kwargs):
1557+
super().__init__(entity_name=entity_name, **kwargs)
1558+
1559+
1560+
class CmsSection(DefaultResource):
1561+
def __init__(self, entity_name='id', **kwargs):
1562+
super().__init__(entity_name=entity_name, **kwargs)
1563+
1564+
1565+
class CmsPage(DefaultResource):
1566+
def __init__(self, entity_name='system_name', **kwargs):
1567+
super().__init__(entity_name=entity_name, **kwargs)
1568+
1569+
1570+
class CmsLayout(DefaultResource):
1571+
def __init__(self, entity_name='system_name', **kwargs):
1572+
super().__init__(entity_name=entity_name, **kwargs)
1573+
1574+
1575+
class CmsPartial(DefaultResource):
1576+
def __init__(self, entity_name='system_name', **kwargs):
1577+
super().__init__(entity_name=entity_name, **kwargs)

threescale_api/utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def extract_response(response: requests.Response, entity: str = None,
2323
if collection and collection in extracted:
2424
extracted = extracted.get(collection)
2525
if isinstance(extracted, list):
26-
return [value.get(entity) for value in extracted]
26+
return [value.get(entity) for value in extracted if entity in value]
2727
if entity in extracted.keys():
2828
return extracted.get(entity)
2929
return extracted

0 commit comments

Comments
 (0)