mirror of
https://github.com/shlinkio/shlink.git
synced 2025-02-18 16:29:56 +03:00
Add tests for ShortUrlRedirectionRuleService::setRulesForShortUrl
This commit is contained in:
parent
f9e4d6d617
commit
f700abd65d
5 changed files with 86 additions and 14 deletions
|
@ -8,6 +8,8 @@ use Laminas\InputFilter\Exception\InvalidArgumentException;
|
||||||
use Shlinkio\Shlink\Core\Exception\ValidationException;
|
use Shlinkio\Shlink\Core\Exception\ValidationException;
|
||||||
use Shlinkio\Shlink\Core\RedirectRule\Model\Validation\RedirectRulesInputFilter;
|
use Shlinkio\Shlink\Core\RedirectRule\Model\Validation\RedirectRulesInputFilter;
|
||||||
|
|
||||||
|
use function array_values;
|
||||||
|
|
||||||
readonly class RedirectRulesData
|
readonly class RedirectRulesData
|
||||||
{
|
{
|
||||||
private function __construct(public array $rules)
|
private function __construct(public array $rules)
|
||||||
|
@ -22,7 +24,7 @@ readonly class RedirectRulesData
|
||||||
throw ValidationException::fromInputFilter($inputFilter);
|
throw ValidationException::fromInputFilter($inputFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new self($inputFilter->getValue(RedirectRulesInputFilter::REDIRECT_RULES));
|
return new self(array_values($inputFilter->getValue(RedirectRulesInputFilter::REDIRECT_RULES)));
|
||||||
} catch (InvalidArgumentException) {
|
} catch (InvalidArgumentException) {
|
||||||
throw ValidationException::fromArray(
|
throw ValidationException::fromArray(
|
||||||
[RedirectRulesInputFilter::REDIRECT_RULES => RedirectRulesInputFilter::REDIRECT_RULES],
|
[RedirectRulesInputFilter::REDIRECT_RULES => RedirectRulesInputFilter::REDIRECT_RULES],
|
||||||
|
|
|
@ -20,7 +20,6 @@ class RedirectRulesInputFilter extends InputFilter
|
||||||
{
|
{
|
||||||
public const REDIRECT_RULES = 'redirectRules';
|
public const REDIRECT_RULES = 'redirectRules';
|
||||||
|
|
||||||
public const RULE_PRIORITY = 'priority';
|
|
||||||
public const RULE_LONG_URL = 'longUrl';
|
public const RULE_LONG_URL = 'longUrl';
|
||||||
public const RULE_CONDITIONS = 'conditions';
|
public const RULE_CONDITIONS = 'conditions';
|
||||||
|
|
||||||
|
@ -48,8 +47,6 @@ class RedirectRulesInputFilter extends InputFilter
|
||||||
{
|
{
|
||||||
$redirectRuleInputFilter = new InputFilter();
|
$redirectRuleInputFilter = new InputFilter();
|
||||||
|
|
||||||
$redirectRuleInputFilter->add(InputFactory::numeric(self::RULE_PRIORITY, required: true));
|
|
||||||
|
|
||||||
$longUrl = InputFactory::basic(self::RULE_LONG_URL, required: true);
|
$longUrl = InputFactory::basic(self::RULE_LONG_URL, required: true);
|
||||||
$longUrl->setValidatorChain(ShortUrlInputFilter::longUrlValidators());
|
$longUrl->setValidatorChain(ShortUrlInputFilter::longUrlValidators());
|
||||||
$redirectRuleInputFilter->add($longUrl);
|
$redirectRuleInputFilter->add($longUrl);
|
||||||
|
|
|
@ -52,10 +52,10 @@ readonly class ShortUrlRedirectRuleService implements ShortUrlRedirectRuleServic
|
||||||
|
|
||||||
// Then insert new rules
|
// Then insert new rules
|
||||||
$rules = [];
|
$rules = [];
|
||||||
foreach ($data->rules as $rule) {
|
foreach ($data->rules as $index => $rule) {
|
||||||
$rule = new ShortUrlRedirectRule(
|
$rule = new ShortUrlRedirectRule(
|
||||||
shortUrl: $shortUrl,
|
shortUrl: $shortUrl,
|
||||||
priority: $rule[RedirectRulesInputFilter::RULE_PRIORITY],
|
priority: $index + 1,
|
||||||
longUrl: $rule[RedirectRulesInputFilter::RULE_LONG_URL],
|
longUrl: $rule[RedirectRulesInputFilter::RULE_LONG_URL],
|
||||||
conditions: new ArrayCollection(array_map(
|
conditions: new ArrayCollection(array_map(
|
||||||
RedirectCondition::fromRawData(...),
|
RedirectCondition::fromRawData(...),
|
||||||
|
|
|
@ -14,18 +14,13 @@ class RedirectRulesDataTest extends TestCase
|
||||||
{
|
{
|
||||||
#[Test]
|
#[Test]
|
||||||
#[TestWith([['redirectRules' => ['foo']]])]
|
#[TestWith([['redirectRules' => ['foo']]])]
|
||||||
#[TestWith([['redirectRules' => [
|
|
||||||
['priority' => 'foo'],
|
|
||||||
]]])]
|
|
||||||
#[TestWith([['redirectRules' => [
|
#[TestWith([['redirectRules' => [
|
||||||
[
|
[
|
||||||
'priority' => 4,
|
|
||||||
'longUrl' => 34,
|
'longUrl' => 34,
|
||||||
],
|
],
|
||||||
]]])]
|
]]])]
|
||||||
#[TestWith([['redirectRules' => [
|
#[TestWith([['redirectRules' => [
|
||||||
[
|
[
|
||||||
'priority' => 4,
|
|
||||||
'longUrl' => 'https://example.com',
|
'longUrl' => 'https://example.com',
|
||||||
'conditions' => [
|
'conditions' => [
|
||||||
[
|
[
|
||||||
|
@ -36,7 +31,6 @@ class RedirectRulesDataTest extends TestCase
|
||||||
]]])]
|
]]])]
|
||||||
#[TestWith([['redirectRules' => [
|
#[TestWith([['redirectRules' => [
|
||||||
[
|
[
|
||||||
'priority' => 4,
|
|
||||||
'longUrl' => 'https://example.com',
|
'longUrl' => 'https://example.com',
|
||||||
'conditions' => [
|
'conditions' => [
|
||||||
[
|
[
|
||||||
|
@ -49,7 +43,6 @@ class RedirectRulesDataTest extends TestCase
|
||||||
]]])]
|
]]])]
|
||||||
#[TestWith([['redirectRules' => [
|
#[TestWith([['redirectRules' => [
|
||||||
[
|
[
|
||||||
'priority' => 4,
|
|
||||||
'longUrl' => 'https://example.com',
|
'longUrl' => 'https://example.com',
|
||||||
'conditions' => [
|
'conditions' => [
|
||||||
[
|
[
|
||||||
|
|
|
@ -11,6 +11,9 @@ use PHPUnit\Framework\TestCase;
|
||||||
use Shlinkio\Shlink\Core\Model\DeviceType;
|
use Shlinkio\Shlink\Core\Model\DeviceType;
|
||||||
use Shlinkio\Shlink\Core\RedirectRule\Entity\RedirectCondition;
|
use Shlinkio\Shlink\Core\RedirectRule\Entity\RedirectCondition;
|
||||||
use Shlinkio\Shlink\Core\RedirectRule\Entity\ShortUrlRedirectRule;
|
use Shlinkio\Shlink\Core\RedirectRule\Entity\ShortUrlRedirectRule;
|
||||||
|
use Shlinkio\Shlink\Core\RedirectRule\Model\RedirectConditionType;
|
||||||
|
use Shlinkio\Shlink\Core\RedirectRule\Model\RedirectRulesData;
|
||||||
|
use Shlinkio\Shlink\Core\RedirectRule\Model\Validation\RedirectRulesInputFilter;
|
||||||
use Shlinkio\Shlink\Core\RedirectRule\ShortUrlRedirectRuleService;
|
use Shlinkio\Shlink\Core\RedirectRule\ShortUrlRedirectRuleService;
|
||||||
use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
|
use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
|
||||||
|
|
||||||
|
@ -26,7 +29,7 @@ class ShortUrlRedirectRuleServiceTest extends TestCase
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Test]
|
#[Test]
|
||||||
public function delegatesToRepository(): void
|
public function rulesForShortUrlDelegatesToRepository(): void
|
||||||
{
|
{
|
||||||
$shortUrl = ShortUrl::withLongUrl('https://shlink.io');
|
$shortUrl = ShortUrl::withLongUrl('https://shlink.io');
|
||||||
$rules = [
|
$rules = [
|
||||||
|
@ -52,4 +55,81 @@ class ShortUrlRedirectRuleServiceTest extends TestCase
|
||||||
|
|
||||||
self::assertSame($rules, $result);
|
self::assertSame($rules, $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[Test]
|
||||||
|
public function setRulesForShortUrlParsesProvidedData(): void
|
||||||
|
{
|
||||||
|
$shortUrl = ShortUrl::withLongUrl('https://example.com');
|
||||||
|
$data = RedirectRulesData::fromRawData([
|
||||||
|
RedirectRulesInputFilter::REDIRECT_RULES => [
|
||||||
|
[
|
||||||
|
RedirectRulesInputFilter::RULE_LONG_URL => 'https://example.com/first',
|
||||||
|
RedirectRulesInputFilter::RULE_CONDITIONS => [
|
||||||
|
[
|
||||||
|
RedirectRulesInputFilter::CONDITION_TYPE => RedirectConditionType::DEVICE->value,
|
||||||
|
RedirectRulesInputFilter::CONDITION_MATCH_KEY => null,
|
||||||
|
RedirectRulesInputFilter::CONDITION_MATCH_VALUE => DeviceType::ANDROID->value,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
RedirectRulesInputFilter::CONDITION_TYPE => RedirectConditionType::QUERY_PARAM->value,
|
||||||
|
RedirectRulesInputFilter::CONDITION_MATCH_KEY => 'foo',
|
||||||
|
RedirectRulesInputFilter::CONDITION_MATCH_VALUE => 'bar',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
RedirectRulesInputFilter::RULE_LONG_URL => 'https://example.com/second',
|
||||||
|
RedirectRulesInputFilter::RULE_CONDITIONS => [
|
||||||
|
[
|
||||||
|
RedirectRulesInputFilter::CONDITION_TYPE => RedirectConditionType::DEVICE->value,
|
||||||
|
RedirectRulesInputFilter::CONDITION_MATCH_KEY => null,
|
||||||
|
RedirectRulesInputFilter::CONDITION_MATCH_VALUE => DeviceType::IOS->value,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->em->expects($this->once())->method('wrapInTransaction')->willReturnCallback(
|
||||||
|
fn (callable $callback) => $callback(),
|
||||||
|
);
|
||||||
|
$this->em->expects($this->exactly(2))->method('persist');
|
||||||
|
$this->em->expects($this->never())->method('remove');
|
||||||
|
|
||||||
|
$result = $this->ruleService->setRulesForShortUrl($shortUrl, $data);
|
||||||
|
|
||||||
|
self::assertCount(2, $result);
|
||||||
|
self::assertInstanceOf(ShortUrlRedirectRule::class, $result[0]);
|
||||||
|
self::assertInstanceOf(ShortUrlRedirectRule::class, $result[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Test]
|
||||||
|
public function setRulesForShortUrlRemovesOldRules(): void
|
||||||
|
{
|
||||||
|
$shortUrl = ShortUrl::withLongUrl('https://example.com');
|
||||||
|
$data = RedirectRulesData::fromRawData([
|
||||||
|
RedirectRulesInputFilter::REDIRECT_RULES => [],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$repo = $this->createMock(EntityRepository::class);
|
||||||
|
$repo->expects($this->once())->method('findBy')->with(
|
||||||
|
['shortUrl' => $shortUrl],
|
||||||
|
['priority' => 'ASC'],
|
||||||
|
)->willReturn([
|
||||||
|
new ShortUrlRedirectRule($shortUrl, 1, 'https://example.com'),
|
||||||
|
new ShortUrlRedirectRule($shortUrl, 2, 'https://example.com'),
|
||||||
|
]);
|
||||||
|
$this->em->expects($this->once())->method('getRepository')->with(ShortUrlRedirectRule::class)->willReturn(
|
||||||
|
$repo,
|
||||||
|
);
|
||||||
|
$this->em->expects($this->once())->method('wrapInTransaction')->willReturnCallback(
|
||||||
|
fn (callable $callback) => $callback(),
|
||||||
|
);
|
||||||
|
$this->em->expects($this->never())->method('persist');
|
||||||
|
$this->em->expects($this->exactly(2))->method('remove');
|
||||||
|
|
||||||
|
$result = $this->ruleService->setRulesForShortUrl($shortUrl, $data);
|
||||||
|
|
||||||
|
self::assertCount(0, $result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue