diff --git a/src/Bundle/ChillDocStoreBundle/Controller/StoredObjectVersionApiController.php b/src/Bundle/ChillDocStoreBundle/Controller/StoredObjectVersionApiController.php new file mode 100644 index 000000000..4104ae67d --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/Controller/StoredObjectVersionApiController.php @@ -0,0 +1,64 @@ +security->isGranted(StoredObjectRoleEnum::SEE->value, $storedObject)) { + throw new AccessDeniedHttpException('not allowed to see this stored object'); + } + + $total = $storedObject->getVersions()->count(); + $paginator = $this->paginatorFactory->create($total); + + $criteria = Criteria::create(); + $criteria->orderBy(['id' => Order::Ascending]); + $criteria->setMaxResults($paginator->getItemsPerPage())->setFirstResult($paginator->getCurrentPageFirstItemNumber()); + $items = $storedObject->getVersions()->matching($criteria); + + return new JsonResponse( + $this->serializer->serialize(new Collection($items, $paginator), 'json', [AbstractNormalizer::GROUPS => ['read']]), + json: true + ); + } +} diff --git a/src/Bundle/ChillDocStoreBundle/Entity/StoredObject.php b/src/Bundle/ChillDocStoreBundle/Entity/StoredObject.php index 6efc3fb9c..c6d9e362c 100644 --- a/src/Bundle/ChillDocStoreBundle/Entity/StoredObject.php +++ b/src/Bundle/ChillDocStoreBundle/Entity/StoredObject.php @@ -18,6 +18,7 @@ use Chill\MainBundle\Doctrine\Model\TrackCreationInterface; use Chill\MainBundle\Doctrine\Model\TrackCreationTrait; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; +use Doctrine\Common\Collections\Selectable; use Doctrine\ORM\Mapping as ORM; use Ramsey\Uuid\Uuid; use Ramsey\Uuid\UuidInterface; @@ -89,10 +90,10 @@ class StoredObject implements Document, TrackCreationInterface private string $generationErrors = ''; /** - * @var Collection + * @var Collection&Selectable */ #[ORM\OneToMany(mappedBy: 'storedObject', targetEntity: StoredObjectVersion::class, cascade: ['persist'], orphanRemoval: true)] - private Collection $versions; + private Collection&Selectable $versions; /** * @param StoredObject::STATUS_* $status @@ -256,7 +257,7 @@ class StoredObject implements Document, TrackCreationInterface return $this->template; } - public function getVersions(): Collection + public function getVersions(): Collection&Selectable { return $this->versions; } diff --git a/src/Bundle/ChillDocStoreBundle/Tests/Controller/StoredObjectVersionApiControllerTest.php b/src/Bundle/ChillDocStoreBundle/Tests/Controller/StoredObjectVersionApiControllerTest.php new file mode 100644 index 000000000..27154831d --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/Tests/Controller/StoredObjectVersionApiControllerTest.php @@ -0,0 +1,77 @@ +registerVersion(); + } + + $security = $this->prophesize(Security::class); + $security->isGranted(StoredObjectRoleEnum::SEE->value, $storedObject) + ->willReturn(true) + ->shouldBeCalledOnce(); + + $controller = $this->buildController($security->reveal()); + + $response = $controller->listVersions($storedObject); + $body = json_decode($response->getContent(), true, 512, JSON_THROW_ON_ERROR); + + self::assertEquals($response->getStatusCode(), 200); + self::assertIsArray($body); + self::assertArrayHasKey('results', $body); + self::assertCount(10, $body['results']); + } + + private function buildController(Security $security): StoredObjectVersionApiController + { + $paginator = $this->prophesize(Paginator::class); + $paginator->getCurrentPageFirstItemNumber()->willReturn(0); + $paginator->getItemsPerPage()->willReturn(10); + $paginator->getTotalItems()->willReturn(15); + $paginator->hasNextPage()->willReturn(false); + $paginator->hasPreviousPage()->willReturn(false); + + $paginatorFactory = $this->prophesize(PaginatorFactoryInterface::class); + $paginatorFactory->create(Argument::type('int'))->willReturn($paginator); + + $serializer = new Serializer([ + new StoredObjectVersionNormalizer(), new CollectionNormalizer(), + ], [new JsonEncoder()]); + + return new StoredObjectVersionApiController($paginatorFactory->reveal(), $serializer, $security); + } +} diff --git a/src/Bundle/ChillDocStoreBundle/chill.api.specs.yaml b/src/Bundle/ChillDocStoreBundle/chill.api.specs.yaml index 28345e463..fb1e71ba5 100644 --- a/src/Bundle/ChillDocStoreBundle/chill.api.specs.yaml +++ b/src/Bundle/ChillDocStoreBundle/chill.api.specs.yaml @@ -105,3 +105,28 @@ paths: 404: description: "Not found" + /1.0/doc-store/stored-object/{uuid}/versions: + get: + tags: + - storedobject + summary: Get a signed route to post stored object + parameters: + - in: path + name: uuid + required: true + allowEmptyValue: false + description: The UUID of the storedObjeect + schema: + type: string + format: uuid + responses: + 200: + description: "OK" + content: + application/json: + schema: + type: object + 403: + description: "Unauthorized" + 404: + description: "Not found"