async def test_register_addon(container_requester): cur_count = len(configure.get_configurations("guillotina.tests", "addon")) @configure.addon(name="myaddon", title="My addon") class MyAddon(Addon): @classmethod def install(cls, container, request): # install code pass @classmethod def uninstall(cls, container, request): # uninstall code pass assert len(configure.get_configurations("guillotina.tests", "addon")) == cur_count + 1 async with container_requester as requester: # now test it... config = requester.root.app.config configure.load_configuration(config, "guillotina.tests", "addon") config.execute_actions() response, status = await requester("GET", "/db/guillotina/@addons") assert "myaddon" in [a["id"] for a in response["available"]]
async def test_register_service_with_path(container_requester): cur_count = len(configure.get_configurations("guillotina.tests", "service")) class TestService(Service): async def __call__(self): path = self.request.matchdict["filepath"] component = self.request.matchdict["component"] return {"filepath": path, "component": component} configure.register_configuration( TestService, dict( context=IContainer, name="@foobar/endpoint/{component}/{filepath:path}", permission="guillotina.ViewContent", ), "service", ) assert len(configure.get_configurations( "guillotina.tests", "service")) == cur_count + 1 # noqa async with container_requester as requester: config = requester.root.app.config configure.load_configuration(config, "guillotina.tests", "service") config.execute_actions() response, status = await requester( "GET", "/db/guillotina/@foobar/endpoint/comp1/root/folder/another") assert response["filepath"] == "root/folder/another"
def reload_content_configuration(): root = get_utility(IApplication, name="root") configure.load_configuration(root.app.config, "guillotina.contrib.dyncontent.contents", "contenttype") root.app.config.execute_actions() load_cached_schema()
async def test_creator_used_from_content_creation(self, dummy_request): self.request = dummy_request utils.login(self.request) container = await create_content( 'Container', id='guillotina', title='Guillotina') container.__name__ = 'guillotina' utils._p_register(container) import guillotina.tests configure.register_configuration(Folder, dict( type_name="TestType2", behaviors=[], module=guillotina.tests # for registration initialization ), 'contenttype') root = get_utility(IApplication, name='root') configure.load_configuration( root.app.config, 'guillotina.tests', 'contenttype') root.app.config.execute_actions() load_cached_schema() obj = await create_content_in_container( container, 'TestType2', 'foobar', creators=('root',), contributors=('root',)) assert obj.creators == ('root',) assert obj.contributors == ('root',) behavior = IDublinCore(obj) assert behavior.creators == ('root',) assert behavior.contributors == ('root',)
async def test_register_service_permission(container_requester): cur_count = len(configure.get_configurations('guillotina.tests', 'service')) class TestService(Service): async def __call__(self): return {"foo": "bar"} configure.permission('guillotina.NoBody', 'Nobody has access') configure.register_configuration( TestService, dict(context=IContainer, name="@foobar2", permission='guillotina.NoBody'), 'service') assert len(configure.get_configurations( 'guillotina.tests', 'service')) == cur_count + 1 # noqa async with container_requester as requester: config = requester.root.app.config configure.load_configuration(config, 'guillotina.tests', 'service') config.execute_actions() response, status = await requester('GET', '/db/guillotina/@foobar2') assert status == 401
async def test_register_addon(container_requester): cur_count = len(configure.get_configurations('guillotina.tests', 'addon')) @configure.addon(name="myaddon", title="My addon") class MyAddon(Addon): @classmethod def install(cls, container, request): # install code pass @classmethod def uninstall(cls, container, request): # uninstall code pass assert len(configure.get_configurations('guillotina.tests', 'addon')) == cur_count + 1 async with container_requester as requester: # now test it... config = requester.root.app.config configure.load_configuration(config, 'guillotina.tests', 'addon') config.execute_actions() response, status = await requester('GET', '/db/guillotina/@addons') assert 'myaddon' in [a['id'] for a in response['available']]
async def test_creator_used_from_content_creation(dummy_guillotina): utils.login() async with transaction(db=await get_database("db")): container = await create_content("Container", id="guillotina", title="Guillotina") container.__name__ = "guillotina" utils.register(container) import guillotina.tests configure.register_configuration( Folder, dict( type_name="TestType2", behaviors=[], module=guillotina.tests ), # for registration initialization "contenttype", ) root = get_utility(IApplication, name="root") configure.load_configuration(root.app.config, "guillotina.tests", "contenttype") root.app.config.execute_actions() load_cached_schema() obj = await create_content_in_container( container, "TestType2", "foobar", creators=("root",), contributors=("root",) ) assert obj.creators == ("root",) assert obj.contributors == ("root",) behavior = IDublinCore(obj) assert behavior.creators == ("root",) assert behavior.contributors == ("root",)
async def test_register_contenttype(container_requester): cur_count = len( configure.get_configurations('guillotina.tests', 'contenttype')) class IMyType(Interface): pass class MyType(Item): pass configure.register_configuration( MyType, dict(context=IContainer, schema=IMyType, type_name="MyType1", behaviors=["guillotina.behaviors.dublincore.IDublinCore"]), 'contenttype') assert len(configure.get_configurations( 'guillotina.tests', 'contenttype')) == cur_count + 1 # noqa async with container_requester as requester: config = requester.root.app.config # now test it... configure.load_configuration(config, 'guillotina.tests', 'contenttype') config.execute_actions() response, status = await requester('GET', '/db/guillotina/@types') assert any("MyType1" in s['title'] for s in response)
async def test_allowed_types(dummy_guillotina): utils.login() async with transaction(db=await get_database("db")): container = await create_content("Container", id="guillotina", title="Guillotina") container.__name__ = "guillotina" utils.register(container) import guillotina.tests configure.register_configuration( Folder, dict( type_name="TestType", allowed_types=["Item"], module=guillotina.tests, # for registration initialization ), "contenttype", ) root = get_utility(IApplication, name="root") configure.load_configuration(root.app.config, "guillotina.tests", "contenttype") root.app.config.execute_actions() load_cached_schema() obj = await create_content_in_container(container, "TestType", "foobar") constrains = IConstrainTypes(obj, None) assert constrains.get_allowed_types() == ["Item"] assert constrains.is_type_allowed("Item") with pytest.raises(NotAllowedContentType): await create_content_in_container(obj, "TestType", "foobar") await create_content_in_container(obj, "Item", "foobar")
def setup_app(): settings = TESTING_SETTINGS.copy() settings['applications'] = ['guillotina.documentation'] aioapp = make_app(settings=settings) @configure.addon( name="myaddon", title="My addon") class MyAddon(Addon): @classmethod def install(cls, site, request): # install code pass @classmethod def uninstall(cls, site, request): # uninstall code pass config = aioapp.config configure.load_configuration( config, 'guillotina.documentation', 'addon') aioapp.config.execute_actions() load_cached_schema()
async def test_register_behavior(container_requester): cur_count = len( configure.get_configurations("guillotina.tests", "behavior")) from guillotina.interfaces import IResource from guillotina import schema class IMyBehavior(Interface): foobar = schema.Text() class IMyBehavior2(Interface): foobar = schema.Text() configure.behavior( title="MyBehavior", provides=IMyBehavior, factory="guillotina.behaviors.instance.AnnotationBehavior", for_="guillotina.interfaces.IResource", )() configure.behavior( title="MyBehavior2", provides=IMyBehavior2, factory="guillotina.behaviors.instance.AnnotationBehavior", for_="guillotina.interfaces.IResource", )() assert len(configure.get_configurations("guillotina.tests", "behavior")) == cur_count + 2 class IMyType(IResource): pass class MyType(Item): pass configure.register_configuration( MyType, dict(context=IContainer, schema=IMyType, type_name="MyType2", behaviors=[IMyBehavior]), "contenttype", ) root = get_utility(IApplication, name="root") config = root.app.config # now test it... configure.load_configuration(config, "guillotina.tests", "contenttype") configure.load_configuration(config, "guillotina.tests", "behavior") config.execute_actions() async with container_requester as requester: response, status = await requester("GET", "/db/guillotina/@types") type_ = [s for s in response if s["title"] == "MyType2"][0] assert "foobar" in type_["definitions"][ "guillotina.tests.test_configure.IMyBehavior"]["properties"] # also get_all_possible_schemas_for_type should come with this new behavior behaviors_schemas = get_all_possible_schemas_for_type("MyType2") assert IMyBehavior2 in behaviors_schemas
async def test_allowed_types(self, dummy_request): self.request = dummy_request utils.login(self.request) container = await create_content( 'Container', id='guillotina', title='Guillotina') container.__name__ = 'guillotina' utils._p_register(container) import guillotina.tests configure.register_configuration(Folder, dict( type_name="TestType", allowed_types=['Item'], module=guillotina.tests # for registration initialization ), 'contenttype') root = get_utility(IApplication, name='root') configure.load_configuration( root.app.config, 'guillotina.tests', 'contenttype') root.app.config.execute_actions() load_cached_schema() obj = await create_content_in_container(container, 'TestType', 'foobar') constrains = IConstrainTypes(obj, None) assert constrains.get_allowed_types() == ['Item'] assert constrains.is_type_allowed('Item') with pytest.raises(NotAllowedContentType): await create_content_in_container(obj, 'TestType', 'foobar') await create_content_in_container(obj, 'Item', 'foobar')
async def test_register_behavior(container_requester): cur_count = len( configure.get_configurations('guillotina.tests', 'behavior')) from guillotina.interfaces import IFormFieldProvider, IResource from zope.interface import provider from guillotina import schema @provider(IFormFieldProvider) class IMyBehavior(Interface): foobar = schema.Text() class IMyBehavior2(Interface): foobar = schema.Text() configure.behavior( title="MyBehavior", provides=IMyBehavior, factory="guillotina.behaviors.instance.AnnotationBehavior", for_="guillotina.interfaces.IResource" )() configure.behavior( title="MyBehavior2", provides=IMyBehavior2, factory="guillotina.behaviors.instance.AnnotationBehavior", for_="guillotina.interfaces.IResource" )() assert len(configure.get_configurations('guillotina.tests', 'behavior')) == cur_count + 2 class IMyType(IResource): pass class MyType(Item): pass configure.register_configuration(MyType, dict( context=IContainer, schema=IMyType, type_name="MyType2", behaviors=[IMyBehavior] ), 'contenttype') root = getUtility(IApplication, name='root') config = root.app.config # now test it... configure.load_configuration(config, 'guillotina.tests', 'contenttype') configure.load_configuration(config, 'guillotina.tests', 'behavior') config.execute_actions() async with await container_requester as requester: response, status = await requester('GET', '/db/guillotina/@types') type_ = [s for s in response if s['title'] == 'MyType2'][0] assert 'foobar' in type_['definitions']['IMyBehavior']['properties'] # also get_all_possible_schemas_for_type should come with this new behavior behaviors_schemas = get_all_possible_schemas_for_type('MyType2') assert IMyBehavior2 in behaviors_schemas
async def __aenter__(self): configure.register_configuration(FoobarType, dict( schema=IFoobarType, portal_type="Foobar", behaviors=[] ), 'contenttype') requester = await super(CustomTypeSiteRequesterAsyncContextManager, self).__aenter__() config = requester.root.app.config # now test it... configure.load_configuration( config, 'guillotina.tests', 'contenttype') config.execute_actions() load_cached_schema() return requester
async def test_globally_addable_types(dummy_guillotina): utils.login() async with transaction(db=await get_database("db")): container = await create_content("Container", id="guillotina", title="Guillotina") container.__name__ = "guillotina" utils.register(container) import guillotina.tests # Define BarType which is not globally addable configure.register_configuration( Folder, dict(type_name="BarType", module=guillotina.tests, globally_addable=False), "contenttype") # Define the only content where BarType is addable configure.register_configuration( Folder, dict(type_name="FooType", allowed_types=["BarType"], module=guillotina.tests), "contenttype", ) root = get_utility(IApplication, name="root") configure.load_configuration(root.app.config, "guillotina.tests", "contenttype") root.app.config.execute_actions() load_cached_schema() # Check that BarType can be added in FooType foo = await create_content_in_container(container, "FooType", "foo") await create_content_in_container(foo, "BarType", "bar") # Check that BarType cannot be globally added with pytest.raises(NotAllowedContentType): await create_content_in_container(container, "BarType", "bar") # Check it can be bypassed await create_content_in_container(container, "BarType", "bar", check_constraints=False)
async def __aenter__(self): configure.register_configuration(FoobarType, dict( schema=IFoobarType, type_name="Foobar", behaviors=[ 'guillotina.behaviors.dublincore.IDublinCore' ] ), 'contenttype') requester = await super(CustomTypeContainerRequesterAsyncContextManager, self).__aenter__() config = requester.root.app.config # now test it... configure.load_configuration( config, 'guillotina.tests', 'contenttype') config.execute_actions() load_cached_schema() return requester
async def __aenter__(self): configure.register_configuration( FoobarType, dict( schema=IFoobarType, type_name="Foobar", behaviors=["guillotina.behaviors.dublincore.IDublinCore"], ), "contenttype", ) requester = await super( CustomTypeContainerRequesterAsyncContextManager, self).__aenter__() config = requester.root.app.config # now test it... configure.load_configuration(config, "guillotina.tests", "contenttype") config.execute_actions() load_cached_schema() return requester
async def test_register_behavior(site_requester): cur_count = len( configure.get_configurations('guillotina.tests', 'behavior')) from guillotina.interfaces import IFormFieldProvider from zope.interface import provider from guillotina import schema @provider(IFormFieldProvider) class IMyBehavior(Interface): foobar = schema.Text() configure.behavior( title="MyBehavior", provides=IMyBehavior, factory="guillotina.behaviors.instance.AnnotationBehavior", for_="guillotina.interfaces.IResource")() assert len(configure.get_configurations('guillotina.tests', 'behavior')) == cur_count + 1 class IMyType(Interface): pass class MyType(Item): pass configure.register_configuration( MyType, dict(context=ISite, schema=IMyType, portal_type="MyType2", behaviors=[IMyBehavior]), 'contenttype') async with await site_requester as requester: config = requester.root.app.config # now test it... configure.load_configuration(config, 'guillotina.tests', 'contenttype') config.execute_actions() response, status = await requester('GET', '/db/guillotina/@types') type_ = [s for s in response if s['title'] == 'MyType2'][0] assert 'foobar' in type_['definitions']['IMyBehavior']['properties']
async def test_register_service(container_requester): cur_count = len(configure.get_configurations("guillotina.tests", "service")) class TestService(Service): async def __call__(self): return {"foo": "bar"} configure.register_configuration( TestService, dict(context=IContainer, name="@foobar", permission="guillotina.ViewContent"), "service" ) assert len(configure.get_configurations("guillotina.tests", "service")) == cur_count + 1 # noqa async with container_requester as requester: config = requester.root.app.config configure.load_configuration(config, "guillotina.tests", "service") config.execute_actions() response, status = await requester("GET", "/db/guillotina/@foobar") assert response["foo"] == "bar"
async def test_register_service(site_requester): cur_count = len(configure.get_configurations('guillotina.tests', 'service')) class TestService(Service): async def __call__(self): return {"foo": "bar"} configure.register_configuration( TestService, dict(context=ISite, name="@foobar", permission='guillotina.ViewContent'), 'service') assert len(configure.get_configurations( 'guillotina.tests', 'service')) == cur_count + 1 # noqa async with await site_requester as requester: config = requester.root.app.config configure.load_configuration(config, 'guillotina.tests', 'service') config.execute_actions() response, status = await requester('GET', '/db/guillotina/@foobar') assert response['foo'] == 'bar'
def create_content_factory(proto_name, proto_definition): parent_interface = import_class( proto_definition.get('inherited_interface', 'guillotina.interfaces.content.IFolder')) parent_class = import_class( proto_definition.get('inherited_class', 'guillotina.content.Folder')) schema_fields, tags = get_fields( properties=proto_definition.get('properties')) for fieldset_id, fieldset_list in proto_definition.get('fieldsets', {}).items(): for field_id in fieldset_list: tags.setdefault(field_id, {})['fieldset'] = fieldset_id class_interface = InterfaceClass('I' + proto_name, (parent_interface, ), schema_fields, __module__='guillotina_cms.interfaces') for field_id, tag in tags.items(): for tag_id, tag_metadata in tag.items(): if tag_id in SUPPORTED_DIRECTIVES: if tag_metadata is None: SUPPORTED_DIRECTIVES[tag_id].apply(class_interface, field_id) elif isinstance(tag_metadata, dict): SUPPORTED_DIRECTIVES[tag_id].apply(class_interface, field_id, **tag_metadata) elif isinstance(tag_metadata, list): SUPPORTED_DIRECTIVES[tag_id].apply(class_interface, field_id, *tag_metadata) elif tag_id == 'fieldset': SUPPORTED_DIRECTIVES[tag_id].apply(class_interface, field_id, tag_metadata) elif isinstance(tag_metadata, str): SUPPORTED_DIRECTIVES[tag_id].apply( class_interface, **{field_id: tag_metadata}) klass = type(proto_name, (parent_class, ), {}) klass.__module__ = 'guillotina_cms.dyncontent' setattr(dyncontent, proto_name, klass) behaviors = [] for bhr in proto_definition.get('behaviors', []): if bhr in BEHAVIOR_CACHE: behaviors.append(BEHAVIOR_CACHE[bhr]) else: raise Exception(f"Behavior not found {bhr}") contenttype = { 'schema': class_interface, 'type_name': proto_name, 'allowed_types': proto_definition.get('allowed_types', []), 'add_permission': proto_definition.get('add_permission', 'guillotina.AddContent'), 'behaviors': behaviors } utility = query_utility(IResourceFactory, name=proto_name) if utility is not None: sm = get_global_components() sm.unregisterUtility(utility, IResourceFactory, proto_name) configure.register_configuration(klass, contenttype, 'contenttype') root = get_utility(IApplication, name='root') configure.load_configuration(root.app.config, 'guillotina_cms.dyncontent', 'contenttype') root.app.config.execute_actions() configure.clear() load_cached_schema() # Verify its created if proto_name in FACTORY_CACHE: del FACTORY_CACHE[proto_name] get_cached_factory(proto_name)
def create_behaviors_factory(proto_name, proto_definition): if proto_definition.get('for', None) is None: raise Exception('We need a for interface') else: for_ = import_class(proto_definition.get('for')) if for_ is None: raise Exception('Wrong for interface') parent_class = import_class( proto_definition.get( 'inherited_class', 'guillotina.behaviors.instance.AnnotationBehavior')) schema_fields, tags = get_fields( properties=proto_definition.get('properties')) base_interface = proto_definition.get('base_interface', None) if base_interface is None: base_interface = Interface class_interface = InterfaceClass('I' + proto_name, (base_interface, ), schema_fields, __module__='guillotina_cms.interfaces') for field_id, tag in tags.items(): for tag_id, tag_metadata in tag.items(): if tag_id in SUPPORTED_DIRECTIVES: SUPPORTED_DIRECTIVES[tag_id].apply(class_interface, field_id, tag_metadata) klass = type(proto_name, (parent_class, ), {}) klass.__module__ = 'guillotina_cms.behaviors' behavior = { 'for_': for_, 'provides': class_interface, 'data_key': proto_definition.get('data_key', 'default'), 'auto_serialize': proto_definition.get('auto_serialize', True), 'name': proto_name, 'name_only': proto_definition.get('name_only', False), 'title': proto_definition.get('title', ''), 'marker': proto_definition.get('marker', None), 'description': proto_definition.get('description', '') } configure.register_configuration(klass, behavior, 'behavior') root = get_utility(IApplication, name='root') configure.load_configuration(root.app.config, 'guillotina_cms.behaviors', 'behavior') root.app.config.execute_actions() configure.clear() load_cached_schema() # Verify its created interface_name = 'guillotina_cms.interfaces.I' + proto_name utility = get_utility(IBehavior, name=interface_name) interface_name = 'guillotina_cms.interfaces.I' + proto_name utility2 = get_utility(IBehavior, name=proto_name) assert BEHAVIOR_CACHE[interface_name] == class_interface utility.interface == class_interface utility2.interface == class_interface