Issues (14)

Security Analysis    no request data  

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

tests/ParserTest.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
namespace Thunder\SimilarWebApi\Tests;
3
4
use Thunder\SimilarWebApi\Client;
5
use Thunder\SimilarWebApi\ClientFacade;
6
use Thunder\SimilarWebApi\Parser\JsonParser;
7
use Thunder\SimilarWebApi\AbstractRequest;
8
use Thunder\SimilarWebApi\AbstractResponse;
9
use Thunder\SimilarWebApi\Parser\XmlParser;
10
11
/**
12
 * @author Tomasz Kowalczyk <[email protected]>
13
 */
14
class ParserTest extends \PHPUnit_Framework_TestCase
15
    {
16
    /**
17
     * @expectedException \RuntimeException
18
     */
19
    public function testExceptionWhenResponseClassDoesNotExist()
20
        {
21
        $endpoint = new JsonParser('Invalid', array());
22
        $endpoint->getResponse('{"content":""}');
23
        }
24
25
    /**
26
     * @dataProvider provideEndpoints
27
     */
28
    public function testClientCalls($call, $exception, array $formats,
29
                                    array $valueTests, array $arrayTests,
30
                                    array $mapTests, array $tupleTests)
31
        {
32
        $token = sha1('user_key');
33
        $clientClass = 'Thunder\\SimilarWebApi\\Client';
34
        $args = array(
35
            'domain' => 'google.com',
36
            'app' => 'com.google.app.id',
37
            'page' => 1,
38
            'period' => 'weekly',
39
            'start' => '08-2014',
40
            'end' => '09-2014',
41
            'main' => 'true',
42
            'store' => '0',
43
            );
44
45
        foreach($formats as $format => $file)
46
            {
47
            $content = file_get_contents(__DIR__.'/Fixtures/'.$file);
48
            $format = strtoupper($format);
49
50
            $requestClass = 'Thunder\\SimilarWebApi\\Request\\'.$call;
51
            $reflectionClass = new \ReflectionClass($requestClass);
52
            $ctorArgs = array_map(function(\ReflectionParameter $parameter) use($args) {
53
                return $args[$parameter->name];
54
                }, $reflectionClass->getConstructor()->getParameters());
55
            /** @var $request AbstractRequest */
56
            $request = $reflectionClass->newInstanceArgs($ctorArgs);
57
            $this->assertEquals($requestClass, get_class($request));
58
59
            /** @var $clientMock \PHPUnit_Framework_MockObject_MockObject */
60
            $clientMock = $this->getMock($clientClass, array('executeCall'), array($token, $format));
61
            $clientMock
62
                ->expects($this->at(0))
63
                ->method('executeCall')
64
                ->with($request->getCallUrl($format, $token))
65
                ->will($this->returnValue($content));
66
            if(null !== $exception)
67
                {
68
                $this->setExpectedException($exception);
69
                }
70
71
            /** @var $clientMock Client */
72
            $clientFacade = new ClientFacade($clientMock);
73
            $response = call_user_func_array(array($clientFacade, 'get'.$call.'Response'), $ctorArgs);
74
            $cachedResponse = call_user_func_array(array($clientFacade, 'get'.$call.'Response'), $ctorArgs);
75
            if(null === $exception)
76
                {
77
                $this->assertTrue($response === $cachedResponse);
78
                $this->assertInstanceOf('Thunder\\SimilarWebApi\\AbstractResponse', $response);
79
                $this->assertInstanceOf('Thunder\\SimilarWebApi\\RawResponse', $response->getRawResponse());
80
                $this->runResponseTests($response, $valueTests, $arrayTests, $mapTests, $tupleTests);
81
                }
82
            }
83
        }
84
85
    /**
86
     * THIS TEST VERIFIES LIBRARY BEHAVIOR USING ACTUAL REQUESTS TO SIMILARWEB
87
     * API WITH YOUR API KEY. YES, EXACTLY THE SAME YOU PAID FOR WITH YOUR
88
     * PRECIOUS MONEY. IF YOU WANT TO RUN IT, UNCOMMENT METHOD BELOW AND SET
89
     * $token VARIABLE TO VALUE RECEIVED FROM SIMILARWEB DEVELOPER PANEL.
90
     * ALL CURRENTLY IMPLEMENTED CALLS IN THIS TEST USE ABOUT > 80 < API HITS.
91
     *
92
     *                       <<< YOU HAVE BEEN WARNED >>>
93
     *
94
     * @dataProvider provideEndpoints
95
     */
96
    /* public function testRealClientCalls($call, $exception, array $formats,
0 ignored issues
show
Unused Code Comprehensibility introduced by
62% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
97
                                    array $valueTests, array $arrayTests,
98
                                    array $mapTests, array $tupleTests)
99
        {
100
        $token = 'YOUR_API_TOKEN_HERE';
101
102
        $args = array(
103
            'domain' => 'google.com',
104
            'app' => 'com.google.android.gm',
105
            'page' => 1,
106
            'period' => 'weekly',
107
            'start' => '08-2014',
108
            'end' => '09-2014',
109
            'main' => 'true',
110
            'store' => '0',
111
            );
112
113
        if($exception !== null) { return; }
114
        foreach($formats as $format => $file)
115
            {
116
            $format = strtoupper($format);
117
            $client = new Client($token, $format);
118
119
            $requestClass = 'Thunder\\SimilarWebApi\\Request\\'.$call;
120
            $reflectionClass = new \ReflectionClass($requestClass);
121
            $ctorArgs = array_map(function(\ReflectionParameter $parameter) use($args) {
122
                return $args[$parameter->getName()];
123
                }, $reflectionClass->getConstructor()->getParameters());
124
            $request = $reflectionClass->newInstanceArgs($ctorArgs);
125
            $this->assertEquals($requestClass, get_class($request));
126
127
            $response = $client->getResponse($request);
128
            $cachedResponse = $client->getResponse($request);
129
            $this->assertEmpty(array_diff(array_keys($valueTests), array_keys($response->getRawResponse()->getValues())));
130
            $this->assertEmpty(array_diff(array_keys($arrayTests), array_keys($response->getRawResponse()->getArrays())));
131
            $this->assertEmpty(array_diff(array_keys($mapTests), array_keys($response->getRawResponse()->getMaps())));
132
            $this->assertEmpty(array_diff(array_keys($tupleTests), array_keys($response->getRawResponse()->getTuples())));
133
134
            $this->assertTrue($response === $cachedResponse);
135
            $this->assertInstanceOf('Thunder\\SimilarWebApi\\AbstractResponse', $response);
136
            $this->assertInstanceOf('Thunder\\SimilarWebApi\\RawResponse', $response->getRawResponse());
137
            }
138
        } */
139
140
    protected function runResponseTests(AbstractResponse $response, array $valueTests, array $arrayTests, array $mapTests, array $tupleTests)
141
        {
142
        $rawResponse = $response->getRawResponse();
143
        foreach($valueTests as $key => $value)
144
            {
145
            $this->assertEquals($value, $rawResponse->getValue($key));
146
            $call = call_user_func_array(array($response, 'get'.ucfirst($key)), array());
147
            $this->assertEquals($value, $call, var_export($value, true).' === '.var_export($call, true));
148
            }
149
        foreach($arrayTests as $key => $testData)
150
            {
151
            foreach($testData as $name => $value)
152
                {
153
                if('count' == $name)
154
                    {
155
                    $this->assertEquals($value, count($rawResponse->getArray($key)));
156
                    $call = call_user_func_array(array($response, 'get'.ucfirst($key)), array());
157
                    $this->assertEquals($value, count($call),
158
                        var_export($value, true).' === '.var_export(count($call), true));
159
                    }
160
                }
161
            }
162
        foreach($mapTests as $key => $testData)
163
            {
164
            foreach($testData as $name => $value)
165
                {
166
                if('count' == $name)
167
                    {
168
                    $this->assertEquals($value, count($rawResponse->getMap($key)),
169
                        $key.' '.var_export($value, true).' === '.var_export(count($rawResponse->getMap($key)), true));
170
                    $call = call_user_func_array(array($response, 'get'.ucfirst($key)), array());
171
                    $this->assertEquals($value, count($call),
172
                        var_export($value, true).' === '.var_export(count($call), true));
173
                    }
174
                }
175
            }
176
        foreach($tupleTests as $key => $testData)
177
            {
178
            foreach($testData as $name => $value)
179
                {
180
                if('count' == $name)
181
                    {
182
                    $this->assertEquals($value, count($rawResponse->getTuple($key)));
183
                    $method = 'get'.ucfirst($key);
184
                    $this->assertTrue(method_exists($response, $method), sprintf('undefined method %s::%s', get_class($response), $method));
185
                    $call = call_user_func_array(array($response, $method), array());
186
                    $this->assertEquals($value, count($call),
187
                        var_export($value, true).' === '.var_export(count($call), true));
188
                    }
189
                }
190
            }
191
        }
192
193
    public function provideEndpoints()
194
        {
195
        $items = array(
196
197
            /* --- INVALID TESTS ------------------------------------------- */
198
199
            array('Traffic', 'RuntimeException', array('json' => 'invalid/invalid.json'),
200
                array(), array(), array(), array()),
201
            array('Traffic', 'RuntimeException', array('xml' => 'invalid/invalid.xml'),
202
                array(), array(), array(), array()),
203
204
            /* --- V0 TESTS ------------------------------------------------ */
205
206
            array('GlobalRank', null,
207
                array(
208
                    'json' => 'v0/globalRank/200_google.json',
209
                    'xml' => 'v0/globalRank/200_google.xml',
210
                    ),
211
                array('rank' => 2),
212
                array(/* no arrays */),
213
                array(/* no maps */),
214
                array(/* no tuples */),
215
                ),
216
217
            array('SimilarSites', null, array(
218
                    'json' => 'v0/similarSites/200_google.json',
219
                    'xml' => 'v0/similarSites/200_google.xml',
220
                    ),
221
                array(/* no values */),
222
                array(/* no arrays */),
223
                array('similarSites' => array('count' => 20)),
224
                array(/* no tuples */),
225
                ),
226
227
            array('Tagging', null, array(
228
                    'json' => 'v0/tagging/200_google.json',
229
                    'xml' => 'v0/tagging/200_google.xml',
230
                    ),
231
                array(/* no values */),
232
                array(/* no arrays */),
233
                array('tags' => array('count' => 10)),
234
                array(/* no tuples */),
235
                ),
236
237
            array('V0WebsiteCategorization', null, array(
238
                    'json' => 'v0/websiteCategorization/200_google.json',
239
                    'xml' => 'v0/websiteCategorization/200_google.xml',
240
                    ),
241
                array('category' => 'Internet_and_Telecom/Search_Engine'),
242
                array(/* no arrays */),
243
                array(/* no maps */),
244
                array(/* no tuples */),
245
                ),
246
247
            array('WebsiteCategoryRank', null, array(
248
                    'json' => 'v0/websiteCategoryRank/200_google.json',
249
                    'xml' => 'v0/websiteCategoryRank/200_google.xml',
250
                    ),
251
                array(
252
                    'category' => 'Internet_and_Telecom/Search_Engine',
253
                    'rank' => 1,
254
                    ),
255
                array(/* no arrays */),
256
                array(/* no maps */),
257
                array(/* no tuples */),
258
                ),
259
260
            array('WebsiteCountryRank', null, array(
261
                    'json' => 'v0/websiteCountryRanking/200_google.json',
262
                    'xml' => 'v0/websiteCountryRanking/200_google.xml',
263
                    ),
264
                array(/* no values */),
265
                array(/* no arrays */),
266
                array('topCountryRanks' => array('count' => 5)),
267
                array(/* no tuples */),
268
                ),
269
270
            /* --- V1 TESTS ------------------------------------------------ */
271
272
            array('Traffic', null,
273
                array(
274
                    'json' => 'v1/traffic/200_google.json',
275
                    'xml' => 'v1/traffic/200_google.xml',
276
                    ),
277
                array(
278
                    'globalRank' => 2,
279
                    'countryRank' => 1,
280
                    'countryCode' => 840,
281
                    'date' => '12/2013',
282
                    ),
283
                array(/* no arrays */),
284
                array(
285
                    'topCountryShares' => array('count' => 228),
286
                    'trafficReach' => array('count' => 27),
287
                    'trafficShares' => array('count' => 6),
288
                    ),
289
                array(/* no tuples */),
290
                ),
291
292
            array('Engagement', null, array(
293
                    'json' => 'v1/engagement/200_google.json',
294
                    'xml' => 'v1/engagement/200_google.xml',
295
                    ),
296
                array(
297
                    'averagePageViews' => 10.131644139915386,
298
                    'averageTimeOnSite' => 662.9348950744902,
299
                    'bounceRate' => 0.2576071545711606,
300
                    'date' => '12/2013',
301
                    ),
302
                array(/* no arrays */),
303
                array(/* no maps */),
304
                array(/* no tuples */),
305
                ),
306
307
            array('Keywords', null, array(
308
                    'json' => 'v1/keywords/200_google.json',
309
                    'xml' => 'v1/keywords/200_google.xml',
310
                    ),
311
                array(
312
                    'organicSearchShare' => 0.991548209408053,
313
                    'paidSearchShare' => 0.008451790591947006,
314
                    'startDate' => '10/2013',
315
                    'endDate' => '12/2013',
316
                    ),
317
                array(
318
                    'topOrganicTerms' => array('count' => 10),
319
                    'topPaidTerms' => array('count' => 7),
320
                    ),
321
                array(/* no maps */),
322
                array(/* no tuples */),
323
                ),
324
325
            array('SocialReferrals', null, array(
326
                    'json' => 'v1/socialReferrals/200_google.json',
327
                    'xml' => 'v1/socialReferrals/200_google.xml',
328
                    ),
329
                array(
330
                    'startDate' => '10/2013',
331
                    'endDate' => '12/2013',
332
                    ),
333
                array(/* no arrays */),
334
                array('socialSources' => array('count' => 152)),
335
                array(/* no tuples */),
336
                ),
337
338
            /* --- V2 TESTS ------------------------------------------------ */
339
340
            array('AdultWebsites', null, array(
341
                    'json' => 'v2/adultWebsites/200_google.json',
342
                    'xml' => 'v2/adultWebsites/200_google.xml',
343
                    ),
344
                array('category' => 'Internet_and_Telecom/Search_Engine'),
345
                array(/* no arrays */),
346
                array(/* no maps */),
347
                array(/* no tuples */),
348
                ),
349
            array('AdultWebsites', null, array(
350
                    'json' => 'v2/adultWebsites/200_sex.json',
351
                    'xml' => 'v2/adultWebsites/200_sex.xml',
352
                    ),
353
                array('category' => 'Adult'),
354
                array(/* no arrays */),
355
                array(/* no maps */),
356
                array(/* no tuples */),
357
                ),
358
359
            array('AlsoVisited', null, array(
360
                    'json' => 'v2/alsoVisited/200_google.json',
361
                    'xml' => 'v2/alsoVisited/200_google.xml',
362
                    ),
363
                array(/* no values */),
364
                array(/* no arrays */),
365
                array('alsoVisited' => array('count' => 13)),
366
                array(/* no tuples */),
367
                ),
368
369
            array('CategoryRank', null, array(
370
                    'json' => 'v2/categoryRank/200_google.json',
371
                    'xml' => 'v2/categoryRank/200_google.xml',
372
                    ),
373
                array(
374
                    'category' => 'Internet_and_Telecom/Search_Engine',
375
                    'rank' => 1,
376
                    ),
377
                array(/* no arrays */),
378
                array(/* no maps */),
379
                array(/* no tuples */),
380
                ),
381
382
            array('Destinations', null, array(
383
                    'json' => 'v2/destinations/200_google.json',
384
                    'xml' => 'v2/destinations/200_google.xml',
385
                    ),
386
                array('startDate' => '10/2013', 'endDate' => '12/2013'),
387
                array('sites' => array('count' => 10)),
388
                array(/* no maps */),
389
                array(/* no tuples */),
390
                ),
391
392
            array('EstimatedVisitors', null, array(
393
                    'json' => 'v2/estimatedVisitors/200_google.json',
394
                    'xml' => 'v2/estimatedVisitors/200_google.xml',
395
                    ),
396
                array('estimatedVisitors' => 8788535663),
397
                array(/* no arrays */),
398
                array(/* no maps */),
399
                array(/* no tuples */),
400
                ),
401
402
            array('Referrals', null, array(
403
                    'json' => 'v2/referrals/200_google.json',
404
                    'xml' => 'v2/referrals/200_google.xml',
405
                    ),
406
                array('startDate' => '10/2013', 'endDate' => '12/2013'),
407
                array('sites' => array('count' => 10)),
408
                array(/* no maps */),
409
                array(/* no tuples */),
410
                ),
411
412
            array('SimilarWebsites', null, array(
413
                    'json' => 'v2/similarWebsites/200_google.json',
414
                    'xml' => 'v2/similarWebsites/200_google.xml',
415
                    ),
416
                array(/* no values */),
417
                array(/* no arrays */),
418
                array('similarWebsites' => array('count' => 20)),
419
                array(/* no tuples */),
420
                ),
421
422
            array('WebsiteCategorization', null, array(
423
                    'json' => 'v2/websiteCategorization/200_google.json',
424
                    'xml' => 'v2/websiteCategorization/200_google.xml',
425
                    ),
426
                array('category' => 'Internet_and_Telecom/Search_Engine'),
427
                array(/* no arrays */),
428
                array(/* no maps */),
429
                array(/* no tuples */),
430
                ),
431
432
            array('WebsiteTags', null, array(
433
                    'json' => 'v2/websiteTags/200_google.json',
434
                    'xml' => 'v2/websiteTags/200_google.xml',
435
                    ),
436
                array(/* no values */),
437
                array(/* no arrays */),
438
                array('tags' => array('count' => 10)),
439
                array(/* no tuples */),
440
                ),
441
442
            /* --- V1 PRO TESTS -------------------------------------------- */
443
444
            array('TrafficPro', null, array(
445
                    'json' => 'v1pro/traffic/200_google.json',
446
                    'xml' => 'v1pro/traffic/200_google.xml',
447
                    ),
448
                array(/* no values */),
449
                array(/* no arrays */),
450
                array('values' => array('count' => 7)),
451
                array(/* no tuples */),
452
                ),
453
454
            array('EngagementBounceRate', null, array(
455
                    'json' => 'v1pro/engagement/bouncerate/200_google.json',
456
                    'xml' => 'v1pro/engagement/bouncerate/200_google.xml',
457
                    ),
458
                array(/* no values */),
459
                array(/* no arrays */),
460
                array('values' => array('count' => 2)),
461
                array(/* no tuples */),
462
                ),
463
            array('EngagementPageViews', null, array(
464
                    'json' => 'v1pro/engagement/pageviews/200_google.json',
465
                    'xml' => 'v1pro/engagement/pageviews/200_google.xml',
466
                    ),
467
                array(/* no values */),
468
                array(/* no arrays */),
469
                array('values' => array('count' => 2)),
470
                array(/* no tuples */),
471
                ),
472
            array('EngagementVisitDuration', null, array(
473
                    'json' => 'v1pro/engagement/visitduration/200_google.json',
474
                    'xml' => 'v1pro/engagement/visitduration/200_google.xml',
475
                    ),
476
                array(/* no values */),
477
                array(/* no arrays */),
478
                array('values' => array('count' => 2)),
479
                array(/* no tuples */),
480
                ),
481
482
            array('ReferralsPro', null, array(
483
                    'json' => 'v1pro/referrals/200_google.json',
484
                    'xml' => 'v1pro/referrals/200_google.xml',
485
                    ),
486
                array('results' => 10, 'total' => 1058),
487
                array(/* no arrays */),
488
                array(/* no maps */),
489
                array('sites' => array('count' => 10)),
490
                ),
491
492
            array('KeywordsOrganicSearch', null, array(
493
                    'json' => 'v1pro/searchKeywords/organic/200_google.json',
494
                    'xml' => 'v1pro/searchKeywords/organic/200_google.xml',
495
                    ),
496
                array('results' => 10, 'total' => 35125),
497
                array(/* no arrays */),
498
                array(/* no maps */),
499
                array('terms' => array('count' => 10)),
500
                ),
501
            array('KeywordsPaidSearch', null, array(
502
                    'json' => 'v1pro/searchKeywords/paid/200_google.json',
503
                    'xml' => 'v1pro/searchKeywords/paid/200_google.xml',
504
                    ),
505
                array('results' => 10, 'total' => 1412),
506
                array(/* no arrays */),
507
                array(/* no maps */),
508
                array('terms' => array('count' => 10)),
509
                ),
510
511
            array('KeywordCompetitorsOrganic', null, array(
512
                    'json' => 'v1pro/searchCompetitors/organic/200_google.json',
513
                    'xml' => 'v1pro/searchCompetitors/organic/200_google.xml',
514
                    ),
515
                array('results' => 10, 'total' => 1435),
516
                array(/* no arrays */),
517
                array('values' => array('count' => 10)),
518
                array(/* no tuples */),
519
                ),
520
            array('KeywordCompetitorsPaid', null, array(
521
                    'json' => 'v1pro/searchCompetitors/paid/200_google.json',
522
                    'xml' => 'v1pro/searchCompetitors/paid/200_google.xml',
523
                    ),
524
                array('results' => 10, 'total' => 1680),
525
                array(/* no arrays */),
526
                array('values' => array('count' => 10)),
527
                array(/* no tuples */),
528
                ),
529
530
            /* --- MOBILE TESTS -------------------------------------------- */
531
532
            array('MobileApp', null, array(
533
                    'json' => 'mobile/app/android_gmail.json',
534
                    'xml' => 'mobile/app/android_gmail.xml',
535
                    ),
536
                array(
537
                    'title' => 'Gmail',
538
                    'cover' => 'https://lh5.ggpht.com/jVUU0A5NY5EzMqn9AyakWNb0mUHWAkDTjnnamSGqTiEW9FEqnq4CpIEsi-5U2wzo-eYq=w300',
539
                    'author' => 'Google Inc.',
540
                    'price' => 'Free',
541
                    'mainCategory' => 'Communication',
542
                    'mainCategoryId' => 'communication',
543
                    'rating' => 4.3047308921813965,
544
                    ),
545
                array(/* no arrays */),
546
                array(/* no maps */),
547
                array(/* no tuples */),
548
                ),
549
            array('MobileAppInstalls', null, array(
550
                    'json' => 'mobile/installs/android_gmail.json',
551
                    'xml' => 'mobile/installs/android_gmail.xml',
552
                    ),
553
                array('min' => 1000000000, 'max' => 5000000000),
554
                array(/* no arrays */),
555
                array(/* no maps */),
556
                array(/* no tuples */),
557
                ),
558
            array('MobileRelatedApps', null, array(
559
                    'json' => 'mobile/relatedApps/200_google.json',
560
                    'xml' => 'mobile/relatedApps/200_google.xml',
561
                    ),
562
                array(/* no values */),
563
                array(/* no arrays */),
564
                array('apps' => array('count' => 101)),
565
                array(/* no tuples */),
566
                ),
567
568
            /* --- END TESTS ----------------------------------------------- */
569
570
            );
571
572
        return $items;
573
        }
574
575
    /**
576
     * @expectedException \RuntimeException
577
     */
578
    public function testInvalidResponseClassJson()
579
        {
580
        $instance = new JsonParser('Traffic', array());
581
        $instance->getResponse('');
582
        }
583
584
    /**
585
     * @expectedException \RuntimeException
586
     */
587
    public function testInvalidResponseClassXml()
588
        {
589
        $instance = new XmlParser('Traffic', array());
590
        $instance->getResponse('');
591
        }
592
    }
593