mirror of
https://github.com/shlinkio/shlink.git
synced 2024-11-22 12:48:24 +03:00
Make Visit::date field readonly
This commit is contained in:
parent
ce0f61b66d
commit
ca42425b33
13 changed files with 41 additions and 46 deletions
|
@ -55,7 +55,7 @@ abstract class AbstractVisitsListCommand extends Command
|
||||||
|
|
||||||
$rowData = [
|
$rowData = [
|
||||||
'referer' => $visit->referer,
|
'referer' => $visit->referer,
|
||||||
'date' => $visit->getDate()->toAtomString(),
|
'date' => $visit->date->toAtomString(),
|
||||||
'userAgent' => $visit->userAgent,
|
'userAgent' => $visit->userAgent,
|
||||||
'potentialBot' => $visit->potentialBot,
|
'potentialBot' => $visit->potentialBot,
|
||||||
'country' => $visit->getVisitLocation()?->countryName ?? 'Unknown',
|
'country' => $visit->getVisitLocation()?->countryName ?? 'Unknown',
|
||||||
|
|
|
@ -60,7 +60,7 @@ class GetDomainVisitsCommandTest extends TestCase
|
||||||
+---------+---------------------------+------------+---------+--------+---------------+
|
+---------+---------------------------+------------+---------+--------+---------------+
|
||||||
| Referer | Date | User agent | Country | City | Short Url |
|
| Referer | Date | User agent | Country | City | Short Url |
|
||||||
+---------+---------------------------+------------+---------+--------+---------------+
|
+---------+---------------------------+------------+---------+--------+---------------+
|
||||||
| foo | {$visit->getDate()->toAtomString()} | bar | Spain | Madrid | the_short_url |
|
| foo | {$visit->date->toAtomString()} | bar | Spain | Madrid | the_short_url |
|
||||||
+---------+---------------------------+------------+---------+--------+---------------+
|
+---------+---------------------------+------------+---------+--------+---------------+
|
||||||
|
|
||||||
OUTPUT,
|
OUTPUT,
|
||||||
|
|
|
@ -110,7 +110,7 @@ class GetShortUrlVisitsCommandTest extends TestCase
|
||||||
+---------+---------------------------+------------+---------+--------+
|
+---------+---------------------------+------------+---------+--------+
|
||||||
| Referer | Date | User agent | Country | City |
|
| Referer | Date | User agent | Country | City |
|
||||||
+---------+---------------------------+------------+---------+--------+
|
+---------+---------------------------+------------+---------+--------+
|
||||||
| foo | {$visit->getDate()->toAtomString()} | bar | Spain | Madrid |
|
| foo | {$visit->date->toAtomString()} | bar | Spain | Madrid |
|
||||||
+---------+---------------------------+------------+---------+--------+
|
+---------+---------------------------+------------+---------+--------+
|
||||||
|
|
||||||
OUTPUT,
|
OUTPUT,
|
||||||
|
|
|
@ -57,7 +57,7 @@ class GetTagVisitsCommandTest extends TestCase
|
||||||
+---------+---------------------------+------------+---------+--------+---------------+
|
+---------+---------------------------+------------+---------+--------+---------------+
|
||||||
| Referer | Date | User agent | Country | City | Short Url |
|
| Referer | Date | User agent | Country | City | Short Url |
|
||||||
+---------+---------------------------+------------+---------+--------+---------------+
|
+---------+---------------------------+------------+---------+--------+---------------+
|
||||||
| foo | {$visit->getDate()->toAtomString()} | bar | Spain | Madrid | the_short_url |
|
| foo | {$visit->date->toAtomString()} | bar | Spain | Madrid | the_short_url |
|
||||||
+---------+---------------------------+------------+---------+--------+---------------+
|
+---------+---------------------------+------------+---------+--------+---------------+
|
||||||
|
|
||||||
OUTPUT,
|
OUTPUT,
|
||||||
|
|
|
@ -56,7 +56,7 @@ class GetNonOrphanVisitsCommandTest extends TestCase
|
||||||
+---------+---------------------------+------------+---------+--------+---------------+
|
+---------+---------------------------+------------+---------+--------+---------------+
|
||||||
| Referer | Date | User agent | Country | City | Short Url |
|
| Referer | Date | User agent | Country | City | Short Url |
|
||||||
+---------+---------------------------+------------+---------+--------+---------------+
|
+---------+---------------------------+------------+---------+--------+---------------+
|
||||||
| foo | {$visit->getDate()->toAtomString()} | bar | Spain | Madrid | the_short_url |
|
| foo | {$visit->date->toAtomString()} | bar | Spain | Madrid | the_short_url |
|
||||||
+---------+---------------------------+------------+---------+--------+---------------+
|
+---------+---------------------------+------------+---------+--------+---------------+
|
||||||
|
|
||||||
OUTPUT,
|
OUTPUT,
|
||||||
|
|
|
@ -54,7 +54,7 @@ class GetOrphanVisitsCommandTest extends TestCase
|
||||||
+---------+---------------------------+------------+---------+--------+----------+
|
+---------+---------------------------+------------+---------+--------+----------+
|
||||||
| Referer | Date | User agent | Country | City | Type |
|
| Referer | Date | User agent | Country | City | Type |
|
||||||
+---------+---------------------------+------------+---------+--------+----------+
|
+---------+---------------------------+------------+---------+--------+----------+
|
||||||
| foo | {$visit->getDate()->toAtomString()} | bar | Spain | Madrid | base_url |
|
| foo | {$visit->date->toAtomString()} | bar | Spain | Madrid | base_url |
|
||||||
+---------+---------------------------+------------+---------+--------+----------+
|
+---------+---------------------------+------------+---------+--------+----------+
|
||||||
|
|
||||||
OUTPUT,
|
OUTPUT,
|
||||||
|
|
|
@ -139,7 +139,7 @@ class ImportedLinksProcessor implements ImportedLinksProcessorInterface
|
||||||
$importedVisits = 0;
|
$importedVisits = 0;
|
||||||
foreach ($iterable as $importedOrphanVisit) {
|
foreach ($iterable as $importedOrphanVisit) {
|
||||||
// Skip visits which are older than the most recent already imported visit's date
|
// Skip visits which are older than the most recent already imported visit's date
|
||||||
if ($mostRecentOrphanVisit?->getDate()->greaterThanOrEquals(normalizeDate($importedOrphanVisit->date))) {
|
if ($mostRecentOrphanVisit?->date->greaterThanOrEquals(normalizeDate($importedOrphanVisit->date))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -209,7 +209,7 @@ class ShortUrl extends AbstractEntity
|
||||||
->setMaxResults(1);
|
->setMaxResults(1);
|
||||||
$visit = $this->visits->matching($criteria)->last();
|
$visit = $this->visits->matching($criteria)->last();
|
||||||
|
|
||||||
return $visit instanceof Visit ? $visit->getDate() : null;
|
return $visit instanceof Visit ? $visit->date : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -29,8 +29,7 @@ class Visit extends AbstractEntity implements JsonSerializable
|
||||||
public readonly ?string $remoteAddr = null,
|
public readonly ?string $remoteAddr = null,
|
||||||
public readonly ?string $visitedUrl = null,
|
public readonly ?string $visitedUrl = null,
|
||||||
private ?VisitLocation $visitLocation = null,
|
private ?VisitLocation $visitLocation = null,
|
||||||
// TODO Make public readonly once VisitRepositoryTest does not try to set it
|
public readonly Chronos $date = new Chronos(),
|
||||||
private Chronos $date = new Chronos(),
|
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,14 +146,6 @@ class Visit extends AbstractEntity implements JsonSerializable
|
||||||
return $this->type;
|
return $this->type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
public function getDate(): Chronos
|
|
||||||
{
|
|
||||||
return $this->date;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function jsonSerialize(): array
|
public function jsonSerialize(): array
|
||||||
{
|
{
|
||||||
$base = [
|
$base = [
|
||||||
|
|
|
@ -6,7 +6,6 @@ namespace ShlinkioDbTest\Shlink\Core\Visit\Repository;
|
||||||
|
|
||||||
use Cake\Chronos\Chronos;
|
use Cake\Chronos\Chronos;
|
||||||
use PHPUnit\Framework\Attributes\Test;
|
use PHPUnit\Framework\Attributes\Test;
|
||||||
use ReflectionObject;
|
|
||||||
use Shlinkio\Shlink\Common\Util\DateRange;
|
use Shlinkio\Shlink\Common\Util\DateRange;
|
||||||
use Shlinkio\Shlink\Core\Domain\Entity\Domain;
|
use Shlinkio\Shlink\Core\Domain\Entity\Domain;
|
||||||
use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
|
use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
|
||||||
|
@ -371,15 +370,15 @@ class VisitRepositoryTest extends DatabaseTestCase
|
||||||
$botsCount = 3;
|
$botsCount = 3;
|
||||||
for ($i = 0; $i < 6; $i++) {
|
for ($i = 0; $i < 6; $i++) {
|
||||||
$this->getEntityManager()->persist($this->setDateOnVisit(
|
$this->getEntityManager()->persist($this->setDateOnVisit(
|
||||||
Visit::forBasePath($botsCount < 1 ? Visitor::emptyInstance() : Visitor::botInstance()),
|
fn () => Visit::forBasePath($botsCount < 1 ? Visitor::emptyInstance() : Visitor::botInstance()),
|
||||||
Chronos::parse(sprintf('2020-01-0%s', $i + 1)),
|
Chronos::parse(sprintf('2020-01-0%s', $i + 1)),
|
||||||
));
|
));
|
||||||
$this->getEntityManager()->persist($this->setDateOnVisit(
|
$this->getEntityManager()->persist($this->setDateOnVisit(
|
||||||
Visit::forInvalidShortUrl(Visitor::emptyInstance()),
|
fn () => Visit::forInvalidShortUrl(Visitor::emptyInstance()),
|
||||||
Chronos::parse(sprintf('2020-01-0%s', $i + 1)),
|
Chronos::parse(sprintf('2020-01-0%s', $i + 1)),
|
||||||
));
|
));
|
||||||
$this->getEntityManager()->persist($this->setDateOnVisit(
|
$this->getEntityManager()->persist($this->setDateOnVisit(
|
||||||
Visit::forRegularNotFound(Visitor::emptyInstance()),
|
fn () => Visit::forRegularNotFound(Visitor::emptyInstance()),
|
||||||
Chronos::parse(sprintf('2020-01-0%s', $i + 1)),
|
Chronos::parse(sprintf('2020-01-0%s', $i + 1)),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -429,15 +428,15 @@ class VisitRepositoryTest extends DatabaseTestCase
|
||||||
|
|
||||||
for ($i = 0; $i < 6; $i++) {
|
for ($i = 0; $i < 6; $i++) {
|
||||||
$this->getEntityManager()->persist($this->setDateOnVisit(
|
$this->getEntityManager()->persist($this->setDateOnVisit(
|
||||||
Visit::forBasePath(Visitor::emptyInstance()),
|
fn () => Visit::forBasePath(Visitor::emptyInstance()),
|
||||||
Chronos::parse(sprintf('2020-01-0%s', $i + 1)),
|
Chronos::parse(sprintf('2020-01-0%s', $i + 1)),
|
||||||
));
|
));
|
||||||
$this->getEntityManager()->persist($this->setDateOnVisit(
|
$this->getEntityManager()->persist($this->setDateOnVisit(
|
||||||
Visit::forInvalidShortUrl(Visitor::emptyInstance()),
|
fn () => Visit::forInvalidShortUrl(Visitor::emptyInstance()),
|
||||||
Chronos::parse(sprintf('2020-01-0%s', $i + 1)),
|
Chronos::parse(sprintf('2020-01-0%s', $i + 1)),
|
||||||
));
|
));
|
||||||
$this->getEntityManager()->persist($this->setDateOnVisit(
|
$this->getEntityManager()->persist($this->setDateOnVisit(
|
||||||
Visit::forRegularNotFound(Visitor::emptyInstance()),
|
fn () => Visit::forRegularNotFound(Visitor::emptyInstance()),
|
||||||
Chronos::parse(sprintf('2020-01-0%s', $i + 1)),
|
Chronos::parse(sprintf('2020-01-0%s', $i + 1)),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -566,7 +565,7 @@ class VisitRepositoryTest extends DatabaseTestCase
|
||||||
{
|
{
|
||||||
for ($i = 0; $i < $amount; $i++) {
|
for ($i = 0; $i < $amount; $i++) {
|
||||||
$visit = $this->setDateOnVisit(
|
$visit = $this->setDateOnVisit(
|
||||||
Visit::forValidShortUrl(
|
fn () => Visit::forValidShortUrl(
|
||||||
$shortUrl,
|
$shortUrl,
|
||||||
$botsAmount < 1 ? Visitor::emptyInstance() : Visitor::botInstance(),
|
$botsAmount < 1 ? Visitor::emptyInstance() : Visitor::botInstance(),
|
||||||
),
|
),
|
||||||
|
@ -578,12 +577,14 @@ class VisitRepositoryTest extends DatabaseTestCase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function setDateOnVisit(Visit $visit, Chronos $date): Visit
|
/**
|
||||||
|
* @param callable(): Visit $createVisit
|
||||||
|
*/
|
||||||
|
private function setDateOnVisit(callable $createVisit, Chronos $date): Visit
|
||||||
{
|
{
|
||||||
$ref = new ReflectionObject($visit);
|
Chronos::setTestNow($date);
|
||||||
$dateProp = $ref->getProperty('date');
|
$visit = $createVisit();
|
||||||
$dateProp->setAccessible(true);
|
Chronos::setTestNow();
|
||||||
$dateProp->setValue($visit, $date);
|
|
||||||
|
|
||||||
return $visit;
|
return $visit;
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,7 @@ class PublishingUpdatesGeneratorTest extends TestCase
|
||||||
'referer' => '',
|
'referer' => '',
|
||||||
'userAgent' => '',
|
'userAgent' => '',
|
||||||
'visitLocation' => null,
|
'visitLocation' => null,
|
||||||
'date' => $visit->getDate()->toAtomString(),
|
'date' => $visit->date->toAtomString(),
|
||||||
'potentialBot' => false,
|
'potentialBot' => false,
|
||||||
'visitedUrl' => '',
|
'visitedUrl' => '',
|
||||||
],
|
],
|
||||||
|
@ -100,7 +100,7 @@ class PublishingUpdatesGeneratorTest extends TestCase
|
||||||
'referer' => '',
|
'referer' => '',
|
||||||
'userAgent' => '',
|
'userAgent' => '',
|
||||||
'visitLocation' => null,
|
'visitLocation' => null,
|
||||||
'date' => $orphanVisit->getDate()->toAtomString(),
|
'date' => $orphanVisit->date->toAtomString(),
|
||||||
'potentialBot' => false,
|
'potentialBot' => false,
|
||||||
'visitedUrl' => $orphanVisit->visitedUrl,
|
'visitedUrl' => $orphanVisit->visitedUrl,
|
||||||
'type' => $orphanVisit->type->value,
|
'type' => $orphanVisit->type->value,
|
||||||
|
|
|
@ -26,7 +26,7 @@ class VisitTest extends TestCase
|
||||||
|
|
||||||
self::assertEquals([
|
self::assertEquals([
|
||||||
'referer' => 'some site',
|
'referer' => 'some site',
|
||||||
'date' => $visit->getDate()->toAtomString(),
|
'date' => $visit->date->toAtomString(),
|
||||||
'userAgent' => $userAgent,
|
'userAgent' => $userAgent,
|
||||||
'visitLocation' => null,
|
'visitLocation' => null,
|
||||||
'potentialBot' => $expectedToBePotentialBot,
|
'potentialBot' => $expectedToBePotentialBot,
|
||||||
|
@ -58,7 +58,7 @@ class VisitTest extends TestCase
|
||||||
$visit = Visit::forBasePath(Visitor::emptyInstance()),
|
$visit = Visit::forBasePath(Visitor::emptyInstance()),
|
||||||
[
|
[
|
||||||
'referer' => '',
|
'referer' => '',
|
||||||
'date' => $visit->getDate()->toAtomString(),
|
'date' => $visit->date->toAtomString(),
|
||||||
'userAgent' => '',
|
'userAgent' => '',
|
||||||
'visitLocation' => null,
|
'visitLocation' => null,
|
||||||
'potentialBot' => false,
|
'potentialBot' => false,
|
||||||
|
@ -74,7 +74,7 @@ class VisitTest extends TestCase
|
||||||
)),
|
)),
|
||||||
[
|
[
|
||||||
'referer' => 'bar',
|
'referer' => 'bar',
|
||||||
'date' => $visit->getDate()->toAtomString(),
|
'date' => $visit->date->toAtomString(),
|
||||||
'userAgent' => 'foo',
|
'userAgent' => 'foo',
|
||||||
'visitLocation' => null,
|
'visitLocation' => null,
|
||||||
'potentialBot' => false,
|
'potentialBot' => false,
|
||||||
|
@ -92,7 +92,7 @@ class VisitTest extends TestCase
|
||||||
)->locate($location = VisitLocation::fromGeolocation(Location::emptyInstance())),
|
)->locate($location = VisitLocation::fromGeolocation(Location::emptyInstance())),
|
||||||
[
|
[
|
||||||
'referer' => 'referer',
|
'referer' => 'referer',
|
||||||
'date' => $visit->getDate()->toAtomString(),
|
'date' => $visit->date->toAtomString(),
|
||||||
'userAgent' => 'user-agent',
|
'userAgent' => 'user-agent',
|
||||||
'visitLocation' => $location,
|
'visitLocation' => $location,
|
||||||
'potentialBot' => false,
|
'potentialBot' => false,
|
||||||
|
|
|
@ -8,7 +8,6 @@ use Cake\Chronos\Chronos;
|
||||||
use Doctrine\Common\DataFixtures\AbstractFixture;
|
use Doctrine\Common\DataFixtures\AbstractFixture;
|
||||||
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
|
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
|
||||||
use Doctrine\Persistence\ObjectManager;
|
use Doctrine\Persistence\ObjectManager;
|
||||||
use ReflectionObject;
|
|
||||||
use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
|
use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
|
||||||
use Shlinkio\Shlink\Core\Visit\Entity\Visit;
|
use Shlinkio\Shlink\Core\Visit\Entity\Visit;
|
||||||
use Shlinkio\Shlink\Core\Visit\Model\Visitor;
|
use Shlinkio\Shlink\Core\Visit\Model\Visitor;
|
||||||
|
@ -50,27 +49,31 @@ class VisitsFixture extends AbstractFixture implements DependentFixtureInterface
|
||||||
);
|
);
|
||||||
|
|
||||||
$manager->persist($this->setVisitDate(
|
$manager->persist($this->setVisitDate(
|
||||||
Visit::forBasePath(new Visitor('shlink-tests-agent', 'https://s.test', '1.2.3.4', '')),
|
fn () => Visit::forBasePath(new Visitor('shlink-tests-agent', 'https://s.test', '1.2.3.4', '')),
|
||||||
'2020-01-01',
|
'2020-01-01',
|
||||||
));
|
));
|
||||||
$manager->persist($this->setVisitDate(
|
$manager->persist($this->setVisitDate(
|
||||||
Visit::forRegularNotFound(new Visitor('shlink-tests-agent', 'https://s.test/foo/bar', '1.2.3.4', '')),
|
fn () => Visit::forRegularNotFound(
|
||||||
|
new Visitor('shlink-tests-agent', 'https://s.test/foo/bar', '1.2.3.4', ''),
|
||||||
|
),
|
||||||
'2020-02-01',
|
'2020-02-01',
|
||||||
));
|
));
|
||||||
$manager->persist($this->setVisitDate(
|
$manager->persist($this->setVisitDate(
|
||||||
Visit::forInvalidShortUrl(new Visitor('cf-facebook', 'https://s.test/foo', '1.2.3.4', 'foo.com')),
|
fn () => Visit::forInvalidShortUrl(new Visitor('cf-facebook', 'https://s.test/foo', '1.2.3.4', 'foo.com')),
|
||||||
'2020-03-01',
|
'2020-03-01',
|
||||||
));
|
));
|
||||||
|
|
||||||
$manager->flush();
|
$manager->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function setVisitDate(Visit $visit, string $date): Visit
|
/**
|
||||||
|
* @param callable(): Visit $createVisit
|
||||||
|
*/
|
||||||
|
private function setVisitDate(callable $createVisit, string $date): Visit
|
||||||
{
|
{
|
||||||
$ref = new ReflectionObject($visit);
|
Chronos::setTestNow($date);
|
||||||
$dateProp = $ref->getProperty('date');
|
$visit = $createVisit();
|
||||||
$dateProp->setAccessible(true);
|
Chronos::setTestNow();
|
||||||
$dateProp->setValue($visit, Chronos::parse($date));
|
|
||||||
|
|
||||||
return $visit;
|
return $visit;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue