code = new CampaignCode('Camp100'); $this->name = new CampaignName('Name'); $this->publication = \boolval(0); $this->printAllAtOnce = \boolval(1); $this->coupons = [ new CampaignCoupon( new ProcessingCode('PC1'), new CouponQuantity(100), Country::FRANCE, new PrintRules(maxPerCustomer: 3) ) ]; $this->brandCode = new BrandCode('AAA01'); $this->actorId = ActorId::generate(); }); afterEach(function (): void { CarbonImmutable::setTestNow(); }); it('creates a campaign', function (): void { // GIVEN $id = CampaignId::generate(); // WHEN $campaign = Campaign::hydrate( $id, $this->code, $this->name, $this->publication, $this->printAllAtOnce, $this->coupons, $this->brandCode, $this->actorId ); // THEN expect($campaign->id())->toBe($id) ->and($campaign->code)->toBe($this->code) ->and($campaign->name)->toBe($this->name) ->and($campaign->publication)->toBe($this->publication) ->and($campaign->printAllAtOnce)->toBe($this->printAllAtOnce) ->and($campaign->coupons)->toBe($this->coupons) ->and($campaign->brandCode)->toBe($this->brandCode) ->and($campaign->updatedAt)->toBeNull() ->and($campaign->updatedAt())->toBeNull(); }); it('creates a campaign without coupon', function (): void { // GIVEN $id = CampaignId::generate(); // WHEN $campaign = Campaign::hydrate( $id, $this->code, $this->name, $this->publication, $this->printAllAtOnce, [], $this->brandCode, $this->actorId ); // THEN expect($campaign->coupons)->toBe([]); }); it('creates a coupon with an explicit updatedAt date', function (): void { // GIVEN $id = CampaignId::generate(); $updatedAt = new \DateTimeImmutable('2026-09-22 10:00:00', new \DateTimeZone('UTC')); // WHEN $campaign = Campaign::hydrate( $id, $this->code, $this->name, $this->publication, $this->printAllAtOnce, $this->coupons, $this->brandCode, $this->actorId, $updatedAt ); // THEN expect($campaign->updatedAt)->toBe($updatedAt) ->and($campaign->updatedAt())->toBe($updatedAt); }); it('creates a new campaign with a freshly generated id', function (): void { // GIVEN / WHEN $campaign = Campaign::create( $this->code, $this->name, $this->publication, $this->printAllAtOnce, $this->coupons, $this->brandCode, $this->actorId ); // THEN expect($campaign->id())->toBeInstanceOf(CampaignId::class) ->and($campaign->code)->toBe($this->code) ->and($campaign->name)->toBe($this->name) ->and($campaign->publication)->toBe($this->publication) ->and($campaign->printAllAtOnce)->toBe($this->printAllAtOnce) ->and($campaign->coupons)->toBe($this->coupons) ->and($campaign->brandCode)->toBe($this->brandCode) ->and($campaign->updatedAt)->toBeNull() ->and($campaign->updatedAt())->toBeNull(); }); it('generates a different id for each created campaign', function (): void { // GIVEN / WHEN $firstCampaign = Campaign::create( $this->code, $this->name, $this->publication, $this->printAllAtOnce, $this->coupons, $this->brandCode, $this->actorId ); $secondCampaign = Campaign::create( $this->code, $this->name, $this->publication, $this->printAllAtOnce, $this->coupons, $this->brandCode, $this->actorId ); // THEN expect($firstCampaign->id()->equals($secondCampaign->id()))->toBeFalse(); }); it('returns the creation date extracted from the id', function (): void { // GIVEN $expected = new \DateTimeImmutable('2024-06-15 12:34:56.789000', new \DateTimeZone('UTC')); $id = new CampaignId(Uuid::uuid7($expected)); $campaign = Campaign::hydrate( $id, $this->code, $this->name, $this->publication, $this->printAllAtOnce, $this->coupons, $this->brandCode, $this->actorId ); // WHEN $result = $campaign->createdAt(); // THEN expect($result->format('Y-m-d H:i:s.v'))->toBe($expected->format('Y-m-d H:i:s.v')); }); it('rejects a campaign with a non-coupon element', function (): void { // GIVEN $id = CampaignId::generate(); $coupons = ['PC1']; // WHEN / THEN expect(fn (): Campaign => Campaign::hydrate( $id, $this->code, $this->name, $this->publication, $this->printAllAtOnce, $coupons, $this->brandCode, $this->actorId ))->toThrow(\DomainException::class, 'Campaign coupons must be CampaignCoupon instances.'); }); });