Commit 70281569 authored by Guy Thouret's avatar Guy Thouret
Browse files

Boost Campaign validate dates delegate - #1201

parent dd38b793
Pipeline #101989915 failed with stages
in 2 minutes and 56 seconds
<?php
namespace Minds\Core\Boost\Delegates;
use Minds\Core\Boost\Network\Campaign;
use Minds\Core\Boost\Network\CampaignException;
class ValidateCampaignDatesDelegate
{
/**
* @param Campaign $campaign
* @return Campaign
* @throws CampaignException
*/
public function onCreate(Campaign $campaign)
{
$start = $this->normaliseStartTime($campaign->getStart());
$end = $this->normaliseEndTime($campaign->getEnd());
$this->validateStartTime($start);
$this->validateEndTime($end);
$this->validateStartAgainstEnd($start, $end);
return $campaign->setStart($start)->setEnd($end);
}
/**
* @param Campaign $campaign
* @param Campaign $campaignRef
* @return Campaign
* @throws CampaignException
*/
public function onUpdate(Campaign $campaign, Campaign $campaignRef)
{
// TODO: Ensure date updates from ref are valid against original campaign budget, etc.
$start = $this->normaliseStartTime($campaignRef->getStart());
$end = $this->normaliseEndTime($campaignRef->getEnd());
$this->validateStartTime($start);
$this->validateEndTime($end);
$this->validateStartAgainstEnd($start, $end);
if (!$campaign->hasStarted()) {
$campaign->setStart($start);
}
if (!$campaign->hasFinished() && $campaign->getEnd() < $end) {
$campaign->setEnd($end);
}
return $campaign;
}
private function normaliseStartTime(int $startTime): int
{
return strtotime(date('Y-m-d', $startTime / 1000) . ' 00:00:00') * 1000;
}
private function normaliseEndTime(int $endTime): int
{
return strtotime(date('Y-m-d', $endTime / 1000) . ' 23:59:59') * 1000;
}
private function validateStartTime(int $startTime): void
{
if ($startTime <= 0) {
throw new CampaignException('Campaign should have a start date');
}
$today = strtotime(date('Y-m-d') . ' 00:00:00') * 1000;
if ($startTime < $today) {
throw new CampaignException('Campaign start should not be in the past');
}
}
private function validateEndTime(int $endTime): void
{
if ($endTime <= 0) {
throw new CampaignException('Campaign should have an end date');
}
}
private function validateStartAgainstEnd(int $start, int $end): void
{
if ($start >= $end) {
throw new CampaignException('Campaign end before starting');
}
$startPlusOneMonth = strtotime('+1 month', $start / 1000) * 1000;
if ($startPlusOneMonth < $end) {
throw new CampaignException('Campaign must not be longer than 1 month');
}
}
}
<?php
namespace Spec\Minds\Core\Boost\Delegates;
use Minds\Core\Boost\Network\Campaign;
use Minds\Core\Boost\Network\CampaignException;
use Minds\Core\Boost\Delegates\ValidateCampaignDatesDelegate;
use PhpSpec\ObjectBehavior;
class ValidateCampaignDatesDelegateSpec extends ObjectBehavior
{
public function it_is_initializable()
{
$this->shouldHaveType(ValidateCampaignDatesDelegate::class);
}
public function it_should_reject_start_date_in_past_on_create(Campaign $campaign)
{
$campaign->getStart()->willReturn(strtotime('-1 day') * 1000);
$campaign->getEnd()->willReturn(strtotime('+3 days') * 1000);
$this->shouldThrow(CampaignException::class)->during('onCreate', [$campaign]);
}
public function it_should_reject_end_date_before_start_date_on_create(Campaign $campaign)
{
$campaign->getStart()->willReturn(strtotime('+2 days') * 1000);
$campaign->getEnd()->willReturn(strtotime('+1 days') * 1000);
$this->shouldThrow(CampaignException::class)->during('onCreate', [$campaign]);
}
public function it_should_adjust_start_and_end_to_first_and_last_timestamps_of_days_on_create(Campaign $campaign)
{
$campaign->getStart()->willReturn(strtotime('today 12:01:31') * 1000);
$campaign->getEnd()->willReturn(strtotime('+1 days 17:32:05') * 1000);
$campaign->setStart(strtotime('today 00:00:00') * 1000)->shouldBeCalled()->willReturn($campaign);
$campaign->setEnd(strtotime('+1 days 23:59:59') * 1000)->shouldBeCalled()->willReturn($campaign);
$this->onCreate($campaign);
}
public function it_should_accept_valid_days_on_create(Campaign $campaign)
{
$campaign->getStart()->willReturn(strtotime('+2 days') * 1000);
$campaign->getEnd()->willReturn(strtotime('+5 days') * 1000);
$campaign->setStart(strtotime('+2 days 00:00:00') * 1000)->shouldBeCalled()->willReturn($campaign);
$campaign->setEnd(strtotime('+5 days 23:59:59') * 1000)->shouldBeCalled()->willReturn($campaign);
$this->onCreate($campaign);
}
public function it_should_reject_campaign_longer_than_one_month(Campaign $campaign)
{
$campaign->getStart()->willReturn(strtotime('+2 days') * 1000);
$campaign->getEnd()->willReturn(strtotime('+34 days') * 1000);
$this->shouldThrow(CampaignException::class)->during('onCreate', [$campaign]);
}
/* public function it_should_validate_dates_are_valid_against_campaign_budget_on_update()
{
// TODO: Not Implemented yet
}*/
public function it_should_not_change_start_date_if_campaign_has_started_on_update(Campaign $campaign, Campaign $campaignRef)
{
$campaign->hasStarted()->shouldBeCalled()->willReturn(true);
$campaign->hasFinished()->shouldBeCalled()->willReturn(true);
$campaignRef->getStart()->willReturn(strtotime('+2 days') * 1000);
$campaignRef->getEnd()->willReturn(strtotime('+5 days') * 1000);
$campaign->getStart()->willReturn(strtotime('+2 days') * 1000);
$campaign->getEnd()->willReturn(strtotime('+5 days') * 1000);
$this->onUpdate($campaign, $campaignRef);
}
public function it_should_change_start_date_if_campaign_has_not_started_on_update(Campaign $campaign, Campaign $campaignRef)
{
$campaign->hasStarted()->shouldBeCalled()->willReturn(false);
$campaign->hasFinished()->shouldBeCalled()->willReturn(false);
$campaignRef->getStart()->willReturn(strtotime('+2 days') * 1000);
$campaignRef->getEnd()->willReturn(strtotime('+5 days') * 1000);
$campaign->getStart()->willReturn(strtotime('+2 days') * 1000);
$campaign->getEnd()->willReturn(strtotime('+5 days') * 1000);
$campaign->setStart(strtotime('+2 days 00:00:00') * 1000)->shouldBeCalled()->willReturn($campaign);
$campaign->setEnd(strtotime('+5 days 23:59:59') * 1000)->shouldBeCalled();
$this->onUpdate($campaign, $campaignRef);
}
public function it_should_only_change_end_date_if_campaign_hasnt_finished_on_update(Campaign $campaign, Campaign $campaignRef)
{
$campaign->hasStarted()->shouldBeCalled()->willReturn(true);
$campaign->hasFinished()->shouldBeCalled()->willReturn(false);
$campaignRef->getStart()->willReturn(strtotime('+2 days') * 1000);
$campaignRef->getEnd()->willReturn(strtotime('+7 days') * 1000);
$campaign->getStart()->willReturn(strtotime('+2 days') * 1000);
$campaign->getEnd()->willReturn(strtotime('+5 days') * 1000);
$campaign->setEnd(strtotime('+7 days 23:59:59') * 1000)->shouldBeCalled();
$this->onUpdate($campaign, $campaignRef);
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment