Completed
Pull Request — master (#4)
by Laurens
05:13
created

getClientProxyMock()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 29
Code Lines 24

Duplication

Lines 29
Ratio 100 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 29
loc 29
rs 8.8571
cc 1
eloc 24
nc 1
nop 1
1
<?php
2
3
namespace Tests\Werkspot\BingAdsApiBundle\Tests\Api\Report;
4
5
use BingAds\Bulk\ReportTimePeriod;
6
use BingAds\Proxy\ClientProxy;
7
use BingAds\Reporting\AccountThroughAdGroupReportScope;
8
use BingAds\Reporting\GeoLocationPerformanceReportRequest;
9
use BingAds\Reporting\NonHourlyReportAggregation;
10
use BingAds\Reporting\ReportFormat;
11
use BingAds\Reporting\ReportTime;
12
use Mockery;
13
use PHPUnit_Framework_TestCase;
14
use Symfony\Component\Filesystem\Filesystem;
15
use Werkspot\BingAdsApiBundle\Api\Client;
16
use Werkspot\BingAdsApiBundle\Api\Exceptions;
17
use Werkspot\BingAdsApiBundle\Api\Helper;
18
use Werkspot\BingAdsApiBundle\Api\Report\GeoLocationPerformanceReport;
19
use Werkspot\BingAdsApiBundle\Guzzle\OauthTokenService;
20
use Werkspot\BingAdsApiBundle\Model\AccessToken;
21
use Werkspot\BingAdsApiBundle\Model\ApiDetails;
22
23
class GeoLocationPerformanceReportTest extends PHPUnit_Framework_TestCase
24
{
25
    const YESTERDAY = 'Yesterday';
26
    const ACCESS_TOKEN = '2ec09aeccaf634d982eec793037e37fe';
27
    const REFRESH_TOKEN = '0c59f7e609b0cc467067e39d523116ce';
28
29
    public function testGetRequest()
30
    {
31
        $expected = new GeoLocationPerformanceReportRequest();
32
        $expected->Format = ReportFormat::Csv;
33
        $expected->ReportName = GeoLocationPerformanceReport::NAME;
34
        $expected->ReturnOnlyCompleteData = true;
35
        $expected->Aggregation = NonHourlyReportAggregation::Daily;
36
        $expected->Scope = new AccountThroughAdGroupReportScope();
37
        $expected->Time = new ReportTime();
38
        $expected->Time->PredefinedTime = self::YESTERDAY;
1 ignored issue
show
Documentation Bug introduced by
It seems like self::YESTERDAY of type string is incompatible with the declared type object<BingAds\Reporting\ReportTimePeriod> of property $PredefinedTime.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
39
        $expected->Columns = [];
40
41
        $report = new GeoLocationPerformanceReport();
42
        $result = $report->getRequest([], self::YESTERDAY);
43
44
        $this->assertEquals($expected, $result);
45
    }
46
47
    public function testSetAggregation()
48
    {
49
        $report = new GeoLocationPerformanceReport();
50
51
        $result = $report->getRequest([], self::YESTERDAY);
52
        $this->assertEquals(NonHourlyReportAggregation::Daily, $result->Aggregation);
0 ignored issues
show
Bug introduced by
The property Aggregation does not seem to exist in BingAds\Reporting\ReportRequest.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
53
54
        $report->setAggregation(NonHourlyReportAggregation::Monthly);
55
        $result = $report->getRequest([], self::YESTERDAY);
56
57
        $this->assertEquals(NonHourlyReportAggregation::Monthly, $result->Aggregation);
58
    }
59
60
    public function testGeoLocationPerformanceReportReturnsArrayWithCsv()
61
    {
62
        $apiClient = $this->getApiClient(
63
            $this->getRequestNewAccessTokenMock(),
64
            new ApiDetails('refreshToken', 'clientId', 'clientSecret', 'redirectUri', 'devToken'),
65
            $this->getClientProxyMock(),
66
            $this->getFileHelperMock(),
67
            $this->getCsvHelperMock(),
68
            $this->getTimeHelperMock()
69
        );
70
        $result = $apiClient->get(['TimePeriod', 'AccountName', 'AdGroupId'], 'GeoLocationPerformanceReport', ReportTimePeriod::LastWeek);
71
        $this->assertEquals([ASSETS_DIR . 'report.csv'], $result);
72
    }
73
74
    public function testGeoLocationPerformanceReportMoveFile()
75
    {
76
        $apiClient = $this->getApiClient(
77
            $this->getRequestNewAccessTokenMock(),
78
            new ApiDetails('refreshToken', 'clientId', 'clientSecret', 'redirectUri', 'devToken'),
79
            $this->getClientProxyMock(),
80
            $this->getFileHelperMock(),
81
            $this->getCsvHelperMock(),
82
            $this->getTimeHelperMock()
83
        );
84
        $result = $apiClient->get(['TimePeriod', 'AccountName', 'AdGroupId'], 'GeoLocationPerformanceReport', ReportTimePeriod::LastWeek, ASSETS_DIR . 'test.csv');
85
        $this->assertEquals(ASSETS_DIR . 'test.csv', $result);
86
87
        //--Move File back
88
        $fileSystem = new Filesystem();
89
        $fileSystem->rename(ASSETS_DIR . 'test.csv', ASSETS_DIR . 'report.csv');
90
    }
91
92
    public function testGetRefreshToken()
93
    {
94
        $apiClient = $this->getApiClient(
95
            $this->getRequestNewAccessTokenMock(),
96
            new ApiDetails('refreshToken', 'clientId', 'clientSecret', 'redirectUri', 'devToken'),
97
            $this->getClientProxyMock(),
98
            $this->getFileHelperMock(),
99
            $this->getCsvHelperMock(),
100
            $this->getTimeHelperMock()
101
        );
102
103
        $this->assertEquals('refreshToken', $apiClient->getRefreshToken());
104
105
        $apiClient->get(['TimePeriod', 'AccountName', 'AdGroupId'], 'GeoLocationPerformanceReport', ReportTimePeriod::LastWeek);
106
        $this->assertEquals(self::REFRESH_TOKEN, $apiClient->getRefreshToken());
107
    }
108
109 View Code Duplication
    public function testGeoLocationPerformanceReportTimeoutException()
1 ignored issue
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...
110
    {
111
        $this->expectException(Exceptions\RequestTimeoutException::class);
112
        $apiClient = $this->getApiClient(
113
            $this->getRequestNewAccessTokenMock(),
114
            new ApiDetails('refreshToken', 'clientId', 'clientSecret', 'redirectUri', 'devToken'),
115
            $this->getClientProxyMock('Pending'),
116
            new Helper\File(),
117
            new Helper\Csv(),
118
            $this->getTimeHelperMock()
119
        );
120
        $apiClient->get(['TimePeriod', 'AccountName', 'AdGroupId'], 'GeoLocationPerformanceReport');
121
    }
122
123 View Code Duplication
    public function testGeoLocationPerformanceReportRequestErrorException()
1 ignored issue
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...
124
    {
125
        $this->expectException(Exceptions\ReportRequestErrorException::class);
126
        $apiClient = $this->getApiClient(
127
            $this->getRequestNewAccessTokenMock(),
128
            new ApiDetails('refreshToken', 'clientId', 'clientSecret', 'redirectUri', 'devToken'),
129
            $this->getClientProxyMock('Error'),
130
            new Helper\File(),
131
            new Helper\Csv(),
132
            $this->getTimeHelperMock()
133
        );
134
        $apiClient->get(['TimePeriod', 'AccountName', 'AdGroupId'], 'GeoLocationPerformanceReport');
135
    }
136
137
    public function testPollGenerateReportSoapException()
138
    {
139
        $clientProxyMock = Mockery::mock(ClientProxy::class);
140
        $clientProxyMock->ReportRequestId = 'reportID';
1 ignored issue
show
Bug introduced by
Accessing ReportRequestId on the interface Mockery\MockInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
141
        $clientProxyMock
1 ignored issue
show
Bug introduced by
The method shouldReceive() does not seem to exist on object<Mockery\Expectation>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
142
            ->shouldReceive('ConstructWithCredentials')
143
            ->andReturnSelf()
144
            ->once()
145
            ->shouldReceive('GetNamespace')
146
            ->once()
147
            ->andReturn('Namespace')
148
            ->shouldReceive('GetService')
149
            ->twice()
150
            ->andReturnSelf()
151
            ->shouldReceive('SubmitGenerateReport')
152
            ->once()
153
            ->andReturnSelf()
154
            ->shouldReceive('PollGenerateReport')
155
            ->andThrow($this->generateSoapFault(0));
156
        $this->expectException(Exceptions\SoapInternalErrorException::class);
157
        $apiClient = $this->getApiClient(
158
            $this->getRequestNewAccessTokenMock(),
159
            new ApiDetails('refreshToken', 'clientId', 'clientSecret', 'redirectUri', 'devToken'),
160
            $clientProxyMock,
161
            new Helper\File(),
162
            new Helper\Csv(),
163
            $this->getTimeHelperMock()
164
        );
165
        $apiClient->get(['TimePeriod', 'AccountName', 'AdGroupId'], 'GeoLocationPerformanceReport');
166
    }
167
    /**
168
     * @return Mockery\MockInterface
169
     */
170 View Code Duplication
    private function getClientProxyMock($reportStatus = 'Success')
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...
171
    {
172
        $clientProxyMock = Mockery::mock(ClientProxy::class);
173
        $clientProxyMock
1 ignored issue
show
Bug introduced by
The method shouldReceive() does not seem to exist on object<Mockery\Expectation>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
174
            ->shouldReceive('ConstructWithCredentials')
175
            ->andReturnSelf()
176
            ->once()
177
            ->shouldReceive('GetNamespace')
178
            ->between(1, 48)
179
            ->andReturn('Namespace')
180
            ->shouldReceive('GetService')
181
            ->between(2, 49)
182
            ->andReturnSelf()
183
            ->shouldReceive('SubmitGenerateReport')
184
            ->between(1, 48)
185
            ->andReturnSelf()
186
            ->shouldReceive('PollGenerateReport')
187
            ->between(1, 48)
188
            ->andReturnSelf();
189
190
        $status = new \stdClass();
191
        $status->Status = $reportStatus;
192
        $status->ReportDownloadUrl = 'http://example.com/download.zip';
193
194
        $clientProxyMock->ReportRequestId = 'reportID';
1 ignored issue
show
Bug introduced by
Accessing ReportRequestId on the interface Mockery\MockInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
195
        $clientProxyMock->ReportRequestStatus = $status;
1 ignored issue
show
Bug introduced by
Accessing ReportRequestStatus on the interface Mockery\MockInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
196
197
        return $clientProxyMock;
198
    }
199
200
    /**
201
     * @return Mockery\MockInterface
202
     */
203 View Code Duplication
    private function getRequestNewAccessTokenMock()
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...
204
    {
205
        $requestNewAccessTokenMock = Mockery::mock(OauthTokenService::class);
206
        $requestNewAccessTokenMock
207
            ->shouldReceive('refreshToken')
208
            ->with('clientId', 'clientSecret', 'redirectUri', AccessToken::class)
209
            ->once()
210
            ->andReturn(new AccessToken(self::ACCESS_TOKEN, self::REFRESH_TOKEN));
211
212
        return $requestNewAccessTokenMock;
213
    }
214
215
    /**
216
     * @return Mockery\MockInterface
217
     */
218
    private function getFileHelperMock()
219
    {
220
        $zipHelperMock = Mockery::mock(Helper\File::class);
221
        $zipHelperMock
1 ignored issue
show
Bug introduced by
The method shouldReceive() does not seem to exist on object<Mockery\Expectation>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
222
            ->shouldReceive('getFile')
223
            ->andReturn('/tmp/report.zip')
224
            ->once()
225
            ->shouldReceive('unZip')
226
            ->with('/tmp/report.zip')
227
            ->andReturn([ASSETS_DIR . 'report.csv'])
228
            ->once();
229
230
        return $zipHelperMock;
231
    }
232
233
    /**
234
     * @return Mockery\MockInterface
235
     */
236
    private function getCsvHelperMock()
237
    {
238
        $lines = file(ASSETS_DIR . 'report.csv');
239
        $csvHelperMock = Mockery::mock(Helper\Csv::class);
240
        $csvHelperMock
1 ignored issue
show
Bug introduced by
The method shouldReceive() does not seem to exist on object<Mockery\Expectation>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
241
            ->shouldReceive('removeHeaders')
242
            ->andReturn($lines)
243
            ->once()
244
            ->shouldReceive('removeLastLines')
245
            ->andReturn($lines)
246
            ->once()
247
            ->shouldReceive('convertDateMDYtoYMD')
248
            ->andReturn($lines)
249
            ->once();
250
251
        return $csvHelperMock;
252
    }
253
254
    private function getTimeHelperMock()
255
    {
256
        $timeHelperMock = Mockery::mock(Helper\Time::class);
257
        $timeHelperMock->shouldReceive('sleep')->andReturnNull();
1 ignored issue
show
Unused Code introduced by
The call to the method Mockery\Expectation::andReturnNull() seems un-needed as the method has no side-effects.

PHP Analyzer performs a side-effects analysis of your code. A side-effect is basically anything that might be visible after the scope of the method is left.

Let’s take a look at an example:

class User
{
    private $email;

    public function getEmail()
    {
        return $this->email;
    }

    public function setEmail($email)
    {
        $this->email = $email;
    }
}

If we look at the getEmail() method, we can see that it has no side-effect. Whether you call this method or not, no future calls to other methods are affected by this. As such code as the following is useless:

$user = new User();
$user->getEmail(); // This line could safely be removed as it has no effect.

On the hand, if we look at the setEmail(), this method _has_ side-effects. In the following case, we could not remove the method call:

$user = new User();
$user->setEmail('email@domain'); // This line has a side-effect (it changes an
                                 // instance variable).
Loading history...
258
259
        return $timeHelperMock;
260
    }
261
262
    /**
263
     * @param OauthTokenService $requestNewAccessToken
264
     * @param ClientProxy $clientProxy
265
     * @param Helper\File $fileHelper
266
     * @param Helper\Csv $csvHelper
267
     * @param Helper\Time $timeHelper
268
     *
269
     * @return Client
270
     */
271 View Code Duplication
    private function getApiClient(OauthTokenService $requestNewAccessToken, ApiDetails $apiDetails, ClientProxy $clientProxy, Helper\File $fileHelper, Helper\Csv $csvHelper, Helper\Time $timeHelper)
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...
272
    {
273
        $apiClient = new Client($requestNewAccessToken, $apiDetails, $clientProxy, $fileHelper, $csvHelper, $timeHelper);
274
        $apiClient->setConfig(['cache_dir' => '/tmp']);
275
276
        return $apiClient;
277
    }
278
279 View Code Duplication
    private function generateSoapFault($code)
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...
280
    {
281
        $message = "an error message {$code}";
282
        $error = new \stdClass();
283
        $error->Code = $code;
284
        $error->Message = $message;
285
        $exception = new \SoapFault('Server', '');
286
        $exception->detail = new \stdClass();
1 ignored issue
show
Bug introduced by
The property detail does not seem to exist in SoapFault.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
287
        $exception->detail->AdApiFaultDetail = new \stdClass();
288
        $exception->detail->AdApiFaultDetail->Errors = new \stdClass();
289
        $exception->detail->AdApiFaultDetail->Errors->AdApiError = [$error];
290
291
        return $exception;
292
    }
293
}
294