Skip to content

Commit

Permalink
Merge pull request #40 from acelaya-forks/feature/visits-summary-bots
Browse files Browse the repository at this point in the history
Feature/visits summary bots
  • Loading branch information
acelaya authored Mar 23, 2023
2 parents 9f8bb28 + d3f5a06 commit 422a44d
Show file tree
Hide file tree
Showing 8 changed files with 144 additions and 43 deletions.
6 changes: 3 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this

## [Unreleased]
### Added
* *Nothing*
* [#38](https://github.com/shlinkio/shlink-php-sdk/issues/38) Add support for bot and non-bot visits in summary.

### Changed
* Replaced references to `doma.in` by `s.test`.
* Updated to PHPUnit 10.
* Replace references to `doma.in` by `s.test`.
* Update to PHPUnit 10.

### Deprecated
* *Nothing*
Expand Down
4 changes: 2 additions & 2 deletions docs/contexts/visits.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ use function count;

$summary = $visitsClient->getVisitsSummary();

echo 'Non-orphan visits: ' . $summary->visitsCount;
echo 'Orphan visits: ' . $summary->orphanVisitsCount;
echo 'Non-orphan visits: ' . $summary->nonOrphanVisits->total;
echo 'Orphan visits: ' . $summary->orphanVisits->total;
echo 'Total visits: ' . count($summary);
```

Expand Down
27 changes: 14 additions & 13 deletions src/ShortUrls/Model/ShortUrl.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use DateTimeImmutable;
use DateTimeInterface;
use Shlinkio\Shlink\SDK\Visits\Model\VisitsCount;

final class ShortUrl
{
Expand All @@ -24,7 +25,7 @@ private function __construct(
public readonly bool $forwardQuery,
public readonly array $tags,
public readonly ShortUrlMeta $meta,
public readonly ShortUrlVisitsSummary $visitsSummary,
public readonly VisitsCount $visitsSummary,
) {
$this->visitsCount = $visitsCount;
}
Expand All @@ -34,19 +35,19 @@ public static function fromArray(array $payload): self
$visitsCount = $payload['visitsCount'] ?? 0;

return new self(
$payload['shortCode'] ?? '',
$payload['shortUrl'] ?? '',
$payload['longUrl'] ?? '',
shortCode: $payload['shortCode'] ?? '',
shortUrl: $payload['shortUrl'] ?? '',
longUrl: $payload['longUrl'] ?? '',
// @phpstan-ignore-next-line
DateTimeImmutable::createFromFormat(DateTimeInterface::ATOM, $payload['dateCreated']),
$visitsCount,
$payload['domain'] ?? null,
$payload['title'] ?? null,
$payload['crawlable'] ?? false,
$payload['forwardQuery'] ?? false,
$payload['tags'] ?? [],
ShortUrlMeta::fromArray($payload['meta'] ?? []),
ShortUrlVisitsSummary::fromArrayWithFallback($payload['visitsSummary'] ?? [], $visitsCount),
dateCreated: DateTimeImmutable::createFromFormat(DateTimeInterface::ATOM, $payload['dateCreated']),
visitsCount: $visitsCount,
domain: $payload['domain'] ?? null,
title: $payload['title'] ?? null,
crawlable: $payload['crawlable'] ?? false,
forwardQuery: $payload['forwardQuery'] ?? false,
tags: $payload['tags'] ?? [],
meta: ShortUrlMeta::fromArray($payload['meta'] ?? []),
visitsSummary: VisitsCount::fromArrayWithFallback($payload['visitsSummary'] ?? [], $visitsCount),
);
}
}
14 changes: 9 additions & 5 deletions src/ShortUrls/Model/ShortUrlVisitsSummary.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,22 @@

namespace Shlinkio\Shlink\SDK\ShortUrls\Model;

final class ShortUrlVisitsSummary
/**
* @deprecated Use VisitsCount instead
*/
class ShortUrlVisitsSummary
{
private function __construct(
public readonly int $total,
public readonly ?int $nonBots,
public readonly ?int $bots,
public readonly ?int $nonBots,// These are optional for Shlink <3.4.0
public readonly ?int $bots,// These are optional for Shlink <3.4.0
) {
}

public static function fromArrayWithFallback(array $payload, int $fallbackTotal): self
public static function fromArrayWithFallback(array $payload, int $fallbackTotal): static
{
return new self(
// @phpstan-ignore-next-line
return new static(
$payload['total'] ?? $fallbackTotal,
$payload['nonBots'] ?? null,
$payload['bots'] ?? null,
Expand Down
15 changes: 15 additions & 0 deletions src/Visits/Model/VisitsCount.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

namespace Shlinkio\Shlink\SDK\Visits\Model;

use Shlinkio\Shlink\SDK\ShortUrls\Model\ShortUrlVisitsSummary;

/**
* @todo This class should be called VisitsSummary for consistency on how things are called in Shlink, but there's
* another class with that name already
*/
final class VisitsCount extends ShortUrlVisitsSummary
{
}
30 changes: 25 additions & 5 deletions src/Visits/Model/VisitsSummary.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,42 @@

use Countable;

/**
* @todo This class should have a different name, so that VisitsCount could be called VisitsSummary.
* Perhaps VisitsAmounts.
*/
final class VisitsSummary implements Countable
{
private function __construct(public readonly int $visitsCount, public readonly int $orphanVisitsCount)
{
/** @deprecated Use $nonOrphanVisits->total instead */
public readonly int $visitsCount;
/** @deprecated Use $orphanVisits->total instead */
public readonly int $orphanVisitsCount;

private function __construct(
public readonly VisitsCount $nonOrphanVisits,
public readonly VisitsCount $orphanVisits,
int $visitsCount,
int $orphanVisitsCount,
) {
$this->visitsCount = $visitsCount;
$this->orphanVisitsCount = $orphanVisitsCount;
}

public static function fromArray(array $payload): self
{
$visitsCount = $payload['visitsCount'] ?? 0;
$orphanVisitsCount = $payload['orphanVisitsCount'] ?? 0;

return new self(
$payload['visitsCount'] ?? 0,
$payload['orphanVisitsCount'] ?? 0,
nonOrphanVisits: VisitsCount::fromArrayWithFallback($payload['nonOrphanVisits'] ?? [], $visitsCount),
orphanVisits: VisitsCount::fromArrayWithFallback($payload['orphanVisits'] ?? [], $orphanVisitsCount),
visitsCount: $visitsCount,
orphanVisitsCount: $orphanVisitsCount,
);
}

public function count(): int
{
return $this->visitsCount + $this->orphanVisitsCount;
return $this->nonOrphanVisits->total + $this->orphanVisits->total;
}
}
10 changes: 5 additions & 5 deletions test/ShortUrls/Model/ShortUrlTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
use PHPUnit\Framework\TestCase;
use Shlinkio\Shlink\SDK\ShortUrls\Model\ShortUrl;
use Shlinkio\Shlink\SDK\ShortUrls\Model\ShortUrlMeta;
use Shlinkio\Shlink\SDK\ShortUrls\Model\ShortUrlVisitsSummary;
use Shlinkio\Shlink\SDK\Visits\Model\VisitsCount;

class ShortUrlTest extends TestCase
{
Expand All @@ -29,7 +29,7 @@ public function properObjectIsCreatedFromArray(
bool $expectedForwardQuery,
array $expectedTags,
ShortUrlMeta $expectedMeta,
ShortUrlVisitsSummary $expectedVisitsSummary,
VisitsCount $expectedVisitsSummary,
): void {
$shortUrl = ShortUrl::fromArray($payload);

Expand Down Expand Up @@ -65,7 +65,7 @@ public static function providePayloads(): iterable
false,
[],
ShortUrlMeta::fromArray([]),
ShortUrlVisitsSummary::fromArrayWithFallback([], 0),
VisitsCount::fromArrayWithFallback([], 0),
];
yield 'all values' => [
[
Expand Down Expand Up @@ -99,7 +99,7 @@ public static function providePayloads(): iterable
true,
['foo', 'bar'],
ShortUrlMeta::fromArray($meta),
ShortUrlVisitsSummary::fromArrayWithFallback($visitsSummary, 5),
VisitsCount::fromArrayWithFallback($visitsSummary, 5),
];
yield 'visits total fallback' => [
['dateCreated' => $formattedDate, 'visitsCount' => 35],
Expand All @@ -114,7 +114,7 @@ public static function providePayloads(): iterable
false,
[],
ShortUrlMeta::fromArray([]),
ShortUrlVisitsSummary::fromArrayWithFallback([], 35),
VisitsCount::fromArrayWithFallback([], 35),
];
}
}
81 changes: 71 additions & 10 deletions test/Visits/VisitsClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use Shlinkio\Shlink\SDK\Tags\Exception\TagNotFoundException;
use Shlinkio\Shlink\SDK\Visits\Model\VisitInterface;
use Shlinkio\Shlink\SDK\Visits\Model\VisitsList;
use Shlinkio\Shlink\SDK\Visits\Model\VisitsSummary;
use Shlinkio\Shlink\SDK\Visits\VisitsClient;
use Throwable;

Expand All @@ -40,21 +41,81 @@ public function setUp(): void
$this->now = (new DateTimeImmutable())->format(DateTimeInterface::ATOM);
}

#[Test]
public function getVisitsSummaryPerformsExpectedCall(): void
/**
* @param callable(VisitsSummary): void $assert
*/
#[Test, DataProvider('provideVisits')]
public function getVisitsSummaryPerformsExpectedCall(array $visits, callable $assert): void
{
$this->httpClient->expects($this->once())->method('getFromShlink')->with('/visits')->willReturn([
'visits' => [
'visitsCount' => 200,
'orphanVisitsCount' => 38,
],
'visits' => $visits,
]);

$result = $this->visitsClient->getVisitsSummary();
$assert($this->visitsClient->getVisitsSummary());
}

self::assertEquals(200, $result->visitsCount);
self::assertEquals(38, $result->orphanVisitsCount);
self::assertCount(238, $result);
public function provideVisits(): iterable
{
yield 'legacy response' => [[
'visitsCount' => 200,
'orphanVisitsCount' => 38,
], function (VisitsSummary $result): void {
self::assertEquals(200, $result->visitsCount);
self::assertEquals(38, $result->orphanVisitsCount);
self::assertEquals(200, $result->nonOrphanVisits->total);
self::assertEquals(38, $result->orphanVisits->total);
self::assertNull($result->nonOrphanVisits->bots);
self::assertNull($result->nonOrphanVisits->nonBots);
self::assertNull($result->orphanVisits->bots);
self::assertNull($result->orphanVisits->nonBots);
self::assertCount(238, $result);
}];
yield 'current response' => [[
'visitsCount' => 200,
'orphanVisitsCount' => 38,
'nonOrphanVisits' => [
'total' => 200,
'nonBots' => 150,
'bots' => 50,
],
'orphanVisits' => [
'total' => 38,
'nonBots' => 30,
'bots' => 8,
],
], function (VisitsSummary $result): void {
self::assertEquals(200, $result->visitsCount);
self::assertEquals(38, $result->orphanVisitsCount);
self::assertEquals(200, $result->nonOrphanVisits->total);
self::assertEquals(150, $result->nonOrphanVisits->nonBots);
self::assertEquals(50, $result->nonOrphanVisits->bots);
self::assertEquals(38, $result->orphanVisits->total);
self::assertEquals(30, $result->orphanVisits->nonBots);
self::assertEquals(8, $result->orphanVisits->bots);
self::assertCount(238, $result);
}];
yield 'future response' => [[
'nonOrphanVisits' => [
'total' => 200,
'nonBots' => 150,
'bots' => 50,
],
'orphanVisits' => [
'total' => 38,
'nonBots' => 30,
'bots' => 8,
],
], function (VisitsSummary $result): void {
self::assertEquals(0, $result->visitsCount);
self::assertEquals(0, $result->orphanVisitsCount);
self::assertEquals(200, $result->nonOrphanVisits->total);
self::assertEquals(150, $result->nonOrphanVisits->nonBots);
self::assertEquals(50, $result->nonOrphanVisits->bots);
self::assertEquals(38, $result->orphanVisits->total);
self::assertEquals(30, $result->orphanVisits->nonBots);
self::assertEquals(8, $result->orphanVisits->bots);
self::assertCount(238, $result);
}];
}

#[Test, DataProvider('provideShortUrls')]
Expand Down

0 comments on commit 422a44d

Please sign in to comment.