Skip to content

[CalendarLink] DTSTAMP bypasses the Clock component, making output non-deterministic #3813

Description

@ker0x

Component: CalendarLink
Version: v3.4.0

Problem

IcsBuilder::build() reads the wall clock directly:

'DTSTAMP:'.$this->formatUtc(new \DateTimeImmutable('now', new \DateTimeZone('UTC'))),

The builder already takes an injectable UuidFactory so that UID generation
can be controlled in tests (MockUuidFactory in IcsBuilderTest), but
DTSTAMP has no equivalent seam. The consequence is that no test — upstream or
downstream — can assert on a complete .ics payload or on the generated
data: URI, since one line changes every second.

Symfony ships symfony/clock precisely for this, and the component already
depends on the framework.

Suggested fix

Accept an optional ClockInterface, mirroring the existing UuidFactory
parameter:

public function __construct(
    ?UuidFactory $uuidFactory = null,
    private readonly ClockInterface $clock = new NativeClock(),
) {
    $this->uuidFactory = $uuidFactory ?? new UuidFactory();
}

and use $this->clock->now() for DTSTAMP. Backward compatible, and it would
let IcsBuilderTest assert on whole payloads. Happy to open a PR.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions