From d0145fc4e1a62f7b9c8b16a0ac40d05132234acd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Podkalicki?= <38037054+PawelPodkalicki@users.noreply.github.com> Date: Thu, 13 Apr 2023 12:09:42 +0200 Subject: [PATCH 1/3] Fix errors and warnings in tests (#69) * Fix errors and warnings in tests * increase coverage --- composer.lock | 21 +-- .../Domain/Service/PaymentCalculatorTest.php | 142 +++++++++++++++++- .../DoctrineEventRepositoryTest.php | 8 +- .../Repository/RepositoryTestCase.php | 3 +- tests/UI/Controller/ReportControllerTest.php | 11 +- 5 files changed, 165 insertions(+), 20 deletions(-) diff --git a/composer.lock b/composer.lock index 0c2a07e..4c26b13 100644 --- a/composer.lock +++ b/composer.lock @@ -5739,20 +5739,20 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.27", + "version": "9.6.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "a2bc7ffdca99f92d959b3f2270529334030bba38" + "reference": "b65d59a059d3004a040c16a82e07bbdf6cfdd115" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a2bc7ffdca99f92d959b3f2270529334030bba38", - "reference": "a2bc7ffdca99f92d959b3f2270529334030bba38", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b65d59a059d3004a040c16a82e07bbdf6cfdd115", + "reference": "b65d59a059d3004a040c16a82e07bbdf6cfdd115", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.3.1", + "doctrine/instantiator": "^1.3.1 || ^2", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", @@ -5781,8 +5781,8 @@ "sebastian/version": "^3.0.2" }, "suggest": { - "ext-soap": "*", - "ext-xdebug": "*" + "ext-soap": "To be able to generate mocks based on WSDL files", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" }, "bin": [ "phpunit" @@ -5790,7 +5790,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "9.5-dev" + "dev-master": "9.6-dev" } }, "autoload": { @@ -5821,7 +5821,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.27" + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.6" }, "funding": [ { @@ -5837,7 +5838,7 @@ "type": "tidelift" } ], - "time": "2022-12-09T07:31:23+00:00" + "time": "2023-03-27T11:43:46+00:00" }, { "name": "qossmic/deptrac-shim", diff --git a/tests/Domain/Service/PaymentCalculatorTest.php b/tests/Domain/Service/PaymentCalculatorTest.php index aa92871..c329cb4 100644 --- a/tests/Domain/Service/PaymentCalculatorTest.php +++ b/tests/Domain/Service/PaymentCalculatorTest.php @@ -981,7 +981,7 @@ public function testAutoCpmEmptyHistory(): void $payments = (new PaymentCalculator($campaigns, $bidStrategies, $repository, $config)) ->calculate($reportId, [self::viewEvent()]); - $this->assertCount(1, $payments); + $this->assertCount(1, [...$payments]); } public function testAutoCpmNoScore(): void @@ -1165,7 +1165,7 @@ public function testAutoCpmNoViewIncreaseOnGreaterCpm(): void $this->assertLessThan($previousCampaignCost->getScore(), $campaignCost->getScore()); $this->assertGreaterThan($previousCampaignCost->getMaxCpm(), $campaignCost->getMaxCpm()); $this->assertGreaterThan(1.0, $campaignCost->getCpmFactor()); - $this->assertEquals($previousCampaignCost->getViews(), $campaignCost->getViews()); + $this->assertEquals(5100, $campaignCost->getViews()); $this->assertGreaterThan($previousCampaignCost->getViewsCost(), $campaignCost->getViewsCost()); $this->assertEquals(0, $campaignCost->getClicks()); $this->assertEquals(0, $campaignCost->getClicksCost()); @@ -1177,7 +1177,143 @@ public function testAutoCpmNoViewIncreaseOnGreaterCpm(): void $payments = (new PaymentCalculator($campaigns, $bidStrategies, $repository, $config)) ->calculate($reportId, self::uniqueViewEvents($views)); - $this->assertCount($views, $payments); + $this->assertCount($views, [...$payments]); + } + + public function testAutoCpmSmallViewIncreaseOnGreaterCpm(): void + { + $reportId = 7200; + $config = new PaymentCalculatorConfig(); + $campaigns = new CampaignCollection( + self::campaign( + ['budget' => 190 * 10 ** 11, 'max_cpm' => null, 'max_cpc' => null], + [self::banner()], + [self::conversion()], + ) + ); + $bidStrategies = new BidStrategyCollection(); + + $repository = $this->createMock(CampaignCostRepository::class); + $previousViews = 5100; + $previousScore = $previousViews ** 2 / (4900 * $config->getAutoCpmDefault() / 1000); + $previousMaxCpm = (int)(1.1 * $config->getAutoCpmDefault()); + $previousViewsCost = (int)($previousViews * 1.1 * $config->getAutoCpmDefault() / 1000); + + $views = $previousViews + 200; + + $previousCampaignCost = new CampaignCost( + $reportId - 3600, + new Id(self::CAMPAIGN_ID), + $previousScore, + $previousMaxCpm, + 1.1, + $previousViews, + $previousViewsCost, + 0, + 0, + 0, + 0 + ); + $repository + ->expects($this->once()) + ->method('fetch') + ->with($reportId, new Id(self::CAMPAIGN_ID)) + ->willReturn($previousCampaignCost); + $repository + ->expects($this->once()) + ->method('saveAll') + ->willReturnCallback(function ($campaignCostCollection) use ($reportId, $config, $previousCampaignCost) { + $this->assertTrue($campaignCostCollection instanceof CampaignCostCollection); + $this->assertCount(1, $campaignCostCollection); + + /** @var CampaignCost $campaignCost */ + $campaignCost = $campaignCostCollection->first(); + $this->assertEquals($reportId, $campaignCost->getReportId()); + $this->assertEquals(self::CAMPAIGN_ID, $campaignCost->getCampaignId()->toString()); + $this->assertLessThan($previousCampaignCost->getScore(), $campaignCost->getScore()); + $this->assertLessThan($previousCampaignCost->getMaxCpm(), $campaignCost->getMaxCpm()); + $this->assertLessThan(1.0, $campaignCost->getCpmFactor()); + $this->assertEquals(5300, $campaignCost->getViews()); + $this->assertLessThan($previousCampaignCost->getViewsCost(), $campaignCost->getViewsCost()); + $this->assertEquals(0, $campaignCost->getClicks()); + $this->assertEquals(0, $campaignCost->getClicksCost()); + $this->assertEquals(0, $campaignCost->getConversions()); + $this->assertEquals(0, $campaignCost->getConversionsCost()); + + return 1; + }); + + $payments = (new PaymentCalculator($campaigns, $bidStrategies, $repository, $config)) + ->calculate($reportId, self::uniqueViewEvents($views)); + $this->assertCount($views, [...$payments]); + } + + public function testAutoCpmBigViewIncreaseOnGreaterCpm(): void + { + $reportId = 7200; + $config = new PaymentCalculatorConfig(); + $campaigns = new CampaignCollection( + self::campaign( + ['budget' => 190 * 10 ** 11, 'max_cpm' => null, 'max_cpc' => null], + [self::banner()], + [self::conversion()], + ) + ); + $bidStrategies = new BidStrategyCollection(); + + $repository = $this->createMock(CampaignCostRepository::class); + $previousViews = 5100; + $previousScore = $previousViews ** 2 / (4900 * $config->getAutoCpmDefault() / 1000); + $previousMaxCpm = (int)(1.1 * $config->getAutoCpmDefault()); + $previousViewsCost = (int)($previousViews * 1.1 * $config->getAutoCpmDefault() / 1000); + + $views = $previousViews + 900; + + $previousCampaignCost = new CampaignCost( + $reportId - 3600, + new Id(self::CAMPAIGN_ID), + $previousScore, + $previousMaxCpm, + 1.1, + $previousViews, + $previousViewsCost, + 0, + 0, + 0, + 0 + ); + $repository + ->expects($this->once()) + ->method('fetch') + ->with($reportId, new Id(self::CAMPAIGN_ID)) + ->willReturn($previousCampaignCost); + $repository + ->expects($this->once()) + ->method('saveAll') + ->willReturnCallback(function ($campaignCostCollection) use ($reportId, $config, $previousCampaignCost) { + $this->assertTrue($campaignCostCollection instanceof CampaignCostCollection); + $this->assertCount(1, $campaignCostCollection); + + /** @var CampaignCost $campaignCost */ + $campaignCost = $campaignCostCollection->first(); + $this->assertEquals($reportId, $campaignCost->getReportId()); + $this->assertEquals(self::CAMPAIGN_ID, $campaignCost->getCampaignId()->toString()); + $this->assertGreaterThan($previousCampaignCost->getScore(), $campaignCost->getScore()); + $this->assertGreaterThan($previousCampaignCost->getMaxCpm(), $campaignCost->getMaxCpm()); + $this->assertGreaterThan(1.0, $campaignCost->getCpmFactor()); + $this->assertEquals(6000, $campaignCost->getViews()); + $this->assertGreaterThan($previousCampaignCost->getViewsCost(), $campaignCost->getViewsCost()); + $this->assertEquals(0, $campaignCost->getClicks()); + $this->assertEquals(0, $campaignCost->getClicksCost()); + $this->assertEquals(0, $campaignCost->getConversions()); + $this->assertEquals(0, $campaignCost->getConversionsCost()); + + return 1; + }); + + $payments = (new PaymentCalculator($campaigns, $bidStrategies, $repository, $config)) + ->calculate($reportId, self::uniqueViewEvents($views)); + $this->assertCount($views, [...$payments]); } /** diff --git a/tests/Infrastructure/Repository/DoctrineEventRepositoryTest.php b/tests/Infrastructure/Repository/DoctrineEventRepositoryTest.php index 9f12c76..482cbfc 100644 --- a/tests/Infrastructure/Repository/DoctrineEventRepositoryTest.php +++ b/tests/Infrastructure/Repository/DoctrineEventRepositoryTest.php @@ -58,9 +58,11 @@ public function testRepository(): void ); $this->assertCount( 4, - $repository->fetchByTime( - DateTimeHelper::fromTimestamp($timestamp - 70), - DateTimeHelper::fromTimestamp($timestamp - 30) + self::iterableToArray( + $repository->fetchByTime( + DateTimeHelper::fromTimestamp($timestamp - 70), + DateTimeHelper::fromTimestamp($timestamp - 30), + ) ) ); $this->assertEmpty( diff --git a/tests/Infrastructure/Repository/RepositoryTestCase.php b/tests/Infrastructure/Repository/RepositoryTestCase.php index 830023f..fca4c4e 100644 --- a/tests/Infrastructure/Repository/RepositoryTestCase.php +++ b/tests/Infrastructure/Repository/RepositoryTestCase.php @@ -10,8 +10,7 @@ abstract class RepositoryTestCase extends KernelTestCase { - /** @var Connection */ - protected $connection; + protected Connection $connection; protected function setUp(): void { diff --git a/tests/UI/Controller/ReportControllerTest.php b/tests/UI/Controller/ReportControllerTest.php index 022b20c..dccd6a1 100644 --- a/tests/UI/Controller/ReportControllerTest.php +++ b/tests/UI/Controller/ReportControllerTest.php @@ -4,6 +4,7 @@ namespace App\Tests\UI\Controller; +use DateTimeImmutable; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Component\BrowserKit\AbstractBrowser; @@ -33,7 +34,7 @@ public function testGetNoneExistingReports(): void public function testGetReports(): void { - $timestamp = 1673344800; + $timestamp = $this->getHourTimestamp(); $client = self::createClient(); $this->addEvents($client, $timestamp - 200, $timestamp + 8000); @@ -67,7 +68,7 @@ public function testGetReports(): void public function testGetReportsByIds(): void { - $timestamp = 1673344800; + $timestamp = $this->getHourTimestamp(); $client = self::createClient(); $this->addEvents($client, $timestamp - 200, $timestamp + 8000); @@ -123,4 +124,10 @@ private function getReports(AbstractBrowser $client, array $parameters = []): Ab $client->request('GET', '/api/v1/reports?' . http_build_query($parameters)); return $client; } + + private function getHourTimestamp(): int + { + $timestamp = (new DateTimeImmutable('-1 day'))->getTimestamp(); + return (int)floor($timestamp / 3600) * 3600; + } } From 68de8622a46d24e0da628a88c6f2dea719f1a488 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Podkalicki?= <38037054+PawelPodkalicki@users.noreply.github.com> Date: Tue, 30 May 2023 15:58:27 +0200 Subject: [PATCH 2/3] Reject events with invalid ads.txt (#70) * extend database * add ads_txt --- CHANGELOG.md | 2 ++ src/Application/DTO/EventUpdateDTO.php | 1 + src/Domain/Model/Event.php | 17 ++++----- src/Domain/Model/Impression.php | 17 ++++----- src/Domain/Model/ImpressionCase.php | 29 +++++++-------- src/Domain/Model/Payment.php | 21 ++++------- src/Domain/Service/PaymentCalculator.php | 2 ++ src/Domain/ValueObject/Context.php | 36 +++++++++++++------ src/Domain/ValueObject/Id.php | 3 +- src/Domain/ValueObject/PaymentStatus.php | 6 ++-- src/Infrastructure/Mapper/EventMapper.php | 3 ++ .../Migrations/Version20230413090625.php | 36 +++++++++++++++++++ .../Command/ReportCalculateCommandTest.php | 1 + tests/Application/DTO/EventUpdateDTOTest.php | 5 +++ tests/Domain/Model/ClickEventTest.php | 3 +- tests/Domain/Model/ConversionEventTest.php | 3 +- tests/Domain/Model/EventTest.php | 3 +- tests/Domain/Model/ImpressionCaseTest.php | 3 +- tests/Domain/Model/ImpressionTest.php | 3 +- tests/Domain/Model/ViewEventTest.php | 3 +- .../Domain/Service/PaymentCalculatorTest.php | 14 +++++--- tests/Domain/ValueObject/ContextTest.php | 9 ++--- .../DoctrineEventRepositoryTest.php | 5 ++- tests/UI/Controller/EventControllerTest.php | 4 +++ 24 files changed, 154 insertions(+), 75 deletions(-) create mode 100644 src/Infrastructure/Migrations/Version20230413090625.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 06f416e..fd26bd5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Added +- Reject events without valid ads.txt ## [1.5.0] - 2022-01-25 ### Added diff --git a/src/Application/DTO/EventUpdateDTO.php b/src/Application/DTO/EventUpdateDTO.php index faa8b71..6034458 100644 --- a/src/Application/DTO/EventUpdateDTO.php +++ b/src/Application/DTO/EventUpdateDTO.php @@ -173,6 +173,7 @@ protected function createImpressionModel(array $input): Impression $context = new Context( $input['human_score'], $input['page_rank'], + $input['ads_txt'] ?? null, $input['keywords'] ?? [], $input['context'] ?? [] ); diff --git a/src/Domain/Model/Event.php b/src/Domain/Model/Event.php index 1bcab44..83bf0ce 100644 --- a/src/Domain/Model/Event.php +++ b/src/Domain/Model/Event.php @@ -12,17 +12,13 @@ abstract class Event { - /** @var Id */ - private $id; + private Id $id; - /** @var EventType */ - private $type; + private EventType $type; - /** @var DateTimeInterface */ - private $time; + private DateTimeInterface $time; - /** @var ImpressionCase */ - private $case; + private ImpressionCase $case; public function __construct( Id $id, @@ -143,4 +139,9 @@ public function getPageRank(): float { return $this->case->getPageRank(); } + + public function getAdsTxt(): ?int + { + return $this->case->getAdsTxt(); + } } diff --git a/src/Domain/Model/Impression.php b/src/Domain/Model/Impression.php index 4771cb6..deb960a 100644 --- a/src/Domain/Model/Impression.php +++ b/src/Domain/Model/Impression.php @@ -9,17 +9,13 @@ final class Impression { - /** @var Id */ - private $id; + private Id $id; - /** @var Id */ - private $trackingId; + private Id $trackingId; - /** @var Id */ - private $userId; + private Id $userId; - /** @var Context */ - private $context; + private Context $context; public function __construct( Id $id, @@ -72,4 +68,9 @@ public function getPageRank(): float { return $this->context->getPageRank(); } + + public function getAdsTxt(): ?int + { + return $this->context->getAdsTxt(); + } } diff --git a/src/Domain/Model/ImpressionCase.php b/src/Domain/Model/ImpressionCase.php index a3ddc73..b241034 100644 --- a/src/Domain/Model/ImpressionCase.php +++ b/src/Domain/Model/ImpressionCase.php @@ -10,29 +10,21 @@ final class ImpressionCase { - /** @var Id */ - private $id; + private Id $id; - /** @var DateTimeInterface */ - private $time; + private DateTimeInterface $time; - /** @var Id */ - private $publisherId; + private Id $publisherId; - /** @var ?Id */ - private $zoneId; + private ?Id $zoneId; - /** @var Id */ - private $advertiserId; + private Id $advertiserId; - /** @var Id */ - private $campaignId; + private Id $campaignId; - /** @var Id */ - private $bannerId; + private Id $bannerId; - /** @var Impression */ - private $impression; + private Impression $impression; public function __construct( Id $id, @@ -133,4 +125,9 @@ public function getPageRank(): float { return $this->impression->getPageRank(); } + + public function getAdsTxt(): ?int + { + return $this->impression->getAdsTxt(); + } } diff --git a/src/Domain/Model/Payment.php b/src/Domain/Model/Payment.php index 2d5c979..5d117b8 100644 --- a/src/Domain/Model/Payment.php +++ b/src/Domain/Model/Payment.php @@ -11,20 +11,15 @@ final class Payment { - /** @var EventType */ - private $eventType; + private EventType $eventType; - /** @var Id */ - private $eventId; + private Id $eventId; - /** @var PaymentStatus */ - private $status; + private PaymentStatus $status; - /** @var ?int */ - private $value; + private ?int $value; - /** @var int */ - private $reportId; + private ?int $reportId; public function __construct( EventType $eventType, @@ -37,9 +32,7 @@ public function __construct( $this->eventId = $eventId; $this->status = $status; $this->value = $value; - if ($reportId !== null) { - $this->reportId = $reportId; - } + $this->reportId = $reportId; } public function getReportId(): int @@ -81,7 +74,7 @@ public function isAccepted(): bool return $this->status->isAccepted(); } - public function getValue() + public function getValue(): ?int { return $this->value; } diff --git a/src/Domain/Service/PaymentCalculator.php b/src/Domain/Service/PaymentCalculator.php index faafed1..56f6819 100644 --- a/src/Domain/Service/PaymentCalculator.php +++ b/src/Domain/Service/PaymentCalculator.php @@ -149,6 +149,8 @@ private function validateEvent(array $event): int if (null === $campaign) { return PaymentStatus::CAMPAIGN_NOT_FOUND; + } elseif (0 === $event['ads_txt']) { + return PaymentStatus::INVALID_ADS_TXT; } $caseTime = DateTimeHelper::fromString($event['case_time']); diff --git a/src/Domain/ValueObject/Context.php b/src/Domain/ValueObject/Context.php index 2572be4..68e78ce 100644 --- a/src/Domain/ValueObject/Context.php +++ b/src/Domain/ValueObject/Context.php @@ -8,20 +8,23 @@ class Context { - /** @var float */ - private $humanScore; + private float $humanScore; - /** @var float */ - private $pageRank; + private float $pageRank; - /** @var array */ - private $keywords; + private ?int $adsTxt; - /* @var array */ - private $data; + private array $keywords; - public function __construct(float $humanScore, float $pageRank, array $keywords = [], array $data = []) - { + private array $data; + + public function __construct( + float $humanScore, + float $pageRank, + ?int $adsTxt = null, + array $keywords = [], + array $data = [], + ) { if ($humanScore < 0 || $humanScore > 1) { throw InvalidArgumentException::fromArgument( 'human score', @@ -36,9 +39,17 @@ public function __construct(float $humanScore, float $pageRank, array $keywords 'Must be in the range of <0, 1> or equal -1.' ); } + if (null !== $adsTxt && 0 !== $adsTxt && 1 !== $adsTxt) { + throw InvalidArgumentException::fromArgument( + 'ads txt', + (string)$adsTxt, + 'Must be 0, 1 or null.' + ); + } $this->humanScore = $humanScore; $this->pageRank = $pageRank; + $this->adsTxt = $adsTxt; $this->keywords = $keywords; $this->data = $data; } @@ -53,6 +64,11 @@ public function getPageRank(): float return $this->pageRank; } + public function getAdsTxt(): ?int + { + return $this->adsTxt; + } + public function getKeywords(): array { return $this->keywords; diff --git a/src/Domain/ValueObject/Id.php b/src/Domain/ValueObject/Id.php index ebce102..8bf8d45 100644 --- a/src/Domain/ValueObject/Id.php +++ b/src/Domain/ValueObject/Id.php @@ -10,8 +10,7 @@ class Id { - /** @var string */ - private $id; + private string $id; public function __construct(string $id) { diff --git a/src/Domain/ValueObject/PaymentStatus.php b/src/Domain/ValueObject/PaymentStatus.php index 96224c6..16550e8 100644 --- a/src/Domain/ValueObject/PaymentStatus.php +++ b/src/Domain/ValueObject/PaymentStatus.php @@ -22,6 +22,8 @@ final class PaymentStatus public const CONVERSION_NOT_FOUND = 6; + public const INVALID_ADS_TXT = 7; + private static $labels = [ self::ACCEPTED => 'accepted', self::CAMPAIGN_NOT_FOUND => 'rejected:campaign_not_found', @@ -30,10 +32,10 @@ final class PaymentStatus self::BANNER_NOT_FOUND => 'rejected:banner_not_found', self::CAMPAIGN_OUTDATED => 'rejected:campaign_outdated', self::CONVERSION_NOT_FOUND => 'rejected:conversion_not_found', + self::INVALID_ADS_TXT => 'rejected:invalid_ads_txt', ]; - /** @var ?int */ - private $status; + private ?int $status; public function __construct(?int $status = null) { diff --git a/src/Infrastructure/Mapper/EventMapper.php b/src/Infrastructure/Mapper/EventMapper.php index c27f2c1..cf1c8ee 100644 --- a/src/Infrastructure/Mapper/EventMapper.php +++ b/src/Infrastructure/Mapper/EventMapper.php @@ -30,6 +30,7 @@ public static function map(Event $event): array 'user_id' => $event->getUserId()->toBin(), 'human_score' => $event->getHumanScore(), 'page_rank' => $event->getPageRank(), + 'ads_txt' => $event->getAdsTxt(), 'keywords' => $event->getKeywords(), 'context' => $event->getContextData(), ]; @@ -52,6 +53,7 @@ public static function types(): array 'user_id' => Types::BINARY, 'human_score' => Types::FLOAT, 'page_rank' => Types::FLOAT, + 'ads_txt' => Types::INTEGER, 'keywords' => Types::JSON, 'context' => Types::JSON, ]; @@ -75,6 +77,7 @@ public static function fillRaw(array $row): array 'user_id' => bin2hex($row['user_id']), 'human_score' => (float)$row['human_score'], 'page_rank' => (float)$row['page_rank'], + 'ads_txt' => $row['ads_txt'], 'keywords' => json_decode($row['keywords'], true), 'context' => json_decode($row['context'], true), ]; diff --git a/src/Infrastructure/Migrations/Version20230413090625.php b/src/Infrastructure/Migrations/Version20230413090625.php new file mode 100644 index 0000000..5a84f3b --- /dev/null +++ b/src/Infrastructure/Migrations/Version20230413090625.php @@ -0,0 +1,36 @@ +addSql(sprintf('ALTER TABLE %s ADD COLUMN ads_txt TINYINT(1) NULL DEFAULT NULL', $table)); + } + } + + public function down(Schema $schema): void + { + foreach (self::EVENT_TABLES as $table) { + $this->addSql(sprintf('ALTER TABLE %s DROP COLUMN ads_txt', $table)); + } + } +} diff --git a/tests/Application/Command/ReportCalculateCommandTest.php b/tests/Application/Command/ReportCalculateCommandTest.php index eb13b19..a7a6e3f 100644 --- a/tests/Application/Command/ReportCalculateCommandTest.php +++ b/tests/Application/Command/ReportCalculateCommandTest.php @@ -162,6 +162,7 @@ private static function event(int $id): array 'human_score' => 0.9, 'keywords' => ['r1' => ['r1_v1'], 'e1' => ['e1_v3']], 'context' => [], + 'ads_txt' => 1, ]; } } diff --git a/tests/Application/DTO/EventUpdateDTOTest.php b/tests/Application/DTO/EventUpdateDTOTest.php index 9507267..6b40641 100644 --- a/tests/Application/DTO/EventUpdateDTOTest.php +++ b/tests/Application/DTO/EventUpdateDTOTest.php @@ -232,6 +232,9 @@ protected static function validImpressionDataProvider(): array [[static::simpleEvent(['page_rank' => 1.0])]], [[static::simpleEvent(['page_rank' => -1.0])]], [[static::simpleEvent(['page_rank' => -1])]], + [[static::simpleEvent(['ads_txt' => 0])]], + [[static::simpleEvent(['ads_txt' => null])]], + [[static::simpleEvent([], 'ads_txt')]], ]; } @@ -311,6 +314,7 @@ protected static function invalidImpressionDataProvider(): array [[static::simpleEvent(['human_score' => -1])]], [[static::simpleEvent(['human_score' => 100])]], [[static::simpleEvent(['human_score' => 'invalid_value'])]], + [[static::simpleEvent(['ads_txt' => -1])]], ]; } @@ -331,6 +335,7 @@ protected static function simpleEvent(array $mergeData = [], string $remove = nu 'user_id' => '33c567e1396b4cadb52223a51796fd01', 'human_score' => 0.99, 'page_rank' => 1.0, + 'ads_txt' => 1, ], $mergeData ); diff --git a/tests/Domain/Model/ClickEventTest.php b/tests/Domain/Model/ClickEventTest.php index 33e113c..b0f64ee 100644 --- a/tests/Domain/Model/ClickEventTest.php +++ b/tests/Domain/Model/ClickEventTest.php @@ -36,12 +36,13 @@ public function testInstanceOfClickEvent(): void $context = ['a' => 123]; $humanScore = 0.89; $pageRank = 0.99; + $adsTxt = 1; $impression = new Impression( new Id($impressionId), new Id($trackingId), new Id($userId), - new Context($humanScore, $pageRank, $keywords, $context) + new Context($humanScore, $pageRank, $adsTxt, $keywords, $context), ); $case = new ImpressionCase( diff --git a/tests/Domain/Model/ConversionEventTest.php b/tests/Domain/Model/ConversionEventTest.php index e9a167e..a2c8c48 100644 --- a/tests/Domain/Model/ConversionEventTest.php +++ b/tests/Domain/Model/ConversionEventTest.php @@ -41,12 +41,13 @@ public function testInstanceOfConversionEvent(): void $context = ['a' => 123]; $humanScore = 0.89; $pageRank = 0.99; + $adsTxt = 1; $impression = new Impression( new Id($impressionId), new Id($trackingId), new Id($userId), - new Context($humanScore, $pageRank, $keywords, $context) + new Context($humanScore, $pageRank, $adsTxt, $keywords, $context), ); $case = new ImpressionCase( diff --git a/tests/Domain/Model/EventTest.php b/tests/Domain/Model/EventTest.php index 655dfdf..12704ce 100644 --- a/tests/Domain/Model/EventTest.php +++ b/tests/Domain/Model/EventTest.php @@ -36,12 +36,13 @@ public function testInstanceOfEvent(): void $context = ['a' => 123]; $humanScore = 0.89; $pageRank = 0.99; + $adsTxt = 1; $impression = new Impression( new Id($impressionId), new Id($trackingId), new Id($userId), - new Context($humanScore, $pageRank, $keywords, $context) + new Context($humanScore, $pageRank, $adsTxt, $keywords, $context), ); $case = new ImpressionCase( diff --git a/tests/Domain/Model/ImpressionCaseTest.php b/tests/Domain/Model/ImpressionCaseTest.php index 28c7e4b..3ce1073 100644 --- a/tests/Domain/Model/ImpressionCaseTest.php +++ b/tests/Domain/Model/ImpressionCaseTest.php @@ -30,12 +30,13 @@ public function testInstanceOfImpressionCase(): void $context = ['a' => 123]; $humanScore = 0.89; $pageRank = 0.99; + $adsTxt = 1; $impression = new Impression( new Id($impressionId), new Id($trackingId), new Id($userId), - new Context($humanScore, $pageRank, $keywords, $context) + new Context($humanScore, $pageRank, $adsTxt, $keywords, $context), ); $case = new ImpressionCase( diff --git a/tests/Domain/Model/ImpressionTest.php b/tests/Domain/Model/ImpressionTest.php index 5cbc0e9..ff1e5be 100644 --- a/tests/Domain/Model/ImpressionTest.php +++ b/tests/Domain/Model/ImpressionTest.php @@ -20,12 +20,13 @@ public function testInstanceOfImpression(): void $context = ['a' => 123]; $humanScore = 0.89; $pageRank = 0.99; + $adsTxt = 1; $impression = new Impression( new Id($impressionId), new Id($trackingId), new Id($userId), - new Context($humanScore, $pageRank, $keywords, $context) + new Context($humanScore, $pageRank, $adsTxt, $keywords, $context), ); $this->assertInstanceOf(Impression::class, $impression); diff --git a/tests/Domain/Model/ViewEventTest.php b/tests/Domain/Model/ViewEventTest.php index 02f274a..f62ebc7 100644 --- a/tests/Domain/Model/ViewEventTest.php +++ b/tests/Domain/Model/ViewEventTest.php @@ -37,12 +37,13 @@ public function testInstanceOfViewEvent(): void $context = ['a' => 123]; $humanScore = 0.89; $pageRank = 0.99; + $adsTxt = 1; $impression = new Impression( new Id($impressionId), new Id($trackingId), new Id($userId), - new Context($humanScore, $pageRank, $keywords, $context) + new Context($humanScore, $pageRank, $adsTxt, $keywords, $context), ); $case = new ImpressionCase( diff --git a/tests/Domain/Service/PaymentCalculatorTest.php b/tests/Domain/Service/PaymentCalculatorTest.php index c329cb4..55feb68 100644 --- a/tests/Domain/Service/PaymentCalculatorTest.php +++ b/tests/Domain/Service/PaymentCalculatorTest.php @@ -290,6 +290,11 @@ public function testKeywords(): void $this->statusForAll(PaymentStatus::INVALID_TARGETING, [], ['filters' => ['exclude' => ['e1' => ['e1_v3']]]]); } + public function testAdsTxtInvalid(): void + { + $this->statusForAll(PaymentStatus::INVALID_ADS_TXT, ['ads_txt' => 0]); + } + public function testSimpleEvents(): void { $campaigns = new CampaignCollection(self::campaign([], [self::banner()], [self::conversion()])); @@ -1388,7 +1393,7 @@ function viewsByCpm($cpm): int } private function statusForAll( - int $status, + int $expectedStatus, array $eventData = [], array $campaignData = [], array $bannerData = [], @@ -1399,13 +1404,13 @@ private function statusForAll( ); $payment = $this->single($campaigns, self::viewEvent($eventData)); - $this->assertEquals($status, $payment['status']); + $this->assertEquals($expectedStatus, $payment['status']); $payment = $this->single($campaigns, self::clickEvent($eventData)); - $this->assertEquals($status, $payment['status']); + $this->assertEquals($expectedStatus, $payment['status']); $payment = $this->single($campaigns, self::conversionEvent($eventData)); - $this->assertEquals($status, $payment['status']); + $this->assertEquals($expectedStatus, $payment['status']); } private function single(CampaignCollection $campaigns, array $event, array $config = []): array @@ -1621,6 +1626,7 @@ private static function event(): array 'human_score' => 0.9, 'keywords' => ['r1' => ['r1_v1'], 'e1' => ['e1_v3']], 'context' => [], + 'ads_txt' => 1, ]; } diff --git a/tests/Domain/ValueObject/ContextTest.php b/tests/Domain/ValueObject/ContextTest.php index 29b7fe8..b31262e 100644 --- a/tests/Domain/ValueObject/ContextTest.php +++ b/tests/Domain/ValueObject/ContextTest.php @@ -22,6 +22,7 @@ public function testInstanceOfContext(): void $humanScore = 0.89; $pageRank = 0.99; + $adsTxt = 1; $keywords = [ 'k1' => $k1, @@ -35,7 +36,7 @@ public function testInstanceOfContext(): void 'cc' => $cc, ]; - $context = new Context($humanScore, $pageRank, $keywords, $data); + $context = new Context($humanScore, $pageRank, $adsTxt, $keywords, $data); $this->assertInstanceOf(Context::class, $context); $this->assertEquals($humanScore, $context->getHumanScore()); @@ -53,7 +54,7 @@ public function testInstanceOfContext(): void public function testCpaOnly(): void { - $context = new Context(0.89, -1, [], []); + $context = new Context(0.89, -1); $this->assertEquals(-1, $context->getPageRank()); } @@ -63,7 +64,7 @@ public function testTooLowHumanScore(): void new Context(-0.88, 1.0); } - public function testTooHightHumanScore(): void + public function testTooHighHumanScore(): void { $this->expectException(InvalidArgumentException::class); new Context(1.88, 1.0); @@ -75,7 +76,7 @@ public function testTooLowPageRank(): void new Context(1.0, -0.88); } - public function testTooHightPageRank(): void + public function testTooHighPageRank(): void { $this->expectException(InvalidArgumentException::class); new Context(1.0, 1.88); diff --git a/tests/Infrastructure/Repository/DoctrineEventRepositoryTest.php b/tests/Infrastructure/Repository/DoctrineEventRepositoryTest.php index 482cbfc..87bec80 100644 --- a/tests/Infrastructure/Repository/DoctrineEventRepositoryTest.php +++ b/tests/Infrastructure/Repository/DoctrineEventRepositoryTest.php @@ -107,6 +107,7 @@ public function testViewEvent(): void $this->assertEquals('93c567e1396b4cadb52223a51796fd01', $event['user_id']); $this->assertEquals(0.98, $event['human_score']); $this->assertEquals(0.74, $event['page_rank']); + $this->assertEquals(1, $event['ads_txt']); $this->assertEquals(['a' => 'aaa'], $event['keywords']); $this->assertEquals(['b' => 'bbb'], $event['context']); } @@ -137,6 +138,7 @@ public function testClickEvent(): void $this->assertEquals('93c567e1396b4cadb52223a51796fd01', $event['user_id']); $this->assertEquals(0.98, $event['human_score']); $this->assertEquals(0.74, $event['page_rank']); + $this->assertEquals(1, $event['ads_txt']); $this->assertEquals(['a' => 'aaa'], $event['keywords']); $this->assertEquals(['b' => 'bbb'], $event['context']); } @@ -167,6 +169,7 @@ public function testConversionEvent(): void $this->assertEquals('93c567e1396b4cadb52223a51796fd01', $event['user_id']); $this->assertEquals(0.98, $event['human_score']); $this->assertEquals(0.74, $event['page_rank']); + $this->assertEquals(1, $event['ads_txt']); $this->assertEquals(['a' => 'aaa'], $event['keywords']); $this->assertEquals(['b' => 'bbb'], $event['context']); $this->assertEquals('f2c567e1396b4cadb52223a51796fd01', $event['group_id']); @@ -252,7 +255,7 @@ private static function impressionCase(int $timestamp): ImpressionCase new Id('73c567e1396b4cadb52223a51796fd01'), new Id('83c567e1396b4cadb52223a51796fd01'), new Id('93c567e1396b4cadb52223a51796fd01'), - new Context(0.98, 0.74, ['a' => 'aaa'], ['b' => 'bbb']) + new Context(0.98, 0.74, 1, ['a' => 'aaa'], ['b' => 'bbb']) ); return new ImpressionCase( diff --git a/tests/UI/Controller/EventControllerTest.php b/tests/UI/Controller/EventControllerTest.php index 5256077..54aa644 100644 --- a/tests/UI/Controller/EventControllerTest.php +++ b/tests/UI/Controller/EventControllerTest.php @@ -29,6 +29,7 @@ public function testUpdateViews(): void 'user_id' => '33c567e1396b4cadb52223a51796fd01', 'page_rank' => 0.99, 'human_score' => 0.89, + 'ads_txt' => 1, ], ], ]; @@ -90,6 +91,7 @@ public function testUpdateClicks(): void 'user_id' => '33c567e1396b4cadb52223a51796fd01', 'human_score' => 0.99, 'page_rank' => 0.8, + 'ads_txt' => 1, ], ], ]; @@ -215,6 +217,7 @@ public function testDuplicateEvents(): void 'user_id' => '33c567e1396b4cadb52223a51796fd01', 'human_score' => 0.99, 'page_rank' => 0.8, + 'ads_txt' => 1, ], ], ]; @@ -243,6 +246,7 @@ public function testDuplicateEvents(): void 'user_id' => '33c567e1396b4cadb52223a51796fd01', 'human_score' => 0.99, 'page_rank' => 0.8, + 'ads_txt' => 1, ], ], ]; From accb0b4d83610af469f4538cede6a7952554f136 Mon Sep 17 00:00:00 2001 From: Maciej Pilarczyk Date: Tue, 30 May 2023 16:00:13 +0200 Subject: [PATCH 3/3] v1.6.0 --- CHANGELOG.md | 7 +++++-- sonar-project.properties | 3 ++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fd26bd5..18ca0f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,10 +5,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] + +## [1.6.0] - 2023-05-30 ### Added - Reject events without valid ads.txt -## [1.5.0] - 2022-01-25 +## [1.5.0] - 2023-01-25 ### Added - Fetch reports ### Changed @@ -94,7 +96,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Rewriting from Python to PHP -[Unreleased]: https://github.com/adshares/adpay/compare/v1.2.0...HEAD +[Unreleased]: https://github.com/adshares/adpay/compare/v1.6.0...HEAD +[1.6.0]: https://github.com/adshares/adpay/compare/v1.5.0...v1.6.0 [1.5.0]: https://github.com/adshares/adpay/compare/v1.4.2...v1.5.0 [1.4.2]: https://github.com/adshares/adpay/compare/v1.4.1...v1.4.2 [1.4.1]: https://github.com/adshares/adpay/compare/v1.4.0...v1.4.1 diff --git a/sonar-project.properties b/sonar-project.properties index 93bcb2a..1ec1f75 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -2,7 +2,8 @@ sonar.host.url=https://sonarcloud.io sonar.organization=adshares-github sonar.projectKey=adshares-adpay sonar.projectName=Adshares AdPay -sonar.projectVersion=1.5 +sonar.projectVersion=1.6 +sonar.projectVersion=1.6 # ===================================================== # Meta-data for the project