diff --git a/book/extend-admin.rst b/book/extend-admin.rst index e92a0401..bbd139ca 100644 --- a/book/extend-admin.rst +++ b/book/extend-admin.rst @@ -269,6 +269,20 @@ as well, then you should be able to see these actions when using the ``debug:rou app.put_event PUT ANY ANY /admin/api/events/{id}.{_format} app.delete_event DELETE ANY ANY /admin/api/events/{id}.{_format} +.. note:: + + To expose routes also to the admin frontend, you must use the `FOSJsRoutingBundle`_ and set the ``methods`` and the ``expose`` + parameter for the actions. + + For example: ``options: ['expose' => true], methods: ['POST']``. Further examples of exposed routes, can be found in the + `Sulu Workshops`_, specifically assignment 10. + + Sulu automatically exposes actions with names that match the regex pattern ``(.+\.)?c?get_.*``. + + If you want to verify the active rules for exposing routes, you can use the command ``bin/console debug:config fos_js_routing``. + + To confirm that your route is correctly registered, use the command ``bin/console fos:js-routing:debug``. + These routes are spread over two different URLs, one without the ID (``/admin/api/events``) and one with the ID (``/admin/api/events/{id}``). The first one is used to get a list of available events and to create new events, while the latter is about already existing events. @@ -847,3 +861,5 @@ the parent then the ``/config/forms/event_details.xml`` would look like this: .. _Sulu workshop: https://github.com/sulu/sulu-workshop .. _Sulu Demo repository: https://github.com/sulu/sulu-demo/pulls?q=is%3Aopen+is%3Apr+label%3AExample .. _Sulu Javascript Docs: https://jsdocs.sulu.io/ +.. _FOSJsRoutingBundle: https://github.com/FriendsOfSymfony/FOSJsRoutingBundle/blob/master/Resources/doc/usage.rst +.. _Sulu Workshops: https://github.com/sulu/sulu-workshop/pulls diff --git a/bundles/audience_targeting.rst b/bundles/audience_targeting.rst index e2b281b0..152610db 100644 --- a/bundles/audience_targeting.rst +++ b/bundles/audience_targeting.rst @@ -104,8 +104,7 @@ the following steps: deleting the cache folder * Update the schema of your database with the `doctrine:schema:update` command or the `doctrine:migrations:diff` command -* Make sure that the users the feature should be enabled for have the correct - permissions +* Make sure to have the correct permissions by enabling the feature `target-groups` in the user roles. The feature will be visible under `Settings` menu. Manually set target group ------------------------- diff --git a/bundles/index.rst b/bundles/index.rst index a2f3b84d..ddeea5f4 100644 --- a/bundles/index.rst +++ b/bundles/index.rst @@ -28,6 +28,7 @@ documented the most important ones. security/index snippet tag + test trash website/index diff --git a/bundles/test.rst b/bundles/test.rst new file mode 100644 index 00000000..85cc7f5f --- /dev/null +++ b/bundles/test.rst @@ -0,0 +1,143 @@ +TestBundle +========== + +Writing automatic tests for a Sulu project will be similar to tests in a usual +Symfony project. Therefore you should have a look at their `test documentation`_. + + +Sulu's Kernel Context +--------------------- + +Sulu adds an additional layer to the service container of Symfony. This is +the kernel context. It separates the *admin* area from the *website* area. + +When you start writing integration or functional tests you have to keep in mind +that some services are only available in either context. + +Integration Tests +----------------- + +In integration tests you may have depencencies on other services. If a service +is only available in the website context you will get issues, because the +kernel is in admin context per default. + +Therefore Sulu provides an extended `KernelTestCase`_ to specify the kernel +context. + +.. code-block:: php + + // tests/Integration/Service/NewsletterGeneratorTest.php + namespace App\Tests\Integration\Service; + + use Sulu\Bundle\TestBundle\Testing\KernelTestCase; + use Sulu\Component\HttpKernel\SuluKernel; + + class NewsletterGeneratorTest extends KernelTestCase + { + public function testSomething() + { + self::bootKernel([ + 'sulu.context' => SuluKernel::CONTEXT_WEBSITE + ]); + + // ... + } + } + +This will boot the kernel in the website context so that you have access to +the services living in it. + +Functional Tests +---------------- + +In functional tests you test your application from a higher level. Instead of +single methods or algorithms you run the functions from the same level as the +user. + +Similar to integration tests you also have to boot the kernel in the website +context if you want to test controllers and services living in that context. + +Use Sulu's `SuluTestCase`_ to create a client in the website context and define +your expectations to the called action. + +.. code-block:: php + + // tests/Functional/Controller/Website/RegistrationControllerTest.php + namespace App\Tests\Functional\Controller\Website; + + use Sulu\Bundle\TestBundle\Testing\SuluTestCase; + use Sulu\Component\HttpKernel\SuluKernel; + + class RegistrationControllerTest extends SuluTestCase + { + public function testIndexAction(): void + { + $client = static::createWebsiteClient(); + $crawler = $client->request('GET', '/registration/'); + + $this->assertResponseIsSuccessful(); + $this->assertSelectorTextContains('h1', 'Join our Community'); + + // ... + } + } + +Actually calling ``$client = static::createWebsiteClient()`` is equal to this + +.. code-block:: php + + $client = static::createClient([ + 'sulu.context' => SuluKernel::CONTEXT_WEBSITE, + ]); + +Visit the documentation of the `DOM Crawler`_ to find out how to use it to make +your assertions. + +Logging in Users (Authentication) +--------------------------------- + +If you need a logged in user to test secured actions, Sulu provides a test +user, which you can use. + +.. code-block:: php + + class ArticleAdminControllerTest extends SuluTestCase + { + public function testIndexAction(): void + { + $client = static::createClient(); + + $user = $this->getTestUser(); + $client->loginUser($user); + } + } + +The user you get, is an entity of the type ``Sulu\Bundle\SecurityBundle\Entity\User``, +has the role *ROLE_USER* and it is automatically granted access if authorization +is checked. + +Database purging +---------------- + +If you are doing database manipulations in your tests, and need a clean database +before you run your tests. You may want to use Sulu's database purging helper. + +.. code-block:: php + + class ActivityRepositoryTest extends SuluTestCase + { + public function setUp(): void + { + static::purgeDatabase(); + } + } + +This purges the database before each test, that is defined in the test class. +If you only want to purge the database once before your tests run you can use +it in ``setUpBeforeClass()`` instead of ``setUp()``. + + +.. _test documentation: https://symfony.com/doc/current/testing.html +.. _KernelTestCase: https://github.com/sulu/sulu/blob/2.5/src/Sulu/Bundle/TestBundle/Testing/KernelTestCase.php +.. _SuluTestCase: https://github.com/sulu/sulu/blob/2.5/src/Sulu/Bundle/TestBundle/Testing/SuluTestCase.php +.. _DOM Crawler: https://symfony.com/doc/current/testing/dom_crawler.html diff --git a/bundles/trash.rst b/bundles/trash.rst index bd86943d..69acd4be 100644 --- a/bundles/trash.rst +++ b/bundles/trash.rst @@ -74,6 +74,12 @@ in time. } } +.. Tip:: + + If you're using the default `services.yaml configuration from Symfony`_, the example should work as is. + However, if you've created a custom ``TrashItemHandler`` in a separate bundle, be sure to tag the service with + ``sulu_trash.store_trash_item_handler`` to ensure proper functionality. + Restore an entity from a trash item ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -117,6 +123,13 @@ with the correct data. } } +.. Tip:: + + If you're using the default `services.yaml configuration from Symfony`_, the example should work as is. + However, if you've created a custom ``TrashItemHandler`` in a separate bundle, be sure to tag the service with + ``sulu_trash.restore_trash_item_handler`` to ensure proper functionality. + + (Optional) Add restore configuration for your entity ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -158,6 +171,12 @@ previous steps to implement the ``RestoreConfigurationProviderInterface`` and re } } +.. Tip:: + + If you're using the default `services.yaml configuration from Symfony`_, the example should work as is. + However, if you've created a custom ``TrashItemHandler`` with the restore functionality in a separate bundle, + be sure to tag the service also with ``sulu_trash.restore_configuration_provider`` to ensure proper functionality. + The ``RestoreConfiguration`` class allows to set the following configuration properties. All configuration properties are optional an can be set to ``null``. @@ -195,6 +214,12 @@ This extension point allows to clean up external data when a trash item is remov cannot be restored anymore. For example, this can be used to clean up associated files on the hard drive or related data in an external system. +.. Tip:: + + If you're using the default `services.yaml configuration from Symfony`_, the example should work as is. + However, if you've created a custom ``TrashItemHandler`` with the restore functionality in a separate bundle, + be sure to tag the service also with ``sulu_trash.remove_trash_item_handler`` to ensure proper functionality. + .. _TrashItem entity: https://github.com/sulu/sulu/blob/2.x/src/Sulu/Bundle/TrashBundle/Domain/Model/TrashItem.php .. _TrashManager service: https://github.com/sulu/sulu/blob/2.x/src/Sulu/Bundle/TrashBundle/Application/TrashManager/TrashManager.php .. _StoreTrashItemHandlerInterface interface: https://github.com/sulu/sulu/blob/2.x/src/Sulu/Bundle/TrashBundle/Application/TrashItemHandler/StoreTrashItemHandlerInterface.php @@ -202,3 +227,4 @@ drive or related data in an external system. .. _RemoveTrashItemHandlerInterface interface: https://github.com/sulu/sulu/blob/2.x/src/Sulu/Bundle/TrashBundle/Application/TrashItemHandler/RemoveTrashItemHandlerInterface.php .. _RestoreConfiguration object: https://github.com/sulu/sulu/blob/2.x/src/Sulu/Bundle/TrashBundle/Application/RestoreConfigurationProvider/RestoreConfiguration.php .. _RestoreConfigurationProviderInterface interface: https://github.com/sulu/sulu/blob/2.x/src/Sulu/Bundle/TrashBundle/Application/RestoreConfigurationProvider/RestoreConfigurationProviderInterface.php +.. _services.yaml configuration from Symfony: https://symfony.com/doc/6.4/service_container.html#service-container-services-load-example \ No newline at end of file diff --git a/reference/components/document-manager/using_the_document_manager.rst b/reference/components/document-manager/using_the_document_manager.rst index 03be5f39..88c4850d 100644 --- a/reference/components/document-manager/using_the_document_manager.rst +++ b/reference/components/document-manager/using_the_document_manager.rst @@ -62,6 +62,14 @@ on which subscribers you have registered. See the :doc:`subscribers` chapter for more information. +.. note:: + + Be aware that documents can only be created in the admin context, not in the website context. For CLI commands, this means you must use ``bin/adminconsole`` to execute the command. Alternatively, you can execute a command that dispatches messages via the Symfony Messenger. In this case, the consumer that consumes the dispatched message must also run in the admin context. + + .. code-block:: bash + + bin/adminconsole your:command + The Path Builder ----------------