requestedCoupon = new RequestedCoupon( new CouponName('Coupon A'), new CouponProductName('Product A'), new RequestedCouponQuantity(100), new WarningThresholdQuantity(10), new Period(new DateTime('2026-01-01'), new DateTime('2026-02-01')), new MoneyAmount(new Money(Currency::EUR, 300)), new ProcessingCode('PC1'), new CouponPicture(new PicturePath('coupons/product.jpg'), new PicturePath('coupons/thumbnail.jpg')), new GS1('01234567890128', BarcodeFormat::EAN13), new CouponValidity(30, new DateTime()), ); }); it('finds a campaign request by its id, along with its brand', function (): void { // GIVEN $id = CampaignRequestId::generate(); $code = new BrandCode('AAA01'); $campaignRequest = CampaignRequest::hydrate( $id, $code, new Applicant('John', 'Doe', new Email('john.doe@example.com')), new CountryAuthorized(Country::FRANCE), CampaignRequestType::CLUB, new PrintRules(maxPerCustomer: 3), $this->requestedCoupon, CampaignRequestStatus::CREATED, ); $brand = Brand::hydrate( BrandId::generate(), $code, new BrandName('Brand A'), new PicturePath('brands/logo.jpg'), new Rcs('RCS PARIS 111 222 333'), new Email('contact@example.com'), ); $repository = \Mockery::mock(CampaignRequestRepository::class); $repository->shouldReceive('findById')->once()->with($id)->andReturn($campaignRequest); $brandRepository = \Mockery::mock(BrandRepository::class); $brandRepository->shouldReceive('findByCode')->once()->with($code)->andReturn($brand); $useCase = new FindCampaignRequest($repository, $brandRepository); // WHEN $result = $useCase->execute(new Input(id: $id)); // THEN expect($result)->toBeInstanceOf(CampaignRequestFound::class) ->and($result->brand)->toBe($brand) ->and($result->applicant)->toBe($campaignRequest->applicant) ->and($result->country)->toBe($campaignRequest->country) ->and($result->campaignType)->toBe($campaignRequest->campaignType) ->and($result->printRules)->toBe($campaignRequest->printRules) ->and($result->requestedCoupon)->toBe($campaignRequest->requestedCoupon) ->and($result->status)->toBe($campaignRequest->status) ->and($result->rejectionReason)->toBeNull(); }); it('finds a rejected campaign request with its rejection reason', function (): void { // GIVEN $id = CampaignRequestId::generate(); $code = new BrandCode('AAA01'); $rejectionReason = new RejectionReason('Missing legal documents.'); $campaignRequest = CampaignRequest::hydrate( $id, $code, new Applicant('John', 'Doe', new Email('john.doe@example.com')), new CountryAuthorized(Country::FRANCE), CampaignRequestType::CLUB, new PrintRules(maxPerCustomer: 3), $this->requestedCoupon, CampaignRequestStatus::REJECTED, $rejectionReason, ); $repository = \Mockery::mock(CampaignRequestRepository::class); $repository->shouldReceive('findById')->once()->with($id)->andReturn($campaignRequest); $brandRepository = \Mockery::mock(BrandRepository::class); $brandRepository->shouldReceive('findByCode')->once()->with($code)->andReturn( Brand::hydrate( BrandId::generate(), $code, new BrandName('Brand A'), new PicturePath('brands/logo.jpg'), new Rcs('RCS PARIS 111 222 333'), new Email('contact@example.com'), ) ); $useCase = new FindCampaignRequest($repository, $brandRepository); // WHEN $result = $useCase->execute(new Input(id: $id)); // THEN expect($result)->toBeInstanceOf(CampaignRequestFound::class) ->and($result->status)->toBe(CampaignRequestStatus::REJECTED) ->and($result->rejectionReason)->toBe($rejectionReason); }); it('returns CampaignRequestNotFound when the id is not found', function (): void { // GIVEN $id = CampaignRequestId::generate(); $repository = \Mockery::mock(CampaignRequestRepository::class); $repository->shouldReceive('findById')->once()->with($id)->andReturn(null); $brandRepository = \Mockery::mock(BrandRepository::class); $brandRepository->shouldNotReceive('findByCode'); $useCase = new FindCampaignRequest($repository, $brandRepository); // WHEN $result = $useCase->execute(new Input(id: $id)); // THEN expect($result)->toBeInstanceOf(CampaignRequestNotFound::class); }); it('throws when the campaign request references a brand that no longer exists', function (): void { // GIVEN $id = CampaignRequestId::generate(); $code = new BrandCode('AAA01'); $campaignRequest = CampaignRequest::hydrate( $id, $code, new Applicant('John', 'Doe', new Email('john.doe@example.com')), new CountryAuthorized(Country::FRANCE), CampaignRequestType::CLUB, new PrintRules(maxPerCustomer: 3), $this->requestedCoupon, CampaignRequestStatus::CREATED, ); $repository = \Mockery::mock(CampaignRequestRepository::class); $repository->shouldReceive('findById')->once()->with($id)->andReturn($campaignRequest); $brandRepository = \Mockery::mock(BrandRepository::class); $brandRepository->shouldReceive('findByCode')->once()->with($code)->andReturn(null); $useCase = new FindCampaignRequest($repository, $brandRepository); // WHEN $action = fn (): Output => $useCase->execute(new Input(id: $id)); // THEN expect($action)->toThrow(BrandNotFoundException::class); }); }); describe('find campaign request use case assertions', function (): void { it('rejects an input of the wrong type', function (): void { // GIVEN $repository = \Mockery::mock(CampaignRequestRepository::class); $brandRepository = \Mockery::mock(BrandRepository::class); $useCase = new FindCampaignRequest($repository, $brandRepository); $invalidInput = new class () implements BaseInput { }; // WHEN $action = fn (): Output => $useCase->execute($invalidInput); // THEN expect($action)->toThrow(\InvalidArgumentException::class); }); });