-
-
Notifications
You must be signed in to change notification settings - Fork 933
Closed
Labels
Description
API Platform version(s) affected: 3.0.4
Description
Calling getOperation with null or empty string as $operationName can lead to wrong cache hit.
How to reproduce
- Specify a resource
User
with default CRUD operations - Run the following test code
class GetOperationTest extends ApiTestCase {
public function test1GetOperationForGet() {
$resourceMetadataCollection = $this->getResourceMetadataFactory()->create(User::class);
$getOperation = $resourceMetadataCollection->getOperation(null, false, true);
$this->assertInstanceOf(Get::class, $getOperation);
}
public function test2GetOperationForGetCollection() {
$resourceMetadataCollection = $this->getResourceMetadataFactory()->create(User::class);
$getCollectionOperation = $resourceMetadataCollection->getOperation(null, true, true);
$this->assertInstanceOf(GetCollection::class, $getCollectionOperation);
}
public function test3GetOperationForBoth() {
$resourceMetadataCollection = $this->getResourceMetadataFactory()->create(User::class);
$getOperation = $resourceMetadataCollection->getOperation(null, false, true);
$this->assertInstanceOf(Get::class, $getOperation);
$getCollectionOperation = $resourceMetadataCollection->getOperation(null, true, true);
$this->assertInstanceOf(GetCollection::class, $getCollectionOperation);
}
}
- Expected all tests to succeed. While test1 and test3 are running fine, test3 however fails with
Failed asserting that ApiPlatform\Metadata\Get Object (...) is an instance of class "ApiPlatform\Metadata\GetCollection".
Possible Solution
The problem in test3 is that the first call of getOperation
populates operationCache
with an empty string as key:
return $this->operationCache[self::HTTP_PREFIX.$operationName] = $operation;
where $operationName
is empty string.
The second call to getOperation
will immediately return the cache hit.
Possible solution:
Store the operation in operationCache with actual name of the operation, not with $operationName:
return $this->operationCache[self::HTTP_PREFIX.$operation->getName()] = $operation;
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
Done