discount)->toBe($discount) ->and($input->type)->toBe(DiscountType::PERCENT) ->and($input->value)->toBe($value) ->and($input->is_old_price_displayed)->toBeTrue() ->and($input->period)->toBe($period) ->and($input->associatedProductsIds)->toBe(['prod-1', 'prod-2']); }); it('creates a valid UpdateDiscountInput instance with amount', function (): void { // GIVEN $discount = new Discount(); $type = DiscountType::AMOUNT; $value = DiscountValue::fromAmount(new Money(1500, new Currency('EUR'))); // WHEN $input = new UpdateDiscountInput( discount: $discount, type: $type, value: $value, is_old_price_displayed: false, ); // THEN expect($input->type)->toBe(DiscountType::AMOUNT) ->and($input->value)->toBe($value) ->and($input->is_old_price_displayed)->toBeFalse() ->and($input->associatedProductsIds)->toBeEmpty(); }); it('throws when discount value type does not match discount type', function (): void { // GIVEN $discount = new Discount(); $type = DiscountType::AMOUNT; $value = DiscountValue::fromPercentage(15); // WHEN expect(fn () => new UpdateDiscountInput( discount: $discount, type: $type, value: $value, is_old_price_displayed: true, )) // THEN ->toThrow(\InvalidArgumentException::class, 'The discount value type must match the discount type.'); }); it('throws when associatedProductsIds contains non-string items', function (): void { // GIVEN $discount = new Discount(); $type = DiscountType::PERCENT; $value = DiscountValue::fromPercentage(10); // WHEN expect(fn () => new UpdateDiscountInput( discount: $discount, type: $type, value: $value, is_old_price_displayed: true, associatedProductsIds: [123], // @phpstan-ignore argument.type )) // THEN ->toThrow(\InvalidArgumentException::class); }); });