Skip to content

Commit 4467266

Browse files
committed
Add: validateNoClickTrackLinks
1 parent df18946 commit 4467266

2 files changed

Lines changed: 81 additions & 0 deletions

File tree

src/Messaging/Request/Message/MessageContentRequest.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use OpenApi\Attributes as OA;
88
use PhpList\Core\Domain\Messaging\Model\Dto\Message\MessageContentDto;
99
use Symfony\Component\Validator\Constraints as Assert;
10+
use Symfony\Component\Validator\Context\ExecutionContextInterface;
1011

1112
#[OA\Schema(
1213
schema: 'MessageContentRequest',
@@ -20,6 +21,9 @@
2021
)]
2122
class MessageContentRequest implements RequestDtoInterface
2223
{
24+
private const CLICKTRACK_MESSAGE = 'You should not paste the results of a test message back into the editor. '
25+
. 'This will break the click-track statistics, and overload the server.';
26+
2327
#[Assert\NotBlank]
2428
public string $subject;
2529

@@ -29,6 +33,25 @@ class MessageContentRequest implements RequestDtoInterface
2933
#[Assert\NotBlank]
3034
public string $footer;
3135

36+
#[Assert\Callback('validateNoClickTrackLinks')]
37+
public function validateNoClickTrackLinks(ExecutionContextInterface $context): void
38+
{
39+
if (!isset($this->text)) {
40+
return;
41+
}
42+
43+
$hasClickTrackLinks = preg_match('/lt\.php\?id=[\w%]{22}/', $this->text) === 1
44+
|| preg_match('/lt\.php\?id=[\w%]{16}/', $this->text) === 1
45+
|| preg_match('#/lt/[\w%]{22}#', $this->text) === 1
46+
|| preg_match('#/lt/[\w%]{16}#', $this->text) === 1;
47+
48+
if ($hasClickTrackLinks) {
49+
$context->buildViolation(self::CLICKTRACK_MESSAGE)
50+
->atPath('text')
51+
->addViolation();
52+
}
53+
}
54+
3255
public function getDto(): MessageContentDto
3356
{
3457
return new MessageContentDto(
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpList\RestBundle\Tests\Unit\Messaging\Request;
6+
7+
use PhpList\RestBundle\Messaging\Request\Message\MessageContentRequest;
8+
use PHPUnit\Framework\TestCase;
9+
use Symfony\Component\Validator\Context\ExecutionContextInterface;
10+
use Symfony\Component\Validator\Violation\ConstraintViolationBuilderInterface;
11+
12+
class MessageContentRequestTest extends TestCase
13+
{
14+
public function testValidateNoClickTrackLinksWithCleanTextDoesNotAddViolation(): void
15+
{
16+
$request = new MessageContentRequest();
17+
$request->text = 'Hello, this is a normal message body.';
18+
19+
$context = $this->createMock(ExecutionContextInterface::class);
20+
$context->expects($this->never())->method('buildViolation');
21+
22+
$request->validateNoClickTrackLinks($context);
23+
}
24+
25+
public function testValidateNoClickTrackLinksWithLtPhpPatternAddsViolation(): void
26+
{
27+
$request = new MessageContentRequest();
28+
$request->text = 'See this link: https://example.com/lt.php?id=abcdefghijklmnop';
29+
30+
$builder = $this->createMock(ConstraintViolationBuilderInterface::class);
31+
$builder->expects($this->once())->method('atPath')->with('text')->willReturnSelf();
32+
$builder->expects($this->once())->method('addViolation');
33+
34+
$context = $this->createMock(ExecutionContextInterface::class);
35+
$context->expects($this->once())
36+
->method('buildViolation')
37+
->willReturn($builder);
38+
39+
$request->validateNoClickTrackLinks($context);
40+
}
41+
42+
public function testValidateNoClickTrackLinksWithLinkMapPatternAddsViolation(): void
43+
{
44+
$request = new MessageContentRequest();
45+
$request->text = 'Mapped link: https://example.com/lt/abcdefghijklmnopqrstuv';
46+
47+
$builder = $this->createMock(ConstraintViolationBuilderInterface::class);
48+
$builder->expects($this->once())->method('atPath')->with('text')->willReturnSelf();
49+
$builder->expects($this->once())->method('addViolation');
50+
51+
$context = $this->createMock(ExecutionContextInterface::class);
52+
$context->expects($this->once())
53+
->method('buildViolation')
54+
->willReturn($builder);
55+
56+
$request->validateNoClickTrackLinks($context);
57+
}
58+
}

0 commit comments

Comments
 (0)