Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion docs/ORMContext/see-entity-in-repository-with-properties.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,25 @@ This step allows you to verify that a specific entity exists in the database by
- Validating complex entity state with multiple property conditions
- Testing business logic that modifies entity properties

#### Embedded Properties (Value Objects)

Both steps support Doctrine embedded objects using dotted property paths:

```gherkin
Then I see entity "App\Entity\Balance" with properties:
"""
{
"customerId": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
"balanceValue.amount": "500000",
"balanceValue.currency": "USD",
}
"""
```

The dotted notation (e.g., `balanceValue.amount`) allows querying embedded value objects defined in your entity mappings.

#### Notes:

- Properties with `null` values are queried using `IS NULL` condition
- All other properties are matched using equality
- All other properties are matched using equality
- Embedded property paths use dotted notation (e.g., `embeddable.field`)
32 changes: 18 additions & 14 deletions src/Context/ORMContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Behat\Behat\Context\Context;
use Behat\Gherkin\Node\PyStringNode;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\NonUniqueResultException;
use Doctrine\ORM\NoResultException;
Expand All @@ -24,7 +25,7 @@ public function __construct(EntityManagerInterface $manager)

/**
* @And I see :count entities :entityClass
*
*
* @param class-string $entityClass
*/
public function andISeeInRepository(int $count, string $entityClass): void
Expand All @@ -34,7 +35,7 @@ public function andISeeInRepository(int $count, string $entityClass): void

/**
* @Then I see :count entities :entityClass
*
*
* @param class-string $entityClass
*/
public function thenISeeInRepository(int $count, string $entityClass): void
Expand All @@ -44,7 +45,7 @@ public function thenISeeInRepository(int $count, string $entityClass): void

/**
* @And I see entity :entity with id :id
*
*
* @param class-string $entityClass
*/
public function andISeeEntityInRepositoryWithId(string $entityClass, string $id): void
Expand All @@ -54,7 +55,7 @@ public function andISeeEntityInRepositoryWithId(string $entityClass, string $id)

/**
* @Then I see entity :entity with id :id
*
*
* @param class-string $entityClass
*/
public function thenISeeEntityInRepositoryWithId(string $entityClass, string $id): void
Expand All @@ -64,7 +65,8 @@ public function thenISeeEntityInRepositoryWithId(string $entityClass, string $id

/**
* @Then I see entity :entity with properties:
*
* @And I see entity :entity with properties:
*
* @param class-string $entityClass
*/
public function andISeeEntityInRepositoryWithProperties(string $entityClass, PyStringNode $string): void
Expand All @@ -88,19 +90,20 @@ private function seeInRepository(int $count, string $entityClass, ?array $params

if (null !== $params) {
$metadata = $this->manager->getClassMetadata($entityClass);
$paramIndex = 0;

foreach ($params as $columnName => $columnValue) {
$isEmbeddedPath = str_contains($columnName, '.');
$paramName = $isEmbeddedPath ? 'p' . $paramIndex++ : $columnName;

if ($columnValue === null) {
$query->andWhere(sprintf('e.%s IS NULL', $columnName));
} elseif (!$isEmbeddedPath && $this->isJsonField($metadata, $columnName)) {
// Handle JSON fields with proper DQL (skip for embedded paths)
$this->addJsonFieldCondition($query, $columnName, $columnValue);
} else {
if ($this->isJsonField($metadata, $columnName)) {
// Handle JSON fields with proper DQL
$this->addJsonFieldCondition($query, $columnName, $columnValue);
} else {
// Regular field comparison
$query->andWhere(sprintf('e.%s = :%s', $columnName, $columnName))
->setParameter($columnName, $columnValue);
}
$query->andWhere(sprintf('e.%s = :%s', $columnName, $paramName))
->setParameter($paramName, $columnValue);
}
}
}
Expand All @@ -117,7 +120,7 @@ private function seeInRepository(int $count, string $entityClass, ?array $params

/**
* Check if a field is mapped as JSON type
*
*
* @param \Doctrine\ORM\Mapping\ClassMetadata<object> $metadata
*/
private function isJsonField(\Doctrine\ORM\Mapping\ClassMetadata $metadata, string $fieldName): bool
Expand All @@ -139,6 +142,7 @@ private function isJsonField(\Doctrine\ORM\Mapping\ClassMetadata $metadata, stri
*/
private function addJsonFieldCondition(QueryBuilder $query, string $fieldName, $expectedValue): void
{
/** @var AbstractPlatform $platform */
$platform = $this->manager->getConnection()->getDatabasePlatform();
$platformName = $platform->getName();

Expand Down
Loading