diff --git a/app/Resources/views/admin/user.html.twig b/app/Resources/views/admin/user.html.twig
index 1e6b093f..7ef71838 100644
--- a/app/Resources/views/admin/user.html.twig
+++ b/app/Resources/views/admin/user.html.twig
@@ -1,48 +1,48 @@
{% extends 'base.html.twig' %}
{% import "macros/datatables.html.twig" as tables %}
{% import "macros/widgets.html.twig" as widgets %}
-{% import "AvanzuAdminThemeBundle:layout:macros.html.twig" as macro %}
{% block page_title %}{{ 'admin_user.title'|trans }}{% endblock %}
{% block page_subtitle %}{{ 'admin_user.subtitle'|trans }} {{ 'subtitle.amount'|trans({'%count%': entries.count}) }}{% endblock %}
+{% block javascript_imports %}{% endblock %}
{% block main %}
- {% if entries.count > 0 %}
- {{ tables.data_table_header({
- 'label.id': 'hidden-xs',
- 'label.alias': '',
- 'label.username': 'hidden-xs',
- 'label.email': 'hidden-xs hidden-sm',
- 'label.title': 'hidden-xs',
- 'label.active': '',
- 'label.roles': '',
- 'label.actions': '',
- }, null, {'plus-square': path('admin_user_create')}) }}
-
- {% for entry in entries %}
-
- | {{ entry.id }} |
- {{ widgets.username(entry) }} |
- {{ entry.username }} |
- {{ entry.email }} |
- {{ entry.title }} |
- {{ widgets.label_visible(entry.active) }} |
-
- {% for role in entry.roles %}
- {{ widgets.label_role(role) }}
- {% endfor %}
- |
-
- {{ widgets.button_group({
- 'edit': path('user_profile', {'username' : entry.username}),
- 'trash': path('user_profile_delete', {'username' : entry.username})
- }) }}
- |
-
- {% endfor %}
-
- {{ tables.data_table_footer(entries, 'admin_user_paginated') }}
- {% else %}
+ {% if entries.count == 0 %}
{{ widgets.callout('warning', 'error.no_entries_found') }}
{% endif %}
+
+ {{ tables.data_table_header({
+ 'label.id': 'hidden-xs',
+ 'label.alias': '',
+ 'label.username': 'hidden-xs',
+ 'label.email': 'hidden-xs hidden-sm',
+ 'label.title': 'hidden-xs',
+ 'label.active': '',
+ 'label.roles': '',
+ 'label.actions': '',
+ }, toolbarForm, {'plus-square': path('admin_user_create')}) }}
+
+ {% for entry in entries %}
+
+ | {{ entry.id }} |
+ {{ widgets.username(entry) }} |
+ {{ entry.username }} |
+ {{ entry.email }} |
+ {{ entry.title }} |
+ {{ widgets.label_visible(entry.active) }} |
+
+ {% for role in entry.roles %}
+ {{ widgets.label_role(role) }}
+ {% endfor %}
+ |
+
+ {{ widgets.button_group({
+ 'edit': path('user_profile', {'username' : entry.username}),
+ 'trash': path('user_profile_delete', {'username' : entry.username})
+ }) }}
+ |
+
+ {% endfor %}
+
+ {{ tables.data_table_footer(entries, 'admin_user_paginated') }}
{% endblock %}
diff --git a/app/config/services.yml b/app/config/services.yml
index 6477ba37..f53cd9cc 100644
--- a/app/config/services.yml
+++ b/app/config/services.yml
@@ -70,8 +70,8 @@ services:
# ================================================================================
# form to edit user roles
- app.admin.user_profile_roles:
- class: AppBundle\Form\UserRolesType
+ app.admin.user_role:
+ class: AppBundle\Form\Type\UserRoleType
arguments: ["%security.role_hierarchy.roles%"]
tags:
- { name: form.type }
diff --git a/composer.json b/composer.json
index 86b1b6ed..1e59c40f 100644
--- a/composer.json
+++ b/composer.json
@@ -5,7 +5,8 @@
"description": "Kimai Time Tracking reloaded",
"autoload": {
"psr-4": {
- "": "src/"
+ "": "src/",
+ "KimaiTest\\": "tests/"
},
"classmap": [
"app/AppKernel.php",
diff --git a/src/AppBundle/Controller/Admin/UserController.php b/src/AppBundle/Controller/Admin/UserController.php
index 02328af7..6f8dc0f5 100644
--- a/src/AppBundle/Controller/Admin/UserController.php
+++ b/src/AppBundle/Controller/Admin/UserController.php
@@ -13,6 +13,7 @@ namespace AppBundle\Controller\Admin;
use AppBundle\Controller\AbstractController;
use AppBundle\Entity\User;
+use AppBundle\Form\Toolbar\UserToolbarForm;
use AppBundle\Form\UserCreateType;
use AppBundle\Repository\Query\UserQuery;
use Pagerfanta\Pagerfanta;
@@ -32,23 +33,49 @@ use Symfony\Component\HttpFoundation\Request;
*/
class UserController extends AbstractController
{
+
+ /**
+ * @param Request $request
+ * @return UserQuery
+ */
+ protected function getQueryForRequest(Request $request)
+ {
+ $visibility = $request->get('visibility', UserQuery::SHOW_VISIBLE);
+ if (strlen($visibility) == 0 || (int)$visibility != $visibility) {
+ $visibility = UserQuery::SHOW_BOTH;
+ }
+ $pageSize = (int) $request->get('pageSize');
+ $userRole = $request->get('role');
+
+ $query = new UserQuery();
+ $query
+ ->setPageSize($pageSize)
+ ->setVisibility($visibility)
+ ->setRole($userRole)
+ ;
+
+ return $query ;
+ }
+
/**
* @Route("/", defaults={"page": 1}, name="admin_user")
* @Route("/page/{page}", requirements={"page": "[1-9]\d*"}, name="admin_user_paginated")
* @Method("GET")
- * @Cache(smaxage="10")
* @Security("is_granted('view_all', user)")
*/
- public function indexAction($page)
+ public function indexAction($page, Request $request)
{
- $query = new UserQuery();
- $query->setVisibility(UserQuery::SHOW_BOTH);
+ $query = $this->getQueryForRequest($request);
$query->setPage($page);
/* @var $entries Pagerfanta */
$entries = $this->getDoctrine()->getRepository(User::class)->findByQuery($query);
- return $this->render('admin/user.html.twig', ['entries' => $entries]);
+ return $this->render('admin/user.html.twig', [
+ 'entries' => $entries,
+ 'query' => $query,
+ 'toolbarForm' => $this->getToolbarForm($query)->createView(),
+ ]);
}
/**
@@ -87,6 +114,24 @@ class UserController extends AbstractController
);
}
+ /**
+ * @param UserQuery $query
+ * @return \Symfony\Component\Form\FormInterface
+ */
+ protected function getToolbarForm(UserQuery $query)
+ {
+ return $this->createForm(
+ UserToolbarForm::class,
+ $query,
+ [
+ 'action' => $this->generateUrl('admin_user_paginated', [
+ 'page' => $query->getPage(),
+ ]),
+ 'method' => 'GET',
+ ]
+ );
+ }
+
/**
* @param User $user
* @return \Symfony\Component\Form\FormInterface
diff --git a/src/TimesheetBundle/Form/Toolbar/AbstractToolbarForm.php b/src/AppBundle/Form/Toolbar/AbstractToolbarForm.php
similarity index 94%
rename from src/TimesheetBundle/Form/Toolbar/AbstractToolbarForm.php
rename to src/AppBundle/Form/Toolbar/AbstractToolbarForm.php
index 926be590..4c43c46e 100644
--- a/src/TimesheetBundle/Form/Toolbar/AbstractToolbarForm.php
+++ b/src/AppBundle/Form/Toolbar/AbstractToolbarForm.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace TimesheetBundle\Form\Toolbar;
+namespace AppBundle\Form\Toolbar;
use Symfony\Component\Form\AbstractType;
diff --git a/src/TimesheetBundle/Form/Toolbar/PagedToolbarForm.php b/src/AppBundle/Form/Toolbar/PagedToolbarForm.php
similarity index 95%
rename from src/TimesheetBundle/Form/Toolbar/PagedToolbarForm.php
rename to src/AppBundle/Form/Toolbar/PagedToolbarForm.php
index d0d60ee0..11ba8ca5 100644
--- a/src/TimesheetBundle/Form/Toolbar/PagedToolbarForm.php
+++ b/src/AppBundle/Form/Toolbar/PagedToolbarForm.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace TimesheetBundle\Form\Toolbar;
+namespace AppBundle\Form\Toolbar;
use AppBundle\Form\Type\PageSizeType;
use Symfony\Component\Form\FormBuilderInterface;
diff --git a/src/AppBundle/Form/Toolbar/UserToolbarForm.php b/src/AppBundle/Form/Toolbar/UserToolbarForm.php
new file mode 100644
index 00000000..72fea3c6
--- /dev/null
+++ b/src/AppBundle/Form/Toolbar/UserToolbarForm.php
@@ -0,0 +1,51 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace AppBundle\Form\Toolbar;
+
+use AppBundle\Form\Type\UserRoleType;
+use AppBundle\Repository\Query\UserQuery;
+use Symfony\Component\Form\FormBuilderInterface;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+
+/**
+ * Defines the form used for filtering the user.
+ *
+ * @author Kevin Papst
+ */
+class UserToolbarForm extends VisibilityToolbarForm
+{
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildForm(FormBuilderInterface $builder, array $options)
+ {
+ parent::buildForm($builder, $options);
+
+ $builder
+ ->add('role', UserRoleType::class, [
+ 'required' => false,
+ ])
+ ;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function configureOptions(OptionsResolver $resolver)
+ {
+ $resolver->setDefaults([
+ 'data_class' => UserQuery::class,
+ 'csrf_protection' => false,
+ ]);
+ }
+}
diff --git a/src/TimesheetBundle/Form/Toolbar/VisibilityToolbarForm.php b/src/AppBundle/Form/Toolbar/VisibilityToolbarForm.php
similarity index 95%
rename from src/TimesheetBundle/Form/Toolbar/VisibilityToolbarForm.php
rename to src/AppBundle/Form/Toolbar/VisibilityToolbarForm.php
index 0b69911c..2493261f 100644
--- a/src/TimesheetBundle/Form/Toolbar/VisibilityToolbarForm.php
+++ b/src/AppBundle/Form/Toolbar/VisibilityToolbarForm.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace TimesheetBundle\Form\Toolbar;
+namespace AppBundle\Form\Toolbar;
use AppBundle\Form\Type\VisibilityType;
use Symfony\Component\Form\FormBuilderInterface;
diff --git a/src/AppBundle/Form/Type/UserRoleType.php b/src/AppBundle/Form/Type/UserRoleType.php
new file mode 100644
index 00000000..4f12a02c
--- /dev/null
+++ b/src/AppBundle/Form/Type/UserRoleType.php
@@ -0,0 +1,67 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace AppBundle\Form\Type;
+
+use Symfony\Component\Form\AbstractType;
+use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+
+/**
+ * Custom form field type to select a user role.
+ *
+ * @author Kevin Papst
+ */
+class UserRoleType extends AbstractType
+{
+
+ /**
+ * @var string[]
+ */
+ protected $roles = [];
+
+ /**
+ * UserRolesType constructor.
+ * @param string[] $roles
+ */
+ public function __construct(array $roles)
+ {
+ $this->roles = $roles;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function configureOptions(OptionsResolver $resolver)
+ {
+ $roles = [];
+
+ foreach ($this->roles as $key => $value) {
+ $roles[$key] = $key;
+ foreach ($value as $value2) {
+ $roles[$value2] = $value2;
+ }
+ }
+
+ $resolver->setDefaults([
+ 'label' => 'label.roles',
+ 'choices' => $roles,
+ ]);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getParent()
+ {
+ return ChoiceType::class;
+ }
+}
diff --git a/src/AppBundle/Form/UserRolesType.php b/src/AppBundle/Form/UserRolesType.php
index a3946313..0e12bdf0 100644
--- a/src/AppBundle/Form/UserRolesType.php
+++ b/src/AppBundle/Form/UserRolesType.php
@@ -12,8 +12,8 @@
namespace AppBundle\Form;
use AppBundle\Entity\User;
+use AppBundle\Form\Type\UserRoleType;
use Symfony\Component\Form\AbstractType;
-use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
@@ -24,40 +24,16 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
*/
class UserRolesType extends AbstractType
{
- /**
- * @var string[]
- */
- protected $roles = [];
-
- /**
- * UserRolesType constructor.
- * @param string[] $roles
- */
- public function __construct(array $roles)
- {
- $this->roles = $roles;
- }
-
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
- $roles = [];
-
- foreach ($this->roles as $key => $value) {
- $roles[$key] = $key;
- foreach ($value as $value2) {
- $roles[$value2] = $value2;
- }
- }
-
$builder
// string[]
- ->add('roles', ChoiceType::class, [
+ ->add('roles', UserRoleType::class, [
'label' => 'label.roles',
'multiple' => true,
- 'choices' => $roles,
])
;
}
diff --git a/src/AppBundle/Repository/Query/BaseQuery.php b/src/AppBundle/Repository/Query/BaseQuery.php
index c68fc38e..dfb276db 100644
--- a/src/AppBundle/Repository/Query/BaseQuery.php
+++ b/src/AppBundle/Repository/Query/BaseQuery.php
@@ -67,7 +67,7 @@ class BaseQuery
*/
public function setPage($page)
{
- $this->page = $page;
+ $this->page = (int)$page;
return $this;
}
diff --git a/src/AppBundle/Repository/Query/UserQuery.php b/src/AppBundle/Repository/Query/UserQuery.php
index 0111f27a..48dd2348 100644
--- a/src/AppBundle/Repository/Query/UserQuery.php
+++ b/src/AppBundle/Repository/Query/UserQuery.php
@@ -19,4 +19,29 @@ namespace AppBundle\Repository\Query;
class UserQuery extends BaseQuery implements VisibilityInterface
{
use VisibilityTrait;
+
+ /**
+ * @var string
+ */
+ protected $role;
+
+ /**
+ * @return string
+ */
+ public function getRole()
+ {
+ return $this->role;
+ }
+
+ /**
+ * @param string $role
+ * @return UserQuery
+ */
+ public function setRole($role)
+ {
+ if (strpos($role, 'ROLE_') !== false || $role === null) {
+ $this->role = $role;
+ }
+ return $this;
+ }
}
diff --git a/src/AppBundle/Repository/Query/VisibilityInterface.php b/src/AppBundle/Repository/Query/VisibilityInterface.php
index 852713dc..a51a4bab 100644
--- a/src/AppBundle/Repository/Query/VisibilityInterface.php
+++ b/src/AppBundle/Repository/Query/VisibilityInterface.php
@@ -21,4 +21,26 @@ interface VisibilityInterface
const SHOW_VISIBLE = 1;
const SHOW_HIDDEN = 0;
const SHOW_BOTH = 2;
+
+ /**
+ * @return $this
+ */
+ public function getVisibility();
+
+ /**
+ * @param int $visibility
+ * @return $this
+ */
+ public function setVisibility($visibility);
+
+ /**
+ * @return bool
+ */
+ public function isExclusiveVisibility();
+
+ /**
+ * @param bool $exclusiveVisibility
+ * @return $this
+ */
+ public function setExclusiveVisibility($exclusiveVisibility);
}
diff --git a/src/AppBundle/Repository/Query/VisibilityTrait.php b/src/AppBundle/Repository/Query/VisibilityTrait.php
index c1f1670b..6baf3d64 100644
--- a/src/AppBundle/Repository/Query/VisibilityTrait.php
+++ b/src/AppBundle/Repository/Query/VisibilityTrait.php
@@ -41,7 +41,7 @@ trait VisibilityTrait
*/
public function setVisibility($visibility)
{
- if (in_array($visibility, [self::SHOW_BOTH, self::SHOW_VISIBLE, self::SHOW_HIDDEN])) {
+ if (in_array($visibility, [self::SHOW_BOTH, self::SHOW_VISIBLE, self::SHOW_HIDDEN], true)) {
$this->visibility = $visibility;
}
return $this;
diff --git a/src/AppBundle/Repository/UserRepository.php b/src/AppBundle/Repository/UserRepository.php
index e7f44f8f..f1406699 100644
--- a/src/AppBundle/Repository/UserRepository.php
+++ b/src/AppBundle/Repository/UserRepository.php
@@ -57,10 +57,14 @@ class UserRepository extends AbstractRepository
->from('AppBundle:User', 'u')
->orderBy('u.' . $query->getOrderBy(), $query->getOrder());
- if ($query->getVisibility() === UserQuery::SHOW_VISIBLE) {
- $qb->andWhere('u.visible = 1');
- } elseif ($query->getVisibility() === UserQuery::SHOW_HIDDEN) {
- $qb->andWhere('u.visible = 0');
+ if ($query->getVisibility() == UserQuery::SHOW_VISIBLE) {
+ $qb->andWhere('u.active = 1');
+ } elseif ($query->getVisibility() == UserQuery::SHOW_HIDDEN) {
+ $qb->andWhere('u.active = 0');
+ }
+
+ if ($query->getRole() !== null) {
+ $qb->andWhere('u.roles LIKE :role')->setParameter('role', '%' . $query->getRole() . '%');
}
return $this->getPager($qb->getQuery(), $query->getPage(), $query->getPageSize());
diff --git a/src/TimesheetBundle/Form/Toolbar/CustomerToolbarForm.php b/src/TimesheetBundle/Form/Toolbar/CustomerToolbarForm.php
index fa119cea..5857ee54 100644
--- a/src/TimesheetBundle/Form/Toolbar/CustomerToolbarForm.php
+++ b/src/TimesheetBundle/Form/Toolbar/CustomerToolbarForm.php
@@ -11,6 +11,7 @@
namespace TimesheetBundle\Form\Toolbar;
+use AppBundle\Form\Toolbar\VisibilityToolbarForm;
use Symfony\Component\OptionsResolver\OptionsResolver;
use TimesheetBundle\Repository\Query\CustomerQuery;
diff --git a/src/TimesheetBundle/Form/Toolbar/ProjectToolbarForm.php b/src/TimesheetBundle/Form/Toolbar/ProjectToolbarForm.php
index 9090ea4c..e0755608 100644
--- a/src/TimesheetBundle/Form/Toolbar/ProjectToolbarForm.php
+++ b/src/TimesheetBundle/Form/Toolbar/ProjectToolbarForm.php
@@ -11,6 +11,7 @@
namespace TimesheetBundle\Form\Toolbar;
+use AppBundle\Form\Toolbar\VisibilityToolbarForm;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use TimesheetBundle\Form\Type\CustomerType;
diff --git a/src/TimesheetBundle/Repository/Query/TimesheetQuery.php b/src/TimesheetBundle/Repository/Query/TimesheetQuery.php
index 0789d365..71546a54 100644
--- a/src/TimesheetBundle/Repository/Query/TimesheetQuery.php
+++ b/src/TimesheetBundle/Repository/Query/TimesheetQuery.php
@@ -153,7 +153,7 @@ class TimesheetQuery extends BaseQuery
*/
public function setState($state)
{
- if (in_array($state, [self::STATE_ALL, self::STATE_RUNNING, self::STATE_STOPPED])) {
+ if (in_array($state, [self::STATE_ALL, self::STATE_RUNNING, self::STATE_STOPPED], true)) {
$this->state = $state;
}
return $this;
diff --git a/tests/AppBundle/Repository/Query/BaseQueryTest.php b/tests/AppBundle/Repository/Query/BaseQueryTest.php
new file mode 100644
index 00000000..93846fe8
--- /dev/null
+++ b/tests/AppBundle/Repository/Query/BaseQueryTest.php
@@ -0,0 +1,99 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace KimaiTest\AppBundle\Repository\Query;
+
+use AppBundle\Entity\User;
+use AppBundle\Repository\Query\BaseQuery;
+use \PHPUnit\Framework\TestCase;
+
+/**
+ * @covers \AppBundle\Repository\Query\BaseQuery
+ * @author Kevin Papst
+ */
+class BaseQueryTest extends TestCase
+{
+
+ public function testQuery()
+ {
+ $this->assertBaseQuery(new BaseQuery());
+ }
+
+ protected function assertBaseQuery(BaseQuery $sut)
+ {
+ $this->assertResultType($sut);
+ $this->assertHiddenEntity($sut);
+ $this->assertPage($sut);
+ $this->assertPageSize($sut);
+ $this->assertOrderBy($sut);
+ $this->assertOrder($sut);
+ }
+
+ protected function assertResultType(BaseQuery $sut)
+ {
+ $this->assertEquals(BaseQuery::RESULT_TYPE_PAGER, $sut->getResultType());
+
+ $sut->setResultType('foo-bar');
+ $this->assertEquals(BaseQuery::RESULT_TYPE_PAGER, $sut->getResultType());
+
+ $sut->setResultType(BaseQuery::RESULT_TYPE_QUERYBUILDER);
+ $this->assertEquals(BaseQuery::RESULT_TYPE_QUERYBUILDER, $sut->getResultType());
+ }
+
+ protected function assertHiddenEntity(BaseQuery $sut)
+ {
+ $this->assertNull($sut->getHiddenEntity());
+
+ $actual = new User();
+ $actual->setUsername('foo-bar');
+
+ $sut->setHiddenEntity($actual);
+ $this->assertEquals($actual, $sut->getHiddenEntity());
+ }
+
+ protected function assertPage(BaseQuery $sut)
+ {
+ $this->assertEquals(BaseQuery::DEFAULT_PAGE, $sut->getPage());
+
+ $sut->setPage(42);
+ $this->assertEquals(42, $sut->getPage());
+ }
+
+ protected function assertPageSize(BaseQuery $sut)
+ {
+ $this->assertEquals(BaseQuery::DEFAULT_PAGESIZE, $sut->getPageSize());
+
+ $sut->setPageSize(100);
+ $this->assertEquals(100, $sut->getPageSize());
+ }
+
+ protected function assertOrderBy(BaseQuery $sut, $column = 'id')
+ {
+ $this->assertEquals($column, $sut->getOrderBy());
+
+ $sut->setOrderBy('foo');
+ $this->assertEquals('foo', $sut->getOrderBy());
+ }
+
+ protected function assertOrder(BaseQuery $sut, $order = BaseQuery::ORDER_ASC)
+ {
+ $this->assertEquals($order, $sut->getOrder());
+
+ $sut->setOrder('foo');
+ $this->assertEquals($order, $sut->getOrder());
+
+ $sut->setOrder(BaseQuery::ORDER_ASC);
+ $this->assertEquals(BaseQuery::ORDER_ASC, $sut->getOrder());
+
+ $sut->setOrder(BaseQuery::ORDER_DESC);
+ $this->assertEquals(BaseQuery::ORDER_DESC, $sut->getOrder());
+ }
+}
diff --git a/tests/AppBundle/Repository/Query/UserQueryTest.php b/tests/AppBundle/Repository/Query/UserQueryTest.php
new file mode 100644
index 00000000..fc5bb2c9
--- /dev/null
+++ b/tests/AppBundle/Repository/Query/UserQueryTest.php
@@ -0,0 +1,43 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace KimaiTest\AppBundle\Repository\Query;
+
+use AppBundle\Repository\Query\UserQuery;
+use AppBundle\Repository\Query\VisibilityInterface;
+use AppBundle\Repository\Query\VisibilityTrait;
+
+/**
+ * @covers \AppBundle\Repository\Query\UserQuery
+ * @author Kevin Papst
+ */
+class UserQueryTest extends BaseQueryTest
+{
+ public function testQuery()
+ {
+ $sut = new UserQuery();
+ $this->assertBaseQuery($sut);
+ $this->assertInstanceOf(VisibilityInterface::class, $sut);
+ $this->assertArrayHasKey(VisibilityTrait::class, class_uses($sut));
+ $this->assertRole($sut);
+ }
+
+ protected function assertRole(UserQuery $sut)
+ {
+ $this->assertNull($sut->getRole());
+
+ $sut->setRole('foo-bar');
+ $this->assertNull($sut->getRole());
+
+ $sut->setRole('ROLE_USER');
+ $this->assertEquals('ROLE_USER', $sut->getRole());
+ }
+}
diff --git a/tests/AppBundle/Repository/Query/VisibilityTraitImplementation.php b/tests/AppBundle/Repository/Query/VisibilityTraitImplementation.php
new file mode 100644
index 00000000..2c2be7c0
--- /dev/null
+++ b/tests/AppBundle/Repository/Query/VisibilityTraitImplementation.php
@@ -0,0 +1,23 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace KimaiTest\AppBundle\Repository\Query;
+
+use AppBundle\Repository\Query\VisibilityInterface;
+use AppBundle\Repository\Query\VisibilityTrait;
+
+/**
+ * @author Kevin Papst
+ */
+class VisibilityTraitImplementation implements VisibilityInterface
+{
+ use VisibilityTrait;
+}
diff --git a/tests/AppBundle/Repository/Query/VisibilityTraitTest.php b/tests/AppBundle/Repository/Query/VisibilityTraitTest.php
new file mode 100644
index 00000000..fb36ebdc
--- /dev/null
+++ b/tests/AppBundle/Repository/Query/VisibilityTraitTest.php
@@ -0,0 +1,46 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace KimaiTest\AppBundle\Repository\Query;
+
+use AppBundle\Repository\Query\VisibilityInterface;
+use AppBundle\Repository\Query\VisibilityTrait;
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @covers \AppBundle\Repository\Query\VisibilityTrait
+ * @author Kevin Papst
+ */
+class VisibilityTraitTest extends TestCase
+{
+ public function testVisibilityTrait()
+ {
+ $sut = new VisibilityTraitImplementation();
+
+ $this->assertFalse($sut->isExclusiveVisibility());
+ $this->assertEquals(VisibilityTraitImplementation::SHOW_VISIBLE, $sut->getVisibility());
+
+ $sut->setExclusiveVisibility(true);
+ $this->assertTrue($sut->isExclusiveVisibility());
+
+ $sut->setVisibility('foo-bar');
+ $this->assertEquals(VisibilityTraitImplementation::SHOW_VISIBLE, $sut->getVisibility());
+
+ $sut->setVisibility(VisibilityTraitImplementation::SHOW_BOTH);
+ $this->assertEquals(VisibilityTraitImplementation::SHOW_BOTH, $sut->getVisibility());
+
+ $sut->setVisibility(VisibilityTraitImplementation::SHOW_HIDDEN);
+ $this->assertEquals(VisibilityTraitImplementation::SHOW_HIDDEN, $sut->getVisibility());
+
+ $sut->setVisibility(VisibilityTraitImplementation::SHOW_VISIBLE);
+ $this->assertEquals(VisibilityTraitImplementation::SHOW_VISIBLE, $sut->getVisibility());
+ }
+}
diff --git a/tests/TimesheetBundle/Repository/Query/ActivityQueryTest.php b/tests/TimesheetBundle/Repository/Query/ActivityQueryTest.php
new file mode 100644
index 00000000..c873b5be
--- /dev/null
+++ b/tests/TimesheetBundle/Repository/Query/ActivityQueryTest.php
@@ -0,0 +1,50 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace KimaiTest\TimesheetBundle\Repository\Query;
+
+use AppBundle\Repository\Query\VisibilityInterface;
+use AppBundle\Repository\Query\VisibilityTrait;
+use KimaiTest\AppBundle\Repository\Query\BaseQueryTest;
+use TimesheetBundle\Entity\Customer;
+use TimesheetBundle\Entity\Project;
+use TimesheetBundle\Repository\Query\ActivityQuery;
+
+/**
+ * @covers \TimesheetBundle\Repository\Query\ActivityQuery
+ * @author Kevin Papst
+ */
+class ActivityQueryTest extends BaseQueryTest
+{
+ public function testQuery()
+ {
+ $sut = new ActivityQuery();
+
+ $this->assertBaseQuery($sut);
+ $this->assertInstanceOf(VisibilityInterface::class, $sut);
+ $this->assertArrayHasKey(VisibilityTrait::class, class_uses($sut));
+
+ $this->assertNull($sut->getCustomer());
+ $this->assertNull($sut->getProject());
+
+ $expected = new Customer();
+ $expected->setName('foo-bar');
+ $sut->setCustomer($expected);
+
+ $this->assertEquals($expected, $sut->getCustomer());
+
+ $expected = new Project();
+ $expected->setName('foo-bar');
+ $sut->setProject($expected);
+
+ $this->assertEquals($expected, $sut->getProject());
+ }
+}
diff --git a/tests/TimesheetBundle/Repository/Query/CustomerQueryTest.php b/tests/TimesheetBundle/Repository/Query/CustomerQueryTest.php
new file mode 100644
index 00000000..797968de
--- /dev/null
+++ b/tests/TimesheetBundle/Repository/Query/CustomerQueryTest.php
@@ -0,0 +1,33 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace KimaiTest\TimesheetBundle\Repository\Query;
+
+use AppBundle\Repository\Query\VisibilityInterface;
+use AppBundle\Repository\Query\VisibilityTrait;
+use KimaiTest\AppBundle\Repository\Query\BaseQueryTest;
+use TimesheetBundle\Repository\Query\CustomerQuery;
+
+/**
+ * @covers \TimesheetBundle\Repository\Query\CustomerQuery
+ * @author Kevin Papst
+ */
+class CustomerQueryTest extends BaseQueryTest
+{
+ public function testQuery()
+ {
+ $sut = new CustomerQuery();
+
+ $this->assertBaseQuery($sut);
+ $this->assertInstanceOf(VisibilityInterface::class, $sut);
+ $this->assertArrayHasKey(VisibilityTrait::class, class_uses($sut));
+ }
+}
diff --git a/tests/TimesheetBundle/Repository/Query/ProjectQueryTest.php b/tests/TimesheetBundle/Repository/Query/ProjectQueryTest.php
new file mode 100644
index 00000000..6dc8da0e
--- /dev/null
+++ b/tests/TimesheetBundle/Repository/Query/ProjectQueryTest.php
@@ -0,0 +1,42 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace KimaiTest\TimesheetBundle\Repository\Query;
+
+use AppBundle\Repository\Query\VisibilityInterface;
+use AppBundle\Repository\Query\VisibilityTrait;
+use KimaiTest\AppBundle\Repository\Query\BaseQueryTest;
+use TimesheetBundle\Entity\Customer;
+use TimesheetBundle\Repository\Query\ProjectQuery;
+
+/**
+ * @covers \TimesheetBundle\Repository\Query\ProjectQuery
+ * @author Kevin Papst
+ */
+class ProjectQueryTest extends BaseQueryTest
+{
+ public function testQuery()
+ {
+ $sut = new ProjectQuery();
+
+ $this->assertBaseQuery($sut);
+ $this->assertInstanceOf(VisibilityInterface::class, $sut);
+ $this->assertArrayHasKey(VisibilityTrait::class, class_uses($sut));
+
+ $this->assertNull($sut->getCustomer());
+
+ $expected = new Customer();
+ $expected->setName('foo-bar');
+ $sut->setCustomer($expected);
+
+ $this->assertEquals($expected, $sut->getCustomer());
+ }
+}
diff --git a/tests/TimesheetBundle/Repository/Query/TimesheetQueryTest.php b/tests/TimesheetBundle/Repository/Query/TimesheetQueryTest.php
index 2ae8825f..1870aa10 100644
--- a/tests/TimesheetBundle/Repository/Query/TimesheetQueryTest.php
+++ b/tests/TimesheetBundle/Repository/Query/TimesheetQueryTest.php
@@ -11,32 +11,91 @@
namespace KimaiTest\TimesheetBundle\Repository\Query;
-use AppBundle\Repository\Query\BaseQuery;
-use \PHPUnit\Framework\TestCase;
+use AppBundle\Entity\User;
+use KimaiTest\AppBundle\Repository\Query\BaseQueryTest;
+use TimesheetBundle\Entity\Activity;
+use TimesheetBundle\Entity\Customer;
+use TimesheetBundle\Entity\Project;
use TimesheetBundle\Repository\Query\TimesheetQuery;
/**
* @covers \TimesheetBundle\Repository\Query\TimesheetQuery
* @author Kevin Papst
*/
-class TimesheetQueryTest extends TestCase
+class TimesheetQueryTest extends BaseQueryTest
{
-
- public function testSetOrder()
+ public function testQuery()
{
- $class = new \ReflectionClass(new BaseQuery());
- $this->assertTrue($class->hasProperty('order'));
- $this->assertTrue($class->hasProperty('orderBy'));
-
$sut = new TimesheetQuery();
- $this->assertEquals(TimesheetQuery::ORDER_DESC, $sut->getOrder());
- $this->assertEquals('begin', $sut->getOrderBy());
+ $this->assertResultType($sut);
+ $this->assertHiddenEntity($sut);
+ $this->assertPage($sut);
+ $this->assertPageSize($sut);
+ $this->assertOrderBy($sut, 'begin');
+ $this->assertOrder($sut, TimesheetQuery::ORDER_DESC);
- $sut->setOrder(TimesheetQuery::ORDER_ASC);
- $sut->setOrderBy('id');
+ $this->assertUser($sut);
+ $this->assertCustomer($sut);
+ $this->assertProject($sut);
+ $this->assertActivity($sut);
+ $this->assertState($sut);
+ }
- $this->assertEquals(TimesheetQuery::ORDER_ASC, $sut->getOrder());
- $this->assertEquals('id', $sut->getOrderBy());
+ protected function assertUser(TimesheetQuery $sut)
+ {
+ $this->assertNull($sut->getUser());
+
+ $expected = new User();
+ $expected->setUsername('foo-bar');
+ $sut->setUser($expected);
+ $this->assertEquals($expected, $sut->getUser());
+ }
+
+ protected function assertCustomer(TimesheetQuery $sut)
+ {
+ $this->assertNull($sut->getCustomer());
+
+ $expected = new Customer();
+ $expected->setName('foo-bar');
+ $sut->setCustomer($expected);
+ $this->assertEquals($expected, $sut->getCustomer());
+ }
+
+ protected function assertProject(TimesheetQuery $sut)
+ {
+ $this->assertNull($sut->getProject());
+
+ $expected = new Project();
+ $expected->setName('foo-bar');
+ $sut->setProject($expected);
+ $this->assertEquals($expected, $sut->getProject());
+ }
+
+ protected function assertActivity(TimesheetQuery $sut)
+ {
+ $this->assertNull($sut->getActivity());
+
+ $expected = new Activity();
+ $expected->setName('foo-bar');
+ $sut->setActivity($expected);
+ $this->assertEquals($expected, $sut->getActivity());
+ }
+
+ protected function assertState(TimesheetQuery $sut)
+ {
+ $this->assertEquals(TimesheetQuery::STATE_ALL, $sut->getState());
+
+ $sut->setState('foo-bar');
+ $this->assertEquals(TimesheetQuery::STATE_ALL, $sut->getState());
+
+ $sut->setState(TimesheetQuery::STATE_STOPPED);
+ $this->assertEquals(TimesheetQuery::STATE_STOPPED, $sut->getState());
+
+ $sut->setState(TimesheetQuery::STATE_RUNNING);
+ $this->assertEquals(TimesheetQuery::STATE_RUNNING, $sut->getState());
+
+ $sut->setState(TimesheetQuery::STATE_ALL);
+ $this->assertEquals(TimesheetQuery::STATE_ALL, $sut->getState());
}
}