Merge branch 'changes-after-review' into 'refonte'
Changes after review See merge request ldc-web/projets/mesbr!56
This commit is contained in:
commit
4d3c778d17
7 changed files with 68 additions and 100 deletions
|
|
@ -13,7 +13,7 @@ final readonly class Input implements UseCaseInput
|
|||
{
|
||||
public function __construct(
|
||||
public Pagination $pagination,
|
||||
public ?CampaignRequestSortCriteria $sort = null,
|
||||
public CampaignRequestSortCriteria $sort,
|
||||
public ?CampaignRequestFilters $filters = null,
|
||||
) {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,9 +12,18 @@ use Shared\ValueObjects\Money;
|
|||
*/
|
||||
final readonly class MoneyAmount implements \Stringable, Equatable
|
||||
{
|
||||
private const int MIN_FACE_VALUE_IN_CENTS = 1;
|
||||
private const int MAX_FACE_VALUE_IN_CENTS = 300;
|
||||
|
||||
public function __construct(
|
||||
public Money $value,
|
||||
) {
|
||||
if ($this->value->value < self::MIN_FACE_VALUE_IN_CENTS || $this->value->value > self::MAX_FACE_VALUE_IN_CENTS) {
|
||||
throw new \DomainException(sprintf(
|
||||
'Money amount must be between 0.01€ and 3.00€, %s given.',
|
||||
$this->value,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
|
|
|
|||
|
|
@ -17,9 +17,6 @@ use Shared\Enums\Country;
|
|||
|
||||
final readonly class RequestedCoupon
|
||||
{
|
||||
private const int MIN_FACE_VALUE_IN_CENTS = 1;
|
||||
private const int MAX_FACE_VALUE_IN_CENTS = 300;
|
||||
|
||||
/**
|
||||
* @param array<CouponValidityInformation> $couponValidityInformation
|
||||
* @param array<IncoCode> $products
|
||||
|
|
@ -36,21 +33,12 @@ final readonly class RequestedCoupon
|
|||
public ?PrintRules $printRules = null,
|
||||
public ?GS1 $gs1 = null,
|
||||
) {
|
||||
$money = $this->moneyAmount->value;
|
||||
|
||||
foreach ($this->couponValidityInformation as $validityInformation) {
|
||||
if (!$validityInformation instanceof CouponValidityInformation) {
|
||||
throw new \DomainException('Coupon validity information must be CouponValidityInformation instances.');
|
||||
}
|
||||
}
|
||||
|
||||
if ($money->value < self::MIN_FACE_VALUE_IN_CENTS || $money->value > self::MAX_FACE_VALUE_IN_CENTS) {
|
||||
throw new \DomainException(sprintf(
|
||||
'Coupon face value must be between 0.01€ and 3.00€, %s given.',
|
||||
$money,
|
||||
));
|
||||
}
|
||||
|
||||
if (!$this->hasValidityInformationFor(Country::FRANCE)) {
|
||||
throw new \DomainException('A coupon requires validity information for France.');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ interface CampaignRequestRepository extends Repository
|
|||
*/
|
||||
public function findAll(
|
||||
Pagination $pagination,
|
||||
?CampaignRequestSortCriteria $sortCriteria = null,
|
||||
CampaignRequestSortCriteria $sortCriteria,
|
||||
?CampaignRequestFilters $filters = null,
|
||||
): Paginated;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,11 +71,18 @@ describe('list campaigns request use case', function (): void {
|
|||
new PrintRules(maxPerCustomer: 3),
|
||||
new GS1('01234567890128', BarcodeFormat::EAN13)
|
||||
);
|
||||
|
||||
$this->pagination = Pagination::firstPage();
|
||||
|
||||
$this->sort = new CampaignRequestSortCriteria(
|
||||
clauses: [
|
||||
new CampaignRequestSortClause(field: CampaignRequestSortField::CreatedAt, direction: \SortDirection::Descending),
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
it('maps repository campaigns request to list items, preserving pagination and sort', function (): void {
|
||||
// GIVEN
|
||||
$pagination = Pagination::firstPage();
|
||||
$campaignRequest1 = CampaignRequest::hydrate(
|
||||
CampaignRequestId::generate(),
|
||||
new BrandCode('AAA01'),
|
||||
|
|
@ -94,7 +101,7 @@ describe('list campaigns request use case', function (): void {
|
|||
$this->couponB,
|
||||
CampaignRequestStatus::CREATED,
|
||||
);
|
||||
$paginated = new Paginated($pagination, [$campaignRequest1, $campaignRequest2], 2);
|
||||
$paginated = new Paginated($this->pagination, [$campaignRequest1, $campaignRequest2], 2);
|
||||
|
||||
$sort = new CampaignRequestSortCriteria(
|
||||
clauses: [
|
||||
|
|
@ -103,12 +110,12 @@ describe('list campaigns request use case', function (): void {
|
|||
]
|
||||
);
|
||||
$filters = new CampaignRequestFilters($campaignRequest2->brandCode, CampaignRequestStatus::CREATED);
|
||||
$input = new Input(pagination: $pagination, sort: $sort, filters: $filters);
|
||||
$input = new Input(pagination: $this->pagination, sort: $sort, filters: $filters);
|
||||
|
||||
$repository = \Mockery::mock(CampaignRequestRepository::class);
|
||||
$repository->shouldReceive('findAll')
|
||||
->once()
|
||||
->with($pagination, CampaignRequestSortCriteria::class, CampaignRequestFilters::class)
|
||||
->with($this->pagination, CampaignRequestSortCriteria::class, CampaignRequestFilters::class)
|
||||
->andReturn($paginated);
|
||||
|
||||
$useCase = new ListCampaignsRequest($repository);
|
||||
|
|
@ -128,12 +135,11 @@ describe('list campaigns request use case', function (): void {
|
|||
->and($items[0]->campaignType)->toBe($campaignRequest1->campaignType)
|
||||
->and($items[0]->status)->toBe($campaignRequest1->status)
|
||||
->and($result->campaignsRequest->getTotal())->toBe(2)
|
||||
->and($result->campaignsRequest->getPagination())->toBe($pagination);
|
||||
->and($result->campaignsRequest->getPagination())->toBe($this->pagination);
|
||||
});
|
||||
|
||||
it('lists campaigns request with filters but without sort', function (): void {
|
||||
it('lists campaigns request with filters', function (): void {
|
||||
// GIVEN
|
||||
$pagination = Pagination::firstPage();
|
||||
$campaignRequest = CampaignRequest::hydrate(
|
||||
CampaignRequestId::generate(),
|
||||
new BrandCode('AAA01'),
|
||||
|
|
@ -143,15 +149,15 @@ describe('list campaigns request use case', function (): void {
|
|||
$this->couponA,
|
||||
CampaignRequestStatus::CREATED,
|
||||
);
|
||||
$paginated = new Paginated($pagination, [$campaignRequest], 1);
|
||||
$paginated = new Paginated($this->pagination, [$campaignRequest], 1);
|
||||
|
||||
$filters = new CampaignRequestFilters($campaignRequest->brandCode, CampaignRequestStatus::CREATED);
|
||||
$input = new Input(pagination: $pagination, filters: $filters);
|
||||
$input = new Input(pagination: $this->pagination, sort: $this->sort, filters: $filters);
|
||||
|
||||
$repository = \Mockery::mock(CampaignRequestRepository::class);
|
||||
$repository->shouldReceive('findAll')
|
||||
->once()
|
||||
->with($pagination, null, $filters)
|
||||
->with($this->pagination, $this->sort, $filters)
|
||||
->andReturn($paginated);
|
||||
|
||||
$useCase = new ListCampaignsRequest($repository);
|
||||
|
|
@ -167,12 +173,11 @@ describe('list campaigns request use case', function (): void {
|
|||
->and($items[0]->name)->toBe($campaignRequest->name)
|
||||
->and($items[0]->status)->toBe($campaignRequest->status)
|
||||
->and($result->campaignsRequest->getTotal())->toBe(1)
|
||||
->and($result->campaignsRequest->getPagination())->toBe($pagination);
|
||||
->and($result->campaignsRequest->getPagination())->toBe($this->pagination);
|
||||
});
|
||||
|
||||
it('lists campaigns request with sort but without filters', function (): void {
|
||||
// GIVEN
|
||||
$pagination = Pagination::firstPage();
|
||||
$campaignRequest1 = CampaignRequest::hydrate(
|
||||
CampaignRequestId::generate(),
|
||||
new BrandCode('AAA01'),
|
||||
|
|
@ -191,19 +196,19 @@ describe('list campaigns request use case', function (): void {
|
|||
$this->couponB,
|
||||
CampaignRequestStatus::CREATED,
|
||||
);
|
||||
$paginated = new Paginated($pagination, [$campaignRequest2, $campaignRequest1], 2);
|
||||
$paginated = new Paginated($this->pagination, [$campaignRequest2, $campaignRequest1], 2);
|
||||
|
||||
$sort = new CampaignRequestSortCriteria(
|
||||
clauses: [
|
||||
new CampaignRequestSortClause(field: CampaignRequestSortField::BrandCode, direction: \SortDirection::Descending),
|
||||
]
|
||||
);
|
||||
$input = new Input(pagination: $pagination, sort: $sort);
|
||||
$input = new Input(pagination: $this->pagination, sort: $sort);
|
||||
|
||||
$repository = \Mockery::mock(CampaignRequestRepository::class);
|
||||
$repository->shouldReceive('findAll')
|
||||
->once()
|
||||
->with($pagination, $sort, null)
|
||||
->with($this->pagination, $sort, null)
|
||||
->andReturn($paginated);
|
||||
|
||||
$useCase = new ListCampaignsRequest($repository);
|
||||
|
|
@ -217,19 +222,18 @@ describe('list campaigns request use case', function (): void {
|
|||
->and($items[0]->brandCode)->toBe($campaignRequest2->brandCode)
|
||||
->and($items[1]->brandCode)->toBe($campaignRequest1->brandCode)
|
||||
->and($result->campaignsRequest->getTotal())->toBe(2)
|
||||
->and($result->campaignsRequest->getPagination())->toBe($pagination);
|
||||
->and($result->campaignsRequest->getPagination())->toBe($this->pagination);
|
||||
});
|
||||
|
||||
it('returns an empty list without error when there are no campaigns request', function (): void {
|
||||
// GIVEN
|
||||
$pagination = Pagination::firstPage();
|
||||
$paginated = new Paginated($pagination, [], 0);
|
||||
$input = new Input(pagination: $pagination);
|
||||
$paginated = new Paginated($this->pagination, [], 0);
|
||||
$input = new Input(pagination: $this->pagination, sort: $this->sort);
|
||||
|
||||
$repository = \Mockery::mock(CampaignRequestRepository::class);
|
||||
$repository->shouldReceive('findAll')
|
||||
->once()
|
||||
->with($pagination, null, null)
|
||||
->with($this->pagination, $this->sort, null)
|
||||
->andReturn($paginated);
|
||||
|
||||
$useCase = new ListCampaignsRequest($repository);
|
||||
|
|
|
|||
|
|
@ -12,8 +12,11 @@ covers(MoneyAmount::class);
|
|||
|
||||
describe('money amount', function (): void {
|
||||
beforeEach(function (): void {
|
||||
$this->money = new Money(Currency::EUR, 300);
|
||||
$this->secondMoney = new Money(Currency::EUR, 500);
|
||||
$this->money = new Money(Currency::EUR, 300);
|
||||
$this->secondMoney = new Money(Currency::EUR, 200);
|
||||
$this->minimumMoney = new Money(Currency::EUR, 1);
|
||||
$this->zeroMoney = new Money(Currency::EUR, 0);
|
||||
$this->aboveLimitMoney = new Money(Currency::EUR, 301);
|
||||
});
|
||||
|
||||
it('wraps a Money value', function (): void {
|
||||
|
|
@ -54,4 +57,32 @@ describe('money amount', function (): void {
|
|||
// THEN
|
||||
expect((string) $amount)->toBe((string) $amount->value);
|
||||
});
|
||||
|
||||
it('accepts the minimum amount of 0.01€', function (): void {
|
||||
// GIVEN / WHEN
|
||||
$amount = new MoneyAmount($this->minimumMoney);
|
||||
|
||||
// THEN
|
||||
expect($amount->value)->toBe($this->minimumMoney);
|
||||
});
|
||||
|
||||
it('accepts the maximum amount of 3.00€', function (): void {
|
||||
// GIVEN / WHEN
|
||||
$amount = new MoneyAmount($this->money);
|
||||
|
||||
// THEN
|
||||
expect($amount->value)->toBe($this->money);
|
||||
});
|
||||
|
||||
it('throws when the amount is zero', function (): void {
|
||||
// GIVEN / WHEN / THEN
|
||||
expect(fn () => new MoneyAmount($this->zeroMoney))
|
||||
->toThrow(\DomainException::class, 'Money amount must be between 0.01€ and 3.00€');
|
||||
});
|
||||
|
||||
it('throws when the amount is above 3.00€', function (): void {
|
||||
// GIVEN / WHEN / THEN
|
||||
expect(fn () => new MoneyAmount($this->aboveLimitMoney))
|
||||
->toThrow(\DomainException::class, 'Money amount must be between 0.01€ and 3.00€');
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -188,70 +188,6 @@ describe('requested coupon', function (): void {
|
|||
))->toThrow(\DomainException::class, 'Coupon validity information must be CouponValidityInformation instances.');
|
||||
});
|
||||
|
||||
it('accepts the minimum face value of 0.01€', function (): void {
|
||||
// GIVEN
|
||||
$moneyAmount = new MoneyAmount(new Money(Currency::EUR, 1));
|
||||
|
||||
// WHEN
|
||||
$coupon = new RequestedCoupon(
|
||||
name: $this->name,
|
||||
quantity: $this->quantity,
|
||||
diffusion: $this->diffusion,
|
||||
moneyAmount: $moneyAmount,
|
||||
processingCode: $this->processingCode,
|
||||
couponValidity: $this->couponValidity,
|
||||
couponValidityInformation: $this->couponValidityInformation,
|
||||
);
|
||||
|
||||
// THEN
|
||||
expect($coupon->moneyAmount)->toBe($moneyAmount);
|
||||
});
|
||||
|
||||
it('accepts the maximum face value of 3.00€', function (): void {
|
||||
// GIVEN
|
||||
$moneyAmount = new MoneyAmount(new Money(Currency::EUR, 300));
|
||||
|
||||
// WHEN
|
||||
$coupon = new RequestedCoupon(
|
||||
name: $this->name,
|
||||
quantity: $this->quantity,
|
||||
diffusion: $this->diffusion,
|
||||
moneyAmount: $moneyAmount,
|
||||
processingCode: $this->processingCode,
|
||||
couponValidity: $this->couponValidity,
|
||||
couponValidityInformation: $this->couponValidityInformation,
|
||||
);
|
||||
|
||||
// THEN
|
||||
expect($coupon->moneyAmount)->toBe($moneyAmount);
|
||||
});
|
||||
|
||||
it('throws when the face value is zero', function (): void {
|
||||
// GIVEN / WHEN / THEN
|
||||
expect(fn () => new RequestedCoupon(
|
||||
name: $this->name,
|
||||
quantity: $this->quantity,
|
||||
diffusion: $this->diffusion,
|
||||
moneyAmount: new MoneyAmount(new Money(Currency::EUR, 0)),
|
||||
processingCode: $this->processingCode,
|
||||
couponValidity: $this->couponValidity,
|
||||
couponValidityInformation: $this->couponValidityInformation,
|
||||
))->toThrow(\DomainException::class, 'Coupon face value must be between 0.01€ and 3.00€');
|
||||
});
|
||||
|
||||
it('throws when the face value is above 3.00€', function (): void {
|
||||
// GIVEN / WHEN / THEN
|
||||
expect(fn () => new RequestedCoupon(
|
||||
name: $this->name,
|
||||
quantity: $this->quantity,
|
||||
diffusion: $this->diffusion,
|
||||
moneyAmount: new MoneyAmount(new Money(Currency::EUR, 301)),
|
||||
processingCode: $this->processingCode,
|
||||
couponValidity: $this->couponValidity,
|
||||
couponValidityInformation: $this->couponValidityInformation,
|
||||
))->toThrow(\DomainException::class, 'Coupon face value must be between 0.01€ and 3.00€');
|
||||
});
|
||||
|
||||
it('throws when a gs1 coupon has no benelux validity information', function (): void {
|
||||
// GIVEN / WHEN / THEN
|
||||
expect(fn () => new RequestedCoupon(
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue