Skip to content

Commit 5ce2d7b

Browse files
committed
Fix CwaFixtureBuilder: timestamp components added directly via GroupBuilder::add()
1 parent a5f5bbd commit 5ce2d7b

3 files changed

Lines changed: 39 additions & 0 deletions

File tree

CLAUDE.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,12 @@ Services instrumented with optional `?CwaCollectorData` arg: `JWTEventListener`,
614614

615615
---
616616

617+
## ~~Bug: `CwaFixtureBuilder::createPositions()` does not timestamp components~~ — FIXED
618+
619+
**Fix (committed PLACEHOLDER):** In `createPositions()`, before `$this->persistWithAssociations($component)`, guard with `isConfigured()` and call `persistTimestampedFields($component, true)` when the component is not already in `$persistedEntities`. PHPUnit test added to `tests/Fixture/CwaFixtureBuilderTest.php`.
620+
621+
---
622+
617623
## Known Configuration Quirks
618624

619625
*(none)*

src/Fixture/CwaFixtureBuilder.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,10 @@ private function createPositions(GroupBuilder $groupBuilder): bool
534534
$position->sortValue = $item['sort'];
535535
$position->component = $component;
536536
$position->componentGroup = $componentGroup;
537+
if (!isset($this->persistedEntities[spl_object_id($component)])
538+
&& $this->timestampedPersister->isConfigured($component)) {
539+
$this->timestampedPersister->persistTimestampedFields($component, true);
540+
}
537541
$this->timestampedPersister->persistTimestampedFields($position, true);
538542
$this->persistWithAssociations($component);
539543
$this->manager->persist($position);

tests/Fixture/CwaFixtureBuilderTest.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1999,6 +1999,35 @@ public function test_on_routes_created_fires_exactly_once_across_multiple_flushe
19991999
$this->assertSame(1, $callCount, 'onRoutesCreated must fire exactly once even when flush() is called multiple times');
20002000
}
20012001

2002+
public function test_timestamped_persister_called_for_component_added_directly_to_group(): void
2003+
{
2004+
$calls = [];
2005+
$component = new class extends AbstractComponent {};
2006+
2007+
$persister = $this->createStub(TimestampedDataPersister::class);
2008+
$persister->method('isConfigured')->willReturnCallback(
2009+
static fn (object $entity): bool => $entity instanceof AbstractComponent
2010+
);
2011+
$persister->method('persistTimestampedFields')->willReturnCallback(
2012+
static function (object $entity, bool $isNew) use (&$calls): void {
2013+
$calls[] = ['entity' => $entity, 'isNew' => $isNew];
2014+
}
2015+
);
2016+
2017+
$builder = $this->makeBuilder(timestampedPersister: $persister);
2018+
$builder->layout('main', 'CwaLayoutPrimary');
2019+
$builder->page('home', 'Template', layout: 'main', isTemplate: true)
2020+
->group('primary')
2021+
->add($component);
2022+
$builder->flush();
2023+
2024+
$componentCalls = array_values(array_filter($calls, static fn ($c) => $c['entity'] === $component));
2025+
$this->assertNotEmpty($componentCalls, 'persistTimestampedFields must be called for component added via GroupBuilder::add() when isConfigured() returns true');
2026+
foreach ($componentCalls as $call) {
2027+
$this->assertTrue($call['isNew']);
2028+
}
2029+
}
2030+
20022031
// --- readProperty: DoWhile traverses parent class hierarchy (kills not-covered DoWhile mutant line 578) ---
20032032

20042033
public function test_read_property_finds_property_declared_only_in_parent_class(): void

0 commit comments

Comments
 (0)