Completed
Pull Request — master (#8)
by Laurens
02:34
created

ClientTest::testSetApiDetails()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 28
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 1
Metric Value
c 3
b 0
f 1
dl 0
loc 28
rs 8.8571
cc 1
eloc 21
nc 1
nop 0
1
<?php
2
namespace Test\Werkspot\BingAdsApiBundle\Api;
3
4
use BingAds\Bulk\ReportTimePeriod;
5
use BingAds\Proxy\ClientProxy;
6
use GuzzleHttp\Client as GuzzleClient;
7
use Mockery;
8
use Mockery\MockInterface;
9
use PHPUnit_Framework_TestCase;
10
use SoapFault;
11
use stdClass;
12
use Symfony\Component\Filesystem\Filesystem;
13
use Symfony\Component\Finder\Finder;
14
use Werkspot\BingAdsApiBundle\Api\Client;
15
use Werkspot\BingAdsApiBundle\Api\Exceptions;
16
use Werkspot\BingAdsApiBundle\Api\Helper;
17
use Werkspot\BingAdsApiBundle\Guzzle\OauthTokenService;
18
use Werkspot\BingAdsApiBundle\Model\AccessToken;
19
use Werkspot\BingAdsApiBundle\Model\ApiDetails;
20
21
class ClientTest extends PHPUnit_Framework_TestCase
22
{
23
    const ACCESS_TOKEN = '2ec09aeccaf634d982eec793037e37fe';
24
    const REFRESH_TOKEN = '0c59f7e609b0cc467067e39d523116ce';
25
26
    public function testSetApiDetails()
27
    {
28
        $newApiDetails = new ApiDetails('1', '2', '3', '4', '5');
29
30
        $expected = $this->getApiClient(
31
            new OauthTokenService(new \GuzzleHttp\Client()),
32
            $newApiDetails,
33
            new ClientProxy('example.com'),
34
            $this->getFileHelper(),
35
            new Helper\Csv(),
36
            $this->getTimeHelperMock(),
37
            new Filesystem()
38
        );
39
40
        $api = $this->getApiClient(
41
            new OauthTokenService(new \GuzzleHttp\Client()),
42
            new ApiDetails(null, null, null, null, null),
43
            new ClientProxy('example.com'),
44
            $this->getFileHelper(),
45
            new Helper\Csv(),
46
            $this->getTimeHelperMock(),
47
            new Filesystem()
48
        );
49
50
        $this->assertNotEquals($expected, $api);
51
        $api->setApiDetails($newApiDetails);
52
        $this->assertEquals($expected, $api);
53
    }
54
55
    /**
56
     * @dataProvider getTestSoapExceptionData
57
     *
58
     * @param int $code
59
     * @param string $exceptionClassName
60
     */
61
    public function testSoapExceptions($code, $exceptionClassName)
62
    {
63
        $this->expectException($exceptionClassName);
64
        $this->runClientSoapException($code);
65
    }
66
67
    /**
68
     * @dataProvider getTestSoapExceptionData
69
     *
70
     * @param int $code
71
     * @param string $exceptionClassName
72
     */
73
    public function testSoapOperationErrorExceptions($code, $exceptionClassName)
74
    {
75
        $this->expectException($exceptionClassName);
76
        $this->runClientSoapException($code, 'OperationError');
77
    }
78
79
    /**
80
     * @dataProvider getTestSoapExceptionData
81
     *
82
     * @param int $code
83
     * @param string $exceptionClassName
84
     */
85
    public function testSoapBatchErrorExceptions($code, $exceptionClassName)
86
    {
87
        $this->expectException($exceptionClassName);
88
        $this->runClientSoapException($code, 'BatchErrors');
89
    }
90
91
    public function getTestSoapExceptionData()
92
    {
93
        return [
94
            0 => [
95
                'errorCode' => 0,
96
                'exceptionClassName' => Exceptions\SoapInternalErrorException::class
97
            ],
98
            105 => [
99
                'errorCode' => 105,
100
                'exceptionClassName' => Exceptions\SoapInvalidCredentialsException::class,
101
            ],
102
            106 => [
103
                'errorCode' => 106,
104
                'exceptionClassName' => Exceptions\SoapUserIsNotAuthorizedException::class,
105
            ],
106
            2004 => [
107
                'errorCode' => 2004,
108
                'exceptionClassName' => Exceptions\SoapNoCompleteDataAvailableException::class,
109
            ],
110
            2100 => [
111
                'errorCode' => 2100,
112
                'exceptionClassName' => Exceptions\SoapReportingServiceInvalidReportIdException::class,
113
            ],
114
            9999 => [
115
                'errorCode' => 9999,
116
                'exceptionClassName' => Exceptions\SoapUnknownErrorException::class,
117
            ],
118
        ];
119
    }
120
121
    /**
122
     * @param int $code
123
     * @param null|string $type
124
     *
125
     * @return MockInterface
126
     */
127
    private function runClientSoapException($code, $type = null)
128
    {
129
        $clientProxyMock = $this->getClientProxyMock();
130
        $clientProxyMock
131
            ->shouldReceive('GetService')
132
            ->andThrow($this->generateSoapFault($code, $type));
133
134
        $apiClient = $this->getApiClient(
135
            $this->getOauthTokenServiceMock(),
136
            new ApiDetails('refreshToken', 'clientId', 'clientSecret', 'redirectUri', 'devToken'),
137
            $clientProxyMock,
138
            $this->getFileHelper(),
139
            new Helper\Csv(),
140
            $this->getTimeHelperMock(),
141
            new Filesystem()
142
        );
143
144
        $apiClient->getReport('GeoLocationPerformanceReport', [], ReportTimePeriod::LastWeek, 'test.csv');
145
    }
146
147
    /**
148
     * @return Mockery\MockInterface
149
     */
150
    private function getOauthTokenServiceMock()
151
    {
152
        $oauthTokenServiceMock = Mockery::mock(OauthTokenService::class);
153
        $oauthTokenServiceMock
154
            ->shouldReceive('refreshToken')
155
            ->with('clientId', 'clientSecret', 'redirectUri', AccessToken::class)
156
            ->once()
157
            ->andReturn(new AccessToken(self::ACCESS_TOKEN, self::REFRESH_TOKEN));
158
159
        return $oauthTokenServiceMock;
160
    }
161
162
    private function getTimeHelperMock()
163
    {
164
        $timeHelperMock = Mockery::mock(Helper\Time::class);
165
        $timeHelperMock->shouldReceive('sleep')->andReturnNull();
166
167
        return $timeHelperMock;
168
    }
169
170
    /**
171
     * @param OauthTokenService $oauthTokenService
172
     * @param ApiDetails $apiDetails
173
     * @param ClientProxy $clientProxy
174
     * @param Helper\File $fileHelper
175
     * @param Helper\Csv $csvHelper
176
     * @param Helper\Time $timeHelper
177
     * @param Filesystem $filesystem
178
     *
179
     * @return Client
180
     */
181
    private function getApiClient(OauthTokenService $oauthTokenService, ApiDetails $apiDetails, ClientProxy $clientProxy, Helper\File $fileHelper, Helper\Csv $csvHelper, Helper\Time $timeHelper, Filesystem $filesystem)
182
    {
183
        $apiClient = new Client($oauthTokenService, $apiDetails, $clientProxy, $fileHelper, $csvHelper, $timeHelper, $filesystem);
184
        $apiClient->setConfig(['cache_dir' => '/tmp']);
185
186
        return $apiClient;
187
    }
188
189
    /**
190
     * @param int $code
191
     * @param null|string $type
192
     *
193
     * @return \SoapFault
194
     */
195
    private function generateSoapFault($code, $type = null)
196
    {
197
        $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...
198
        $error = new stdClass();
199
        $error->Code = $code;
200
        $error->Message = $message;
201
        $exception = new SoapFault('Server', '');
202
        $exception->detail = new stdClass();
203
        if ($type === 'BatchErrors') {
204
            $exception->detail->ApiFaultDetail = new stdClass();
205
            $exception->detail->ApiFaultDetail->BatchErrors = new stdClass();
206
            $exception->detail->ApiFaultDetail->BatchErrors->BatchError = [$error];
207
        } elseif ($type === 'OperationError') {
208
            $exception->detail->ApiFaultDetail = new stdClass();
209
            $exception->detail->ApiFaultDetail->OperationErrors = new stdClass();
210
            $exception->detail->ApiFaultDetail->OperationErrors->OperationError = [$error];
211
        } else {
212
            $exception->detail->AdApiFaultDetail = new stdClass();
213
            $exception->detail->AdApiFaultDetail->Errors = new stdClass();
214
            $exception->detail->AdApiFaultDetail->Errors->AdApiError = [$error];
215
        }
216
217
        return $exception;
218
    }
219
220
    private function getClientProxyMock()
221
    {
222
        $clientProxyMock = Mockery::mock(ClientProxy::class);
223
        $clientProxyMock
224
            ->shouldReceive('ConstructWithCredentials')
225
            ->andReturnSelf()
226
            ->once()
227
            ->shouldReceive('GetNamespace')
228
            ->andReturn('Namespace');
229
230
        return $clientProxyMock;
231
    }
232
233
    /**
234
     * @return Helper\File
235
     */
236
    private function getFileHelper()
237
    {
238
        return  new Helper\File(new GuzzleClient(), new Filesystem(), new Finder());
239
    }
240
}
241