Completed
Pull Request — master (#176)
by Alejandro
03:36
created

ProcessVisitsCommandTest::setUp()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16

Duplication

Lines 16
Ratio 100 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 16
loc 16
rs 9.7333
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace ShlinkioTest\Shlink\CLI\Command\Visit;
5
6
use PHPUnit\Framework\TestCase;
7
use Prophecy\Argument;
8
use Prophecy\Prophecy\ObjectProphecy;
9
use Shlinkio\Shlink\CLI\Command\Visit\ProcessVisitsCommand;
10
use Shlinkio\Shlink\Common\Service\IpApiLocationResolver;
11
use Shlinkio\Shlink\Core\Entity\Visit;
12
use Shlinkio\Shlink\Core\Service\VisitService;
13
use Symfony\Component\Console\Application;
14
use Symfony\Component\Console\Tester\CommandTester;
15
use Zend\I18n\Translator\Translator;
16
17
class ProcessVisitsCommandTest extends TestCase
18
{
19
    /**
20
     * @var CommandTester
21
     */
22
    protected $commandTester;
23
    /**
24
     * @var ObjectProphecy
25
     */
26
    protected $visitService;
27
    /**
28
     * @var ObjectProphecy
29
     */
30
    protected $ipResolver;
31
32 View Code Duplication
    public function setUp()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
33
    {
34
        $this->visitService = $this->prophesize(VisitService::class);
35
        $this->ipResolver = $this->prophesize(IpApiLocationResolver::class);
36
        $this->ipResolver->getApiLimit()->willReturn(10000000000);
37
38
        $command = new ProcessVisitsCommand(
39
            $this->visitService->reveal(),
40
            $this->ipResolver->reveal(),
41
            Translator::factory([])
42
        );
43
        $app = new Application();
44
        $app->add($command);
45
46
        $this->commandTester = new CommandTester($command);
47
    }
48
49
    /**
50
     * @test
51
     */
52
    public function allReturnedVisitsIpsAreProcessed()
53
    {
54
        $visits = [
55
            (new Visit())->setRemoteAddr('1.2.3.4'),
56
            (new Visit())->setRemoteAddr('4.3.2.1'),
57
            (new Visit())->setRemoteAddr('12.34.56.78'),
58
        ];
59
        $this->visitService->getUnlocatedVisits()->willReturn($visits)
60
                                                 ->shouldBeCalledTimes(1);
61
62
        $this->visitService->saveVisit(Argument::any())->shouldBeCalledTimes(count($visits));
63
        $this->ipResolver->resolveIpLocation(Argument::any())->willReturn([])
64
                                                             ->shouldBeCalledTimes(count($visits));
65
66
        $this->commandTester->execute([
67
            'command' => 'visit:process',
68
        ]);
69
        $output = $this->commandTester->getDisplay();
70
        $this->assertTrue(strpos($output, 'Processing IP 1.2.3.4') === 0);
71
        $this->assertTrue(strpos($output, 'Processing IP 4.3.2.1') > 0);
72
        $this->assertTrue(strpos($output, 'Processing IP 12.34.56.78') > 0);
73
    }
74
75
    /**
76
     * @test
77
     */
78
    public function localhostAddressIsIgnored()
79
    {
80
        $visits = [
81
            (new Visit())->setRemoteAddr('1.2.3.4'),
82
            (new Visit())->setRemoteAddr('4.3.2.1'),
83
            (new Visit())->setRemoteAddr('12.34.56.78'),
84
            (new Visit())->setRemoteAddr('127.0.0.1'),
85
            (new Visit())->setRemoteAddr('127.0.0.1'),
86
        ];
87
        $this->visitService->getUnlocatedVisits()->willReturn($visits)
88
            ->shouldBeCalledTimes(1);
89
90
        $this->visitService->saveVisit(Argument::any())->shouldBeCalledTimes(count($visits) - 2);
91
        $this->ipResolver->resolveIpLocation(Argument::any())->willReturn([])
92
                                                             ->shouldBeCalledTimes(count($visits) - 2);
93
94
        $this->commandTester->execute([
95
            'command' => 'visit:process',
96
        ]);
97
        $output = $this->commandTester->getDisplay();
98
        $this->assertTrue(strpos($output, 'Ignored localhost address') > 0);
99
    }
100
101
    /**
102
     * @test
103
     */
104
    public function sleepsEveryTimeTheApiLimitIsReached()
105
    {
106
        $visits = [
107
            (new Visit())->setRemoteAddr('1.2.3.4'),
108
            (new Visit())->setRemoteAddr('4.3.2.1'),
109
            (new Visit())->setRemoteAddr('12.34.56.78'),
110
            (new Visit())->setRemoteAddr('1.2.3.4'),
111
            (new Visit())->setRemoteAddr('4.3.2.1'),
112
            (new Visit())->setRemoteAddr('12.34.56.78'),
113
            (new Visit())->setRemoteAddr('1.2.3.4'),
114
            (new Visit())->setRemoteAddr('4.3.2.1'),
115
            (new Visit())->setRemoteAddr('12.34.56.78'),
116
            (new Visit())->setRemoteAddr('4.3.2.1'),
117
        ];
118
        $apiLimit = 3;
119
120
        $this->visitService->getUnlocatedVisits()->willReturn($visits);
121
        $this->visitService->saveVisit(Argument::any())->will(function () {
122
        });
123
124
        $getApiLimit = $this->ipResolver->getApiLimit()->willReturn($apiLimit);
125
        $getApiInterval = $this->ipResolver->getApiInterval()->willReturn(0);
126
        $resolveIpLocation = $this->ipResolver->resolveIpLocation(Argument::any())->willReturn([])
127
            ->shouldBeCalledTimes(count($visits));
128
129
        $this->commandTester->execute([
130
            'command' => 'visit:process',
131
        ]);
132
133
        $getApiLimit->shouldHaveBeenCalledTimes(\count($visits));
134
        $getApiInterval->shouldHaveBeenCalledTimes(\round(\count($visits) / $apiLimit));
135
        $resolveIpLocation->shouldHaveBeenCalledTimes(\count($visits));
136
    }
137
}
138