Failed Conditions
Pull Request — master (#8)
by Laurens
02:20
created

testGeoLocationPerformanceReportMoveFile()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 31
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 31
rs 8.8571
cc 1
eloc 23
nc 1
nop 0
1
<?php
2
namespace Tests\Werkspot\BingAdsApiBundle\Api\Report;
3
4
use BingAds\Bulk\ReportTimePeriod;
5
use BingAds\Proxy\ClientProxy;
6
use BingAds\Reporting\AccountThroughAdGroupReportScope;
7
use BingAds\Reporting\GeoLocationPerformanceReportRequest;
8
use BingAds\Reporting\NonHourlyReportAggregation;
9
use BingAds\Reporting\ReportFormat;
10
use BingAds\Reporting\ReportTime;
11
use Mockery;
12
use PHPUnit_Framework_TestCase;
13
use SoapFault;
14
use stdClass;
15
use Symfony\Component\Filesystem\Filesystem;
16
use Werkspot\BingAdsApiBundle\Api\Client;
17
use Werkspot\BingAdsApiBundle\Api\Exceptions;
18
use Werkspot\BingAdsApiBundle\Api\Helper;
19
use Werkspot\BingAdsApiBundle\Api\Report\GeoLocationPerformanceReport;
20
use Werkspot\BingAdsApiBundle\Guzzle\OauthTokenService;
21
use Werkspot\BingAdsApiBundle\Model\AccessToken;
22
use Werkspot\BingAdsApiBundle\Model\ApiDetails;
23
24
class GeoLocationPerformanceReportTest extends PHPUnit_Framework_TestCase
25
{
26
    const YESTERDAY = 'Yesterday';
27
    const ACCESS_TOKEN = '2ec09aeccaf634d982eec793037e37fe';
28
    const REFRESH_TOKEN = '0c59f7e609b0cc467067e39d523116ce';
29
30
    const CACHE_DIR = '/tmp';
31
32
    const CSV_REPORT_PATH = 'report.csv';
33
34
    private static $LINES_IN_REPORT = ['something', 'else'];
35
36
    public function testGetRequest()
37
    {
38
        $expected = new GeoLocationPerformanceReportRequest();
39
        $expected->Format = ReportFormat::Csv;
40
        $expected->ReportName = GeoLocationPerformanceReport::NAME;
41
        $expected->ReturnOnlyCompleteData = true;
42
        $expected->Aggregation = NonHourlyReportAggregation::Daily;
43
        $expected->Scope = new AccountThroughAdGroupReportScope();
44
        $expected->Time = new ReportTime();
45
        $expected->Time->PredefinedTime = self::YESTERDAY;
46
        $expected->Columns = [];
47
48
        $report = new GeoLocationPerformanceReport();
49
        $report->setTimePeriod(self::YESTERDAY);
50
        $report->setColumns([]);
51
        $result = $report->getRequest();
52
53
        $this->assertEquals($expected, $result);
54
    }
55
56
    public function testSetAggregation()
57
    {
58
        $report = new GeoLocationPerformanceReport();
59
60
        $report->setTimePeriod(self::YESTERDAY);
61
        $report->setColumns([]);
62
        $result = $report->getRequest();
63
        $this->assertEquals(NonHourlyReportAggregation::Daily, $result->Aggregation);
64
65
        $report->setAggregation(NonHourlyReportAggregation::Monthly);
66
        $report->setTimePeriod(self::YESTERDAY);
67
        $report->setColumns([]);
68
        $result = $report->getRequest();
69
70
        $this->assertEquals(NonHourlyReportAggregation::Monthly, $result->Aggregation);
71
    }
72
73
    public function testGeoLocationPerformanceReportMoveFile()
74
    {
75
        $fileLocation = 'test.csv';
76
77
        $fileSystem = $this->getFilesystemMock();
78
79
        $fileSystem
80
            ->shouldReceive('exists')
81
            ->with(self::CACHE_DIR . '/' . Client::CACHE_SUBDIRECTORY)
82
            ->andReturn(true)
83
            ->once()
84
85
            ->shouldReceive('rename')
86
            ->with(self::CSV_REPORT_PATH, $fileLocation)
87
            ->andReturn(true)
88
            ->once();
89
90
        $apiClient = $this->getApiClient(
91
            $this->getRequestNewAccessTokenMock(),
92
            new ApiDetails('refreshToken', 'clientId', 'clientSecret', 'redirectUri', 'devToken'),
93
            $this->getClientProxyMock(),
94
            $this->getFileHelperMock(),
95
            $this->getCsvHelperMock(),
96
            $this->getTimeHelperMock(),
97
            $fileSystem
98
        );
99
100
        $this->assertEquals('refreshToken', $apiClient->getRefreshToken());
101
        $apiClient->getReport('GeoLocationPerformanceReport', ['TimePeriod', 'AccountName', 'AdGroupId'], ReportTimePeriod::LastWeek, $fileLocation);
102
        $this->assertEquals(self::REFRESH_TOKEN, $apiClient->getRefreshToken());
103
    }
104
105
    /**
106
     * @expectedException \Werkspot\BingAdsApiBundle\Api\Exceptions\RequestTimeoutException
107
     */
108
    public function testGeoLocationPerformanceReportTimeoutException()
109
    {
110
        $fileSystem = $this->getFilesystemMock();
111
        $fileSystem
112
            ->shouldReceive('exists')
113
            ->with(self::CACHE_DIR . '/' . Client::CACHE_SUBDIRECTORY)
114
            ->andReturn(true)
115
            ->once();
116
117
        $apiClient = $this->getApiClient(
118
            $this->getRequestNewAccessTokenMock(),
119
            new ApiDetails('refreshToken', 'clientId', 'clientSecret', 'redirectUri', 'devToken'),
120
            $this->getClientProxyMock('Pending'),
121
            new Helper\File(),
122
            new Helper\Csv(),
123
            $this->getTimeHelperMock(),
124
            $fileSystem
125
        );
126
        $apiClient->getReport('GeoLocationPerformanceReport', ['TimePeriod', 'AccountName', 'AdGroupId'], ReportTimePeriod::LastMonth, self::CSV_REPORT_PATH);
127
    }
128
129
    /**
130
     * @expectedException \Werkspot\BingAdsApiBundle\Api\Exceptions\ReportRequestErrorException
131
     */
132
    public function testGeoLocationPerformanceReportRequestErrorException()
133
    {
134
        $apiClient = $this->getApiClient(
135
            $this->getRequestNewAccessTokenMock(),
136
            new ApiDetails('refreshToken', 'clientId', 'clientSecret', 'redirectUri', 'devToken'),
137
            $this->getClientProxyMock('Error'),
138
            new Helper\File(),
139
            new Helper\Csv(),
140
            $this->getTimeHelperMock(),
141
            new Filesystem()
142
        );
143
        $apiClient->getReport('GeoLocationPerformanceReport', ['TimePeriod', 'AccountName', 'AdGroupId'], ReportTimePeriod::LastMonth, self::CSV_REPORT_PATH);
144
    }
145
146
    public function testPollGenerateReportSoapException()
147
    {
148
        $clientProxyMock = Mockery::mock(ClientProxy::class);
149
        $clientProxyMock->ReportRequestId = 'reportID';
150
        $clientProxyMock
151
            ->shouldReceive('ConstructWithCredentials')
152
            ->andReturnSelf()
153
            ->once()
154
            ->shouldReceive('GetNamespace')
155
            ->once()
156
            ->andReturn('Namespace')
157
            ->shouldReceive('GetService')
158
            ->twice()
159
            ->andReturnSelf()
160
            ->shouldReceive('SubmitGenerateReport')
161
            ->once()
162
            ->andReturnSelf()
163
            ->shouldReceive('PollGenerateReport')
164
            ->andThrow($this->generateSoapFault(0));
165
        $this->expectException(Exceptions\SoapInternalErrorException::class);
166
        $apiClient = $this->getApiClient(
167
            $this->getRequestNewAccessTokenMock(),
168
            new ApiDetails('refreshToken', 'clientId', 'clientSecret', 'redirectUri', 'devToken'),
169
            $clientProxyMock,
170
            new Helper\File(),
171
            new Helper\Csv(),
172
            $this->getTimeHelperMock(),
173
            new Filesystem()
174
        );
175
        $apiClient->getReport('GeoLocationPerformanceReport', ['TimePeriod', 'AccountName', 'AdGroupId'], ReportTimePeriod::LastMonth, self::CSV_REPORT_PATH);
176
    }
177
    /**
178
     * @return Mockery\MockInterface|ClientProxy
179
     */
180
    private function getClientProxyMock($reportStatus = 'Success')
181
    {
182
        $clientProxyMock = Mockery::mock(ClientProxy::class);
183
        $clientProxyMock
184
            ->shouldReceive('ConstructWithCredentials')
185
            ->andReturnSelf()
186
            ->once()
187
188
            ->shouldReceive('GetNamespace')
189
            ->between(1, 48)
190
            ->andReturn('Namespace')
191
192
            ->shouldReceive('GetService')
193
            ->between(2, 49)
194
            ->andReturnSelf()
195
196
            ->shouldReceive('SubmitGenerateReport')
197
            ->between(1, 48)
198
            ->andReturnSelf()
199
200
            ->shouldReceive('PollGenerateReport')
201
            ->between(1, 48)
202
            ->andReturnSelf();
203
204
        $status = new \stdClass();
205
        $status->Status = $reportStatus;
206
        $status->ReportDownloadUrl = 'http://example.com/download.zip';
207
208
        $clientProxyMock->ReportRequestId = 'reportID';
209
        $clientProxyMock->ReportRequestStatus = $status;
210
211
        return $clientProxyMock;
212
    }
213
214
    /**
215
     * @return Mockery\MockInterface|OauthTokenService
216
     */
217
    private function getRequestNewAccessTokenMock()
218
    {
219
        $oauthTokenServiceMock = Mockery::mock(OauthTokenService::class);
220
        $oauthTokenServiceMock
221
            ->shouldReceive('refreshToken')
222
            ->with('clientId', 'clientSecret', 'redirectUri', AccessToken::class)
223
            ->andReturn(new AccessToken(self::ACCESS_TOKEN, self::REFRESH_TOKEN));
224
225
        return $oauthTokenServiceMock;
226
    }
227
228
    /**
229
     * @return Mockery\MockInterface|Helper\File
230
     */
231
    private function getFileHelperMock()
232
    {
233
        $zipHelperMock = Mockery::mock(Helper\File::class);
234
        $zipHelperMock
235
            ->shouldReceive('copyFile')
236
            ->andReturn('/tmp/report.zip')
237
            ->once()
238
239
            ->shouldReceive('unZip')
240
            ->with('/tmp/report.zip')
241
            ->andReturn([self::CSV_REPORT_PATH])
242
            ->once()
243
244
            ->shouldReceive('isHealthyZipFile')
245
            ->with('/tmp/report.zip')
246
            ->andReturn(true)
247
            ->once()
248
249
            ->shouldReceive('readFileLinesIntoArray')
250
            ->with(self::CSV_REPORT_PATH)
251
            ->andReturn(self::$LINES_IN_REPORT)
252
            ->once()
253
254
            ->shouldReceive('writeLinesToFile')
255
            ->with(self::$LINES_IN_REPORT, self::CSV_REPORT_PATH)
256
            ->once()
257
        ;
258
259
        return $zipHelperMock;
260
    }
261
262
    /**
263
     * @return Mockery\MockInterface|Helper\Csv
264
     */
265
    private function getCsvHelperMock()
266
    {
267
        $lines = self::$LINES_IN_REPORT;
268
        $csvHelperMock = Mockery::mock(Helper\Csv::class);
269
        $csvHelperMock
270
            ->shouldReceive('removeHeaders')
271
            ->andReturn($lines)
272
            ->once()
273
            ->shouldReceive('removeLastLines')
274
            ->andReturn($lines)
275
            ->once()
276
            ->shouldReceive('convertDateMDYtoYMD')
277
            ->andReturn($lines)
278
            ->once();
279
280
        return $csvHelperMock;
281
    }
282
283
    /**
284
     * @return Mockery\MockInterface|Helper\Time
285
     */
286
    private function getTimeHelperMock()
287
    {
288
        $timeHelperMock = Mockery::mock(Helper\Time::class);
289
        $timeHelperMock->shouldReceive('sleep')->andReturnNull();
290
291
        return $timeHelperMock;
292
    }
293
294
    /**
295
     * @param OauthTokenService $requestNewAccessToken
296
     * @param ApiDetails $apiDetails
297
     * @param ClientProxy $clientProxy
298
     * @param Helper\File $fileHelper
299
     * @param Helper\Csv $csvHelper
300
     * @param Helper\Time $timeHelper
301
     * @param Filesystem $fileSystem
302
     *
303
     * @return Client
304
     */
305
    private function getApiClient(OauthTokenService $requestNewAccessToken, ApiDetails $apiDetails, ClientProxy $clientProxy, Helper\File $fileHelper, Helper\Csv $csvHelper, Helper\Time $timeHelper, Filesystem $fileSystem)
306
    {
307
        $apiClient = new Client($requestNewAccessToken, $apiDetails, $clientProxy, $fileHelper, $csvHelper, $timeHelper, $fileSystem);
308
        $apiClient->setConfig(['cache_dir' => self::CACHE_DIR]);
309
310
        return $apiClient;
311
    }
312
313
    /**
314
     * @param $code
315
     *
316
     * @return SoapFault
317
     */
318
    private function generateSoapFault($code)
319
    {
320
        $message = "an error message {$code}";
0 ignored issues
show
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $code instead of interpolation.

It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings.

// Instead of
$x = "foo $bar $baz";

// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
Loading history...
321
        $error = new stdClass();
322
        $error->Code = $code;
323
        $error->Message = $message;
324
        $exception = new SoapFault('Server', '');
325
        $exception->detail = new stdClass();
326
        $exception->detail->AdApiFaultDetail = new stdClass();
327
        $exception->detail->AdApiFaultDetail->Errors = new stdClass();
328
        $exception->detail->AdApiFaultDetail->Errors->AdApiError = [$error];
329
330
        return $exception;
331
    }
332
333
    /**
334
     * @return Mockery\MockInterface|Filesystem
335
     */
336
    private function getFilesystemMock()
337
    {
338
        return Mockery::mock(Filesystem::class);
339
    }
340
}
341