added API functions to save meta fields (#1063)

This commit is contained in:
Kevin Papst
2019-08-26 14:30:39 +02:00
committed by GitHub
parent ceeec7b8a6
commit 15673555a2
14 changed files with 624 additions and 68 deletions

View File

@@ -12,6 +12,7 @@ declare(strict_types=1);
namespace App\API;
use App\Entity\Activity;
use App\Event\ActivityMetaDefinitionEvent;
use App\Form\API\ActivityApiEditForm;
use App\Repository\ActivityRepository;
use App\Repository\Query\ActivityQuery;
@@ -22,6 +23,7 @@ use FOS\RestBundle\View\View;
use FOS\RestBundle\View\ViewHandlerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Swagger\Annotations as SWG;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
@@ -36,16 +38,21 @@ class ActivityController extends BaseApiController
/**
* @var ActivityRepository
*/
protected $repository;
private $repository;
/**
* @var ViewHandlerInterface
*/
protected $viewHandler;
private $viewHandler;
/**
* @var EventDispatcherInterface
*/
private $dispatcher;
public function __construct(ViewHandlerInterface $viewHandler, ActivityRepository $repository)
public function __construct(ViewHandlerInterface $viewHandler, ActivityRepository $repository, EventDispatcherInterface $dispatcher)
{
$this->viewHandler = $viewHandler;
$this->repository = $repository;
$this->dispatcher = $dispatcher;
}
/**
@@ -169,14 +176,15 @@ class ActivityController extends BaseApiController
$activity = new Activity();
$event = new ActivityMetaDefinitionEvent($activity);
$this->dispatcher->dispatch($event, ActivityMetaDefinitionEvent::class);
$form = $this->createForm(ActivityApiEditForm::class, $activity);
$form->submit($request->request->all());
if ($form->isValid()) {
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($activity);
$entityManager->flush();
$this->repository->saveActivity($activity);
$view = new View($activity, 200);
$view->getContext()->setGroups(['Default', 'Entity', 'Activity']);
@@ -218,6 +226,8 @@ class ActivityController extends BaseApiController
* @param Request $request
* @param string $id
* @return Response
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function patchAction(Request $request, string $id)
{
@@ -231,6 +241,9 @@ class ActivityController extends BaseApiController
throw new AccessDeniedHttpException('User cannot update activity');
}
$event = new ActivityMetaDefinitionEvent($activity);
$this->dispatcher->dispatch($event, ActivityMetaDefinitionEvent::class);
$form = $this->createForm(ActivityApiEditForm::class, $activity);
$form->setData($activity);
@@ -243,13 +256,67 @@ class ActivityController extends BaseApiController
return $this->viewHandler->handle($view);
}
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($activity);
$entityManager->flush();
$this->repository->saveActivity($activity);
$view = new View($activity, Response::HTTP_OK);
$view->getContext()->setGroups(['Default', 'Entity', 'Activity']);
return $this->viewHandler->handle($view);
}
/**
* Sets the value of a meta-field for an existing activity.
*
* @SWG\Response(
* response=200,
* description="Sets the value of an existing/configured meta-field. You cannot create unknown meta-fields, if the given name is not a configured meta-field, this will return an exception.",
* @SWG\Schema(ref="#/definitions/ActivityEntity")
* )
* @SWG\Parameter(
* name="id",
* in="path",
* type="integer",
* description="Activity record ID to set the meta-field value for",
* required=true,
* )
* @Rest\RequestParam(name="name", strict=true, nullable=false, description="The meta-field name")
* @Rest\RequestParam(name="value", strict=true, nullable=false, description="The meta-field value")
*
* @param int $id
* @param ParamFetcherInterface $paramFetcher
* @return Response
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function metaAction($id, ParamFetcherInterface $paramFetcher)
{
$activity = $this->repository->find($id);
if (null === $activity) {
throw new NotFoundException();
}
if (!$this->isGranted('edit', $activity)) {
throw new AccessDeniedHttpException('You are not allowed to update this activity');
}
$event = new ActivityMetaDefinitionEvent($activity);
$this->dispatcher->dispatch($event, ActivityMetaDefinitionEvent::class);
$name = $paramFetcher->get('name');
$value = $paramFetcher->get('value');
if (null === ($meta = $activity->getMetaField($name))) {
throw new \InvalidArgumentException('Unknown meta-field requested');
}
$meta->setValue($value);
$this->repository->saveActivity($activity);
$view = new View($activity, 200);
$view->getContext()->setGroups(['Default', 'Entity', 'Project']);
return $this->viewHandler->handle($view);
}
}

View File

@@ -12,6 +12,7 @@ declare(strict_types=1);
namespace App\API;
use App\Entity\Customer;
use App\Event\CustomerMetaDefinitionEvent;
use App\Form\API\CustomerApiEditForm;
use App\Repository\CustomerRepository;
use App\Repository\Query\CustomerQuery;
@@ -22,6 +23,7 @@ use FOS\RestBundle\View\View;
use FOS\RestBundle\View\ViewHandlerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Swagger\Annotations as SWG;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
@@ -36,16 +38,21 @@ class CustomerController extends BaseApiController
/**
* @var CustomerRepository
*/
protected $repository;
private $repository;
/**
* @var ViewHandlerInterface
*/
protected $viewHandler;
private $viewHandler;
/**
* @var EventDispatcherInterface
*/
private $dispatcher;
public function __construct(ViewHandlerInterface $viewHandler, CustomerRepository $repository)
public function __construct(ViewHandlerInterface $viewHandler, CustomerRepository $repository, EventDispatcherInterface $dispatcher)
{
$this->viewHandler = $viewHandler;
$this->repository = $repository;
$this->dispatcher = $dispatcher;
}
/**
@@ -148,14 +155,15 @@ class CustomerController extends BaseApiController
$customer = new Customer();
$event = new CustomerMetaDefinitionEvent($customer);
$this->dispatcher->dispatch($event, CustomerMetaDefinitionEvent::class);
$form = $this->createForm(CustomerApiEditForm::class, $customer);
$form->submit($request->request->all());
if ($form->isValid()) {
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($customer);
$entityManager->flush();
$this->repository->saveCustomer($customer);
$view = new View($customer, 200);
$view->getContext()->setGroups(['Default', 'Entity', 'Customer']);
@@ -197,6 +205,8 @@ class CustomerController extends BaseApiController
* @param Request $request
* @param string $id
* @return Response
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function patchAction(Request $request, string $id)
{
@@ -210,6 +220,9 @@ class CustomerController extends BaseApiController
throw new AccessDeniedHttpException('User cannot update customer');
}
$event = new CustomerMetaDefinitionEvent($customer);
$this->dispatcher->dispatch($event, CustomerMetaDefinitionEvent::class);
$form = $this->createForm(CustomerApiEditForm::class, $customer);
$form->setData($customer);
@@ -222,13 +235,67 @@ class CustomerController extends BaseApiController
return $this->viewHandler->handle($view);
}
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($customer);
$entityManager->flush();
$this->repository->saveCustomer($customer);
$view = new View($customer, Response::HTTP_OK);
$view->getContext()->setGroups(['Default', 'Entity', 'Customer']);
return $this->viewHandler->handle($view);
}
/**
* Sets the value of a meta-field for an existing customer.
*
* @SWG\Response(
* response=200,
* description="Sets the value of an existing/configured meta-field. You cannot create unknown meta-fields, if the given name is not a configured meta-field, this will return an exception.",
* @SWG\Schema(ref="#/definitions/CustomerEntity")
* )
* @SWG\Parameter(
* name="id",
* in="path",
* type="integer",
* description="Customer record ID to set the meta-field value for",
* required=true,
* )
* @Rest\RequestParam(name="name", strict=true, nullable=false, description="The meta-field name")
* @Rest\RequestParam(name="value", strict=true, nullable=false, description="The meta-field value")
*
* @param int $id
* @param ParamFetcherInterface $paramFetcher
* @return Response
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function metaAction($id, ParamFetcherInterface $paramFetcher)
{
$customer = $this->repository->find($id);
if (null === $customer) {
throw new NotFoundException();
}
if (!$this->isGranted('edit', $customer)) {
throw new AccessDeniedHttpException('You are not allowed to update this customer');
}
$event = new CustomerMetaDefinitionEvent($customer);
$this->dispatcher->dispatch($event, CustomerMetaDefinitionEvent::class);
$name = $paramFetcher->get('name');
$value = $paramFetcher->get('value');
if (null === ($meta = $customer->getMetaField($name))) {
throw new \InvalidArgumentException('Unknown meta-field requested');
}
$meta->setValue($value);
$this->repository->saveCustomer($customer);
$view = new View($customer, 200);
$view->getContext()->setGroups(['Default', 'Entity', 'Customer']);
return $this->viewHandler->handle($view);
}
}

View File

@@ -12,6 +12,7 @@ declare(strict_types=1);
namespace App\API;
use App\Entity\Project;
use App\Event\ProjectMetaDefinitionEvent;
use App\Form\API\ProjectApiEditForm;
use App\Repository\ProjectRepository;
use App\Repository\Query\ProjectQuery;
@@ -22,6 +23,7 @@ use FOS\RestBundle\View\View;
use FOS\RestBundle\View\ViewHandlerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Swagger\Annotations as SWG;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
@@ -36,16 +38,21 @@ class ProjectController extends BaseApiController
/**
* @var ProjectRepository
*/
protected $repository;
private $repository;
/**
* @var ViewHandlerInterface
*/
protected $viewHandler;
private $viewHandler;
/**
* @var EventDispatcherInterface
*/
private $dispatcher;
public function __construct(ViewHandlerInterface $viewHandler, ProjectRepository $repository)
public function __construct(ViewHandlerInterface $viewHandler, ProjectRepository $repository, EventDispatcherInterface $dispatcher)
{
$this->viewHandler = $viewHandler;
$this->repository = $repository;
$this->dispatcher = $dispatcher;
}
/**
@@ -154,14 +161,15 @@ class ProjectController extends BaseApiController
$project = new Project();
$event = new ProjectMetaDefinitionEvent($project);
$this->dispatcher->dispatch($event, ProjectMetaDefinitionEvent::class);
$form = $this->createForm(ProjectApiEditForm::class, $project);
$form->submit($request->request->all());
if ($form->isValid()) {
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($project);
$entityManager->flush();
$this->repository->saveProject($project);
$view = new View($project, 200);
$view->getContext()->setGroups(['Default', 'Entity', 'Project']);
@@ -203,6 +211,8 @@ class ProjectController extends BaseApiController
* @param Request $request
* @param string $id
* @return Response
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function patchAction(Request $request, string $id)
{
@@ -216,6 +226,9 @@ class ProjectController extends BaseApiController
throw new AccessDeniedHttpException('User cannot update project');
}
$event = new ProjectMetaDefinitionEvent($project);
$this->dispatcher->dispatch($event, ProjectMetaDefinitionEvent::class);
$form = $this->createForm(ProjectApiEditForm::class, $project);
$form->setData($project);
@@ -228,13 +241,67 @@ class ProjectController extends BaseApiController
return $this->viewHandler->handle($view);
}
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($project);
$entityManager->flush();
$this->repository->saveProject($project);
$view = new View($project, Response::HTTP_OK);
$view->getContext()->setGroups(['Default', 'Entity', 'Project']);
return $this->viewHandler->handle($view);
}
/**
* Sets the value of a meta-field for an existing project.
*
* @SWG\Response(
* response=200,
* description="Sets the value of an existing/configured meta-field. You cannot create unknown meta-fields, if the given name is not a configured meta-field, this will return an exception.",
* @SWG\Schema(ref="#/definitions/ProjectEntity")
* )
* @SWG\Parameter(
* name="id",
* in="path",
* type="integer",
* description="Project record ID to set the meta-field value for",
* required=true,
* )
* @Rest\RequestParam(name="name", strict=true, nullable=false, description="The meta-field name")
* @Rest\RequestParam(name="value", strict=true, nullable=false, description="The meta-field value")
*
* @param int $id
* @param ParamFetcherInterface $paramFetcher
* @return Response
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function metaAction($id, ParamFetcherInterface $paramFetcher)
{
$project = $this->repository->find($id);
if (null === $project) {
throw new NotFoundException();
}
if (!$this->isGranted('edit', $project)) {
throw new AccessDeniedHttpException('You are not allowed to update this project');
}
$event = new ProjectMetaDefinitionEvent($project);
$this->dispatcher->dispatch($event, ProjectMetaDefinitionEvent::class);
$name = $paramFetcher->get('name');
$value = $paramFetcher->get('value');
if (null === ($meta = $project->getMetaField($name))) {
throw new \InvalidArgumentException('Unknown meta-field requested');
}
$meta->setValue($value);
$this->repository->saveProject($project);
$view = new View($project, 200);
$view->getContext()->setGroups(['Default', 'Entity', 'Project']);
return $this->viewHandler->handle($view);
}
}

View File

@@ -14,6 +14,7 @@ namespace App\API;
use App\Configuration\TimesheetConfiguration;
use App\Entity\Timesheet;
use App\Entity\User;
use App\Event\TimesheetMetaDefinitionEvent;
use App\Form\API\TimesheetApiEditForm;
use App\Repository\Query\TimesheetQuery;
use App\Repository\TagRepository;
@@ -30,6 +31,7 @@ use FOS\RestBundle\View\ViewHandlerInterface;
use Pagerfanta\Pagerfanta;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Swagger\Annotations as SWG;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
@@ -47,27 +49,31 @@ class TimesheetController extends BaseApiController
/**
* @var TimesheetRepository
*/
protected $repository;
private $repository;
/**
* @var ViewHandlerInterface
*/
protected $viewHandler;
private $viewHandler;
/**
* @var TimesheetConfiguration
*/
protected $configuration;
private $configuration;
/**
* @var UserDateTimeFactory
*/
protected $dateTime;
private $dateTime;
/**
* @var TagRepository
*/
protected $tagRepository;
private $tagRepository;
/**
* @var TrackingModeService
*/
protected $trackingModeService;
private $trackingModeService;
/**
* @var EventDispatcherInterface
*/
private $dispatcher;
public function __construct(
ViewHandlerInterface $viewHandler,
@@ -75,7 +81,8 @@ class TimesheetController extends BaseApiController
UserDateTimeFactory $dateTime,
TimesheetConfiguration $configuration,
TagRepository $tagRepository,
TrackingModeService $trackingModeService
TrackingModeService $trackingModeService,
EventDispatcherInterface $dispatcher
) {
$this->viewHandler = $viewHandler;
$this->repository = $repository;
@@ -83,6 +90,7 @@ class TimesheetController extends BaseApiController
$this->dateTime = $dateTime;
$this->tagRepository = $tagRepository;
$this->trackingModeService = $trackingModeService;
$this->dispatcher = $dispatcher;
}
protected function getTrackingMode(): TrackingModeInterface
@@ -282,6 +290,9 @@ class TimesheetController extends BaseApiController
$timesheet->setUser($this->getUser());
$timesheet->setBegin($this->dateTime->createDateTime());
$event = new TimesheetMetaDefinitionEvent($timesheet);
$this->dispatcher->dispatch($event, TimesheetMetaDefinitionEvent::class);
$mode = $this->getTrackingMode();
$form = $this->createForm(TimesheetApiEditForm::class, $timesheet, [
@@ -305,9 +316,7 @@ class TimesheetController extends BaseApiController
);
}
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($timesheet);
$entityManager->flush();
$this->repository->save($timesheet);
$view = new View($timesheet, 200);
$view->getContext()->setGroups(['Default', 'Entity', 'Timesheet']);
@@ -362,6 +371,9 @@ class TimesheetController extends BaseApiController
throw new AccessDeniedHttpException('You are not allowed to update this timesheet');
}
$event = new TimesheetMetaDefinitionEvent($timesheet);
$this->dispatcher->dispatch($event, TimesheetMetaDefinitionEvent::class);
$mode = $this->getTrackingMode();
$form = $this->createForm(TimesheetApiEditForm::class, $timesheet, [
@@ -382,9 +394,7 @@ class TimesheetController extends BaseApiController
return $this->viewHandler->handle($view);
}
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($timesheet);
$entityManager->flush();
$this->repository->save($timesheet);
$view = new View($timesheet, Response::HTTP_OK);
$view->getContext()->setGroups(['Default', 'Entity', 'Timesheet']);
@@ -588,8 +598,8 @@ class TimesheetController extends BaseApiController
/** @var User $user */
$user = $this->getUser();
$entry = new Timesheet();
$entry
$copyTimesheet = new Timesheet();
$copyTimesheet
->setBegin($this->dateTime->createDateTime())
->setUser($user)
->setActivity($timesheet->getActivity())
@@ -598,29 +608,29 @@ class TimesheetController extends BaseApiController
if (null !== ($copy = $paramFetcher->get('copy'))) {
if (in_array($copy, ['rates', 'all'])) {
$entry->setHourlyRate($timesheet->getHourlyRate());
$entry->setFixedRate($timesheet->getFixedRate());
$copyTimesheet->setHourlyRate($timesheet->getHourlyRate());
$copyTimesheet->setFixedRate($timesheet->getFixedRate());
}
if (in_array($copy, ['description', 'all'])) {
$entry->setDescription($timesheet->getDescription());
$copyTimesheet->setDescription($timesheet->getDescription());
}
if (in_array($copy, ['tags', 'all'])) {
foreach ($timesheet->getTags() as $tag) {
$entry->addTag($tag);
$copyTimesheet->addTag($tag);
}
}
if (in_array($copy, ['meta', 'all'])) {
foreach ($timesheet->getMetaFields() as $metaField) {
$metaNew = clone $metaField;
$entry->setMetaField($metaNew);
$copyTimesheet->setMetaField($metaNew);
}
}
}
$errors = $validator->validate($entry);
$errors = $validator->validate($copyTimesheet);
if (count($errors) > 0) {
throw new BadRequestHttpException($errors[0]->getPropertyPath() . ' = ' . $errors[0]->getMessage());
@@ -631,11 +641,9 @@ class TimesheetController extends BaseApiController
$this->configuration->getActiveEntriesHardLimit()
);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($entry);
$entityManager->flush();
$this->repository->save($copyTimesheet);
$view = new View($entry, 200);
$view = new View($copyTimesheet, 200);
$view->getContext()->setGroups(['Default', 'Entity', 'Timesheet']);
return $this->viewHandler->handle($view);
@@ -659,6 +667,8 @@ class TimesheetController extends BaseApiController
*
* @param int $id
* @return Response
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function exportAction($id)
{
@@ -677,9 +687,63 @@ class TimesheetController extends BaseApiController
$timesheet->setExported(!$timesheet->isExported());
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($timesheet);
$entityManager->flush();
$this->repository->save($timesheet);
$view = new View($timesheet, 200);
$view->getContext()->setGroups(['Default', 'Entity', 'Timesheet']);
return $this->viewHandler->handle($view);
}
/**
* Sets the value of a meta-field for an existing timesheet.
*
* @SWG\Response(
* response=200,
* description="Sets the value of an existing/configured meta-field. You cannot create unknown meta-fields, if the given name is not a configured meta-field, this will return an exception.",
* @SWG\Schema(ref="#/definitions/TimesheetEntity")
* )
* @SWG\Parameter(
* name="id",
* in="path",
* type="integer",
* description="Timesheet record ID to set the meta-field value for",
* required=true,
* )
* @Rest\RequestParam(name="name", strict=true, nullable=false, description="The meta-field name")
* @Rest\RequestParam(name="value", strict=true, nullable=false, description="The meta-field value")
*
* @param int $id
* @param ParamFetcherInterface $paramFetcher
* @return Response
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function metaAction($id, ParamFetcherInterface $paramFetcher)
{
$timesheet = $this->repository->find($id);
if (null === $timesheet) {
throw new NotFoundException();
}
if (!$this->isGranted('edit', $timesheet)) {
throw new AccessDeniedHttpException('You are not allowed to update this timesheet');
}
$event = new TimesheetMetaDefinitionEvent($timesheet);
$this->dispatcher->dispatch($event, TimesheetMetaDefinitionEvent::class);
$name = $paramFetcher->get('name');
$value = $paramFetcher->get('value');
if (null === ($meta = $timesheet->getMetaField($name))) {
throw new \InvalidArgumentException('Unknown meta-field requested');
}
$meta->setValue($value);
$this->repository->save($timesheet);
$view = new View($timesheet, 200);
$view->getContext()->setGroups(['Default', 'Entity', 'Timesheet']);

View File

@@ -26,6 +26,26 @@ use Pagerfanta\Pagerfanta;
class ActivityRepository extends EntityRepository
{
/**
* @param mixed $id
* @param null $lockMode
* @param null $lockVersion
* @return Activity|null
*/
public function find($id, $lockMode = null, $lockVersion = null)
{
/** @var Activity|null $activity */
$activity = parent::find($id, $lockMode, $lockVersion);
if (null === $activity) {
return null;
}
$loader = new ActivityLoader($this->getEntityManager());
$loader->loadResults([$activity]);
return $activity;
}
/**
* @param Activity $activity
* @throws ORMException

View File

@@ -28,6 +28,26 @@ use Pagerfanta\Pagerfanta;
class CustomerRepository extends EntityRepository
{
/**
* @param mixed $id
* @param null $lockMode
* @param null $lockVersion
* @return Customer|null
*/
public function find($id, $lockMode = null, $lockVersion = null)
{
/** @var Customer|null $customer */
$customer = parent::find($id, $lockMode, $lockVersion);
if (null === $customer) {
return null;
}
$loader = new CustomerLoader($this->getEntityManager());
$loader->loadResults([$customer]);
return $customer;
}
/**
* @param Customer $customer
* @throws ORMException

View File

@@ -25,11 +25,28 @@ use Doctrine\ORM\Query;
use Doctrine\ORM\QueryBuilder;
use Pagerfanta\Pagerfanta;
/**
* Class ProjectRepository
*/
class ProjectRepository extends EntityRepository
{
/**
* @param mixed $id
* @param null $lockMode
* @param null $lockVersion
* @return Project|null
*/
public function find($id, $lockMode = null, $lockVersion = null)
{
/** @var Project|null $project */
$project = parent::find($id, $lockMode, $lockVersion);
if (null === $project) {
return null;
}
$loader = new ProjectLoader($this->getEntityManager());
$loader->loadResults([$project]);
return $project;
}
/**
* @param Project $project
* @throws ORMException

View File

@@ -22,6 +22,20 @@ use Pagerfanta\Pagerfanta;
class TeamRepository extends EntityRepository
{
public function find($id, $lockMode = null, $lockVersion = null)
{
/** @var Team|null $team */
$team = parent::find($id, $lockMode, $lockVersion);
if (null === $team) {
return null;
}
$loader = new TeamLoader($this->getEntityManager());
$loader->loadResults([$team]);
return $team;
}
/**
* @param Team $team
* @throws ORMException

View File

@@ -35,6 +35,26 @@ class TimesheetRepository extends EntityRepository
public const STATS_QUERY_ACTIVE = 'active';
public const STATS_QUERY_MONTHLY = 'monthly';
/**
* @param mixed $id
* @param null $lockMode
* @param null $lockVersion
* @return Timesheet|null
*/
public function find($id, $lockMode = null, $lockVersion = null)
{
/** @var Timesheet|null $timesheet */
$timesheet = parent::find($id, $lockMode, $lockVersion);
if (null === $timesheet) {
return null;
}
$loader = new TimesheetLoader($this->getEntityManager());
$loader->loadResults([$timesheet]);
return $timesheet;
}
/**
* @param Timesheet $timesheet
* @throws \Doctrine\ORM\ORMException

View File

@@ -151,6 +151,14 @@ abstract class APIControllerBaseTest extends ControllerBaseTest
}
protected function assertEntityNotFoundForPatch(string $role, string $url, array $data)
{
return $this->assertExceptionForPatchAction($role, $url, $data, [
'code' => 404,
'message' => 'Not found'
]);
}
protected function assertExceptionForPatchAction(string $role, string $url, array $data, array $expectedErrors)
{
$client = $this->getClientForAuthenticatedUser($role);
@@ -158,15 +166,10 @@ abstract class APIControllerBaseTest extends ControllerBaseTest
$response = $client->getResponse();
$this->assertFalse($response->isSuccessful());
$expected = [
'code' => 404,
'message' => 'Not found'
];
$this->assertEquals(404, $client->getResponse()->getStatusCode());
$this->assertEquals($expectedErrors['code'], $client->getResponse()->getStatusCode());
$this->assertEquals(
$expected,
$expectedErrors,
json_decode($client->getResponse()->getContent(), true)
);
}

View File

@@ -13,6 +13,7 @@ use App\Entity\Activity;
use App\Entity\Customer;
use App\Entity\Project;
use App\Entity\User;
use App\Tests\Mocks\ActivityTestMetaFieldSubscriberMock;
use Symfony\Bundle\FrameworkBundle\Client;
use Symfony\Component\HttpFoundation\Response;
@@ -219,6 +220,54 @@ class ActivityControllerTest extends APIControllerBaseTest
$this->assertApiCallValidationError($response, ['project']);
}
public function testMetaActionThrowsNotFound()
{
$this->assertEntityNotFoundForPatch(User::ROLE_ADMIN, '/api/activities/42/meta', []);
}
public function testMetaActionThrowsExceptionOnMissingName()
{
return $this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/activities/1/meta', ['value' => 'X'], [
'code' => 400,
'message' => 'Parameter "name" of value "NULL" violated a constraint "This value should not be null."'
]);
}
public function testMetaActionThrowsExceptionOnMissingValue()
{
return $this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/activities/1/meta', ['name' => 'X'], [
'code' => 400,
'message' => 'Parameter "value" of value "NULL" violated a constraint "This value should not be null."'
]);
}
public function testMetaActionThrowsExceptionOnMissingMetafield()
{
return $this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/activities/1/meta', ['name' => 'X', 'value' => 'Y'], [
'code' => 500,
'message' => 'Unknown meta-field requested'
]);
}
public function testMetaAction()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
$client->getContainer()->get('event_dispatcher')->addSubscriber(new ActivityTestMetaFieldSubscriberMock());
$data = [
'name' => 'metatestmock',
'value' => 'another,testing,bar'
];
$this->request($client, '/api/activities/1/meta', 'PATCH', [], json_encode($data));
$this->assertTrue($client->getResponse()->isSuccessful());
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
/** @var Activity $activity */
$activity = $em->getRepository(Activity::class)->find(1);
$this->assertEquals('another,testing,bar', $activity->getMetaField('metatestmock')->getValue());
}
protected function assertStructure(array $result, $full = true)
{
$expectedKeys = [

View File

@@ -9,7 +9,9 @@
namespace App\Tests\API;
use App\Entity\Customer;
use App\Entity\User;
use App\Tests\Mocks\CustomerTestMetaFieldSubscriberMock;
use Symfony\Component\HttpFoundation\Response;
/**
@@ -161,6 +163,54 @@ class CustomerControllerTest extends APIControllerBaseTest
$this->assertApiCallValidationError($response, ['currency']);
}
public function testMetaActionThrowsNotFound()
{
$this->assertEntityNotFoundForPatch(User::ROLE_ADMIN, '/api/customers/42/meta', []);
}
public function testMetaActionThrowsExceptionOnMissingName()
{
return $this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/customers/1/meta', ['value' => 'X'], [
'code' => 400,
'message' => 'Parameter "name" of value "NULL" violated a constraint "This value should not be null."'
]);
}
public function testMetaActionThrowsExceptionOnMissingValue()
{
return $this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/customers/1/meta', ['name' => 'X'], [
'code' => 400,
'message' => 'Parameter "value" of value "NULL" violated a constraint "This value should not be null."'
]);
}
public function testMetaActionThrowsExceptionOnMissingMetafield()
{
return $this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/customers/1/meta', ['name' => 'X', 'value' => 'Y'], [
'code' => 500,
'message' => 'Unknown meta-field requested'
]);
}
public function testMetaAction()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
$client->getContainer()->get('event_dispatcher')->addSubscriber(new CustomerTestMetaFieldSubscriberMock());
$data = [
'name' => 'metatestmock',
'value' => 'another,testing,bar'
];
$this->request($client, '/api/customers/1/meta', 'PATCH', [], json_encode($data));
$this->assertTrue($client->getResponse()->isSuccessful());
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
/** @var Customer $customer */
$customer = $em->getRepository(Customer::class)->find(1);
$this->assertEquals('another,testing,bar', $customer->getMetaField('metatestmock')->getValue());
}
protected function assertStructure(array $result, $full = true)
{
$expectedKeys = [

View File

@@ -13,6 +13,7 @@ use App\Entity\Customer;
use App\Entity\Project;
use App\Entity\User;
use App\Repository\Query\VisibilityQuery;
use App\Tests\Mocks\ProjectTestMetaFieldSubscriberMock;
use Symfony\Bundle\FrameworkBundle\Client;
use Symfony\Component\HttpFoundation\Response;
@@ -211,6 +212,54 @@ class ProjectControllerTest extends APIControllerBaseTest
$this->assertApiCallValidationError($response, ['customer']);
}
public function testMetaActionThrowsNotFound()
{
$this->assertEntityNotFoundForPatch(User::ROLE_ADMIN, '/api/projects/42/meta', []);
}
public function testMetaActionThrowsExceptionOnMissingName()
{
return $this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/projects/1/meta', ['value' => 'X'], [
'code' => 400,
'message' => 'Parameter "name" of value "NULL" violated a constraint "This value should not be null."'
]);
}
public function testMetaActionThrowsExceptionOnMissingValue()
{
return $this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/projects/1/meta', ['name' => 'X'], [
'code' => 400,
'message' => 'Parameter "value" of value "NULL" violated a constraint "This value should not be null."'
]);
}
public function testMetaActionThrowsExceptionOnMissingMetafield()
{
return $this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/projects/1/meta', ['name' => 'X', 'value' => 'Y'], [
'code' => 500,
'message' => 'Unknown meta-field requested'
]);
}
public function testMetaAction()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
$client->getContainer()->get('event_dispatcher')->addSubscriber(new ProjectTestMetaFieldSubscriberMock());
$data = [
'name' => 'metatestmock',
'value' => 'another,testing,bar'
];
$this->request($client, '/api/projects/1/meta', 'PATCH', [], json_encode($data));
$this->assertTrue($client->getResponse()->isSuccessful());
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
/** @var Project $project */
$project = $em->getRepository(Project::class)->find(1);
$this->assertEquals('another,testing,bar', $project->getMetaField('metatestmock')->getValue());
}
protected function assertStructure(array $result, $full = true)
{
$expectedKeys = [

View File

@@ -18,6 +18,7 @@ use App\Entity\TimesheetMeta;
use App\Entity\User;
use App\Tests\DataFixtures\TimesheetFixtures;
use App\Tests\Mocks\Security\UserDateTimeFactoryFactory;
use App\Tests\Mocks\TimesheetTestMetaFieldSubscriberMock;
use App\Timesheet\UserDateTimeFactory;
use Symfony\Component\HttpFoundation\Response;
@@ -619,7 +620,7 @@ class TimesheetControllerTest extends APIControllerBaseTest
public function testStopThrowsNotFound()
{
$this->assertEntityNotFound(User::ROLE_USER, '/api/timesheets/11/stop', 'PATCH');
$this->assertEntityNotFoundForPatch(User::ROLE_USER, '/api/timesheets/11/stop', []);
}
public function testStopNotAllowedForUser()
@@ -782,7 +783,7 @@ class TimesheetControllerTest extends APIControllerBaseTest
public function testRestartThrowsNotFound()
{
$this->assertEntityNotFound(User::ROLE_USER, '/api/timesheets/42/restart', 'PATCH');
$this->assertEntityNotFoundForPatch(User::ROLE_USER, '/api/timesheets/42/restart', []);
}
public function testExportAction()
@@ -821,7 +822,55 @@ class TimesheetControllerTest extends APIControllerBaseTest
public function testExportThrowsNotFound()
{
$this->assertEntityNotFound(User::ROLE_ADMIN, '/api/timesheets/42/export', 'PATCH');
$this->assertEntityNotFoundForPatch(User::ROLE_ADMIN, '/api/timesheets/42/export', []);
}
public function testMetaActionThrowsNotFound()
{
$this->assertEntityNotFoundForPatch(User::ROLE_ADMIN, '/api/timesheets/42/meta', []);
}
public function testMetaActionThrowsExceptionOnMissingName()
{
return $this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/timesheets/1/meta', ['value' => 'X'], [
'code' => 400,
'message' => 'Parameter "name" of value "NULL" violated a constraint "This value should not be null."'
]);
}
public function testMetaActionThrowsExceptionOnMissingValue()
{
return $this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/timesheets/1/meta', ['name' => 'X'], [
'code' => 400,
'message' => 'Parameter "value" of value "NULL" violated a constraint "This value should not be null."'
]);
}
public function testMetaActionThrowsExceptionOnMissingMetafield()
{
return $this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/timesheets/1/meta', ['name' => 'X', 'value' => 'Y'], [
'code' => 500,
'message' => 'Unknown meta-field requested'
]);
}
public function testMetaAction()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER);
$client->getContainer()->get('event_dispatcher')->addSubscriber(new TimesheetTestMetaFieldSubscriberMock());
$data = [
'name' => 'metatestmock',
'value' => 'another,testing,bar'
];
$this->request($client, '/api/timesheets/1/meta', 'PATCH', [], json_encode($data));
$this->assertTrue($client->getResponse()->isSuccessful());
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
/** @var Timesheet $timesheet */
$timesheet = $em->getRepository(Timesheet::class)->find(1);
$this->assertEquals('another,testing,bar', $timesheet->getMetaField('metatestmock')->getValue());
}
protected function assertDefaultStructure(array $result, $full = true)