Completed
Pull Request — master (#6)
by Laurens
03:01
created

ClientTest::runClientSoapException()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 17
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 0 Features 2
Metric Value
c 5
b 0
f 2
dl 0
loc 17
rs 9.4285
cc 1
eloc 13
nc 1
nop 2
1
<?php
2
3
namespace Test\Werkspot\BingAdsApiBundle\Api;
4
5
use BingAds\Bulk\ReportTimePeriod;
6
use BingAds\Proxy\ClientProxy;
7
use Mockery;
8
use Mockery\MockInterface;
9
use PHPUnit_Framework_TestCase;
10
use Werkspot\BingAdsApiBundle\Api\Client;
11
use Werkspot\BingAdsApiBundle\Api\Exceptions;
12
use Werkspot\BingAdsApiBundle\Api\Helper;
13
use Werkspot\BingAdsApiBundle\Guzzle\OauthTokenService;
14
use Werkspot\BingAdsApiBundle\Model\AccessToken;
15
use Werkspot\BingAdsApiBundle\Model\ApiDetails;
16
17
class ClientTest extends PHPUnit_Framework_TestCase
18
{
19
    const ACCESS_TOKEN = '2ec09aeccaf634d982eec793037e37fe';
20
    const REFRESH_TOKEN = '0c59f7e609b0cc467067e39d523116ce';
21
22
    public function testSetApiDetails()
23
    {
24
        $expected = new Client(
25
            new OauthTokenService(new \GuzzleHttp\Client()),
26
            new ApiDetails('1', '2', '3', '4', '5'),
27
            new ClientProxy('example.com'),
28
            new Helper\File(),
29
            new Helper\Csv(),
30
            $this->getTimeHelperMock()
31
        );
32
33
        $api = new Client(
34
            new OauthTokenService(new \GuzzleHttp\Client()),
35
            new ApiDetails(null, null, null, null, null),
36
            new ClientProxy('example.com'),
37
            new Helper\File(),
38
            new Helper\Csv(),
39
            $this->getTimeHelperMock()
40
        );
41
        $api->setApiDetails(new ApiDetails('1', '2', '3', '4', '5'));
42
        $this->assertEquals($expected, $api);
43
    }
44
45
    /**
46
     * @dataProvider getTestSoapExceptionData
47
     *
48
     * @param int $code
49
     * @param string $exceptionClassName
50
     */
51
    public function testSoapExceptions($code, $exceptionClassName)
52
    {
53
        $this->expectException($exceptionClassName);
54
        $this->runClientSoapException($code);
55
    }
56
57
    /**
58
     * @dataProvider getTestSoapExceptionData
59
     *
60
     * @param int $code
61
     * @param string $exceptionClassName
62
     */
63
    public function testSoapOperationErrorExceptions($code, $exceptionClassName)
64
    {
65
        $this->expectException($exceptionClassName);
66
        $this->runClientSoapException($code, 'OperationError');
67
    }
68
69
    /**
70
     * @dataProvider getTestSoapExceptionData
71
     *
72
     * @param int $code
73
     * @param string $exceptionClassName
74
     */
75
    public function testSoapAdApiErrorExceptions($code, $exceptionClassName)
76
    {
77
        $this->expectException($exceptionClassName);
78
        $this->runClientSoapException($code, 'BatchErrors');
79
    }
80
81
    public function getTestSoapExceptionData()
82
    {
83
        return [
84
            0 => [
85
                'errorCode' => 0,
86
                'exceptionClassName' => Exceptions\SoapInternalErrorException::class
87
            ],
88
            105 => [
89
                'errorCode' => 105,
90
                'exceptionClassName' => Exceptions\SoapInvalidCredentialsException::class,
91
            ],
92
            106 => [
93
                'errorCode' => 106,
94
                'exceptionClassName' => Exceptions\SoapUserIsNotAuthorizedException::class,
95
            ],
96
            2004 => [
97
                'errorCode' => 2004,
98
                'exceptionClassName' => Exceptions\SoapNoCompleteDataAvailableException::class,
99
            ],
100
            2100 => [
101
                'errorCode' => 2100,
102
                'exceptionClassName' => Exceptions\SoapReportingServiceInvalidReportIdException::class,
103
            ],
104
            9999 => [
105
                'errorCode' => 9999,
106
                'exceptionClassName' => Exceptions\SoapUnknownErrorException::class,
107
            ],
108
        ];
109
    }
110
111
    /**
112
     * @var int $code
113
     * @var null|string $type
114
     *
115
     * @return MockInterface
0 ignored issues
show
Documentation introduced by
Should the return type not be MockInterface|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
116
     */
117
    private function runClientSoapException($code, $type = null)
118
    {
119
        $clientProxyMock = $this->getClientProxyMock();
120
        $clientProxyMock
121
            ->shouldReceive('GetService')
122
            ->andThrow($this->generateSoapFault($code, $type));
123
124
        $apiClient = $this->getApiClient(
125
            $this->getOauthTokenServiceMock(),
126
            new ApiDetails('refreshToken', 'clientId', 'clientSecret', 'redirectUri', 'devToken'),
127
            $clientProxyMock,
128
            new Helper\File(),
129
            new Helper\Csv(),
130
            $this->getTimeHelperMock()
131
        );
132
        $apiClient->get([], 'GeoLocationPerformanceReport', ReportTimePeriod::LastWeek);
133
    }
134
135
    /**
136
     * @return Mockery\MockInterface
137
     */
138 View Code Duplication
    private function getOauthTokenServiceMock()
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...
139
    {
140
        $oauthTokenServiceMock = Mockery::mock(OauthTokenService::class);
141
        $oauthTokenServiceMock
142
            ->shouldReceive('refreshToken')
143
            ->with('clientId', 'clientSecret', 'redirectUri', AccessToken::class)
144
            ->once()
145
            ->andReturn(new AccessToken(self::ACCESS_TOKEN, self::REFRESH_TOKEN));
146
147
        return $oauthTokenServiceMock;
148
    }
149
150
    private function getTimeHelperMock()
151
    {
152
        $timeHelperMock = Mockery::mock(Helper\Time::class);
153
        $timeHelperMock->shouldReceive('sleep')->andReturnNull();
154
155
        return $timeHelperMock;
156
    }
157
158
    /**
159
     * @param OauthTokenService $oauthTokenService
160
     * @param ClientProxy $clientProxy
161
     * @param Helper\File $fileHelper
162
     * @param Helper\Csv $csvHelper
163
     * @param Helper\Time $timeHelper
164
     *
165
     * @return Client
166
     */
167 View Code Duplication
    private function getApiClient(OauthTokenService $oauthTokenService, 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...
168
    {
169
        $apiClient = new Client($oauthTokenService, $apiDetails, $clientProxy, $fileHelper, $csvHelper, $timeHelper);
170
        $apiClient->setConfig(['cache_dir' => '/tmp']);
171
172
        return $apiClient;
173
    }
174
175
    private function generateSoapFault($code, $type = null)
176
    {
177
        $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...
178
        $error = new \stdClass();
179
        $error->Code = $code;
180
        $error->Message = $message;
181
        $exception = new \SoapFault('Server', '');
182
        $exception->detail = new \stdClass();
183
        if ($type === 'BatchErrors') {
184
            $exception->detail->ApiFaultDetail = new \stdClass();
185
            $exception->detail->ApiFaultDetail->BatchErrors = [$error];
186
        } elseif ($type === 'OperationError') {
187
            $exception->detail->ApiFaultDetail = new \stdClass();
188
            $exception->detail->ApiFaultDetail->OperationErrors = new \stdClass();
189
            $exception->detail->ApiFaultDetail->OperationErrors->OperationError = [$error];
190
        } else {
191
            $exception->detail->AdApiFaultDetail = new \stdClass();
192
            $exception->detail->AdApiFaultDetail->Errors = new \stdClass();
193
            $exception->detail->AdApiFaultDetail->Errors->AdApiError = [$error];
194
        }
195
196
        return $exception;
197
    }
198
199
    private function getClientProxyMock()
200
    {
201
        $clientProxyMock = Mockery::mock(ClientProxy::class);
202
        $clientProxyMock
203
            ->shouldReceive('ConstructWithCredentials')
204
            ->andReturnSelf()
205
            ->once()
206
            ->shouldReceive('GetNamespace')
207
            ->andReturn('Namespace');
208
209
        return $clientProxyMock;
210
    }
211
}
212