Skip to content

Commit

Permalink
Added exception if stockLevels is found within the JSON data and adde…
Browse files Browse the repository at this point in the history
…d unit test, relates to #551
  • Loading branch information
Felicitus committed Jan 11, 2016
1 parent a5576df commit 5690750
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 3 deletions.
12 changes: 9 additions & 3 deletions app/config/config_partkeepr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -283,11 +283,17 @@ services:
factory: [ "@api.operation_factory", "createItemOperation" ]
arguments: [ "@resource.part", "GET" ]

resource.part.item_operation.put:
resource.part.item_operation.custom_put:
class: "Dunglas\ApiBundle\Api\Operation\Operation"
public: false
factory: [ "@api.operation_factory", "createItemOperation" ]
arguments: [ "@resource.part", "PUT" ]
arguments:
- "@resource.part"
- [ "PUT" ]
- "/parts/{id}"
- "partkeepr.part.put"
- "PartPut"


resource.part.item_operation.delete:
class: "Dunglas\ApiBundle\Api\Operation\Operation"
Expand Down Expand Up @@ -334,7 +340,7 @@ services:
tags: [ { name: "api.resource" } ]
calls:
- method: "initItemOperations"
arguments: [ [ "@resource.part.item_operation.get", "@resource.part.item_operation.put", "@resource.part.item_operation.delete", "@resource.part.item_operation.add_stock", "@resource.part.item_operation.remove_stock", "@resource.part.item_operation.set_stock" ] ]
arguments: [ [ "@resource.part.item_operation.get", "@resource.part.item_operation.custom_put", "@resource.part.item_operation.delete", "@resource.part.item_operation.add_stock", "@resource.part.item_operation.remove_stock", "@resource.part.item_operation.set_stock" ] ]
- method: "initCollectionOperations"
arguments: [ [ "@resource.part.collection_operation.get", "@resource.part.collection_operation.custom_post" ] ]
- method: "initFilters"
Expand Down
82 changes: 82 additions & 0 deletions src/PartKeepr/PartBundle/Action/PartPutAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<?php
namespace PartKeepr\PartBundle\Action;


use Dunglas\ApiBundle\Action\ActionUtilTrait;
use Dunglas\ApiBundle\Api\ResourceInterface;
use Dunglas\ApiBundle\Exception\RuntimeException;
use Dunglas\ApiBundle\Model\DataProviderInterface;
use PartKeepr\AuthBundle\Exceptions\UserLimitReachedException;
use PartKeepr\AuthBundle\Exceptions\UserProtectedException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Serializer\SerializerInterface;

class PartPutAction
{
use ActionUtilTrait;

/**
* @var DataProviderInterface
*/
private $dataProvider;

/**
* @var SerializerInterface
*/
private $serializer;

public function __construct(
DataProviderInterface $dataProvider,
SerializerInterface $serializer
) {
$this->dataProvider = $dataProvider;
$this->serializer = $serializer;
}

/**
* Create a new item.
*
* @param Request $request
* @param string|int $id
*
* @return mixed
*
* @throws NotFoundHttpException
* @throws RuntimeException
* @throws UserProtectedException
* @throws UserLimitReachedException
* @throws \Exception If a stockLevels attribute is found in the request
*/
public function __invoke(Request $request, $id)
{
/**
* @var $resourceType ResourceInterface
*/
list($resourceType, $format) = $this->extractAttributes($request);

/**
* Workaround to ensure stockLevels are not overwritten in a PUT request.
* @see https://github.com/partkeepr/PartKeepr/issues/551
*/
$data = json_decode($request->getContent());

if (property_exists($data, "stockLevels")) {
throw new \Exception("stockLevels may not be written in a PUT request!");
}

$data = $this->getItem($this->dataProvider, $resourceType, $id);

$context = $resourceType->getDenormalizationContext();
$context['object_to_populate'] = $data;

$data = $this->serializer->deserialize(
$request->getContent(),
$resourceType->getEntityClass(),
$format,
$context
);

return $data;
}
}
4 changes: 4 additions & 0 deletions src/PartKeepr/PartBundle/Resources/config/actions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
<service id="partkeepr.part.post" class="PartKeepr\PartBundle\Action\PostAction">
<argument type="service" id="api.serializer" />
<argument type="service" id="partkeepr.part_service" />
</service>
<service id="partkeepr.part.put" class="PartKeepr\PartBundle\Action\PartPutAction">
<argument type="service" id="api.data_provider"/>
<argument type="service" id="api.serializer" />
</service>
<service id="partkeepr.part.add_stock" class="PartKeepr\PartBundle\Action\AddStockAction">
<argument type="service" id="api.data_provider"/>
Expand Down
73 changes: 73 additions & 0 deletions src/PartKeepr/PartBundle/Tests/Issues/StockHistoryLostTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?php
namespace PartKeepr\PartBundle\Tests\Issues;

use Doctrine\Common\DataFixtures\ProxyReferenceRepository;
use PartKeepr\CoreBundle\Tests\WebTestCase;
use PartKeepr\PartBundle\Entity\Part;
use PartKeepr\StockBundle\Entity\StockEntry;

/**
* Class StockHistoryLostTest
*
* Unit test against issue #551 (stock history gets removed after saving part)
*/
class StockHistoryLostTest extends WebTestCase
{
/**
* @var ProxyReferenceRepository
*/
protected $fixtures;

public function setUp()
{
$this->fixtures = $this->loadFixtures(
array(
'PartKeepr\StorageLocationBundle\DataFixtures\CategoryDataLoader',
'PartKeepr\StorageLocationBundle\DataFixtures\StorageLocationLoader',
'PartKeepr\PartBundle\DataFixtures\CategoryDataLoader',
'PartKeepr\PartBundle\DataFixtures\PartDataLoader',
'PartKeepr\AuthBundle\DataFixtures\LoadUserData',
'PartKeepr\ManufacturerBundle\Tests\DataFixtures\ManufacturerDataLoader',
'PartKeepr\DistributorBundle\Tests\DataFixtures\DistributorDataLoader',
)
)->getReferenceRepository();
}

public function testStockHistory () {
$client = static::makeClient(true);

/**
* @var $part1 Part
*/
$part1 = $this->fixtures->getReference("part.1");

$stockLevel = new StockEntry();
$stockLevel->setPart($part1);
$stockLevel->setStockLevel(5);

$fosUser = $this->fixtures->getReference("user.admin");
$userService = $this->getContainer()->get("partkeepr.userservice");
$user = $userService->getProxyUser($fosUser->getUsername(), $userService->getBuiltinProvider(), true);

$stockLevel->setUser($user);
$part1->addStockLevel($stockLevel);

$this->getContainer()->get("doctrine.orm.default_entity_manager")->flush();

$iriCoverter = $this->getContainer()->get("api.iri_converter");
$iri = $iriCoverter->getIriFromItem($part1);

$client->request("GET", $iri);

$response = $client->getResponse()->getContent();
$responseObj = json_decode($response, true);
$responseObj["stockLevels"] = array();

$client->request("PUT", $iri, array(), array(), array(), json_encode($responseObj));

$this->assertEquals(500, $client->getResponse()->getStatusCode());

$this->getContainer()->get("doctrine.orm.default_entity_manager")->refresh($part1);
$this->assertEquals(1, count($part1->getStockLevels()));
}
}

0 comments on commit 5690750

Please sign in to comment.